ref: 41399234f6694133bbd64910b86ff61bce67367a
dir: /src/wasm-index.html/
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>wipEout</title>
<style>
html, body {
color: #ccc;
font-family: Monospace;
font-size: 13px;
background-color: #111;
margin: 0px;
}
a {
color: #ffc603;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
canvas {
border: 0px none;
background-color: black;
width: 100%;
height: 100%;
aspect-ratio: 16 / 9;
}
#head {
left: 0;
right: 0;
top: 0;
padding: 4px 16px 6px 16px;
xheight: 24px;
background-color: #222;
display: flex;
justify-content: space-between;
}
@keyframes page-loader {
0% {transform: rotate(0deg); }
100% { transform: rotate(360deg);}
}
.container {
position: relative;
}
.info-overlay {
text-align: center;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
width: 200px;
height: 200px;
display: none;
}
.fullscreen {
margin: 0 8px;
}
#spinner {
content: "";
border-radius: 50%;
width: 48px;
height: 48px;
position: absolute;
margin: auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
border-top: 2px solid #222;
border-right: 2px solid #222;
border-bottom: 2px solid #222;
border-left: 2px solid #ffc603;
transform: translateZ(0);
animation: page-loader 1.1s infinite linear;
}
h1 {
color: #fff;
display: inline-block;
margin: 0;
padding: 0;
font-size: 12px;
}
.key {
margin-right: 16px;
}
kbd {
background-color: #eee;
border-radius: 3px;
border: 1px solid #b4b4b4;
box-shadow:
0 1px 1px rgba(0, 0, 0, 0.2),
0 2px 0 0 rgba(255, 255, 255, 0.7) inset;
color: #333;
display: inline-block;
font-size: 0.85em;
font-weight: 700;
line-height: 1;
padding: 1px 2px;
white-space: nowrap;
}
</style>
</head>
<body>
<div id="head">
<div>
<h1>wipEout</h1>
<a href="#" id="fullscreen">fullscreen</a>
<span class="key"><kbd>◀</kbd><kbd>▲</kbd><kbd>▼</kbd><kbd>▶</kbd> steering</span>
<span class="key"><kbd>X</kbd> thrust</span>
<span class="key"><kbd>Z</kbd> shoot</span>
<span class="key"><kbd>C</kbd> brake left</span>
<span class="key"><kbd>V</kbd> brake right</span>
<span class="key"><kbd>A</kbd> view</span>
</div>
<div>
Read:
<a href="https://phoboslab.org/log/2023/08/rewriting-wipeout">
Rewriting wipEout
</a>
</div>
</div>
<div id="game" class="container">
<canvas id="canvas" oncontextmenu="event.preventDefault()" tabindex=-1></canvas>
<div class="info-overlay" id="loading">
<div id="spinner"></div>
<div id="status">Downloading...</div>
<div>
<progress value="0" max="100" id="progress" hidden=1></progress>
</div>
</div>
<div class="info-overlay" id="select-version">
<p>
<a href="#" id="load-full-version">FULL VERSION</a><br/>
the complete game ~144mb
</p>
<p>
<a href="#" id="load-minimal-version">MINIMAL VERSION</a><br/>
no intro, no music ~11mb
</p>
</div>
</div>
</div>
<script type='text/javascript'>
var loadScript = (ev, src) => {
ev.preventDefault();
// Hide select-version, show loader
document.getElementById('select-version').style.display = 'none';
document.getElementById('loading').style.display = 'block';
// Load the requested script
var s = document.createElement('script');
s.setAttribute('src', src);
document.head.appendChild(s);
// Attemp to unlock Audio :(
var audioCtx = new AudioContext();
audioCtx.resume();
return false;
};
var requestFullscreen = (ev) => {
ev.preventDefault();
document.getElementById('game').requestFullscreen();
};
document.getElementById('select-version').style.display = 'block';
document.getElementById('fullscreen').addEventListener('click', (ev) => requestFullscreen(ev, 'wipeout.js'))
document.getElementById('load-full-version').addEventListener('click', (ev) => loadScript(ev, 'wipeout.js'));
document.getElementById('load-minimal-version').addEventListener('click', (ev) => loadScript(ev, 'wipeout-minimal.js'));
var statusElement = document.getElementById('status');
var progressElement = document.getElementById('progress');
var spinnerElement = document.getElementById('spinner');
var Module = {
preRun: [],
postRun: [],
print: function(text) {
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
console.log(text);
},
canvas: document.getElementById('canvas'),
setStatus: (text) => {
if (!Module.setStatus.last) {
Module.setStatus.last = { time: Date.now(), text: '' };
}
if (text === Module.setStatus.last.text) {
return;
}
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
var now = Date.now();
if (m && now - Module.setStatus.last.time < 30) {
return; // if this is a progress update, skip it if too soon
}
Module.setStatus.last.time = now;
Module.setStatus.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 = false;
} else {
progressElement.value = null;
progressElement.max = null;
progressElement.hidden = true;
if (!text) {
spinnerElement.hidden = true;
document.getElementById('loading').style.display = 'none';
}
}
statusElement.innerHTML = text;
},
totalDependencies: 0,
monitorRunDependencies: (left) => {
Module.totalDependencies = Math.max(Module.totalDependencies, left);
Module.setStatus(left ? 'preparing... (' + (Module.totalDependencies-left) + '/' + Module.totalDependencies + ')' : 'all downloads complete.');
}
};
Module.setStatus('downloading...');
window.onerror = () => {
Module.setStatus('Exception thrown, see JavaScript console');
document.getElementById('loading').style.display = 'block';
spinnerElement.style.display = 'none';
Module.setStatus = (text) => {
if (text) {
console.error('[post-exception status] ' + text);
}
};
};
</script>
</body>
</html>