sketch out os api, binary stream writer in js, app sleep when no animation, local and universal time

This commit is contained in:
krzosa
2025-01-04 11:03:36 +01:00
parent 6f795b7ea6
commit dcd1266477
13 changed files with 316 additions and 87 deletions

View File

@@ -36,8 +36,6 @@ while (true) {
}
*/
fn_wasm_import f64 wasm_get_milliseconds(void);
gb_wasm_export char wasm_temp_buff1[128] = {[127] = 0x13};
gb_wasm_export i32 wasm_temp_buff1_len = 127;
gb_wasm_export char wasm_temp_buff2[128] = {[127] = 0x13};
@@ -47,7 +45,6 @@ gb f64 wasm_dpr;
gb f64 wasm_delta_time;
gb f64 wasm_time;
gb f64 wasm_last_time;
gb f64 wasm_app_init_time;
gb app_event_list_t wasm_event_list;
typedef struct wasm_cached_t wasm_cached_t;
@@ -56,7 +53,7 @@ struct wasm_cached_t {
b8 ctrl, alt, meta, shift;
} wasm_cached;
fn void app_update(app_event_list_t eventswasm_event_list);
fn b32 app_update(app_event_list_t);
fn void app_init(void);
fn void wasm_add_event(app_event_t event) {
@@ -179,12 +176,8 @@ fn_wasm_export void wasm_key_up(char *key, b32 ctrl, b32 shift, b32 alt, b32 met
}
}
fn f64 wasm_seconds_now(void) {
return wasm_get_milliseconds() / 1000.0;
}
fn_wasm_export void wasm_update(f64 width, f64 height, f64 dpr) {
wasm_time = wasm_seconds_now();
fn_wasm_export void wasm_update(f64 time, f64 width, f64 height, f64 dpr) {
wasm_time = time;
wasm_delta_time = wasm_time - wasm_last_time;
v2f64_t window_size = (v2f64_t){width / dpr, height / dpr};
@@ -216,13 +209,12 @@ fn_wasm_export void wasm_update(f64 width, f64 height, f64 dpr) {
fn_wasm_export void wasm_init(void) {
core_init();
app_init();
wasm_app_init_time = wasm_seconds_now();
}
fn f64 app_get_anim_time(void) {
return wasm_time;
return wasm_time / 1000.0;
}
fn f64 app_get_anim_delta_time(void) {
return wasm_delta_time;
return wasm_delta_time / 1000.0;
}

View File

@@ -33,6 +33,33 @@
</html>
<script>
class stream_t {
constructor(dataview, ptr, len) {
this.dv = dataview;
this.ptr = ptr;
this.len = len;
this.i = 0;
}
write_u32(value) {
if (this.i + 4 <= this.len) {
this.dv.setUint32(this.ptr + this.i, value, true);
this.i += 4;
} else {
console.log("reached end of buffer while stream writing");
}
}
write_u16(value) {
if (this.i + 2 <= this.len) {
this.dv.setUint16(this.ptr + this.i, value, true);
this.i += 2;
} else {
console.log("reached end of buffer while stream writing");
}
}
}
class memory_t {
exports = null; // this is set after wasm module created
constructor(wasm_memory) {
@@ -58,12 +85,16 @@ class memory_t {
this.u8[ptr + i] = 0;
}
write_string(temp, string) {
write_string_to_cglobal(temp, string) {
const ptr = this.exports[temp].value;
const len = this.data_view.getInt32(this.exports[temp + "_len"].value, true);
this.write_string_into_cmemory(ptr, len, string);
return ptr;
}
stream_write(ptr, len) {
return new stream_t(this.data_view, ptr, len);
}
}
const canvas = document.getElementById("canvas");
@@ -78,7 +109,36 @@ const mem = new memory_t(new WebAssembly['Memory']({ initial: 2000, maximum: 655
const request = await fetch('main.wasm');
const binary = await request.arrayBuffer();
const wasm_imports = {
const wasm_os_imports = {
wasm_local_time_now: (ptr, len) => {
const date = new Date();
const stream = mem.stream_write(ptr, len);
stream.write_u16(date.getMilliseconds());
stream.write_u16(date.getSeconds());
stream.write_u16(date.getMinutes());
stream.write_u16(date.getHours());
stream.write_u16(date.getDate());
stream.write_u16(date.getMonth());
stream.write_u16(date.getFullYear());
},
wasm_universal_time_now: (ptr, len) => {
const date = new Date();
const stream = mem.stream_write(ptr, len);
stream.write_u16(date.getUTCMilliseconds());
stream.write_u16(date.getUTCSeconds());
stream.write_u16(date.getUTCMinutes());
stream.write_u16(date.getUTCHours());
stream.write_u16(date.getUTCDate());
stream.write_u16(date.getUTCMonth());
stream.write_u16(date.getUTCFullYear());
},
wasm_milliseconds_now: () => { return performance.now(); },
};
let wasm_app_imports = {
// core
memory: mem.mem,
@@ -86,7 +146,6 @@ const mem = new memory_t(new WebAssembly['Memory']({ initial: 2000, maximum: 655
wasm_alert: (str, len) => { alert(mem.read_cstr(str,len)); },
wasm_trap: () => { throw new Error(); },
wasm_write_to_console: (str, len) => { console.log(mem.read_cstr(str, len)); },
wasm_get_milliseconds: () => { return performance.now(); },
// gfx
wasm_draw_text: (str, len, x, y, font_str, font_len, font_size, r, g, b, a) => {
@@ -125,37 +184,59 @@ const mem = new memory_t(new WebAssembly['Memory']({ initial: 2000, maximum: 655
};
const program = await WebAssembly['instantiate'](binary, { "env": wasm_imports });
Object.assign(wasm_app_imports, wasm_os_imports);
const program = await WebAssembly['instantiate'](binary, { "env": wasm_app_imports });
const instance = program['instance'];
const wasm_exports = instance['exports'];
mem.exports = wasm_exports;
wasm_exports['wasm_init']();
addEventListener("keydown", (event) => {
wasm_exports["wasm_key_down"](mem.write_string("wasm_temp_buff1", event.key), event.ctrlKey, event.shiftKey, event.altKey, event.metaKey);
});
addEventListener("keyup", (event) => {
wasm_exports["wasm_key_up"](mem.write_string("wasm_temp_buff1", event.key), event.ctrlKey, event.shiftKey, event.altKey, event.metaKey);
});
addEventListener("mousemove", (event) => {
wasm_exports["wasm_mouse_move"](event.clientX, event.clientY, event.ctrlKey, event.shiftKey, event.altKey, event.metaKey);
});
addEventListener("mousedown", (event) => {
wasm_exports["wasm_mouse_down"](event.clientX, event.clientY, event.button, event.ctrlKey, event.shiftKey, event.altKey, event.metaKey);
});
addEventListener("mouseup", (event) => {
wasm_exports["wasm_mouse_up"](event.clientX, event.clientY, event.button, event.ctrlKey, event.shiftKey, event.altKey, event.metaKey);
});
addEventListener("wheel", (event) => {
wasm_exports["wasm_mouse_wheel"](event.clientX, event.clientY, event.deltaX, event.deltaY, event.deltaZ, event.ctrlKey, event.shiftKey, event.altKey, event.metaKey);
});
let awake = false;
requestAnimationFrame(function update(time) {
function wasm_update(time) {
const dpr = window.devicePixelRatio;
canvas.width = canvas.getBoundingClientRect().width * dpr;
canvas.height = canvas.getBoundingClientRect().height * dpr;
wasm_exports['wasm_update'](canvas.width, canvas.height, dpr);
requestAnimationFrame(update);
let animating = wasm_exports['wasm_update'](time, canvas.width, canvas.height, dpr);
if (animating) {
requestAnimationFrame(wasm_update);
} else {
awake = false;
}
}
function wake_up() {
if (awake) return;
awake = true;
window.requestAnimationFrame(wasm_update);
}
addEventListener("keydown", (event) => {
wasm_exports["wasm_key_down"](mem.write_string_to_cglobal("wasm_temp_buff1", event.key), event.ctrlKey, event.shiftKey, event.altKey, event.metaKey);
wake_up();
});
addEventListener("keyup", (event) => {
wasm_exports["wasm_key_up"](mem.write_string_to_cglobal("wasm_temp_buff1", event.key), event.ctrlKey, event.shiftKey, event.altKey, event.metaKey);
wake_up();
});
addEventListener("mousemove", (event) => {
wasm_exports["wasm_mouse_move"](event.clientX, event.clientY, event.ctrlKey, event.shiftKey, event.altKey, event.metaKey);
wake_up();
});
addEventListener("mousedown", (event) => {
wasm_exports["wasm_mouse_down"](event.clientX, event.clientY, event.button, event.ctrlKey, event.shiftKey, event.altKey, event.metaKey);
wake_up();
});
addEventListener("mouseup", (event) => {
wasm_exports["wasm_mouse_up"](event.clientX, event.clientY, event.button, event.ctrlKey, event.shiftKey, event.altKey, event.metaKey);
wake_up();
});
addEventListener("wheel", (event) => {
wasm_exports["wasm_mouse_wheel"](event.clientX, event.clientY, event.deltaX, event.deltaY, event.deltaZ, event.ctrlKey, event.shiftKey, event.altKey, event.metaKey);
wake_up();
});
requestAnimationFrame(wasm_update);
})()
</script>

View File

@@ -10,7 +10,6 @@
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "winmm.lib")
gb b32 w32_good_scheduling;
gb WNDCLASSW w32_wc;
gb HWND w32_window_handle;
@@ -43,6 +42,7 @@ fn f64 w32_get_dpr(HWND window_handle) {
///////////////////////////////
// event processing
gb app_event_list_t w32_event_list;
gb ma_arena_t *w32_event_arena;