a-game

2D platformer written from scratch.
git clone git://git.amin.space/a-game.git
Log | Files | Refs | README | LICENSE

commit b687b427c267ffbfbc2c9a614c5a6c823b9aa0a9
parent 728a0a52d0964c1cc74c39466ad2828db6e82b5d
Author: amin <dev@aminmesbah.com>
Date:   Mon,  1 Jul 2019 23:05:58 +0000

Get keyboard input via the browser

FossilOrigin-Name: 9a06e01254efa2325c33260368021123adbd136eb6c2327810faa1ebadb95d08
Diffstat:
Mbuild_wasm.sh | 1+
Msrc/platform_wasm.c | 59++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Msrc/platform_wasm_loader.js | 20++++++++++++++++++++
3 files changed, 73 insertions(+), 7 deletions(-)

diff --git a/build_wasm.sh b/build_wasm.sh @@ -36,6 +36,7 @@ wasm-ld \ --export=init \ --export=render \ --export=window_resize \ + --export=key_callback \ --import-memory rm $wasm_dir/*.o diff --git a/src/platform_wasm.c b/src/platform_wasm.c @@ -4,14 +4,35 @@ extern unsigned char __heap_base; -struct GameMemory game_memory = {0}; -struct GameInput game_input = {0}; -i32 g_width = PLATFORM_SCR_WIDTH; -i32 g_height = PLATFORM_SCR_HEIGHT; +// There's no standardized, nondeprecated way to get a numeric ID of a keyboard +// key, so I guess we have to do that ourselves. +enum WasmKey { + WASM_KEY_LEFT, + WASM_KEY_RIGHT, + WASM_KEY_UP, + WASM_KEY_DOWN, + WASM_KEY_S, + WASM_KEY_F11, +}; + +// TODO: map this in a nicer way +global_variable int platform_input_map[NUM_GAME_BUTTONS] = { + [BTN_LEFT] = WASM_KEY_LEFT, + [BTN_RIGHT] = WASM_KEY_RIGHT, + [BTN_UP] = WASM_KEY_UP, + [BTN_DOWN] = WASM_KEY_DOWN, + [BTN_JUMP] = WASM_KEY_S, + [BTN_DEBUG_FLOAT] = WASM_KEY_F11, +}; + +global_variable struct GameMemory game_memory = {0}; +global_variable struct GameInput game_input = {0}; +global_variable i32 g_width = PLATFORM_SCR_WIDTH; +global_variable i32 g_height = PLATFORM_SCR_HEIGHT; // TODO: replace with allocator -char g_mem_buffer[1000] = {0}; -i32 g_mem_buffer_i = 0; -u32 time = 0; +global_variable char g_mem_buffer[1000] = {0}; +global_variable i32 g_mem_buffer_i = 0; +global_variable u32 time = 0; i32 str_length(const char *str) { @@ -64,6 +85,30 @@ void window_resize(int w, int h) glViewport(0, 0, g_width, g_height); } +void key_callback(enum WasmKey key, bool key_action_is_pressed) +{ + enum GameButton game_button = NULL_GAME_BUTTON; + // TODO: Determine the button in a nicer way + for (enum GameButton b = 0; b < NUM_GAME_BUTTONS; b++) + { + if (platform_input_map[b] == key) + { + game_button = b; + } + } + if (game_button != NULL_GAME_BUTTON) + { + if (key_action_is_pressed) + { + game_input.button_states |= (1 << game_button); + } + else + { + game_input.button_states &= ~(1 << game_button); + } + } +} + PLATFORM_MEMORY_FREE(wasm_memory_free) { // do nothing diff --git a/src/platform_wasm_loader.js b/src/platform_wasm_loader.js @@ -6,6 +6,18 @@ let files = []; let gl = null; let gl_id_freelist = []; let gl_id_map = [null]; +// NOTE(amin): These values _must_ match the corresponding ones used by the +// platform layer in `enum WasmKey`. +// By the way: Thanks a lot, W3C, for not having any standardized _numeric_ +// representation of a key. +const key_numeric_codes = { + ArrowLeft: 0, + ArrowRight: 1, + ArrowUp: 2, + ArrowDown: 3, + KeyS: 4, + F11: 5, +}; imports["webglAttachShader"] = function(program_id, shader_id) { let program = gl_id_map[program_id]; let shader = gl_id_map[shader_id]; @@ -215,6 +227,12 @@ function file_load(name) { }); return promise; } +function on_key_event(e, key_is_down) { + let sane_numeric_code = key_numeric_codes[e.code]; + if (sane_numeric_code !== undefined) { + exports['key_callback'](sane_numeric_code, key_is_down); + } +} window.onload = async function() { let ctxopts = { alpha: false, @@ -241,6 +259,8 @@ window.onload = async function() { exports = instance['exports']; canvas_resize(); window.addEventListener("resize", canvas_resize); + window.addEventListener("keyup", (event) => {on_key_event(event, false)}, false); + window.addEventListener("keydown", (event) => {on_key_event(event, true)}, false); if(!exports['init']()) { error_fatal("Game initialization failed."); }