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