|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.