diff options
-rw-r--r-- | source/nds/gui.c | 135 |
1 files changed, 95 insertions, 40 deletions
diff --git a/source/nds/gui.c b/source/nds/gui.c index 67de6cd..8b645fe 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -330,17 +330,53 @@ static void quit(void); /*-------------------------------------------------------- Get GUI input --------------------------------------------------------*/ +#define BUTTON_REPEAT_START (21428 / 2) +#define BUTTON_REPEAT_CONTINUE (21428 / 20) + +u32 button_repeat_timestamp; + +typedef enum +{ + BUTTON_NOT_HELD, + BUTTON_HELD_INITIAL, + BUTTON_HELD_REPEAT +} button_repeat_state_type; + +button_repeat_state_type button_repeat_state = BUTTON_NOT_HELD; +unsigned int gui_button_repeat = 0; + +gui_action_type key_to_cursor(unsigned int key) +{ + switch (key) + { + case KEY_UP: return CURSOR_UP; + case KEY_DOWN: return CURSOR_DOWN; + case KEY_LEFT: return CURSOR_LEFT; + case KEY_RIGHT: return CURSOR_RIGHT; + case KEY_L: return CURSOR_LTRIGGER; + case KEY_R: return CURSOR_RTRIGGER; + case KEY_A: return CURSOR_SELECT; + case KEY_B: return CURSOR_BACK; + case KEY_X: return CURSOR_EXIT; + case KEY_TOUCH: return CURSOR_TOUCH; + default: return CURSOR_NONE; + } +} + +static unsigned int gui_keys[] = { + KEY_A, KEY_B, KEY_X, KEY_L, KEY_R, KEY_TOUCH, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT +}; + gui_action_type get_gui_input(void) { - unsigned int key; gui_action_type ret; - key = getKey(); + struct key_buf inputdata; + ds2_getrawInput(&inputdata); - if (key & KEY_LID) + if (inputdata.key & KEY_LID) { ds2_setSupend(); - struct key_buf inputdata; do { ds2_getrawInput(&inputdata); mdelay(1); @@ -352,44 +388,63 @@ gui_action_type get_gui_input(void) // ds2_setBacklight(3); } - switch(key) + unsigned int i; + while (1) { - case KEY_UP: - ret = CURSOR_UP; - break; - case KEY_DOWN: - ret = CURSOR_DOWN; - break; - case KEY_LEFT: - ret = CURSOR_LEFT; - break; - case KEY_RIGHT: - ret = CURSOR_RIGHT; - break; - case KEY_L: - ret = CURSOR_LTRIGGER; - break; - case KEY_R: - ret = CURSOR_RTRIGGER; - break; - case KEY_A: - ret = CURSOR_SELECT; - break; - case KEY_B: - ret = CURSOR_BACK; - break; - case KEY_X: - ret = CURSOR_EXIT; - break; - case KEY_TOUCH: - ret = CURSOR_TOUCH; - break; - default: - ret = CURSOR_NONE; - break; + switch (button_repeat_state) + { + case BUTTON_NOT_HELD: + // Pick the first pressed button out of the gui_keys array. + for (i = 0; i < sizeof(gui_keys) / sizeof(gui_keys[0]); i++) + { + if (inputdata.key & gui_keys[i]) + { + button_repeat_state = BUTTON_HELD_INITIAL; + button_repeat_timestamp = getSysTime(); + gui_button_repeat = gui_keys[i]; + return key_to_cursor(gui_keys[i]); + } + } + return CURSOR_NONE; + case BUTTON_HELD_INITIAL: + case BUTTON_HELD_REPEAT: + // If the key that was being held isn't anymore... + if (!(inputdata.key & gui_button_repeat)) + { + button_repeat_state = BUTTON_NOT_HELD; + // Go see if another key is held (try #2) + break; + } + else + { + unsigned int IsRepeatReady = getSysTime() - button_repeat_timestamp >= (button_repeat_state == BUTTON_HELD_INITIAL ? BUTTON_REPEAT_START : BUTTON_REPEAT_CONTINUE); + if (!IsRepeatReady) + { + // Temporarily turn off the key. + // It's not its turn to be repeated. + inputdata.key &= ~gui_button_repeat; + } + + // Pick the first pressed button out of the gui_keys array. + for (i = 0; i < sizeof(gui_keys) / sizeof(gui_keys[0]); i++) + { + if (inputdata.key & gui_keys[i]) + { + // If it's the held key, + // it's now repeating quickly. + button_repeat_state = gui_keys[i] == gui_button_repeat ? BUTTON_HELD_REPEAT : BUTTON_HELD_INITIAL; + button_repeat_timestamp = getSysTime(); + gui_button_repeat = gui_keys[i]; + return key_to_cursor(gui_keys[i]); + } + } + // If it was time for the repeat but it + // didn't occur, stop repeating. + if (IsRepeatReady) button_repeat_state = BUTTON_NOT_HELD; + return CURSOR_NONE; + } + } } - - return ret; } /*-------------------------------------------------------- |