Annotation of quakeworld/client/keys.c, revision 1.1.1.1

1.1       root        1: /*
                      2: Copyright (C) 1996-1997 Id Software, Inc.
                      3: 
                      4: This program is free software; you can redistribute it and/or
                      5: modify it under the terms of the GNU General Public License
                      6: as published by the Free Software Foundation; either version 2
                      7: of the License, or (at your option) any later version.
                      8: 
                      9: This program is distributed in the hope that it will be useful,
                     10: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
                     12: 
                     13: See the GNU General Public License for more details.
                     14: 
                     15: You should have received a copy of the GNU General Public License
                     16: along with this program; if not, write to the Free Software
                     17: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
                     18: 
                     19: */
                     20: #include "quakedef.h"
                     21: #ifdef _WINDOWS
                     22: #include <windows.h>
                     23: #endif
                     24: /*
                     25: 
                     26: key up events are sent even if in console mode
                     27: 
                     28: */
                     29: 
                     30: 
                     31: #define                MAXCMDLINE      256
                     32: char   key_lines[32][MAXCMDLINE];
                     33: int            key_linepos;
                     34: int            shift_down=false;
                     35: int            key_lastpress;
                     36: 
                     37: int            edit_line=0;
                     38: int            history_line=0;
                     39: 
                     40: keydest_t      key_dest;
                     41: 
                     42: int            key_count;                      // incremented every key event
                     43: 
                     44: char   *keybindings[256];
                     45: qboolean       consolekeys[256];       // if true, can't be rebound while in console
                     46: qboolean       menubound[256]; // if true, can't be rebound while in menu
                     47: int            keyshift[256];          // key to map to if shift held down in console
                     48: int            key_repeats[256];       // if > 1, it is autorepeating
                     49: qboolean       keydown[256];
                     50: 
                     51: typedef struct
                     52: {
                     53:        char    *name;
                     54:        int             keynum;
                     55: } keyname_t;
                     56: 
                     57: keyname_t keynames[] =
                     58: {
                     59:        {"TAB", K_TAB},
                     60:        {"ENTER", K_ENTER},
                     61:        {"ESCAPE", K_ESCAPE},
                     62:        {"SPACE", K_SPACE},
                     63:        {"BACKSPACE", K_BACKSPACE},
                     64:        {"UPARROW", K_UPARROW},
                     65:        {"DOWNARROW", K_DOWNARROW},
                     66:        {"LEFTARROW", K_LEFTARROW},
                     67:        {"RIGHTARROW", K_RIGHTARROW},
                     68: 
                     69:        {"ALT", K_ALT},
                     70:        {"CTRL", K_CTRL},
                     71:        {"SHIFT", K_SHIFT},
                     72:        
                     73:        {"F1", K_F1},
                     74:        {"F2", K_F2},
                     75:        {"F3", K_F3},
                     76:        {"F4", K_F4},
                     77:        {"F5", K_F5},
                     78:        {"F6", K_F6},
                     79:        {"F7", K_F7},
                     80:        {"F8", K_F8},
                     81:        {"F9", K_F9},
                     82:        {"F10", K_F10},
                     83:        {"F11", K_F11},
                     84:        {"F12", K_F12},
                     85: 
                     86:        {"INS", K_INS},
                     87:        {"DEL", K_DEL},
                     88:        {"PGDN", K_PGDN},
                     89:        {"PGUP", K_PGUP},
                     90:        {"HOME", K_HOME},
                     91:        {"END", K_END},
                     92: 
                     93:        {"MOUSE1", K_MOUSE1},
                     94:        {"MOUSE2", K_MOUSE2},
                     95:        {"MOUSE3", K_MOUSE3},
                     96: 
                     97:        {"JOY1", K_JOY1},
                     98:        {"JOY2", K_JOY2},
                     99:        {"JOY3", K_JOY3},
                    100:        {"JOY4", K_JOY4},
                    101: 
                    102:        {"AUX1", K_AUX1},
                    103:        {"AUX2", K_AUX2},
                    104:        {"AUX3", K_AUX3},
                    105:        {"AUX4", K_AUX4},
                    106:        {"AUX5", K_AUX5},
                    107:        {"AUX6", K_AUX6},
                    108:        {"AUX7", K_AUX7},
                    109:        {"AUX8", K_AUX8},
                    110:        {"AUX9", K_AUX9},
                    111:        {"AUX10", K_AUX10},
                    112:        {"AUX11", K_AUX11},
                    113:        {"AUX12", K_AUX12},
                    114:        {"AUX13", K_AUX13},
                    115:        {"AUX14", K_AUX14},
                    116:        {"AUX15", K_AUX15},
                    117:        {"AUX16", K_AUX16},
                    118:        {"AUX17", K_AUX17},
                    119:        {"AUX18", K_AUX18},
                    120:        {"AUX19", K_AUX19},
                    121:        {"AUX20", K_AUX20},
                    122:        {"AUX21", K_AUX21},
                    123:        {"AUX22", K_AUX22},
                    124:        {"AUX23", K_AUX23},
                    125:        {"AUX24", K_AUX24},
                    126:        {"AUX25", K_AUX25},
                    127:        {"AUX26", K_AUX26},
                    128:        {"AUX27", K_AUX27},
                    129:        {"AUX28", K_AUX28},
                    130:        {"AUX29", K_AUX29},
                    131:        {"AUX30", K_AUX30},
                    132:        {"AUX31", K_AUX31},
                    133:        {"AUX32", K_AUX32},
                    134: 
                    135:        {"PAUSE", K_PAUSE},
                    136: 
                    137:        {"MWHEELUP", K_MWHEELUP},
                    138:        {"MWHEELDOWN", K_MWHEELDOWN},
                    139: 
                    140:        {"SEMICOLON", ';'},     // because a raw semicolon seperates commands
                    141: 
                    142:        {NULL,0}
                    143: };
                    144: 
                    145: /*
                    146: ==============================================================================
                    147: 
                    148:                        LINE TYPING INTO THE CONSOLE
                    149: 
                    150: ==============================================================================
                    151: */
                    152: 
                    153: qboolean CheckForCommand (void)
                    154: {
                    155:        char    command[128];
                    156:        char    *cmd, *s;
                    157:        int             i;
                    158: 
                    159:        s = key_lines[edit_line]+1;
                    160: 
                    161:        for (i=0 ; i<127 ; i++)
                    162:                if (s[i] <= ' ')
                    163:                        break;
                    164:                else
                    165:                        command[i] = s[i];
                    166:        command[i] = 0;
                    167: 
                    168:        cmd = Cmd_CompleteCommand (command);
                    169:        if (!cmd || strcmp (cmd, command))
                    170:                cmd = Cvar_CompleteVariable (command);
                    171:        if (!cmd  || strcmp (cmd, command) )
                    172:                return false;           // just a chat message
                    173:        return true;
                    174: }
                    175: 
                    176: void CompleteCommand (void)
                    177: {
                    178:        char    *cmd, *s;
                    179: 
                    180:        s = key_lines[edit_line]+1;
                    181:        if (*s == '\\' || *s == '/')
                    182:                s++;
                    183: 
                    184:        cmd = Cmd_CompleteCommand (s);
                    185:        if (!cmd)
                    186:                cmd = Cvar_CompleteVariable (s);
                    187:        if (cmd)
                    188:        {
                    189:                key_lines[edit_line][1] = '/';
                    190:                Q_strcpy (key_lines[edit_line]+2, cmd);
                    191:                key_linepos = Q_strlen(cmd)+2;
                    192:                key_lines[edit_line][key_linepos] = ' ';
                    193:                key_linepos++;
                    194:                key_lines[edit_line][key_linepos] = 0;
                    195:                return;
                    196:        }
                    197: }
                    198: 
                    199: /*
                    200: ====================
                    201: Key_Console
                    202: 
                    203: Interactive line editing and console scrollback
                    204: ====================
                    205: */
                    206: void Key_Console (int key)
                    207: {
                    208: #ifdef _WIN32
                    209:        char    *cmd, *s;
                    210:        int             i;
                    211:        HANDLE  th;
                    212:        char    *clipText, *textCopied;
                    213: #endif
                    214:        
                    215:        if (key == K_ENTER)
                    216:        {       // backslash text are commands, else chat
                    217:                if (key_lines[edit_line][1] == '\\' || key_lines[edit_line][1] == '/')
                    218:                        Cbuf_AddText (key_lines[edit_line]+2);  // skip the >
                    219:                else if (CheckForCommand())
                    220:                        Cbuf_AddText (key_lines[edit_line]+1);  // valid command
                    221:                else
                    222:                {       // convert to a chat message
                    223:                        if (cls.state >= ca_connected)
                    224:                                Cbuf_AddText ("say ");
                    225:                        Cbuf_AddText (key_lines[edit_line]+1);  // skip the >
                    226:                }
                    227: 
                    228:                Cbuf_AddText ("\n");
                    229:                Con_Printf ("%s\n",key_lines[edit_line]);
                    230:                edit_line = (edit_line + 1) & 31;
                    231:                history_line = edit_line;
                    232:                key_lines[edit_line][0] = ']';
                    233:                key_linepos = 1;
                    234:                if (cls.state == ca_disconnected)
                    235:                        SCR_UpdateScreen ();    // force an update, because the command
                    236:                                                                        // may take some time
                    237:                return;
                    238:        }
                    239: 
                    240:        if (key == K_TAB)
                    241:        {       // command completion
                    242:                CompleteCommand ();
                    243:                return;
                    244:        }
                    245:        
                    246:        if (key == K_BACKSPACE || key == K_LEFTARROW)
                    247:        {
                    248:                if (key_linepos > 1)
                    249:                        key_linepos--;
                    250:                return;
                    251:        }
                    252: 
                    253:        if (key == K_UPARROW)
                    254:        {
                    255:                do
                    256:                {
                    257:                        history_line = (history_line - 1) & 31;
                    258:                } while (history_line != edit_line
                    259:                                && !key_lines[history_line][1]);
                    260:                if (history_line == edit_line)
                    261:                        history_line = (edit_line+1)&31;
                    262:                Q_strcpy(key_lines[edit_line], key_lines[history_line]);
                    263:                key_linepos = Q_strlen(key_lines[edit_line]);
                    264:                return;
                    265:        }
                    266: 
                    267:        if (key == K_DOWNARROW)
                    268:        {
                    269:                if (history_line == edit_line) return;
                    270:                do
                    271:                {
                    272:                        history_line = (history_line + 1) & 31;
                    273:                }
                    274:                while (history_line != edit_line
                    275:                        && !key_lines[history_line][1]);
                    276:                if (history_line == edit_line)
                    277:                {
                    278:                        key_lines[edit_line][0] = ']';
                    279:                        key_linepos = 1;
                    280:                }
                    281:                else
                    282:                {
                    283:                        Q_strcpy(key_lines[edit_line], key_lines[history_line]);
                    284:                        key_linepos = Q_strlen(key_lines[edit_line]);
                    285:                }
                    286:                return;
                    287:        }
                    288: 
                    289:        if (key == K_PGUP || key==K_MWHEELUP)
                    290:        {
                    291:                con->display -= 2;
                    292:                return;
                    293:        }
                    294: 
                    295:        if (key == K_PGDN || key==K_MWHEELDOWN)
                    296:        {
                    297:                con->display += 2;
                    298:                if (con->display > con->current)
                    299:                        con->display = con->current;
                    300:                return;
                    301:        }
                    302: 
                    303:        if (key == K_HOME)
                    304:        {
                    305:                con->display = con->current - con_totallines + 10;
                    306:                return;
                    307:        }
                    308: 
                    309:        if (key == K_END)
                    310:        {
                    311:                con->display = con->current;
                    312:                return;
                    313:        }
                    314:        
                    315: #ifdef _WIN32
                    316:        if ((key=='V' || key=='v') && GetKeyState(VK_CONTROL)<0) {
                    317:                if (OpenClipboard(NULL)) {
                    318:                        th = GetClipboardData(CF_TEXT);
                    319:                        if (th) {
                    320:                                clipText = GlobalLock(th);
                    321:                                if (clipText) {
                    322:                                        textCopied = malloc(GlobalSize(th)+1);
                    323:                                        strcpy(textCopied, clipText);
                    324:        /* Substitutes a NULL for every token */strtok(textCopied, "\n\r\b");
                    325:                                        i = strlen(textCopied);
                    326:                                        if (i+key_linepos>=MAXCMDLINE)
                    327:                                                i=MAXCMDLINE-key_linepos;
                    328:                                        if (i>0) {
                    329:                                                textCopied[i]=0;
                    330:                                                strcat(key_lines[edit_line], textCopied);
                    331:                                                key_linepos+=i;;
                    332:                                        }
                    333:                                        free(textCopied);
                    334:                                }
                    335:                                GlobalUnlock(th);
                    336:                        }
                    337:                        CloseClipboard();
                    338:                return;
                    339:                }
                    340:        }
                    341: #endif
                    342: 
                    343:        if (key < 32 || key > 127)
                    344:                return; // non printable
                    345:                
                    346:        if (key_linepos < MAXCMDLINE-1)
                    347:        {
                    348:                key_lines[edit_line][key_linepos] = key;
                    349:                key_linepos++;
                    350:                key_lines[edit_line][key_linepos] = 0;
                    351:        }
                    352: 
                    353: }
                    354: 
                    355: //============================================================================
                    356: 
                    357: qboolean       chat_team;
                    358: char           chat_buffer[MAXCMDLINE];
                    359: int                    chat_bufferlen = 0;
                    360: 
                    361: void Key_Message (int key)
                    362: {
                    363: 
                    364:        if (key == K_ENTER)
                    365:        {
                    366:                if (chat_team)
                    367:                        Cbuf_AddText ("say_team \"");
                    368:                else
                    369:                        Cbuf_AddText ("say \"");
                    370:                Cbuf_AddText(chat_buffer);
                    371:                Cbuf_AddText("\"\n");
                    372: 
                    373:                key_dest = key_game;
                    374:                chat_bufferlen = 0;
                    375:                chat_buffer[0] = 0;
                    376:                return;
                    377:        }
                    378: 
                    379:        if (key == K_ESCAPE)
                    380:        {
                    381:                key_dest = key_game;
                    382:                chat_bufferlen = 0;
                    383:                chat_buffer[0] = 0;
                    384:                return;
                    385:        }
                    386: 
                    387:        if (key < 32 || key > 127)
                    388:                return; // non printable
                    389: 
                    390:        if (key == K_BACKSPACE)
                    391:        {
                    392:                if (chat_bufferlen)
                    393:                {
                    394:                        chat_bufferlen--;
                    395:                        chat_buffer[chat_bufferlen] = 0;
                    396:                }
                    397:                return;
                    398:        }
                    399: 
                    400:        if (chat_bufferlen == sizeof(chat_buffer)-1)
                    401:                return; // all full
                    402: 
                    403:        chat_buffer[chat_bufferlen++] = key;
                    404:        chat_buffer[chat_bufferlen] = 0;
                    405: }
                    406: 
                    407: //============================================================================
                    408: 
                    409: 
                    410: /*
                    411: ===================
                    412: Key_StringToKeynum
                    413: 
                    414: Returns a key number to be used to index keybindings[] by looking at
                    415: the given string.  Single ascii characters return themselves, while
                    416: the K_* names are matched up.
                    417: ===================
                    418: */
                    419: int Key_StringToKeynum (char *str)
                    420: {
                    421:        keyname_t       *kn;
                    422:        
                    423:        if (!str || !str[0])
                    424:                return -1;
                    425:        if (!str[1])
                    426:                return str[0];
                    427: 
                    428:        for (kn=keynames ; kn->name ; kn++)
                    429:        {
                    430:                if (!Q_strcasecmp(str,kn->name))
                    431:                        return kn->keynum;
                    432:        }
                    433:        return -1;
                    434: }
                    435: 
                    436: /*
                    437: ===================
                    438: Key_KeynumToString
                    439: 
                    440: Returns a string (either a single ascii char, or a K_* name) for the
                    441: given keynum.
                    442: FIXME: handle quote special (general escape sequence?)
                    443: ===================
                    444: */
                    445: char *Key_KeynumToString (int keynum)
                    446: {
                    447:        keyname_t       *kn;    
                    448:        static  char    tinystr[2];
                    449:        
                    450:        if (keynum == -1)
                    451:                return "<KEY NOT FOUND>";
                    452:        if (keynum > 32 && keynum < 127)
                    453:        {       // printable ascii
                    454:                tinystr[0] = keynum;
                    455:                tinystr[1] = 0;
                    456:                return tinystr;
                    457:        }
                    458:        
                    459:        for (kn=keynames ; kn->name ; kn++)
                    460:                if (keynum == kn->keynum)
                    461:                        return kn->name;
                    462: 
                    463:        return "<UNKNOWN KEYNUM>";
                    464: }
                    465: 
                    466: 
                    467: /*
                    468: ===================
                    469: Key_SetBinding
                    470: ===================
                    471: */
                    472: void Key_SetBinding (int keynum, char *binding)
                    473: {
                    474:        char    *new;
                    475:        int             l;
                    476:                        
                    477:        if (keynum == -1)
                    478:                return;
                    479: 
                    480: // free old bindings
                    481:        if (keybindings[keynum])
                    482:        {
                    483:                Z_Free (keybindings[keynum]);
                    484:                keybindings[keynum] = NULL;
                    485:        }
                    486:                        
                    487: // allocate memory for new binding
                    488:        l = Q_strlen (binding); 
                    489:        new = Z_Malloc (l+1);
                    490:        Q_strcpy (new, binding);
                    491:        new[l] = 0;
                    492:        keybindings[keynum] = new;      
                    493: }
                    494: 
                    495: /*
                    496: ===================
                    497: Key_Unbind_f
                    498: ===================
                    499: */
                    500: void Key_Unbind_f (void)
                    501: {
                    502:        int             b;
                    503: 
                    504:        if (Cmd_Argc() != 2)
                    505:        {
                    506:                Con_Printf ("unbind <key> : remove commands from a key\n");
                    507:                return;
                    508:        }
                    509:        
                    510:        b = Key_StringToKeynum (Cmd_Argv(1));
                    511:        if (b==-1)
                    512:        {
                    513:                Con_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv(1));
                    514:                return;
                    515:        }
                    516: 
                    517:        Key_SetBinding (b, "");
                    518: }
                    519: 
                    520: void Key_Unbindall_f (void)
                    521: {
                    522:        int             i;
                    523:        
                    524:        for (i=0 ; i<256 ; i++)
                    525:                if (keybindings[i])
                    526:                        Key_SetBinding (i, "");
                    527: }
                    528: 
                    529: 
                    530: /*
                    531: ===================
                    532: Key_Bind_f
                    533: ===================
                    534: */
                    535: void Key_Bind_f (void)
                    536: {
                    537:        int                     i, c, b;
                    538:        char            cmd[1024];
                    539:        
                    540:        c = Cmd_Argc();
                    541: 
                    542:        if (c != 2 && c != 3)
                    543:        {
                    544:                Con_Printf ("bind <key> [command] : attach a command to a key\n");
                    545:                return;
                    546:        }
                    547:        b = Key_StringToKeynum (Cmd_Argv(1));
                    548:        if (b==-1)
                    549:        {
                    550:                Con_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv(1));
                    551:                return;
                    552:        }
                    553: 
                    554:        if (c == 2)
                    555:        {
                    556:                if (keybindings[b])
                    557:                        Con_Printf ("\"%s\" = \"%s\"\n", Cmd_Argv(1), keybindings[b] );
                    558:                else
                    559:                        Con_Printf ("\"%s\" is not bound\n", Cmd_Argv(1) );
                    560:                return;
                    561:        }
                    562:        
                    563: // copy the rest of the command line
                    564:        cmd[0] = 0;             // start out with a null string
                    565:        for (i=2 ; i< c ; i++)
                    566:        {
                    567:                strcat (cmd, Cmd_Argv(i));
                    568:                if (i != (c-1))
                    569:                        strcat (cmd, " ");
                    570:        }
                    571: 
                    572:        Key_SetBinding (b, cmd);
                    573: }
                    574: 
                    575: /*
                    576: ============
                    577: Key_WriteBindings
                    578: 
                    579: Writes lines containing "bind key value"
                    580: ============
                    581: */
                    582: void Key_WriteBindings (FILE *f)
                    583: {
                    584:        int             i;
                    585: 
                    586:        for (i=0 ; i<256 ; i++)
                    587:                if (keybindings[i])
                    588:                        fprintf (f, "bind %s \"%s\"\n", Key_KeynumToString(i), keybindings[i]);
                    589: }
                    590: 
                    591: 
                    592: /*
                    593: ===================
                    594: Key_Init
                    595: ===================
                    596: */
                    597: void Key_Init (void)
                    598: {
                    599:        int             i;
                    600: 
                    601:        for (i=0 ; i<32 ; i++)
                    602:        {
                    603:                key_lines[i][0] = ']';
                    604:                key_lines[i][1] = 0;
                    605:        }
                    606:        key_linepos = 1;
                    607:        
                    608: //
                    609: // init ascii characters in console mode
                    610: //
                    611:        for (i=32 ; i<128 ; i++)
                    612:                consolekeys[i] = true;
                    613:        consolekeys[K_ENTER] = true;
                    614:        consolekeys[K_TAB] = true;
                    615:        consolekeys[K_LEFTARROW] = true;
                    616:        consolekeys[K_RIGHTARROW] = true;
                    617:        consolekeys[K_UPARROW] = true;
                    618:        consolekeys[K_DOWNARROW] = true;
                    619:        consolekeys[K_BACKSPACE] = true;
                    620:        consolekeys[K_HOME] = true;
                    621:        consolekeys[K_END] = true;
                    622:        consolekeys[K_PGUP] = true;
                    623:        consolekeys[K_PGDN] = true;
                    624:        consolekeys[K_SHIFT] = true;
                    625:        consolekeys[K_MWHEELUP] = true;
                    626:        consolekeys[K_MWHEELDOWN] = true;
                    627:        consolekeys['`'] = false;
                    628:        consolekeys['~'] = false;
                    629: 
                    630:        for (i=0 ; i<256 ; i++)
                    631:                keyshift[i] = i;
                    632:        for (i='a' ; i<='z' ; i++)
                    633:                keyshift[i] = i - 'a' + 'A';
                    634:        keyshift['1'] = '!';
                    635:        keyshift['2'] = '@';
                    636:        keyshift['3'] = '#';
                    637:        keyshift['4'] = '$';
                    638:        keyshift['5'] = '%';
                    639:        keyshift['6'] = '^';
                    640:        keyshift['7'] = '&';
                    641:        keyshift['8'] = '*';
                    642:        keyshift['9'] = '(';
                    643:        keyshift['0'] = ')';
                    644:        keyshift['-'] = '_';
                    645:        keyshift['='] = '+';
                    646:        keyshift[','] = '<';
                    647:        keyshift['.'] = '>';
                    648:        keyshift['/'] = '?';
                    649:        keyshift[';'] = ':';
                    650:        keyshift['\''] = '"';
                    651:        keyshift['['] = '{';
                    652:        keyshift[']'] = '}';
                    653:        keyshift['`'] = '~';
                    654:        keyshift['\\'] = '|';
                    655: 
                    656:        menubound[K_ESCAPE] = true;
                    657:        for (i=0 ; i<12 ; i++)
                    658:                menubound[K_F1+i] = true;
                    659: 
                    660: //
                    661: // register our functions
                    662: //
                    663:        Cmd_AddCommand ("bind",Key_Bind_f);
                    664:        Cmd_AddCommand ("unbind",Key_Unbind_f);
                    665:        Cmd_AddCommand ("unbindall",Key_Unbindall_f);
                    666: 
                    667: 
                    668: }
                    669: 
                    670: /*
                    671: ===================
                    672: Key_Event
                    673: 
                    674: Called by the system between frames for both key up and key down events
                    675: Should NOT be called during an interrupt!
                    676: ===================
                    677: */
                    678: void Key_Event (int key, qboolean down)
                    679: {
                    680:        char    *kb;
                    681:        char    cmd[1024];
                    682: 
                    683: //     Con_Printf ("%i : %i\n", key, down); //@@@
                    684: 
                    685:        keydown[key] = down;
                    686: 
                    687:        if (!down)
                    688:                key_repeats[key] = 0;
                    689: 
                    690:        key_lastpress = key;
                    691:        key_count++;
                    692:        if (key_count <= 0)
                    693:        {
                    694:                return;         // just catching keys for Con_NotifyBox
                    695:        }
                    696: 
                    697: // update auto-repeat status
                    698:        if (down)
                    699:        {
                    700:                key_repeats[key]++;
                    701:                if (key != K_BACKSPACE 
                    702:                        && key != K_PAUSE 
                    703:                        && key != K_PGUP 
                    704:                        && key != K_PGDN
                    705:                        && key_repeats[key] > 1)
                    706:                        return; // ignore most autorepeats
                    707:                        
                    708:                if (key >= 200 && !keybindings[key])
                    709:                        Con_Printf ("%s is unbound, hit F4 to set.\n", Key_KeynumToString (key) );
                    710:        }
                    711: 
                    712:        if (key == K_SHIFT)
                    713:                shift_down = down;
                    714: 
                    715: //
                    716: // handle escape specialy, so the user can never unbind it
                    717: //
                    718:        if (key == K_ESCAPE)
                    719:        {
                    720:                if (!down)
                    721:                        return;
                    722:                switch (key_dest)
                    723:                {
                    724:                case key_message:
                    725:                        Key_Message (key);
                    726:                        break;
                    727:                case key_menu:
                    728:                        M_Keydown (key);
                    729:                        break;
                    730:                case key_game:
                    731:                case key_console:
                    732:                        M_ToggleMenu_f ();
                    733:                        break;
                    734:                default:
                    735:                        Sys_Error ("Bad key_dest");
                    736:                }
                    737:                return;
                    738:        }
                    739: 
                    740: //
                    741: // key up events only generate commands if the game key binding is
                    742: // a button command (leading + sign).  These will occur even in console mode,
                    743: // to keep the character from continuing an action started before a console
                    744: // switch.  Button commands include the kenum as a parameter, so multiple
                    745: // downs can be matched with ups
                    746: //
                    747:        if (!down)
                    748:        {
                    749:                kb = keybindings[key];
                    750:                if (kb && kb[0] == '+')
                    751:                {
                    752:                        sprintf (cmd, "-%s %i\n", kb+1, key);
                    753:                        Cbuf_AddText (cmd);
                    754:                }
                    755:                if (keyshift[key] != key)
                    756:                {
                    757:                        kb = keybindings[keyshift[key]];
                    758:                        if (kb && kb[0] == '+')
                    759:                        {
                    760:                                sprintf (cmd, "-%s %i\n", kb+1, key);
                    761:                                Cbuf_AddText (cmd);
                    762:                        }
                    763:                }
                    764:                return;
                    765:        }
                    766: 
                    767: //
                    768: // during demo playback, most keys bring up the main menu
                    769: //
                    770:        if (cls.demoplayback && down && consolekeys[key] && key_dest == key_game)
                    771:        {
                    772:                M_ToggleMenu_f ();
                    773:                return;
                    774:        }
                    775: 
                    776: //
                    777: // if not a consolekey, send to the interpreter no matter what mode is
                    778: //
                    779:        if ( (key_dest == key_menu && menubound[key])
                    780:        || (key_dest == key_console && !consolekeys[key])
                    781:        || (key_dest == key_game && ( cls.state == ca_active || !consolekeys[key] ) ) )
                    782:        {
                    783:                kb = keybindings[key];
                    784:                if (kb)
                    785:                {
                    786:                        if (kb[0] == '+')
                    787:                        {       // button commands add keynum as a parm
                    788:                                sprintf (cmd, "%s %i\n", kb, key);
                    789:                                Cbuf_AddText (cmd);
                    790:                        }
                    791:                        else
                    792:                        {
                    793:                                Cbuf_AddText (kb);
                    794:                                Cbuf_AddText ("\n");
                    795:                        }
                    796:                }
                    797:                return;
                    798:        }
                    799: 
                    800:        if (!down)
                    801:                return;         // other systems only care about key down events
                    802: 
                    803:        if (shift_down)
                    804:                key = keyshift[key];
                    805: 
                    806:        switch (key_dest)
                    807:        {
                    808:        case key_message:
                    809:                Key_Message (key);
                    810:                break;
                    811:        case key_menu:
                    812:                M_Keydown (key);
                    813:                break;
                    814: 
                    815:        case key_game:
                    816:        case key_console:
                    817:                Key_Console (key);
                    818:                break;
                    819:        default:
                    820:                Sys_Error ("Bad key_dest");
                    821:        }
                    822: }
                    823: 
                    824: /*
                    825: ===================
                    826: Key_ClearStates
                    827: ===================
                    828: */
                    829: void Key_ClearStates (void)
                    830: {
                    831:        int             i;
                    832: 
                    833:        for (i=0 ; i<256 ; i++)
                    834:        {
                    835:                keydown[i] = false;
                    836:                key_repeats[i] = false;
                    837:        }
                    838: }
                    839: 

unix.superglobalmegacorp.com

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