Mirai's Miscellaneous Misadventures
M49 / index.html
<!-- license: AGPLv3 or later -->
<!-- copyright 2024 zamfofex -->
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title> Mirai's Miscellaneous Misadventures </title>
<style>
*, ::before, ::after
{
touch-action: none;
}
html, body
{
width: 100%;
height: 100%;
display: flex;
}
body
{
margin: 0;
background: #000;
}
canvas
{
width: 100%;
height: 100%;
image-rendering: crisp-edges;
image-rendering: pixelated;
object-fit: contain;
outline: none;
}
</style>
<script type="module">
import * as WebAssembly from "https://esm.sh/asyncify-wasm@1.2.1"
let canvas = document.querySelector("canvas")
let context = canvas.getContext("2d")
let cache = new Map()
let rch = [0x11, 0x44, 0x77, 0x99, 0xCC, 0xFF]
let gch = [0x11, 0x33, 0x55, 0x77, 0x99, 0xBB, 0xDD, 0xFF]
let bch = [0x22, 0x55, 0x88, 0xBB, 0xEE]
let createTexture = async (data0, asset) =>
{
let view = new DataView(memory.buffer)
if (asset < 0) asset = 0x10000 + asset
let width = view.getUint32(asset, true)
let height = view.getUint32(asset + 4, true)
let colors = view.getUint32(asset + 8, true)
let image = new ImageData(width, height)
let {data} = image
for (let x = 0 ; x < width ; x++)
for (let y = 0 ; y < height ; y++)
{
let o = x + y * width
let color = view.getUint8(colors + o)
if (color === 0) continue
if (color < 0x10)
{
let ch = color * 0x11
data[o * 4 + 0] = ch
data[o * 4 + 1] = ch
data[o * 4 + 2] = ch
data[o * 4 + 3] = 0xFF
}
else
{
color -= 0x10
let r = rch[Math.floor(color / 40) % 6]
let g = gch[Math.floor(color / 5) % 8]
let b = bch[Math.floor(color / 1) % 5]
data[o * 4 + 0] = r
data[o * 4 + 1] = g
data[o * 4 + 2] = b
data[o * 4 + 3] = 0xFF
}
}
cache.set(asset, await createImageBitmap(image))
return asset
}
let stamp = (data, x, y, asset) => context.drawImage(cache.get(asset), x, y)
let invalidate = (data, asset) => cache.delete(asset)
let past = performance.now()
let promise
let resolve = () => { }
let tick = () =>
{
let now = performance.now()
resolve(left * 2 + right)
promise = new Promise(f => { setTimeout(tick, (100 / 3) + past - now) ; resolve = f })
past = now
}
let imports =
{
env:
{
mimimi_wasm_texture: createTexture,
mimimi_wasm_invalidate: invalidate,
mimimi_wasm_stamp: stamp,
mimimi_wasm_sync: () => promise,
},
wasi_snapshot_preview1: {proc_exit: () => { throw new Error("exit called") }},
}
let response = await fetch("mimimi-loader.wasm")
let buffer = await response.arrayBuffer()
let {instance} = await WebAssembly.instantiate(buffer, imports)
let {memory, _start} = instance.exports
let left = 0
let right = 0
addEventListener("keydown", ({code}) =>
{
if (code === "ArrowLeft") left = 1
if (code === "ArrowRight") right = 1
if (code === "KeyA") left = 1
if (code === "KeyD") right = 1
})
addEventListener("keyup", ({code}) =>
{
if (code === "ArrowLeft") left = 0
if (code === "ArrowRight") right = 0
if (code === "KeyA") left = 0
if (code === "KeyD") right = 0
})
addEventListener("contextmenu", event => event.preventDefault())
addEventListener("pointerdown", event =>
{
if (event.pointerType === "mouse") return
if (event.button !== 0) return
if (event.offsetX < innerWidth / 2)
left = 1
else
right = 1
})
addEventListener("pointerup", event =>
{
if (event.pointerType === "mouse") return
if (event.button !== 0) return
left = 0
right = 0
})
addEventListener("mousedown", ({button}) =>
{
if (button === 0) left = 1
if (button === 2) right = 1
})
addEventListener("mouseup", ({button}) =>
{
if (button === 0) left = 0
if (button === 2) right = 0
})
tick()
_start()
</script>
<canvas width="512" height="256"></canvas>