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