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

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

unix.superglobalmegacorp.com

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