Mirai's Miscellaneous Misadventures

M53 / index.html

1<!-- license: AGPLv3 or later -->
2<!-- copyright 2024 zamfofex -->
3
4<!doctype html>
5<html lang="en">
6<meta charset="utf-8">
7<meta name="viewport" content="width=device-width">
8
9<title> Mirai's Miscellaneous Misadventures </title>
10
11<style>
12
13*, ::before, ::after
14{
15    touch-action: none;
16}
17
18html, body
19{
20    width: 100%;
21    height: 100%;
22    display: flex;
23}
24
25body
26{
27    margin: 0;
28    background: #000;
29}
30
31canvas
32{
33    width: 100%;
34    height: 100%;
35    image-rendering: crisp-edges;
36    image-rendering: pixelated;
37    object-fit: contain;
38    outline: none;
39}
40
41</style>
42
43<script type="module">
44
45import * as WebAssembly from "https://esm.sh/asyncify-wasm@1.2.1"
46
47let canvas = document.querySelector("canvas")
48let context = canvas.getContext("2d")
49
50let rch = [0x11, 0x44, 0x77, 0x99, 0xCC, 0xFF]
51let gch = [0x11, 0x33, 0x55, 0x77, 0x99, 0xBB, 0xDD, 0xFF]
52let bch = [0x22, 0x55, 0x88, 0xBB, 0xEE]
53
54let show = (width, height, colors) =>
55{
56    let view = new DataView(memory.buffer)
57
58    if (colors < 0) colors += 0x10000
59
60    let image = new ImageData(width, height)
61    let {data} = image
62
63    for (let x = 0 ; x < width ; x++)
64    for (let y = 0 ; y < height ; y++)
65    {
66        let o = x + y * width
67        let color = view.getUint8(colors + o)
68
69        if (color === 0) continue
70
71        if (color < 0x10)
72        {
73            let ch = color * 0x11
74            data[o * 4 + 0] = ch
75            data[o * 4 + 1] = ch
76            data[o * 4 + 2] = ch
77            data[o * 4 + 3] = 0xFF
78        }
79        else
80        {
81            color -= 0x10
82            let r = rch[Math.floor(color / 40) % 6]
83            let g = gch[Math.floor(color / 5) % 8]
84            let b = bch[Math.floor(color / 1) % 5]
85
86            data[o * 4 + 0] = r
87            data[o * 4 + 1] = g
88            data[o * 4 + 2] = b
89            data[o * 4 + 3] = 0xFF
90        }
91    }
92
93    canvas.width = width
94    canvas.height = height
95    context.putImageData(image, 0, 0)
96
97    return new Promise(fn => fns.push(fn))
98}
99
100let past = -Infinity
101
102let fns = []
103let tick = () =>
104{
105    let now = performance.now()
106    fns.splice(0).forEach(fn => fn())
107    setTimeout(tick, Math.max(0, past - now) + 100 / 6)
108    past = now
109}
110
111let imports =
112{
113    env:
114    {
115        mimimi_wasm_sync: show,
116        mimimi_wasm_keys: () => left * 2 + right,
117        mimimi_wasm_width: () => innerWidth,
118        mimimi_wasm_height: () => innerHeight,
119    },
120    wasi_snapshot_preview1: {proc_exit: () => { throw new Error() }},
121}
122
123let response = await fetch("mimimi.wasm")
124let buffer = await response.arrayBuffer()
125let {instance} = await WebAssembly.instantiate(buffer, imports)
126let {memory, _start} = instance.exports
127
128let left = 0
129let right = 0
130
131let leftKeys = ["ArrowLeft", "KeyA", "Numpad4", "KeyH"]
132let rightKeys = ["ArrowRight", "KeyD", "Numpad6", "KeyL"]
133
134addEventListener("keydown", ({code}) =>
135{
136    if (leftKeys.includes(code)) left = 1
137    if (rightKeys.includes(code)) right = 1
138})
139
140addEventListener("keyup", ({code}) =>
141{
142    if (leftKeys.includes(code)) left = 0
143    if (rightKeys.includes(code)) right = 0
144})
145
146addEventListener("contextmenu", event => event.preventDefault())
147
148addEventListener("pointerdown", event =>
149{
150    if (event.pointerType === "mouse") return
151    if (event.button !== 0) return
152
153    if (event.offsetX < innerWidth / 2)
154        left = 1
155    else
156        right = 1
157})
158
159addEventListener("pointerup", event =>
160{
161    if (event.pointerType === "mouse") return
162    if (event.button !== 0) return
163
164    left = 0
165    right = 0
166})
167
168addEventListener("mousedown", ({button}) =>
169{
170    if (button === 0) left = 1
171    if (button === 2) right = 1
172})
173
174addEventListener("mouseup", ({button}) =>
175{
176    if (button === 0) left = 0
177    if (button === 2) right = 0
178})
179
180_start()
181tick()
182
183</script>
184
185<canvas width="512" height="256"></canvas>