|
|
1.1 root 1: /*
1.1.1.6 root 2: Hatari - keymap.c
1.1.1.5 root 3:
1.1.1.15 root 4: This file is distributed under the GNU General Public License, version 2
5: or at your option any later version. Read the file gpl.txt for details.
1.1 root 6:
1.1.1.3 root 7: Here we process a key press and the remapping of the scancodes.
1.1 root 8: */
1.1.1.12 root 9: const char Keymap_fileid[] = "Hatari keymap.c : " __DATE__ " " __TIME__;
1.1 root 10:
1.1.1.11 root 11: #include <ctype.h>
1.1 root 12: #include "main.h"
13: #include "keymap.h"
1.1.1.5 root 14: #include "configuration.h"
1.1.1.10 root 15: #include "file.h"
1.1.1.3 root 16: #include "ikbd.h"
17: #include "joy.h"
18: #include "shortcut.h"
1.1.1.11 root 19: #include "str.h"
1.1.1.3 root 20: #include "screen.h"
1.1.1.4 root 21: #include "debugui.h"
1.1.1.9 root 22: #include "log.h"
1.1 root 23:
1.1.1.2 root 24:
25: /*-----------------------------------------------------------------------*/
1.1 root 26: /*
1.1.1.5 root 27: Remap table of PC keys to ST scan codes, -ve is invalid key (ie doesn't occur on ST)
1.1 root 28:
29: PC Keyboard:-
30:
31: Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Print Scroll Pause
32:
33: 1 59 60 61 62 63 64 65 66 67 68 87 88 70 69
34:
35:
1.1.1.10 root 36: ! " $ % ^ & * ( ) _ + Page
1.1 root 37: ` 1 2 3 4 5 6 7 8 9 0 - = <- Ins Home Up
38:
39: 41 2 3 4 5 6 7 8 9 10 11 12 13 14 82 71 73
40: -- -- --
41: |
42: { } | Page
43: Tab Q W E R T Y U I O P [ ] <---- Del End Down
1.1.1.5 root 44:
1.1 root 45: 15 16 17 18 19 20 21 22 23 24 25 26 27 28 83 79 81
46: -- -- --
47:
48: : @ ~ ^
49: Caps A S D F G H J K L ; ' # |
50:
51: 58 30 31 32 33 34 35 36 37 38 39 40 43 72
52: --
1.1.1.5 root 53:
1.1 root 54: ^ | < > ? ^
55: | \ Z X C V B N M , . / | <- | ->
56:
57: 42 86 44 45 46 47 48 49 50 51 52 53 54 75 80 77
58: -- -- --
59:
60: Ctrl Alt SPACE Alt Gr Ctrl
61:
62: 29 56 57 56 29
63: --
64:
65: And:-
66:
67: Num
68: Lock / * -
69:
70: 69 53 55 74
71: -- --
72:
73: 7 8 9 +
74: Home ^ Pg Up
75:
76: 71 72 73 78
77:
78:
79: 4 5 6
80: <- ->
81:
82: 75 76 77
83:
84:
85: 1 2 3
86: End | Pg Dn Enter
87:
88: 79 70 81 28
89: --
90:
91: 0 .
92: Ins Del
93:
94: 82 83
95:
96:
97: */
98:
99:
1.1.1.5 root 100: /* SDL symbolic key to ST scan code mapping table */
101: static const char SymbolicKeyToSTScanCode[SDLK_LAST] =
102: {
1.1.1.10 root 103: /* ST, PC Code */
104: -1, /* 0 */
105: -1, /* 1 */
106: -1, /* 2 */
107: -1, /* 3 */
108: -1, /* 4 */
109: -1, /* 5 */
110: -1, /* 6 */
111: -1, /* 7 */
112: 0x0E, /* SDLK_BACKSPACE=8 */
113: 0x0F, /* SDLK_TAB=9 */
114: -1, /* 10 */
115: -1, /* 11 */
116: 0x47, /* SDLK_CLEAR = 12 */
117: 0x1C, /* SDLK_RETURN = 13 */
118: -1, /* 14 */
119: -1, /* 15 */
120: -1, /* 16 */
121: -1, /* 17 */
122: -1, /* 18 */
123: -1, /* SDLK_PAUSE = 19 */
124: -1, /* 20 */
125: -1, /* 21 */
126: -1, /* 22 */
127: -1, /* 23 */
128: -1, /* 24 */
129: -1, /* 25 */
130: -1, /* 26 */
131: 0x01, /* SDLK_ESCAPE = 27 */
132: -1, /* 28 */
133: -1, /* 29 */
134: -1, /* 30 */
135: -1, /* 31 */
136: 0x39, /* SDLK_SPACE = 32 */
137: -1, /* SDLK_EXCLAIM = 33 */
138: -1, /* SDLK_QUOTEDBL = 34 */
139: 0x29, /* SDLK_HASH = 35 */
140: -1, /* SDLK_DOLLAR = 36 */
141: -1, /* 37 */
142: -1, /* SDLK_AMPERSAND = 38 */
143: 0x28, /* SDLK_QUOTE = 39 */
144: 0x63, /* SDLK_LEFTPAREN = 40 */
145: 0x64, /* SDLK_RIGHTPAREN = 41 */
146: -1, /* SDLK_ASTERISK = 42 */
147: 0x1B, /* SDLK_PLUS = 43 */
148: 0x33, /* SDLK_COMMA = 44 */
149: 0x35, /* SDLK_MINUS = 45 */
150: 0x34, /* SDLK_PERIOD = 46 */
151: 0x35, /* SDLK_SLASH = 47 */
152: 0x0B, /* SDLK_0 = 48 */
153: 0x02, /* SDLK_1 = 49 */
154: 0x03, /* SDLK_2 = 50 */
155: 0x04, /* SDLK_3 = 51 */
156: 0x05, /* SDLK_4 = 52 */
157: 0x06, /* SDLK_5 = 53 */
158: 0x07, /* SDLK_6 = 54 */
159: 0x08, /* SDLK_7 = 55 */
160: 0x09, /* SDLK_8 = 56 */
161: 0x0A, /* SDLK_9 = 57 */
162: -1, /* SDLK_COLON = 58 */
163: 0x27, /* SDLK_SEMICOLON = 59 */
164: 0x60, /* SDLK_LESS = 60 */
165: 0x0D, /* SDLK_EQUALS = 61 */
166: -1, /* SDLK_GREATER = 62 */
167: -1, /* SDLK_QUESTION = 63 */
168: -1, /* SDLK_AT = 64 */
169: -1, /* 65 */ /* Skip uppercase letters */
170: -1, /* 66 */
171: -1, /* 67 */
172: -1, /* 68 */
173: -1, /* 69 */
174: -1, /* 70 */
175: -1, /* 71 */
176: -1, /* 72 */
177: -1, /* 73 */
178: -1, /* 74 */
179: -1, /* 75 */
180: -1, /* 76 */
181: -1, /* 77 */
182: -1, /* 78 */
183: -1, /* 79 */
184: -1, /* 80 */
185: -1, /* 81 */
186: -1, /* 82 */
187: -1, /* 83 */
188: -1, /* 84 */
189: -1, /* 85 */
190: -1, /* 86 */
191: -1, /* 87 */
192: -1, /* 88 */
193: -1, /* 89 */
194: -1, /* 90 */
195: 0x63, /* SDLK_LEFTBRACKET = 91 */
196: 0x2B, /* SDLK_BACKSLASH = 92 */ /* Might be 0x60 for UK keyboards */
197: 0x64, /* SDLK_RIGHTBRACKET = 93 */
198: 0x2B, /* SDLK_CARET = 94 */
199: -1, /* SDLK_UNDERSCORE = 95 */
200: 0x52, /* SDLK_BACKQUOTE = 96 */
201: 0x1E, /* SDLK_a = 97 */
202: 0x30, /* SDLK_b = 98 */
203: 0x2E, /* SDLK_c = 99 */
204: 0x20, /* SDLK_d = 100 */
205: 0x12, /* SDLK_e = 101 */
206: 0x21, /* SDLK_f = 102 */
207: 0x22, /* SDLK_g = 103 */
208: 0x23, /* SDLK_h = 104 */
209: 0x17, /* SDLK_i = 105 */
210: 0x24, /* SDLK_j = 106 */
211: 0x25, /* SDLK_k = 107 */
212: 0x26, /* SDLK_l = 108 */
213: 0x32, /* SDLK_m = 109 */
214: 0x31, /* SDLK_n = 110 */
215: 0x18, /* SDLK_o = 111 */
216: 0x19, /* SDLK_p = 112 */
217: 0x10, /* SDLK_q = 113 */
218: 0x13, /* SDLK_r = 114 */
219: 0x1F, /* SDLK_s = 115 */
220: 0x14, /* SDLK_t = 116 */
221: 0x16, /* SDLK_u = 117 */
222: 0x2F, /* SDLK_v = 118 */
223: 0x11, /* SDLK_w = 119 */
224: 0x2D, /* SDLK_x = 120 */
225: 0x15, /* SDLK_y = 121 */
226: 0x2C, /* SDLK_z = 122 */
227: -1, /* 123 */
228: -1, /* 124 */
229: -1, /* 125 */
230: -1, /* 126 */
231: 0x53, /* SDLK_DELETE = 127 */
232: /* End of ASCII mapped keysyms */
233: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 128-143*/
234: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 144-159*/
1.1.1.11 root 235: 0x0d, 0x0c, 0x1a, 0x28, 0x27, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 160-175*/
1.1.1.10 root 236: -1, -1, -1, -1, 0x0D, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 176-191*/
237: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192-207*/
238: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0x0C, /* 208-223*/
239: -1, -1, -1, -1, 0x28, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224-239*/
240: -1, -1, -1, -1, -1, -1, 0x27, -1, -1, -1, -1, -1, 0x1A, -1, -1, -1, /* 240-255*/
241: /* Numeric keypad: */
242: 0x70, /* SDLK_KP0 = 256 */
243: 0x6D, /* SDLK_KP1 = 257 */
244: 0x6E, /* SDLK_KP2 = 258 */
245: 0x6F, /* SDLK_KP3 = 259 */
246: 0x6A, /* SDLK_KP4 = 260 */
247: 0x6B, /* SDLK_KP5 = 261 */
248: 0x6C, /* SDLK_KP6 = 262 */
249: 0x67, /* SDLK_KP7 = 263 */
250: 0x68, /* SDLK_KP8 = 264 */
251: 0x69, /* SDLK_KP9 = 265 */
252: 0x71, /* SDLK_KP_PERIOD = 266 */
253: 0x65, /* SDLK_KP_DIVIDE = 267 */
254: 0x66, /* SDLK_KP_MULTIPLY = 268 */
255: 0x4A, /* SDLK_KP_MINUS = 269 */
256: 0x4E, /* SDLK_KP_PLUS = 270 */
257: 0x72, /* SDLK_KP_ENTER = 271 */
1.1.1.11 root 258: 0x61, /* SDLK_KP_EQUALS = 272 */
1.1.1.10 root 259: /* Arrows + Home/End pad */
260: 0x48, /* SDLK_UP = 273 */
261: 0x50, /* SDLK_DOWN = 274 */
262: 0x4D, /* SDLK_RIGHT = 275 */
263: 0x4B, /* SDLK_LEFT = 276 */
264: 0x52, /* SDLK_INSERT = 277 */
265: 0x47, /* SDLK_HOME = 278 */
266: 0x61, /* SDLK_END = 279 */
267: 0x63, /* SDLK_PAGEUP = 280 */
268: 0x64, /* SDLK_PAGEDOWN = 281 */
269: /* Function keys */
270: 0x3B, /* SDLK_F1 = 282 */
271: 0x3C, /* SDLK_F2 = 283 */
272: 0x3D, /* SDLK_F3 = 284 */
273: 0x3E, /* SDLK_F4 = 285 */
274: 0x3F, /* SDLK_F5 = 286 */
275: 0x40, /* SDLK_F6 = 287 */
276: 0x41, /* SDLK_F7 = 288 */
277: 0x42, /* SDLK_F8 = 289 */
278: 0x43, /* SDLK_F9 = 290 */
279: 0x44, /* SDLK_F10 = 291 */
280: -1, /* SDLK_F11 = 292 */
281: -1, /* SDLK_F12 = 293 */
1.1.1.11 root 282: 0x62, /* SDLK_F13 = 294 */
1.1.1.10 root 283: -1, /* SDLK_F14 = 295 */
284: -1, /* SDLK_F15 = 296 */
285: -1, /* 297 */
286: -1, /* 298 */
287: -1, /* 299 */
288: /* Key state modifier keys */
289: -1, /* SDLK_NUMLOCK = 300 */
290: 0x3A, /* SDLK_CAPSLOCK = 301 */
291: 0x61, /* SDLK_SCROLLOCK = 302 */
292: 0x36, /* SDLK_RSHIFT = 303 */
293: 0x2A, /* SDLK_LSHIFT = 304 */
294: 0x1D, /* SDLK_RCTRL = 305 */
295: 0x1D, /* SDLK_LCTRL = 306 */
296: 0x38, /* SDLK_RALT = 307 */
297: 0x38, /* SDLK_LALT = 308 */
298: -1, /* SDLK_RMETA = 309 */
299: -1, /* SDLK_LMETA = 310 */
300: -1, /* SDLK_LSUPER = 311 */
301: -1, /* SDLK_RSUPER = 312 */
302: -1, /* SDLK_MODE = 313 */ /* "Alt Gr" key */
303: -1, /* SDLK_COMPOSE = 314 */
304: /* Miscellaneous function keys */
305: 0x62, /* SDLK_HELP = 315 */
306: 0x62, /* SDLK_PRINT = 316 */
307: -1, /* SDLK_SYSREQ = 317 */
308: -1, /* SDLK_BREAK = 318 */
309: -1, /* SDLK_MENU = 319 */
310: -1, /* SDLK_POWER = 320 */
311: -1, /* SDLK_EURO = 321 */
312: 0x61 /* SDLK_UNDO = 322 */
1.1 root 313: };
314:
1.1.1.5 root 315: /* Table for loaded keys: */
316: static char LoadedKeyToSTScanCode[SDLK_LAST];
317:
318: /* This table is used to translate a symbolic keycode to the (SDL) scancode */
319: static Uint8 SdlSymToSdlScan[SDLK_LAST];
320:
1.1 root 321:
1.1.1.3 root 322: /* List of ST scan codes to NOT de-bounce when running in maximum speed */
1.1.1.9 root 323: static const char DebounceExtendedKeys[] =
1.1.1.5 root 324: {
1.1.1.10 root 325: 0x1d, /* CTRL */
326: 0x2a, /* Left SHIFT */
327: 0x01, /* ESC */
328: 0x38, /* ALT */
329: 0x36, /* Right SHIFT */
330: 0 /* term */
1.1.1.3 root 331: };
332:
333:
1.1.1.5 root 334:
335: /*-----------------------------------------------------------------------*/
1.1.1.10 root 336: /**
337: * Initialization.
338: */
1.1.1.5 root 339: void Keymap_Init(void)
340: {
1.1.1.10 root 341: memset(SdlSymToSdlScan, 0, sizeof(SdlSymToSdlScan)); /* Clear array */
342: Keymap_LoadRemapFile(ConfigureParams.Keyboard.szMappingFileName);
1.1.1.5 root 343: }
344:
345:
346: /*-----------------------------------------------------------------------*/
1.1.1.10 root 347: /**
348: * Heuristic analysis to find out the obscure scancode offset.
349: * Some keys like 'z' can't be used for detection since they are on different
350: * locations on "qwertz" and "azerty" keyboards.
351: * This clever code has originally been taken from the emulator Aranym. (cheers!)
352: */
1.1.1.5 root 353: static int Keymap_FindScanCodeOffset(SDL_keysym* keysym)
354: {
1.1.1.10 root 355: int offset = -1; /* uninitialized scancode offset */
356: int scanPC = keysym->scancode;
1.1.1.5 root 357:
1.1.1.10 root 358: if (scanPC == 0) return -1; /* Ignore illegal scancode */
1.1.1.5 root 359:
1.1.1.10 root 360: switch (keysym->sym)
361: {
362: case SDLK_ESCAPE: offset = scanPC - 0x01; break;
363: case SDLK_1: offset = scanPC - 0x02; break;
364: case SDLK_2: offset = scanPC - 0x03; break;
365: case SDLK_3: offset = scanPC - 0x04; break;
366: case SDLK_4: offset = scanPC - 0x05; break;
367: case SDLK_5: offset = scanPC - 0x06; break;
368: case SDLK_6: offset = scanPC - 0x07; break;
369: case SDLK_7: offset = scanPC - 0x08; break;
370: case SDLK_8: offset = scanPC - 0x09; break;
371: case SDLK_9: offset = scanPC - 0x0a; break;
372: case SDLK_0: offset = scanPC - 0x0b; break;
373: case SDLK_BACKSPACE: offset = scanPC - 0x0e; break;
374: case SDLK_TAB: offset = scanPC - 0x0f; break;
375: case SDLK_RETURN: offset = scanPC - 0x1c; break;
376: case SDLK_SPACE: offset = scanPC - 0x39; break;
377: /*case SDLK_q: offset = scanPC - 0x10; break;*/ /* different on azerty */
378: /*case SDLK_w: offset = scanPC - 0x11; break;*/ /* different on azerty */
379: case SDLK_e: offset = scanPC - 0x12; break;
380: case SDLK_r: offset = scanPC - 0x13; break;
381: case SDLK_t: offset = scanPC - 0x14; break;
382: /*case SDLK_y: offset = scanPC - 0x15; break;*/ /* different on qwertz */
383: case SDLK_u: offset = scanPC - 0x16; break;
384: case SDLK_i: offset = scanPC - 0x17; break;
385: case SDLK_o: offset = scanPC - 0x18; break;
386: case SDLK_p: offset = scanPC - 0x19; break;
387: /*case SDLK_a: offset = scanPC - 0x1e; break;*/ /* different on azerty */
388: case SDLK_s: offset = scanPC - 0x1f; break;
389: case SDLK_d: offset = scanPC - 0x20; break;
390: case SDLK_f: offset = scanPC - 0x21; break;
391: case SDLK_g: offset = scanPC - 0x22; break;
392: case SDLK_h: offset = scanPC - 0x23; break;
393: case SDLK_j: offset = scanPC - 0x24; break;
394: case SDLK_k: offset = scanPC - 0x25; break;
395: case SDLK_l: offset = scanPC - 0x26; break;
396: /*case SDLK_z: offset = scanPC - 0x2c; break;*/ /* different on qwertz and azerty */
397: case SDLK_x: offset = scanPC - 0x2d; break;
398: case SDLK_c: offset = scanPC - 0x2e; break;
399: case SDLK_v: offset = scanPC - 0x2f; break;
400: case SDLK_b: offset = scanPC - 0x30; break;
401: case SDLK_n: offset = scanPC - 0x31; break;
402: /*case SDLK_m: offset = scanPC - 0x32; break;*/ /* different on azerty */
403: case SDLK_CAPSLOCK: offset = scanPC - 0x3a; break;
404: case SDLK_LSHIFT: offset = scanPC - 0x2a; break;
405: case SDLK_LCTRL: offset = scanPC - 0x1d; break;
406: case SDLK_LALT: offset = scanPC - 0x38; break;
407: case SDLK_F1: offset = scanPC - 0x3b; break;
408: case SDLK_F2: offset = scanPC - 0x3c; break;
409: case SDLK_F3: offset = scanPC - 0x3d; break;
410: case SDLK_F4: offset = scanPC - 0x3e; break;
411: case SDLK_F5: offset = scanPC - 0x3f; break;
412: case SDLK_F6: offset = scanPC - 0x40; break;
413: case SDLK_F7: offset = scanPC - 0x41; break;
414: case SDLK_F8: offset = scanPC - 0x42; break;
415: case SDLK_F9: offset = scanPC - 0x43; break;
416: case SDLK_F10: offset = scanPC - 0x44; break;
417: default: break;
418: }
419:
420: if (offset != -1)
421: {
422: fprintf(stderr, "Detected scancode offset = %d (key: '%s' with scancode $%02x)\n",
423: offset, SDL_GetKeyName(keysym->sym), scanPC);
424: }
1.1.1.5 root 425:
1.1.1.10 root 426: return offset;
1.1.1.5 root 427: }
428:
429:
430: /*-----------------------------------------------------------------------*/
1.1.1.10 root 431: /**
432: * Map PC scancode to ST scancode.
433: * This code was heavily inspired by the emulator Aranym. (cheers!)
434: */
1.1.1.5 root 435: static char Keymap_PcToStScanCode(SDL_keysym* keysym)
436: {
1.1.1.10 root 437: static int offset = -1; /* uninitialized scancode offset */
1.1.1.5 root 438:
1.1.1.10 root 439: switch (keysym->sym)
440: {
441: /* Numeric Pad */
442: /* note that the numbers are handled in Keymap_GetKeyPadScanCode()! */
443: case SDLK_KP_DIVIDE: return 0x65; /* Numpad / */
444: case SDLK_KP_MULTIPLY: return 0x66; /* NumPad * */
445: case SDLK_KP_MINUS: return 0x4a; /* NumPad - */
446: case SDLK_KP_PLUS: return 0x4e; /* NumPad + */
447: case SDLK_KP_PERIOD: return 0x71; /* NumPad . */
448: case SDLK_KP_ENTER: return 0x72; /* NumPad Enter */
449:
450: /* Special Keys */
451: case SDLK_PAGEUP: return 0x62; /* F11 => Help */
452: case SDLK_PAGEDOWN: return 0x61; /* F12 => Undo */
453: case SDLK_HOME: return 0x47; /* Home */
454: case SDLK_END: return 0x60; /* End => "<>" on German Atari kbd */
455: case SDLK_UP: return 0x48; /* Arrow Up */
456: case SDLK_LEFT: return 0x4b; /* Arrow Left */
457: case SDLK_RIGHT: return 0x4d; /* Arrow Right */
458: case SDLK_DOWN: return 0x50; /* Arrow Down */
459: case SDLK_INSERT: return 0x52; /* Insert */
460: case SDLK_DELETE: return 0x53; /* Delete */
461: case SDLK_LESS: return 0x60; /* "<" */
462:
463: /* Map Right Alt/Alt Gr/Control to the Atari keys */
464: case SDLK_RCTRL: return 0x1d; /* Control */
465: case SDLK_RALT: return 0x38; /* Alternate */
466:
467: default:
468: /* Process remaining keys: assume that it's PC101 keyboard
469: * and that it is compatible with Atari ST keyboard (basically
470: * same scancodes but on different platforms with different
471: * base offset (framebuffer = 0, X11 = 8).
472: * Try to detect the offset using a little bit of black magic.
473: * If offset is known then simply pass the scancode. */
474: if (offset == -1)
475: {
476: offset = Keymap_FindScanCodeOffset(keysym);
477: }
478:
479: if (offset >= 0)
480: {
481: /* offset is defined so pass the scancode directly */
482: return (keysym->scancode - offset);
483: }
484: else
485: {
486: /* Failed to detect offset, so use default value 8 */
487: fprintf(stderr, "Offset detection failed with "
488: "key '%s', scancode = 0x%02x, symcode = 0x%02x\n",
489: SDL_GetKeyName(keysym->sym), keysym->scancode, keysym->sym);
490: return (keysym->scancode - 8);
491: }
492: break;
493: }
1.1.1.5 root 494: }
495:
496:
497: /*-----------------------------------------------------------------------*/
1.1.1.10 root 498: /**
499: * Remap a keypad key to ST scan code. We use a separate function for this
500: * so that we can easily toggle between number and cursor mode with the
501: * numlock key.
502: */
1.1.1.5 root 503: static char Keymap_GetKeyPadScanCode(SDL_keysym* pKeySym)
504: {
1.1.1.10 root 505: if (SDL_GetModState() & KMOD_NUM)
506: {
507: switch (pKeySym->sym)
508: {
509: case SDLK_KP0: return 0x70; /* NumPad 0 */
510: case SDLK_KP1: return 0x6d; /* NumPad 1 */
511: case SDLK_KP2: return 0x6e; /* NumPad 2 */
512: case SDLK_KP3: return 0x6f; /* NumPad 3 */
513: case SDLK_KP4: return 0x6a; /* NumPad 4 */
514: case SDLK_KP5: return 0x6b; /* NumPad 5 */
515: case SDLK_KP6: return 0x6c; /* NumPad 6 */
516: case SDLK_KP7: return 0x67; /* NumPad 7 */
517: case SDLK_KP8: return 0x68; /* NumPad 8 */
518: case SDLK_KP9: return 0x69; /* NumPad 9 */
519: default: break;
520: }
521: }
522: else
523: {
524: switch (pKeySym->sym)
525: {
526: case SDLK_KP0: return 0x70; /* NumPad 0 */
527: case SDLK_KP1: return 0x6d; /* NumPad 1 */
528: case SDLK_KP2: return 0x50; /* Cursor down */
529: case SDLK_KP3: return 0x6f; /* NumPad 3 */
530: case SDLK_KP4: return 0x4b; /* Cursor left */
531: case SDLK_KP5: return 0x50; /* Cursor down (again?) */
532: case SDLK_KP6: return 0x4d; /* Cursor right */
533: case SDLK_KP7: return 0x52; /* Insert - good for Dungeon Master */
534: case SDLK_KP8: return 0x48; /* Cursor up */
535: case SDLK_KP9: return 0x47; /* Home - again for Dungeon Master */
536: default: break;
537: }
538: }
1.1.1.5 root 539:
1.1.1.10 root 540: return -1;
1.1.1.5 root 541: }
1.1 root 542:
543:
1.1.1.2 root 544: /*-----------------------------------------------------------------------*/
1.1.1.10 root 545: /**
546: * Remap SDL Key to ST Scan code
547: */
1.1.1.16! root 548: static char Keymap_RemapKeyToSTScanCode(SDL_keysym* pKeySym)
1.1 root 549: {
1.1.1.10 root 550: if (pKeySym->sym >= SDLK_LAST) return -1; /* Avoid illegal keys */
1.1.1.5 root 551:
1.1.1.10 root 552: /* Check for keypad first so we can handle numlock */
553: if (ConfigureParams.Keyboard.nKeymapType != KEYMAP_LOADED)
554: {
555: if (pKeySym->sym >= SDLK_KP0 && pKeySym->sym <= SDLK_KP9)
556: {
557: return Keymap_GetKeyPadScanCode(pKeySym);
558: }
559: }
560:
561: /* Remap from PC scancodes? */
562: if (ConfigureParams.Keyboard.nKeymapType == KEYMAP_SCANCODE)
563: {
564: /* We sometimes enter here with an illegal (=0) scancode, so we keep
565: * track of the right scancodes in a table and then use a value from there.
566: */
567: if (pKeySym->scancode != 0)
568: {
569: SdlSymToSdlScan[pKeySym->sym] = pKeySym->scancode;
570: }
571: else
572: {
573: pKeySym->scancode = SdlSymToSdlScan[pKeySym->sym];
574: if (pKeySym->scancode == 0)
575: fprintf(stderr, "Warning: Key scancode is 0!\n");
576: }
577:
578: return Keymap_PcToStScanCode(pKeySym);
579: }
580:
581: /* Use default or loaded? */
582: if (ConfigureParams.Keyboard.nKeymapType == KEYMAP_LOADED)
583: return LoadedKeyToSTScanCode[pKeySym->sym];
584: else
585: return SymbolicKeyToSTScanCode[pKeySym->sym];
1.1 root 586: }
587:
1.1.1.2 root 588:
589: /*-----------------------------------------------------------------------*/
1.1.1.10 root 590: /**
591: * Load keyboard remap file
592: */
1.1 root 593: void Keymap_LoadRemapFile(char *pszFileName)
594: {
1.1.1.10 root 595: char szString[1024];
596: int STScanCode, PCKeyCode;
597: FILE *in;
598:
599: /* Initialize table with default values */
600: memcpy(LoadedKeyToSTScanCode, SymbolicKeyToSTScanCode, sizeof(LoadedKeyToSTScanCode));
601:
1.1.1.11 root 602: if (!*pszFileName)
603: return;
604:
1.1.1.10 root 605: /* Attempt to load file */
1.1.1.11 root 606: if (!File_Exists(pszFileName))
1.1.1.10 root 607: {
1.1.1.11 root 608: Log_Printf(LOG_DEBUG, "Keymap_LoadRemapFile: '%s' not a file\n", pszFileName);
609: return;
610: }
611: in = fopen(pszFileName, "r");
612: if (!in)
613: {
614: Log_Printf(LOG_DEBUG, "Keymap_LoadRemapFile: failed to "
615: " open keymap file '%s'\n", pszFileName);
616: return;
617: }
618:
619: while (!feof(in))
620: {
621: /* Read line from file */
622: if (fgets(szString, sizeof(szString), in) == NULL)
623: break;
624: /* Remove white-space from start of line */
625: Str_Trim(szString);
626: if (strlen(szString)>0)
627: {
628: /* Is a comment? */
629: if ( (szString[0]==';') || (szString[0]=='#') )
630: continue;
631: /* Read values */
632: sscanf(szString, "%d,%d", &PCKeyCode, &STScanCode);
633: /* Store into remap table, check both value within range */
634: if ( (PCKeyCode>=0) && (PCKeyCode<SDLK_LAST) &&
635: (STScanCode>=0) && (STScanCode<256) )
636: LoadedKeyToSTScanCode[PCKeyCode] = STScanCode;
1.1.1.10 root 637: }
638: }
1.1.1.11 root 639:
640: fclose(in);
1.1 root 641: }
1.1.1.3 root 642:
643:
644: /*-----------------------------------------------------------------------*/
1.1.1.10 root 645: /**
646: * Scan list of keys to NOT de-bounce when running in maximum speed, eg ALT,SHIFT,CTRL etc...
1.1.1.13 root 647: * @return true if key requires de-bouncing
1.1.1.10 root 648: */
1.1.1.11 root 649: static bool Keymap_DebounceSTKey(char STScanCode)
1.1.1.3 root 650: {
1.1.1.10 root 651: int i=0;
1.1.1.3 root 652:
1.1.1.11 root 653: /* Are we in fast forward, and have disabled key repeat? */
1.1.1.13 root 654: if ((ConfigureParams.System.bFastForward == true)
1.1.1.10 root 655: && (ConfigureParams.Keyboard.bDisableKeyRepeat))
656: {
657: /* We should de-bounce all non extended keys,
658: * e.g. leave ALT, SHIFT, CTRL etc... held */
659: while (DebounceExtendedKeys[i])
660: {
661: if (STScanCode == DebounceExtendedKeys[i])
1.1.1.13 root 662: return false;
1.1.1.10 root 663: i++;
664: }
665:
666: /* De-bounce key */
1.1.1.13 root 667: return true;
1.1.1.10 root 668: }
1.1.1.3 root 669:
1.1.1.10 root 670: /* Do not de-bounce key */
1.1.1.13 root 671: return false;
1.1.1.3 root 672: }
673:
674:
675: /*-----------------------------------------------------------------------*/
1.1.1.10 root 676: /**
677: * Debounce any PC key held down if running with key repeat disabled.
678: * This is called each ST frame, so keys get held down for one VBL which
679: * is enough for 68000 code to scan.
680: */
1.1.1.3 root 681: void Keymap_DebounceAllKeys(void)
682: {
1.1.1.16! root 683: uint8_t nScanCode;
1.1.1.10 root 684:
1.1.1.11 root 685: /* Return if we aren't in fast forward or have not disabled key repeat */
1.1.1.13 root 686: if ((ConfigureParams.System.bFastForward == false)
1.1.1.10 root 687: || (!ConfigureParams.Keyboard.bDisableKeyRepeat))
688: {
689: return;
690: }
691:
1.1.1.16! root 692: /* Now run through each key looking for ones held down */
! 693: for (nScanCode = 1; nScanCode <= KBD_MAX_SCANCODE; nScanCode++)
1.1.1.10 root 694: {
695: /* Is key held? */
1.1.1.16! root 696: if (Keyboard.KeyStates[nScanCode])
1.1.1.10 root 697: {
1.1.1.16! root 698: /* Does this require de-bouncing? */
! 699: if (Keymap_DebounceSTKey(nScanCode))
1.1.1.10 root 700: {
1.1.1.16! root 701: IKBD_PressSTKey(nScanCode, false);
! 702: Keyboard.KeyStates[nScanCode] = false;
1.1.1.10 root 703: }
704: }
705: }
1.1.1.3 root 706:
707: }
708:
709:
710: /*-----------------------------------------------------------------------*/
1.1.1.10 root 711: /**
712: * User press key down
713: */
1.1.1.5 root 714: void Keymap_KeyDown(SDL_keysym *sdlkey)
1.1.1.3 root 715: {
1.1.1.16! root 716: uint8_t STScanCode;
1.1.1.10 root 717: int symkey = sdlkey->sym;
718: int modkey = sdlkey->mod;
719:
720: /*fprintf(stderr, "keydown: sym=%i scan=%i mod=$%x\n",symkey, sdlkey->scancode, modkey);*/
721:
722: if (ShortCut_CheckKeys(modkey, symkey, 1))
723: return;
724:
725: /* If using joystick emulation via keyboard, DON'T send keys to keyboard processor!!!
726: * Some games use keyboard as pause! */
727: if (Joy_KeyDown(symkey, modkey))
728: return;
729:
730: /* Handle special keys */
731: if (symkey == SDLK_RALT || symkey == SDLK_LMETA || symkey == SDLK_RMETA
732: || symkey == SDLK_MODE || symkey == SDLK_NUMLOCK)
733: {
734: /* Ignore modifier keys that aren't passed to the ST */
735: return;
736: }
737:
738: STScanCode = Keymap_RemapKeyToSTScanCode(sdlkey);
1.1.1.16! root 739: if (STScanCode != (uint8_t)-1)
1.1.1.10 root 740: {
1.1.1.16! root 741: if (!Keyboard.KeyStates[STScanCode])
! 742: {
! 743: /* Set down */
! 744: Keyboard.KeyStates[STScanCode] = true;
1.1.1.13 root 745: IKBD_PressSTKey(STScanCode, true);
1.1.1.16! root 746: }
1.1.1.10 root 747: }
1.1.1.3 root 748: }
749:
750:
751: /*-----------------------------------------------------------------------*/
1.1.1.10 root 752: /**
753: * User released key
754: */
1.1.1.5 root 755: void Keymap_KeyUp(SDL_keysym *sdlkey)
1.1.1.3 root 756: {
1.1.1.16! root 757: uint8_t STScanCode;
1.1.1.10 root 758: int symkey = sdlkey->sym;
759: int modkey = sdlkey->mod;
760:
761: /*fprintf(stderr, "keyup: sym=%i scan=%i mod=$%x\n",symkey, sdlkey->scancode, modkey);*/
762:
763: /* Ignore short-cut keys here */
764:
765: if (ShortCut_CheckKeys(modkey, symkey, 0))
766: return;
767:
768: /* If using keyboard emulation, DON'T send keys to keyboard processor!!!
769: * Some games use keyboard as pause! */
770: if (Joy_KeyUp(symkey, modkey))
771: return;
772:
773: /* Handle special keys */
774: if (symkey == SDLK_RALT || symkey == SDLK_LMETA || symkey == SDLK_RMETA
775: || symkey == SDLK_MODE || symkey == SDLK_NUMLOCK)
776: {
777: /* Ignore modifier keys that aren't passed to the ST */
778: return;
779: }
780:
1.1.1.16! root 781: STScanCode = Keymap_RemapKeyToSTScanCode(sdlkey);
1.1.1.10 root 782: /* Release key (only if was pressed) */
1.1.1.16! root 783: if (STScanCode != (uint8_t)-1)
1.1.1.10 root 784: {
1.1.1.16! root 785: if (Keyboard.KeyStates[STScanCode])
1.1.1.10 root 786: {
1.1.1.13 root 787: IKBD_PressSTKey(STScanCode, false);
1.1.1.16! root 788: Keyboard.KeyStates[STScanCode] = false;
1.1.1.10 root 789: }
790: }
1.1.1.3 root 791: }
792:
1.1.1.11 root 793: /*-----------------------------------------------------------------------*/
794: /**
795: * Simulate press or release of a key corresponding to given character
796: */
797: void Keymap_SimulateCharacter(char asckey, bool press)
798: {
799: SDL_keysym sdlkey;
800:
1.1.1.13 root 801: sdlkey.mod = KMOD_NONE;
1.1.1.11 root 802: sdlkey.scancode = 0;
1.1.1.16! root 803: if (isupper((unsigned char)asckey)) {
1.1.1.11 root 804: if (press) {
805: sdlkey.sym = SDLK_LSHIFT;
806: Keymap_KeyDown(&sdlkey);
807: }
1.1.1.16! root 808: sdlkey.sym = tolower((unsigned char)asckey);
1.1.1.13 root 809: sdlkey.mod = KMOD_LSHIFT;
1.1.1.11 root 810: } else {
811: sdlkey.sym = asckey;
812: }
813: if (press) {
814: Keymap_KeyDown(&sdlkey);
815: } else {
816: Keymap_KeyUp(&sdlkey);
1.1.1.16! root 817: if (isupper((unsigned char)asckey)) {
1.1.1.11 root 818: sdlkey.sym = SDLK_LSHIFT;
819: Keymap_KeyUp(&sdlkey);
820: }
821: }
822: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.