Initial commit.

This commit is contained in:
CSG-Dominic
2025-03-11 13:06:14 -05:00
commit ba27084fa1
23 changed files with 2822 additions and 0 deletions

View File

@@ -0,0 +1,96 @@
import { useEffect, useRef, useState } from 'react';
import styles from './Emulator.module.scss';
type EmulatorSystem = (
'gb' | 'gbc' | 'gba'
);
type EmulatorCore = (
'gambatte' | 'mgba'
);
const EMULATOR_SYSTEM_CORES:{ [key in EmulatorSystem]:EmulatorCore } = {
'gb': 'gambatte',
'gbc': 'gambatte',
'gba': 'mgba'
}
export type EmulatorProps = {
system:EmulatorSystem;
};
type SendEmulatorMessageInit = {
message:'init';
core:EmulatorCore;
system:EmulatorSystem;
game:string;
gameName:string;
}
type SendEmulatorMessage = (
SendEmulatorMessageInit
);
type ReceiveEmulatorOnGameStart = {
message:'start'
}
type ReceiveEmulatorMessage = (
ReceiveEmulatorOnGameStart
);
export const Emulator:React.FC<EmulatorProps> = props => {
const iframeRef = useRef<HTMLIFrameElement>(null);
const [ hasInit, setHasInit ] = useState(false);
const send = (msg:SendEmulatorMessage) => {
iframeRef.current?.contentWindow?.postMessage(msg, '*');
};
useEffect(() => {
if(hasInit) return;
setHasInit(true);
send({
message: 'init',
core: EMULATOR_SYSTEM_CORES[props.system],
system: props.system,
game: '/test.gbc',
gameName: 'Pokemon - Crystal Version'
});
window.onmessage = (e) => {
if(!e.data) {
console.error('Invalid message received:', e.data);
return;
}
const msg = e.data as ReceiveEmulatorMessage;
console.log('recv', msg);
switch(msg.message) {
case 'start':
console.log('Game started!');
break
default:
console.error('Invalid message received:', msg);
break
}
};
}, [ iframeRef ]);
return (
<div className={styles.emulator}>
<div className={[
styles.emulator__box,
styles[`emulator__box--${props.system}`]
].join(' ')} />
<iframe
src="/emulator.html"
className={styles.emulator__iframe}
ref={iframeRef}
/>
</div>
);
}