# HG changeset patch # User Mike Becker # Date 1749470560 -7200 # Node ID cd82643bb6d949e15c4628bc9c0110fe3aaceafb # Parent d190fe5315bd09753d65cca899ae714471aeeed9 implement edge-triggered key press/release diff -r d190fe5315bd -r cd82643bb6d9 src/ascension/input.h --- a/src/ascension/input.h Mon Jun 09 13:18:41 2025 +0200 +++ b/src/ascension/input.h Mon Jun 09 14:02:40 2025 +0200 @@ -28,8 +28,6 @@ #ifndef ASCENSION_INPUT_H #define ASCENSION_INPUT_H -#include "window.h" - #include typedef struct AscInput AscInput; @@ -55,19 +53,39 @@ * The index of the window, the mouse was last seen in. */ unsigned mouse_window; - bool keys[SDL_NUM_SCANCODES]; + /** + * State of the keys. + * @see asc_key_pressed() + * @see asc_key_released() + * @see asc_key_down() + * @see asc_key_up() + */ + unsigned char keys[SDL_NUM_SCANCODES]; }; +#define ASC_KEY_DOWN_FLAG 1u +#define ASC_KEY_PRESS_FLAG 2u +#define ASC_KEY_RELEASE_FLAG 4u + +#define ASC_KEY(name) SDL_SCANCODE_##name + +#define asc_key_down(scancode) \ + (asc_context.input.keys[scancode] & ASC_KEY_DOWN_FLAG) +#define asc_key_up(scancode) \ + (asc_context.input.keys[scancode] == 0) #define asc_key_pressed(scancode) \ - (asc_context.input.keys[SDL_SCANCODE_##scancode]) + (asc_context.input.keys[scancode] & ASC_KEY_PRESS_FLAG) +#define asc_key_released(scancode) \ + (asc_context.input.keys[scancode] & ASC_KEY_RELEASE_FLAG) #define asc_mouse_x asc_context.input.mouse_x #define asc_mouse_y asc_context.input.mouse_y #define asc_mouse_window asc_context.input.mouse_window -#define asc_mouse_pos (asc_vec2i) {asc_mouse_x, asc_mouse_y} +// TODO: think about whether this should be asc_vec2u +#define asc_mouse_pos ((asc_vec2i) {asc_mouse_x, asc_mouse_y}) #define asc_mouse_move_x asc_context.input.mouse_xrel #define asc_mouse_move_y asc_context.input.mouse_yrel -#define asc_mouse_move (asc_vec2i) {asc_mouse_move_x, asc_mouse_move_y} +#define asc_mouse_move ((asc_vec2i) {asc_mouse_move_x, asc_mouse_move_y}) #endif //ASCENSION_INPUT_H diff -r d190fe5315bd -r cd82643bb6d9 src/context.c --- a/src/context.c Mon Jun 09 13:18:41 2025 +0200 +++ b/src/context.c Mon Jun 09 14:02:40 2025 +0200 @@ -147,6 +147,11 @@ asc_context.input.mouse_xrel = 0; asc_context.input.mouse_yrel = 0; + // reset key flags + for (unsigned int i = 0 ; i < SDL_NUM_SCANCODES ; i++) { + asc_clear_flag(asc_context.input.keys[i], ASC_KEY_RELEASE_FLAG|ASC_KEY_PRESS_FLAG); + } + // dispatch SDL events SDL_Event event; while (SDL_PollEvent(&event)) { @@ -183,10 +188,14 @@ break; } case SDL_KEYDOWN: - asc_context.input.keys[event.key.keysym.scancode] = true; + // we only set the down and press flags if the key is not already known to be down + if (asc_key_up(event.key.keysym.scancode)) { + asc_set_flag(asc_context.input.keys[event.key.keysym.scancode], ASC_KEY_DOWN_FLAG|ASC_KEY_PRESS_FLAG); + } break; case SDL_KEYUP: - asc_context.input.keys[event.key.keysym.scancode] = false; + // we can directly set the release flag - it will be cleared next round + asc_context.input.keys[event.key.keysym.scancode] = ASC_KEY_RELEASE_FLAG; break; } } diff -r d190fe5315bd -r cd82643bb6d9 test/snake/snake.c --- a/test/snake/snake.c Mon Jun 09 13:18:41 2025 +0200 +++ b/test/snake/snake.c Mon Jun 09 14:02:40 2025 +0200 @@ -207,14 +207,13 @@ } // debug-key for clearing the shader registry - if (asc_key_pressed(S)) { - // TODO: implement edge-triggered key press handling + if (asc_key_pressed(ASC_KEY(S))) { asc_shader_clear_registry(); asc_dprintf("Shader cache cleared."); } // quit application on ESC key press - if (asc_key_pressed(ESCAPE)) { + if (asc_key_pressed(ASC_KEY(ESCAPE))) { asc_context_quit(); } } while (asc_loop_next());