From 2a17e82f9dbf6260ef3533157630a12ecfd1a8fe Mon Sep 17 00:00:00 2001 From: Andrei Alexeyev Date: Wed, 23 Oct 2024 18:04:47 +0200 Subject: [PATCH] emscripten: modularize js/wasm, split from html shell --- emscripten/meson.build | 7 ++ emscripten/preamble.js | 145 ++++--------------------------------- emscripten/shell.html | 105 ++++++++++++++++++++++++++- src/meson.build | 17 +++-- src/vfs/emscripten_fetch.c | 2 + 5 files changed, 135 insertions(+), 141 deletions(-) diff --git a/emscripten/meson.build b/emscripten/meson.build index 9d9a9540..10ab6875 100644 --- a/emscripten/meson.build +++ b/emscripten/meson.build @@ -1,5 +1,6 @@ em_preamble = files('preamble.js') +em_postamble = files('postamble.js') em_shell = files('shell.html') if host_machine.system() == 'emscripten' @@ -12,4 +13,10 @@ if host_machine.system() == 'emscripten' install_dir : bindir, install_tag : 'runtime', ) + install_data( + em_shell, + rename : 'taisei.html', + install_dir : bindir, + install_tag : 'runtime', + ) endif diff --git a/emscripten/preamble.js b/emscripten/preamble.js index 41d4570d..da24e4c9 100644 --- a/emscripten/preamble.js +++ b/emscripten/preamble.js @@ -1,118 +1,26 @@ -function E(id) { return document.getElementById(id); } +Module['totalDependencies'] = 0; +Module['monitorRunDependencies'] = function(left) { + Module['totalDependencies'] = Math.max(Module['totalDependencies'], left); + Module['setStatus']( + left ? 'Preparing… (' + (Module['totalDependencies']-left) + '/' + Module['totalDependencies'] + ')' + : 'All downloads complete.'); +}; -var statusElement = E('status'); -var progressElement = E('progress'); -var spinnerElement = E('spinner'); -var canvasElement = E('canvas'); -var canvasContainerElement = E('canvasContainer'); -var logToggleElement = E('logToggle'); -var logToggleContainerElement = E('logToggleContainer'); -var logContainerElement = E('logContainer'); -var logOutputElement = E('output'); -var dlMessage = statusElement.innerText; -logToggleElement.checked = false; - -window['toggleLog'] = function toggleLog() { - logContainerElement.hidden = !logToggleElement.checked; - logOutputElement.scrollTop = logOutputElement.scrollHeight; -} - -var glContext = canvasElement.getContext('webgl2', { - 'alpha' : false, - 'antialias' : false, - 'depth' : false, - 'powerPreference' : 'high-performance', - 'premultipliedAlpha' : true, - 'preserveDrawingBuffer' : false, - 'stencil' : false, -}); - -if(!glContext) { - throw "Could not create a WebGL 2 context"; -} - -// glContext = WebGLDebugUtils.makeDebugContext(glContext); +Module['initFilesystem'] = function() { + FS.mkdir('/persistent'); + FS.mount(IDBFS, {}, '/persistent'); +}; // WebGL extensions have to be explicitly enabled to make the functionality available. // Note that Emscripten will always report all *supported* extensions in GL_EXTENSIONS, // regardless of whether they are enabled or not. This is non-conformant from the GLES // perspective. The easiest way to fix that is to enable all of them here. +var glContext = Module['preinitializedWebGLContext']; glContext.getSupportedExtensions().forEach(function(ext) { glContext.getExtension(ext); }); -canvasElement.addEventListener("webglcontextlost", function(e) { - alert('WebGL context lost. You will need to reload the page.'); - e.preventDefault(); -}, false); - -logOutputElement.value = ''; // clear browser cache - -Module = { - 'preRun': [function() { - ENV["TAISEI_NOASYNC"] = "1"; - ENV["TAISEI_NOUNLOAD"] = "1"; - ENV["TAISEI_PREFER_SDL_VIDEODRIVERS"] = "emscripten"; - ENV["TAISEI_RENDERER"] = "gles30"; - - FS.mkdir('/persistent'); - FS.mount(IDBFS, {}, '/persistent'); - }], - 'postRun': [], - 'onFirstFrame': function() { - canvasContainerElement.hidden = false; - logToggleContainerElement.style.display = "inline-block"; - Module['setStatus']('', true); - }, - 'print': function(text) { - if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' '); - console.log(text); - logOutputElement.value += text + "\n"; - logOutputElement.scrollTop = logOutputElement.scrollHeight; // focus on bottom - }, - 'printErr': function(text) { - if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' '); - console.error(text); - }, - 'canvas': canvasElement, - 'preinitializedWebGLContext': glContext, - 'setStatus': function(text, force) { - var ss = Module['setStatus']; - if (!text && !force) return; - if (!ss.last) ss.last = { time: Date.now(), text: '' }; - if (text === ss.last.text) return; - var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/); - var now = Date.now(); - if (m && now - ss.last.time < 30) return; // if this is a progress update, skip it if too soon - ss.last.time = now; - ss.last.text = text; - if (m) { - text = m[1]; - progressElement.value = parseInt(m[2])*100; - progressElement.max = parseInt(m[4])*100; - progressElement.hidden = false; - spinnerElement.hidden = !canvasElement.hidden; - } else { - progressElement.value = null; - progressElement.max = null; - progressElement.hidden = true; - if (!text) spinnerElement.hidden = true; - } - statusElement.innerText = text.replace(/^Downloading(?: data)?\.\.\./, dlMessage).replace('...', '…'); - console.log("[STATUS] " + statusElement.innerText); - }, - 'totalDependencies': 0, - 'monitorRunDependencies': function(left) { - Module['totalDependencies'] = Math.max(Module['totalDependencies'], left); - Module['setStatus'](left ? 'Preparing… (' + (Module['totalDependencies']-left) + '/' + Module['totalDependencies'] + ')' : 'All downloads complete.'); - } -}; - -window.onerror = function(error) { - Module['setStatus']('Error: ' + error); -}; - function SyncFS(is_load, ccptr) { FS.syncfs(is_load, function(err) { Module['ccall']( @@ -124,35 +32,8 @@ function SyncFS(is_load, ccptr) { }); } -(function() { - // Try to enable audio playback as soon as possible. - // It must happen inside an input event handler. - // https://github.com/emscripten-core/emscripten/issues/6511 - // https://github.com/emscripten-ports/SDL2/issues/57 - - function resumeAudio() { - var sdl2 = Module['SDL2']; - - if(typeof sdl2 === 'undefined') { - return; - } - - if(sdl2.audioContext.state == 'suspended') { - sdl2.audioContext.resume(); - } - - if(sdl2.audioContext.state == 'running') { - canvasElement.removeEventListener('click', resumeAudio); - document.removeEventListener('keydown', resumeAudio); - } - } - - canvasElement.addEventListener('click', resumeAudio); - document.addEventListener('keydown', resumeAudio); -})(); - if(typeof dynCall === 'undefined') { - dynCall = window['dynCall'] = Module['dynCall'] = function dynCall(sig, ptr, args) { + dynCall = Module['dynCall'] = function dynCall(sig, ptr, args) { return wasmTable.get(ptr).apply(this, args); } }; diff --git a/emscripten/shell.html b/emscripten/shell.html index db9210aa..c29d5ef4 100644 --- a/emscripten/shell.html +++ b/emscripten/shell.html @@ -5,6 +5,7 @@ Taisei Project — Web version (Experimental!) +