UNPKG

@soapbox.pub/wasmboy

Version:

Soapbox fork of Wasmboy.

103 lines (86 loc) 2.8 kB
// Modules import uzip from '../3p/UZIP'; // Collection of functions to parse roms // Private function to fetch a game export const fetchROMAsByteArray = (ROM, loadOptions) => { const fetchROMAsByteArrayTask = async () => { // Check if we were passed straight bytes if (ArrayBuffer.isView(ROM) && ROM.constructor === Uint8Array) { return { ROM: ROM }; } else if (typeof ROM === 'object' && ROM.size) { // We were passed a file from HTML file input // Read the file as a Uint8Array let byteArray = await getROMFromFileReaderAsByteArray(ROM); if (ROM.name.toLowerCase().endsWith('.zip')) { byteArray = await parseByteArrayAsZip(byteArray); } return { ROM: byteArray, name: ROM.name }; } else { // We were passed a URL // Fetch the file // First check if we have headers const fetchHeaders = {}; if (loadOptions && loadOptions.headers) { fetchHeaders.headers = loadOptions.headers; } let bytes = await fetch(ROM, fetchHeaders).then(blob => { if (!blob.ok) { return Promise.reject(blob); } return blob.arrayBuffer(); }); let fileName = ROM; if (loadOptions && loadOptions.fileName) { fileName = loadOptions.fileName; } // Get our byteArray let byteArray = new Uint8Array(bytes); if (fileName.toLowerCase().endsWith('.zip')) { byteArray = await parseByteArrayAsZip(byteArray); } return { ROM: byteArray, name: fileName }; } }; return fetchROMAsByteArrayTask(); }; const getROMFromFileReaderAsByteArray = async ROM => { const fileReaderByteArray = await new Promise((resolve, reject) => { // Read the file object // https://www.javascripture.com/FileReader#readAsArrayBuffer_Blob const fileReader = new FileReader(); fileReader.onload = () => { const byteArray = new Uint8Array(fileReader.result); resolve(byteArray); }; fileReader.readAsArrayBuffer(ROM); }); return fileReaderByteArray; }; // Function to parse and find the gb files within an archive const parseByteArrayAsZip = async byteArray => { // Parse the zip using UZIP const unzipObject = await uzip.parse(byteArray); // Find the ROM in the output let foundROM = false; const unzipObjectKeys = Object.keys(unzipObject); unzipObjectKeys.some(key => { const lowercaseKey = key.toLowerCase(); if (lowercaseKey.includes('.gb') || lowercaseKey.includes('.gbc') || lowercaseKey.includes('.bin')) { foundROM = unzipObject[key]; return true; } return false; }); if (!foundROM) { throw new Error('Could not find a ROM in zip...'); } return foundROM; };