From afc0e9d93285b5bd2db808f3c5d735b566c2f8a6 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Fri, 16 Apr 2021 20:11:18 +0200 Subject: Implement key polling and example of usage for toggle and hold --- src/main.c | 71 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/src/main.c b/src/main.c index 28239cc..f684530 100644 --- a/src/main.c +++ b/src/main.c @@ -307,7 +307,7 @@ u32 profile_stop() { // // Memory address for key input register -#define KEY_INPUTS *((vu16*) 0x04000130) +#define KEY_INPUTS *((vu16*) 0x04000130) // Alias for key pressing bits. #define KEY_A (1 << 0) @@ -321,6 +321,33 @@ u32 profile_stop() { #define KEY_R (1 << 8) #define KEY_L (1 << 9) +#define KEY_MASK 0x03FF + +// Saving the previous and current key states as globals for now. +static u16 key_curr = 0; +static u16 key_prev = 0; + +static inline void +poll_keys() { + key_prev = key_curr; + key_curr = ~KEY_INPUTS & KEY_MASK; +} + +// Returns true if the given key has been pressed at time of calling and was not +// pressed since the previous call. For example, if a key is being held, this +// function will return `true` only on the frame where the key initially +// activated. +static inline u32 +key_pressed(u32 key) { + return (key_curr & key) & ~(key_prev & key); +} + +// Check if the given key is pressed and has been since at least one frame. +static inline u32 +key_hold(u32 key) { + return (key_curr & key) & key_prev & key; +} + // Check if the given key/button is currently pressed. #define KEY_PRESSED(key) (~(KEY_INPUTS) & key) @@ -330,43 +357,29 @@ int main(void) { draw_fill_rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, COLOR_GREY); int frame_counter = 0; + bool toggle_key_down = false; while(true) { wait_vsync(); if (frame_counter++ > 30) { frame_counter = 0; } + poll_keys(); - if (KEY_PRESSED(KEY_DOWN)) { - put_text(8, 8, COLOR_RED, "down"); + // Toggle frame counter when we press down. + if (key_pressed(KEY_DOWN)) { + toggle_key_down ^= 1; } - else if (KEY_PRESSED(KEY_UP)) { - put_text(8, 8, COLOR_RED, "up"); - } - else if (KEY_PRESSED(KEY_LEFT)) { - put_text(8, 8, COLOR_RED, "left"); - } - else if (KEY_PRESSED(KEY_RIGHT)) { - put_text(8, 8, COLOR_RED, "right"); - } - else if (KEY_PRESSED(KEY_A)) { - put_text(8, 8, COLOR_RED, "A"); - } - else if (KEY_PRESSED(KEY_B)) { - put_text(8, 8, COLOR_RED, "B"); - } - else if (KEY_PRESSED(KEY_START)) { - put_text(8, 8, COLOR_RED, "start"); - } - else if (KEY_PRESSED(KEY_SELECT)) { - put_text(8, 8, COLOR_RED, "select"); - } - else if (KEY_PRESSED(KEY_L)) { - put_text(8, 8, COLOR_RED, "L"); + if (toggle_key_down) { + put_text(8, 8, COLOR_GREY, "TOGGLE: OFF"); + put_text(8, 8, COLOR_RED, "TOGGLE: ON"); + } else { + put_text(8, 8, COLOR_GREY, "TOGGLE: ON"); + put_text(8, 8, COLOR_RED, "TOGGLE: OFF"); } - else if (KEY_PRESSED(KEY_R)) { - put_text(8, 8, COLOR_RED, "R"); + if (key_hold(KEY_DOWN)) { + put_text(8, 24, COLOR_RED, "HOLDING"); } else { - draw_fill_rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, COLOR_GREY); + put_text(8, 24, COLOR_GREY, "HOLDING"); } }; -- cgit v1.2.1