diff options
author | Bad Diode <bd@badd10de.dev> | 2021-04-16 20:11:18 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-04-16 20:11:18 +0200 |
commit | afc0e9d93285b5bd2db808f3c5d735b566c2f8a6 (patch) | |
tree | c3e7427f39122e52c21efd3381cc7aad3a71dd56 | |
parent | 271ec55924819ae27d4f8349cc8f60e60411aad0 (diff) | |
download | gba-experiments-afc0e9d93285b5bd2db808f3c5d735b566c2f8a6.tar.gz gba-experiments-afc0e9d93285b5bd2db808f3c5d735b566c2f8a6.zip |
Implement key polling and example of usage for toggle and hold
-rw-r--r-- | src/main.c | 71 |
1 files changed, 42 insertions, 29 deletions
@@ -307,7 +307,7 @@ u32 profile_stop() { | |||
307 | // | 307 | // |
308 | 308 | ||
309 | // Memory address for key input register | 309 | // Memory address for key input register |
310 | #define KEY_INPUTS *((vu16*) 0x04000130) | 310 | #define KEY_INPUTS *((vu16*) 0x04000130) |
311 | 311 | ||
312 | // Alias for key pressing bits. | 312 | // Alias for key pressing bits. |
313 | #define KEY_A (1 << 0) | 313 | #define KEY_A (1 << 0) |
@@ -321,6 +321,33 @@ u32 profile_stop() { | |||
321 | #define KEY_R (1 << 8) | 321 | #define KEY_R (1 << 8) |
322 | #define KEY_L (1 << 9) | 322 | #define KEY_L (1 << 9) |
323 | 323 | ||
324 | #define KEY_MASK 0x03FF | ||
325 | |||
326 | // Saving the previous and current key states as globals for now. | ||
327 | static u16 key_curr = 0; | ||
328 | static u16 key_prev = 0; | ||
329 | |||
330 | static inline void | ||
331 | poll_keys() { | ||
332 | key_prev = key_curr; | ||
333 | key_curr = ~KEY_INPUTS & KEY_MASK; | ||
334 | } | ||
335 | |||
336 | // Returns true if the given key has been pressed at time of calling and was not | ||
337 | // pressed since the previous call. For example, if a key is being held, this | ||
338 | // function will return `true` only on the frame where the key initially | ||
339 | // activated. | ||
340 | static inline u32 | ||
341 | key_pressed(u32 key) { | ||
342 | return (key_curr & key) & ~(key_prev & key); | ||
343 | } | ||
344 | |||
345 | // Check if the given key is pressed and has been since at least one frame. | ||
346 | static inline u32 | ||
347 | key_hold(u32 key) { | ||
348 | return (key_curr & key) & key_prev & key; | ||
349 | } | ||
350 | |||
324 | // Check if the given key/button is currently pressed. | 351 | // Check if the given key/button is currently pressed. |
325 | #define KEY_PRESSED(key) (~(KEY_INPUTS) & key) | 352 | #define KEY_PRESSED(key) (~(KEY_INPUTS) & key) |
326 | 353 | ||
@@ -330,43 +357,29 @@ int main(void) { | |||
330 | draw_fill_rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, COLOR_GREY); | 357 | draw_fill_rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, COLOR_GREY); |
331 | 358 | ||
332 | int frame_counter = 0; | 359 | int frame_counter = 0; |
360 | bool toggle_key_down = false; | ||
333 | while(true) { | 361 | while(true) { |
334 | wait_vsync(); | 362 | wait_vsync(); |
335 | if (frame_counter++ > 30) { | 363 | if (frame_counter++ > 30) { |
336 | frame_counter = 0; | 364 | frame_counter = 0; |
337 | } | 365 | } |
366 | poll_keys(); | ||
338 | 367 | ||
339 | if (KEY_PRESSED(KEY_DOWN)) { | 368 | // Toggle frame counter when we press down. |
340 | put_text(8, 8, COLOR_RED, "down"); | 369 | if (key_pressed(KEY_DOWN)) { |
370 | toggle_key_down ^= 1; | ||
341 | } | 371 | } |
342 | else if (KEY_PRESSED(KEY_UP)) { | 372 | if (toggle_key_down) { |
343 | put_text(8, 8, COLOR_RED, "up"); | 373 | put_text(8, 8, COLOR_GREY, "TOGGLE: OFF"); |
344 | } | 374 | put_text(8, 8, COLOR_RED, "TOGGLE: ON"); |
345 | else if (KEY_PRESSED(KEY_LEFT)) { | 375 | } else { |
346 | put_text(8, 8, COLOR_RED, "left"); | 376 | put_text(8, 8, COLOR_GREY, "TOGGLE: ON"); |
347 | } | 377 | put_text(8, 8, COLOR_RED, "TOGGLE: OFF"); |
348 | else if (KEY_PRESSED(KEY_RIGHT)) { | ||
349 | put_text(8, 8, COLOR_RED, "right"); | ||
350 | } | ||
351 | else if (KEY_PRESSED(KEY_A)) { | ||
352 | put_text(8, 8, COLOR_RED, "A"); | ||
353 | } | ||
354 | else if (KEY_PRESSED(KEY_B)) { | ||
355 | put_text(8, 8, COLOR_RED, "B"); | ||
356 | } | ||
357 | else if (KEY_PRESSED(KEY_START)) { | ||
358 | put_text(8, 8, COLOR_RED, "start"); | ||
359 | } | ||
360 | else if (KEY_PRESSED(KEY_SELECT)) { | ||
361 | put_text(8, 8, COLOR_RED, "select"); | ||
362 | } | ||
363 | else if (KEY_PRESSED(KEY_L)) { | ||
364 | put_text(8, 8, COLOR_RED, "L"); | ||
365 | } | 378 | } |
366 | else if (KEY_PRESSED(KEY_R)) { | 379 | if (key_hold(KEY_DOWN)) { |
367 | put_text(8, 8, COLOR_RED, "R"); | 380 | put_text(8, 24, COLOR_RED, "HOLDING"); |
368 | } else { | 381 | } else { |
369 | draw_fill_rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, COLOR_GREY); | 382 | put_text(8, 24, COLOR_GREY, "HOLDING"); |
370 | } | 383 | } |
371 | }; | 384 | }; |
372 | 385 | ||