wasm events to list, wm_char
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -2,6 +2,9 @@ backup
|
|||||||
build/
|
build/
|
||||||
*.wasm
|
*.wasm
|
||||||
*.o
|
*.o
|
||||||
MSVC/
|
|
||||||
|
*sublime-project*
|
||||||
|
*sublime-workspace*
|
||||||
|
|
||||||
multimedia.c
|
multimedia.c
|
||||||
multimedia.h
|
multimedia.h
|
||||||
@@ -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 char wasm_temp_buff2[128] = {[127] = 0x13};
|
||||||
glb_wasm_export i32 wasm_temp_buff2_len = 127;
|
glb_wasm_export i32 wasm_temp_buff2_len = 127;
|
||||||
|
|
||||||
// @todo: event list
|
|
||||||
global f64 wasm_dpr;
|
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_delta_time;
|
||||||
global f64 wasm_time;
|
global f64 wasm_time;
|
||||||
global f64 wasm_last_time_milliseconds;
|
global f64 wasm_last_time_milliseconds;
|
||||||
global f64 wasm_app_init_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;
|
typedef struct wasm_cached_t wasm_cached_t;
|
||||||
struct wasm_cached_t {
|
struct wasm_cached_t {
|
||||||
@@ -58,16 +55,13 @@ struct wasm_cached_t {
|
|||||||
b8 ctrl, alt, meta, shift;
|
b8 ctrl, alt, meta, shift;
|
||||||
} wasm_cached;
|
} 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 app_init(void);
|
||||||
|
|
||||||
fn void wasm_add_event(app_event_t event) {
|
fn void wasm_add_event(app_event_t event) {
|
||||||
if (wasm_events.len < lengthof(wasm_events.data)) {
|
app_event_t *ev = ma_push_type(tcx.temp, app_event_t);
|
||||||
STACK_PUSH(wasm_events, event);
|
SLLQ_APPEND(wasm_event_list.first, wasm_event_list.last, ev);
|
||||||
} else if (wasm_event_failed_to_queue == false) {
|
wasm_event_list.len += 1;
|
||||||
wasm_event_failed_to_queue = true;
|
|
||||||
debugf("failed to queue event");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn_wasm_export void wasm_mouse_move(f64 x, f64 y, b32 ctrl, b32 shift, b32 alt, b32 meta) {
|
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};
|
v2f64_t window_size = (v2f64_t){width / dpr, height / dpr};
|
||||||
wasm_dpr = dpr;
|
wasm_dpr = dpr;
|
||||||
|
|
||||||
if (wasm_events.len == 0) {
|
if (wasm_event_list.first == NULL) {
|
||||||
wasm_add_event((app_event_t){
|
wasm_add_event((app_event_t){
|
||||||
.kind = app_event_kind_update,
|
.kind = app_event_kind_update,
|
||||||
.mouse_pos = wasm_cached.mouse_pos,
|
.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) {
|
for (app_event_t *ev = wasm_event_list.first; ev; ev = ev->next) {
|
||||||
wasm_events.data[i].dpr = dpr;
|
ev->dpr = dpr;
|
||||||
wasm_events.data[i].window_size = window_size;
|
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;
|
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();
|
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) {
|
fn f64 app_get_anim_time(void) {
|
||||||
return wasm_time;
|
return wasm_time;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,9 +19,6 @@ HWND w32_window_handle;
|
|||||||
HDC w32_dc;
|
HDC w32_dc;
|
||||||
b32 w32_quit_app;
|
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) {
|
fn v2f64_t w32_get_window_size(HWND window) {
|
||||||
RECT window_rect;
|
RECT window_rect;
|
||||||
GetClientRect(window, &window_rect);
|
GetClientRect(window, &window_rect);
|
||||||
@@ -46,6 +43,11 @@ fn f64 w32_get_dpr(HWND window_handle) {
|
|||||||
return result;
|
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) {
|
fn void w32_push_event(app_event_t event) {
|
||||||
app_event_t *ev = ma_push_type(w32_event_arena, app_event_t);
|
app_event_t *ev = ma_push_type(w32_event_arena, app_event_t);
|
||||||
*ev = event;
|
*ev = event;
|
||||||
@@ -61,6 +63,25 @@ fn void w32_push_event(app_event_t event) {
|
|||||||
w32_event_list.len += 1;
|
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) {
|
fn LRESULT CALLBACK w32_window_proc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||||
switch (msg) {
|
switch (msg) {
|
||||||
case WM_CLOSE: {
|
case WM_CLOSE: {
|
||||||
@@ -134,13 +155,11 @@ fn LRESULT CALLBACK w32_window_proc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lp
|
|||||||
});
|
});
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
// @todo:
|
||||||
|
// WM_CHAR sends 2byte codepoints in 2 messages??????
|
||||||
case WM_CHAR: {
|
case WM_CHAR: {
|
||||||
//https://handmade.network/forums/t/2011-keyboard_inputs_-_scancodes,_raw_input,_text_input,_key_names
|
w32_push_wm_char_event(wparam);
|
||||||
// WM_UNICHAR
|
} break;
|
||||||
/*
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
default: return DefWindowProcW(wnd, msg, wparam, lparam);
|
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);
|
// 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_frame_start = os_seconds_now();
|
||||||
f64 time_delta = 0.01666666666666;
|
f64 time_delta = 1.0 / refresh_rate;
|
||||||
f64 time_total = 0.0;
|
f64 time_total = 0.0;
|
||||||
f64 time_update = 0.0;
|
f64 time_update = 0.0;
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,8 @@ typedef double f64;
|
|||||||
#define million(n) ((n)*1000000)
|
#define million(n) ((n)*1000000)
|
||||||
#define billion(n) ((n)*1000000000)
|
#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 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(type, size) struct { type data[size]; i32 len; }
|
||||||
#define STACK_PUSH(stack, ...) (assert((stack).len < lengthof((stack).data)), (stack).data[(stack).len++] = __VA_ARGS__)
|
#define STACK_PUSH(stack, ...) (assert((stack).len < lengthof((stack).data)), (stack).data[(stack).len++] = __VA_ARGS__)
|
||||||
|
|||||||
@@ -51,7 +51,10 @@ fn void core_init(void) {
|
|||||||
tcx._perm.data = memory;
|
tcx._perm.data = memory;
|
||||||
tcx._perm.commit = tcx._perm.reserve = memory_size;
|
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[0], mib(1));
|
||||||
ma_push_arena_ex(&tcx._perm, &tcx.scratch[1], kib(256));
|
ma_push_arena_ex(&tcx._perm, &tcx.scratch[1], kib(256));
|
||||||
ma_push_arena_ex(&tcx._perm, &tcx.scratch[2], kib(64));
|
ma_push_arena_ex(&tcx._perm, &tcx.scratch[2], kib(64));
|
||||||
|
|
||||||
|
tcx.temp = ma_push_arena(perm, mib(2));
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,11 @@ fn utf32_result_t utf16_to_utf32(uint16_t *c, int max_advance) {
|
|||||||
result.out_str = 0x10000;
|
result.out_str = 0x10000;
|
||||||
result.out_str += (uint32_t)(c[0] & 0x03FF) << 10u | (c[1] & 0x03FF);
|
result.out_str += (uint32_t)(c[0] & 0x03FF) << 10u | (c[1] & 0x03FF);
|
||||||
result.advance = 2;
|
result.advance = 2;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
result.error = 2;
|
result.error = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
result.error = 1;
|
result.error = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,20 +9,17 @@ gfx_t *gfx = NULL;
|
|||||||
|
|
||||||
void app_init(void) {
|
void app_init(void) {
|
||||||
ma_arena_t *perm = &tcx._perm;
|
ma_arena_t *perm = &tcx._perm;
|
||||||
tcx.temp = ma_push_arena(perm, mib(1));
|
|
||||||
gfx = ma_push_type(perm, gfx_t);
|
gfx = ma_push_type(perm, gfx_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
void app_update(void) {
|
void app_update(app_event_list_t events) {
|
||||||
ma_set0(tcx.temp);
|
for (app_event_t *ev = events.first; ev; ev = ev->next) {
|
||||||
|
|
||||||
for (app_event_t *ev = app_iterate_events(); app_is_event_valid(ev); app_next_event(&ev)) {
|
|
||||||
// update
|
// update
|
||||||
}
|
}
|
||||||
|
|
||||||
// These steps should be totally optional!!
|
// 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 delta = app_get_anim_delta_time();
|
||||||
f64 time = app_get_anim_time();
|
f64 time = app_get_anim_time();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user