From b34ff18a60c461f129eb0749930a3e88870572d8 Mon Sep 17 00:00:00 2001 From: Dennis Ranke Date: Tue, 2 Nov 2021 23:27:46 +0100 Subject: [PATCH] add file input to load cart from filesystem --- web/src/base.wasm | Bin 102 -> 91 bytes web/src/index.html | 1 + web/src/main.js | 154 +++++++++++++++++++++++++++-------------- web/src/uw8loader.wasm | Bin 385 -> 382 bytes 4 files changed, 102 insertions(+), 53 deletions(-) diff --git a/web/src/base.wasm b/web/src/base.wasm index f316a6a3722fa351b02d97c065597839cf0274ad..2182ab7ad5d967a94fc804140b415635231bf78c 100644 GIT binary patch literal 91 zcmZQbEY4+QU|?WmWlUhKXJF!CWG*eYU@l6`Wny4rW@2PuXJ=$C$xLQo;L>N*Wn`>p pc2HncV01jdl&`?x$d#J~X6F`LF;oCqj9E&Ijtvd09=r_P+yIY@4|f0n delta 86 zcmaz}(_ly}&Shj^U|?inOkiMOl3-#kEw^AUO3Ylr7?imNjyFgPAy h%2#G^C5s&}? diff --git a/web/src/index.html b/web/src/index.html index 51fddd7..b3411ae 100644 --- a/web/src/index.html +++ b/web/src/index.html @@ -7,6 +7,7 @@
+ diff --git a/web/src/main.js b/web/src/main.js index 3d045ac..f88dae5 100644 --- a/web/src/main.js +++ b/web/src/main.js @@ -8,6 +8,14 @@ async function loadWasm(url, imports) { return new WebAssembly.Instance(compiled_module, imports); } +function setMessage(size, error) { + let html = size ? `${size} bytes` : 'Insert cart'; + if(error) { + html += ` - ${error.replaceAll('<', '<')}` + } + document.getElementById('message').innerHTML = html; +} + let cancelFunction; async function runModule(data) { @@ -16,69 +24,99 @@ async function runModule(data) { cancelFunction = null; } - document.getElementById('message').innerText = '' + data.byteLength + ' bytes'; + let cartridgeSize = data.byteLength; - let loaderImport = { - uw8: { - ram: new WebAssembly.Memory({ initial: 8 }) - } - }; - let loadMem = loaderImport.uw8.ram.buffer; - let loader = await loadWasm(loaderUrl, loaderImport); - - new Uint8Array(loadMem).set(new Uint8Array(data)); - - let baseModule = await (await fetch(baseUrl)).arrayBuffer(); - new Uint8Array(loadMem).set(new Uint8Array(baseModule), data.byteLength); - - let destOffset = data.byteLength + baseModule.byteLength; - let endOffset = loader.exports.load_uw8(0, data.byteLength, data.byteLength, destOffset); - - data = new ArrayBuffer(endOffset - destOffset); - new Uint8Array(data).set(new Uint8Array(loadMem).slice(destOffset, endOffset)); - - let importObject = { - uw8: { - ram: new WebAssembly.Memory({ initial: 8, maximum: 8 }), - time: new WebAssembly.Global({value: 'i32', mutable: true}, 0), - } - }; - - let instance = new WebAssembly.Instance(await WebAssembly.compile(data), importObject); - - let canvasCtx = document.getElementById('screen').getContext('2d'); - let imageData = canvasCtx.createImageData(320, 256); - - let buffer = imageData.data; - for(let i = 0; i < 320*256; ++i) { - buffer[i * 4 + 3] = 255; + setMessage(cartridgeSize); + if(cartridgeSize == 0) { + return; } - let startTime = Date.now(); + let dataU8Array = new Uint8Array(data); - let keepRunning = true; - cancelFunction = () => keepRunning = false; - - function mainloop() { - if(!keepRunning) { - return; + let newURL = window.location.pathname; + if(cartridgeSize <= 1024) { + let dataString = ''; + for(let byte of dataU8Array) { + dataString += String.fromCharCode(byte); } - importObject.uw8.time.value = Date.now() - startTime; + newURL += '#' + btoa(dataString); + } + if(newURL != window.location.href) { + history.replaceState(null, null, newURL); + history.pushState(null, null, newURL); + } - instance.exports.tic(); + try { - let framebuffer = new Uint8Array(importObject.uw8.ram.buffer.slice(120, 120 + 320*256)); + let loaderImport = { + uw8: { + ram: new WebAssembly.Memory({ initial: 8 }) + } + }; + let loadMem = loaderImport.uw8.ram.buffer; + let loader = await loadWasm(loaderUrl, loaderImport); + + let baseModule = await (await fetch(baseUrl)).arrayBuffer(); + + if(dataU8Array[0] != 0) { + new Uint8Array(loadMem).set(dataU8Array); + new Uint8Array(loadMem).set(new Uint8Array(baseModule), data.byteLength); + + let destOffset = data.byteLength + baseModule.byteLength; + let endOffset = loader.exports.load_uw8(0, data.byteLength, data.byteLength, destOffset); + + data = new ArrayBuffer(endOffset - destOffset); + new Uint8Array(data).set(new Uint8Array(loadMem).slice(destOffset, endOffset)); + } + + let importObject = { + uw8: { + ram: new WebAssembly.Memory({ initial: 8, maximum: 8 }), + } + }; + + let instance = new WebAssembly.Instance(await WebAssembly.compile(data), importObject); + + let canvasCtx = document.getElementById('screen').getContext('2d'); + let imageData = canvasCtx.createImageData(320, 256); + + let buffer = imageData.data; for(let i = 0; i < 320*256; ++i) { - buffer[i * 4] = framebuffer[i]; - buffer[i * 4 + 1] = framebuffer[i]; - buffer[i * 4 + 2] = framebuffer[i]; + buffer[i * 4 + 3] = 255; } - canvasCtx.putImageData(imageData, 0, 0); + + let startTime = Date.now(); + + let keepRunning = true; + cancelFunction = () => keepRunning = false; - window.requestAnimationFrame(mainloop); + + function mainloop() { + if(!keepRunning) { + return; + } + + try { + instance.exports.tic(Date.now() - startTime); + + let framebuffer = new Uint8Array(importObject.uw8.ram.buffer.slice(120, 120 + 320*256)); + for(let i = 0; i < 320*256; ++i) { + buffer[i * 4] = framebuffer[i]; + buffer[i * 4 + 1] = framebuffer[i]; + buffer[i * 4 + 2] = framebuffer[i]; + } + canvasCtx.putImageData(imageData, 0, 0); + + window.requestAnimationFrame(mainloop); + } catch(err) { + setMessage(cartridgeSize, err.toString()); + } + } + + mainloop(); + } catch(err) { + setMessage(cartridgeSize, err.toString()); } - - mainloop(); } async function runModuleFromURL(url) { @@ -86,8 +124,18 @@ async function runModuleFromURL(url) { } function runModuleFromHash() { - runModuleFromURL('data:;base64,' + window.location.hash.slice(1)); + let base64Data = window.location.hash.slice(1); + if(base64Data.length > 0) { + runModuleFromURL('data:;base64,' + base64Data); + } } +let fileInput = document.getElementById('cart'); +fileInput.onchange = () => { + if(fileInput.files.length > 0) { + runModuleFromURL(URL.createObjectURL(fileInput.files[0])); + } +}; + window.onhashchange = runModuleFromHash; runModuleFromHash(); \ No newline at end of file diff --git a/web/src/uw8loader.wasm b/web/src/uw8loader.wasm index c66e4ddadb107fc8ebd1996e620ef8c66d286dc0..9b9ac4f338a6ccd48bbe3892d86f0c7f990b027a 100644 GIT binary patch delta 115 zcmZo<{>L=IgJla7%le5vGAzsrELjsXZP{2A*aVoACayE}V^v@RvN*C7feZy8#l*wN z&8@)7?as(jufX8Qn5D?*$e_ps#LUbNKqZX23=B#vj{g}76_`tk6qyv59oe%KnH3np KN++8#`Tzj^;}i%0 delta 118 zcmeyz)W|%+gJnAt%Z7q5NRs|*y#l*wN z&8@)7?a9beufX8Qn5D?*$e_ps#LUbN3XHl842moYj9_t~1{TNv4225JB}Ix%3e1k| LS&Gb)jTn6Z48#-l