shithub: wipeout

ref: 24b6efd3ea9d12661a96bfbed6bc86241e30aa70
dir: /src/wasm-index.html/

View raw version
<!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>