1 #define WIN32_LEAN_AND_MEAN
10 extern void PumpMessages(void);
12 // These are to kludge up a bit my slightly broken GCC directx port.
14 #define E_FAIL (HRESULT)0x80004005L
17 #define SUCCEEDED(a) ((HRESULT)(a) >= 0)
24 extern void PumpMessages(void);
26 volatile int keyd_time_when_last_pressed;
27 volatile unsigned char keyd_last_pressed;
28 volatile unsigned char keyd_last_released;
29 volatile unsigned char keyd_pressed [256];
30 unsigned char keyd_repeat;
31 unsigned char WMKey_Handler_Ready=0;
34 fix g_rgtimeDown [256];
35 fix g_rgtimeElapsed [256];
36 ULONG g_rgcDowns [256];
39 char ascii_table[256];
40 char shifted_ascii_table[256];
43 LPDIRECTINPUTDEVICE g_lpdidKeybd;
48 #define KEY_BUFFER_SIZE 16
50 ULONG g_rgbKeyQueue [KEY_BUFFER_SIZE];
51 fix g_rgtimeQueue [KEY_BUFFER_SIZE];
52 ULONG g_rgbPressedQueue [KEY_BUFFER_SIZE];
54 ULONG iQueueStart = 0;
57 KEYCODE ShiftKeyCode (KEYCODE kcKey)
61 if (keyd_pressed [kcKey])
66 if (keyd_pressed [KEY_LSHIFT] || keyd_pressed [KEY_RSHIFT])
68 kcShifted |= KEY_SHIFTED;
70 if (keyd_pressed [KEY_LCTRL] || keyd_pressed [KEY_RCTRL])
72 kcShifted |= KEY_CTRLED;
74 if (keyd_pressed [KEY_LALT] || keyd_pressed [KEY_RALT])
76 kcShifted |= KEY_ALTED;
91 return iQueueEnd != KEY_BUFFER_SIZE - 1;
95 return iQueueEnd != iQueueStart - 1;
99 void FlushQueue (void)
101 iQueueStart = iQueueEnd = 0;
104 void PushKey (ULONG kcKey, fix timeDown)
106 if (SpaceInBuffer ())
108 g_rgbKeyQueue [iQueueEnd] = ShiftKeyCode(kcKey);
109 g_rgtimeQueue [iQueueEnd] = timeDown;
111 if (iQueueEnd ++ == KEY_BUFFER_SIZE)
118 BOOL PopKey (KEYCODE *piKey, fix *ptimeDown)
120 if (iQueueEnd != iQueueStart)
122 // there are items in the queue
126 *piKey = g_rgbKeyQueue [iQueueStart];
128 if (ptimeDown != NULL)
130 *ptimeDown = g_rgbPressedQueue [iQueueStart];
133 if (iQueueStart ++ == KEY_BUFFER_SIZE)
146 static BOOL EnsureInit (void)
148 if (g_lpdidKeybd == NULL)
153 return g_lpdidKeybd != NULL;
156 void key_close(void);
161 // my kingdom, my kingdom for C++...
162 if (SUCCEEDED (hr = DirectInputCreate (GetModuleHandle (NULL), DIRECTINPUT_VERSION, &g_lpdi, NULL)))
164 if (SUCCEEDED (hr = IDirectInput_CreateDevice (g_lpdi, (void *)&GUID_SysKeyboard, &g_lpdidKeybd, NULL)))
168 dipdw.diph.dwSize = sizeof (DIPROPDWORD);
169 dipdw.diph.dwHeaderSize = sizeof (DIPROPHEADER);
170 dipdw.diph.dwObj = 0;
171 dipdw.diph.dwHow = DIPH_DEVICE;
174 if (SUCCEEDED (hr = IDirectInputDevice_SetDataFormat (g_lpdidKeybd, &c_dfDIKeyboard)) &&
175 SUCCEEDED (hr = IDirectInputDevice_SetCooperativeLevel (g_lpdidKeybd, g_hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND)) &&
176 SUCCEEDED (hr = IDirectInputDevice_SetProperty (g_lpdidKeybd, DIPROP_BUFFERSIZE, &dipdw.diph)) &&
177 SUCCEEDED (hr = IDirectInputDevice_Acquire (g_lpdidKeybd)))
180 WMKey_Handler_Ready = 1;
182 // Clear the keyboard array
189 IDirectInputDevice_Release (g_lpdidKeybd);
198 WMKey_Handler_Ready = 0;
199 if (g_lpdidKeybd != NULL)
201 IDirectInputDevice_Unacquire (g_lpdidKeybd);
202 IDirectInputDevice_Release (g_lpdidKeybd);
207 IDirectInput_Release (g_lpdi);
212 HRESULT ReadKey (DIDEVICEOBJECTDATA *pdidod)
216 if (g_lpdidKeybd == NULL)
218 hr = IDirectInputDevice_Acquire (g_lpdidKeybd);
221 hr = IDirectInputDevice_GetDeviceData (
227 if (SUCCEEDED (hr) && cElements != 1)
234 void UpdateState (DIDEVICEOBJECTDATA *pdidod)
236 KEYCODE kcKey = pdidod->dwOfs;
238 fix timeNow = timer_get_fixed_seconds ();
240 if (pdidod->dwData & 0x80)
242 keyd_pressed [kcKey] = 1;
243 keyd_last_pressed = kcKey;
244 g_rgtimeDown [kcKey] = keyd_time_when_last_pressed = timeNow;
245 g_rgcDowns [kcKey] ++;
246 PushKey (kcKey, keyd_time_when_last_pressed);
250 keyd_pressed [kcKey] = 0;
251 keyd_last_released = kcKey;
253 g_rgtimeElapsed [kcKey] = timeNow - g_rgtimeDown [kcKey];
257 void keyboard_handler()
259 // static int peekmsgcount = 0;
260 DIDEVICEOBJECTDATA didod;
261 while (SUCCEEDED (ReadKey (&didod)))
263 UpdateState (&didod);
265 //added 02/20/99 by adb to prevent message overflow
266 //(this should probably go somewhere else...)
267 // if (++peekmsgcount == 64) // 64 = wild guess...
282 ULONG cElements = INFINITE;
285 IDirectInputDevice_GetDeviceData (
287 sizeof (DIDEVICEOBJECTDATA),
292 for (kcKey = 0; kcKey < 256; kcKey ++)
294 g_rgtimeElapsed [kcKey] = 0;
295 g_rgcDowns [kcKey] = 0;
296 g_rgcUps [kcKey] = 0;
297 keyd_pressed [kcKey] = 0;
308 while (!PopKey (&kcKey, NULL))
316 KEYCODE key_inkey_time(fix * pTime)
322 PopKey (&kcKey, pTime);
329 return key_inkey_time (NULL);
332 KEYCODE key_peekkey ()
343 unsigned char key_to_ascii(KEYCODE kcKey )
345 BOOL bShifted = kcKey & KEY_SHIFTED;
348 kcKey &= ~KEY_SHIFTED;
354 ch = shifted_ascii_table [kcKey & 0xff];
358 ch = ascii_table [kcKey & 0xff];
369 // Returns the number of seconds this key has been down since last call.
370 fix key_down_time(KEYCODE kcKey)
374 if ((kcKey<0) || (kcKey>127)) return 0;
376 if (keyd_pressed [kcKey])
378 fix timeNow = timer_get_fixed_seconds ();
379 timeElapsed = timeNow - g_rgtimeDown [kcKey];
380 g_rgtimeDown [kcKey] = timeNow;
384 timeElapsed = g_rgtimeElapsed [kcKey];
385 g_rgtimeElapsed [kcKey] = 0;
392 unsigned int key_down_count(KEYCODE kcKey)
396 if ((kcKey < 0) || (kcKey > 127))
402 n = g_rgcDowns [kcKey];
403 g_rgcDowns [kcKey] = 0;
409 unsigned int key_up_count(KEYCODE kcKey)
414 if ((kcKey < 0) || (kcKey > 127))
420 n = g_rgcUps [kcKey];
421 g_rgcUps [kcKey] = 0;
428 #define ___ ((char) 255)
429 char ascii_table[256] =
431 ___, ___, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', ___, ___,
432 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', ___, ___, 'a', 's',
433 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';','\'', '`', ___,'\\', 'z', 'x', 'c', 'v',
434 'b', 'n', 'm', ',', '.', '/', ___, '*', ___, ___, ___, ___, ___, ___, ___, ___,
435 ___, ___, ___, ___, ___, ___, ___, '7', '8', '9', '-', '4', '5', '6', '+', '1',
436 '2', '3', '0', '.', ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___,
437 ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___,
438 ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___,
441 char shifted_ascii_table[256] =
443 ___, ___, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', ___, ___,
444 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', ___, ___, 'A', 'S',
445 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':','\"', '~', ___, '|', 'Z', 'X', 'C', 'V',
446 'B', 'N', 'M', '<', '>', '?', ___, '*', ___, ___, ___, ___, ___, ___, ___, ___,
447 ___, ___, ___, ___, ___, ___, ___, '&', '*', '(', '_', '$', '%', '^', '=', '!',
448 '@', '#', ')', '>', ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___,
449 ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___,
450 ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___,
454 char * key_text[256] = {
455 "","ESC","1","2","3","4","5","6","7","8","9","0","-",
456 "=","BSPC","TAB","Q","W","E","R","T","Y","U","I","O",
457 "P","[","]","
\83","LCTRL","A","S","D","F",
458 "G","H","J","K","L",";","'","`",
459 "LSHFT","\\","Z","X","C","V","B","N","M",",",
460 ".","/","RSHFT","PAD*","LALT","SPC",
461 "CPSLK","F1","F2","F3","F4","F5","F6","F7","F8","F9",
462 "F10","NMLCK","SCLK","PAD7","PAD8","PAD9","PAD-",
463 "PAD4","PAD5","PAD6","PAD+","PAD1","PAD2","PAD3","PAD0",
464 "PAD.","","","","F11","F12","","","","","","","","","",
465 "","","","","","","","","","","","","","","","","","","","",
466 "","","","","","","","","","","","","","","","","","","","",
467 "","","","","","","","","","","","","","","","","","",
468 "PAD
\83","RCTRL","","","","","","","","","","","","","",
469 "","","","","","","","","","","PAD/","","","RALT","",
470 "","","","","","","","","","","","","","HOME","
\82","PGUP",
471 "","
\81","","
\7f","","END","
\80","PGDN","INS",
472 "DEL","","","","","","","","","","","","","","","","","",
473 "","","","","","","","","","","","","","","","","","","","",
474 "","","","","","","" };
475 #if 0 // what was this? -- adb
476 "","","","HOME","UP","PGUP","","LEFT","","RGHT","","END","DOWN","PGDN","INS","DEL",
477 "","
\81","","
\7f","","","?","","",
478 "","","","","","","","","","","","","","","","","","",
479 "","","","","","","","","","","","","","","","","","","","",
480 "","","","","","","" };