UNPKG

@soapbox.pub/wasmboy

Version:

Soapbox fork of Wasmboy.

174 lines (158 loc) 7.84 kB
import { postMessage, onMessage } from '../../../worker/workerapi'; import { WORKER_MESSAGE_TYPE, MEMORY_TYPE } from '../../../worker/constants'; import { getEventData } from '../../../worker/util'; import { getSmartWorkerMessage } from '../../../worker/smartworker'; // Our memory getters import { getBootRom } from './boot'; import { getCartridgeRom } from './rom'; import { getCartridgeRam } from './ram'; import { getCartridgeHeader } from './header'; import { getGameBoyMemory } from './gameboymemory'; import { getPaletteMemory } from './palettememory'; import { getInternalState } from './internalstate'; // On message handler for when memory worker // posts to lib Worker export function memoryWorkerOnMessage(libWorker, event) { // Handle our messages from the main thread const eventData = getEventData(event); switch (eventData.message.type) { case WORKER_MESSAGE_TYPE.CLEAR_MEMORY: { // Clear Wasm memory // https://docs.google.com/spreadsheets/d/17xrEzJk5-sCB9J2mMJcVnzhbE-XH_NvczVSQH9OHvRk/edit?usp=sharing for (let i = 0; i <= libWorker.wasmByteMemory.length; i++) { libWorker.wasmByteMemory[i] = 0; } const wasmByteMemory = libWorker.wasmByteMemory.slice(0); libWorker.memoryWorkerPort.postMessage( getSmartWorkerMessage( { type: WORKER_MESSAGE_TYPE.CLEAR_MEMORY_DONE, wasmByteMemory: wasmByteMemory.buffer }, eventData.messageId ), [wasmByteMemory.buffer] ); return; } case WORKER_MESSAGE_TYPE.GET_CONSTANTS: { libWorker.WASMBOY_BOOT_ROM_LOCATION = libWorker.wasmInstance.exports.BOOT_ROM_LOCATION.valueOf(); libWorker.WASMBOY_GAME_BYTES_LOCATION = libWorker.wasmInstance.exports.CARTRIDGE_ROM_LOCATION.valueOf(); (libWorker.WASMBOY_GAME_RAM_BANKS_LOCATION = libWorker.wasmInstance.exports.CARTRIDGE_RAM_LOCATION.valueOf()), (libWorker.WASMBOY_INTERNAL_STATE_SIZE = libWorker.wasmInstance.exports.WASMBOY_STATE_SIZE.valueOf()), (libWorker.WASMBOY_INTERNAL_STATE_LOCATION = libWorker.wasmInstance.exports.WASMBOY_STATE_LOCATION.valueOf()), (libWorker.WASMBOY_INTERNAL_MEMORY_SIZE = libWorker.wasmInstance.exports.GAMEBOY_INTERNAL_MEMORY_SIZE.valueOf()), (libWorker.WASMBOY_INTERNAL_MEMORY_LOCATION = libWorker.wasmInstance.exports.GAMEBOY_INTERNAL_MEMORY_LOCATION.valueOf()), (libWorker.WASMBOY_PALETTE_MEMORY_SIZE = libWorker.wasmInstance.exports.GBC_PALETTE_SIZE.valueOf()), (libWorker.WASMBOY_PALETTE_MEMORY_LOCATION = libWorker.wasmInstance.exports.GBC_PALETTE_LOCATION.valueOf()); // Forward to our lib worker libWorker.memoryWorkerPort.postMessage( getSmartWorkerMessage( { type: WORKER_MESSAGE_TYPE.GET_CONSTANTS_DONE, WASMBOY_BOOT_ROM_LOCATION: libWorker.wasmInstance.exports.BOOT_ROM_LOCATION.valueOf(), WASMBOY_GAME_BYTES_LOCATION: libWorker.wasmInstance.exports.CARTRIDGE_ROM_LOCATION.valueOf(), WASMBOY_GAME_RAM_BANKS_LOCATION: libWorker.wasmInstance.exports.CARTRIDGE_RAM_LOCATION.valueOf(), WASMBOY_INTERNAL_STATE_SIZE: libWorker.wasmInstance.exports.WASMBOY_STATE_SIZE.valueOf(), WASMBOY_INTERNAL_STATE_LOCATION: libWorker.wasmInstance.exports.WASMBOY_STATE_LOCATION.valueOf(), WASMBOY_INTERNAL_MEMORY_SIZE: libWorker.wasmInstance.exports.GAMEBOY_INTERNAL_MEMORY_SIZE.valueOf(), WASMBOY_INTERNAL_MEMORY_LOCATION: libWorker.wasmInstance.exports.GAMEBOY_INTERNAL_MEMORY_LOCATION.valueOf(), WASMBOY_PALETTE_MEMORY_SIZE: libWorker.wasmInstance.exports.GBC_PALETTE_SIZE.valueOf(), WASMBOY_PALETTE_MEMORY_LOCATION: libWorker.wasmInstance.exports.GBC_PALETTE_LOCATION.valueOf() }, eventData.messageId ) ); return; } case WORKER_MESSAGE_TYPE.SET_MEMORY: { const memoryKeys = Object.keys(eventData.message); if (memoryKeys.includes(MEMORY_TYPE.BOOT_ROM)) { libWorker.wasmByteMemory.set(new Uint8Array(eventData.message[MEMORY_TYPE.BOOT_ROM]), libWorker.WASMBOY_BOOT_ROM_LOCATION); } if (memoryKeys.includes(MEMORY_TYPE.CARTRIDGE_ROM)) { libWorker.wasmByteMemory.set(new Uint8Array(eventData.message[MEMORY_TYPE.CARTRIDGE_ROM]), libWorker.WASMBOY_GAME_BYTES_LOCATION); } if (memoryKeys.includes(MEMORY_TYPE.CARTRIDGE_RAM)) { libWorker.wasmByteMemory.set( new Uint8Array(eventData.message[MEMORY_TYPE.CARTRIDGE_RAM]), libWorker.WASMBOY_GAME_RAM_BANKS_LOCATION ); } if (memoryKeys.includes(MEMORY_TYPE.GAMEBOY_MEMORY)) { libWorker.wasmByteMemory.set( new Uint8Array(eventData.message[MEMORY_TYPE.GAMEBOY_MEMORY]), libWorker.WASMBOY_INTERNAL_MEMORY_LOCATION ); } if (memoryKeys.includes(MEMORY_TYPE.PALETTE_MEMORY)) { libWorker.wasmByteMemory.set( new Uint8Array(eventData.message[MEMORY_TYPE.PALETTE_MEMORY]), libWorker.WASMBOY_PALETTE_MEMORY_LOCATION ); } if (memoryKeys.includes(MEMORY_TYPE.INTERNAL_STATE)) { libWorker.wasmByteMemory.set( new Uint8Array(eventData.message[MEMORY_TYPE.INTERNAL_STATE]), libWorker.WASMBOY_INTERNAL_STATE_LOCATION ); libWorker.wasmInstance.exports.loadState(); } libWorker.memoryWorkerPort.postMessage( getSmartWorkerMessage( { type: WORKER_MESSAGE_TYPE.SET_MEMORY_DONE }, eventData.messageId ) ); return; } case WORKER_MESSAGE_TYPE.GET_MEMORY: { // Construct our data object const responseMemory = { type: WORKER_MESSAGE_TYPE.GET_MEMORY }; const responseTransferrables = []; const memoryTypes = eventData.message.memoryTypes; if (memoryTypes.includes(MEMORY_TYPE.BOOT_ROM)) { const bootRom = getBootRom(libWorker).buffer; responseMemory[MEMORY_TYPE.BOOT_ROM] = bootRom; responseTransferrables.push(bootRom); } if (memoryTypes.includes(MEMORY_TYPE.CARTRIDGE_ROM)) { const cartridgeRom = getCartridgeRom(libWorker).buffer; responseMemory[MEMORY_TYPE.CARTRIDGE_ROM] = cartridgeRom; responseTransferrables.push(cartridgeRom); } if (memoryTypes.includes(MEMORY_TYPE.CARTRIDGE_RAM)) { const cartridgeRam = getCartridgeRam(libWorker).buffer; responseMemory[MEMORY_TYPE.CARTRIDGE_RAM] = cartridgeRam; responseTransferrables.push(cartridgeRam); } if (memoryTypes.includes(MEMORY_TYPE.CARTRIDGE_HEADER)) { const cartridgeHeader = getCartridgeHeader(libWorker).buffer; responseMemory[MEMORY_TYPE.CARTRIDGE_HEADER] = cartridgeHeader; responseTransferrables.push(cartridgeHeader); } if (memoryTypes.includes(MEMORY_TYPE.GAMEBOY_MEMORY)) { const gameboyMemory = getGameBoyMemory(libWorker).buffer; responseMemory[MEMORY_TYPE.GAMEBOY_MEMORY] = gameboyMemory; responseTransferrables.push(gameboyMemory); } if (memoryTypes.includes(MEMORY_TYPE.PALETTE_MEMORY)) { const paletteMemory = getPaletteMemory(libWorker).buffer; responseMemory[MEMORY_TYPE.PALETTE_MEMORY] = paletteMemory; responseTransferrables.push(paletteMemory); } if (memoryTypes.includes(MEMORY_TYPE.INTERNAL_STATE)) { libWorker.wasmInstance.exports.saveState(); const internalState = getInternalState(libWorker).buffer; responseMemory[MEMORY_TYPE.INTERNAL_STATE] = internalState; responseTransferrables.push(internalState); } libWorker.memoryWorkerPort.postMessage(getSmartWorkerMessage(responseMemory, eventData.messageId), responseTransferrables); return; } } }