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

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

unix.superglobalmegacorp.com

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