Add the ability to package the web simulator

This commit is contained in:
Romain Goyet
2017-10-20 14:57:39 +02:00
committed by Ecco
parent d0a50c316e
commit 9a41ee8ad9
5 changed files with 230 additions and 166 deletions

View File

@@ -1,5 +1,16 @@
TOOLCHAIN = emscripten
USE_LIBA = 0
EXE = html
EXE = js
OS_WITH_ONBOARDING_APP ?= 0
OS_WITH_SOFTWARE_UPDATE_PROMPT ?= 0
numworks_simulator.zip: LDFLAGS += --memory-init-file 0
numworks_simulator.zip: app.js
@rm -rf $(basename $@)
@mkdir $(basename $@)
@cp app.js $(basename $@)/firmware.js
@cp ion/src/emscripten/background.jpg $(basename $@)/
@cp ion/src/emscripten/simulator.html $(basename $@)/
@echo "ZIP $@"
@zip -r -9 $@ $(basename $@) > /dev/null
@rm -rf $(basename $@)

View File

@@ -1,5 +1,5 @@
CC = emcc
CXX = emcc
LD = emcc
LDFLAGS = -s EXPORTED_FUNCTIONS="['_main', '_IonEventsEmscriptenPushEvent']" -Os --shell-file ion/src/emscripten/shell.html
LDFLAGS = -s EXPORTED_FUNCTIONS="['_main', '_IonEventsEmscriptenPushEvent']" -Os
SIZE = size

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

View File

@@ -1,164 +0,0 @@
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width">
<title>Emscripten-Generated Code</title>
<style>
.buttons a {
display: block;
width: 100px;
height:50px;
}
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
textarea.emscripten { font-family: monospace; width: 80%; }
div.emscripten { text-align: center; }
div.emscripten_border { border: 1px solid black; }
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
canvas.emscripten { border: 0px none; }
.spinner {
height: 50px;
width: 50px;
margin: 0px auto;
-webkit-animation: rotation .8s linear infinite;
-moz-animation: rotation .8s linear infinite;
-o-animation: rotation .8s linear infinite;
animation: rotation 0.8s linear infinite;
border-left: 10px solid rgb(0,150,240);
border-right: 10px solid rgb(0,150,240);
border-bottom: 10px solid rgb(0,150,240);
border-top: 10px solid rgb(100,0,200);
border-radius: 100%;
background-color: rgb(200,100,250);
}
@-webkit-keyframes rotation {
from {-webkit-transform: rotate(0deg);}
to {-webkit-transform: rotate(360deg);}
}
@-moz-keyframes rotation {
from {-moz-transform: rotate(0deg);}
to {-moz-transform: rotate(360deg);}
}
@-o-keyframes rotation {
from {-o-transform: rotate(0deg);}
to {-o-transform: rotate(360deg);}
}
@keyframes rotation {
from {transform: rotate(0deg);}
to {transform: rotate(360deg);}
}
</style>
</head>
<body>
<hr/>
<figure style="overflow:visible;" id="spinner"><div class="spinner"></div><center style="margin-top:0.5em"><strong>emscripten</strong></center></figure>
<div class="emscripten" id="status">Downloading...</div>
<div class="emscripten">
<progress value="0" max="100" id="progress" hidden=1></progress>
</div>
<div class="emscripten_border">
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
</div>
<hr/>
<div class="buttons">
<a href="#" onclick="Module._IonEmscriptenPushEvent(0);">Left</a>
<a href="#" onclick="Module._IonEmscriptenPushEvent(1);">Up</a>
<a href="#" onclick="Module._IonEmscriptenPushEvent(2);">Down</a>
<a href="#" onclick="Module._IonEmscriptenPushEvent(3);">Right</a>
<a href="#" onclick="Module._IonEmscriptenPushEvent(4);">OK</a>
</div>
<div class="emscripten">
<input type="checkbox" id="resize">Resize canvas
<input type="checkbox" id="pointerLock" checked>Lock/hide mouse pointer
&nbsp;&nbsp;&nbsp;
<input type="button" value="Fullscreen" onclick="Module.requestFullScreen(document.getElementById('pointerLock').checked,
document.getElementById('resize').checked)">
</div>
<hr/>
<textarea class="emscripten" id="output" rows="8"></textarea>
<hr>
<script type='text/javascript'>
var statusElement = document.getElementById('status');
var progressElement = document.getElementById('progress');
var spinnerElement = document.getElementById('spinner');
var Module = {
preRun: [],
postRun: [],
print: (function() {
var element = document.getElementById('output');
if (element) element.value = ''; // clear browser cache
return function(text) {
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
// These replacements are necessary if you render to raw HTML
//text = text.replace(/&/g, "&amp;");
//text = text.replace(/</g, "&lt;");
//text = text.replace(/>/g, "&gt;");
//text = text.replace('\n', '<br>', 'g');
console.log(text);
if (element) {
element.value += text + "\n";
element.scrollTop = element.scrollHeight; // focus on bottom
}
};
})(),
printErr: function(text) {
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
if (0) { // XXX disabled for safety typeof dump == 'function') {
dump(text + '\n'); // fast, straight to the real console
} else {
console.error(text);
}
},
canvas: (function() {
var canvas = document.getElementById('canvas');
// As a default initial behavior, pop up an alert when webgl context is lost. To make your
// application robust, you may want to override this behavior before shipping!
// See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
return canvas;
})(),
setStatus: function(text) {
if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' };
if (text === Module.setStatus.text) return;
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
var now = Date.now();
if (m && now - Date.now() < 30) return; // if this is a progress update, skip it if too soon
if (m) {
text = m[1];
progressElement.value = parseInt(m[2])*100;
progressElement.max = parseInt(m[4])*100;
progressElement.hidden = false;
spinnerElement.hidden = false;
} else {
progressElement.value = null;
progressElement.max = null;
progressElement.hidden = true;
if (!text) spinnerElement.hidden = true;
}
statusElement.innerHTML = text;
},
totalDependencies: 0,
monitorRunDependencies: function(left) {
this.totalDependencies = Math.max(this.totalDependencies, left);
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
}
};
Module.setStatus('Downloading...');
window.onerror = function() {
Module.setStatus('Exception thrown, see JavaScript console');
spinnerElement.style.display = 'none';
Module.setStatus = function(text) {
if (text) Module.printErr('[post-exception status] ' + text);
};
};
</script>
{{{ SCRIPT }}}
</body>
</html>

View File

@@ -0,0 +1,217 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>NumWorks graphing calculator</title>
<style>
.keys {
margin-top: 20px;
margin-bottom: 20px; }
.key {
margin-top: 6px;
border: 1px solid #333;
border-radius: 2px;
padding: 2px 3px;
text-align: center;
min-width: 26px;
display: inline-block; }
.calculator {
position: relative;
display: inline-block;
text-align: left; }
.calculator > img {
/* Rely on the img content to set the dimensions */
max-height: 100vh;
max-width: 100%;
display: block; }
.calculator .screen {
position: absolute;
top: 10.3%;
left: 24.25%;
width: 52.1%;
height: 23.2%;
border: 0 none; }
.calculator .keyboard {
position: absolute;
top: 37%;
left: 19%;
width: 63%;
bottom: 14%; }
.calculator .keyboard a {
border-radius: 40%;
display: block;
float: left; }
.calculator .keyboard a:hover {
background-color: rgba(0, 0, 0, 0.1); }
.calculator .keyboard a:active {
background-color: rgba(0, 0, 0, 0.2); }
.calculator .keyboard .nav {
position: absolute;
top: 0;
height: 27%;
width: 100%; }
.calculator .keyboard .nav a {
position: absolute; }
.calculator .keyboard .nav .left {
top: 36%;
left: 3%;
width: 15%;
height: 28%; }
.calculator .keyboard .nav .right {
top: 36%;
left: 17%;
width: 15%;
height: 28%; }
.calculator .keyboard .nav .top {
top: 7%;
left: 12.5%;
width: 10%;
height: 40%; }
.calculator .keyboard .nav .bottom {
top: 53%;
left: 12.5%;
width: 10%;
height: 40%; }
.calculator .keyboard .nav .home {
top: 12%;
left: 42%;
width: 16%;
height: 33%; }
.calculator .keyboard .nav .power {
top: 54%;
left: 42%;
width: 16%;
height: 33%; }
.calculator .keyboard .nav .ok {
top: 30%;
left: 68%;
width: 13%;
height: 38%; }
.calculator .keyboard .nav .back {
top: 30%;
left: 84%;
width: 13%;
height: 38%; }
.calculator .keyboard .functions {
position: absolute;
top: 26.75%;
left: 1%;
width: 98%; }
.calculator .keyboard .functions a {
margin: 1.7% 1%;
width: 14.65%;
height: 0;
padding-top: 10%; }
.calculator .keyboard .digits {
position: absolute;
top: 57%;
left: 0.5%;
width: 98%; }
.calculator .keyboard .digits a {
margin: 1.8% 2%;
width: 16%;
height: 0;
padding-top: 11%; }
</style>
</head>
<body>
<div>
<p>NumWorks simulator - beta version - contact@numworks.com</p>
</div>
<div class="calculator">
<img src="background.jpg" alt="NumWorks Calculator">
<canvas id="screen" class="screen" oncontextmenu="event.preventDefault()"></canvas>
<div class="keyboard">
<div class="nav">
<a class="left" href="" data-key="0"></a>
<a class="top" href="" data-key="1"></a>
<a class="bottom" href="" data-key="2"></a>
<a class="right" href="" data-key="3"></a>
<a class="ok" href="" data-key="4"></a>
<a class="back" href="" data-key="5"></a>
<a class="home" href="" data-key="6"></a>
<a class="power" href="" data-key="7"></a>
</div>
<div class="functions">
<a href="" data-key="12"></a>
<a href="" data-key="13"></a>
<a href="" data-key="14"></a>
<a href="" data-key="15"></a>
<a href="" data-key="16"></a>
<a href="" data-key="17"></a>
<a href="" data-key="18"></a>
<a href="" data-key="19"></a>
<a href="" data-key="20"></a>
<a href="" data-key="21"></a>
<a href="" data-key="22"></a>
<a href="" data-key="23"></a>
<a href="" data-key="24"></a>
<a href="" data-key="25"></a>
<a href="" data-key="26"></a>
<a href="" data-key="27"></a>
<a href="" data-key="28"></a>
<a href="" data-key="29"></a>
</div>
<div class="digits">
<a href="" data-key="30"></a>
<a href="" data-key="31"></a>
<a href="" data-key="32"></a>
<a href="" data-key="33"></a>
<a href="" data-key="34"></a>
<a href="" data-key="36"></a>
<a href="" data-key="37"></a>
<a href="" data-key="38"></a>
<a href="" data-key="39"></a>
<a href="" data-key="40"></a>
<a href="" data-key="42"></a>
<a href="" data-key="43"></a>
<a href="" data-key="44"></a>
<a href="" data-key="45"></a>
<a href="" data-key="46"></a>
<a href="" data-key="48"></a>
<a href="" data-key="49"></a>
<a href="" data-key="50"></a>
<a href="" data-key="51"></a>
<a href="" data-key="52"></a>
</div>
</div>
</div>
<script>
var Module = {
arguments: ["fr"],
preRun: [],
postRun: [],
print: function(text) {
console.log(text);
},
printErr: function(text) {
console.error(text);
},
canvas: document.getElementById("screen")
};
</script>
<script src="firmware.js"></script>
<script>
var buttons = document.querySelectorAll(".calculator .keyboard a");
for (var i=0; i< buttons.length; i++) {
var button = buttons[i];
button.addEventListener("click", function(e) {
console.log("CLICK");
Module._IonEventsEmscriptenPushEvent(this.getAttribute("data-key"));
e.preventDefault();
});
}
window.addEventListener("keydown", function(e) {
// space and arrow keys
if([32, 37, 38, 39, 40].indexOf(e.keyCode) > -1) {
e.preventDefault();
}
}, false);
</script>
</body>
</html>