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