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 | |