doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
KeyInput.cpp
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 #include "../idlib/precompiled.h"
30 #pragma hdrstop
31 
32 typedef struct {
33  char *name;
34  int keynum;
35  char *strId; // localized string id
36 } keyname_t;
37 
38 // keys that can be set without a special name
39 static const char unnamedkeys[] = "*,-=./[\\]1234567890abcdefghijklmnopqrstuvwxyz";
40 
41 #if MACOS_X
42 const char* OSX_GetLocalizedString( const char* );
43 #endif
44 
45 // names not in this list can either be lowercase ascii, or '0xnn' hex sequences
47 {
48  {"TAB", K_TAB, "#str_07018"},
49  {"ENTER", K_ENTER, "#str_07019"},
50  {"ESCAPE", K_ESCAPE, "#str_07020"},
51  {"SPACE", K_SPACE, "#str_07021"},
52  {"BACKSPACE", K_BACKSPACE, "#str_07022"},
53  {"UPARROW", K_UPARROW, "#str_07023"},
54  {"DOWNARROW", K_DOWNARROW, "#str_07024"},
55  {"LEFTARROW", K_LEFTARROW, "#str_07025"},
56  {"RIGHTARROW", K_RIGHTARROW, "#str_07026"},
57 
58  {"ALT", K_ALT, "#str_07027"},
59  {"RIGHTALT", K_RIGHT_ALT, "#str_07027"},
60  {"CTRL", K_CTRL, "#str_07028"},
61  {"SHIFT", K_SHIFT, "#str_07029"},
62 
63  {"LWIN", K_LWIN, "#str_07030"},
64  {"RWIN", K_RWIN, "#str_07031"},
65  {"MENU", K_MENU, "#str_07032"},
66 
67  {"COMMAND", K_COMMAND, "#str_07033"},
68 
69  {"CAPSLOCK", K_CAPSLOCK, "#str_07034"},
70  {"SCROLL", K_SCROLL, "#str_07035"},
71  {"PRINTSCREEN", K_PRINT_SCR, "#str_07179"},
72 
73  {"F1", K_F1, "#str_07036"},
74  {"F2", K_F2, "#str_07037"},
75  {"F3", K_F3, "#str_07038"},
76  {"F4", K_F4, "#str_07039"},
77  {"F5", K_F5, "#str_07040"},
78  {"F6", K_F6, "#str_07041"},
79  {"F7", K_F7, "#str_07042"},
80  {"F8", K_F8, "#str_07043"},
81  {"F9", K_F9, "#str_07044"},
82  {"F10", K_F10, "#str_07045"},
83  {"F11", K_F11, "#str_07046"},
84  {"F12", K_F12, "#str_07047"},
85 
86  {"INS", K_INS, "#str_07048"},
87  {"DEL", K_DEL, "#str_07049"},
88  {"PGDN", K_PGDN, "#str_07050"},
89  {"PGUP", K_PGUP, "#str_07051"},
90  {"HOME", K_HOME, "#str_07052"},
91  {"END", K_END, "#str_07053"},
92 
93  {"MOUSE1", K_MOUSE1, "#str_07054"},
94  {"MOUSE2", K_MOUSE2, "#str_07055"},
95  {"MOUSE3", K_MOUSE3, "#str_07056"},
96  {"MOUSE4", K_MOUSE4, "#str_07057"},
97  {"MOUSE5", K_MOUSE5, "#str_07058"},
98  {"MOUSE6", K_MOUSE6, "#str_07059"},
99  {"MOUSE7", K_MOUSE7, "#str_07060"},
100  {"MOUSE8", K_MOUSE8, "#str_07061"},
101 
102  {"MWHEELUP", K_MWHEELUP, "#str_07131"},
103  {"MWHEELDOWN", K_MWHEELDOWN, "#str_07132"},
104 
105  {"JOY1", K_JOY1, "#str_07062"},
106  {"JOY2", K_JOY2, "#str_07063"},
107  {"JOY3", K_JOY3, "#str_07064"},
108  {"JOY4", K_JOY4, "#str_07065"},
109  {"JOY5", K_JOY5, "#str_07066"},
110  {"JOY6", K_JOY6, "#str_07067"},
111  {"JOY7", K_JOY7, "#str_07068"},
112  {"JOY8", K_JOY8, "#str_07069"},
113  {"JOY9", K_JOY9, "#str_07070"},
114  {"JOY10", K_JOY10, "#str_07071"},
115  {"JOY11", K_JOY11, "#str_07072"},
116  {"JOY12", K_JOY12, "#str_07073"},
117  {"JOY13", K_JOY13, "#str_07074"},
118  {"JOY14", K_JOY14, "#str_07075"},
119  {"JOY15", K_JOY15, "#str_07076"},
120  {"JOY16", K_JOY16, "#str_07077"},
121  {"JOY17", K_JOY17, "#str_07078"},
122  {"JOY18", K_JOY18, "#str_07079"},
123  {"JOY19", K_JOY19, "#str_07080"},
124  {"JOY20", K_JOY20, "#str_07081"},
125  {"JOY21", K_JOY21, "#str_07082"},
126  {"JOY22", K_JOY22, "#str_07083"},
127  {"JOY23", K_JOY23, "#str_07084"},
128  {"JOY24", K_JOY24, "#str_07085"},
129  {"JOY25", K_JOY25, "#str_07086"},
130  {"JOY26", K_JOY26, "#str_07087"},
131  {"JOY27", K_JOY27, "#str_07088"},
132  {"JOY28", K_JOY28, "#str_07089"},
133  {"JOY29", K_JOY29, "#str_07090"},
134  {"JOY30", K_JOY30, "#str_07091"},
135  {"JOY31", K_JOY31, "#str_07092"},
136  {"JOY32", K_JOY32, "#str_07093"},
137 
138  {"AUX1", K_AUX1, "#str_07094"},
139  {"AUX2", K_AUX2, "#str_07095"},
140  {"AUX3", K_AUX3, "#str_07096"},
141  {"AUX4", K_AUX4, "#str_07097"},
142  {"AUX5", K_AUX5, "#str_07098"},
143  {"AUX6", K_AUX6, "#str_07099"},
144  {"AUX7", K_AUX7, "#str_07100"},
145  {"AUX8", K_AUX8, "#str_07101"},
146  {"AUX9", K_AUX9, "#str_07102"},
147  {"AUX10", K_AUX10, "#str_07103"},
148  {"AUX11", K_AUX11, "#str_07104"},
149  {"AUX12", K_AUX12, "#str_07105"},
150  {"AUX13", K_AUX13, "#str_07106"},
151  {"AUX14", K_AUX14, "#str_07107"},
152  {"AUX15", K_AUX15, "#str_07108"},
153  {"AUX16", K_AUX16, "#str_07109"},
154 
155  {"KP_HOME", K_KP_HOME, "#str_07110"},
156  {"KP_UPARROW", K_KP_UPARROW, "#str_07111"},
157  {"KP_PGUP", K_KP_PGUP, "#str_07112"},
158  {"KP_LEFTARROW", K_KP_LEFTARROW, "#str_07113"},
159  {"KP_5", K_KP_5, "#str_07114"},
160  {"KP_RIGHTARROW", K_KP_RIGHTARROW, "#str_07115"},
161  {"KP_END", K_KP_END, "#str_07116"},
162  {"KP_DOWNARROW", K_KP_DOWNARROW, "#str_07117"},
163  {"KP_PGDN", K_KP_PGDN, "#str_07118"},
164  {"KP_ENTER", K_KP_ENTER, "#str_07119"},
165  {"KP_INS", K_KP_INS, "#str_07120"},
166  {"KP_DEL", K_KP_DEL, "#str_07121"},
167  {"KP_SLASH", K_KP_SLASH, "#str_07122"},
168  {"KP_MINUS", K_KP_MINUS, "#str_07123"},
169  {"KP_PLUS", K_KP_PLUS, "#str_07124"},
170  {"KP_NUMLOCK", K_KP_NUMLOCK, "#str_07125"},
171  {"KP_STAR", K_KP_STAR, "#str_07126"},
172  {"KP_EQUALS", K_KP_EQUALS, "#str_07127"},
173 
174  {"PAUSE", K_PAUSE, "#str_07128"},
175 
176  {"SEMICOLON", ';', "#str_07129"}, // because a raw semicolon separates commands
177  {"APOSTROPHE", '\'', "#str_07130"}, // because a raw apostrophe messes with parsing
178 
179  {NULL, 0, NULL}
180 };
181 
182 
183 
184 static const int MAX_KEYS = 256;
185 
186 class idKey {
187 public:
188  idKey( void ) { down = false; repeats = 0; usercmdAction = 0; }
189  bool down;
190  int repeats; // if > 1, it is autorepeating
192  int usercmdAction; // for testing by the asyncronous usercmd generation
193 };
194 
195 bool key_overstrikeMode = false;
197 
198 #define ID_DOOM_LEGACY
199 
200 #ifdef ID_DOOM_LEGACY
201 
202 char * cheatCodes[] = {
203  "iddqd", // Invincibility
204  "idkfa", // All weapons, keys, ammo, and 200% armor
205  "idfa", // Reset ammunition
206  "idspispopd", // Walk through walls
207  "idclip", // Walk through walls
208  "idchoppers", // Chainsaw
209 /*
210  "idbeholds", // Berserker strength
211  "idbeholdv", // Temporary invincibility
212  "idbeholdi", // Temporary invisibility
213  "idbeholda", // Full automap
214  "idbeholdr", // Anti-radiation suit
215  "idbeholdl", // Light amplification visor
216  "idclev", // Level select
217  "iddt", // Toggle full map; full map and objects; normal map
218  "idmypos", // Display coordinates and heading
219  "idmus", // Change music to indicated level
220  "fhhall", // Kill all enemies in level
221  "fhshh", // Invisible to enemies until attack
222 */
223  NULL
224 };
225 char lastKeys[32];
227 
228 #endif
229 
230 /*
231 ===================
232 idKeyInput::ArgCompletion_KeyName
233 ===================
234 */
235 void idKeyInput::ArgCompletion_KeyName( const idCmdArgs &args, void(*callback)( const char *s ) ) {
236  keyname_t *kn;
237  int i;
238 
239  for( i = 0; i < sizeof( unnamedkeys ) - 1; i++ ) {
240  callback( va( "%s %c", args.Argv( 0 ), unnamedkeys[ i ] ) );
241  }
242 
243  for ( kn = keynames; kn->name; kn++ ) {
244  callback( va( "%s %s", args.Argv( 0 ), kn->name ) );
245  }
246 }
247 
248 /*
249 ===================
250 idKeyInput::GetOverstrikeMode
251 ===================
252 */
254  return key_overstrikeMode;
255 }
256 
257 /*
258 ===================
259 idKeyInput::SetOverstrikeMode
260 ===================
261 */
262 void idKeyInput::SetOverstrikeMode( bool state ) {
263  key_overstrikeMode = state;
264 }
265 
266 /*
267 ===================
268 idKeyInput::IsDown
269 ===================
270 */
271 bool idKeyInput::IsDown( int keynum ) {
272  if ( keynum == -1 ) {
273  return false;
274  }
275 
276  return keys[keynum].down;
277 }
278 
279 /*
280 ===================
281 idKeyInput::StringToKeyNum
282 
283 Returns a key number to be used to index keys[] by looking at
284 the given string. Single ascii characters return themselves, while
285 the K_* names are matched up.
286 
287 0x11 will be interpreted as raw hex, which will allow new controlers
288 to be configured even if they don't have defined names.
289 ===================
290 */
291 int idKeyInput::StringToKeyNum( const char *str ) {
292  keyname_t *kn;
293 
294  if ( !str || !str[0] ) {
295  return -1;
296  }
297  if ( !str[1] ) {
298  return (unsigned char)(str[0]);
299  }
300 
301  // check for hex code
302  if ( str[0] == '0' && str[1] == 'x' && strlen( str ) == 4 ) {
303  int n1, n2;
304 
305  n1 = str[2];
306  if ( n1 >= '0' && n1 <= '9' ) {
307  n1 -= '0';
308  } else if ( n1 >= 'a' && n1 <= 'f' ) {
309  n1 = n1 - 'a' + 10;
310  } else {
311  n1 = 0;
312  }
313 
314  n2 = str[3];
315  if ( n2 >= '0' && n2 <= '9' ) {
316  n2 -= '0';
317  } else if ( n2 >= 'a' && n2 <= 'f' ) {
318  n2 = n2 - 'a' + 10;
319  } else {
320  n2 = 0;
321  }
322 
323  return n1 * 16 + n2;
324  }
325 
326  // scan for a text match
327  for ( kn = keynames; kn->name; kn++ ) {
328  if ( !idStr::Icmp( str, kn->name ) ) {
329  return kn->keynum;
330  }
331  }
332 
333  return -1;
334 }
335 
336 /*
337 ===================
338 idKeyInput::KeyNumToString
339 
340 Returns a string (either a single ascii char, a K_* name, or a 0x11 hex string) for the
341 given keynum.
342 ===================
343 */
344 const char *idKeyInput::KeyNumToString( int keynum, bool localized ) {
345  keyname_t *kn;
346  static char tinystr[5];
347  int i, j;
348 
349  if ( keynum == -1 ) {
350  return "<KEY NOT FOUND>";
351  }
352 
353  if ( keynum < 0 || keynum > 255 ) {
354  return "<OUT OF RANGE>";
355  }
356 
357  // check for printable ascii (don't use quote)
358  if ( keynum > 32 && keynum < 127 && keynum != '"' && keynum != ';' && keynum != '\'' ) {
359  tinystr[0] = Sys_MapCharForKey( keynum );
360  tinystr[1] = 0;
361  return tinystr;
362  }
363 
364  // check for a key string
365  for ( kn = keynames; kn->name; kn++ ) {
366  if ( keynum == kn->keynum ) {
367  if ( !localized || kn->strId[0] != '#' ) {
368  return kn->name;
369  } else {
370 #if MACOS_X
371 
372  switch ( kn->keynum ) {
373  case K_ENTER:
374  case K_BACKSPACE:
375  case K_ALT:
376  case K_INS:
377  case K_PRINT_SCR:
378  return OSX_GetLocalizedString( kn->name );
379  break;
380  default :
381  return common->GetLanguageDict()->GetString( kn->strId ); break;
382  }
383 #else
384  return common->GetLanguageDict()->GetString( kn->strId );
385 #endif
386  }
387  }
388  }
389 
390  // check for European high-ASCII characters
391  if ( localized && keynum >= 161 && keynum <= 255 ) {
392  tinystr[0] = keynum;
393  tinystr[1] = 0;
394  return tinystr;
395  }
396 
397  // make a hex string
398  i = keynum >> 4;
399  j = keynum & 15;
400 
401  tinystr[0] = '0';
402  tinystr[1] = 'x';
403  tinystr[2] = i > 9 ? i - 10 + 'a' : i + '0';
404  tinystr[3] = j > 9 ? j - 10 + 'a' : j + '0';
405  tinystr[4] = 0;
406 
407  return tinystr;
408 }
409 
410 /*
411 ===================
412 idKeyInput::SetBinding
413 ===================
414 */
415 void idKeyInput::SetBinding( int keynum, const char *binding ) {
416  if ( keynum == -1 ) {
417  return;
418  }
419 
420  // Clear out all button states so we aren't stuck forever thinking this key is held down
421  usercmdGen->Clear();
422 
423  // allocate memory for new binding
424  keys[keynum].binding = binding;
425 
426  // find the action for the async command generation
427  keys[keynum].usercmdAction = usercmdGen->CommandStringUsercmdData( binding );
428 
429  // consider this like modifying an archived cvar, so the
430  // file write will be triggered at the next oportunity
432 }
433 
434 
435 /*
436 ===================
437 idKeyInput::GetBinding
438 ===================
439 */
440 const char *idKeyInput::GetBinding( int keynum ) {
441  if ( keynum == -1 ) {
442  return "";
443  }
444 
445  return keys[ keynum ].binding;
446 }
447 
448 /*
449 ===================
450 idKeyInput::GetUsercmdAction
451 ===================
452 */
453 int idKeyInput::GetUsercmdAction( int keynum ) {
454  return keys[ keynum ].usercmdAction;
455 }
456 
457 /*
458 ===================
459 Key_Unbind_f
460 ===================
461 */
462 void Key_Unbind_f( const idCmdArgs &args ) {
463  int b;
464 
465  if ( args.Argc() != 2 ) {
466  common->Printf( "unbind <key> : remove commands from a key\n" );
467  return;
468  }
469 
470  b = idKeyInput::StringToKeyNum( args.Argv(1) );
471  if ( b == -1 ) {
472  // If it wasn't a key, it could be a command
473  if ( !idKeyInput::UnbindBinding( args.Argv(1) ) ) {
474  common->Printf( "\"%s\" isn't a valid key\n", args.Argv(1) );
475  }
476  } else {
477  idKeyInput::SetBinding( b, "" );
478  }
479 }
480 
481 /*
482 ===================
483 Key_Unbindall_f
484 ===================
485 */
486 void Key_Unbindall_f( const idCmdArgs &args ) {
487  int i;
488 
489  for ( i = 0; i < MAX_KEYS; i++ ) {
490  idKeyInput::SetBinding( i, "" );
491  }
492 }
493 
494 /*
495 ===================
496 Key_Bind_f
497 ===================
498 */
499 void Key_Bind_f( const idCmdArgs &args ) {
500  int i, c, b;
501  char cmd[MAX_STRING_CHARS];
502 
503  c = args.Argc();
504 
505  if ( c < 2 ) {
506  common->Printf( "bind <key> [command] : attach a command to a key\n" );
507  return;
508  }
509  b = idKeyInput::StringToKeyNum( args.Argv(1) );
510  if ( b == -1 ) {
511  common->Printf( "\"%s\" isn't a valid key\n", args.Argv(1) );
512  return;
513  }
514 
515  if ( c == 2 ) {
516  if ( keys[b].binding.Length() ) {
517  common->Printf( "\"%s\" = \"%s\"\n", args.Argv(1), keys[b].binding.c_str() );
518  }
519  else {
520  common->Printf( "\"%s\" is not bound\n", args.Argv(1) );
521  }
522  return;
523  }
524 
525  // copy the rest of the command line
526  cmd[0] = 0; // start out with a null string
527  for ( i = 2; i < c; i++ ) {
528  strcat( cmd, args.Argv( i ) );
529  if ( i != (c-1) ) {
530  strcat( cmd, " " );
531  }
532  }
533 
534  idKeyInput::SetBinding( b, cmd );
535 }
536 
537 /*
538 ============
539 Key_BindUnBindTwo_f
540 
541 binds keynum to bindcommand and unbinds if there are already two binds on the key
542 ============
543 */
544 void Key_BindUnBindTwo_f( const idCmdArgs &args ) {
545  int c = args.Argc();
546  if ( c < 3 ) {
547  common->Printf( "bindunbindtwo <keynum> [command]\n" );
548  return;
549  }
550  int key = atoi( args.Argv( 1 ) );
551  idStr bind = args.Argv( 2 );
552  if ( idKeyInput::NumBinds( bind ) >= 2 && !idKeyInput::KeyIsBoundTo( key, bind ) ) {
554  }
555  idKeyInput::SetBinding( key, bind );
556 }
557 
558 
559 
560 /*
561 ============
562 idKeyInput::WriteBindings
563 
564 Writes lines containing "bind key value"
565 ============
566 */
568  int i;
569 
570  f->Printf( "unbindall\n" );
571 
572  for ( i = 0; i < MAX_KEYS; i++ ) {
573  if ( keys[i].binding.Length() ) {
574  const char *name = KeyNumToString( i, false );
575 
576  // handle the escape character nicely
577  if ( !strcmp( name, "\\" ) ) {
578  f->Printf( "bind \"\\\" \"%s\"\n", keys[i].binding.c_str() );
579  } else {
580  f->Printf( "bind \"%s\" \"%s\"\n", KeyNumToString( i, false ), keys[i].binding.c_str() );
581  }
582  }
583  }
584 }
585 
586 /*
587 ============
588 Key_ListBinds_f
589 ============
590 */
591 void Key_ListBinds_f( const idCmdArgs &args ) {
592  int i;
593 
594  for ( i = 0; i < MAX_KEYS; i++ ) {
595  if ( keys[i].binding.Length() ) {
596  common->Printf( "%s \"%s\"\n", idKeyInput::KeyNumToString( i, false ), keys[i].binding.c_str() );
597  }
598  }
599 }
600 
601 /*
602 ============
603 idKeyInput::KeysFromBinding
604 returns the localized name of the key for the binding
605 ============
606 */
607 const char *idKeyInput::KeysFromBinding( const char *bind ) {
608  int i;
609  static char keyName[MAX_STRING_CHARS];
610 
611  keyName[0] = '\0';
612  if ( bind && *bind ) {
613  for ( i = 0; i < MAX_KEYS; i++ ) {
614  if ( keys[i].binding.Icmp( bind ) == 0 ) {
615  if ( keyName[0] != '\0' ) {
616  idStr::Append( keyName, sizeof( keyName ), common->GetLanguageDict()->GetString( "#str_07183" ) );
617  }
618  idStr::Append( keyName, sizeof( keyName ), KeyNumToString( i, true ) );
619  }
620  }
621  }
622  if ( keyName[0] == '\0' ) {
623  idStr::Copynz( keyName, common->GetLanguageDict()->GetString( "#str_07133" ), sizeof( keyName ) );
624  }
625  idStr::ToLower( keyName );
626  return keyName;
627 }
628 
629 /*
630 ============
631 idKeyInput::BindingFromKey
632 returns the binding for the localized name of the key
633 ============
634 */
635 const char *idKeyInput::BindingFromKey( const char *key ) {
636  const int keyNum = idKeyInput::StringToKeyNum( key );
637  if ( keyNum<0 || keyNum >= MAX_KEYS ) {
638  return NULL;
639  }
640  return keys[keyNum].binding.c_str();
641 }
642 
643 /*
644 ============
645 idKeyInput::UnbindBinding
646 ============
647 */
648 bool idKeyInput::UnbindBinding( const char *binding ) {
649  bool unbound = false;
650  int i;
651 
652  if ( binding && *binding ) {
653  for ( i = 0; i < MAX_KEYS; i++ ) {
654  if ( keys[i].binding.Icmp( binding ) == 0 ) {
655  SetBinding( i, "" );
656  unbound = true;
657  }
658  }
659  }
660  return unbound;
661 }
662 
663 /*
664 ============
665 idKeyInput::NumBinds
666 ============
667 */
668 int idKeyInput::NumBinds( const char *binding ) {
669  int i, count = 0;
670 
671  if ( binding && *binding ) {
672  for ( i = 0; i < MAX_KEYS; i++ ) {
673  if ( keys[i].binding.Icmp( binding ) == 0 ) {
674  count++;
675  }
676  }
677  }
678  return count;
679 }
680 
681 /*
682 ============
683 idKeyInput::KeyIsBountTo
684 ============
685 */
686 bool idKeyInput::KeyIsBoundTo( int keynum, const char *binding ) {
687  if ( keynum >= 0 && keynum < MAX_KEYS ) {
688  return ( keys[keynum].binding.Icmp( binding ) == 0 );
689  }
690  return false;
691 }
692 
693 /*
694 ===================
695 idKeyInput::PreliminaryKeyEvent
696 
697 Tracks global key up/down state
698 Called by the system for both key up and key down events
699 ===================
700 */
701 void idKeyInput::PreliminaryKeyEvent( int keynum, bool down ) {
702  keys[keynum].down = down;
703 
704 #ifdef ID_DOOM_LEGACY
705  if ( down ) {
706  lastKeys[ 0 + ( lastKeyIndex & 15 )] = keynum;
707  lastKeys[16 + ( lastKeyIndex & 15 )] = keynum;
708  lastKeyIndex = ( lastKeyIndex + 1 ) & 15;
709  for ( int i = 0; cheatCodes[i] != NULL; i++ ) {
710  int l = strlen( cheatCodes[i] );
711  assert( l <= 16 );
712  if ( idStr::Icmpn( lastKeys + 16 + ( lastKeyIndex & 15 ) - l, cheatCodes[i], l ) == 0 ) {
713  common->Printf( "your memory serves you well!\n" );
714  break;
715  }
716  }
717  }
718 #endif
719 }
720 
721 /*
722 =================
723 idKeyInput::ExecKeyBinding
724 =================
725 */
726 bool idKeyInput::ExecKeyBinding( int keynum ) {
727  // commands that are used by the async thread
728  // don't add text
729  if ( keys[keynum].usercmdAction ) {
730  return false;
731  }
732 
733  // send the bound action
734  if ( keys[keynum].binding.Length() ) {
735  cmdSystem->BufferCommandText( CMD_EXEC_APPEND, keys[keynum].binding.c_str() );
737  }
738  return true;
739 }
740 
741 /*
742 ===================
743 idKeyInput::ClearStates
744 ===================
745 */
747  int i;
748 
749  for ( i = 0; i < MAX_KEYS; i++ ) {
750  if ( keys[i].down ) {
751  PreliminaryKeyEvent( i, false );
752  }
753  keys[i].down = false;
754  }
755 
756  // clear the usercommand states
757  usercmdGen->Clear();
758 }
759 
760 /*
761 ===================
762 idKeyInput::Init
763 ===================
764 */
765 void idKeyInput::Init( void ) {
766 
767  keys = new idKey[MAX_KEYS];
768 
769  // register our functions
770  cmdSystem->AddCommand( "bind", Key_Bind_f, CMD_FL_SYSTEM, "binds a command to a key", idKeyInput::ArgCompletion_KeyName );
771  cmdSystem->AddCommand( "bindunbindtwo", Key_BindUnBindTwo_f, CMD_FL_SYSTEM, "binds a key but unbinds it first if there are more than two binds" );
772  cmdSystem->AddCommand( "unbind", Key_Unbind_f, CMD_FL_SYSTEM, "unbinds any command from a key", idKeyInput::ArgCompletion_KeyName );
773  cmdSystem->AddCommand( "unbindall", Key_Unbindall_f, CMD_FL_SYSTEM, "unbinds any commands from all keys" );
774  cmdSystem->AddCommand( "listBinds", Key_ListBinds_f, CMD_FL_SYSTEM, "lists key bindings" );
775 }
776 
777 /*
778 ===================
779 idKeyInput::Shutdown
780 ===================
781 */
782 void idKeyInput::Shutdown( void ) {
783  delete [] keys;
784  keys = NULL;
785 }
static bool IsDown(int keyNum)
Definition: KeyInput.cpp:271
static int GetUsercmdAction(int keyNum)
Definition: KeyInput.cpp:453
#define MAX_KEYS
static bool UnbindBinding(const char *bind)
Definition: KeyInput.cpp:648
Definition: KeyInput.h:78
static void Shutdown(void)
Definition: KeyInput.cpp:782
#define strcmp
Definition: Str.h:41
const char * OSX_GetLocalizedString(const char *key)
Definition: macosx_misc.mm:74
Definition: KeyInput.h:83
int repeats
Definition: KeyInput.cpp:190
Definition: KeyInput.h:82
assert(prefInfo.fullscreenBtn)
idCVarSystem * cvarSystem
Definition: CVarSystem.cpp:487
Definition: KeyInput.h:88
static int StringToKeyNum(const char *str)
Definition: KeyInput.cpp:291
void Key_ListBinds_f(const idCmdArgs &args)
Definition: KeyInput.cpp:591
void ToLower(void)
Definition: Str.h:817
virtual void virtual void virtual const idLangDict * GetLanguageDict(void)=0
Definition: KeyInput.h:86
int lastKeyIndex
Definition: KeyInput.cpp:226
Definition: KeyInput.h:74
static void WriteBindings(idFile *f)
Definition: KeyInput.cpp:567
virtual void Clear(void)=0
virtual void SetModifiedFlags(int flags)=0
void Key_Unbindall_f(const idCmdArgs &args)
Definition: KeyInput.cpp:486
static void ClearStates(void)
Definition: KeyInput.cpp:746
Definition: KeyInput.h:85
prefInfo callback
idStr binding
Definition: KeyInput.cpp:191
Definition: KeyInput.h:81
virtual int CommandStringUsercmdData(const char *cmdString)=0
idCmdSystem * cmdSystem
Definition: CmdSystem.cpp:116
GLdouble s
Definition: glext.h:2935
int i
Definition: process.py:33
Definition: KeyInput.h:91
int Icmp(const char *text) const
Definition: Str.h:667
list l
Definition: prepare.py:17
int Icmpn(const char *text, int n) const
Definition: Str.h:672
Definition: File.h:50
virtual void BufferCommandText(cmdExecution_t exec, const char *text)=0
Definition: KeyInput.h:90
char * name
Definition: KeyInput.cpp:33
GLuint GLuint GLsizei count
Definition: glext.h:2845
Definition: KeyInput.h:80
Definition: KeyInput.h:73
const GLubyte * c
Definition: glext.h:4677
void Key_BindUnBindTwo_f(const idCmdArgs &args)
Definition: KeyInput.cpp:544
#define MAX_STRING_CHARS
Definition: Lib.h:95
static int NumBinds(const char *binding)
Definition: KeyInput.cpp:668
static bool GetOverstrikeMode(void)
Definition: KeyInput.cpp:253
idCommon * common
Definition: Common.cpp:206
#define NULL
Definition: Lib.h:88
static const char * BindingFromKey(const char *key)
Definition: KeyInput.cpp:635
static void Copynz(char *dest, const char *src, int destsize)
Definition: Str.cpp:1376
const char * GetString(const char *str) const
Definition: LangDict.cpp:148
Definition: KeyInput.h:47
Definition: KeyInput.h:84
static void Init(void)
Definition: KeyInput.cpp:765
int Argc(void) const
Definition: CmdArgs.h:48
idUsercmdGen * usercmdGen
Definition: UsercmdGen.cpp:419
bool down
Definition: KeyInput.cpp:189
virtual void Printf(const char *fmt,...) id_attribute((format(printf
Definition: KeyInput.h:87
static const char * KeyNumToString(int keyNum, bool localized)
Definition: KeyInput.cpp:344
keyname_t keynames[]
Definition: KeyInput.cpp:46
static bool ExecKeyBinding(int keyNum)
Definition: KeyInput.cpp:726
char lastKeys[32]
Definition: KeyInput.cpp:225
static const char * KeysFromBinding(const char *bind)
Definition: KeyInput.cpp:607
GLubyte GLubyte b
Definition: glext.h:4662
static bool KeyIsBoundTo(int keyNum, const char *binding)
Definition: KeyInput.cpp:686
tuple f
Definition: idal.py:89
void Append(const char a)
Definition: Str.h:729
Definition: KeyInput.h:70
char * cheatCodes[]
Definition: KeyInput.cpp:202
const GLcharARB * name
Definition: glext.h:3629
static void ArgCompletion_KeyName(const idCmdArgs &args, void(*callback)(const char *s))
Definition: KeyInput.cpp:235
idKey * keys
Definition: KeyInput.cpp:196
Definition: Str.h:116
char * strId
Definition: KeyInput.cpp:35
const char * c_str(void) const
Definition: Str.h:487
void Key_Bind_f(const idCmdArgs &args)
Definition: KeyInput.cpp:499
static void SetBinding(int keyNum, const char *binding)
Definition: KeyInput.cpp:415
const char * Argv(int arg) const
Definition: CmdArgs.h:50
GLint j
Definition: qgl.h:264
int usercmdAction
Definition: KeyInput.cpp:192
bool key_overstrikeMode
Definition: KeyInput.cpp:195
char * va(const char *fmt,...)
Definition: Str.cpp:1568
void Key_Unbind_f(const idCmdArgs &args)
Definition: KeyInput.cpp:462
unsigned char Sys_MapCharForKey(int key)
Definition: dedicated.cpp:57
static void SetOverstrikeMode(bool state)
Definition: KeyInput.cpp:262
Definition: KeyInput.h:89
idKey(void)
Definition: KeyInput.cpp:188
virtual int Printf(const char *fmt,...) id_attribute((format(printf
Definition: File.cpp:260
virtual void AddCommand(const char *cmdName, cmdFunction_t function, int flags, const char *description, argCompletion_t argCompletion=NULL)=0
int keynum
Definition: KeyInput.cpp:34
static const char * GetBinding(int keyNum)
Definition: KeyInput.cpp:440
static void PreliminaryKeyEvent(int keyNum, bool down)
Definition: KeyInput.cpp:701