wasm events to list, wm_char

This commit is contained in:
krzosa
2025-01-03 08:24:40 +01:00
parent 6933566a86
commit 3cdfbd1957
7 changed files with 68 additions and 59 deletions

5
.gitignore vendored
View File

@@ -2,6 +2,9 @@ backup
build/
*.wasm
*.o
MSVC/
*sublime-project*
*sublime-workspace*
multimedia.c
multimedia.h

View File

@@ -42,15 +42,12 @@ glb_wasm_export i32 wasm_temp_buff1_len = 127;
glb_wasm_export char wasm_temp_buff2[128] = {[127] = 0x13};
glb_wasm_export i32 wasm_temp_buff2_len = 127;
// @todo: event list
global f64 wasm_dpr;
global STACK(app_event_t, 256) wasm_events;
global b32 wasm_event_failed_to_queue;
global f64 wasm_delta_time;
global f64 wasm_time;
global f64 wasm_last_time_milliseconds;
global f64 wasm_app_init_time_milliseconds;
global app_event_list_t wasm_event_list;
typedef struct wasm_cached_t wasm_cached_t;
struct wasm_cached_t {
@@ -58,16 +55,13 @@ struct wasm_cached_t {
b8 ctrl, alt, meta, shift;
} wasm_cached;
fn void app_update(void);
fn void app_update(app_event_list_t eventswasm_event_list);
fn void app_init(void);
fn void wasm_add_event(app_event_t event) {
if (wasm_events.len < lengthof(wasm_events.data)) {
STACK_PUSH(wasm_events, event);
} else if (wasm_event_failed_to_queue == false) {
wasm_event_failed_to_queue = true;
debugf("failed to queue event");
}
app_event_t *ev = ma_push_type(tcx.temp, app_event_t);
SLLQ_APPEND(wasm_event_list.first, wasm_event_list.last, ev);
wasm_event_list.len += 1;
}
fn_wasm_export void wasm_mouse_move(f64 x, f64 y, b32 ctrl, b32 shift, b32 alt, b32 meta) {
@@ -191,7 +185,7 @@ fn_wasm_export void wasm_update(f64 width, f64 height, f64 dpr) {
v2f64_t window_size = (v2f64_t){width / dpr, height / dpr};
wasm_dpr = dpr;
if (wasm_events.len == 0) {
if (wasm_event_list.first == NULL) {
wasm_add_event((app_event_t){
.kind = app_event_kind_update,
.mouse_pos = wasm_cached.mouse_pos,
@@ -202,14 +196,15 @@ fn_wasm_export void wasm_update(f64 width, f64 height, f64 dpr) {
});
}
for (i32 i = 0; i < wasm_events.len; i += 1) {
wasm_events.data[i].dpr = dpr;
wasm_events.data[i].window_size = window_size;
for (app_event_t *ev = wasm_event_list.first; ev; ev = ev->next) {
ev->dpr = dpr;
ev->window_size = window_size;
}
app_update();
app_update(wasm_event_list);
wasm_events.len = 0;
ma_set0(tcx.temp);
zero_struct(&wasm_event_list);
wasm_last_time_milliseconds = wasm_time;
}
@@ -219,22 +214,6 @@ fn_wasm_export void wasm_init(void) {
wasm_app_init_time_milliseconds = os_milliseconds_now();
}
fn app_event_t *app_iterate_events(void) {
return wasm_events.data;
}
fn b32 app_is_event_valid(app_event_t *event) {
return event < (wasm_events.data + wasm_events.len);
}
fn void app_next_event(app_event_t **event) {
event[0] += 1;
}
fn app_event_t *app_get_last_event(void) {
return wasm_events.data + wasm_events.len - 1;
}
fn f64 app_get_anim_time(void) {
return wasm_time;
}

View File

@@ -19,9 +19,6 @@ HWND w32_window_handle;
HDC w32_dc;
b32 w32_quit_app;
app_event_list_t w32_event_list;
ma_arena_t *w32_event_arena;
fn v2f64_t w32_get_window_size(HWND window) {
RECT window_rect;
GetClientRect(window, &window_rect);
@@ -46,6 +43,11 @@ fn f64 w32_get_dpr(HWND window_handle) {
return result;
}
///////////////////////////////
// event processing
app_event_list_t w32_event_list;
ma_arena_t *w32_event_arena;
fn void w32_push_event(app_event_t event) {
app_event_t *ev = ma_push_type(w32_event_arena, app_event_t);
*ev = event;
@@ -61,6 +63,25 @@ fn void w32_push_event(app_event_t event) {
w32_event_list.len += 1;
}
fn void w32_push_wm_char_event(WPARAM wparam) {
if (wparam >= 32 || wparam == 127) return;
s8_t string = s8_lit("?");
utf32_result_t encode = utf16_to_utf32((u16 *)&wparam, 1);
if (!encode.error) {
utf8_result_t encode8 = utf32_to_utf8(encode.out_str);
if (!encode8.error) {
string = s8(encode8.out_str, encode8.len);
string = s8_copy(w32_event_arena, string);
}
}
w32_push_event((app_event_t){
.kind = app_event_kind_text,
.text = string,
});
}
fn LRESULT CALLBACK w32_window_proc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam) {
switch (msg) {
case WM_CLOSE: {
@@ -134,13 +155,11 @@ fn LRESULT CALLBACK w32_window_proc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lp
});
} break;
case WM_CHAR: {
//https://handmade.network/forums/t/2011-keyboard_inputs_-_scancodes,_raw_input,_text_input,_key_names
// WM_UNICHAR
/*
I looked closer to how you process WM_CHAR in example code and I believe it is very wrong. wParam doesn't contain two ushorts joined in one 32-bit value. It is always one UTF-16 value. That means 16-bits. If Windows wants to send you unicode codepoint with value >0xFFFF, then it sends two UTF-16 WM_CHAR messages. Each with one part of UTF-16 surrogate pair. So your first WM_CHAR needs to remember it, and second one construct full unicode codepoint. For example, this is mentioned here: http://www.catch22.net/tuts/unicode-text-editing
*/
} break
// @todo:
// WM_CHAR sends 2byte codepoints in 2 messages??????
case WM_CHAR: {
w32_push_wm_char_event(wparam);
} break;
default: return DefWindowProcW(wnd, msg, wparam, lparam);
@@ -296,8 +315,14 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n
// w32_canvas_t canvas = w32_create_canvas(w32_window_handle);
f64 refresh_rate = 60;
DEVMODEW devmodew = {0};
if (EnumDisplaySettingsW(0, ENUM_CURRENT_SETTINGS, &devmodew)) {
refresh_rate = (f64)devmodew.dmDisplayFrequency;
}
f64 time_frame_start = os_seconds_now();
f64 time_delta = 0.01666666666666;
f64 time_delta = 1.0 / refresh_rate;
f64 time_total = 0.0;
f64 time_update = 0.0;

View File

@@ -62,6 +62,8 @@ typedef double f64;
#define million(n) ((n)*1000000)
#define billion(n) ((n)*1000000000)
#define zero_struct(x) memory_zero((x), sizeof(*(x)))
#define DEFER_LOOP(begin, end) for (i32 PASTE(_i_, __LINE__) = (begin, 0); !PASTE(_i_, __LINE__); PASTE(_i_, __LINE__) += (end, 1))
#define STACK(type, size) struct { type data[size]; i32 len; }
#define STACK_PUSH(stack, ...) (assert((stack).len < lengthof((stack).data)), (stack).data[(stack).len++] = __VA_ARGS__)

View File

@@ -51,7 +51,10 @@ fn void core_init(void) {
tcx._perm.data = memory;
tcx._perm.commit = tcx._perm.reserve = memory_size;
ma_arena_t *perm = &tcx._perm;
ma_push_arena_ex(&tcx._perm, &tcx.scratch[0], mib(1));
ma_push_arena_ex(&tcx._perm, &tcx.scratch[1], kib(256));
ma_push_arena_ex(&tcx._perm, &tcx.scratch[2], kib(64));
tcx.temp = ma_push_arena(perm, mib(2));
}

View File

@@ -8,11 +8,11 @@ fn utf32_result_t utf16_to_utf32(uint16_t *c, int max_advance) {
result.out_str = 0x10000;
result.out_str += (uint32_t)(c[0] & 0x03FF) << 10u | (c[1] & 0x03FF);
result.advance = 2;
}
else
} else {
result.error = 2;
}
}
}
else {
result.error = 1;
}

View File

@@ -9,20 +9,17 @@ gfx_t *gfx = NULL;
void app_init(void) {
ma_arena_t *perm = &tcx._perm;
tcx.temp = ma_push_arena(perm, mib(1));
gfx = ma_push_type(perm, gfx_t);
}
void app_update(void) {
ma_set0(tcx.temp);
for (app_event_t *ev = app_iterate_events(); app_is_event_valid(ev); app_next_event(&ev)) {
void app_update(app_event_list_t events) {
for (app_event_t *ev = events.first; ev; ev = ev->next) {
// update
}
// These steps should be totally optional!!
{
app_event_t *ev = app_get_last_event();
app_event_t *ev = events.last;
f64 delta = app_get_anim_delta_time();
f64 time = app_get_anim_time();