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