Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 944 lines (810 sloc) 17.931 kb
372afde @tbradshaw The original Quake 2 sources as originally released under the GPL licens...
tbradshaw authored
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 */
20 #include "client.h"
21
22 /*
23
24 key up events are sent even if in console mode
25
26 */
27
28
29 #define MAXCMDLINE 256
30 char key_lines[32][MAXCMDLINE];
31 int key_linepos;
32 int shift_down=false;
33 int anykeydown;
34
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];
45
46 typedef struct
47 {
48 char *name;
49 int keynum;
50 } keyname_t;
51
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},
63
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},
80
81 {"INS", K_INS},
82 {"DEL", K_DEL},
83 {"PGDN", K_PGDN},
84 {"PGUP", K_PGUP},
85 {"HOME", K_HOME},
86 {"END", K_END},
87
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},
96
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},
150
151 {"SEMICOLON", ';'}, // because a raw semicolon seperates commands
152
153 {NULL,0}
154 };
155
156 /*
157 ==============================================================================
158
159 LINE TYPING INTO THE CONSOLE
160
161 ==============================================================================
162 */
163
164 void CompleteCommand (void)
165 {
166 char *cmd, *s;
167
168 s = key_lines[edit_line]+1;
169 if (*s == '\\' || *s == '/')
170 s++;
171
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 }
186
187 /*
188 ====================
189 Key_Console
190
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 }
278
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
285
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 }
297
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 }
310
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 }
325
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 }
348
349 if (key == K_PGUP || key == K_KP_PGUP )
350 {
351 con.display -= 2;
352 return;
353 }
354
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 }
362
363 if (key == K_HOME || key == K_KP_HOME )
364 {
365 con.display = con.current - con.totallines + 10;
366 return;
367 }
368
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 }
384
385 }
386
387 //============================================================================
388
389 qboolean chat_team;
390 char chat_buffer[MAXCMDLINE];
391 int chat_bufferlen = 0;
392
393 void Key_Message (int key)
394 {
395
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");
404
405 cls.key_dest = key_game;
406 chat_bufferlen = 0;
407 chat_buffer[0] = 0;
408 return;
409 }
410
411 if (key == K_ESCAPE)
412 {
413 cls.key_dest = key_game;
414 chat_bufferlen = 0;
415 chat_buffer[0] = 0;
416 return;
417 }
418
419 if (key < 32 || key > 127)
420 return; // non printable
421
422 if (key == K_BACKSPACE)
423 {
424 if (chat_bufferlen)
425 {
426 chat_bufferlen--;
427 chat_buffer[chat_bufferlen] = 0;
428 }
429 return;
430 }
431
432 if (chat_bufferlen == sizeof(chat_buffer)-1)
433 return; // all full
434
435 chat_buffer[chat_bufferlen++] = key;
436 chat_buffer[chat_bufferlen] = 0;
437 }
438
439 //============================================================================
440
441
442 /*
443 ===================
444 Key_StringToKeynum
445
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];
459
460 for (kn=keynames ; kn->name ; kn++)
461 {
462 if (!Q_strcasecmp(str,kn->name))
463 return kn->keynum;
464 }
465 return -1;
466 }
467
468 /*
469 ===================
470 Key_KeynumToString
471
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;
494
495 return "<UNKNOWN KEYNUM>";
496 }
497
498
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;
511
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 }
526
527 /*
528 ===================
529 Key_Unbind_f
530 ===================
531 */
532 void Key_Unbind_f (void)
533 {
534 int b;
535
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 }
548
549 Key_SetBinding (b, "");
550 }
551
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 }
560
561
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();
573
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 }
585
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 }
603
604 Key_SetBinding (b, cmd);
605 }
606
607 /*
608 ============
609 Key_WriteBindings
610
611 Writes lines containing "bind key value"
612 ============
613 */
614 void Key_WriteBindings (FILE *f)
615 {
616 int i;
617
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 }
622
623
624 /*
625 ============
626 Key_Bindlist_f
627
628 ============
629 */
630 void Key_Bindlist_f (void)
631 {
632 int i;
633
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 }
638
639
640 /*
641 ===================
642 Key_Init
643 ===================
644 */
645 void Key_Init (void)
646 {
647 int i;
648
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;
692
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['\\'] = '|';
718
719 menubound[K_ESCAPE] = true;
720 for (i=0 ; i<12 ; i++)
721 menubound[K_F1+i] = true;
722
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 }
731
732 /*
733 ===================
734 Key_Event
735
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 }
752
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 }
773
774 if (key == K_SHIFT)
775 shift_down = down;
776
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 }
785
786 // any key during the attract mode will bring up the menu
787 if (cl.attractloop && cls.key_dest != key_menu)
788 key = K_ESCAPE;
789
790 // menu key is hardcoded, so the user can never unbind it
791 if (key == K_ESCAPE)
792 {
793 if (!down)
794 return;
795
796 if (cl.frame.playerstate.stats[STAT_LAYOUTS] && cls.key_dest == key_game)
797 { // put away help computer / inventory
798 Cbuf_AddText ("cmd putaway\n");
799 return;
800 }
801 switch (cls.key_dest)
802 {
803 case key_message:
804 Key_Message (key);
805 break;
806 case key_menu:
807 M_Keydown (key);
808 break;
809 case key_game:
810 case key_console:
811 M_Menu_Main_f ();
812 break;
813 default:
814 Com_Error (ERR_FATAL, "Bad cls.key_dest");
815 }
816 return;
817 }
818
819 // track if any key is down for BUTTON_ANY
820 keydown[key] = down;
821 if (down)
822 {
823 if (key_repeats[key] == 1)
824 anykeydown++;
825 }
826 else
827 {
828 anykeydown--;
829 if (anykeydown < 0)
830 anykeydown = 0;
831 }
832
833 //
834 // key up events only generate commands if the game key binding is
835 // a button command (leading + sign). These will occur even in console mode,
836 // to keep the character from continuing an action started before a console
837 // switch. Button commands include the kenum as a parameter, so multiple
838 // downs can be matched with ups
839 //
840 if (!down)
841 {
842 kb = keybindings[key];
843 if (kb && kb[0] == '+')
844 {
845 Com_sprintf (cmd, sizeof(cmd), "-%s %i %i\n", kb+1, key, time);
846 Cbuf_AddText (cmd);
847 }
848 if (keyshift[key] != key)
849 {
850 kb = keybindings[keyshift[key]];
851 if (kb && kb[0] == '+')
852 {
853 Com_sprintf (cmd, sizeof(cmd), "-%s %i %i\n", kb+1, key, time);
854 Cbuf_AddText (cmd);
855 }
856 }
857 return;
858 }
859
860 //
861 // if not a consolekey, send to the interpreter no matter what mode is
862 //
863 if ( (cls.key_dest == key_menu && menubound[key])
864 || (cls.key_dest == key_console && !consolekeys[key])
865 || (cls.key_dest == key_game && ( cls.state == ca_active || !consolekeys[key] ) ) )
866 {
867 kb = keybindings[key];
868 if (kb)
869 {
870 if (kb[0] == '+')
871 { // button commands add keynum and time as a parm
872 Com_sprintf (cmd, sizeof(cmd), "%s %i %i\n", kb, key, time);
873 Cbuf_AddText (cmd);
874 }
875 else
876 {
877 Cbuf_AddText (kb);
878 Cbuf_AddText ("\n");
879 }
880 }
881 return;
882 }
883
884 if (!down)
885 return; // other systems only care about key down events
886
887 if (shift_down)
888 key = keyshift[key];
889
890 switch (cls.key_dest)
891 {
892 case key_message:
893 Key_Message (key);
894 break;
895 case key_menu:
896 M_Keydown (key);
897 break;
898
899 case key_game:
900 case key_console:
901 Key_Console (key);
902 break;
903 default:
904 Com_Error (ERR_FATAL, "Bad cls.key_dest");
905 }
906 }
907
908 /*
909 ===================
910 Key_ClearStates
911 ===================
912 */
913 void Key_ClearStates (void)
914 {
915 int i;
916
917 anykeydown = false;
918
919 for (i=0 ; i<256 ; i++)
920 {
921 if ( keydown[i] || key_repeats[i] )
922 Key_Event( i, false, 0 );
923 keydown[i] = 0;
924 key_repeats[i] = 0;
925 }
926 }
927
928
929 /*
930 ===================
931 Key_GetKey
932 ===================
933 */
934 int Key_GetKey (void)
935 {
936 key_waiting = -1;
937
938 while (key_waiting == -1)
939 Sys_SendKeyEvents ();
940
941 return key_waiting;
942 }
943
Something went wrong with that request. Please try again.