|
|
1.1 root 1: /*
2: Hatari
3:
1.1.1.3 ! root 4: Here we process a key press and the remapping of the scancodes.
1.1 root 5: */
6:
7: #include <stdio.h>
1.1.1.2 root 8: #include <SDL_keysym.h> /* Needed for SDLK_LAST */
1.1 root 9:
10: #include "main.h"
11: #include "debug.h"
12: #include "keymap.h"
13: #include "memAlloc.h"
14: #include "misc.h"
1.1.1.3 ! root 15: #include "dialog.h"
! 16: #include "ikbd.h"
! 17: #include "joy.h"
! 18: #include "shortcut.h"
! 19: #include "screen.h"
1.1 root 20:
1.1.1.2 root 21:
22: /*-----------------------------------------------------------------------*/
1.1 root 23: /*
24: Remap table of Windows keys to ST Scan codes, -ve is invalid key(ie doesn't occur on ST)
25:
26: PC Keyboard:-
27:
28: Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Print Scroll Pause
29:
30: 1 59 60 61 62 63 64 65 66 67 68 87 88 70 69
31:
32:
33: � ! " � $ % ^ & * ( ) _ + Page
34: ` 1 2 3 4 5 6 7 8 9 0 - = <- Ins Home Up
35:
36: 41 2 3 4 5 6 7 8 9 10 11 12 13 14 82 71 73
37: -- -- --
38: |
39: { } | Page
40: Tab Q W E R T Y U I O P [ ] <---- Del End Down
41:
42: 15 16 17 18 19 20 21 22 23 24 25 26 27 28 83 79 81
43: -- -- --
44:
45: : @ ~ ^
46: Caps A S D F G H J K L ; ' # |
47:
48: 58 30 31 32 33 34 35 36 37 38 39 40 43 72
49: --
50:
51: ^ | < > ? ^
52: | \ Z X C V B N M , . / | <- | ->
53:
54: 42 86 44 45 46 47 48 49 50 51 52 53 54 75 80 77
55: -- -- --
56:
57: Ctrl Alt SPACE Alt Gr Ctrl
58:
59: 29 56 57 56 29
60: --
61:
62: And:-
63:
64: Num
65: Lock / * -
66:
67: 69 53 55 74
68: -- --
69:
70: 7 8 9 +
71: Home ^ Pg Up
72:
73: 71 72 73 78
74:
75:
76: 4 5 6
77: <- ->
78:
79: 75 76 77
80:
81:
82: 1 2 3
83: End | Pg Dn Enter
84:
85: 79 70 81 28
86: --
87:
88: 0 .
89: Ins Del
90:
91: 82 83
92:
93:
94: */
95:
96:
97: /* SDL Key to ST scan code map table */
1.1.1.2 root 98: char Default_KeyToSTScanCode[SDLK_LAST] = {
99: /* ST Code, PC Code */
1.1 root 100: -1, /* 0 */
101: -1, /* 1 */
102: -1, /* 2 */
103: -1, /* 3 */
104: -1, /* 4 */
105: -1, /* 5 */
106: -1, /* 6 */
107: -1, /* 7 */
108: 0x0E, /* SDLK_BACKSPACE=8 */
109: 0x0F, /* SDLK_TAB=9 */
110: -1, /* 10 */
111: -1, /* 11 */
112: -1, /* SDLK_CLEAR = 12 */
113: 0x1C, /* SDLK_RETURN = 13 */
114: -1, /* 14 */
115: -1, /* 15 */
116: -1, /* 16 */
117: -1, /* 17 */
118: -1, /* 18 */
119: -1, /* SDLK_PAUSE = 19 */
120: -1, /* 20 */
121: -1, /* 21 */
122: -1, /* 22 */
123: -1, /* 23 */
124: -1, /* 24 */
125: -1, /* 25 */
126: -1, /* 26 */
127: 0x01, /* SDLK_ESCAPE = 27 */
128: -1, /* 28 */
129: -1, /* 29 */
130: -1, /* 30 */
131: -1, /* 31 */
132: 0x39, /* SDLK_SPACE = 32 */
133: -1, /* SDLK_EXCLAIM = 33 */
134: -1, /* SDLK_QUOTEDBL = 34 */
135: -1, /* SDLK_HASH = 35 */
136: -1, /* SDLK_DOLLAR = 36 */
137: -1, /* 37 */
138: -1, /* SDLK_AMPERSAND = 38 */
139: -1, /* SDLK_QUOTE = 39 */
140: 0x63, /* SDLK_LEFTPAREN = 40 */
141: 0x64, /* SDLK_RIGHTPAREN = 41 */
142: -1, /* SDLK_ASTERISK = 42 */
143: 0x1B, /* SDLK_PLUS = 43 */
144: 0x33, /* SDLK_COMMA = 44 */
145: 0x35, /* SDLK_MINUS = 45 */
146: 0x34, /* SDLK_PERIOD = 46 */
147: -1, /* SDLK_SLASH = 47 */
148: 0x0B, /* SDLK_0 = 48 */
149: 0x02, /* SDLK_1 = 49 */
150: 0x03, /* SDLK_2 = 50 */
151: 0x04, /* SDLK_3 = 51 */
152: 0x05, /* SDLK_4 = 52 */
153: 0x06, /* SDLK_5 = 53 */
154: 0x07, /* SDLK_6 = 54 */
155: 0x08, /* SDLK_7 = 55 */
156: 0x09, /* SDLK_8 = 56 */
157: 0x0A, /* SDLK_9 = 57 */
158: -1, /* SDLK_COLON = 58 */
159: -1, /* SDLK_SEMICOLON = 59 */
160: 0x60, /* SDLK_LESS = 60 */
161: -1, /* SDLK_EQUALS = 61 */
162: -1, /* SDLK_GREATER = 62 */
163: -1, /* SDLK_QUESTION = 63 */
164: -1, /* SDLK_AT = 64 */
165: -1, /* 65 */ /* Skip uppercase letters */
166: -1, /* 66 */
167: -1, /* 67 */
168: -1, /* 68 */
169: -1, /* 69 */
170: -1, /* 70 */
171: -1, /* 71 */
172: -1, /* 72 */
173: -1, /* 73 */
174: -1, /* 74 */
175: -1, /* 75 */
176: -1, /* 76 */
177: -1, /* 77 */
178: -1, /* 78 */
179: -1, /* 79 */
180: -1, /* 80 */
181: -1, /* 81 */
182: -1, /* 82 */
183: -1, /* 83 */
184: -1, /* 84 */
185: -1, /* 85 */
186: -1, /* 86 */
187: -1, /* 87 */
188: -1, /* 88 */
189: -1, /* 89 */
190: -1, /* 90 */
191: -1, /* SDLK_LEFTBRACKET = 91 */
192: -1, /* SDLK_BACKSLASH = 92 */
193: -1, /* SDLK_RIGHTBRACKET = 93 */
194: -1, /* SDLK_CARET = 94 */
195: -1, /* SDLK_UNDERSCORE = 95 */
196: -1, /* SDLK_BACKQUOTE = 96 */
197: 0x1E, /* SDLK_a = 97 */
198: 0x30, /* SDLK_b = 98 */
199: 0x2E, /* SDLK_c = 99 */
200: 0x20, /* SDLK_d = 100 */
201: 0x12, /* SDLK_e = 101 */
202: 0x21, /* SDLK_f = 102 */
203: 0x22, /* SDLK_g = 103 */
204: 0x23, /* SDLK_h = 104 */
205: 0x17, /* SDLK_i = 105 */
206: 0x24, /* SDLK_j = 106 */
207: 0x25, /* SDLK_k = 107 */
208: 0x26, /* SDLK_l = 108 */
209: 0x32, /* SDLK_m = 109 */
210: 0x31, /* SDLK_n = 110 */
211: 0x18, /* SDLK_o = 111 */
212: 0x19, /* SDLK_p = 112 */
213: 0x10, /* SDLK_q = 113 */
214: 0x13, /* SDLK_r = 114 */
215: 0x1F, /* SDLK_s = 115 */
216: 0x14, /* SDLK_t = 116 */
217: 0x16, /* SDLK_u = 117 */
218: 0x2F, /* SDLK_v = 118 */
219: 0x11, /* SDLK_w = 119 */
220: 0x2D, /* SDLK_x = 120 */
221: 0x15, /* SDLK_y = 121 */
222: 0x2C, /* SDLK_z = 122 */
223: -1, /* 123 */
224: -1, /* 124 */
225: -1, /* 125 */
226: -1, /* 126 */
227: 0x53, /* SDLK_DELETE = 127 */
228: /* End of ASCII mapped keysyms */
229: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 128-143*/
230: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 144-159*/
231: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 160-175*/
232: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 176-191*/
233: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192-207*/
234: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208-223*/
235: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224-239*/
236: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240-255*/
237: /* Numeric keypad: */
238: 0x70, /* SDLK_KP0 = 256 */
239: 0x6D, /* SDLK_KP1 = 257 */
240: 0x6E, /* SDLK_KP2 = 258 */
241: 0x6F, /* SDLK_KP3 = 259 */
242: 0x6A, /* SDLK_KP4 = 260 */
243: 0x6B, /* SDLK_KP5 = 261 */
244: 0x6C, /* SDLK_KP6 = 262 */
245: 0x67, /* SDLK_KP7 = 263 */
246: 0x68, /* SDLK_KP8 = 264 */
247: 0x69, /* SDLK_KP9 = 265 */
248: 0x71, /* SDLK_KP_PERIOD = 266 */
249: 0x65, /* SDLK_KP_DIVIDE = 267 */
250: 0x66, /* SDLK_KP_MULTIPLY = 268 */
251: 0x4A, /* SDLK_KP_MINUS = 269 */
252: 0x4E, /* SDLK_KP_PLUS = 270 */
253: 0x72, /* SDLK_KP_ENTER = 271 */
254: -1, /* SDLK_KP_EQUALS = 272 */
255: /* Arrows + Home/End pad */
256: 0x48, /* SDLK_UP = 273 */
257: 0x50, /* SDLK_DOWN = 274 */
258: 0x4D, /* SDLK_RIGHT = 275 */
259: 0x4B, /* SDLK_LEFT = 276 */
260: 0x52, /* SDLK_INSERT = 277 */
261: 0x47, /* SDLK_HOME = 278 */
262: 0x61, /* SDLK_END = 279 */
263: 0x63, /* SDLK_PAGEUP = 280 */
264: 0x64, /* SDLK_PAGEDOWN = 281 */
265: /* Function keys */
266: 0x3B, /* SDLK_F1 = 282 */
267: 0x3C, /* SDLK_F2 = 283 */
268: 0x3D, /* SDLK_F3 = 284 */
269: 0x3E, /* SDLK_F4 = 285 */
270: 0x3F, /* SDLK_F5 = 286 */
271: 0x40, /* SDLK_F6 = 287 */
272: 0x41, /* SDLK_F7 = 288 */
273: 0x42, /* SDLK_F8 = 289 */
274: 0x43, /* SDLK_F9 = 290 */
275: 0x44, /* SDLK_F10 = 291 */
276: -1, /* SDLK_F11 = 292 */
277: -1, /* SDLK_F12 = 293 */
278: -1, /* SDLK_F13 = 294 */
279: -1, /* SDLK_F14 = 295 */
280: -1, /* SDLK_F15 = 296 */
281: -1, /* 297 */
282: -1, /* 298 */
283: -1, /* 299 */
284: /* Key state modifier keys */
285: -1, /* SDLK_NUMLOCK = 300 */
286: 0x3A, /* SDLK_CAPSLOCK = 301 */
287: 0x61, /* SDLK_SCROLLOCK = 302 */
288: 0x36, /* SDLK_RSHIFT = 303 */
289: 0x2A, /* SDLK_LSHIFT = 304 */
290: 0x1D, /* SDLK_RCTRL = 305 */
291: 0x1D, /* SDLK_LCTRL = 306 */
292: 0x38, /* SDLK_RALT = 307 */
293: 0x38, /* SDLK_LALT = 308 */
294: -1, /* SDLK_RMETA = 309 */
295: -1, /* SDLK_LMETA = 310 */
296: -1, /* SDLK_LSUPER = 311 */ /* Left "Windows" key */
297: -1, /* SDLK_RSUPER = 312 */ /* Right "Windows" key */
298: -1, /* SDLK_MODE = 313 */ /* "Alt Gr" key */
299: -1, /* SDLK_COMPOSE = 314 */ /* Multi-key compose key */
300: /* Miscellaneous function keys */
301: 0x62, /* SDLK_HELP = 315 */
302: 0x63, /* SDLK_PRINT = 316 */
303: -1, /* SDLK_SYSREQ = 317 */
304: -1, /* SDLK_BREAK = 318 */
305: -1, /* SDLK_MENU = 319 */
306: };
307:
308:
1.1.1.3 ! root 309: /* List of ST scan codes to NOT de-bounce when running in maximum speed */
! 310: char DebounceExtendedKeys[] = {
! 311: 0x1d, /* CTRL */
! 312: 0x2a, /* Left SHIFT */
! 313: 0x01, /* ESC */
! 314: 0x38, /* ALT */
! 315: 0x36, /* Right SHIFT */
! 316: 0 /* term */
! 317: };
! 318:
! 319:
1.1.1.2 root 320: char Loaded_KeyToSTScanCode[SDLK_LAST];
1.1 root 321: BOOL bRemapKeyLoaded=FALSE;
322:
323:
1.1.1.2 root 324: /*-----------------------------------------------------------------------*/
1.1 root 325: /*
326: Remap SDL Key to ST Scan code
327: */
328: char Keymap_RemapKeyToSTScanCode(unsigned int Key)
329: {
1.1.1.2 root 330: if( Key >= SDLK_LAST ) return -1; /* Avoid illegal keys */
1.1 root 331: /* Use default or loaded? */
332: if (bRemapKeyLoaded)
333: return(Loaded_KeyToSTScanCode[Key]);
334: else
335: return(Default_KeyToSTScanCode[Key]);
336: }
337:
1.1.1.2 root 338:
339: /*-----------------------------------------------------------------------*/
1.1 root 340: /*
341: Load keyboard remap file
342: */
343: void Keymap_LoadRemapFile(char *pszFileName)
344: {
345: char szString[1024];
346: unsigned int STScanCode,PCScanCode;
347: FILE *in;
348:
1.1.1.2 root 349: /* Default to not loaded */
1.1 root 350: bRemapKeyLoaded = FALSE;
351: Memory_Set(Loaded_KeyToSTScanCode,-1,sizeof(Loaded_KeyToSTScanCode));
352:
1.1.1.2 root 353: /* Attempt to load file */
1.1 root 354: if (strlen(pszFileName)>0) {
1.1.1.2 root 355: /* Open file */
1.1 root 356: in = fopen(pszFileName, "r");
357: if (in) {
358: while(!feof(in)) {
1.1.1.2 root 359: /* Read line from file */
1.1 root 360: fgets(szString, 1024, in);
1.1.1.2 root 361: /* Remove white-space from start of line */
1.1 root 362: Misc_RemoveWhiteSpace(szString,sizeof(szString));
363: if (strlen(szString)>0) {
1.1.1.2 root 364: /* Is a comment? */
1.1 root 365: if ( (szString[0]==';') || (szString[0]=='#') )
366: continue;
1.1.1.2 root 367: /* Read values */
1.1 root 368: sscanf(szString,"%d,%d",&STScanCode,&PCScanCode);
1.1.1.2 root 369: /* Store into remap table, check both value within range */
370: if ( (PCScanCode>=0) && (PCScanCode<SDLK_LAST) && (STScanCode>=0) && (STScanCode<256) )
1.1 root 371: Loaded_KeyToSTScanCode[PCScanCode] = STScanCode;
372: }
373: }
1.1.1.2 root 374: /* Loaded OK */
1.1 root 375: bRemapKeyLoaded = TRUE;
376:
377: fclose(in);
378: }
379: }
380: }
1.1.1.3 ! root 381:
! 382:
! 383:
! 384: /*-----------------------------------------------------------------------*/
! 385: /*
! 386: Scan list of keys to NOT de-bounce when running in maximum speed, eg ALT,SHIFT,CTRL etc...
! 387: Return TRUE if key requires de-bouncing
! 388: */
! 389: BOOL Keymap_DebounceSTKey(char STScanCode)
! 390: {
! 391: int i=0;
! 392:
! 393: /* Are we in maximum speed, and have disabled key repeat? */
! 394: if ( (ConfigureParams.Configure.nMinMaxSpeed!=MINMAXSPEED_MIN) && (ConfigureParams.Keyboard.bDisableKeyRepeat) ) {
! 395: /* We should de-bounce all non extended keys, eg leave ALT,SHIFT,CTRL etc... held */
! 396: while (DebounceExtendedKeys[i]) {
! 397: if (STScanCode==DebounceExtendedKeys[i])
! 398: return(FALSE);
! 399: i++;
! 400: }
! 401:
! 402: /* De-bounce key */
! 403: return(TRUE);
! 404: }
! 405:
! 406: /* Do not de-bounce key */
! 407: return(FALSE);
! 408: }
! 409:
! 410:
! 411: /*-----------------------------------------------------------------------*/
! 412: /*
! 413: Debounce any PC key held down if running with key repeat disabled
! 414: This is called each ST frame, so keys get held down for one VBL which is enough for 68000 code to scan
! 415: */
! 416: void Keymap_DebounceAllKeys(void)
! 417: {
! 418: unsigned int Key;
! 419: char STScanCode;
! 420:
! 421: /* Are we in maximum speed, and have disabled key repeat? */
! 422: if ( (ConfigureParams.Configure.nMinMaxSpeed!=MINMAXSPEED_MIN) && (ConfigureParams.Keyboard.bDisableKeyRepeat) ) {
! 423: /* Now run through each PC key looking for ones held down */
! 424: for(Key=0; Key<SDLK_LAST; Key++) {
! 425: /* Is key held? */
! 426: if (Keyboard.KeyStates[Key]) {
! 427: /* Get scan code */
! 428: STScanCode = Keymap_RemapKeyToSTScanCode(Key);
! 429: if (STScanCode!=-1) {
! 430: /* Does this require de-bouncing? */
! 431: if (Keymap_DebounceSTKey(STScanCode))
! 432: Keymap_KeyUp(Key, 0);
! 433: }
! 434: }
! 435: }
! 436: }
! 437:
! 438: }
! 439:
! 440:
! 441: /*-----------------------------------------------------------------------*/
! 442: /*
! 443: User press key down
! 444: */
! 445: void Keymap_KeyDown( unsigned int sdlkey, unsigned int sdlmod )
! 446: {
! 447: BOOL bPreviousKeyState;
! 448: char STScanCode;
! 449: unsigned int Key;
! 450:
! 451: Key = sdlkey;
! 452:
! 453: /* If using cursor emulation, DON'T send keys to keyboard processor!!! Some games use keyboard as pause! */
! 454: if ( (ConfigureParams.Joysticks.Joy[0].bCursorEmulation || ConfigureParams.Joysticks.Joy[1].bCursorEmulation)
! 455: && !(sdlmod&(KMOD_LSHIFT|KMOD_RSHIFT)) )
! 456: {
! 457: if( Key==SDLK_UP ) { cursorJoyEmu |= 1; return; }
! 458: else if( Key==SDLK_DOWN ) { cursorJoyEmu |= 2; return; }
! 459: else if( Key==SDLK_LEFT ) { cursorJoyEmu |= 4; return; }
! 460: else if( Key==SDLK_RIGHT ) { cursorJoyEmu |= 8; return; }
! 461: else if( Key==SDLK_RCTRL || Key==SDLK_KP0 ) { cursorJoyEmu |= 128; return; }
! 462: }
! 463:
! 464: /* Set down */
! 465: bPreviousKeyState = Keyboard.KeyStates[Key];
! 466: Keyboard.KeyStates[Key] = TRUE;
! 467:
! 468: /* Jump directly to the debugger? */
! 469: if( sdlkey==SDLK_PAUSE && bEnableDebug)
! 470: {
! 471: if(bInFullScreen) Screen_ReturnFromFullScreen();
! 472: DebugUI();
! 473: }
! 474:
! 475: /* If pressed short-cut key, retain keypress until safe to execute (start of VBL) */
! 476: if ( (sdlmod&KMOD_MODE) || (sdlkey==SDLK_F11) || (sdlkey==SDLK_F12) || (sdlkey==SDLK_PAUSE) )
! 477: {
! 478: ShortCutKey.Key = sdlkey;
! 479: if( sdlmod&(KMOD_LCTRL|KMOD_RCTRL) ) ShortCutKey.bCtrlPressed = TRUE;
! 480: if( sdlmod&(KMOD_LSHIFT|KMOD_RSHIFT) ) ShortCutKey.bShiftPressed = TRUE;
! 481: }
! 482: else
! 483: {
! 484: STScanCode = Keymap_RemapKeyToSTScanCode(Key);
! 485: if (STScanCode!=-1)
! 486: {
! 487: if (!bPreviousKeyState)
! 488: IKBD_PressSTKey(STScanCode,TRUE);
! 489: }
! 490: }
! 491:
! 492: }
! 493:
! 494:
! 495: /*-----------------------------------------------------------------------*/
! 496: /*
! 497: User released key
! 498: */
! 499: void Keymap_KeyUp(unsigned int sdlkey, unsigned int sdlmod)
! 500: {
! 501: char STScanCode;
! 502: unsigned int Key;
! 503:
! 504: Key = sdlkey;
! 505:
! 506:
! 507: /* If using cursor emulation, DON'T send keys to keyboard processor!!! Some games use keyboard as pause! */
! 508: if ( (ConfigureParams.Joysticks.Joy[0].bCursorEmulation || ConfigureParams.Joysticks.Joy[1].bCursorEmulation)
! 509: && !(sdlmod&(KMOD_LSHIFT|KMOD_RSHIFT)) )
! 510: {
! 511: if( Key==SDLK_UP ) { cursorJoyEmu &= ~1; return; }
! 512: else if( Key==SDLK_DOWN ) { cursorJoyEmu &= ~2; return; }
! 513: else if( Key==SDLK_LEFT ) { cursorJoyEmu &= ~4; return; }
! 514: else if( Key==SDLK_RIGHT ) { cursorJoyEmu &= ~8; return; }
! 515: else if( Key==SDLK_RCTRL || Key==SDLK_KP0 ) { cursorJoyEmu &= ~128; return; }
! 516: }
! 517:
! 518: /* Release key (only if was pressed) */
! 519: STScanCode = Keymap_RemapKeyToSTScanCode(Key);
! 520: if (STScanCode!=-1) {
! 521: if (Keyboard.KeyStates[Key])
! 522: IKBD_PressSTKey(STScanCode,FALSE);
! 523: }
! 524:
! 525: Keyboard.KeyStates[Key] = FALSE;
! 526: }
! 527:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.