Mirai's Miscellaneous Misadventures
M39 / main.js
// copyright 2023 zamfofex
// license: AGPLv3 or later
let createCanvas = (document, width, height) =>
{
let canvas = document.createElement("canvas")
canvas.width = width
canvas.height = height
canvas.tabIndex = 0
return canvas
}
export let run = async (
{
window = globalThis.window,
document = window.document,
canvas = createCanvas(document, 512, 256),
url = "mimimi.wasm",
body,
module,
} = {}) =>
{
let left = 0
let right = 0
canvas.addEventListener("keydown", ({code}) =>
{
if (code === "ArrowLeft") left = 1
if (code === "ArrowRight") right = 1
if (code === "KeyA") left = 1
if (code === "KeyD") right = 1
})
canvas.addEventListener("keyup", ({code}) =>
{
if (code === "ArrowLeft") left = 0
if (code === "ArrowRight") right = 0
if (code === "KeyA") left = 0
if (code === "KeyD") right = 0
})
let leftT = 0
let rightT = 0
canvas.addEventListener("pointerdown", ({target, offsetX, button}) =>
{
if (button !== 0) return
if (offsetX < target.offsetWidth / 2)
leftT = 1
else
rightT = 1
})
canvas.addEventListener("pointerup", () => { leftT = 0 ; rightT = 0 })
let _memset = (a, b, n) => new Uint8Array(memory.buffer, a, n).set(Array(n).fill(b))
let _memcpy = (a, b, n) => new Uint8Array(memory.buffer, a, n).set(new Uint8Array(memory.buffer, b, n))
let c =
{
_memset, _memcpy,
mimimi_wasm_yield: data =>
{
if (exports.asyncify_get_state() === 2)
exports.asyncify_stop_rewind();
else
exports.asyncify_start_unwind(data + 4);
},
mimimi_wasm_continue: data =>
{
let view = new DataView(memory.buffer)
if (view.getUint32(data, true) === 0)
view.setUint32(data, 1, true),
exports.mimimi_wasm_start_coroutine(data)
else
exports.asyncify_start_rewind(data + 4),
exports.mimimi_wasm_start_coroutine()
if (exports.asyncify_get_state() === 1)
exports.asyncify_stop_unwind()
else
exports.mimimi_wasm_finish_coroutine(data)
},
}
let noop = () => { }
let keys = ["write", "args_sizes_get", "lseek", "_tmpfile", "close", "unlink", "args_get", "_getcwd", "open", "read", "proc_exit"]
for (let key of keys) c[key] = noop
if (!module && !body) body = await fetch(url)
let exports
if (module)
{
let {instance} = await WebAssembly.instantiate(module, {c})
exports = instance.exports
}
else if (body)
{
let result
if (WebAssembly.instantiateStreaming) result = await WebAssembly.instantiateStreaming(body, {c})
else result = await WebAssembly.instantiate(await body.arrayBuffer(), {c})
exports = result.instance.exports
}
let {mimimi_wasm_behave, main, memory} = exports
main()
let context = canvas.getContext("2d")
let image = new ImageData(canvas.width, canvas.height)
let past = performance.now()
let step = () =>
{
let data = mimimi_wasm_behave(left|leftT, right|rightT)
image.data.set(new Uint8Array(memory.buffer, data, canvas.width * canvas.height * 4))
context.putImageData(image, 0, 0)
let now = performance.now()
setTimeout(step, (100 / 3) + past - now)
past = now
}
step()
return canvas
}