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

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

unix.superglobalmegacorp.com

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