1
Fork 0
simplesailing/front/index.js

90 lines
2.1 KiB
JavaScript

var ctx;
var image;
var memory;
var exports;
const width = 160;
const height = 144;
const TIME_GAIN = 0.1; // game is unplayable at full speed with wasm refresh rates
function blit_frame() {
// this is required when using an allocator from wasm as there is
// no way to update the internal pointer when linear memory shifts
image = new ImageData(
new Uint8ClampedArray(
memory.buffer,
exports.BUFFER.value,
4 * width * height,
),
width,
);
ctx.putImageData(image, 0, 0);
}
function blit_text(text, len, x, y, size) {
let decoded = (new TextDecoder())
.decode(new Uint8Array(memory.buffer, text, len));
ctx.font = size +'px serif'
ctx.fillText(decoded,x,y);
}
function keyboard_callback(e) {
const keycode_address = exports.KEYCODE.value;
const value = new Uint8ClampedArray(exports.memory.buffer, keycode_address, 2);
value[0] = e.keyCode;
exports.keyboard_input();
}
async function init() {
const canvas = document.getElementById("window");
canvas.width = width;
canvas.height = height;
ctx = canvas.getContext("2d");
const { instance } = await WebAssembly.instantiateStreaming(
fetch("./index.wasm"),
{
"env" : {
"js_sin": Math.sin,
"blit_frame": blit_frame,
"blit_text": blit_text,
},
}
);
exports = instance.exports;
document.getElementById("body").onkeydown=keyboard_callback;
memory = instance.exports.memory
instance.exports.frame_entry();
ctx.textBaseline = 'top'
ctx.textAlign = 'left';
var last;
var elapsed;
const render = (time) => {
if(!last) { elapsed = 0; }
else {
elapsed = time-last;
}
last=time;
if(!elapsed) {
elapsed = 0.0;
}
const FRAME_TIME = new Float32Array(exports.memory.buffer, exports.LAST_FRAME_TIME, 1);
FRAME_TIME[0] = elapsed * TIME_GAIN;
instance.exports.frame_entry();
requestAnimationFrame(render);
}
render();
}
init();