Annotation of quake2/client/keys.c, revision 1.1.1.3

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

unix.superglobalmegacorp.com

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