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
main
En Yi 2025-08-18 20:49:29 +08:00
parent ee1f0ef62a
commit c8e297265f
7 changed files with 56 additions and 18 deletions

View File

@ -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();

View File

@ -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);

View File

@ -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");

7
main.c
View File

@ -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);

View File

@ -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)

View File

@ -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)
{

View File

@ -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);
}