FS2_Open
Open source remastering of the Freespace 2 engine
key.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) Volition, Inc. 1999. All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell
5  * or otherwise commercially exploit the source or things you created based on the
6  * source.
7  *
8 */
9 
10 
11 
12 //#define USE_DIRECTINPUT
13 
14 #ifdef _WIN32
15 #include <windows.h>
16 #include <windowsx.h>
17 #else
18 #include "SDL.h"
19 #endif
20 
21 #include "controlconfig/controlsconfig.h" //For textify scancode
22 #include "globalincs/pstypes.h"
23 #include "graphics/2d.h"
24 #include "io/key.h"
25 #include "math/fix.h"
26 #include "io/timer.h"
27 #include "localization/localize.h"
28 #include "parse/scripting.h"
29 #include "cmdline/cmdline.h"
30 
31 #define THREADED // to use the proper set of macros
32 #include "osapi/osapi.h"
33 
34 
35 #define KEY_BUFFER_SIZE 16
36 
37 //-------- Variable accessed by outside functions ---------
38 ubyte keyd_buffer_type; // 0=No buffer, 1=buffer ASCII, 2=buffer scans
44 
45 typedef struct keyboard {
53  int down_check[NUM_KEYS]; // nonzero if has been pressed yet this mission
55 } keyboard;
56 
58 
59 int key_inited = 0;
60 
62 
63 //int Backspace_debug=1; // global flag that will enable/disable the backspace key from stopping execution
64  // This flag was created since the backspace key is also used to correct mistakes
65  // when typing in your pilots callsign. This global flag is checked before execution
66  // is stopped.
67 
68 #ifdef SCP_UNIX
69  int SDLtoFS2[SDLK_LAST];
70 #endif
71 
72 int ascii_table[128] =
73 { 255, 255, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=',255,255,
74  'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 255, 255,
75  'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', 39, '`',
76  255, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 255,'*',
77  255, ' ', 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255,255,
78  255, 255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
79  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
80  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
81  255,255,255,255,255,255,255,255 };
82 
84 { 255, 255, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+',255,255,
85  'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 255, 255,
86  'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',
87  255, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 255,255,
88  255, ' ', 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255,255,
89  255, 255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
90  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
91  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
92  255,255,255,255,255,255,255,255 };
93 
94 static int Key_numlock_was_on = 0; // Flag to indicate whether NumLock is on at start
95 
96 #ifdef _WIN32
97  static int Key_running_NT = 0; // NT is the OS
98 #endif
99 
102 
103 #ifdef SCP_UNIX
104 
107 enum KeyboardLayout {
108  KEYBOARD_LAYOUT_DEFAULT,
109  KEYBOARD_LAYOUT_QWERTZ,
110  KEYBOARD_LAYOUT_AZERTY
111 };
112 
113 void FillSDLArray ()
114 {
115  KeyboardLayout layout = KEYBOARD_LAYOUT_DEFAULT;
116 
118  if (!strcmp(Cmdline_keyboard_layout, "qwertz")) {
119  layout = KEYBOARD_LAYOUT_QWERTZ;
120  }
121 
122  if (!strcmp(Cmdline_keyboard_layout, "azerty")) {
123  layout = KEYBOARD_LAYOUT_AZERTY;
124  }
125 
126  }
127 
128  if(layout == KEYBOARD_LAYOUT_AZERTY) {
129  SDLtoFS2[SDLK_WORLD_64] = KEY_0;
130  SDLtoFS2[SDLK_AMPERSAND] = KEY_1;
131  SDLtoFS2[SDLK_WORLD_73] = KEY_2;
132  SDLtoFS2[SDLK_QUOTEDBL] = KEY_3;
133  SDLtoFS2[SDLK_QUOTE] = KEY_4;
134  SDLtoFS2[SDLK_LEFTPAREN] = KEY_5;
135  SDLtoFS2[SDLK_MINUS] = KEY_6;
136  SDLtoFS2[SDLK_WORLD_72] = KEY_7;
137  SDLtoFS2[SDLK_UNDERSCORE] = KEY_8;
138  SDLtoFS2[SDLK_WORLD_71] = KEY_9;
139  } else {
140  SDLtoFS2[SDLK_0] = KEY_0;
141  SDLtoFS2[SDLK_1] = KEY_1;
142  SDLtoFS2[SDLK_2] = KEY_2;
143  SDLtoFS2[SDLK_3] = KEY_3;
144  SDLtoFS2[SDLK_4] = KEY_4;
145  SDLtoFS2[SDLK_5] = KEY_5;
146  SDLtoFS2[SDLK_6] = KEY_6;
147  SDLtoFS2[SDLK_7] = KEY_7;
148  SDLtoFS2[SDLK_8] = KEY_8;
149  SDLtoFS2[SDLK_9] = KEY_9;
150  }
151 
152  SDLtoFS2[SDLK_a] = KEY_A;
153  SDLtoFS2[SDLK_b] = KEY_B;
154  SDLtoFS2[SDLK_c] = KEY_C;
155  SDLtoFS2[SDLK_d] = KEY_D;
156  SDLtoFS2[SDLK_e] = KEY_E;
157  SDLtoFS2[SDLK_f] = KEY_F;
158  SDLtoFS2[SDLK_g] = KEY_G;
159  SDLtoFS2[SDLK_h] = KEY_H;
160  SDLtoFS2[SDLK_i] = KEY_I;
161  SDLtoFS2[SDLK_j] = KEY_J;
162  SDLtoFS2[SDLK_k] = KEY_K;
163  SDLtoFS2[SDLK_l] = KEY_L;
164  SDLtoFS2[SDLK_m] = KEY_M;
165  SDLtoFS2[SDLK_n] = KEY_N;
166  SDLtoFS2[SDLK_o] = KEY_O;
167  SDLtoFS2[SDLK_p] = KEY_P;
168  SDLtoFS2[SDLK_q] = KEY_Q;
169  SDLtoFS2[SDLK_r] = KEY_R;
170  SDLtoFS2[SDLK_s] = KEY_S;
171  SDLtoFS2[SDLK_t] = KEY_T;
172  SDLtoFS2[SDLK_u] = KEY_U;
173  SDLtoFS2[SDLK_v] = KEY_V;
174  SDLtoFS2[SDLK_w] = KEY_W;
175  SDLtoFS2[SDLK_x] = KEY_X;
176  SDLtoFS2[SDLK_y] = KEY_Y;
177  SDLtoFS2[SDLK_z] = KEY_Z;
178 
179  if(layout == KEYBOARD_LAYOUT_DEFAULT) {
180  SDLtoFS2[SDLK_MINUS] = KEY_MINUS;
181  SDLtoFS2[SDLK_EQUALS] = KEY_EQUAL;
182  SDLtoFS2[SDLK_SLASH] = KEY_DIVIDE; // No idea - DDOI
183  SDLtoFS2[SDLK_BACKSLASH] = KEY_SLASH;
184  //SDLtoFS2[SDLK_BACKSLASH] = KEY_SLASH_UK; // ?
185  SDLtoFS2[SDLK_COMMA] = KEY_COMMA;
186  SDLtoFS2[SDLK_PERIOD] = KEY_PERIOD;
187  SDLtoFS2[SDLK_SEMICOLON] = KEY_SEMICOL;
188 
189  SDLtoFS2[SDLK_LEFTBRACKET] = KEY_LBRACKET;
190  SDLtoFS2[SDLK_RIGHTBRACKET] = KEY_RBRACKET;
191 
192  SDLtoFS2[SDLK_BACKQUOTE] = KEY_LAPOSTRO;
193  SDLtoFS2[SDLK_QUOTE] = KEY_RAPOSTRO;
194  }
195 
196  if(layout == KEYBOARD_LAYOUT_QWERTZ) {
197  SDLtoFS2[SDLK_WORLD_63] = KEY_MINUS;
198  SDLtoFS2[SDLK_WORLD_20] = KEY_EQUAL;
199  SDLtoFS2[SDLK_MINUS] = KEY_DIVIDE;
200  SDLtoFS2[SDLK_HASH] = KEY_SLASH;
201  SDLtoFS2[SDLK_COMMA] = KEY_COMMA;
202  SDLtoFS2[SDLK_PERIOD] = KEY_PERIOD;
203  SDLtoFS2[SDLK_WORLD_86] = KEY_SEMICOL;
204 
205  SDLtoFS2[SDLK_WORLD_92] = KEY_LBRACKET;
206  SDLtoFS2[SDLK_PLUS] = KEY_RBRACKET;
207 
208  SDLtoFS2[SDLK_CARET] = KEY_LAPOSTRO;
209  SDLtoFS2[SDLK_WORLD_68] = KEY_RAPOSTRO;
210  }
211 
212  if(layout == KEYBOARD_LAYOUT_AZERTY) {
213  SDLtoFS2[SDLK_RIGHTPAREN] = KEY_MINUS;
214  SDLtoFS2[SDLK_EQUALS] = KEY_EQUAL;
215  SDLtoFS2[SDLK_EXCLAIM] = KEY_DIVIDE;
216  SDLtoFS2[SDLK_ASTERISK] = KEY_SLASH;
217  SDLtoFS2[SDLK_COMMA] = KEY_COMMA;
218  SDLtoFS2[SDLK_COLON] = KEY_PERIOD;
219  SDLtoFS2[SDLK_SEMICOLON] = KEY_SEMICOL;
220 
221  SDLtoFS2[SDLK_CARET] = KEY_LBRACKET;
222  SDLtoFS2[SDLK_DOLLAR] = KEY_RBRACKET;
223 
224  SDLtoFS2[SDLK_WORLD_18] = KEY_LAPOSTRO;
225  SDLtoFS2[SDLK_WORLD_89] = KEY_RAPOSTRO;
226  }
227 
228  SDLtoFS2[SDLK_ESCAPE] = KEY_ESC;
229  SDLtoFS2[SDLK_RETURN] = KEY_ENTER;
230  SDLtoFS2[SDLK_BACKSPACE] = KEY_BACKSP;
231  SDLtoFS2[SDLK_TAB] = KEY_TAB;
232  SDLtoFS2[SDLK_SPACE] = KEY_SPACEBAR;
233 
234  SDLtoFS2[SDLK_NUMLOCK] = KEY_NUMLOCK;
235  SDLtoFS2[SDLK_SCROLLOCK] = KEY_SCROLLOCK;
236  SDLtoFS2[SDLK_CAPSLOCK] = KEY_CAPSLOCK;
237 
238  SDLtoFS2[SDLK_LSHIFT] = KEY_LSHIFT;
239  SDLtoFS2[SDLK_RSHIFT] = KEY_RSHIFT;
240 
241  SDLtoFS2[SDLK_LALT] = KEY_LALT;
242  SDLtoFS2[SDLK_RALT] = KEY_RALT;
243 
244  SDLtoFS2[SDLK_LCTRL] = KEY_LCTRL;
245  SDLtoFS2[SDLK_RCTRL] = KEY_RCTRL;
246 
247  SDLtoFS2[SDLK_F1] = KEY_F1;
248  SDLtoFS2[SDLK_F2] = KEY_F2;
249  SDLtoFS2[SDLK_F3] = KEY_F3;
250  SDLtoFS2[SDLK_F4] = KEY_F4;
251  SDLtoFS2[SDLK_F5] = KEY_F5;
252  SDLtoFS2[SDLK_F6] = KEY_F6;
253  SDLtoFS2[SDLK_F7] = KEY_F7;
254  SDLtoFS2[SDLK_F8] = KEY_F8;
255  SDLtoFS2[SDLK_F9] = KEY_F9;
256  SDLtoFS2[SDLK_F10] = KEY_F10;
257  SDLtoFS2[SDLK_F11] = KEY_F11;
258  SDLtoFS2[SDLK_F12] = KEY_F12;
259 
260  SDLtoFS2[SDLK_KP0] = KEY_PAD0;
261  SDLtoFS2[SDLK_KP1] = KEY_PAD1;
262  SDLtoFS2[SDLK_KP2] = KEY_PAD2;
263  SDLtoFS2[SDLK_KP3] = KEY_PAD3;
264  SDLtoFS2[SDLK_KP4] = KEY_PAD4;
265  SDLtoFS2[SDLK_KP5] = KEY_PAD5;
266  SDLtoFS2[SDLK_KP6] = KEY_PAD6;
267  SDLtoFS2[SDLK_KP7] = KEY_PAD7;
268  SDLtoFS2[SDLK_KP8] = KEY_PAD8;
269  SDLtoFS2[SDLK_KP9] = KEY_PAD9;
270  SDLtoFS2[SDLK_KP_MINUS] = KEY_PADMINUS;
271  SDLtoFS2[SDLK_KP_PLUS] = KEY_PADPLUS;
272  SDLtoFS2[SDLK_KP_PERIOD] = KEY_PADPERIOD;
273  SDLtoFS2[SDLK_KP_DIVIDE] = KEY_PADDIVIDE;
274  SDLtoFS2[SDLK_KP_MULTIPLY] = KEY_PADMULTIPLY;
275  SDLtoFS2[SDLK_KP_ENTER] = KEY_PADENTER;
276 
277  SDLtoFS2[SDLK_INSERT] = KEY_INSERT;
278  SDLtoFS2[SDLK_HOME] = KEY_HOME;
279  SDLtoFS2[SDLK_PAGEUP] = KEY_PAGEUP;
280  SDLtoFS2[SDLK_DELETE] = KEY_DELETE;
281  SDLtoFS2[SDLK_END] = KEY_END;
282  SDLtoFS2[SDLK_PAGEDOWN] = KEY_PAGEDOWN;
283  SDLtoFS2[SDLK_UP] = KEY_UP;
284  SDLtoFS2[SDLK_DOWN] = KEY_DOWN;
285  SDLtoFS2[SDLK_LEFT] = KEY_LEFT;
286  SDLtoFS2[SDLK_RIGHT] = KEY_RIGHT;
287 
288  SDLtoFS2[SDLK_PRINT] = KEY_PRINT_SCRN;
289  SDLtoFS2[SDLK_PAUSE] = KEY_PAUSE;
290  SDLtoFS2[SDLK_BREAK] = KEY_BREAK;
291 }
292 #endif
293 
295 {
296 #ifdef _WIN32
297  unsigned char keys[256];
298  GetKeyboardState(keys);
299  if ( keys[VK_NUMLOCK] ) {
300  return 1;
301  }
302  return 0;
303 #else
304  int keys[SDLK_LAST];
305  SDL_GetKeyState(keys);
306  if ( keys[SDLK_NUMLOCK] ) {
307  return 1;
308  }
309  return 0;
310 #endif
311 }
312 
314 {
315 #ifdef _WIN32
316  unsigned char keys[256];
317  GetKeyboardState(keys);
318  keys[VK_NUMLOCK] = 0;
319  SetKeyboardState(keys);
320 #endif
321 }
322 
324 {
325 #ifdef _WIN32
326  unsigned char keys[256];
327  GetKeyboardState(keys);
328  keys[VK_NUMLOCK] = 1;
329  SetKeyboardState(keys);
330 #endif
331 }
332 
333 // Convert a BIOS scancode to ASCII.
334 // If scancode >= 127, returns 255, meaning there is no corresponding ASCII code.
335 // Uses ascii_table and shifted_ascii_table to translate scancode to ASCII.
336 int key_to_ascii(int keycode )
337 {
338  int shifted;
339 
340  if ( !key_inited ) return 255;
341 
342  shifted = keycode & KEY_SHIFTED;
343  keycode &= 0xFF;
344 
345  if ( keycode>=127 )
346  return 255;
347 
348  if (shifted)
349  return shifted_ascii_table[keycode];
350  else
351  return ascii_table[keycode];
352 }
353 
354 // Flush the keyboard buffer.
355 // Clear the keyboard array (keyd_pressed).
356 void key_flush()
357 {
358  int i;
359  uint CurTime;
360 
361  if ( !key_inited ) return;
362 
364 
365  key_data.keyhead = key_data.keytail = 0;
366 
367  //Clear the keyboard buffer
368  for (i=0; i<KEY_BUFFER_SIZE; i++ ) {
369  key_data.keybuffer[i] = 0;
370  key_data.time_pressed[i] = 0;
371  }
372 
373  //Clear the keyboard array
374 
375  CurTime = timer_get_milliseconds();
376 
377 
378  for (i=0; i<NUM_KEYS; i++ ) {
379  keyd_pressed[i] = 0;
380  key_data.TimeKeyDownChecked[i] = CurTime;
381  key_data.TimeKeyWentDown[i] = CurTime;
382  key_data.TimeKeyHeldDown[i] = 0;
383  key_data.NumDowns[i]=0;
384  key_data.NumUps[i]=0;
385  }
386 
388 }
389 
390 // A nifty function which performs the function:
391 // n = (n+1) % KEY_BUFFER_SIZE
392 // (assuming positive values of n).
393 int add_one( int n )
394 {
395  n++;
396  if ( n >= KEY_BUFFER_SIZE ) n=0;
397  return n;
398 }
399 
400 // Returns 1 if character waiting... 0 otherwise
402 {
403  int is_one_waiting = 0;
404 
405  if ( !key_inited ) return 0;
406 
408 
409  if (key_data.keytail != key_data.keyhead){
410  is_one_waiting = 1;
411  }
412 
414 
415  return is_one_waiting;
416 }
417 
418 // Return key scancode if a key has been pressed,
419 // else return 0.
420 // Reads keys out of the key buffer and updates keyhead.
421 
422 //WMC - Added so scripting can get at keys.
425 {
426  int key = 0;
427 
428  if ( !key_inited ) return 0;
429 
431 
432  if (key_data.keytail!=key_data.keyhead) {
433  key = key_data.keybuffer[key_data.keyhead];
434  key_data.keyhead = add_one(key_data.keyhead);
435  }
436 
438 
439  Current_key_down = key;
440 
441  return key;
442 }
443 
444 // Unget a key. Puts it back in the input queue.
445 void key_outkey(int key)
446 {
447  int bufp;
448 
449  if ( !key_inited ) return;
450 
452 
453  bufp = key_data.keytail+1;
454 
455  if (bufp >= KEY_BUFFER_SIZE){
456  bufp = 0;
457  }
458 
459  key_data.keybuffer[key_data.keytail] = (unsigned short)key;
460 
461  key_data.keytail = bufp;
462 
464 }
465 
466 
467 
468 // Return amount of time last key was held down.
469 // This is currently (July 17, 1996) bogus because our timing is
470 // not accurate.
471 int key_inkey_time(uint * time)
472 {
473  int key = 0;
474 
475  if ( !key_inited ) {
476  *time = 0;
477  return 0;
478  }
479 
481 
482  if (key_data.keytail!=key_data.keyhead) {
483  key = key_data.keybuffer[key_data.keyhead];
484  *time = key_data.time_pressed[key_data.keyhead];
485  key_data.keyhead = add_one(key_data.keyhead);
486  }
487 
489 
490  return key;
491 }
492 
493 
494 // Returns scancode of last key pressed, if any (returns 0 if no key pressed)
495 // but does not update keyhead pointer.
497 {
498  int key = 0;
499 
500  if ( !key_inited ) return 0;
501 
503 
504  if (key_data.keytail!=key_data.keyhead) {
505  key = key_data.keybuffer[key_data.keyhead];
506  }
508 
509  return key;
510 }
511 
512 // If not installed, uses BIOS and returns getch();
513 // Else returns pending key (or waits for one if none waiting).
515 {
516  int dummy=0;
517  int in;
518 
519  if ( !key_inited ) return 0;
520 
521  while (!key_checkch()){
522  os_poll();
523 
524  dummy++;
525  }
526  in = key_inkey();
527 
528  return in;
529 }
530 
531 // Set global shift_status with modifier results (shift, ctrl, alt).
533 {
534  unsigned int shift_status = 0;
535 
536  if ( !key_inited ) return 0;
537 
539 
541  shift_status |= KEY_SHIFTED;
542 
544  shift_status |= KEY_ALTED;
545 
547  shift_status |= KEY_CTRLED;
548 
549 #ifndef NDEBUG
551  shift_status |= KEY_DEBUGGED;
552 #else
553  if (keyd_pressed[KEY_DEBUG_KEY]) {
554  mprintf(("Cheats_enabled = %i, Key_normal_game = %i\n", Cheats_enabled, Key_normal_game));
555  if ((Cheats_enabled) && Key_normal_game) {
556  mprintf(("Debug key\n"));
557  shift_status |= KEY_DEBUGGED1;
558  }
559  }
560 #endif
562 
563  return shift_status;
564 }
565 
566 // Returns amount of time key (specified by "code") has been down since last call.
567 // Returns float, unlike key_down_time() which returns a fix.
568 float key_down_timef(uint scancode)
569 {
570  uint time_down, time;
571  uint delta_time;
572 
573  if ( !key_inited ) {
574  return 0.0f;
575  }
576 
577  if (scancode >= NUM_KEYS) {
578  return 0.0f;
579  }
580 
582 
583  time = timer_get_milliseconds();
584  delta_time = time - key_data.TimeKeyDownChecked[scancode];
585  key_data.TimeKeyDownChecked[scancode] = time;
586 
587  if ( delta_time <= 1 ) {
588  key_data.TimeKeyWentDown[scancode] = time;
589  if (keyd_pressed[scancode]) {
591  return 1.0f;
592  } else {
594  return 0.0f;
595  }
596  }
597 
598  if ( !keyd_pressed[scancode] ) {
599  time_down = key_data.TimeKeyHeldDown[scancode];
600  key_data.TimeKeyHeldDown[scancode] = 0;
601  } else {
602  time_down = time - key_data.TimeKeyWentDown[scancode];
603  key_data.TimeKeyWentDown[scancode] = time;
604  }
605 
607 
608  return i2fl(time_down) / i2fl(delta_time);
609 }
610 
611 /*
612 // Returns amount of time key (specified by "code") has been down since last call.
613 // Returns float, unlike key_down_time() which returns a fix.
614 fix key_down_time( uint code )
615 {
616  uint time_down, time;
617  uint delta_time;
618 
619  if ( !key_inited ) return 0.0f;
620 
621  if ((scancode<0)|| (scancode>=NUM_KEYS)) return 0.0f;
622 
623  EnterCriticalSection( &key_lock );
624 
625  time = timer_get_milliseconds();
626  delta_time = time - TimeKeyDownChecked[scancode];
627  TimeKeyDownChecked[scancode] = time;
628 
629  if ( delta_time <= 1 ) {
630  LeaveCriticalSection( &key_lock );
631  if (keyd_pressed[scancode])
632  return F1_0;
633  else
634  return 0;
635  }
636 
637  if ( !keyd_pressed[scancode] ) {
638  time_down = key_data.TimeKeyHeldDown[scancode];
639  key_data.TimeKeyHeldDown[scancode] = 0;
640  } else {
641  time_down = time - key_data.TimeKeyWentDown[scancode];
642  key_data.TimeKeyWentDown[scancode] = time;
643  }
644 
645  LeaveCriticalSection( &key_lock );
646 
647  return fixmuldiv( time_down, F1_0, delta_time );
648 }
649 */
650 
651 
652 // Returns number of times key has went from up to down since last call.
653 int key_down_count(int scancode)
654 {
655  int n;
656 
657  if ( !key_inited ) return 0;
658  if ((scancode<0)|| (scancode>=NUM_KEYS)) return 0;
659 
661 
662  n = key_data.NumDowns[scancode];
663  key_data.NumDowns[scancode] = 0;
664 
666 
667  return n;
668 }
669 
670 
671 // Returns number of times key has went from down to up since last call.
672 int key_up_count(int scancode)
673 {
674  int n;
675 
676  if ( !key_inited ) return 0;
677  if ((scancode<0)|| (scancode>=NUM_KEYS)) return 0;
678 
680 
681  n = key_data.NumUps[scancode];
682  key_data.NumUps[scancode] = 0;
683 
685 
686  return n;
687 }
688 
689 int key_check(int key)
690 {
691  return key_data.down_check[key];
692 }
693 
694 // Add a key up or down code to the key buffer. state=1 -> down, state=0 -> up
695 // latency => time difference in ms between when key was actually pressed and now
696 //void key_mark( uint code, int state )
697 void key_mark( uint code, int state, uint latency )
698 {
699  uint scancode, breakbit, temp, event_time;
700  ushort keycode;
701 
702  if ( !key_inited ) return;
703 
705 
706  // If running in the UK, need to translate their wacky slash scancode to ours
707  if ( code == KEY_SLASH_UK ) {
708  code = KEY_SLASH;
709  }
710 
711 #ifndef SCP_UNIX
712 
713  if ( (code == 0xc5) && !Key_running_NT ) {
715  }
716 #endif
717 
718  Assert( code < NUM_KEYS );
719 
720  event_time = timer_get_milliseconds() - latency;
721  // event_time = timeGetTime() - latency;
722 
723  // Read in scancode
724  scancode = code & (NUM_KEYS-1);
725  breakbit = !state;
726 
727  if (breakbit) {
728  // Key going up
729  keyd_last_released = scancode;
730  keyd_pressed[scancode] = 0;
731  key_data.NumUps[scancode]++;
732 
733  // What is the point of this code? "temp" is never used!
734  temp = 0;
738  temp |= keyd_pressed[KEY_DEBUG_KEY];
739 
740  if (event_time < key_data.TimeKeyWentDown[scancode]) {
741  key_data.TimeKeyHeldDown[scancode] = 0;
742  } else {
743  key_data.TimeKeyHeldDown[scancode] += event_time - key_data.TimeKeyWentDown[scancode];
744  }
745 
746  Current_key_down = scancode;
748  Current_key_down |= KEY_SHIFTED;
749  }
750 
752  Current_key_down |= KEY_ALTED;
753  }
754 
756  Current_key_down |= KEY_CTRLED;
757  }
758 
759  Script_system.SetHookVar("Key", 's', textify_scancode(Current_key_down));
761  Script_system.RemHookVar("Key");
762  } else {
763  // Key going down
764  keyd_last_pressed = scancode;
765  keyd_time_when_last_pressed = event_time;
766  if (!keyd_pressed[scancode]) {
767  // First time down
768  key_data.TimeKeyWentDown[scancode] = event_time;
769  keyd_pressed[scancode] = 1;
770  key_data.NumDowns[scancode]++;
771  key_data.down_check[scancode]++;
772 
773  //WMC - For scripting
774  Current_key_down = scancode;
776  Current_key_down |= KEY_SHIFTED;
777  }
778 
780  Current_key_down |= KEY_ALTED;
781  }
782 
784  Current_key_down |= KEY_CTRLED;
785  }
786 
787  Script_system.SetHookVar("Key", 's', textify_scancode(Current_key_down));
789  Script_system.RemHookVar("Key");
790  } else if (!keyd_repeat) {
791  // Don't buffer repeating key if repeat mode is off
792  scancode = 0xAA;
793  }
794 
795  if ( scancode!=0xAA ) {
796  keycode = (unsigned short)scancode;
797 
799  keycode |= KEY_SHIFTED;
800  }
801 
803  keycode |= KEY_ALTED;
804  }
805 
807  keycode |= KEY_CTRLED;
808  }
809 
810 #ifndef NDEBUG
811  if ( keyd_pressed[KEY_DEBUG_KEY] ) {
812  keycode |= KEY_DEBUGGED;
813  }
814 #else
815  if ( keyd_pressed[KEY_DEBUG_KEY] ) {
816  mprintf(("Cheats_enabled = %i, Key_normal_game = %i\n", Cheats_enabled, Key_normal_game));
818  keycode |= KEY_DEBUGGED1;
819  }
820  }
821 
822 #endif
823 
824  if ( keycode ) {
825  temp = key_data.keytail+1;
826  if ( temp >= KEY_BUFFER_SIZE ) temp=0;
827 
828  if (temp!=key_data.keyhead) {
829  key_data.keybuffer[key_data.keytail] = keycode;
830  key_data.time_pressed[key_data.keytail] = keyd_time_when_last_pressed;
831  key_data.keytail = temp;
832  }
833  }
834  }
835  }
836 
838 }
839 
840 #ifdef USE_DIRECTINPUT
841 void di_cleanup();
842 int di_init();
843 #endif
844 
845 
846 void key_close()
847 {
848  if ( !key_inited ) return;
849 
850  #ifdef USE_DIRECTINPUT
851  di_cleanup();
852  #endif
853 
854  if ( Key_numlock_was_on ) {
856  Key_numlock_was_on = 0;
857  }
858 
859  key_inited = 0;
860 
862 }
863 
864 void key_init()
865 {
866  // Initialize queue
867  if ( key_inited ) return;
868  key_inited = 1;
869 
871 
873 
874 #ifdef SCP_UNIX
875  FillSDLArray();
876 #endif
877 
879  keyd_buffer_type = 1;
880  keyd_repeat = 1;
881 
882  // Clear the keyboard array
883  key_flush();
884 
886 
887 #ifdef _WIN32
888  #ifdef USE_DIRECTINPUT
889  di_init();
890  #endif
891 
892  OSVERSIONINFO ver;
893  ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
894  GetVersionEx(&ver);
895  if ( ver.dwPlatformId == VER_PLATFORM_WIN32_NT ) {
896  Key_running_NT = 1;
897  } else {
898  Key_running_NT = 0;
899  if ( key_numlock_is_on() ) {
900  Key_numlock_was_on = 1;
902  }
903  }
904 #endif
905 
906  atexit(key_close);
907 }
908 
910 {
911  int i;
912 
913  for (i=0; i<NUM_KEYS; i++)
914  key_data.down_check[i] = 0;
915 }
916 
918 {
919  if ( !key_inited ) return;
920 
921  key_flush();
922 }
923 
925 {
926  if ( !key_inited ) return;
927 
928  key_flush();
929 }
930 
931 #ifdef USE_DIRECTINPUT
932 
933 // JAS - April 18, 1998
934 // Not using because DI has the following problems: (Everything else works ok)
935 // Under NT, Pause and Numlock report as identical keys.
936 // Under 95, Pause is the same as pressing Ctrl then Numlock. So the game fires each
937 // time you hit it.
938 //
939 
940 //============================================================================
941 // Direct Input code
942 // For the keyboard, this basically replaces our old functionallity of:
943 // WM_KEYDOWN:
944 // key_mark(...);
945 // WM_KEYUP:
946 // key_mark(...);
947 //============================================================================
948 
949 
950 #include "directx/vdinput.h"
951 
952 #define MAX_BUFFERED_KEYBOARD_EVENTS 10
953 
954 static LPDIRECTINPUT Di_object = NULL;
955 static LPDIRECTINPUTDEVICE Di_keyboard = NULL;
956 static HANDLE Di_thread = NULL;
957 static DWORD Di_thread_id = NULL;
958 static HANDLE Di_event = NULL;
959 
960 DWORD di_process(DWORD lparam)
961 {
962  while (1) {
963  if ( WaitForSingleObject( Di_event, INFINITE )==WAIT_OBJECT_0 ) {
964 
965  //mprintf(( "Got event!\n" ));
966 
967  HRESULT hr;
968 
969  DIDEVICEOBJECTDATA rgdod[10];
970  DWORD dwItems = MAX_BUFFERED_KEYBOARD_EVENTS;
971 
972 again:;
973  hr = Di_keyboard->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), rgdod, &dwItems, 0);
974 
975  if (hr == DIERR_INPUTLOST) {
976  /*
977  * DirectInput is telling us that the input stream has
978  * been interrupted. We aren't tracking any state
979  * between polls, so we don't have any special reset
980  * that needs to be done. We just re-acquire and
981  * try again.
982  */
983  Sleep(1000); // Pause a second...
984  hr = Di_keyboard->Acquire();
985  if (SUCCEEDED(hr)) {
986  goto again;
987  }
988  }
989 
990  if (SUCCEEDED(hr)) {
991  // dwItems = number of elements read (could be zero)
992  if (hr == DI_BUFFEROVERFLOW) {
993  // Buffer had overflowed.
994  mprintf(( "Buffer overflowed!\n" ));
995  }
996  int i;
997 
998  //mprintf(( "Got %d events\n", dwItems ));
999 
1000  for (i=0; i<(int)dwItems; i++ ) {
1001  int key = rgdod[i].dwOfs;
1002  int state = rgdod[i].dwData;
1003  int stamp = rgdod[i].dwTimeStamp;
1004 
1005  int latency;
1006  latency = timeGetTime() - stamp;
1007  if ( latency < 0 )
1008  latency=0;
1009 
1010 // if ( key == KEY_PRINT_SCRN ) {
1011 // key_mark( key, 1, latency );
1012 // }
1013 // key_mark( key, (state&0x80?1:0), latency );
1014  mprintf(( "Key=%x, State=%x, Time=%d, Latency=%d\n", key, state, stamp, latency ));
1015  }
1016 
1017  }
1018  }
1019 
1020  }
1021 
1022  return 0;
1023 }
1024 
1025 
1026 int di_init()
1027 {
1028  HRESULT hr;
1029 
1030  return 0;
1031 
1032 
1033  /*
1034  * Register with the DirectInput subsystem and get a pointer
1035  * to a IDirectInput interface we can use.
1036  *
1037  * Parameters:
1038  *
1039  * g_hinst
1040  *
1041  * Instance handle to our application or DLL.
1042  *
1043  * DIRECTINPUT_VERSION
1044  *
1045  * The version of DirectInput we were designed for.
1046  * We take the value from the <dinput.h> header file.
1047  *
1048  * &g_pdi
1049  *
1050  * Receives pointer to the IDirectInput interface
1051  * that was created.
1052  *
1053  * NULL
1054  *
1055  * We do not use OLE aggregation, so this parameter
1056  * must be NULL.
1057  *
1058  */
1059  hr = DirectInputCreate(GetModuleHandle(NULL), 0x300, &Di_object, NULL);
1060 
1061  if (FAILED(hr)) {
1062  mprintf(( "DirectInputCreate failed!\n" ));
1063  return FALSE;
1064  }
1065 
1066  /*
1067  * Obtain an interface to the system keyboard device.
1068  *
1069  * Parameters:
1070  *
1071  * GUID_SysKeyboard
1072  *
1073  * The instance GUID for the device we wish to access.
1074  * GUID_SysKeyboard is a predefined instance GUID that
1075  * always refers to the system keyboard device.
1076  *
1077  * &g_pKeyboard
1078  *
1079  * Receives pointer to the IDirectInputDevice interface
1080  * that was created.
1081  *
1082  * NULL
1083  *
1084  * We do not use OLE aggregation, so this parameter
1085  * must be NULL.
1086  *
1087  */
1088  hr = Di_object->CreateDevice(GUID_SysKeyboard, &Di_keyboard, NULL);
1089 
1090  if (FAILED(hr)) {
1091  mprintf(( "CreateDevice failed!\n" ));
1092  return FALSE;
1093  }
1094 
1095  /*
1096  * Set the data format to "keyboard format".
1097  *
1098  * A data format specifies which controls on a device we
1099  * are interested in, and how they should be reported.
1100  *
1101  * This tells DirectInput that we will be passing an array
1102  * of 256 bytes to IDirectInputDevice::GetDeviceState.
1103  *
1104  * Parameters:
1105  *
1106  * c_dfDIKeyboard
1107  *
1108  * Predefined data format which describes
1109  * an array of 256 bytes, one per scancode.
1110  */
1111  hr = Di_keyboard->SetDataFormat(&c_dfDIKeyboard);
1112 
1113  if (FAILED(hr)) {
1114  mprintf(( "SetDataFormat failed!\n" ));
1115  return FALSE;
1116  }
1117 
1118 
1119  /*
1120  * Set the cooperativity level to let DirectInput know how
1121  * this device should interact with the system and with other
1122  * DirectInput applications.
1123  *
1124  * Parameters:
1125  *
1126  * DISCL_NONEXCLUSIVE
1127  *
1128  * Retrieve keyboard data when acquired, not interfering
1129  * with any other applications which are reading keyboard
1130  * data.
1131  *
1132  * DISCL_FOREGROUND
1133  *
1134  * If the user switches away from our application,
1135  * automatically release the keyboard back to the system.
1136  *
1137  */
1138  hr = Di_keyboard->SetCooperativeLevel((HWND)os_get_window(), DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
1139 
1140  if (FAILED(hr)) {
1141  mprintf(( "SetCooperativeLevel failed!\n" ));
1142  return FALSE;
1143  }
1144 
1145  DIPROPDWORD hdr;
1146 
1147  // Turn on buffering
1148  hdr.diph.dwSize = sizeof(DIPROPDWORD);
1149  hdr.diph.dwHeaderSize = sizeof(DIPROPHEADER);
1150  hdr.diph.dwObj = 0;
1151  hdr.diph.dwHow = DIPH_DEVICE; // Apply to entire device
1152  hdr.dwData = 16; //MAX_BUFFERED_KEYBOARD_EVENTS;
1153 
1154  hr = Di_keyboard->SetProperty( DIPROP_BUFFERSIZE, &hdr.diph );
1155  if (FAILED(hr)) {
1156  mprintf(( "SetProperty DIPROP_BUFFERSIZE failed\n" ));
1157  return FALSE;
1158  }
1159 
1160 
1161  Di_event = CreateEvent( NULL, FALSE, FALSE, NULL );
1162  Assert(Di_event != NULL);
1163 
1164  Di_thread = CreateThread(NULL, 1024, (LPTHREAD_START_ROUTINE)di_process, NULL, 0, &Di_thread_id);
1165  Assert( Di_thread != NULL );
1166 
1167  SetThreadPriority(Di_thread, THREAD_PRIORITY_HIGHEST);
1168 
1169  hr = Di_keyboard->SetEventNotification(Di_event);
1170  if (FAILED(hr)) {
1171  mprintf(( "SetEventNotification failed\n" ));
1172  return FALSE;
1173  }
1174 
1175  Di_keyboard->Acquire();
1176 
1177  return TRUE;
1178 }
1179 
1180 void di_cleanup()
1181 {
1182  /*
1183  * Destroy any lingering IDirectInputDevice object.
1184  */
1185  if (Di_keyboard) {
1186 
1187  /*
1188  * Cleanliness is next to godliness. Unacquire the device
1189  * one last time just in case we got really confused and tried
1190  * to exit while the device is still acquired.
1191  */
1192  Di_keyboard->Unacquire();
1193 
1194  Di_keyboard->Release();
1195  Di_keyboard = NULL;
1196  }
1197 
1198  /*
1199  * Destroy any lingering IDirectInput object.
1200  */
1201  if (Di_object) {
1202  Di_object->Release();
1203  Di_object = NULL;
1204  }
1205 
1206  if ( Di_event ) {
1207  CloseHandle(Di_event);
1208  Di_event = NULL;
1209  }
1210 
1211 }
1212 
1213 #endif
1214 
1215 
1216 
1217 
#define KEY_0
Definition: key.h:71
int keyd_time_when_last_pressed
Definition: key.cpp:43
void key_turn_on_numlock()
Definition: key.cpp:323
void key_mark(uint code, int state, uint latency)
Definition: key.cpp:697
#define KEY_LCTRL
Definition: key.h:140
#define KEY_INSERT
Definition: key.h:173
#define KEY_PAD9
Definition: key.h:165
#define KEY_PADMULTIPLY
Definition: key.h:170
#define KEY_K
Definition: key.h:92
struct DIPROPDWORD DIPROPDWORD
#define DISCL_NONEXCLUSIVE
Definition: vdinput.h:623
#define KEY_LAPOSTRO
Definition: key.h:122
#define KEY_F4
Definition: key.h:146
#define KEY_BUFFER_SIZE
Definition: key.cpp:35
void * HWND
Definition: config.h:104
#define DIERR_INPUTLOST
Definition: vdinput.h:1649
#define KEY_PADENTER
Definition: key.h:171
int i
Definition: multi_pxo.cpp:466
#define KEY_6
Definition: key.h:77
#define KEY_SLASH
Definition: key.h:112
#define KEY_PAD5
Definition: key.h:161
DWORD dwHow
Definition: vdinput.h:551
int SDLtoFS2[SDLK_LAST]
int key_numlock_is_on()
Definition: key.cpp:294
int key_inkey()
Definition: key.cpp:424
#define KEY_DOWN
Definition: key.h:180
#define KEY_F10
Definition: key.h:152
#define KEY_Y
Definition: key.h:106
char * Cmdline_keyboard_layout
Definition: cmdline.cpp:449
uint keytail
Definition: key.cpp:54
#define KEY_LEFT
Definition: key.h:181
float key_down_timef(uint scancode)
Definition: key.cpp:568
#define KEY_F12
Definition: key.h:154
#define KEY_PAGEDOWN
Definition: key.h:178
#define DELETE_CRITICAL_SECTION(csc)
Definition: osapi.h:41
#define KEY_5
Definition: key.h:76
void RemHookVar(char *name)
Definition: scripting.cpp:749
#define KEY_PAD8
Definition: key.h:164
#define KEY_8
Definition: key.h:79
uint keyd_last_pressed
Definition: key.cpp:40
#define KEY_RIGHT
Definition: key.h:182
#define KEY_Z
Definition: key.h:107
Assert(pm!=NULL)
#define KEY_1
Definition: key.h:72
int key_checkch()
Definition: key.cpp:401
#define KEY_F11
Definition: key.h:153
#define mprintf(args)
Definition: pstypes.h:238
uint key_get_shift_status()
Definition: key.cpp:532
#define KEY_NUMLOCK
Definition: key.h:130
#define KEY_PAD1
Definition: key.h:157
#define KEY_PAD4
Definition: key.h:160
#define KEY_E
Definition: key.h:86
#define KEY_LSHIFT
Definition: key.h:134
#define KEY_U
Definition: key.h:102
void key_lost_focus()
Definition: key.cpp:917
#define KEY_F8
Definition: key.h:150
#define KEY_F5
Definition: key.h:147
int key_inkey_time(uint *time)
Definition: key.cpp:471
#define TRUE
Definition: pstypes.h:399
DWORD dwData
Definition: vdinput.h:561
#define KEY_PAD0
Definition: key.h:156
SDL_mutex * CRITICAL_SECTION
Definition: config.h:213
#define KEY_V
Definition: key.h:103
#define KEY_C
Definition: key.h:84
uint NumUps[NUM_KEYS]
Definition: key.cpp:52
#define DirectInputCreate
Definition: vdinput.h:1487
void key_flush()
Definition: key.cpp:356
#define KEY_PAGEUP
Definition: key.h:175
DWORD dwHeaderSize
Definition: vdinput.h:549
int key
#define KEY_DELETE
Definition: key.h:176
#define KEY_MINUS
Definition: key.h:109
char stamp[STAMP_STRING_LENGTH]
Definition: fredview.cpp:74
#define CHA_KEYRELEASED
Definition: scripting.h:61
uint TimeKeyHeldDown[NUM_KEYS]
Definition: key.cpp:49
char * textify_scancode(int code)
GLuint in
Definition: Glext.h:9087
int key_to_ascii(int keycode)
Definition: key.cpp:336
script_state Script_system("FS2_Open Scripting")
uint keyd_last_released
Definition: key.cpp:41
CRITICAL_SECTION key_lock
Definition: key.cpp:61
#define KEY_I
Definition: key.h:90
#define KEY_F7
Definition: key.h:149
uint time_pressed[KEY_BUFFER_SIZE]
Definition: key.cpp:47
void key_outkey(int key)
Definition: key.cpp:445
#define KEY_PAD7
Definition: key.h:163
HWND DWORD code
Definition: vddraw.h:425
uint TimeKeyDownChecked[NUM_KEYS]
Definition: key.cpp:50
#define KEY_A
Definition: key.h:82
uint os_get_window()
Definition: osapi.cpp:208
int key_down_count(int scancode)
Definition: key.cpp:653
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
#define KEY_9
Definition: key.h:80
unsigned int uint
Definition: pstypes.h:64
#define KEY_SCROLLOCK
Definition: key.h:131
#define DIPH_DEVICE
Definition: vdinput.h:555
#define DI_BUFFEROVERFLOW
Definition: vdinput.h:1512
int add_one(int n)
Definition: key.cpp:393
int Cheats_enabled
Definition: key.cpp:100
DIPROPHEADER diph
Definition: vdinput.h:560
#define KEY_PAD3
Definition: key.h:159
#define CHA_KEYPRESSED
Definition: scripting.h:60
#define KEY_SHIFTED
Definition: key.h:62
#define KEY_W
Definition: key.h:104
DWORD dwSize
Definition: vdinput.h:548
#define KEY_ENTER
Definition: key.h:125
#define KEY_N
Definition: key.h:95
#define KEY_RCTRL
Definition: key.h:141
keyboard key_data
Definition: key.cpp:57
#define DISCL_FOREGROUND
Definition: vdinput.h:624
#define KEY_J
Definition: key.h:91
#define KEY_PAUSE
Definition: key.h:185
struct IDirectInput * LPDIRECTINPUT
Definition: vdinput.h:1381
ushort keybuffer[KEY_BUFFER_SIZE]
Definition: key.cpp:46
#define ENTER_CRITICAL_SECTION(csc)
Definition: osapi.h:42
#define KEY_R
Definition: key.h:99
void key_got_focus()
Definition: key.cpp:924
#define KEY_DEBUG_KEY
Definition: key.h:69
#define KEY_RALT
Definition: key.h:138
unsigned long DWORD
Definition: config.h:90
#define KEY_BACKSP
Definition: key.h:126
struct IDirectInputDevice * LPDIRECTINPUTDEVICE
Definition: vdinput.h:764
#define KEY_7
Definition: key.h:78
#define KEY_P
Definition: key.h:97
ubyte keyd_repeat
Definition: key.cpp:39
#define KEY_T
Definition: key.h:101
int shifted_ascii_table[128]
Definition: key.cpp:83
#define KEY_DIVIDE
Definition: key.h:111
#define KEY_PADMINUS
Definition: key.h:166
GLclampd n
Definition: Glext.h:7286
unsigned char ubyte
Definition: pstypes.h:62
void key_level_init()
Definition: key.cpp:909
void os_poll()
Definition: osapi.cpp:748
long HRESULT
Definition: vddraw.h:115
#define KEY_F6
Definition: key.h:148
#define KEY_O
Definition: key.h:96
#define KEY_PRINT_SCRN
Definition: key.h:184
int key_up_count(int scancode)
Definition: key.cpp:672
struct DIPROPHEADER DIPROPHEADER
#define KEY_F1
Definition: key.h:143
#define KEY_SLASH_UK
Definition: key.h:113
#define KEY_END
Definition: key.h:177
#define KEY_COMMA
Definition: key.h:114
int RunCondition(int condition, char format='\0', void *data=NULL, class object *objp=NULL, int more_data=0)
Definition: scripting.cpp:924
#define KEY_Q
Definition: key.h:98
int key_getch()
Definition: key.cpp:514
#define KEY_H
Definition: key.h:89
#define KEY_CAPSLOCK
Definition: key.h:132
uint keyhead
Definition: key.cpp:54
#define KEY_B
Definition: key.h:83
int key_check(int key)
Definition: key.cpp:689
#define KEY_EQUAL
Definition: key.h:110
#define KEY_PADPERIOD
Definition: key.h:168
#define LEAVE_CRITICAL_SECTION(csc)
Definition: osapi.h:43
#define NUM_KEYS
Definition: key.h:23
ubyte keyd_buffer_type
Definition: key.cpp:38
#define KEY_ESC
Definition: key.h:124
void key_close()
Definition: key.cpp:846
uint TimeKeyWentDown[NUM_KEYS]
Definition: key.cpp:48
const DIDATAFORMAT c_dfDIKeyboard
#define KEY_ALTED
Definition: key.h:63
int key_inited
Definition: key.cpp:59
#define KEY_DEBUGGED1
Definition: key.h:66
Definition: key.cpp:45
#define KEY_4
Definition: key.h:75
#define INITIALIZE_CRITICAL_SECTION(csc)
Definition: osapi.h:40
unsigned short ushort
Definition: pstypes.h:63
#define KEY_F2
Definition: key.h:144
void key_turn_off_numlock()
Definition: key.cpp:313
#define KEY_DEBUGGED
Definition: key.h:65
#define DIPROP_BUFFERSIZE
Definition: vdinput.h:581
void Sleep(int mili)
ubyte keyd_pressed[NUM_KEYS]
Definition: key.cpp:42
#define KEY_LALT
Definition: key.h:137
#define KEY_LBRACKET
Definition: key.h:118
void SetHookVar(char *name, char format, void *data=NULL)
Definition: scripting.cpp:650
#define KEY_CTRLED
Definition: key.h:64
#define KEY_RAPOSTRO
Definition: key.h:121
#define KEY_SPACEBAR
Definition: key.h:128
#define KEY_TAB
Definition: key.h:127
#define i2fl(i)
Definition: floating.h:32
#define KEY_UP
Definition: key.h:179
int key_peekkey()
Definition: key.cpp:496
int Key_normal_game
Definition: key.cpp:101
int temp
Definition: lua.cpp:4996
#define KEY_G
Definition: key.h:88
#define KEY_SEMICOL
Definition: key.h:116
#define KEY_PAD6
Definition: key.h:162
uint NumDowns[NUM_KEYS]
Definition: key.cpp:51
#define KEY_HOME
Definition: key.h:174
#define KEY_X
Definition: key.h:105
#define KEY_M
Definition: key.h:94
#define KEY_BREAK
Definition: key.h:186
void * HANDLE
Definition: config.h:106
#define KEY_PAD2
Definition: key.h:158
#define KEY_PERIOD
Definition: key.h:115
struct keyboard keyboard
#define KEY_S
Definition: key.h:100
DWORD dwObj
Definition: vdinput.h:550
#define FALSE
Definition: pstypes.h:400
#define KEY_2
Definition: key.h:73
#define KEY_PADPLUS
Definition: key.h:167
int timer_get_milliseconds()
Definition: timer.cpp:150
#define KEY_D
Definition: key.h:85
#define KEY_PADDIVIDE
Definition: key.h:169
int Current_key_down
Definition: key.cpp:423
void key_init()
Definition: key.cpp:864
int ascii_table[128]
Definition: key.cpp:72
#define KEY_F3
Definition: key.h:145
#define KEY_F9
Definition: key.h:151
#define KEY_L
Definition: key.h:93
#define KEY_F
Definition: key.h:87
int down_check[NUM_KEYS]
Definition: key.cpp:53
#define KEY_3
Definition: key.h:74
#define KEY_RBRACKET
Definition: key.h:119
#define KEY_RSHIFT
Definition: key.h:135