diff --git a/web/src/base.wasm b/web/src/base.wasm new file mode 100644 index 0000000..f316a6a Binary files /dev/null and b/web/src/base.wasm differ diff --git a/web/src/index.html b/web/src/index.html index d306344..51fddd7 100644 --- a/web/src/index.html +++ b/web/src/index.html @@ -5,7 +5,8 @@ MicroW8 - + +
diff --git a/web/src/main.js b/web/src/main.js index 832dae4..3d045ac 100644 --- a/web/src/main.js +++ b/web/src/main.js @@ -1,17 +1,50 @@ -import wasmDataUrl from "data-url:./trainride.uw8"; +import loaderUrl from "data-url:./uw8loader.wasm"; +import baseUrl from "data-url:./base.wasm"; -async function main() { - let wasm_module = await (await fetch(wasmDataUrl)).arrayBuffer(); +async function loadWasm(url, imports) { + let wasm_module = await (await fetch(url)).arrayBuffer(); let compiled_module = await WebAssembly.compile(wasm_module); - let import_object = { + return new WebAssembly.Instance(compiled_module, imports); +} + +let cancelFunction; + +async function runModule(data) { + if(cancelFunction) { + cancelFunction(); + cancelFunction = null; + } + + document.getElementById('message').innerText = '' + data.byteLength + ' bytes'; + + 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(compiled_module, import_object); + let instance = new WebAssembly.Instance(await WebAssembly.compile(data), importObject); let canvasCtx = document.getElementById('screen').getContext('2d'); let imageData = canvasCtx.createImageData(320, 256); @@ -23,12 +56,18 @@ async function main() { let startTime = Date.now(); + let keepRunning = true; + cancelFunction = () => keepRunning = false; + function mainloop() { - import_object.uw8.time.value = Date.now() - startTime; + if(!keepRunning) { + return; + } + importObject.uw8.time.value = Date.now() - startTime; instance.exports.tic(); - let framebuffer = new Uint8Array(import_object.uw8.ram.buffer.slice(120, 120 + 320*256)); + 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]; @@ -42,4 +81,13 @@ async function main() { mainloop(); } -main(); \ No newline at end of file +async function runModuleFromURL(url) { + runModule(await (await fetch(url)).arrayBuffer()); +} + +function runModuleFromHash() { + runModuleFromURL('data:;base64,' + window.location.hash.slice(1)); +} + +window.onhashchange = runModuleFromHash; +runModuleFromHash(); \ No newline at end of file diff --git a/web/src/trainride.uw8 b/web/src/trainride.uw8 deleted file mode 100644 index 0d9d59a..0000000 Binary files a/web/src/trainride.uw8 and /dev/null differ diff --git a/web/src/uw8loader.wasm b/web/src/uw8loader.wasm new file mode 100644 index 0000000..c66e4dd Binary files /dev/null and b/web/src/uw8loader.wasm differ