diff options
Diffstat (limited to 'source/keyboard.c')
-rw-r--r-- | source/keyboard.c | 210 |
1 files changed, 197 insertions, 13 deletions
diff --git a/source/keyboard.c b/source/keyboard.c index 978d3d5..2c4d63f 100644 --- a/source/keyboard.c +++ b/source/keyboard.c @@ -22,10 +22,72 @@ #include <nds.h> #include "keyboard.h" +#include "framebuffer.h" #include "keyb_bin.h" /* ---------------------------------------- STATIC DATA */ +static uint16 white = FB_RGB(31, 31, 31); +static uint16 black = FB_RGB(0, 0, 0); + +static struct +{ + int state; + int new_state; + int handled; + int is_sticky; +} key_state[NUM_SOFT_KEYS]; + +static SoftKey pad_left_key = SK_O; +static SoftKey pad_right_key = SK_P; +static SoftKey pad_up_key = SK_Q; +static SoftKey pad_down_key = SK_A; +static SoftKey pad_A_key = SK_SPACE; +static SoftKey pad_B_key = SK_NEWLINE; +static SoftKey pad_X_key = NUM_SOFT_KEYS; +static SoftKey pad_Y_key = NUM_SOFT_KEYS; +static SoftKey pad_R_key = NUM_SOFT_KEYS; +static SoftKey pad_L_key = NUM_SOFT_KEYS; +static SoftKey pad_start_key = NUM_SOFT_KEYS; +static SoftKey pad_select_key = NUM_SOFT_KEYS; + +#define CHECK_STATE(KEYS,BIT,CODE,SHORTCUT) \ + do \ + { \ + key_state[CODE].new_state = (KEYS & BIT); \ + if (SHORTCUT != NUM_SOFT_KEYS && \ + !key_state[SHORTCUT].handled) \ + { \ + key_state[SHORTCUT].new_state = (KEYS & BIT); \ + } \ + } while(0) + + +/* ---------------------------------------- PRIVATE INTERFACES +*/ +static SoftKey LocatePress(const touchPosition *p) +{ + int kx=0,ky=0; + int py=0; + SoftKey key = NUM_SOFT_KEYS; + + if (p->py > 36 && p->px > 2) + { + kx = (p->px - 3) / 25; + ky = p->py - 37; + + py = ky % 30; + ky /= 30; + + if (py<17 && kx >= 0 && kx<10 && ky>=0 && ky<=4) + { + key = kx + ky * 10; + } + } + + return key; +} + /* ---------------------------------------- PUBLIC INTERFACES */ @@ -41,38 +103,160 @@ void SK_DisplayKeyboard(uint16 *vram) int SK_GetEvent(SoftKeyEvent *ev) { - uint32 key=0; - - key=keysDownRepeat(); + static SoftKey last = NUM_SOFT_KEYS; + static int poll_index = -1; - if (key & KEY_TOUCH) + /* Read the keys if this is a new loop + */ + if (poll_index == -1) { - touchPosition tp=touchReadXY(); + int f; + uint32 keys; + + scanKeys(); + + keys = keysHeld(); + + /* Clear the non-sticky keys + */ + for(f=SK_1; f<=SK_CONFIG; f++) + { + key_state[f].handled = FALSE; + + if (key_state[f].is_sticky) + { + key_state[f].new_state = key_state[f].state; + } + else + { + key_state[f].new_state = FALSE; + } + } + + /* Check the soft keyboard + */ + if (keys & KEY_TOUCH) + { + touchPosition tp=touchReadXY(); + + if (tp.py<21 || tp.py>165) + { + key_state[SK_CONFIG].new_state = TRUE; + } + else + { + SoftKey press; - /* - if (tp.px>=x && tp.px<(w+w) && tp.py>=y && tp.py<(y+h)) + press = LocatePress(&tp); + + if (press != NUM_SOFT_KEYS) + { + key_state[press].handled = TRUE; + + if (key_state[press].is_sticky) + { + if (last != press) + { + key_state[press].new_state = + !key_state[press].state; + } + } + else + { + key_state[press].new_state = TRUE; + } + + last = press; + } + } + } + else { - defer=true; - sel=(tp.py-y)/16; + last = NUM_SOFT_KEYS; } + + /* Check non soft-keyboard controls + */ + CHECK_STATE(keys, KEY_A, SK_PAD_A, pad_A_key); + CHECK_STATE(keys, KEY_B, SK_PAD_B, pad_B_key); + CHECK_STATE(keys, KEY_X, SK_PAD_X, pad_X_key); + CHECK_STATE(keys, KEY_Y, SK_PAD_Y, pad_Y_key); + CHECK_STATE(keys, KEY_R, SK_PAD_R, pad_R_key); + CHECK_STATE(keys, KEY_L, SK_PAD_L, pad_L_key); + CHECK_STATE(keys, KEY_START, SK_PAD_START, pad_start_key); + CHECK_STATE(keys, KEY_SELECT, SK_PAD_SELECT, pad_select_key); + CHECK_STATE(keys, KEY_UP, SK_PAD_UP, pad_up_key); + CHECK_STATE(keys, KEY_DOWN, SK_PAD_DOWN, pad_down_key); + CHECK_STATE(keys, KEY_LEFT, SK_PAD_LEFT, pad_left_key); + CHECK_STATE(keys, KEY_RIGHT, SK_PAD_RIGHT, pad_right_key); + + /* Reset key event poll index */ + poll_index = 0; - ev->key=SK_CONFIG; - ev->pressed=TRUE; - return 1; + /* Update any on-screen indicators + */ + for(f=SK_1; f<SK_CONFIG; f++) + { + if (key_state[f].state != key_state[f].new_state) + { + int x,y; + + x = 2 + (f % 10) * 25; + y = 36 + (f / 10) * 30; + + FB_Box(x, y, 26, 19, key_state[f].new_state ? white:black); + } + } } - return 0; + while(poll_index < NUM_SOFT_KEYS && + key_state[poll_index].state == key_state[poll_index].new_state) + { + poll_index++; + } + + if (poll_index < NUM_SOFT_KEYS) + { + key_state[poll_index].state = key_state[poll_index].new_state; + + ev->key = poll_index; + ev->pressed = key_state[poll_index].state; + + return TRUE; + } + else + { + poll_index = -1; + return FALSE; + } } void SK_SetSticky(SoftKey key, int is_sticky) { + key_state[key].is_sticky = is_sticky; + + if (!is_sticky) + { + key_state[key].new_state = FALSE; + } } void SK_ClearKeys(void) { + int f; + + for(f=0; f < NUM_SOFT_KEYS; f++) + { + key_state[f].state = FALSE; + } +} + + +void SK_DefineJoypad(void) +{ } |