this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #1912 from tranxuanthang/main

Refactor and improve browser versions (tic-html, export stubs, webapp)

authored by

Vadim Grigoruk and committed by
GitHub
cb6a98d1 f877c5de

+266 -179
+13 -7
.github/workflows/build.yml
··· 571 571 cd build 572 572 emcmake cmake -DBUILD_SDLGPU=On -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DBUILD_STUB=On .. 573 573 cmake --build . --config $BUILD_TYPE --parallel 574 - cp html/export.html bin/index.html 574 + mkdir bin/html bin/html-export 575 + cp html-export/index.html bin/html-export/index.html 576 + cp bin/tic80*.js bin/html-export/ 577 + cp bin/tic80*.wasm bin/html-export/ 578 + cp html/index.html bin/html/index.html 579 + cp bin/tic80.js bin/html/tic80.js 580 + cp bin/tic80.wasm bin/html/tic80.wasm 575 581 cp bin/tic80.js webapp/tic80.js 576 582 cp bin/tic80.wasm webapp/tic80.wasm 577 583 ··· 580 586 with: 581 587 name: "tic80-html" 582 588 path: | 583 - build/bin/tic80.js 584 - build/bin/tic80.wasm 585 - build/bin/index.html 589 + build/bin/html/tic80.js 590 + build/bin/html/tic80.wasm 591 + build/bin/html/index.html 586 592 587 593 - name: Deploy WebApp 588 594 uses: actions/upload-artifact@v2 ··· 603 609 with: 604 610 name: "tic80-html-stub" 605 611 path: | 606 - build/bin/tic80*.js 607 - build/bin/tic80*.wasm 608 - build/bin/index.html 612 + build/bin/html-export/tic80*.js 613 + build/bin/html-export/tic80*.wasm 614 + build/bin/html-export/index.html 609 615 610 616 # === Export === 611 617 export:
+2 -2
CMakeLists.txt
··· 1020 1020 endif() 1021 1021 1022 1022 if(EMSCRIPTEN) 1023 - set_target_properties(tic80 PROPERTIES LINK_FLAGS "-s WASM=1 -s USE_SDL=2 -s ALLOW_MEMORY_GROWTH=1 -s FETCH=1 --pre-js ${CMAKE_SOURCE_DIR}/build/html/prejs.js -lidbfs.js") 1023 + set_target_properties(tic80 PROPERTIES LINK_FLAGS "-s WASM=1 -s USE_SDL=2 -s ALLOW_MEMORY_GROWTH=1 -s FETCH=1 -s EXPORT_ES6=1 -s MODULARIZE=1 -s ENVIRONMENT=web -s EXPORT_NAME=createModule -s EXTRA_EXPORTED_RUNTIME_METHODS=['ENV'] -lidbfs.js") 1024 1024 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s USE_SDL=2") 1025 1025 1026 1026 if(CMAKE_BUILD_TYPE STREQUAL "Debug") ··· 1173 1173 endif() 1174 1174 1175 1175 if(EMSCRIPTEN) 1176 - set_target_properties(tic80${SCRIPT} PROPERTIES LINK_FLAGS "-s WASM=1 -s USE_SDL=2 -s ALLOW_MEMORY_GROWTH=1 -s FETCH=1 -lidbfs.js") 1176 + set_target_properties(tic80${SCRIPT} PROPERTIES LINK_FLAGS "-s WASM=1 -s USE_SDL=2 -s ALLOW_MEMORY_GROWTH=1 -s FETCH=1 -s EXPORT_ES6=1 -s MODULARIZE=1 -s ENVIRONMENT=web -s EXPORT_NAME=createModule -s EXTRA_EXPORTED_RUNTIME_METHODS=['ENV'] -lidbfs.js") 1177 1177 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s USE_SDL=2") 1178 1178 1179 1179 if(CMAKE_BUILD_TYPE STREQUAL "Debug")
+96
build/html-export/index.html
··· 1 + <!DOCTYPE html> 2 + <html lang="en"> 3 + <head> 4 + <meta charset="utf-8"> 5 + <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 + <meta name="viewport" content="width=device-width, initial-scale=1"> 7 + <title>TIC-80 tiny computer</title> 8 + <style> 9 + body { 10 + margin:0; padding:0; background: #000; display: flex; justify-content: center; align-items: center; height: 100vh; 11 + } 12 + 13 + .tic80-container { 14 + width: 100%; padding-top: 56.66%; position: relative; 15 + } 16 + 17 + .tic80-canvas { 18 + position: absolute; top: 0; left:0; width: 100%; height: 100%; 19 + } 20 + 21 + .tic80-play { 22 + position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 1; background: #1a1c2c; color: #fff; display: flex; justify-content: center; align-items: center; image-rendering: pixelated; cursor: pointer; 23 + } 24 + </style> 25 + </head> 26 + <body> 27 + <div class="tic80-container"> 28 + <canvas class="tic80-canvas" id="canvas" oncontextmenu="event.preventDefault()" tabindex="1"></canvas> 29 + <div class="tic80-play" id="tic80-play"> 30 + <img 31 + src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAF9JREFUOE+d0jsOACAIA1B6/0NjHDB+UFtcnPpC0sLd3cwMAPqvPgQQQRU6ABW6Aiz0BX4QDdwgGdihMjCgvUZlB73y0gXzViQgGxkFvNb5BJhZpwATTFtQggtQCQbQAJ4FQA3PbK2EAAAAAElFTkSuQmCC" 32 + alt="Play" 33 + width="64" height="64" 34 + > 35 + </div> 36 + </div> 37 + 38 + <script type="module"> 39 + import startTic80 from './tic80.js' 40 + 41 + const initialize = () => { 42 + const canvasSelector = '#canvas' 43 + const canvasElement = document.querySelector(canvasSelector) 44 + const playElement = document.getElementById('tic80-play') 45 + 46 + const options = { 47 + canvas: canvasElement, 48 + 49 + arguments: ['cart.tic'], 50 + 51 + saveAs (blob, filename) { 52 + const url = URL.createObjectURL(blob) 53 + 54 + const link = document.createElement('a') 55 + link.href = url 56 + link.download = filename 57 + 58 + link.click() 59 + }, 60 + 61 + showAddPopup (callback) { 62 + callback(null, null) 63 + var input = document.createElement('input') 64 + input.type = 'file' 65 + input.click() 66 + input.addEventListener('change', (event) => { 67 + const file = event.target.files[0] 68 + if (file) { 69 + var reader = new FileReader 70 + reader.onload = function(event) { 71 + var rom = new Uint8Array(event.target.result) 72 + callback(file.name, rom) 73 + } 74 + reader.readAsArrayBuffer(file) 75 + } 76 + }) 77 + }, 78 + 79 + preRun: [ 80 + function (module) { 81 + module.ENV.SDL_EMSCRIPTEN_KEYBOARD_ELEMENT = canvasSelector 82 + } 83 + ] 84 + } 85 + 86 + playElement.addEventListener('click', () => { 87 + playElement.style.display = 'none' 88 + canvasElement.focus() 89 + startTic80(options) 90 + }) 91 + } 92 + 93 + window.addEventListener('DOMContentLoaded', initialize) 94 + </script> 95 + </body> 96 + </html>
-57
build/html/export.html
··· 1 - <!DOCTYPE html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="utf-8"> 5 - <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 - <meta name="viewport" content="width=device-width, initial-scale=1"> 7 - 8 - <title>TIC-80 tiny computer</title> 9 - 10 - <style type="text/css"> 11 - #game-frame > div { font-size: 44px; font-family: monospace; font-weight: bold;} 12 - 13 - /* You can set custom dimensions here */ 14 - .game { width: 100vw; height: 100vh; } 15 - 16 - /* Uncomment to remove the frame on top of the canvas and start the game directly */ 17 - /* #game-frame { display: none; } */ 18 - </style> 19 - </head> 20 - <body style="margin:0; padding:0;"> 21 - 22 - <div class="game" style="margin: 0; position: relative; background: #1a1c2c;"> 23 - 24 - <div id="game-frame" style="cursor: pointer; position: absolute; margin: 0 auto; opacity: 1; background: #1a1c2c; width: 100%; height: 100%;"> 25 - <div style="text-align: center; color: white; display: flex; justify-content: center; align-items: center; width: 100%; height: 100%;"> 26 - <p style="margin: 0;">- CLICK TO PLAY -</p> 27 - </div> 28 - 29 - </div> 30 - 31 - <canvas style="width: 100%; height: 100%; margin: 0 auto; display: block; image-rendering: pixelated;" id="canvas" oncontextmenu="event.preventDefault()" onmousedown="window.focus()"></canvas> 32 - </div> 33 - 34 - <script type="text/javascript"> 35 - var Module = {canvas: document.getElementById('canvas'), arguments:['cart.tic']} 36 - 37 - const gameFrame = document.getElementById('game-frame') 38 - const displayStyle = window.getComputedStyle(gameFrame).display; 39 - 40 - if (displayStyle === 'none') 41 - { 42 - let scriptTag = document.createElement('script'), // create a script tag 43 - firstScriptTag = document.getElementsByTagName('script')[0]; // find the first script tag in the document 44 - scriptTag.src = 'tic80.js'; // set the source of the script to your script 45 - firstScriptTag.parentNode.insertBefore(scriptTag, firstScriptTag); // append the script to the DOM 46 - } else { 47 - gameFrame.addEventListener('click', function() { 48 - let scriptTag = document.createElement('script'), // create a script tag 49 - firstScriptTag = document.getElementsByTagName('script')[0]; // find the first script tag in the document 50 - scriptTag.src = 'tic80.js'; // set the source of the script to your script 51 - firstScriptTag.parentNode.insertBefore(scriptTag, firstScriptTag); // append the script to the DOM 52 - this.remove() 53 - }); 54 - } 55 - </script> 56 - </body> 57 - </html>
+80 -45
build/html/index.html
··· 1 1 <!DOCTYPE html> 2 2 <html lang="en"> 3 - <head> 4 - <meta charset="utf-8"> 5 - <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 - <meta name="viewport" content="width=device-width, initial-scale=1"> 3 + <head> 4 + <meta charset="utf-8"> 5 + <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 + <meta name="viewport" content="width=device-width, initial-scale=1"> 7 + <title>TIC-80 tiny computer</title> 8 + <style> 9 + body { 10 + margin:0; padding:0; background: #000; display: flex; justify-content: center; align-items: center; height: 100vh; 11 + } 7 12 8 - <title>TIC-80 tiny computer</title> 13 + .tic80-container { 14 + width: 100%; padding-top: 56.66%; position: relative; 15 + } 16 + 17 + .tic80-canvas { 18 + position: absolute; top: 0; left:0; width: 100%; height: 100%; 19 + } 20 + 21 + .tic80-play { 22 + position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 1; background: #1a1c2c; color: #fff; display: flex; justify-content: center; align-items: center; image-rendering: pixelated; cursor: pointer; 23 + } 24 + </style> 25 + </head> 26 + <body> 27 + <div class="tic80-container"> 28 + <canvas class="tic80-canvas" id="canvas" oncontextmenu="event.preventDefault()" tabindex="1"></canvas> 29 + <div class="tic80-play" id="tic80-play"> 30 + <img 31 + src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAF9JREFUOE+d0jsOACAIA1B6/0NjHDB+UFtcnPpC0sLd3cwMAPqvPgQQQRU6ABW6Aiz0BX4QDdwgGdihMjCgvUZlB73y0gXzViQgGxkFvNb5BJhZpwATTFtQggtQCQbQAJ4FQA3PbK2EAAAAAElFTkSuQmCC" 32 + alt="Play" 33 + width="64" height="64" 34 + > 35 + </div> 36 + </div> 9 37 10 - <style type="text/css"> 11 - .modal{display:none;position:fixed;z-index:1;padding-top:100px;left:0;top:0;width:100%;height:100%;overflow:auto;background-color:#000;background-color:rgba(0,0,0,.4)} 12 - .modal-content{color: #333c57;position:relative;background-color:#fefefe;margin:auto;padding:2px 16px;border:1px solid #888;width:500px;box-shadow:0 4px 8px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.19);-webkit-animation-name:animatetop;-webkit-animation-duration:.4s;animation-name:animatetop;animation-duration:.4s}@keyframes animatetop{from{top:-300px;opacity:0}to{top:0;opacity:1}} 13 - .close{color:#000;float:right;font-size:28px;font-weight:700} 14 - .close:focus, 15 - .close:hover{color:#000;text-decoration:none;cursor:pointer} 16 - 17 - #game-frame > div { font-size: 44px; font-family: monospace; font-weight: bold;} 38 + <script type="module"> 39 + import startTic80 from './tic80.js' 18 40 19 - /* You can set custom dimensions here */ 20 - .game { width: 100vw; height: 100vh; } 21 - </style> 22 - </head> 23 - <body style="margin:0; padding:0;"> 41 + const initialize = () => { 42 + const canvasSelector = '#canvas' 43 + const canvasElement = document.querySelector(canvasSelector) 44 + const playElement = document.getElementById('tic80-play') 24 45 25 - <div class="game" style="margin: 0; position: relative; background: #1a1c2c;"> 46 + const options = { 47 + canvas: canvasElement, 26 48 27 - <div id="game-frame" style="cursor: pointer; position: absolute; margin: 0 auto; opacity: 1; background: #1a1c2c; width: 100%; height: 100%;"> 28 - <div style="text-align: center; color: white; display: flex; justify-content: center; align-items: center; width: 100%; height: 100%;"> 29 - <p style="margin: 0;">- CLICK TO PLAY -</p> 30 - </div> 49 + saveAs (blob, filename) { 50 + const url = URL.createObjectURL(blob) 31 51 32 - </div> 52 + const link = document.createElement('a') 53 + link.href = url 54 + link.download = filename 33 55 34 - <canvas style="width: 100%; height: 100%; margin: 0 auto; display: block; image-rendering: pixelated;" id="canvas" oncontextmenu="event.preventDefault()" onmousedown="window.focus()"></canvas> 35 - </div> 56 + link.click() 57 + }, 36 58 37 - <div id="add-modal" class="modal"> 38 - <div class="modal-content"> 39 - <span class="close">&times</span> 40 - <p>Select a file to add to the computer</p> 41 - <p><input type="file" id="upload-input"></input></p> 42 - </div> 43 - </div> 59 + showAddPopup (callback) { 60 + callback(null, null) 61 + var input = document.createElement('input') 62 + input.type = 'file' 63 + input.click() 64 + input.addEventListener('change', (event) => { 65 + const file = event.target.files[0] 66 + if (file) { 67 + var reader = new FileReader 68 + reader.onload = function(event) { 69 + var rom = new Uint8Array(event.target.result) 70 + callback(file.name, rom) 71 + } 72 + reader.readAsArrayBuffer(file) 73 + } 74 + }) 75 + }, 44 76 45 - <script type="text/javascript"> 46 - var Module = {canvas: document.getElementById('canvas')} 77 + preRun: [ 78 + function (module) { 79 + module.ENV.SDL_EMSCRIPTEN_KEYBOARD_ELEMENT = canvasSelector 80 + } 81 + ] 82 + } 47 83 48 - const gameFrame = document.getElementById('game-frame') 84 + playElement.addEventListener('click', () => { 85 + playElement.style.display = 'none' 86 + canvasElement.focus() 87 + startTic80(options) 88 + }) 89 + } 49 90 50 - gameFrame.addEventListener('click', function() { 51 - let scriptTag = document.createElement('script'), // create a script tag 52 - firstScriptTag = document.getElementsByTagName('script')[0]; // find the first script tag in the document 53 - scriptTag.src = 'tic80.js'; // set the source of the script to your script 54 - firstScriptTag.parentNode.insertBefore(scriptTag, firstScriptTag); // append the script to the DOM 55 - this.remove() 56 - }); 57 - </script> 58 - </body> 91 + window.addEventListener('DOMContentLoaded', initialize) 92 + </script> 93 + </body> 59 94 </html>
-32
build/html/prejs.js
··· 1 - Module.saveAs = Module.saveAs||function(e){"use strict";if(typeof e==="undefined"||typeof navigator!=="undefined"&&/MSIE [1-9]\./.test(navigator.userAgent)){return}var t=e.document,n=function(){return e.URL||e.webkitURL||e},r=t.createElementNS("http://www.w3.org/1999/xhtml","a"),o="download"in r,i=function(e){var t=new MouseEvent("click");e.dispatchEvent(t)},a=/constructor/i.test(e.HTMLElement),f=/CriOS\/[\d]+/.test(navigator.userAgent),u=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},d="application/octet-stream",s=1e3*40,c=function(e){var t=function(){if(typeof e==="string"){n().revokeObjectURL(e)}else{e.remove()}};setTimeout(t,s)},l=function(e,t,n){t=[].concat(t);var r=t.length;while(r--){var o=e["on"+t[r]];if(typeof o==="function"){try{o.call(e,n||e)}catch(i){u(i)}}}},p=function(e){if(/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)){return new Blob([String.fromCharCode(65279),e],{type:e.type})}return e},v=function(t,u,s){if(!s){t=p(t)}var v=this,w=t.type,m=w===d,y,h=function(){l(v,"writestart progress write writeend".split(" "))},S=function(){if((f||m&&a)&&e.FileReader){var r=new FileReader;r.onloadend=function(){var t=f?r.result:r.result.replace(/^data:[^;]*;/,"data:attachment/file;");var n=e.open(t,"_blank");if(!n)e.location.href=t;t=undefined;v.readyState=v.DONE;h()};r.readAsDataURL(t);v.readyState=v.INIT;return}if(!y){y=n().createObjectURL(t)}if(m){e.location.href=y}else{var o=e.open(y,"_blank");if(!o){e.location.href=y}}v.readyState=v.DONE;h();c(y)};v.readyState=v.INIT;if(o){y=n().createObjectURL(t);setTimeout(function(){r.href=y;r.download=u;i(r);h();c(y);v.readyState=v.DONE});return}S()},w=v.prototype,m=function(e,t,n){return new v(e,t||e.name||"download",n)};if(typeof navigator!=="undefined"&&navigator.msSaveOrOpenBlob){return function(e,t,n){t=t||e.name||"download";if(!n){e=p(e)}return navigator.msSaveOrOpenBlob(e,t)}}w.abort=function(){};w.readyState=w.INIT=0;w.WRITING=1;w.DONE=2;w.error=w.onwritestart=w.onprogress=w.onwrite=w.onabort=w.onerror=w.onwriteend=null;return m}(typeof self!=="undefined"&&self||typeof window!=="undefined"&&window||this.content);if(typeof module!=="undefined"&&module.exports){module.exports.saveAs=saveAs}else if(typeof define!=="undefined"&&define!==null&&define.amd!==null){define([],function(){return saveAs})}; 2 - Module.showAddPopup = function(callback) 3 - { 4 - var modal = document.getElementById('add-modal'); 5 - var span = document.getElementsByClassName("close")[0]; 6 - modal.style.display = "block"; 7 - function cancel(){modal.style.display = "none"; callback(null, null);} 8 - span.onclick = cancel; 9 - window.onclick = function(event) {if (event.target == modal) cancel();} 10 - 11 - var uploadInput = document.getElementById('upload-input'); 12 - uploadInput.onchange = function() 13 - { 14 - var file = uploadInput.files[0]; 15 - 16 - if(!file) return; 17 - 18 - var reader = new FileReader(); 19 - 20 - reader.onload = function(event) 21 - { 22 - var rom = new Uint8Array(event.target.result); 23 - 24 - callback(file.name, rom); 25 - 26 - uploadInput.value = ""; 27 - modal.style.display = "none"; 28 - }; 29 - 30 - reader.readAsArrayBuffer(file); 31 - }; 32 - };
+75 -36
build/webapp/index.html
··· 1 1 <!DOCTYPE html> 2 2 <html lang="en"> 3 - <head> 4 - <meta charset="utf-8"> 5 - <meta name="viewport" content="width=device-width, initial-scale=1"> 6 - <meta name="theme-color" content="#f4f4f4"/> 3 + <head> 4 + <meta charset="utf-8"> 5 + <meta name="viewport" content="width=device-width, initial-scale=1"> 6 + <meta name="theme-color" content="#f4f4f4"/> 7 7 8 - <link rel="manifest" href="tic80.webmanifest"> 9 - <link rel="apple-touch-icon" sizes="180x180" href="tic80-180.png"> 10 - <link rel="apple-touch-icon" sizes="192x192" href="tic80-192.png"> 11 - <link rel="apple-touch-icon" sizes="512x512" href="tic80-512.png"> 8 + <link rel="manifest" href="tic80.webmanifest"> 9 + <link rel="apple-touch-icon" sizes="180x180" href="tic80-180.png"> 10 + <link rel="apple-touch-icon" sizes="192x192" href="tic80-192.png"> 11 + <link rel="apple-touch-icon" sizes="512x512" href="tic80-512.png"> 12 + <title>TIC-80</title> 13 + <style> 14 + body { 15 + margin:0; padding:0; background: #000; display: flex; justify-content: center; align-items: center; height: 100vh; 16 + } 12 17 13 - <title>TIC-80</title> 18 + .tic80-container { 19 + width: 100%; padding-top: 56.66%; position: relative; 20 + } 14 21 15 - <style type="text/css"> 16 - #game-frame > div { font-size: 44px; font-family: monospace; font-weight: bold;} 17 - .game { width: 100vw; height: 100vh; } 18 - </style> 19 - </head> 20 - <body style="margin:0; padding:0;"> 22 + .tic80-canvas { 23 + position: absolute; top: 0; left:0; width: 100%; height: 100%; 24 + } 25 + </style> 26 + </head> 27 + <body> 28 + <div class="tic80-container"> 29 + <canvas class="tic80-canvas" id="canvas" oncontextmenu="event.preventDefault()" tabindex="1"></canvas> 30 + </div> 31 + 32 + <script type="module"> 33 + import startTic80 from './tic80.js' 34 + 35 + navigator.serviceWorker.register('serviceworker.js') 36 + 37 + const initialize = () => { 38 + const canvasSelector = '#canvas' 39 + const canvasElement = document.querySelector(canvasSelector) 40 + 41 + const options = { 42 + canvas: document.getElementById('canvas'), 43 + 44 + saveAs (blob, filename) { 45 + const url = URL.createObjectURL(blob) 46 + 47 + const link = document.createElement('a') 48 + link.href = url 49 + link.download = filename 21 50 22 - <div class="game" style="margin: 0; position: relative; background: #1a1c2c;"> 23 - <div id="game-frame" style="position: absolute; margin: 0 auto; opacity: 1; background: #1a1c2c; width: 100%; height: 100%;"> 24 - <div style="display: flex; justify-content: center; align-items: center; width: 100%; height: 100%;"> 25 - <img src="tic80-512.png"></img> 26 - </div> 27 - </div> 28 - <canvas style="width: 100%; height: 100%; margin: 0 auto; display: block; image-rendering: pixelated;" id="canvas" oncontextmenu="event.preventDefault()" onmousedown="window.focus()"></canvas> 29 - </div> 51 + link.click() 52 + }, 30 53 31 - <script type="text/javascript"> 32 - var Module = { 33 - canvas: document.getElementById('canvas') 34 - } 54 + showAddPopup (callback) { 55 + callback(null, null) 56 + var input = document.createElement('input') 57 + input.type = 'file' 58 + input.click() 59 + input.addEventListener('change', (event) => { 60 + const file = event.target.files[0] 61 + if (file) { 62 + var reader = new FileReader 63 + reader.onload = function(event) { 64 + var rom = new Uint8Array(event.target.result) 65 + callback(file.name, rom) 66 + } 67 + reader.readAsArrayBuffer(file) 68 + } 69 + }) 70 + }, 35 71 36 - navigator.serviceWorker.register('serviceworker.js'); 72 + preRun: [ 73 + function (module) { 74 + module.ENV.SDL_EMSCRIPTEN_KEYBOARD_ELEMENT = canvasSelector 75 + } 76 + ] 77 + } 37 78 38 - setTimeout(function() { 39 - const scriptTag = document.createElement('script'); 40 - scriptTag.src = 'tic80.js'; 79 + canvasElement.focus() 80 + startTic80(options) 81 + } 41 82 42 - document.body.appendChild(scriptTag); 43 - document.getElementById('game-frame').remove() 44 - }, 2000); 45 - </script> 46 - </body> 83 + window.addEventListener('DOMContentLoaded', initialize) 84 + </script> 85 + </body> 47 86 </html>