From c8e297265f2b048c313ef46d903ebfef69e974f6 Mon Sep 17 00:00:00 2001 From: En Yi Date: Mon, 18 Aug 2025 20:49:29 +0800 Subject: [PATCH] Add global keybind for configuration later Changelog: - There is a action to key map in the engine. Each scene can use this keybind to figure out its own action map. - This is to build up configurable key binds later --- engine/engine.c | 17 +++++++++++++++++ engine/engine.h | 6 ++++++ level_test.c | 4 ++++ main.c | 7 +++++++ scenes/game_scene.c | 18 ++++++++---------- scenes/level_select_scene.c | 11 +++++++---- scenes/menu_scene.c | 11 +++++++---- 7 files changed, 56 insertions(+), 18 deletions(-) diff --git a/engine/engine.c b/engine/engine.c index 84f1dc7..51e3868 100644 --- a/engine/engine.c +++ b/engine/engine.c @@ -6,6 +6,7 @@ void init_engine(GameEngine_t* engine, Vector2 starting_win_size) { InitAudioDevice(); + sc_map_init_64(&engine->keybinds, 16, 0); sc_queue_init(&engine->key_buffer); sc_queue_init(&engine->scene_stack); sc_heap_init(&engine->scenes_render_order, 0); @@ -25,11 +26,27 @@ void deinit_engine(GameEngine_t* engine) sc_queue_term(&engine->key_buffer); sc_queue_term(&engine->scene_stack); sc_heap_term(&engine->scenes_render_order); + sc_map_term_64(&engine->keybinds); UnloadRenderTexture(engine->base_canvas); CloseAudioDevice(); CloseWindow(); } +void register_keybind(GameEngine_t* engine, int key, ActionType_t action) +{ + sc_map_put_64(&engine->keybinds, action, key); +} + +int get_keybind_or_default(GameEngine_t* engine, ActionType_t action, int default_key) +{ + int key = sc_map_get_64(&engine->keybinds, action); + if (!sc_map_found(&engine->keybinds)) + { + key = default_key; + }; + return key; +} + void process_inputs(GameEngine_t* engine, Scene_t* scene) { Vector2 raw_mouse_pos = GetMousePosition(); diff --git a/engine/engine.h b/engine/engine.h index 14bbeed..fd5327d 100644 --- a/engine/engine.h +++ b/engine/engine.h @@ -31,6 +31,7 @@ typedef struct GameEngine { SFXList_t sfx_list; // Maintain own queue to handle key presses Scene_t* focused_scene; // The one scene to receive key inputs + struct sc_map_64 keybinds; // Global action -> key mapping struct sc_queue_32 key_buffer; struct sc_queue_ptr scene_stack; struct sc_heap scenes_render_order; @@ -85,6 +86,11 @@ void init_engine(GameEngine_t* engine, Vector2 starting_win_size); void deinit_engine(GameEngine_t* engine); void process_inputs(GameEngine_t* engine, Scene_t* scene); +// Register a key bind. If already exists, will override. +// Does not support multi key to an action +void register_keybind(GameEngine_t* engine, int key, ActionType_t action); +int get_keybind_or_default(GameEngine_t* engine, ActionType_t action, int default_key); + void process_active_scene_inputs(GameEngine_t* engine); void update_curr_scene(GameEngine_t* engine); void render_curr_scene(GameEngine_t* engine); diff --git a/level_test.c b/level_test.c index c79c16b..4d1beaa 100644 --- a/level_test.c +++ b/level_test.c @@ -57,6 +57,10 @@ int main(int argc, char** argv) LevelScene_t level_scene; level_scene.scene.engine = &engine; init_game_scene(&level_scene); + + sc_map_put_64(&level_scene.scene.action_map, KEY_RIGHT_BRACKET, ACTION_NEXTLEVEL); + sc_map_put_64(&level_scene.scene.action_map, KEY_LEFT_BRACKET, ACTION_PREVLEVEL); + level_scene.data.tile_sprites[ONEWAY_TILE] = get_sprite(&engine.assets, "tl_owp"); level_scene.data.tile_sprites[LADDER] = get_sprite(&engine.assets, "tl_ldr"); level_scene.data.tile_sprites[SPIKES] = get_sprite(&engine.assets, "d_spikes"); diff --git a/main.c b/main.c index 1d05980..cb94d28 100644 --- a/main.c +++ b/main.c @@ -37,6 +37,13 @@ int main(void) init_player_creation_rres("res/assets.rres", "player_spr.info", &engine.assets); #endif init_item_creation(&engine.assets); + register_keybind(&engine, KEY_UP, ACTION_UP); + register_keybind(&engine, KEY_DOWN, ACTION_DOWN); + register_keybind(&engine, KEY_LEFT, ACTION_LEFT); + register_keybind(&engine, KEY_RIGHT, ACTION_RIGHT); + register_keybind(&engine, KEY_SPACE, ACTION_JUMP); + register_keybind(&engine, KEY_Q, ACTION_EXIT); + register_keybind(&engine, KEY_Z, ACTION_LOOKAHEAD); load_sfx(&engine, "snd_jump", PLAYER_JMP_SFX); load_sfx(&engine, "snd_land", PLAYER_LAND_SFX); diff --git a/scenes/game_scene.c b/scenes/game_scene.c index aedd2c8..1cd84b4 100644 --- a/scenes/game_scene.c +++ b/scenes/game_scene.c @@ -600,17 +600,15 @@ void init_game_scene(LevelScene_t* scene) // This avoid graphical glitch, not essential //sc_array_add(&scene->scene.systems, &update_tilemap_system); - sc_map_put_64(&scene->scene.action_map, KEY_UP, ACTION_UP); - sc_map_put_64(&scene->scene.action_map, KEY_DOWN, ACTION_DOWN); - sc_map_put_64(&scene->scene.action_map, KEY_LEFT, ACTION_LEFT); - sc_map_put_64(&scene->scene.action_map, KEY_RIGHT, ACTION_RIGHT); - sc_map_put_64(&scene->scene.action_map, KEY_SPACE, ACTION_JUMP); - sc_map_put_64(&scene->scene.action_map, KEY_Q, ACTION_EXIT); - sc_map_put_64(&scene->scene.action_map, KEY_R, ACTION_RESTART); - sc_map_put_64(&scene->scene.action_map, KEY_RIGHT_BRACKET, ACTION_NEXTLEVEL); - sc_map_put_64(&scene->scene.action_map, KEY_LEFT_BRACKET, ACTION_PREVLEVEL); - sc_map_put_64(&scene->scene.action_map, KEY_Z, ACTION_LOOKAHEAD); + sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_UP, KEY_UP), ACTION_UP); + sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_DOWN, KEY_DOWN), ACTION_DOWN); + sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_LEFT, KEY_LEFT), ACTION_LEFT); + sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_RIGHT, KEY_RIGHT), ACTION_RIGHT); + sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_JUMP, KEY_ENTER), ACTION_JUMP); + sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_EXIT, KEY_Q), ACTION_EXIT); + sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_LOOKAHEAD, KEY_Z), ACTION_LOOKAHEAD); + sc_map_put_64(&scene->scene.action_map, KEY_R, ACTION_RESTART); } void free_game_scene(LevelScene_t* scene) diff --git a/scenes/level_select_scene.c b/scenes/level_select_scene.c index 4989bfc..2883c3e 100644 --- a/scenes/level_select_scene.c +++ b/scenes/level_select_scene.c @@ -297,11 +297,14 @@ void init_level_select_scene(LevelSelectScene_t* scene) sc_array_add(&scene->scene.systems, &level_preview_render_func); sc_array_add(&scene->scene.systems, &level_select_render_func); - sc_map_put_64(&scene->scene.action_map, KEY_UP, ACTION_UP); - sc_map_put_64(&scene->scene.action_map, KEY_DOWN, ACTION_DOWN); - sc_map_put_64(&scene->scene.action_map, KEY_Q, ACTION_EXIT); + + sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_UP, KEY_UP), ACTION_UP); + sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_DOWN, KEY_DOWN), ACTION_DOWN); + sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_JUMP, KEY_ENTER), ACTION_CONFIRM); + sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_EXIT, KEY_Q), ACTION_EXIT); + + sc_map_put_64(&scene->scene.action_map, KEY_BACKSPACE, ACTION_EXIT); sc_map_put_64(&scene->scene.action_map, KEY_ENTER, ACTION_CONFIRM); - sc_map_put_64(&scene->scene.action_map, MOUSE_LEFT_BUTTON, ACTION_NEXT_SPAWN); // Abuse an unused action } void free_level_select_scene(LevelSelectScene_t* scene) { diff --git a/scenes/menu_scene.c b/scenes/menu_scene.c index a34675c..1da560d 100644 --- a/scenes/menu_scene.c +++ b/scenes/menu_scene.c @@ -202,10 +202,13 @@ void init_menu_scene(MenuScene_t* scene) } ); - sc_map_put_64(&scene->scene.action_map, KEY_UP, ACTION_UP); - sc_map_put_64(&scene->scene.action_map, KEY_DOWN, ACTION_DOWN); - sc_map_put_64(&scene->scene.action_map, KEY_LEFT, ACTION_LEFT); - sc_map_put_64(&scene->scene.action_map, KEY_RIGHT, ACTION_RIGHT); + + sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_UP, KEY_UP), ACTION_UP); + sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_DOWN, KEY_DOWN), ACTION_DOWN); + sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_LEFT, KEY_LEFT), ACTION_LEFT); + sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_RIGHT, KEY_RIGHT), ACTION_RIGHT); + sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_JUMP, KEY_ENTER), ACTION_CONFIRM); + // Guarantee a enter key for selection sc_map_put_64(&scene->scene.action_map, KEY_ENTER, ACTION_CONFIRM); }