Annotation of hatari/src/keymap.c, revision 1.1.1.12

1.1       root        1: /*
1.1.1.6   root        2:   Hatari - keymap.c
1.1.1.5   root        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.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...
                    647:  * Return TRUE if key requires de-bouncing
                    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? */
                    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])
                    662:                                return(FALSE);
                    663:                        i++;
                    664:                }
                    665: 
                    666:                /* De-bounce key */
                    667:                return TRUE;
                    668:        }
1.1.1.3   root      669: 
1.1.1.10  root      670:        /* Do not de-bounce key */
                    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 */
                    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];
                    750:        Keyboard.KeyStates[symkey] = TRUE;
                    751: 
                    752:        STScanCode = Keymap_RemapKeyToSTScanCode(sdlkey);
                    753:        if (STScanCode != (char)-1)
                    754:        {
                    755:                if (!bPreviousKeyState)
                    756:                        IKBD_PressSTKey(STScanCode, TRUE);
                    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:        else if (symkey == SDLK_CAPSLOCK)
                    791:        {
                    792:                /* Simulate another capslock key press */
                    793:                IKBD_PressSTKey(0x3A, TRUE);
                    794:        }
                    795: 
                    796:        /* Release key (only if was pressed) */
                    797:        if (Keyboard.KeyStates[symkey])
                    798:        {
                    799:                STScanCode = Keymap_RemapKeyToSTScanCode(sdlkey);
                    800:                if (STScanCode != (char)-1)
                    801:                {
                    802:                        IKBD_PressSTKey(STScanCode,FALSE);
                    803:                }
                    804:        }
1.1.1.3   root      805: 
1.1.1.10  root      806:        Keyboard.KeyStates[symkey] = FALSE;
1.1.1.3   root      807: }
                    808: 
1.1.1.11  root      809: /*-----------------------------------------------------------------------*/
                    810: /**
                    811:  * Simulate press or release of a key corresponding to given character
                    812:  */
                    813: void Keymap_SimulateCharacter(char asckey, bool press)
                    814: {
                    815:        SDL_keysym sdlkey;
                    816: 
                    817:        sdlkey.mod = 0;
                    818:        sdlkey.scancode = 0;
                    819:        if (isupper(asckey)) {
                    820:                if (press) {
                    821:                        sdlkey.sym = SDLK_LSHIFT;
                    822:                        Keymap_KeyDown(&sdlkey);
                    823:                }
                    824:                sdlkey.sym = tolower(asckey);
                    825:                sdlkey.mod = SDLK_LSHIFT;
                    826:        } else {
                    827:                sdlkey.sym = asckey;
                    828:        }
                    829:        if (press) {
                    830:                Keymap_KeyDown(&sdlkey);
                    831:        } else {
                    832:                Keymap_KeyUp(&sdlkey);
                    833:                if (isupper(asckey)) {
                    834:                        sdlkey.sym = SDLK_LSHIFT;
                    835:                        Keymap_KeyUp(&sdlkey);
                    836:                }
                    837:        }
                    838: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.