|
|
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.5 root 548: 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.10 root 683: SDLKey key; 684: char STScanCode; 685: SDL_keysym tmpKeySym; 686: 1.1.1.11 root 687: /* Return if we aren't in fast forward or have not disabled key repeat */ 1.1.1.13 root 688: if ((ConfigureParams.System.bFastForward == false) 1.1.1.10 root 689: || (!ConfigureParams.Keyboard.bDisableKeyRepeat)) 690: { 691: return; 692: } 693: 694: tmpKeySym.mod = KMOD_NONE; 695: 696: /* Now run through each PC key looking for ones held down */ 697: for (key = SDLK_FIRST; key < SDLK_LAST; key++) 698: { 699: /* Is key held? */ 700: if (Keyboard.KeyStates[key]) 701: { 702: tmpKeySym.sym = key; 703: tmpKeySym.scancode = 0; 704: 705: /* Get scan code */ 706: STScanCode = Keymap_RemapKeyToSTScanCode(&tmpKeySym); 707: if (STScanCode != (char)-1) 708: { 709: /* Does this require de-bouncing? */ 710: if (Keymap_DebounceSTKey(STScanCode)) 711: Keymap_KeyUp(&tmpKeySym); 712: } 713: } 714: } 1.1.1.3 root 715: 716: } 717: 718: 719: /*-----------------------------------------------------------------------*/ 1.1.1.10 root 720: /** 721: * User press key down 722: */ 1.1.1.5 root 723: void Keymap_KeyDown(SDL_keysym *sdlkey) 1.1.1.3 root 724: { 1.1.1.11 root 725: bool bPreviousKeyState; 1.1.1.10 root 726: char STScanCode; 727: int symkey = sdlkey->sym; 728: int modkey = sdlkey->mod; 729: 730: /*fprintf(stderr, "keydown: sym=%i scan=%i mod=$%x\n",symkey, sdlkey->scancode, modkey);*/ 731: 732: if (ShortCut_CheckKeys(modkey, symkey, 1)) 733: return; 734: 735: /* If using joystick emulation via keyboard, DON'T send keys to keyboard processor!!! 736: * Some games use keyboard as pause! */ 737: if (Joy_KeyDown(symkey, modkey)) 738: return; 739: 740: /* Handle special keys */ 741: if (symkey == SDLK_RALT || symkey == SDLK_LMETA || symkey == SDLK_RMETA 742: || symkey == SDLK_MODE || symkey == SDLK_NUMLOCK) 743: { 744: /* Ignore modifier keys that aren't passed to the ST */ 745: return; 746: } 747: 748: /* Set down */ 749: bPreviousKeyState = Keyboard.KeyStates[symkey]; 1.1.1.13 root 750: Keyboard.KeyStates[symkey] = true; 1.1.1.10 root 751: 752: STScanCode = Keymap_RemapKeyToSTScanCode(sdlkey); 753: if (STScanCode != (char)-1) 754: { 755: if (!bPreviousKeyState) 1.1.1.13 root 756: IKBD_PressSTKey(STScanCode, true); 1.1.1.10 root 757: } 1.1.1.3 root 758: } 759: 760: 761: /*-----------------------------------------------------------------------*/ 1.1.1.10 root 762: /** 763: * User released key 764: */ 1.1.1.5 root 765: void Keymap_KeyUp(SDL_keysym *sdlkey) 1.1.1.3 root 766: { 1.1.1.10 root 767: char STScanCode; 768: int symkey = sdlkey->sym; 769: int modkey = sdlkey->mod; 770: 771: /*fprintf(stderr, "keyup: sym=%i scan=%i mod=$%x\n",symkey, sdlkey->scancode, modkey);*/ 772: 773: /* Ignore short-cut keys here */ 774: 775: if (ShortCut_CheckKeys(modkey, symkey, 0)) 776: return; 777: 778: /* If using keyboard emulation, DON'T send keys to keyboard processor!!! 779: * Some games use keyboard as pause! */ 780: if (Joy_KeyUp(symkey, modkey)) 781: return; 782: 783: /* Handle special keys */ 784: if (symkey == SDLK_RALT || symkey == SDLK_LMETA || symkey == SDLK_RMETA 785: || symkey == SDLK_MODE || symkey == SDLK_NUMLOCK) 786: { 787: /* Ignore modifier keys that aren't passed to the ST */ 788: return; 789: } 790: 791: /* Release key (only if was pressed) */ 792: if (Keyboard.KeyStates[symkey]) 793: { 794: STScanCode = Keymap_RemapKeyToSTScanCode(sdlkey); 795: if (STScanCode != (char)-1) 796: { 1.1.1.13 root 797: IKBD_PressSTKey(STScanCode, false); 1.1.1.10 root 798: } 799: } 1.1.1.3 root 800: 1.1.1.13 root 801: Keyboard.KeyStates[symkey] = false; 1.1.1.3 root 802: } 803: 1.1.1.11 root 804: /*-----------------------------------------------------------------------*/ 805: /** 806: * Simulate press or release of a key corresponding to given character 807: */ 808: void Keymap_SimulateCharacter(char asckey, bool press) 809: { 810: SDL_keysym sdlkey; 811: 1.1.1.13 root 812: sdlkey.mod = KMOD_NONE; 1.1.1.11 root 813: sdlkey.scancode = 0; 814: if (isupper(asckey)) { 815: if (press) { 816: sdlkey.sym = SDLK_LSHIFT; 817: Keymap_KeyDown(&sdlkey); 818: } 819: sdlkey.sym = tolower(asckey); 1.1.1.13 root 820: sdlkey.mod = KMOD_LSHIFT; 1.1.1.11 root 821: } else { 822: sdlkey.sym = asckey; 823: } 824: if (press) { 825: Keymap_KeyDown(&sdlkey); 826: } else { 827: Keymap_KeyUp(&sdlkey); 828: if (isupper(asckey)) { 829: sdlkey.sym = SDLK_LSHIFT; 830: Keymap_KeyUp(&sdlkey); 831: } 832: } 833: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.