// this is an emscripten-only implementation of fenster // make sure to add -sASYNCIFY #include #include #include "emscripten.h" // offsets struct fenster { // byte 32bit const char *title; // 0 0 const int width; // 4 1 const int height; // 8 2 uint32_t *buf; // 12 3 int keys[256]; // 16 4 int mod; // 1040 257 int x; // 1044 258 int y; // 1048 259 int mouse; // 1052 260 }; #define fenster_pixel(f, x, y) ((f)->buf[((y) * (f)->width) + (x)]) #define fenster_sleep emscripten_sleep static bool running = true; EM_JS(int, fenster_open, (struct fenster *f), { if (!Module.canvas) { Module.canvas = document.getElementById('canvas'); if (!Module.canvas) { document.createElement("canvas"); document.appendElement(Module.canvas); } } const p32 = f/4; const width = Module.HEAP32[p32 + 1]; const height = Module.HEAP32[p32 + 2]; Module.canvas.width = width; Module.canvas.height = height; Module.ctx = canvas.getContext("2d"); Module.screen = Module.ctx.getImageData(0, 0, width, height); // TODO: handle mod Module.canvas.addEventListener('mousemove', e => { Module.HEAP32[p32 + 258] = e.offsetX; Module.HEAP32[p32 + 259] = e.offsetY; }); Module.canvas.addEventListener('mousedown', e => { Module.HEAP32[p32 + 260] = e.which; }); Module.canvas.addEventListener('mouseup', e => { Module.HEAP32[p32 + 260] = 0; }); Module.canvas.addEventListener('keydown', e => { Module.HEAP32[p32 + 4 + e.keyCode] = 1; }); Module.canvas.addEventListener('keyup', e => { Module.HEAP32[p32 + 4 + e.keyCode] = 0; }); }); EM_JS(void, emscripten_fenster_loop, (int width, int height, uint32_t* buf), { const byteSize = width * height * 4; const buffer = Module.HEAPU8.subarray(buf, buf + byteSize); // set alpha to 100% and re-arrange RGBA let r,g,b = 0; for (let i=0;iwidth, f->height, f->buf); } // this is hack to make it not pin the main-loop (~60fps) // better would be if we can wrap the loop with emscripten_set_main_loop // which also does not require ASYNCIFY emscripten_sleep(16); return running ? 0 : 1; } void fenster_close(struct fenster *f) { running = false; } EM_JS(int64_t, fenster_time, (void), { return (new Date()).time; });