1 #define WIN32_LEAN_AND_MEAN
12 extern void PumpMessages(void);
14 // These are to kludge up a bit my slightly broken GCC directx port.
16 #define E_FAIL (HRESULT)0x80004005L
19 #define SUCCEEDED(a) ((HRESULT)(a) >= 0)
26 extern void PumpMessages(void);
28 volatile int keyd_time_when_last_pressed;
29 volatile unsigned char keyd_last_pressed;
30 volatile unsigned char keyd_last_released;
31 volatile unsigned char keyd_pressed [256];
32 unsigned char keyd_repeat;
33 unsigned char WMKey_Handler_Ready=0;
36 fix g_rgtimeDown [256];
37 fix g_rgtimeElapsed [256];
38 ULONG g_rgcDowns [256];
41 char ascii_table[256];
42 char shifted_ascii_table[256];
45 LPDIRECTINPUTDEVICE g_lpdidKeybd;
50 #define KEY_BUFFER_SIZE 16
52 ULONG g_rgbKeyQueue [KEY_BUFFER_SIZE];
53 fix g_rgtimeQueue [KEY_BUFFER_SIZE];
54 ULONG g_rgbPressedQueue [KEY_BUFFER_SIZE];
56 ULONG iQueueStart = 0;
59 KEYCODE ShiftKeyCode (KEYCODE kcKey)
63 if (keyd_pressed [kcKey])
68 if (keyd_pressed [KEY_LSHIFT] || keyd_pressed [KEY_RSHIFT])
70 kcShifted |= KEY_SHIFTED;
72 if (keyd_pressed [KEY_LCTRL] || keyd_pressed [KEY_RCTRL])
74 kcShifted |= KEY_CTRLED;
76 if (keyd_pressed [KEY_LALT] || keyd_pressed [KEY_RALT])
78 kcShifted |= KEY_ALTED;
93 return iQueueEnd != KEY_BUFFER_SIZE - 1;
97 return iQueueEnd != iQueueStart - 1;
101 void FlushQueue (void)
103 iQueueStart = iQueueEnd = 0;
106 void PushKey (ULONG kcKey, fix timeDown)
108 if (SpaceInBuffer ())
110 g_rgbKeyQueue [iQueueEnd] = ShiftKeyCode(kcKey);
111 g_rgtimeQueue [iQueueEnd] = timeDown;
113 if (iQueueEnd ++ == KEY_BUFFER_SIZE)
120 BOOL PopKey (KEYCODE *piKey, fix *ptimeDown)
122 if (iQueueEnd != iQueueStart)
124 // there are items in the queue
128 *piKey = g_rgbKeyQueue [iQueueStart];
130 if (ptimeDown != NULL)
132 *ptimeDown = g_rgbPressedQueue [iQueueStart];
135 if (iQueueStart ++ == KEY_BUFFER_SIZE)
148 static BOOL EnsureInit (void)
150 if (g_lpdidKeybd == NULL)
155 return g_lpdidKeybd != NULL;
158 void key_close(void);
163 // my kingdom, my kingdom for C++...
164 if (SUCCEEDED (hr = DirectInputCreate (GetModuleHandle (NULL), DIRECTINPUT_VERSION, &g_lpdi, NULL)))
166 if (SUCCEEDED (hr = IDirectInput_CreateDevice (g_lpdi, (void *)&GUID_SysKeyboard, &g_lpdidKeybd, NULL)))
170 dipdw.diph.dwSize = sizeof (DIPROPDWORD);
171 dipdw.diph.dwHeaderSize = sizeof (DIPROPHEADER);
172 dipdw.diph.dwObj = 0;
173 dipdw.diph.dwHow = DIPH_DEVICE;
176 if (SUCCEEDED (hr = IDirectInputDevice_SetDataFormat (g_lpdidKeybd, &c_dfDIKeyboard)) &&
177 SUCCEEDED (hr = IDirectInputDevice_SetCooperativeLevel (g_lpdidKeybd, g_hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND)) &&
178 SUCCEEDED (hr = IDirectInputDevice_SetProperty (g_lpdidKeybd, DIPROP_BUFFERSIZE, &dipdw.diph)) &&
179 SUCCEEDED (hr = IDirectInputDevice_Acquire (g_lpdidKeybd)))
182 WMKey_Handler_Ready = 1;
184 // Clear the keyboard array
191 IDirectInputDevice_Release (g_lpdidKeybd);
200 WMKey_Handler_Ready = 0;
201 if (g_lpdidKeybd != NULL)
203 IDirectInputDevice_Unacquire (g_lpdidKeybd);
204 IDirectInputDevice_Release (g_lpdidKeybd);
209 IDirectInput_Release (g_lpdi);
214 HRESULT ReadKey (DIDEVICEOBJECTDATA *pdidod)
218 if (g_lpdidKeybd == NULL)
220 hr = IDirectInputDevice_Acquire (g_lpdidKeybd);
223 hr = IDirectInputDevice_GetDeviceData (
229 if (SUCCEEDED (hr) && cElements != 1)
236 void UpdateState (DIDEVICEOBJECTDATA *pdidod)
238 KEYCODE kcKey = pdidod->dwOfs;
240 fix timeNow = timer_get_fixed_seconds ();
242 if (pdidod->dwData & 0x80)
244 keyd_pressed [kcKey] = 1;
245 keyd_last_pressed = kcKey;
246 g_rgtimeDown [kcKey] = keyd_time_when_last_pressed = timeNow;
247 g_rgcDowns [kcKey] ++;
248 PushKey (kcKey, keyd_time_when_last_pressed);
252 keyd_pressed [kcKey] = 0;
253 keyd_last_released = kcKey;
255 g_rgtimeElapsed [kcKey] = timeNow - g_rgtimeDown [kcKey];
259 void keyboard_handler()
261 // static int peekmsgcount = 0;
262 DIDEVICEOBJECTDATA didod;
263 while (SUCCEEDED (ReadKey (&didod)))
265 UpdateState (&didod);
267 //added 02/20/99 by adb to prevent message overflow
268 //(this should probably go somewhere else...)
269 // if (++peekmsgcount == 64) // 64 = wild guess...
284 DWORD cElements = INFINITE;
287 IDirectInputDevice_GetDeviceData(
289 sizeof (DIDEVICEOBJECTDATA),
294 for (kcKey = 0; kcKey < 256; kcKey ++)
296 g_rgtimeElapsed [kcKey] = 0;
297 g_rgcDowns [kcKey] = 0;
298 g_rgcUps [kcKey] = 0;
299 keyd_pressed [kcKey] = 0;
310 while (!PopKey (&kcKey, NULL))
318 KEYCODE key_inkey_time(fix * pTime)
324 PopKey (&kcKey, pTime);
331 return key_inkey_time (NULL);
334 KEYCODE key_peekkey ()
345 unsigned char key_to_ascii(KEYCODE kcKey )
347 BOOL bShifted = kcKey & KEY_SHIFTED;
350 kcKey &= ~KEY_SHIFTED;
356 ch = shifted_ascii_table [kcKey & 0xff];
360 ch = ascii_table [kcKey & 0xff];
371 // Returns the number of seconds this key has been down since last call.
372 fix key_down_time(KEYCODE kcKey)
376 if ((kcKey<0) || (kcKey>127)) return 0;
378 if (keyd_pressed [kcKey])
380 fix timeNow = timer_get_fixed_seconds ();
381 timeElapsed = timeNow - g_rgtimeDown [kcKey];
382 g_rgtimeDown [kcKey] = timeNow;
386 timeElapsed = g_rgtimeElapsed [kcKey];
387 g_rgtimeElapsed [kcKey] = 0;
394 unsigned int key_down_count(KEYCODE kcKey)
398 if ((kcKey < 0) || (kcKey > 127))
404 n = g_rgcDowns [kcKey];
405 g_rgcDowns [kcKey] = 0;
411 unsigned int key_up_count(KEYCODE kcKey)
416 if ((kcKey < 0) || (kcKey > 127))
422 n = g_rgcUps [kcKey];
423 g_rgcUps [kcKey] = 0;
430 #define ___ ((char) 255)
431 char ascii_table[256] =
433 ___, ___, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', ___, ___,
434 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', ___, ___, 'a', 's',
435 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';','\'', '`', ___,'\\', 'z', 'x', 'c', 'v',
436 'b', 'n', 'm', ',', '.', '/', ___, '*', ___, ' ', ___, ___, ___, ___, ___, ___,
437 ___, ___, ___, ___, ___, ___, ___, '7', '8', '9', '-', '4', '5', '6', '+', '1',
438 '2', '3', '0', '.', ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___,
439 ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___,
440 ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___,
443 char shifted_ascii_table[256] =
445 ___, ___, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', ___, ___,
446 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', ___, ___, 'A', 'S',
447 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':','\"', '~', ___, '|', 'Z', 'X', 'C', 'V',
448 'B', 'N', 'M', '<', '>', '?', ___, '*', ___, ' ', ___, ___, ___, ___, ___, ___,
449 ___, ___, ___, ___, ___, ___, ___, '&', '*', '(', '_', '$', '%', '^', '=', '!',
450 '@', '#', ')', '>', ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___,
451 ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___,
452 ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___,
456 char * key_text[256] = {
457 "","ESC","1","2","3","4","5","6","7","8","9","0","-",
458 "=","BSPC","TAB","Q","W","E","R","T","Y","U","I","O",
459 "P","[","]","
\83","LCTRL","A","S","D","F",
460 "G","H","J","K","L",";","'","`",
461 "LSHFT","\\","Z","X","C","V","B","N","M",",",
462 ".","/","RSHFT","PAD*","LALT","SPC",
463 "CPSLK","F1","F2","F3","F4","F5","F6","F7","F8","F9",
464 "F10","NMLCK","SCLK","PAD7","PAD8","PAD9","PAD-",
465 "PAD4","PAD5","PAD6","PAD+","PAD1","PAD2","PAD3","PAD0",
466 "PAD.","","","","F11","F12","","","","","","","","","",
467 "","","","","","","","","","","","","","","","","","","","",
468 "","","","","","","","","","","","","","","","","","","","",
469 "","","","","","","","","","","","","","","","","","",
470 "PAD
\83","RCTRL","","","","","","","","","","","","","",
471 "","","","","","","","","","","PAD/","","","RALT","",
472 "","","","","","","","","","","","","","HOME","
\82","PGUP",
473 "","
\81","","
\7f","","END","
\80","PGDN","INS",
474 "DEL","","","","","","","","","","","","","","","","","",
475 "","","","","","","","","","","","","","","","","","","","",
476 "","","","","","","" };
477 #if 0 // what was this? -- adb
478 "","","","HOME","UP","PGUP","","LEFT","","RGHT","","END","DOWN","PGDN","INS","DEL",
479 "","
\81","","
\7f","","","?","","",
480 "","","","","","","","","","","","","","","","","","",
481 "","","","","","","","","","","","","","","","","","","","",
482 "","","","","","","" };