src/keyboard.c

Thu, 30 Dec 2010 00:37:03 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Thu, 30 Dec 2010 00:37:03 +0000
changeset 86
ebce87d87808
parent 74
51cbc7a44cd9
child 90
934ae2efdd01
permissions
-rw-r--r--

add keyboard event handler; need to do register r/w next.

philpem@74 1 #include "SDL.h"
philpem@86 2 #include "keyboard.h"
philpem@74 3
philpem@74 4 /**
philpem@74 5 * Key map -- a mapping from SDLK_xxx constants to scancodes and vice versa.
philpem@74 6 */
philpem@74 7 struct {
philpem@74 8 SDLKey key; ///< SDLK_xxx key code constant
philpem@74 9 int extended; ///< 1 if this is an extended keycode
philpem@74 10 unsigned char scancode; ///< Keyboard scan code
philpem@74 11 } keymap[] = {
philpem@74 12 { SDLK_UP, 0, 0x01 }, // ROLL/Up [UpArrow]
philpem@74 13 { SDLK_KP2, 0, 0x01 }, // ROLL/Up [Keypad 2]
philpem@74 14 // { SDLK_, 1, 0x02 }, // Clear Line
philpem@74 15 // { SDLK_, 1, 0x03 }, // Rstrt / Ref
philpem@74 16 // { SDLK_, 1, 0x04 }, // Exit
philpem@74 17 { SDLK_KP1, 0, 0x05 }, // PREV [Keypad 1]
philpem@74 18 // { SDLK_, 1, 0x06 }, // Msg
philpem@74 19 // { SDLK_, 1, 0x07 }, // Cancl
philpem@74 20 { SDLK_BACKSPACE, 0, 0x08 }, // Backspace
philpem@74 21 { SDLK_TAB, 0, 0x09 }, // Tab
philpem@74 22 // { SDLK_RETURN, 1, 0x0a }, // ENTER
philpem@74 23 { SDLK_DOWN, 0, 0x0b }, // ROLL/Down [DownArrow]
philpem@74 24 { SDLK_KP0, 0, 0x0b }, // ROLL/Down [Keypad 0]
philpem@74 25 { SDLK_KP3, 0, 0x0c }, // NEXT [Keypad 3]
philpem@74 26 { SDLK_RETURN, 0, 0x0d }, // RETURN [Return]
philpem@74 27 { SDLK_LEFT, 0, 0x0e }, // <-- [LeftArrow]
philpem@74 28 { SDLK_KP_MINUS, 0, 0x0e }, // <-- [Keypad -]
philpem@74 29 { SDLK_RIGHT, 0, 0x0f }, // --> [RightArrow]
philpem@74 30 { SDLK_KP_PERIOD, 0, 0x0f }, // --> [Keypad .]
philpem@74 31 // { SDLK_, 1, 0x10 }, // Creat
philpem@74 32 // { SDLK_, 1, 0x11 }, // Save
philpem@74 33 // { SDLK_, 1, 0x12 }, // Move
philpem@74 34 // { SDLK_, 1, 0x13 }, // Ops
philpem@74 35 // { SDLK_, 1, 0x14 }, // Copy
philpem@74 36 { SDLK_F1, 0, 0x15 }, // F1
philpem@74 37 { SDLK_F2, 0, 0x16 }, // F2
philpem@74 38 { SDLK_F3, 0, 0x17 }, // F3
philpem@74 39 { SDLK_F4, 0, 0x18 }, // F4
philpem@74 40 { SDLK_F5, 0, 0x19 }, // F5
philpem@74 41 { SDLK_F6, 0, 0x1a }, // F6
philpem@74 42 { SDLK_ESCAPE, 0, 0x1b }, // ESC/DEL [Escape]
philpem@74 43 { SDLK_F7, 0, 0x1c }, // F7
philpem@74 44 { SDLK_F8, 0, 0x1d }, // F8
philpem@74 45 // { SDLK_, 1, 0x1e }, // Suspd
philpem@74 46 // { SDLK_, 1, 0x1f }, // Rsume
philpem@74 47 { SDLK_SPACE, 0, 0x20 }, // SPACE [Spacebar]
philpem@74 48 // { SDLK_, 1, 0x21 }, // Undo
philpem@74 49 // { SDLK_, 1, 0x22 }, // Redo
philpem@74 50 // { SDLK_, 1, 0x23 }, // FIND
philpem@74 51 // { SDLK_, 1, 0x24 }, // RPLAC
philpem@74 52 { SDLK_BREAK, 0, 0x25 }, // RESET/BREAK [Pause/Break]
philpem@74 53 // { SDLK_, 1, 0x26 }, // DleteChar
philpem@74 54 { SDLK_QUOTE, 0, 0x27 }, // ' (single-quote)
philpem@74 55 // { SDLK_, 1, 0x28 }, // SLCT/MARK
philpem@74 56 // { SDLK_, 1, 0x29 }, // INPUT/MODE
philpem@74 57 // { SDLK_, 1, 0x2a }, // HELP
philpem@74 58 // Keycode 2B not used
philpem@74 59 { SDLK_COMMA, 0, 0x2c }, // , [Comma]
philpem@74 60 { SDLK_MINUS, 0, 0x2d }, // - [Dash]
philpem@74 61 { SDLK_PERIOD, 0, 0x2e }, // . [Period]
philpem@74 62 { SDLK_SLASH, 0, 0x2f }, // / [Forward-slash]
philpem@74 63 { SDLK_0, 0, 0x30 }, // 0
philpem@74 64 { SDLK_1, 0, 0x31 }, // 1
philpem@74 65 { SDLK_2, 0, 0x32 }, // 2
philpem@74 66 { SDLK_3, 0, 0x33 }, // 3
philpem@74 67 { SDLK_4, 0, 0x34 }, // 4
philpem@74 68 { SDLK_5, 0, 0x35 }, // 5
philpem@74 69 { SDLK_6, 0, 0x36 }, // 6
philpem@74 70 { SDLK_7, 0, 0x37 }, // 7
philpem@74 71 { SDLK_8, 0, 0x38 }, // 8
philpem@74 72 { SDLK_9, 0, 0x39 }, // 9
philpem@74 73 // Keycode 3A not used
philpem@74 74 { SDLK_SEMICOLON, 0, 0x3b }, // ; [Semicolon]
philpem@74 75 // Keycode 3C not used
philpem@74 76 { SDLK_EQUALS, 0, 0x3d }, // = [Equals]
philpem@86 77 // Keycode 3E not used
philpem@86 78 // Keycode 3F = BOGUS (Bad Keycode)
philpem@86 79 // Keycode 40 = All Up
philpem@74 80 // { SDLK_, 1, 0x41 }, // CMD
philpem@74 81 // { SDLK_, 1, 0x42 }, // CLOSE/OPEN
philpem@74 82 { SDLK_KP7, 0, 0x43 }, // PRINT
philpem@74 83 { SDLK_KP8, 0, 0x44 }, // CLEAR/RFRSH
philpem@74 84 { SDLK_CAPSLOCK, 0, 0x45 }, // Caps Lock
philpem@74 85 { SDLK_KP9, 0, 0x46 }, // PAGE
philpem@74 86 { SDLK_KP4, 0, 0x47 }, // BEG
philpem@74 87 { SDLK_LSHIFT, 0, 0x48 }, // Left Shift
philpem@74 88 { SDLK_RSHIFT, 0, 0x49 }, // Right Shift
philpem@74 89 { SDLK_HOME, 0, 0x4a }, // Home
philpem@74 90 { SDLK_KP5, 0, 0x4a }, // Home [Keypad 5]
philpem@74 91 { SDLK_END, 0, 0x4b }, // End
philpem@74 92 { SDLK_KP6, 0, 0x4b }, // End [Keypad 6]
philpem@86 93 { SDLK_LCTRL, 0, 0x4c }, // Left Ctrl
philpem@86 94 { SDLK_RCTRL, 0, 0x4d }, // Right Ctrl
philpem@74 95 // Keycodes 4E thru 5A not used
philpem@74 96 { SDLK_LEFTBRACKET, 0, 0x5b }, // [
philpem@74 97 { SDLK_BACKSLASH, 0, 0x5c }, // \ (backslash)
philpem@74 98 { SDLK_RIGHTBRACKET, 0, 0x5d }, // ]
philpem@74 99 // Keycodes 5E, 5F not used
philpem@74 100 { SDLK_BACKQUOTE, 0, 0x60 }, // `
philpem@74 101 { SDLK_a, 0, 0x61 }, // A
philpem@74 102 { SDLK_b, 0, 0x62 }, // B
philpem@74 103 { SDLK_c, 0, 0x63 }, // C
philpem@74 104 { SDLK_d, 0, 0x64 }, // D
philpem@74 105 { SDLK_e, 0, 0x65 }, // E
philpem@74 106 { SDLK_f, 0, 0x66 }, // F
philpem@74 107 { SDLK_g, 0, 0x67 }, // G
philpem@74 108 { SDLK_h, 0, 0x68 }, // H
philpem@74 109 { SDLK_i, 0, 0x69 }, // I
philpem@74 110 { SDLK_j, 0, 0x6a }, // J
philpem@74 111 { SDLK_k, 0, 0x6b }, // K
philpem@74 112 { SDLK_l, 0, 0x6c }, // L
philpem@74 113 { SDLK_m, 0, 0x6d }, // M
philpem@74 114 { SDLK_n, 0, 0x6e }, // N
philpem@74 115 { SDLK_o, 0, 0x6f }, // O
philpem@74 116 { SDLK_p, 0, 0x70 }, // P
philpem@74 117 { SDLK_q, 0, 0x71 }, // Q
philpem@74 118 { SDLK_r, 0, 0x72 }, // R
philpem@74 119 { SDLK_s, 0, 0x73 }, // S
philpem@74 120 { SDLK_t, 0, 0x74 }, // T
philpem@74 121 { SDLK_u, 0, 0x75 }, // U
philpem@74 122 { SDLK_v, 0, 0x76 }, // V
philpem@74 123 { SDLK_w, 0, 0x77 }, // W
philpem@74 124 { SDLK_x, 0, 0x78 }, // X
philpem@74 125 { SDLK_y, 0, 0x79 }, // Y
philpem@74 126 { SDLK_z, 0, 0x7a }, // Z
philpem@74 127 // Keycodes 7B, 7C, 7D not used
philpem@86 128 { SDLK_NUMLOCK, 0, 0x7e } // Numlock
philpem@74 129 // { SDLK_, 1, 0x7f }, // Dlete
philpem@74 130 };
philpem@74 131
philpem@74 132 /**
philpem@86 133 * List of special key codes
philpem@86 134 */
philpem@86 135 enum {
philpem@86 136 KEY_ALL_UP = 0x40, ///< All keys up
philpem@86 137 KEY_LIST_END = 0x80, ///< End of key code list
philpem@86 138 KEY_BEGIN_MOUSE = 0xCF, ///< Mouse data follows
philpem@86 139 KEY_BEGIN_KEYBOARD = 0xDF, ///< Keyboard data follows
philpem@86 140 };
philpem@86 141
philpem@86 142 /**
philpem@86 143 * List of keyboard commands
philpem@74 144 */
philpem@86 145 enum {
philpem@86 146 KEY_CMD_RESET = 0x92, ///< Reset keyboard
philpem@86 147 KEY_CMD_CAPSLED_OFF = 0xB1, ///< Caps Lock LED off--CHECK!
philpem@86 148 KEY_CMD_CAPSLED_ON = 0xB0, ///< Caps Lock LED on --CHECK!
philpem@86 149 KEY_CMD_NUMLED_OFF = 0xA1, ///< Num Lock LED off --CHECK!
philpem@86 150 KEY_CMD_NUMLED_ON = 0xA0, ///< Num Lock LED on --CHECK!
philpem@86 151 KEY_CMD_MOUSE_ENABLE = 0xD0, ///< Enable mouse
philpem@86 152 KEY_CMD_MOUSE_DISABLE = 0xD1 ///< Disable mouse
philpem@86 153 };
philpem@74 154
philpem@86 155 void keyboard_init(KEYBOARD_STATE *state)
philpem@74 156 {
philpem@74 157 // Set all key states to "not pressed"
philpem@86 158 for (int i=0; i<(sizeof(state->keystate)/sizeof(state->keystate[0])); i++) {
philpem@86 159 state->keystate[i] = 0;
philpem@74 160 }
philpem@74 161 }
philpem@74 162
philpem@86 163 void keyboard_event(KEYBOARD_STATE *state, SDL_Event *ev)
philpem@74 164 {
philpem@86 165 int ks;
philpem@86 166
philpem@86 167 // Figure out the event type
philpem@86 168 if (ev->type == SDL_KEYDOWN) {
philpem@86 169 // Key down event
philpem@86 170 ks = 1;
philpem@86 171 } else if (ev->type == SDL_KEYUP) {
philpem@86 172 // Key up event
philpem@86 173 ks = 0;
philpem@86 174 } else {
philpem@86 175 // Not a keyboard event
philpem@86 176 return;
philpem@86 177 }
philpem@86 178
philpem@86 179 // Loop over the keyinfo, try and find a match for this key
philpem@86 180 // TODO: handle Extended Keymap
philpem@86 181 for (int i=0; i<(sizeof(keymap)/sizeof(keymap[0])); i++) {
philpem@86 182 if (ev->key.keysym.sym == keymap[i].key) {
philpem@86 183 // Key code match. Is this an Extended Map key?
philpem@86 184 if (keymap[i].extended) {
philpem@86 185 // Key is on the Extended map. Need ALT set when pressing the key.
philpem@86 186 if (ev->key.keysym.mod & KMOD_ALT) {
philpem@86 187 // ALT is down, key matches.
philpem@86 188 state->keystate[keymap[i].scancode] = ks;
philpem@86 189 break;
philpem@86 190 }
philpem@86 191 } else {
philpem@86 192 // Key is on the Standard map. ALT must NOT be set when pressing the key.
philpem@86 193 if (!(ev->key.keysym.mod & KMOD_ALT)) {
philpem@86 194 // ALT is up, key matches
philpem@86 195 state->keystate[keymap[i].scancode] = ks;
philpem@86 196 break;
philpem@86 197 }
philpem@86 198 }
philpem@86 199 }
philpem@86 200 }
philpem@74 201 }
philpem@86 202
philpem@86 203 // TODO: register read and write