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}; gb_wasm_export i32 wasm_temp_buff2_len = 127; gb f32 wasm_dpr; gb f32 wasm_delta_time; gb f32 wasm_time; gb f32 wasm_last_time; gb app_frame_t wasm_frame; gb u64 wasm_frame_counter; gb u64 wasm_event_ids; typedef struct wasm_cached_t wasm_cached_t; struct wasm_cached_t { v2f32_t mouse_pos; v2f32_t mouse_delta; b8 ctrl, alt, shift; } wasm_cached; fn b32 app_update(app_frame_t *frame); fn void app_init(f32 dpr); fn void wasm_add_event(app_event_t event) { app_event_t *ev = ma_push_type(tcx.temp, app_event_t); *ev = event; ev->id = ++wasm_event_ids; ev->alt = wasm_cached.alt; ev->ctrl = wasm_cached.ctrl; ev->shift = wasm_cached.shift; ev->mouse_pos = wasm_cached.mouse_pos; ev->mouse_delta = wasm_cached.mouse_delta; SLLQ_APPEND(wasm_frame.first_event, wasm_frame.last_event, ev); wasm_frame.event_count += 1; } fn void wasm_set_cached_mouse(v2f32_t p) { p = v2f32_muls(p, wasm_dpr); wasm_cached.mouse_delta = v2f32_sub(p, wasm_cached.mouse_pos); wasm_cached.mouse_pos = p; } fn void wasm_set_cached_buttons(b32 ctrl, b32 shift, b32 alt) { wasm_cached.ctrl = ctrl; wasm_cached.alt = alt; wasm_cached.shift = shift; } fn_wasm_export void wasm_mouse_move(f32 x, f32 y, b32 ctrl, b32 shift, b32 alt, b32 meta) { wasm_set_cached_mouse((v2f32_t){x, y}); wasm_set_cached_buttons(ctrl, shift, alt); } fn_wasm_export void wasm_mouse_down(f32 x, f32 y, i32 button, b32 ctrl, b32 shift, b32 alt, b32 meta) { button += 1; assert(button >= app_mouse_button_left && button <= app_mouse_button_right); wasm_set_cached_buttons(ctrl, shift, alt); wasm_set_cached_mouse((v2f32_t){x, y}); wasm_add_event((app_event_t){ .kind = app_event_kind_mouse_down, .mouse_button = button, }); } fn_wasm_export void wasm_mouse_up(f32 x, f32 y, i32 button, b32 ctrl, b32 shift, b32 alt, b32 meta) { button += 1; assert(button >= app_mouse_button_left && button <= app_mouse_button_right); wasm_set_cached_buttons(ctrl, shift, alt); wasm_set_cached_mouse((v2f32_t){x, y}); wasm_add_event((app_event_t){ .kind = app_event_kind_mouse_up, .mouse_button = button, }); } fn_wasm_export void wasm_mouse_wheel(f32 x, f32 y, f32 delta_x, f32 delta_y, f32 delta_z, b32 ctrl, b32 shift, b32 alt, b32 meta) { wasm_set_cached_mouse((v2f32_t){x, y}); wasm_set_cached_buttons(ctrl, shift, alt); wasm_add_event((app_event_t){ .kind = app_event_kind_mouse_wheel, .mouse_wheel_delta = {delta_x, -delta_y, delta_z}, }); } fn_wasm_export void wasm_key_down(char *key, b32 ctrl, b32 shift, b32 alt, b32 meta) { wasm_set_cached_buttons(ctrl, shift, alt); assert(wasm_temp_buff1[127] == 0x13); // make sure we didn't overwrite memory in JS assert(wasm_temp_buff2[127] == 0x13); s8_t key8 = s8_from_char(key); wasm_key_map_t map = wasm_map_key_string_to_app_key(key8); if (map.key != app_key_null) { wasm_add_event((app_event_t){ .kind = app_event_kind_key_down, .key = map.key, }); } if (map.filter_out) { return; } s8_t text = s8_copy(tcx.temp, key8); wasm_add_event((app_event_t){ .kind = app_event_kind_text, .text = text, }); } fn_wasm_export void wasm_key_up(char *key, b32 ctrl, b32 shift, b32 alt, b32 meta) { wasm_set_cached_buttons(ctrl, shift, alt); assert(wasm_temp_buff1[127] == 0x13); // make sure we didn't overwrite memory in JS assert(wasm_temp_buff2[127] == 0x13); s8_t key8 = s8_from_char(key); wasm_key_map_t map = wasm_map_key_string_to_app_key(key8); if (map.key != app_key_null) { wasm_add_event((app_event_t){ .kind = app_event_kind_key_up, .key = map.key, }); } } fn_wasm_export b32 wasm_update(f64 time, f32 width, f32 height, f32 dpr) { wasm_time = time; wasm_delta_time = wasm_time - wasm_last_time; wasm_dpr = dpr; if (wasm_frame.first_event == NULL) wasm_add_event((app_event_t){.kind = app_event_kind_update}); wasm_frame.window_size = (v2f32_t){width, height}; wasm_frame.dpr = wasm_dpr; wasm_frame.mouse_pos = wasm_frame.last_event->mouse_pos; wasm_frame.delta = wasm_delta_time; wasm_frame.frame = wasm_frame_counter; b32 animating = app_update(&wasm_frame); ma_set0(tcx.temp); zero_struct(&wasm_frame); wasm_last_time = wasm_time; wasm_frame_counter += 1; return animating; } fn_wasm_export void wasm_init(f32 dpr) { core_init(); app_init(dpr); }