mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 00:01:34 +11:00
dynamically choose frameskip or timeout
This commit is contained in:
parent
61a7e2fa64
commit
3b2ebe6001
|
@ -8,6 +8,7 @@ import {
|
|||
import mGBA from "./vendor/mgba";
|
||||
import { GbaKey, KeyBindings } from "./bindings";
|
||||
import { styled } from "styled-components";
|
||||
import { useSmoothedFramerate } from "./useSmoothedFramerate.hook";
|
||||
|
||||
type Module = any;
|
||||
|
||||
|
@ -40,6 +41,14 @@ export interface MgbaHandle {
|
|||
buttonRelease: (key: GbaKey) => void;
|
||||
}
|
||||
|
||||
const whichFrameSkip = (frameRate: number): number | undefined => {
|
||||
if ((frameRate + 5) % 60 <= 10) {
|
||||
// framerate close to multiple of 60
|
||||
// use frameskip
|
||||
return Math.round(frameRate / 60);
|
||||
}
|
||||
};
|
||||
|
||||
export const Mgba = forwardRef<MgbaHandle, MgbaProps>(
|
||||
({ gameUrl, volume, controls, paused }, ref) => {
|
||||
const canvas = useRef(null);
|
||||
|
@ -92,6 +101,24 @@ export const Mgba = forwardRef<MgbaHandle, MgbaProps>(
|
|||
};
|
||||
}, [state]);
|
||||
|
||||
const frameRate = useSmoothedFramerate();
|
||||
const frameSkipToUse = whichFrameSkip(frameRate);
|
||||
|
||||
useEffect(() => {
|
||||
if (!gameLoaded) return;
|
||||
|
||||
if (frameSkipToUse) {
|
||||
// framerate close to multiple of 60
|
||||
// use frameskip
|
||||
console.log("Using frameskip");
|
||||
mgbaModule.current.setMainLoopTiming(1, frameSkipToUse);
|
||||
} else {
|
||||
// frame rate not close to multiple of 60, use timeout
|
||||
console.log("Using timeout");
|
||||
mgbaModule.current.setMainLoopTiming(0, 1000 / 59.727500569606);
|
||||
}
|
||||
}, [frameSkipToUse, gameLoaded]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!gameLoaded) return;
|
||||
|
||||
|
|
35
website/app/src/useSmoothedFramerate.hook.ts
Normal file
35
website/app/src/useSmoothedFramerate.hook.ts
Normal file
|
@ -0,0 +1,35 @@
|
|||
import { useEffect, useState } from "react";
|
||||
|
||||
|
||||
export const useSmoothedFramerate = (): number => {
|
||||
|
||||
const [smoothedFrameTime, setSmoothedFrameTime] = useState(60);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
let previous: number | undefined = undefined;
|
||||
let stopped = false;
|
||||
|
||||
const raf = (time: DOMHighResTimeStamp) => {
|
||||
if (previous) {
|
||||
let delta = time - previous;
|
||||
|
||||
setSmoothedFrameTime((time) => (time * 3 + delta) / 4);
|
||||
}
|
||||
previous = time;
|
||||
|
||||
|
||||
if (!stopped) {
|
||||
window.requestAnimationFrame(raf);
|
||||
}
|
||||
}
|
||||
|
||||
window.requestAnimationFrame(raf);
|
||||
|
||||
return () => { stopped = true; }
|
||||
|
||||
}, []);
|
||||
|
||||
|
||||
return Math.round(1 / (smoothedFrameTime / 1000));
|
||||
}
|
Loading…
Reference in a new issue