Skip to content
Snippets Groups Projects
gb.ts 34.6 KiB
Newer Older
  • Learn to ignore specific revisions
  •     }
    
        private updatePalette() {
            const palette = PALETTES[this.paletteIndex];
    
            this.gameBoy?.set_palette_colors_wa(palette.colors);
    
            this.storeSettings();
    
        private static async fetchRom(
    
            romPath: string
        ): Promise<{ name: string; data: Uint8Array }> {
            // extracts the name of the ROM from the provided
            // path by splitting its structure
            const romPathS = romPath.split(/\//g);
            let romName = romPathS[romPathS.length - 1].split("?")[0];
            const romNameS = romName.split(/\./g);
            romName = `${romNameS[0]}.${romNameS[romNameS.length - 1]}`;
    
            // loads the ROM data and converts it into the
            // target byte array buffer (to be used by WASM)
            const response = await fetch(romPath);
            const blob = await response.blob();
            const arrayBuffer = await blob.arrayBuffer();
            const romData = new Uint8Array(arrayBuffer);
    
            // returns both the name of the ROM and the data
            // contents as a byte array
            return {
                name: romName,
                data: romData
            };
        }
    }
    
    declare global {
        interface Window {
    
            emulator: GameboyEmulator;
    
            panic: (message: string) => void;
    
            speedCallback: (speed: GameBoySpeed) => void;
    
            loggerCallback: (data: Uint8Array) => void;
    
            printerCallback: (imageBuffer: Uint8Array) => void;
    
            rumbleCallback: (active: boolean) => void;
    
        }
    
        interface Console {
            image(url: string, size?: number): void;
    
        }
    }
    
    window.panic = (message: string) => {
        console.error(message);
    };
    
    
    window.speedCallback = (speed: GameBoySpeed) => {
        window.emulator.onSpeedSwitch(speed);
    };
    
    
    window.loggerCallback = (data: Uint8Array) => {
        window.emulator.onLoggerDevice(data);
    };
    
    
    window.printerCallback = (imageBuffer: Uint8Array) => {
    
        window.emulator.onPrinterDevice(imageBuffer);
    
    window.rumbleCallback = (active: boolean) => {
        if (!active) return;
    
        // runs the vibration actuator on the current window
        // this will probably affect only mobile devices
        window?.navigator?.vibrate?.(250);
    
        // iterates over all the available gamepads to run
        // the vibration actuator on each of them
        let gamepadIndex = 0;
        while (true) {
            const gamepad = navigator.getGamepads()[gamepadIndex];
            if (!gamepad) break;
            gamepad?.vibrationActuator?.playEffect?.("dual-rumble", {
                startDelay: 0,
                duration: 150,
                weakMagnitude: 0.8,
                strongMagnitude: 0.0
            });
            gamepadIndex++;
        }
    };
    
    
    console.image = (url: string, size = 80) => {
        const style = `font-size: ${size}px; background-image: url("${url}"); background-size: contain; background-repeat: no-repeat;`;
        console.log("%c     ", style);
    };
    
    
    const wasm = async (setHook = true) => {
    
    
        // in case the set hook flag is set, then tries to
        // set the panic hook for the WASM module, this call
        // may fail in some versions of wasm-bindgen as the
        // thread is still marked as "panicking", so we need to
        // wrap the call around try/catch
        if (setHook) {
            try {
    
                GameBoy.set_panic_hook_wa();
    
            } catch (err) {
                console.error(err);
            }
        }