-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathweb-demo.html
146 lines (121 loc) · 3.88 KB
/
web-demo.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<!DOCTYPE html>
<!--
Kinetoscope: A Sega Genesis Video Player
Copyright (c) 2024 Joey Parrish
See MIT License in LICENSE.txt
This web-based demo is incomplete without the emulator core
(genesis_plus_gx_libretro.js and genesis_plus_gx_libretro.wasm) and the
Kinetoscope ROM (kinetoscope-streamer.rom), all of which must be in the same folder as
this page.
-->
<html lang="en">
<head>
<title>Kinetoscope Web Emulator Demo</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Kinetoscope Emulator for the web">
<style>
@font-face {
font-family: 'Kode Mono';
font-style: normal;
font-weight: bold;
font-display: block;
src: url(https://fonts.gstatic.com/s/kodemono/v2/A2BLn5pb0QgtVEPFnlYkkaoBgw4qv9odq3619Do.ttf) format('truetype');
}
html, body {
margin: 0;
padding: 0;
/* Prevent pull-to-refresh on mobile, since we use swipe gestures in a
* keyboard-less environment. */
overscroll-behavior: none;
}
body {
background: black;
}
#clickToStart, #instructions {
background: black;
color: white;
border: none;
font-family: "Kode Mono";
font-optical-sizing: auto;
font-weight: bold;
font-size: calc(min(6vw, 20vh));
display: block;
margin: auto;
margin-top: 1em;
}
#clickToStart {
border: 1px white solid;
padding: 0.5em;
font-style: italic;
}
#instructions {
font-size: calc(min(5vw, 16vh));
padding: 1em;
}
</style>
</head>
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/nostalgist.umd.min.js"></script>
<script defer src="gesture-tracker.js"></script>
<script>
// AudioContext needs a user gesture to start. So we define main, but don't
// run it until the user clicks the click-to-start button.
async function main() {
// Change the click-to-start label to a loading indicator.
clickToStart.innerText = 'Loading...'
clickToStart.disabled = true;
// We haven't finished loading JS, try again in 1s.
if (!window.Nostalgist) {
console.log('Waiting for Nostalgist...');
setTimeout(main, 1000);
return;
}
// Launch the emulator, which will create its own canvas.
const nostalgist = await Nostalgist.launch({
core: {
name: 'genesis_plus_gx',
js: 'genesis_plus_gx_libretro.js',
wasm: 'genesis_plus_gx_libretro.wasm',
},
rom: 'kinetoscope-streamer.rom',
onLaunch: () => {
// Once loaded, hide the click-to-start button and instructions.
clickToStart.style.display = 'none';
instructions.style.display = 'none';
},
});
// Resize the emulator when the window changes size.
window.addEventListener('resize', () => {
nostalgist.resize({width: window.innerWidth, height: window.innerHeight});
});
function send(buttonName) {
// Send a button press "down" event, then 100ms later an button "up"
// (release) event.
nostalgist.pressDown(buttonName);
setTimeout(() => nostalgist.pressUp(buttonName), 100);
}
const gestures = new GestureTracker(document.querySelector('canvas'));
gestures.addEventListener('swipe-up', () => send('up'));
gestures.addEventListener('swipe-down', () => send('down'));
// Somehow, nostalgist sending 'a' becomes the "C" button in the ROM. WTF?
gestures.addEventListener('swipe-left', () => send('a'));
gestures.addEventListener('swipe-right', () => send('start'));
gestures.addEventListener('tap', () => send('start'));
// Stored globally for debugging access.
window.nostalgist = nostalgist;
window.gestures = gestures;
}
</script>
<body>
<button id="clickToStart" onclick="main()">Click here to start<br>Kinetoscope Emulator</button>
<div id="instructions">
<ul>
<li>up: ↑ / swipe up</li>
<li>down: ↓ / swipe down</li>
<li>start: enter / tap</li>
<li>pause: enter / tap</li>
<li>stop: X / swipe left</li>
</ul>
</div>
</body>
</html>