mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 00:01:34 +11:00
Nicer key rebinding
This commit is contained in:
parent
ce75b15716
commit
bf722ecdfa
|
@ -48,4 +48,4 @@
|
|||
"@types/styled-components": "^5.1.26",
|
||||
"prettier": "2.8.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,35 +1,97 @@
|
|||
import React, { useState } from "react";
|
||||
import { Mgba } from "./mgba";
|
||||
import { BindingsControl, DefaultBindingsSet } from "./bindings";
|
||||
import { BindingsControl, DefaultBindingsSet, Bindings } from "./bindings";
|
||||
import { styled } from "styled-components";
|
||||
import { useOnKeyUp } from "./useOnKeyUp.hook";
|
||||
|
||||
const BindingsDialog = styled.dialog`
|
||||
border-radius: 5px;
|
||||
margin-top: 20px;
|
||||
`;
|
||||
|
||||
const VolumeLabel = styled.label`
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-bottom: 20px;
|
||||
`;
|
||||
|
||||
const CloseButton = styled.button`
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
`;
|
||||
|
||||
function App() {
|
||||
const [volume, setVolume] = useState(1.0);
|
||||
const [bindings, setBindings] = useState(DefaultBindingsSet());
|
||||
const [paused, setPaused] = useState(false);
|
||||
|
||||
const [showBindings, setShowBindings] = useState(false);
|
||||
|
||||
useOnKeyUp("Escape", () => {
|
||||
setShowBindings(!showBindings);
|
||||
});
|
||||
|
||||
return (
|
||||
<div>
|
||||
{showBindings && (
|
||||
<BindingsWindow
|
||||
bindings={bindings}
|
||||
setBindings={setBindings}
|
||||
setPaused={setPaused}
|
||||
volume={volume}
|
||||
setVolume={setVolume}
|
||||
hide={() => setShowBindings(false)}
|
||||
/>
|
||||
)}
|
||||
<Mgba
|
||||
gameUrl="/game.gba"
|
||||
volume={volume}
|
||||
controls={bindings.Actual}
|
||||
paused={paused}
|
||||
/>
|
||||
<input
|
||||
type="range"
|
||||
value={volume}
|
||||
min="0"
|
||||
max="1"
|
||||
step="0.05"
|
||||
onChange={(e) => setVolume(Number(e.target.value))}
|
||||
></input>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function BindingsWindow({
|
||||
bindings,
|
||||
setBindings,
|
||||
setPaused,
|
||||
volume,
|
||||
setVolume,
|
||||
hide,
|
||||
}: {
|
||||
bindings: Bindings;
|
||||
setBindings: (b: Bindings) => void;
|
||||
setPaused: (paused: boolean) => void;
|
||||
volume: number;
|
||||
setVolume: (v: number) => void;
|
||||
hide: () => void;
|
||||
}) {
|
||||
return (
|
||||
<BindingsDialog open onClose={hide}>
|
||||
<VolumeLabel>
|
||||
Volume:
|
||||
<input
|
||||
type="range"
|
||||
value={volume}
|
||||
min="0"
|
||||
max="1"
|
||||
step="0.05"
|
||||
onChange={(e) => {
|
||||
console.log("e.target.value", e.target.value);
|
||||
console.log("volume", volume);
|
||||
setVolume(Number(e.target.value));
|
||||
}}
|
||||
/>
|
||||
</VolumeLabel>
|
||||
<BindingsControl
|
||||
bindings={bindings}
|
||||
setBindings={setBindings}
|
||||
setPaused={setPaused}
|
||||
/>
|
||||
</div>
|
||||
<CloseButton onClick={hide}>Close</CloseButton>
|
||||
</BindingsDialog>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ export type KeyBindings = {
|
|||
[key in GbaKey]: string;
|
||||
};
|
||||
|
||||
interface Bindings {
|
||||
export interface Bindings {
|
||||
Displayed: KeyBindings;
|
||||
Actual: KeyBindings;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import App from "./App";
|
|||
const root = ReactDOM.createRoot(
|
||||
document.getElementById("root") as HTMLElement
|
||||
);
|
||||
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
|
|
|
@ -78,7 +78,7 @@ export const Mgba: FC<MgbaProps> = ({ gameUrl, volume, controls, paused }) => {
|
|||
try {
|
||||
mgbaModule.current.quitGame();
|
||||
mgbaModule.current.quitMgba();
|
||||
} catch { }
|
||||
} catch {}
|
||||
};
|
||||
}, [state]);
|
||||
|
||||
|
@ -114,33 +114,5 @@ export const Mgba: FC<MgbaProps> = ({ gameUrl, volume, controls, paused }) => {
|
|||
}
|
||||
}, [gameLoaded, paused]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<MgbaCanvas ref={canvas} />
|
||||
<button
|
||||
onClick={() => {
|
||||
if (state !== MgbaState.Initialised) return;
|
||||
mgbaModule.current.saveState(0);
|
||||
}}
|
||||
>
|
||||
Save State
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
if (state !== MgbaState.Initialised) return;
|
||||
mgbaModule.current.loadState(0);
|
||||
}}
|
||||
>
|
||||
Load State
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
if (state !== MgbaState.Initialised) return;
|
||||
mgbaModule.current.quickReload();
|
||||
}}
|
||||
>
|
||||
Restart
|
||||
</button>
|
||||
</>
|
||||
);
|
||||
return <MgbaCanvas ref={canvas} />;
|
||||
};
|
||||
|
|
18
website/src/useOnKeyUp.hook.ts
Normal file
18
website/src/useOnKeyUp.hook.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { useEffect } from "react";
|
||||
|
||||
export const useOnKeyUp = (targetKey: string, callback: () => void) => {
|
||||
useEffect(() => {
|
||||
const downHandler = (evnt: KeyboardEvent) => {
|
||||
console.log(evnt.key);
|
||||
if (evnt.key === targetKey) {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("keyup", downHandler);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("keyup", downHandler);
|
||||
};
|
||||
}, []);
|
||||
};
|
Loading…
Reference in a new issue