| 1 | //============================================================================ |
| 2 | // |
| 3 | // SSSS tt lll lll |
| 4 | // SS SS tt ll ll |
| 5 | // SS tttttt eeee ll ll aaaa |
| 6 | // SSSS tt ee ee ll ll aa |
| 7 | // SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" |
| 8 | // SS SS tt ee ll ll aa aa |
| 9 | // SSSS ttt eeeee llll llll aaaaa |
| 10 | // |
| 11 | // Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony |
| 12 | // and the Stella Team |
| 13 | // |
| 14 | // See the file "License.txt" for information on usage and redistribution of |
| 15 | // this file, and for a DISCLAIMER OF ALL WARRANTIES. |
| 16 | //============================================================================ |
| 17 | |
| 18 | #ifndef STELLA_KEYS_HXX |
| 19 | #define STELLA_KEYS_HXX |
| 20 | |
| 21 | #ifdef SDL_SUPPORT |
| 22 | #include "SDL_lib.hxx" |
| 23 | #endif |
| 24 | |
| 25 | /** |
| 26 | This class implements a thin wrapper around the SDL keysym enumerations, |
| 27 | such that SDL-specific code doesn't have to go into the internal parts of |
| 28 | the codebase. The keycodes are exactly the same, but from the POV of the |
| 29 | rest of the code, they are *KBD* (keyboard) keys, not *SDL* keys. |
| 30 | |
| 31 | If the codebase is ported to future SDL versions or to some other toolkit, |
| 32 | the intent is to simply change this file without having to modify all |
| 33 | other classes that use StellaKey. |
| 34 | |
| 35 | @author Stephen Anthony |
| 36 | */ |
| 37 | |
| 38 | // This comes directly from SDL_scancode.h |
| 39 | enum StellaKey |
| 40 | { |
| 41 | KBDK_UNKNOWN = 0, |
| 42 | |
| 43 | /** |
| 44 | * \name Usage page 0x07 |
| 45 | * |
| 46 | * These values are from usage page 0x07 (USB keyboard page). |
| 47 | */ |
| 48 | /* @{ */ |
| 49 | |
| 50 | KBDK_A = 4, |
| 51 | KBDK_B = 5, |
| 52 | KBDK_C = 6, |
| 53 | KBDK_D = 7, |
| 54 | KBDK_E = 8, |
| 55 | KBDK_F = 9, |
| 56 | KBDK_G = 10, |
| 57 | KBDK_H = 11, |
| 58 | KBDK_I = 12, |
| 59 | KBDK_J = 13, |
| 60 | KBDK_K = 14, |
| 61 | KBDK_L = 15, |
| 62 | KBDK_M = 16, |
| 63 | KBDK_N = 17, |
| 64 | KBDK_O = 18, |
| 65 | KBDK_P = 19, |
| 66 | KBDK_Q = 20, |
| 67 | KBDK_R = 21, |
| 68 | KBDK_S = 22, |
| 69 | KBDK_T = 23, |
| 70 | KBDK_U = 24, |
| 71 | KBDK_V = 25, |
| 72 | KBDK_W = 26, |
| 73 | KBDK_X = 27, |
| 74 | KBDK_Y = 28, |
| 75 | KBDK_Z = 29, |
| 76 | |
| 77 | KBDK_1 = 30, |
| 78 | KBDK_2 = 31, |
| 79 | KBDK_3 = 32, |
| 80 | KBDK_4 = 33, |
| 81 | KBDK_5 = 34, |
| 82 | KBDK_6 = 35, |
| 83 | KBDK_7 = 36, |
| 84 | KBDK_8 = 37, |
| 85 | KBDK_9 = 38, |
| 86 | KBDK_0 = 39, |
| 87 | |
| 88 | KBDK_RETURN = 40, |
| 89 | KBDK_ESCAPE = 41, |
| 90 | KBDK_BACKSPACE = 42, |
| 91 | KBDK_TAB = 43, |
| 92 | KBDK_SPACE = 44, |
| 93 | |
| 94 | KBDK_MINUS = 45, |
| 95 | KBDK_EQUALS = 46, |
| 96 | KBDK_LEFTBRACKET = 47, |
| 97 | KBDK_RIGHTBRACKET = 48, |
| 98 | KBDK_BACKSLASH = 49, /**< Located at the lower left of the return |
| 99 | * key on ISO keyboards and at the right end |
| 100 | * of the QWERTY row on ANSI keyboards. |
| 101 | * Produces REVERSE SOLIDUS (backslash) and |
| 102 | * VERTICAL LINE in a US layout, REVERSE |
| 103 | * SOLIDUS and VERTICAL LINE in a UK Mac |
| 104 | * layout, NUMBER SIGN and TILDE in a UK |
| 105 | * Windows layout, DOLLAR SIGN and POUND SIGN |
| 106 | * in a Swiss German layout, NUMBER SIGN and |
| 107 | * APOSTROPHE in a German layout, GRAVE |
| 108 | * ACCENT and POUND SIGN in a French Mac |
| 109 | * layout, and ASTERISK and MICRO SIGN in a |
| 110 | * French Windows layout. |
| 111 | */ |
| 112 | KBDK_NONUSHASH = 50, /**< ISO USB keyboards actually use this code |
| 113 | * instead of 49 for the same key, but all |
| 114 | * OSes I've seen treat the two codes |
| 115 | * identically. So, as an implementor, unless |
| 116 | * your keyboard generates both of those |
| 117 | * codes and your OS treats them differently, |
| 118 | * you should generate KBDK_BACKSLASH |
| 119 | * instead of this code. As a user, you |
| 120 | * should not rely on this code because SDL |
| 121 | * will never generate it with most (all?) |
| 122 | * keyboards. |
| 123 | */ |
| 124 | KBDK_SEMICOLON = 51, |
| 125 | KBDK_APOSTROPHE = 52, |
| 126 | KBDK_GRAVE = 53, /**< Located in the top left corner (on both ANSI |
| 127 | * and ISO keyboards). Produces GRAVE ACCENT and |
| 128 | * TILDE in a US Windows layout and in US and UK |
| 129 | * Mac layouts on ANSI keyboards, GRAVE ACCENT |
| 130 | * and NOT SIGN in a UK Windows layout, SECTION |
| 131 | * SIGN and PLUS-MINUS SIGN in US and UK Mac |
| 132 | * layouts on ISO keyboards, SECTION SIGN and |
| 133 | * DEGREE SIGN in a Swiss German layout (Mac: |
| 134 | * only on ISO keyboards), CIRCUMFLEX ACCENT and |
| 135 | * DEGREE SIGN in a German layout (Mac: only on |
| 136 | * ISO keyboards), SUPERSCRIPT TWO and TILDE in a |
| 137 | * French Windows layout, COMMERCIAL AT and |
| 138 | * NUMBER SIGN in a French Mac layout on ISO |
| 139 | * keyboards, and LESS-THAN SIGN and GREATER-THAN |
| 140 | * SIGN in a Swiss German, German, or French Mac |
| 141 | * layout on ANSI keyboards. |
| 142 | */ |
| 143 | KBDK_COMMA = 54, |
| 144 | KBDK_PERIOD = 55, |
| 145 | KBDK_SLASH = 56, |
| 146 | |
| 147 | KBDK_CAPSLOCK = 57, |
| 148 | |
| 149 | KBDK_F1 = 58, |
| 150 | KBDK_F2 = 59, |
| 151 | KBDK_F3 = 60, |
| 152 | KBDK_F4 = 61, |
| 153 | KBDK_F5 = 62, |
| 154 | KBDK_F6 = 63, |
| 155 | KBDK_F7 = 64, |
| 156 | KBDK_F8 = 65, |
| 157 | KBDK_F9 = 66, |
| 158 | KBDK_F10 = 67, |
| 159 | KBDK_F11 = 68, |
| 160 | KBDK_F12 = 69, |
| 161 | |
| 162 | KBDK_PRINTSCREEN = 70, |
| 163 | KBDK_SCROLLLOCK = 71, |
| 164 | KBDK_PAUSE = 72, |
| 165 | KBDK_INSERT = 73, /**< insert on PC, help on some Mac keyboards (but |
| 166 | does send code 73, not 117) */ |
| 167 | KBDK_HOME = 74, |
| 168 | KBDK_PAGEUP = 75, |
| 169 | KBDK_DELETE = 76, |
| 170 | KBDK_END = 77, |
| 171 | KBDK_PAGEDOWN = 78, |
| 172 | KBDK_RIGHT = 79, |
| 173 | KBDK_LEFT = 80, |
| 174 | KBDK_DOWN = 81, |
| 175 | KBDK_UP = 82, |
| 176 | |
| 177 | KBDK_NUMLOCKCLEAR = 83, /**< num lock on PC, clear on Mac keyboards |
| 178 | */ |
| 179 | KBDK_KP_DIVIDE = 84, |
| 180 | KBDK_KP_MULTIPLY = 85, |
| 181 | KBDK_KP_MINUS = 86, |
| 182 | KBDK_KP_PLUS = 87, |
| 183 | KBDK_KP_ENTER = 88, |
| 184 | KBDK_KP_1 = 89, |
| 185 | KBDK_KP_2 = 90, |
| 186 | KBDK_KP_3 = 91, |
| 187 | KBDK_KP_4 = 92, |
| 188 | KBDK_KP_5 = 93, |
| 189 | KBDK_KP_6 = 94, |
| 190 | KBDK_KP_7 = 95, |
| 191 | KBDK_KP_8 = 96, |
| 192 | KBDK_KP_9 = 97, |
| 193 | KBDK_KP_0 = 98, |
| 194 | KBDK_KP_PERIOD = 99, |
| 195 | |
| 196 | KBDK_NONUSBACKSLASH = 100, /**< This is the additional key that ISO |
| 197 | * keyboards have over ANSI ones, |
| 198 | * located between left shift and Y. |
| 199 | * Produces GRAVE ACCENT and TILDE in a |
| 200 | * US or UK Mac layout, REVERSE SOLIDUS |
| 201 | * (backslash) and VERTICAL LINE in a |
| 202 | * US or UK Windows layout, and |
| 203 | * LESS-THAN SIGN and GREATER-THAN SIGN |
| 204 | * in a Swiss German, German, or French |
| 205 | * layout. */ |
| 206 | KBDK_APPLICATION = 101, /**< windows contextual menu, compose */ |
| 207 | KBDK_POWER = 102, /**< The USB document says this is a status flag, |
| 208 | * not a physical key - but some Mac keyboards |
| 209 | * do have a power key. */ |
| 210 | KBDK_KP_EQUALS = 103, |
| 211 | KBDK_F13 = 104, |
| 212 | KBDK_F14 = 105, |
| 213 | KBDK_F15 = 106, |
| 214 | KBDK_F16 = 107, |
| 215 | KBDK_F17 = 108, |
| 216 | KBDK_F18 = 109, |
| 217 | KBDK_F19 = 110, |
| 218 | KBDK_F20 = 111, |
| 219 | KBDK_F21 = 112, |
| 220 | KBDK_F22 = 113, |
| 221 | KBDK_F23 = 114, |
| 222 | KBDK_F24 = 115, |
| 223 | KBDK_EXECUTE = 116, |
| 224 | KBDK_HELP = 117, |
| 225 | = 118, |
| 226 | KBDK_SELECT = 119, |
| 227 | KBDK_STOP = 120, |
| 228 | KBDK_AGAIN = 121, /**< redo */ |
| 229 | KBDK_UNDO = 122, |
| 230 | KBDK_CUT = 123, |
| 231 | KBDK_COPY = 124, |
| 232 | KBDK_PASTE = 125, |
| 233 | KBDK_FIND = 126, |
| 234 | KBDK_MUTE = 127, |
| 235 | KBDK_VOLUMEUP = 128, |
| 236 | KBDK_VOLUMEDOWN = 129, |
| 237 | /* not sure whether there's a reason to enable these */ |
| 238 | /* KBDK_LOCKINGCAPSLOCK = 130, */ |
| 239 | /* KBDK_LOCKINGNUMLOCK = 131, */ |
| 240 | /* KBDK_LOCKINGSCROLLLOCK = 132, */ |
| 241 | KBDK_KP_COMMA = 133, |
| 242 | KBDK_KP_EQUALSAS400 = 134, |
| 243 | |
| 244 | KBDK_INTERNATIONAL1 = 135, /**< used on Asian keyboards, see |
| 245 | footnotes in USB doc */ |
| 246 | KBDK_INTERNATIONAL2 = 136, |
| 247 | KBDK_INTERNATIONAL3 = 137, /**< Yen */ |
| 248 | KBDK_INTERNATIONAL4 = 138, |
| 249 | KBDK_INTERNATIONAL5 = 139, |
| 250 | KBDK_INTERNATIONAL6 = 140, |
| 251 | KBDK_INTERNATIONAL7 = 141, |
| 252 | KBDK_INTERNATIONAL8 = 142, |
| 253 | KBDK_INTERNATIONAL9 = 143, |
| 254 | KBDK_LANG1 = 144, /**< Hangul/English toggle */ |
| 255 | KBDK_LANG2 = 145, /**< Hanja conversion */ |
| 256 | KBDK_LANG3 = 146, /**< Katakana */ |
| 257 | KBDK_LANG4 = 147, /**< Hiragana */ |
| 258 | KBDK_LANG5 = 148, /**< Zenkaku/Hankaku */ |
| 259 | KBDK_LANG6 = 149, /**< reserved */ |
| 260 | KBDK_LANG7 = 150, /**< reserved */ |
| 261 | KBDK_LANG8 = 151, /**< reserved */ |
| 262 | KBDK_LANG9 = 152, /**< reserved */ |
| 263 | |
| 264 | KBDK_ALTERASE = 153, /**< Erase-Eaze */ |
| 265 | KBDK_SYSREQ = 154, |
| 266 | KBDK_CANCEL = 155, |
| 267 | KBDK_CLEAR = 156, |
| 268 | KBDK_PRIOR = 157, |
| 269 | KBDK_RETURN2 = 158, |
| 270 | KBDK_SEPARATOR = 159, |
| 271 | KBDK_OUT = 160, |
| 272 | KBDK_OPER = 161, |
| 273 | KBDK_CLEARAGAIN = 162, |
| 274 | KBDK_CRSEL = 163, |
| 275 | KBDK_EXSEL = 164, |
| 276 | |
| 277 | KBDK_KP_00 = 176, |
| 278 | KBDK_KP_000 = 177, |
| 279 | KBDK_THOUSANDSSEPARATOR = 178, |
| 280 | KBDK_DECIMALSEPARATOR = 179, |
| 281 | KBDK_CURRENCYUNIT = 180, |
| 282 | KBDK_CURRENCYSUBUNIT = 181, |
| 283 | KBDK_KP_LEFTPAREN = 182, |
| 284 | KBDK_KP_RIGHTPAREN = 183, |
| 285 | KBDK_KP_LEFTBRACE = 184, |
| 286 | KBDK_KP_RIGHTBRACE = 185, |
| 287 | KBDK_KP_TAB = 186, |
| 288 | KBDK_KP_BACKSPACE = 187, |
| 289 | KBDK_KP_A = 188, |
| 290 | KBDK_KP_B = 189, |
| 291 | KBDK_KP_C = 190, |
| 292 | KBDK_KP_D = 191, |
| 293 | KBDK_KP_E = 192, |
| 294 | KBDK_KP_F = 193, |
| 295 | KBDK_KP_XOR = 194, |
| 296 | KBDK_KP_POWER = 195, |
| 297 | KBDK_KP_PERCENT = 196, |
| 298 | KBDK_KP_LESS = 197, |
| 299 | KBDK_KP_GREATER = 198, |
| 300 | KBDK_KP_AMPERSAND = 199, |
| 301 | KBDK_KP_DBLAMPERSAND = 200, |
| 302 | KBDK_KP_VERTICALBAR = 201, |
| 303 | KBDK_KP_DBLVERTICALBAR = 202, |
| 304 | KBDK_KP_COLON = 203, |
| 305 | KBDK_KP_HASH = 204, |
| 306 | KBDK_KP_SPACE = 205, |
| 307 | KBDK_KP_AT = 206, |
| 308 | KBDK_KP_EXCLAM = 207, |
| 309 | KBDK_KP_MEMSTORE = 208, |
| 310 | KBDK_KP_MEMRECALL = 209, |
| 311 | KBDK_KP_MEMCLEAR = 210, |
| 312 | KBDK_KP_MEMADD = 211, |
| 313 | KBDK_KP_MEMSUBTRACT = 212, |
| 314 | KBDK_KP_MEMMULTIPLY = 213, |
| 315 | KBDK_KP_MEMDIVIDE = 214, |
| 316 | KBDK_KP_PLUSMINUS = 215, |
| 317 | KBDK_KP_CLEAR = 216, |
| 318 | KBDK_KP_CLEARENTRY = 217, |
| 319 | KBDK_KP_BINARY = 218, |
| 320 | KBDK_KP_OCTAL = 219, |
| 321 | KBDK_KP_DECIMAL = 220, |
| 322 | KBDK_KP_HEXADECIMAL = 221, |
| 323 | |
| 324 | KBDK_LCTRL = 224, |
| 325 | KBDK_LSHIFT = 225, |
| 326 | KBDK_LALT = 226, /**< alt, option */ |
| 327 | KBDK_LGUI = 227, /**< windows, command (apple), meta */ |
| 328 | KBDK_RCTRL = 228, |
| 329 | KBDK_RSHIFT = 229, |
| 330 | KBDK_RALT = 230, /**< alt gr, option */ |
| 331 | KBDK_RGUI = 231, /**< windows, command (apple), meta */ |
| 332 | |
| 333 | KBDK_MODE = 257, /**< ALT-GR(aph) key on non-American keyboards |
| 334 | * This is like pressing KBDK_RALT + KBDK_RCTRL |
| 335 | * on some keyboards |
| 336 | */ |
| 337 | |
| 338 | /* @} *//* Usage page 0x07 */ |
| 339 | |
| 340 | /** |
| 341 | * \name Usage page 0x0C |
| 342 | * |
| 343 | * These values are mapped from usage page 0x0C (USB consumer page). |
| 344 | */ |
| 345 | /* @{ */ |
| 346 | |
| 347 | KBDK_AUDIONEXT = 258, |
| 348 | KBDK_AUDIOPREV = 259, |
| 349 | KBDK_AUDIOSTOP = 260, |
| 350 | KBDK_AUDIOPLAY = 261, |
| 351 | KBDK_AUDIOMUTE = 262, |
| 352 | KBDK_MEDIASELECT = 263, |
| 353 | KBDK_WWW = 264, |
| 354 | KBDK_MAIL = 265, |
| 355 | KBDK_CALCULATOR = 266, |
| 356 | KBDK_COMPUTER = 267, |
| 357 | KBDK_AC_SEARCH = 268, |
| 358 | KBDK_AC_HOME = 269, |
| 359 | KBDK_AC_BACK = 270, |
| 360 | KBDK_AC_FORWARD = 271, |
| 361 | KBDK_AC_STOP = 272, |
| 362 | KBDK_AC_REFRESH = 273, |
| 363 | KBDK_AC_BOOKMARKS = 274, |
| 364 | |
| 365 | /* @} *//* Usage page 0x0C */ |
| 366 | |
| 367 | /** |
| 368 | * \name Walther keys |
| 369 | * |
| 370 | * These are values that Christian Walther added (for mac keyboard?). |
| 371 | */ |
| 372 | /* @{ */ |
| 373 | |
| 374 | KBDK_BRIGHTNESSDOWN = 275, |
| 375 | KBDK_BRIGHTNESSUP = 276, |
| 376 | KBDK_DISPLAYSWITCH = 277, /**< display mirroring/dual display |
| 377 | switch, video mode switch */ |
| 378 | KBDK_KBDILLUMTOGGLE = 278, |
| 379 | KBDK_KBDILLUMDOWN = 279, |
| 380 | KBDK_KBDILLUMUP = 280, |
| 381 | KBDK_EJECT = 281, |
| 382 | KBDK_SLEEP = 282, |
| 383 | |
| 384 | KBDK_APP1 = 283, |
| 385 | KBDK_APP2 = 284, |
| 386 | |
| 387 | /* @} *//* Walther keys */ |
| 388 | |
| 389 | /* Add any other keys here. */ |
| 390 | |
| 391 | KBDK_LAST = 512 /**< not a key, just marks the number of scancodes |
| 392 | for array bounds */ |
| 393 | }; |
| 394 | |
| 395 | // This comes directly from SDL_keycode.h |
| 396 | enum StellaMod |
| 397 | { |
| 398 | KBDM_NONE = 0x0000, |
| 399 | KBDM_LSHIFT = 0x0001, |
| 400 | KBDM_RSHIFT = 0x0002, |
| 401 | KBDM_LCTRL = 0x0040, |
| 402 | KBDM_RCTRL = 0x0080, |
| 403 | KBDM_LALT = 0x0100, |
| 404 | KBDM_RALT = 0x0200, |
| 405 | KBDM_LGUI = 0x0400, |
| 406 | KBDM_RGUI = 0x0800, |
| 407 | KBDM_NUM = 0x1000, |
| 408 | KBDM_CAPS = 0x2000, |
| 409 | KBDM_MODE = 0x4000, |
| 410 | KBDM_RESERVED = 0x8000, |
| 411 | KBDM_CTRL = (KBDM_LCTRL|KBDM_RCTRL), |
| 412 | KBDM_SHIFT = (KBDM_LSHIFT|KBDM_RSHIFT), |
| 413 | KBDM_ALT = (KBDM_LALT|KBDM_RALT), |
| 414 | KBDM_GUI = (KBDM_LGUI|KBDM_RGUI) |
| 415 | }; |
| 416 | |
| 417 | // Test if specified modifier is pressed |
| 418 | namespace StellaModTest |
| 419 | { |
| 420 | inline bool isAlt(int mod) |
| 421 | { |
| 422 | #if defined(BSPF_MACOS) || defined(MACOS_KEYS) |
| 423 | return (mod & KBDM_GUI); |
| 424 | #else |
| 425 | return (mod & KBDM_ALT); |
| 426 | #endif |
| 427 | } |
| 428 | |
| 429 | inline bool isControl(int mod) |
| 430 | { |
| 431 | return (mod & KBDM_CTRL); |
| 432 | } |
| 433 | |
| 434 | inline bool isShift(int mod) |
| 435 | { |
| 436 | return (mod & KBDM_SHIFT); |
| 437 | } |
| 438 | } |
| 439 | |
| 440 | namespace StellaKeyName |
| 441 | { |
| 442 | inline const char* forKey(StellaKey key) |
| 443 | { |
| 444 | #ifdef SDL_SUPPORT |
| 445 | return SDL_GetScancodeName(SDL_Scancode(key)); |
| 446 | #else |
| 447 | return "" ; |
| 448 | #endif |
| 449 | } |
| 450 | } |
| 451 | |
| 452 | #endif /* StellaKeys */ |
| 453 | |