Mercurial > vba-clojure
comparison src/win32/DirectInput.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:8ced16adf2e1 | 1:f9f4f1b99eed |
---|---|
1 //#define USE_GETASYNCKEYSTATE_FOR_KEYBOARD | |
2 | |
3 #include "stdafx.h" | |
4 | |
5 #define DIRECTINPUT_VERSION 0x0500 | |
6 #include "dinput.h" | |
7 | |
8 #include "resource.h" | |
9 #include "Input.h" | |
10 #include "Reg.h" | |
11 #include "WinResUtil.h" | |
12 | |
13 // master keyboard translation table | |
14 static const struct { | |
15 int dik; | |
16 int vk; | |
17 int ascii; | |
18 } win_key_trans_table[] = { | |
19 // dinput key virtual key ascii | |
20 { DIK_ESCAPE, VK_ESCAPE, 27 }, | |
21 { DIK_1, '1', '1' }, | |
22 { DIK_2, '2', '2' }, | |
23 { DIK_3, '3', '3' }, | |
24 { DIK_4, '4', '4' }, | |
25 { DIK_5, '5', '5' }, | |
26 { DIK_6, '6', '6' }, | |
27 { DIK_7, '7', '7' }, | |
28 { DIK_8, '8', '8' }, | |
29 { DIK_9, '9', '9' }, | |
30 { DIK_0, '0', '0' }, | |
31 { DIK_MINUS, VK_OEM_MINUS, '-' }, | |
32 { DIK_EQUALS, VK_OEM_PLUS, '=' }, | |
33 { DIK_BACK, VK_BACK, 8 }, | |
34 { DIK_TAB, VK_TAB, 9 }, | |
35 { DIK_Q, 'Q', 'Q' }, | |
36 { DIK_W, 'W', 'W' }, | |
37 { DIK_E, 'E', 'E' }, | |
38 { DIK_R, 'R', 'R' }, | |
39 { DIK_T, 'T', 'T' }, | |
40 { DIK_Y, 'Y', 'Y' }, | |
41 { DIK_U, 'U', 'U' }, | |
42 { DIK_I, 'I', 'I' }, | |
43 { DIK_O, 'O', 'O' }, | |
44 { DIK_P, 'P', 'P' }, | |
45 { DIK_LBRACKET, VK_OEM_4, '[' }, | |
46 { DIK_RBRACKET, VK_OEM_6, ']' }, | |
47 { DIK_RETURN, VK_RETURN, 13 }, | |
48 { DIK_LCONTROL, VK_LCONTROL, 0 }, | |
49 { DIK_A, 'A', 'A' }, | |
50 { DIK_S, 'S', 'S' }, | |
51 { DIK_D, 'D', 'D' }, | |
52 { DIK_F, 'F', 'F' }, | |
53 { DIK_G, 'G', 'G' }, | |
54 { DIK_H, 'H', 'H' }, | |
55 { DIK_J, 'J', 'J' }, | |
56 { DIK_K, 'K', 'K' }, | |
57 { DIK_L, 'L', 'L' }, | |
58 { DIK_SEMICOLON, VK_OEM_1, ';' }, | |
59 { DIK_APOSTROPHE, VK_OEM_7, '\'' }, | |
60 { DIK_GRAVE, VK_OEM_3, '`' }, | |
61 { DIK_LSHIFT, VK_LSHIFT, 0 }, | |
62 { DIK_BACKSLASH, VK_OEM_5, '\\' }, | |
63 { DIK_Z, 'Z', 'Z' }, | |
64 { DIK_X, 'X', 'X' }, | |
65 { DIK_C, 'C', 'C' }, | |
66 { DIK_V, 'V', 'V' }, | |
67 { DIK_B, 'B', 'B' }, | |
68 { DIK_N, 'N', 'N' }, | |
69 { DIK_M, 'M', 'M' }, | |
70 { DIK_COMMA, VK_OEM_COMMA, ',' }, | |
71 { DIK_PERIOD, VK_OEM_PERIOD, '.' }, | |
72 { DIK_SLASH, VK_OEM_2, '/' }, | |
73 { DIK_RSHIFT, VK_RSHIFT, 0 }, | |
74 { DIK_MULTIPLY, VK_MULTIPLY, '*' }, | |
75 { DIK_LMENU, VK_LMENU, 0 }, | |
76 { DIK_SPACE, VK_SPACE, ' ' }, | |
77 { DIK_CAPITAL, VK_CAPITAL, 0 }, | |
78 { DIK_F1, VK_F1, 0 }, | |
79 { DIK_F2, VK_F2, 0 }, | |
80 { DIK_F3, VK_F3, 0 }, | |
81 { DIK_F4, VK_F4, 0 }, | |
82 { DIK_F5, VK_F5, 0 }, | |
83 { DIK_F6, VK_F6, 0 }, | |
84 { DIK_F7, VK_F7, 0 }, | |
85 { DIK_F8, VK_F8, 0 }, | |
86 { DIK_F9, VK_F9, 0 }, | |
87 { DIK_F10, VK_F10, 0 }, | |
88 { DIK_NUMLOCK, VK_NUMLOCK, 0 }, | |
89 { DIK_SCROLL, VK_SCROLL, 0 }, | |
90 { DIK_NUMPAD7, VK_NUMPAD7, 0 }, | |
91 { DIK_NUMPAD8, VK_NUMPAD8, 0 }, | |
92 { DIK_NUMPAD9, VK_NUMPAD9, 0 }, | |
93 { DIK_SUBTRACT, VK_SUBTRACT, 0 }, | |
94 { DIK_NUMPAD4, VK_NUMPAD4, 0 }, | |
95 { DIK_NUMPAD5, VK_NUMPAD5, 0 }, | |
96 { DIK_NUMPAD6, VK_NUMPAD6, 0 }, | |
97 { DIK_ADD, VK_ADD, 0 }, | |
98 { DIK_NUMPAD1, VK_NUMPAD1, 0 }, | |
99 { DIK_NUMPAD2, VK_NUMPAD2, 0 }, | |
100 { DIK_NUMPAD3, VK_NUMPAD3, 0 }, | |
101 { DIK_NUMPAD0, VK_NUMPAD0, 0 }, | |
102 { DIK_DECIMAL, VK_DECIMAL, 0 }, | |
103 { DIK_F11, VK_F11, 0 }, | |
104 { DIK_F12, VK_F12, 0 }, | |
105 { DIK_F13, VK_F13, 0 }, | |
106 { DIK_F14, VK_F14, 0 }, | |
107 { DIK_F15, VK_F15, 0 }, | |
108 { DIK_NUMPADENTER, VK_RETURN, 0 }, | |
109 { DIK_RCONTROL, VK_RCONTROL, 0 }, | |
110 { DIK_DIVIDE, VK_DIVIDE, 0 }, | |
111 { DIK_SYSRQ, 0, 0 }, | |
112 { DIK_RMENU, VK_RMENU, 0 }, | |
113 { DIK_HOME, VK_HOME, 0 }, | |
114 { DIK_UP, VK_UP, 0 }, | |
115 { DIK_PRIOR, VK_PRIOR, 0 }, | |
116 { DIK_LEFT, VK_LEFT, 0 }, | |
117 { DIK_RIGHT, VK_RIGHT, 0 }, | |
118 { DIK_END, VK_END, 0 }, | |
119 { DIK_DOWN, VK_DOWN, 0 }, | |
120 { DIK_NEXT, VK_NEXT, 0 }, | |
121 { DIK_INSERT, VK_INSERT, 0 }, | |
122 { DIK_DELETE, VK_DELETE, 0 }, | |
123 { DIK_LWIN, VK_LWIN, 0 }, | |
124 { DIK_RWIN, VK_RWIN, 0 }, | |
125 { DIK_APPS, VK_APPS, 0 }, | |
126 { DIK_PAUSE, VK_PAUSE, 0 }, | |
127 { 0, VK_CANCEL, 0 }, | |
128 | |
129 // New keys introduced in Windows 2000. These have no MAME codes to | |
130 // preserve compatibility with old config files that may refer to them | |
131 // as e.g. FORWARD instead of e.g. KEYCODE_WEBFORWARD. They need table | |
132 // entries anyway because otherwise they aren't recognized when | |
133 // GetAsyncKeyState polling is used (as happens currently when MAME is | |
134 // paused). Some codes are missing because the mapping to vkey codes | |
135 // isn't clear, and MapVirtualKey is no help. | |
136 | |
137 { DIK_MUTE, VK_VOLUME_MUTE, 0 }, | |
138 { DIK_VOLUMEDOWN, VK_VOLUME_DOWN, 0 }, | |
139 { DIK_VOLUMEUP, VK_VOLUME_UP, 0 }, | |
140 { DIK_WEBHOME, VK_BROWSER_HOME, 0 }, | |
141 { DIK_WEBSEARCH, VK_BROWSER_SEARCH, 0 }, | |
142 { DIK_WEBFAVORITES, VK_BROWSER_FAVORITES, 0 }, | |
143 { DIK_WEBREFRESH, VK_BROWSER_REFRESH, 0 }, | |
144 { DIK_WEBSTOP, VK_BROWSER_STOP, 0 }, | |
145 { DIK_WEBFORWARD, VK_BROWSER_FORWARD, 0 }, | |
146 { DIK_WEBBACK, VK_BROWSER_BACK, 0 }, | |
147 { DIK_MAIL, VK_LAUNCH_MAIL, 0 }, | |
148 { DIK_MEDIASELECT, VK_LAUNCH_MEDIA_SELECT, 0 }, | |
149 }; | |
150 | |
151 extern void directXMessage(const char *); | |
152 extern void winlog(const char *msg, ...); | |
153 | |
154 #define POV_UP 1 | |
155 #define POV_DOWN 2 | |
156 #define POV_RIGHT 4 | |
157 #define POV_LEFT 8 | |
158 | |
159 class DirectInput : public Input | |
160 { | |
161 private: | |
162 HINSTANCE dinputDLL; | |
163 public: | |
164 virtual void checkDevices(); | |
165 DirectInput(); | |
166 virtual ~DirectInput(); | |
167 | |
168 virtual bool initialize(); | |
169 virtual bool readDevices(); | |
170 virtual u32 readDevice(int which, bool sensor); | |
171 virtual CString getKeyName(LONG_PTR key); | |
172 virtual void checkKeys(); | |
173 virtual void activate(); | |
174 virtual void loadSettings(); | |
175 virtual void saveSettings(); | |
176 }; | |
177 | |
178 struct deviceInfo | |
179 { | |
180 LPDIRECTINPUTDEVICE device; | |
181 BOOL isPolled; | |
182 int nButtons; | |
183 int nAxes; | |
184 int nPovs; | |
185 BOOL first; | |
186 struct | |
187 { | |
188 DWORD offset; | |
189 LONG center; | |
190 LONG negative; | |
191 LONG positive; | |
192 } axis[8]; | |
193 int needed; | |
194 union | |
195 { | |
196 UCHAR data[256]; | |
197 DIJOYSTATE state; | |
198 }; | |
199 }; | |
200 | |
201 static deviceInfo * currentDevice = NULL; | |
202 static int numDevices = 1; | |
203 static deviceInfo * pDevices = NULL; | |
204 static LPDIRECTINPUT pDirectInput = NULL; | |
205 static int joyDebug = 0; | |
206 static int axisNumber = 0; | |
207 | |
208 USHORT joypad[4][13] = { | |
209 { | |
210 DIK_LEFT, DIK_RIGHT, | |
211 DIK_UP, DIK_DOWN, | |
212 DIK_Z, DIK_X, | |
213 DIK_RETURN, DIK_BACK, | |
214 DIK_A, DIK_S, | |
215 DIK_SPACE, DIK_F12, | |
216 DIK_C | |
217 }, | |
218 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | |
219 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | |
220 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } | |
221 }; | |
222 | |
223 USHORT motion[4] = { | |
224 DIK_NUMPAD4, DIK_NUMPAD6, DIK_NUMPAD8, DIK_NUMPAD2 | |
225 }; | |
226 | |
227 static int winReadKey(char *name, int num) | |
228 { | |
229 char buffer[80]; | |
230 | |
231 sprintf(buffer, "Joy%d_%s", num, name); | |
232 | |
233 return regQueryDwordValue(buffer, (DWORD)-1); | |
234 } | |
235 | |
236 void winReadKeys() | |
237 { | |
238 int key = -1; | |
239 | |
240 for (int i = 0; i < 4; i++) | |
241 { | |
242 key = winReadKey("Left", i); | |
243 if (key != -1) | |
244 joypad[i][KEY_LEFT] = key; | |
245 key = winReadKey("Right", i); | |
246 if (key != -1) | |
247 joypad[i][KEY_RIGHT] = key; | |
248 key = winReadKey("Up", i); | |
249 if (key != -1) | |
250 joypad[i][KEY_UP] = key; | |
251 key = winReadKey("Down", i); | |
252 if (key != -1) | |
253 joypad[i][KEY_DOWN] = key; | |
254 key = winReadKey("A", i); | |
255 if (key != -1) | |
256 joypad[i][KEY_BUTTON_A] = key; | |
257 key = winReadKey("B", i); | |
258 if (key != -1) | |
259 joypad[i][KEY_BUTTON_B] = key; | |
260 key = winReadKey("L", i); | |
261 if (key != -1) | |
262 joypad[i][KEY_BUTTON_L] = key; | |
263 key = winReadKey("R", i); | |
264 if (key != -1) | |
265 joypad[i][KEY_BUTTON_R] = key; | |
266 key = winReadKey("Start", i); | |
267 if (key != -1) | |
268 joypad[i][KEY_BUTTON_START] = key; | |
269 key = winReadKey("Select", i); | |
270 if (key != -1) | |
271 joypad[i][KEY_BUTTON_SELECT] = key; | |
272 key = winReadKey("Speed", i); | |
273 if (key != -1) | |
274 joypad[i][KEY_BUTTON_SPEED] = key; | |
275 key = winReadKey("Capture", i); | |
276 if (key != -1) | |
277 joypad[i][KEY_BUTTON_CAPTURE] = key; | |
278 key = winReadKey("GS", i); | |
279 if (key != -1) | |
280 joypad[i][KEY_BUTTON_GS] = key; | |
281 } | |
282 key = regQueryDwordValue("Motion_Left", (DWORD)-1); | |
283 if (key != -1) | |
284 motion[KEY_LEFT] = key; | |
285 key = regQueryDwordValue("Motion_Right", (DWORD)-1); | |
286 if (key != -1) | |
287 motion[KEY_RIGHT] = key; | |
288 key = regQueryDwordValue("Motion_Up", (DWORD)-1); | |
289 if (key != -1) | |
290 motion[KEY_UP] = key; | |
291 key = regQueryDwordValue("Motion_Down", (DWORD)-1); | |
292 if (key != -1) | |
293 motion[KEY_DOWN] = key; | |
294 } | |
295 | |
296 static void winSaveKey(char *name, int num, USHORT value) | |
297 { | |
298 char buffer[80]; | |
299 | |
300 sprintf(buffer, "Joy%d_%s", num, name); | |
301 | |
302 regSetDwordValue(buffer, value); | |
303 } | |
304 | |
305 void winSaveKeys() | |
306 { | |
307 for (int i = 0; i < 4; i++) | |
308 { | |
309 winSaveKey("Left", i, joypad[i][KEY_LEFT]); | |
310 winSaveKey("Right", i, joypad[i][KEY_RIGHT]); | |
311 winSaveKey("Up", i, joypad[i][KEY_UP]); | |
312 winSaveKey("Speed", i, joypad[i][KEY_BUTTON_SPEED]); | |
313 winSaveKey("Capture", i, joypad[i][KEY_BUTTON_CAPTURE]); | |
314 winSaveKey("GS", i, joypad[i][KEY_BUTTON_GS]); | |
315 winSaveKey("Down", i, joypad[i][KEY_DOWN]); | |
316 winSaveKey("A", i, joypad[i][KEY_BUTTON_A]); | |
317 winSaveKey("B", i, joypad[i][KEY_BUTTON_B]); | |
318 winSaveKey("L", i, joypad[i][KEY_BUTTON_L]); | |
319 winSaveKey("R", i, joypad[i][KEY_BUTTON_R]); | |
320 winSaveKey("Start", i, joypad[i][KEY_BUTTON_START]); | |
321 winSaveKey("Select", i, joypad[i][KEY_BUTTON_SELECT]); | |
322 } | |
323 regSetDwordValue("joyVersion", 1); | |
324 | |
325 regSetDwordValue("Motion_Left", | |
326 motion[KEY_LEFT]); | |
327 regSetDwordValue("Motion_Right", | |
328 motion[KEY_RIGHT]); | |
329 regSetDwordValue("Motion_Up", | |
330 motion[KEY_UP]); | |
331 regSetDwordValue("Motion_Down", | |
332 motion[KEY_DOWN]); | |
333 } | |
334 | |
335 static BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE*pdidoi, | |
336 VOID*pContext) | |
337 { | |
338 DIPROPRANGE diprg; | |
339 diprg.diph.dwSize = sizeof(DIPROPRANGE); | |
340 diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); | |
341 diprg.diph.dwHow = DIPH_BYOFFSET; | |
342 diprg.diph.dwObj = pdidoi->dwOfs; // Specify the enumerated axis | |
343 | |
344 diprg.lMin = -32768; | |
345 diprg.lMax = 32767; | |
346 // try to set the range | |
347 if (FAILED(currentDevice->device->SetProperty(DIPROP_RANGE, &diprg.diph))) | |
348 { | |
349 // Get the range for the axis | |
350 if (FAILED(currentDevice->device-> | |
351 GetProperty(DIPROP_RANGE, &diprg.diph))) | |
352 { | |
353 return DIENUM_STOP; | |
354 } | |
355 } | |
356 | |
357 DIPROPDWORD didz; | |
358 | |
359 didz.diph.dwSize = sizeof(didz); | |
360 didz.diph.dwHeaderSize = sizeof(DIPROPHEADER); | |
361 didz.diph.dwHow = DIPH_BYOFFSET; | |
362 didz.diph.dwObj = pdidoi->dwOfs; | |
363 | |
364 didz.dwData = 5000; | |
365 | |
366 currentDevice->device->SetProperty(DIPROP_DEADZONE, &didz.diph); | |
367 | |
368 LONG center = (diprg.lMin + diprg.lMax)/2; | |
369 LONG threshold = (diprg.lMax - center)/2; | |
370 | |
371 // only 8 axis supported | |
372 if (axisNumber < 8) | |
373 { | |
374 currentDevice->axis[axisNumber].center = center; | |
375 currentDevice->axis[axisNumber].negative = center - threshold; | |
376 currentDevice->axis[axisNumber].positive = center + threshold; | |
377 currentDevice->axis[axisNumber].offset = pdidoi->dwOfs; | |
378 } | |
379 axisNumber++; | |
380 return DIENUM_CONTINUE; | |
381 } | |
382 | |
383 static BOOL CALLBACK EnumPovsCallback(const DIDEVICEOBJECTINSTANCE*pdidoi, | |
384 VOID*pContext) | |
385 { | |
386 return DIENUM_CONTINUE; | |
387 } | |
388 | |
389 static BOOL CALLBACK DIEnumDevicesCallback(LPCDIDEVICEINSTANCE pInst, | |
390 LPVOID lpvContext) | |
391 { | |
392 ZeroMemory(&pDevices[numDevices], sizeof(deviceInfo)); | |
393 | |
394 HRESULT hRet = pDirectInput->CreateDevice(pInst->guidInstance, | |
395 &pDevices[numDevices].device, | |
396 NULL); | |
397 | |
398 if (hRet != DI_OK) | |
399 return DIENUM_STOP; | |
400 | |
401 DIDEVCAPS caps; | |
402 caps.dwSize = sizeof(DIDEVCAPS); | |
403 | |
404 hRet = pDevices[numDevices].device->GetCapabilities(&caps); | |
405 | |
406 if (hRet == DI_OK) | |
407 { | |
408 if (caps.dwFlags & DIDC_POLLEDDATAFORMAT || | |
409 caps.dwFlags & DIDC_POLLEDDEVICE) | |
410 pDevices[numDevices].isPolled = TRUE; | |
411 | |
412 pDevices[numDevices].nButtons = caps.dwButtons; | |
413 pDevices[numDevices].nAxes = caps.dwAxes; | |
414 pDevices[numDevices].nPovs = caps.dwPOVs; | |
415 | |
416 for (int i = 0; i < 6; i++) | |
417 { | |
418 pDevices[numDevices].axis[i].center = 0x8000; | |
419 pDevices[numDevices].axis[i].negative = 0x4000; | |
420 pDevices[numDevices].axis[i].positive = 0xc000; | |
421 } | |
422 } | |
423 else if (joyDebug) | |
424 winlog("Failed to get device capabilities %08x\n", hRet); | |
425 | |
426 if (joyDebug) | |
427 { | |
428 // don't translate. debug only | |
429 winlog("******************************\n"); | |
430 winlog("Joystick %2d name : %s\n", numDevices, pInst->tszProductName); | |
431 } | |
432 | |
433 numDevices++; | |
434 | |
435 return DIENUM_CONTINUE; | |
436 } | |
437 | |
438 BOOL CALLBACK DIEnumDevicesCallback2(LPCDIDEVICEINSTANCE pInst, | |
439 LPVOID lpvContext) | |
440 { | |
441 numDevices++; | |
442 | |
443 return DIENUM_CONTINUE; | |
444 } | |
445 | |
446 static int getPovState(DWORD value) | |
447 { | |
448 int state = 0; | |
449 if (LOWORD(value) != 0xFFFF) | |
450 { | |
451 if (value < 9000 || value > 27000) | |
452 state |= POV_UP; | |
453 if (value > 0 && value < 18000) | |
454 state |= POV_RIGHT; | |
455 if (value > 9000 && value < 27000) | |
456 state |= POV_DOWN; | |
457 if (value > 18000) | |
458 state |= POV_LEFT; | |
459 } | |
460 return state; | |
461 } | |
462 | |
463 static void checkKeys() | |
464 { | |
465 LONG_PTR dev = 0; | |
466 int i; | |
467 | |
468 for (i = 0; i < numDevices; i++) | |
469 pDevices[i].needed = 0; | |
470 | |
471 for (i = 0; i < 4; i++) | |
472 { | |
473 dev = joypad[i][KEY_LEFT] >> 8; | |
474 if (dev < numDevices && dev >= 0) | |
475 pDevices[dev].needed = 1; | |
476 else | |
477 joypad[i][KEY_LEFT] = DIK_LEFT; | |
478 | |
479 dev = joypad[i][KEY_RIGHT] >> 8; | |
480 if (dev < numDevices && dev >= 0) | |
481 pDevices[dev].needed = 1; | |
482 else | |
483 joypad[i][KEY_RIGHT] = DIK_RIGHT; | |
484 | |
485 dev = joypad[i][KEY_UP] >> 8; | |
486 if (dev < numDevices && dev >= 0) | |
487 pDevices[dev].needed = 1; | |
488 else | |
489 joypad[i][KEY_UP] = DIK_UP; | |
490 | |
491 dev = joypad[i][KEY_DOWN] >> 8; | |
492 if (dev < numDevices && dev >= 0) | |
493 pDevices[dev].needed = 1; | |
494 else | |
495 joypad[i][KEY_DOWN] = DIK_DOWN; | |
496 | |
497 dev = joypad[i][KEY_BUTTON_A] >> 8; | |
498 if (dev < numDevices && dev >= 0) | |
499 pDevices[dev].needed = 1; | |
500 else | |
501 joypad[i][KEY_BUTTON_A] = DIK_Z; | |
502 | |
503 dev = joypad[i][KEY_BUTTON_B] >> 8; | |
504 if (dev < numDevices && dev >= 0) | |
505 pDevices[dev].needed = 1; | |
506 else | |
507 joypad[i][KEY_BUTTON_B] = DIK_X; | |
508 | |
509 dev = joypad[i][KEY_BUTTON_L] >> 8; | |
510 if (dev < numDevices && dev >= 0) | |
511 pDevices[dev].needed = 1; | |
512 else | |
513 joypad[i][KEY_BUTTON_L] = DIK_A; | |
514 | |
515 dev = joypad[i][KEY_BUTTON_R] >> 8; | |
516 if (dev < numDevices && dev >= 0) | |
517 pDevices[dev].needed = 1; | |
518 else | |
519 joypad[i][KEY_BUTTON_R] = DIK_S; | |
520 | |
521 dev = joypad[i][KEY_BUTTON_START] >> 8; | |
522 if (dev < numDevices && dev >= 0) | |
523 pDevices[dev].needed = 1; | |
524 else | |
525 joypad[i][KEY_BUTTON_START] = DIK_RETURN; | |
526 | |
527 dev = joypad[i][KEY_BUTTON_SELECT] >> 8; | |
528 if (dev < numDevices && dev >= 0) | |
529 pDevices[dev].needed = 1; | |
530 else | |
531 joypad[i][KEY_BUTTON_SELECT] = DIK_BACK; | |
532 | |
533 dev = joypad[i][KEY_BUTTON_SPEED] >> 8; | |
534 if (dev < numDevices && dev >= 0) | |
535 pDevices[dev].needed = 1; | |
536 else | |
537 joypad[i][KEY_BUTTON_SPEED] = DIK_SPACE; | |
538 | |
539 dev = joypad[i][KEY_BUTTON_CAPTURE] >> 8; | |
540 if (dev < numDevices && dev >= 0) | |
541 pDevices[dev].needed = 1; | |
542 else | |
543 joypad[i][KEY_BUTTON_CAPTURE] = DIK_F12; | |
544 | |
545 dev = joypad[i][KEY_BUTTON_GS] >> 8; | |
546 if (dev < numDevices && dev >= 0) | |
547 pDevices[dev].needed = 1; | |
548 else | |
549 joypad[i][KEY_BUTTON_GS] = DIK_C; | |
550 } | |
551 | |
552 dev = motion[KEY_UP] >> 8; | |
553 if (dev < numDevices && dev >= 0) | |
554 pDevices[dev].needed = 1; | |
555 else | |
556 motion[KEY_UP] = DIK_NUMPAD8; | |
557 | |
558 dev = motion[KEY_DOWN] >> 8; | |
559 if (dev < numDevices && dev >= 0) | |
560 pDevices[dev].needed = 1; | |
561 else | |
562 motion[KEY_DOWN] = DIK_NUMPAD2; | |
563 | |
564 dev = motion[KEY_LEFT] >> 8; | |
565 if (dev < numDevices && dev >= 0) | |
566 pDevices[dev].needed = 1; | |
567 else | |
568 motion[KEY_LEFT] = DIK_NUMPAD4; | |
569 | |
570 dev = motion[KEY_RIGHT] >> 8; | |
571 if (dev < numDevices && dev >= 0) | |
572 pDevices[dev].needed = 1; | |
573 else | |
574 motion[KEY_RIGHT] = DIK_NUMPAD6; | |
575 } | |
576 | |
577 #define KEYDOWN(buffer, key) (buffer[key] & 0x80) | |
578 | |
579 static bool IsKeyDownAsync (WORD KeyIdent) | |
580 { | |
581 //if (KeyIdent == 0 || KeyIdent == VK_ESCAPE) // if it's the 'disabled' key, it's never pressed | |
582 // return false; | |
583 | |
584 //if (!GUI.BackgroundInput && GUI.hWnd != GetForegroundWindow()) | |
585 // return false; | |
586 | |
587 // the pause key is special, need this to catch all presses of it | |
588 // Both GetKeyState and GetAsyncKeyState cannot catch it anyway, | |
589 // so this should be handled in WM_KEYDOWN message. | |
590 if (KeyIdent == VK_PAUSE) | |
591 { | |
592 return false; | |
593 // if(GetAsyncKeyState(VK_PAUSE)) // not &'ing this with 0x8000 is intentional and necessary | |
594 // return true; | |
595 } | |
596 | |
597 if (KeyIdent == VK_CAPITAL || KeyIdent == VK_NUMLOCK || KeyIdent == VK_SCROLL) | |
598 return ((GetKeyState(KeyIdent) & 0x01) != 0); | |
599 else | |
600 return ((GetAsyncKeyState(KeyIdent) & 0x8000) != 0); | |
601 //return ((GetKeyState (KeyIdent) & 0x80) != 0); | |
602 } | |
603 | |
604 static bool readKeyboard() | |
605 { | |
606 #ifndef USE_GETASYNCKEYSTATE_FOR_KEYBOARD | |
607 if (pDevices[0].needed) | |
608 { | |
609 HRESULT hret = pDevices[0].device-> | |
610 GetDeviceState(256, | |
611 (LPVOID)pDevices[0].data); | |
612 | |
613 if (hret == DIERR_INPUTLOST || hret == DIERR_NOTACQUIRED) | |
614 { | |
615 hret = pDevices[0].device->Acquire(); | |
616 if (hret != DI_OK) | |
617 return false; | |
618 hret = pDevices[0].device->GetDeviceState(256, (LPVOID)pDevices[0].data); | |
619 } | |
620 | |
621 return hret == DI_OK; | |
622 } | |
623 #else | |
624 for (int i = 0; i < sizeof(win_key_trans_table)/sizeof(win_key_trans_table[0]); i++) { | |
625 pDevices[0].data[win_key_trans_table[i].dik] = IsKeyDownAsync(win_key_trans_table[i].vk) ? 0x80 : 0; | |
626 } | |
627 #endif | |
628 return true; | |
629 } | |
630 | |
631 static bool readJoystick(int joy) | |
632 { | |
633 if (pDevices[joy].needed) | |
634 { | |
635 if (pDevices[joy].isPolled) | |
636 ((LPDIRECTINPUTDEVICE2)pDevices[joy].device)->Poll(); | |
637 | |
638 HRESULT hret = pDevices[joy].device-> | |
639 GetDeviceState(sizeof(DIJOYSTATE), | |
640 (LPVOID)&pDevices[joy].state); | |
641 | |
642 if (hret == DIERR_INPUTLOST || hret == DIERR_NOTACQUIRED) | |
643 { | |
644 hret = pDevices[joy].device->Acquire(); | |
645 | |
646 if (hret == DI_OK) | |
647 { | |
648 if (pDevices[joy].isPolled) | |
649 ((LPDIRECTINPUTDEVICE2)pDevices[joy].device)->Poll(); | |
650 | |
651 hret = pDevices[joy].device-> | |
652 GetDeviceState(sizeof(DIJOYSTATE), | |
653 (LPVOID)&pDevices[joy].state); | |
654 } | |
655 } | |
656 | |
657 return hret == DI_OK; | |
658 } | |
659 | |
660 return true; | |
661 } | |
662 | |
663 static void checkKeyboard() | |
664 { | |
665 // mham fix. Patch #1378104 | |
666 UCHAR keystate[256]; | |
667 HRESULT hret = pDevices[0].device->Acquire(); | |
668 | |
669 if (pDevices[0].first) | |
670 { | |
671 pDevices[0].device->GetDeviceState(256, (LPVOID)pDevices[0].data); | |
672 pDevices[0].first = FALSE; | |
673 return; | |
674 } | |
675 | |
676 hret = pDevices[0].device-> | |
677 GetDeviceState(256, (LPVOID)keystate); | |
678 | |
679 if (hret == DIERR_INPUTLOST || hret == DIERR_NOTACQUIRED) | |
680 { | |
681 return; | |
682 } | |
683 | |
684 if (hret == DI_OK) | |
685 { | |
686 for (int i = 0; i < 256; i++) | |
687 { | |
688 if (keystate[i] == pDevices[0].data[i]) | |
689 continue; | |
690 if (KEYDOWN(keystate, i)) | |
691 { | |
692 SendMessage(GetFocus(), JOYCONFIG_MESSAGE, 0, i); | |
693 break; | |
694 } | |
695 } | |
696 } | |
697 memcpy(pDevices[0].data, keystate, sizeof(UCHAR) * 256); | |
698 } | |
699 | |
700 static void checkJoypads() | |
701 { | |
702 DIDEVICEOBJECTINSTANCE di; | |
703 | |
704 ZeroMemory(&di, sizeof(DIDEVICEOBJECTINSTANCE)); | |
705 | |
706 di.dwSize = sizeof(DIDEVICEOBJECTINSTANCE); | |
707 | |
708 int i = 0; | |
709 | |
710 DIJOYSTATE joystick; | |
711 | |
712 for (i = 1; i < numDevices; i++) | |
713 { | |
714 HRESULT hret = pDevices[i].device->Acquire(); | |
715 | |
716 if (pDevices[i].isPolled) | |
717 ((LPDIRECTINPUTDEVICE2)pDevices[i].device)->Poll(); | |
718 | |
719 hret = pDevices[i].device->GetDeviceState(sizeof(joystick), &joystick); | |
720 | |
721 int j; | |
722 | |
723 if (pDevices[i].first) | |
724 { | |
725 memcpy(&pDevices[i].state, &joystick, sizeof(joystick)); | |
726 pDevices[i].first = FALSE; | |
727 continue; | |
728 } | |
729 | |
730 for (j = 0; j < pDevices[i].nButtons; j++) | |
731 { | |
732 if (((pDevices[i].state.rgbButtons[j] ^ joystick.rgbButtons[j]) | |
733 & joystick.rgbButtons[j]) & 0x80) | |
734 { | |
735 HWND focus = GetFocus(); | |
736 | |
737 SendMessage(focus, JOYCONFIG_MESSAGE, i, j+128); | |
738 } | |
739 } | |
740 | |
741 for (j = 0; j < pDevices[i].nAxes && j < 8; j++) | |
742 { | |
743 LONG value = pDevices[i].axis[j].center; | |
744 LONG old = 0; | |
745 switch (pDevices[i].axis[j].offset) | |
746 { | |
747 case DIJOFS_X: | |
748 value = joystick.lX; | |
749 old = pDevices[i].state.lX; | |
750 break; | |
751 case DIJOFS_Y: | |
752 value = joystick.lY; | |
753 old = pDevices[i].state.lY; | |
754 break; | |
755 case DIJOFS_Z: | |
756 value = joystick.lZ; | |
757 old = pDevices[i].state.lZ; | |
758 break; | |
759 case DIJOFS_RX: | |
760 value = joystick.lRx; | |
761 old = pDevices[i].state.lRx; | |
762 break; | |
763 case DIJOFS_RY: | |
764 value = joystick.lRy; | |
765 old = pDevices[i].state.lRy; | |
766 break; | |
767 case DIJOFS_RZ: | |
768 value = joystick.lRz; | |
769 old = pDevices[i].state.lRz; | |
770 break; | |
771 case DIJOFS_SLIDER(0): | |
772 value = joystick.rglSlider[0]; | |
773 old = pDevices[i].state.rglSlider[0]; | |
774 break; | |
775 case DIJOFS_SLIDER(1): | |
776 value = joystick.rglSlider[1]; | |
777 old = pDevices[i].state.rglSlider[1]; | |
778 break; | |
779 } | |
780 if (value != old) | |
781 { | |
782 if (value < pDevices[i].axis[j].negative) | |
783 SendMessage(GetFocus(), JOYCONFIG_MESSAGE, i, (j<<1)); | |
784 else if (value > pDevices[i].axis[j].positive) | |
785 SendMessage(GetFocus(), JOYCONFIG_MESSAGE, i, (j<<1)+1); | |
786 } | |
787 } | |
788 | |
789 for (j = 0; j < 4 && j < pDevices[i].nPovs; j++) | |
790 { | |
791 if (LOWORD(pDevices[i].state.rgdwPOV[j]) != LOWORD(joystick.rgdwPOV[j])) | |
792 { | |
793 int state = getPovState(joystick.rgdwPOV[j]); | |
794 | |
795 if (state & POV_UP) | |
796 SendMessage(GetFocus(), JOYCONFIG_MESSAGE, i, (j<<2)+0x20); | |
797 else if (state & POV_DOWN) | |
798 SendMessage(GetFocus(), JOYCONFIG_MESSAGE, i, (j<<2)+0x21); | |
799 else if (state & POV_RIGHT) | |
800 SendMessage(GetFocus(), JOYCONFIG_MESSAGE, i, (j<<2)+0x22); | |
801 else if (state & POV_LEFT) | |
802 SendMessage(GetFocus(), JOYCONFIG_MESSAGE, i, (j<<2)+0x23); | |
803 } | |
804 } | |
805 | |
806 memcpy(&pDevices[i].state, &joystick, sizeof(joystick)); | |
807 } | |
808 } | |
809 | |
810 BOOL checkKey(LONG_PTR key) | |
811 { | |
812 LONG_PTR dev = (key >> 8); | |
813 | |
814 LONG_PTR k = (key & 255); | |
815 | |
816 if (dev == 0) | |
817 { | |
818 return KEYDOWN(pDevices[0].data, k); | |
819 } | |
820 else if (dev >= numDevices) | |
821 { | |
822 return FALSE; | |
823 } | |
824 else | |
825 { | |
826 if (k < 16) | |
827 { | |
828 LONG_PTR axis = k >> 1; | |
829 LONG value = pDevices[dev].axis[axis].center; | |
830 switch (pDevices[dev].axis[axis].offset) | |
831 { | |
832 case DIJOFS_X: | |
833 value = pDevices[dev].state.lX; | |
834 break; | |
835 case DIJOFS_Y: | |
836 value = pDevices[dev].state.lY; | |
837 break; | |
838 case DIJOFS_Z: | |
839 value = pDevices[dev].state.lZ; | |
840 break; | |
841 case DIJOFS_RX: | |
842 value = pDevices[dev].state.lRx; | |
843 break; | |
844 case DIJOFS_RY: | |
845 value = pDevices[dev].state.lRy; | |
846 break; | |
847 case DIJOFS_RZ: | |
848 value = pDevices[dev].state.lRz; | |
849 break; | |
850 case DIJOFS_SLIDER(0): | |
851 value = pDevices[dev].state.rglSlider[0]; | |
852 break; | |
853 case DIJOFS_SLIDER(1): | |
854 value = pDevices[dev].state.rglSlider[1]; | |
855 break; | |
856 } | |
857 | |
858 if (k & 1) | |
859 return value > pDevices[dev].axis[axis].positive; | |
860 return value < pDevices[dev].axis[axis].negative; | |
861 } | |
862 else if (k < 48) | |
863 { | |
864 LONG_PTR hat = (k >> 2) & 3; | |
865 int state = getPovState(pDevices[dev].state.rgdwPOV[hat]); | |
866 BOOL res = FALSE; | |
867 switch (k & 3) | |
868 { | |
869 case 0: | |
870 res = state & POV_UP; | |
871 break; | |
872 case 1: | |
873 res = state & POV_DOWN; | |
874 break; | |
875 case 2: | |
876 res = state & POV_RIGHT; | |
877 break; | |
878 case 3: | |
879 res = state & POV_LEFT; | |
880 break; | |
881 } | |
882 return res; | |
883 } | |
884 else if (k >= 128) | |
885 { | |
886 return pDevices[dev].state.rgbButtons[k-128] & 0x80; | |
887 } | |
888 } | |
889 | |
890 return FALSE; | |
891 } | |
892 | |
893 DirectInput::DirectInput() | |
894 { | |
895 dinputDLL = NULL; | |
896 } | |
897 | |
898 DirectInput::~DirectInput() | |
899 { | |
900 saveSettings(); | |
901 if (pDirectInput != NULL) | |
902 { | |
903 if (pDevices) | |
904 { | |
905 for (int i = 0; i < numDevices; i++) | |
906 { | |
907 if (pDevices[i].device) | |
908 { | |
909 pDevices[i].device->Unacquire(); | |
910 pDevices[i].device->Release(); | |
911 pDevices[i].device = NULL; | |
912 } | |
913 } | |
914 free(pDevices); | |
915 pDevices = NULL; | |
916 } | |
917 | |
918 pDirectInput->Release(); | |
919 pDirectInput = NULL; | |
920 } | |
921 | |
922 if (dinputDLL) | |
923 { | |
924 /**/ ::FreeLibrary(dinputDLL); | |
925 dinputDLL = NULL; | |
926 } | |
927 } | |
928 | |
929 bool DirectInput::initialize() | |
930 { | |
931 joyDebug = GetPrivateProfileInt("config", | |
932 "joyDebug", | |
933 0, | |
934 "VBA.ini"); | |
935 dinputDLL = /**/ ::LoadLibrary("DINPUT.DLL"); | |
936 HRESULT (WINAPI *DInputCreate)(HINSTANCE, DWORD, LPDIRECTINPUT *, IUnknown *); | |
937 if (dinputDLL != NULL) | |
938 { | |
939 DInputCreate = (HRESULT (WINAPI *)(HINSTANCE, DWORD, LPDIRECTINPUT *, IUnknown *)) | |
940 GetProcAddress(dinputDLL, "DirectInputCreateA"); | |
941 | |
942 if (DInputCreate == NULL) | |
943 { | |
944 directXMessage("DirectInputCreateA"); | |
945 return false; | |
946 } | |
947 } | |
948 else | |
949 { | |
950 directXMessage("DINPUT.DLL"); | |
951 return false; | |
952 } | |
953 | |
954 HRESULT hret = DInputCreate(AfxGetInstanceHandle(), | |
955 DIRECTINPUT_VERSION, | |
956 &pDirectInput, | |
957 NULL); | |
958 if (hret != DI_OK) | |
959 { | |
960 // errorMessage(myLoadString(IDS_ERROR_DISP_CREATE), hret); | |
961 return false; | |
962 } | |
963 | |
964 hret = pDirectInput->EnumDevices(DIDEVTYPE_JOYSTICK, | |
965 DIEnumDevicesCallback2, | |
966 NULL, | |
967 DIEDFL_ATTACHEDONLY); | |
968 | |
969 pDevices = (deviceInfo *)calloc(numDevices, sizeof(deviceInfo)); | |
970 | |
971 hret = pDirectInput->CreateDevice(GUID_SysKeyboard, &pDevices[0].device, NULL); | |
972 pDevices[0].isPolled = false; | |
973 pDevices[0].needed = true; | |
974 pDevices[0].first = true; | |
975 | |
976 if (hret != DI_OK) | |
977 { | |
978 // errorMessage(myLoadString(IDS_ERROR_DISP_CREATEDEVICE), hret); | |
979 return false; | |
980 } | |
981 | |
982 numDevices = 1; | |
983 | |
984 hret = pDirectInput->EnumDevices(DIDEVTYPE_JOYSTICK, | |
985 DIEnumDevicesCallback, | |
986 NULL, | |
987 DIEDFL_ATTACHEDONLY); | |
988 | |
989 // hret = pDevices[0].device->SetCooperativeLevel(hWindow, | |
990 // DISCL_FOREGROUND| | |
991 // DISCL_NONEXCLUSIVE); | |
992 | |
993 if (hret != DI_OK) | |
994 { | |
995 // errorMessage(myLoadString(IDS_ERROR_DISP_LEVEL), hret); | |
996 return false; | |
997 } | |
998 | |
999 hret = pDevices[0].device->SetDataFormat(&c_dfDIKeyboard); | |
1000 | |
1001 if (hret != DI_OK) | |
1002 { | |
1003 // errorMessage(myLoadString(IDS_ERROR_DISP_DATAFORMAT), hret); | |
1004 return false; | |
1005 } | |
1006 | |
1007 for (int i = 1; i < numDevices; i++) | |
1008 { | |
1009 pDevices[i].device->SetDataFormat(&c_dfDIJoystick); | |
1010 pDevices[i].needed = false; | |
1011 pDevices[i].first = true; | |
1012 currentDevice = &pDevices[i]; | |
1013 axisNumber = 0; | |
1014 currentDevice->device->EnumObjects(EnumAxesCallback, NULL, DIDFT_AXIS); | |
1015 currentDevice->device->EnumObjects(EnumPovsCallback, NULL, DIDFT_POV); | |
1016 if (joyDebug) | |
1017 { | |
1018 // don't translate. debug only | |
1019 winlog("Joystick %2d polled : %d\n", i, currentDevice->isPolled); | |
1020 winlog("Joystick %2d buttons : %d\n", i, currentDevice->nButtons); | |
1021 winlog("Joystick %2d povs : %d\n", i, currentDevice->nPovs); | |
1022 winlog("Joystick %2d axes : %d\n", i, currentDevice->nAxes); | |
1023 for (int j = 0; j < currentDevice->nAxes; j++) | |
1024 { | |
1025 winlog("Axis %2d offset : %08lx\n", j, currentDevice->axis[j]. | |
1026 offset); | |
1027 winlog("Axis %2d center : %08lx\n", j, currentDevice->axis[j]. | |
1028 center); | |
1029 winlog("Axis %2d negative : %08lx\n", j, currentDevice->axis[j]. | |
1030 negative); | |
1031 winlog("Axis %2d positive : %08lx\n", j, currentDevice->axis[j]. | |
1032 positive); | |
1033 } | |
1034 } | |
1035 | |
1036 currentDevice = NULL; | |
1037 } | |
1038 | |
1039 for (int i = 0; i < numDevices; i++) | |
1040 pDevices[i].device->Acquire(); | |
1041 | |
1042 return true; | |
1043 } | |
1044 | |
1045 bool DirectInput::readDevices() | |
1046 { | |
1047 bool ok = true; | |
1048 for (int i = 0; i < numDevices; i++) | |
1049 { | |
1050 if (pDevices[i].needed) | |
1051 { | |
1052 ok = (i > 0 ? readJoystick(i) : readKeyboard()) || ok; | |
1053 } | |
1054 } | |
1055 return ok; | |
1056 } | |
1057 | |
1058 bool inputActive = true; // used to disable all input when the window is inactive | |
1059 | |
1060 u32 DirectInput::readDevice(int i, bool sensor) | |
1061 { | |
1062 // this old hack is evil | |
1063 extern int systemGetDefaultJoypad(); | |
1064 extern int32 gbSgbMode, gbSgbMultiplayer; | |
1065 if (!(gbSgbMode && gbSgbMultiplayer)) | |
1066 i = systemGetDefaultJoypad(); | |
1067 | |
1068 u32 res = 0; | |
1069 | |
1070 // manual input | |
1071 if (inputActive) | |
1072 { | |
1073 if (checkKey(joypad[i][KEY_BUTTON_A])) | |
1074 res |= BUTTON_MASK_A; | |
1075 if (checkKey(joypad[i][KEY_BUTTON_B])) | |
1076 res |= BUTTON_MASK_B; | |
1077 if (checkKey(joypad[i][KEY_BUTTON_SELECT])) | |
1078 res |= BUTTON_MASK_SELECT; | |
1079 if (checkKey(joypad[i][KEY_BUTTON_START])) | |
1080 res |= BUTTON_MASK_START; | |
1081 if (checkKey(joypad[i][KEY_RIGHT])) | |
1082 res |= BUTTON_MASK_RIGHT; | |
1083 if (checkKey(joypad[i][KEY_LEFT])) | |
1084 res |= BUTTON_MASK_LEFT; | |
1085 if (checkKey(joypad[i][KEY_UP])) | |
1086 res |= BUTTON_MASK_UP; | |
1087 if (checkKey(joypad[i][KEY_DOWN])) | |
1088 res |= BUTTON_MASK_DOWN; | |
1089 if (checkKey(joypad[i][KEY_BUTTON_R])) | |
1090 res |= BUTTON_MASK_R; | |
1091 if (checkKey(joypad[i][KEY_BUTTON_L])) | |
1092 res |= BUTTON_MASK_L; | |
1093 | |
1094 // unused | |
1095 if (checkKey(motion[KEY_LEFT])) | |
1096 res |= BUTTON_MASK_LEFT_MOTION; | |
1097 else if (checkKey(motion[KEY_RIGHT])) | |
1098 res |= BUTTON_MASK_RIGHT_MOTION; | |
1099 if (checkKey(motion[KEY_UP])) | |
1100 res |= BUTTON_MASK_UP_MOTION; | |
1101 else if (checkKey(motion[KEY_DOWN])) | |
1102 res |= BUTTON_MASK_DOWN_MOTION; | |
1103 } | |
1104 | |
1105 u32 hackedButtons = 0; | |
1106 if (inputActive) | |
1107 { | |
1108 // the "non-button" buttons (what a hack!) | |
1109 if (checkKey(joypad[i][KEY_BUTTON_SPEED])) | |
1110 hackedButtons |= BUTTON_MASK_SPEED; | |
1111 if (checkKey(joypad[i][KEY_BUTTON_CAPTURE])) | |
1112 hackedButtons |= BUTTON_MASK_CAPTURE; | |
1113 if (checkKey(joypad[i][KEY_BUTTON_GS])) | |
1114 hackedButtons |= BUTTON_MASK_GAMESHARK; | |
1115 } | |
1116 | |
1117 extern bool systemIsSpedUp(); | |
1118 if (systemIsSpedUp()) | |
1119 hackedButtons |= BUTTON_MASK_SPEED; | |
1120 | |
1121 return res | hackedButtons; | |
1122 } | |
1123 | |
1124 CString DirectInput::getKeyName(LONG_PTR key) | |
1125 { | |
1126 LONG_PTR d = (key >> 8); | |
1127 LONG_PTR k = key & 255; | |
1128 | |
1129 DIDEVICEOBJECTINSTANCE di; | |
1130 | |
1131 ZeroMemory(&di, sizeof(DIDEVICEOBJECTINSTANCE)); | |
1132 | |
1133 di.dwSize = sizeof(DIDEVICEOBJECTINSTANCE); | |
1134 | |
1135 CString winBuffer = winResLoadString(IDS_ERROR); | |
1136 | |
1137 if (d == 0) | |
1138 { | |
1139 pDevices[0].device->GetObjectInfo(&di, (DWORD)key, DIPH_BYOFFSET); | |
1140 winBuffer = di.tszName; | |
1141 } | |
1142 else if (d < numDevices) | |
1143 { | |
1144 if (k < 16) | |
1145 { | |
1146 if (k < 4) | |
1147 { | |
1148 switch (k) | |
1149 { | |
1150 case 0: | |
1151 winBuffer.Format(winResLoadString(IDS_JOY_LEFT), d); | |
1152 break; | |
1153 case 1: | |
1154 winBuffer.Format(winResLoadString(IDS_JOY_RIGHT), d); | |
1155 break; | |
1156 case 2: | |
1157 winBuffer.Format(winResLoadString(IDS_JOY_UP), d); | |
1158 break; | |
1159 case 3: | |
1160 winBuffer.Format(winResLoadString(IDS_JOY_DOWN), d); | |
1161 break; | |
1162 } | |
1163 } | |
1164 else | |
1165 { | |
1166 pDevices[d].device->GetObjectInfo(&di, | |
1167 pDevices[d].axis[k>>1].offset, | |
1168 DIPH_BYOFFSET); | |
1169 if (k & 1) | |
1170 winBuffer.Format("Joy %d %s +", d, di.tszName); | |
1171 else | |
1172 winBuffer.Format("Joy %d %s -", d, di.tszName); | |
1173 } | |
1174 } | |
1175 else if (k < 48) | |
1176 { | |
1177 LONG_PTR hat = (k >> 2) & 3; | |
1178 pDevices[d].device->GetObjectInfo(&di, | |
1179 (DWORD)DIJOFS_POV(hat), | |
1180 DIPH_BYOFFSET); | |
1181 char * dir = "up"; | |
1182 LONG_PTR dd = k & 3; | |
1183 if (dd == 1) | |
1184 dir = "down"; | |
1185 else if (dd == 2) | |
1186 dir = "right"; | |
1187 else if (dd == 3) | |
1188 dir = "left"; | |
1189 winBuffer.Format("Joy %d %s %s", d, di.tszName, dir); | |
1190 } | |
1191 else | |
1192 { | |
1193 pDevices[d].device->GetObjectInfo(&di, | |
1194 (DWORD)DIJOFS_BUTTON(k-128), | |
1195 DIPH_BYOFFSET); | |
1196 winBuffer.Format(winResLoadString(IDS_JOY_BUTTON), d, di.tszName); | |
1197 } | |
1198 } | |
1199 else | |
1200 { | |
1201 // Joystick isn't plugged in. We can't decipher k, so just show its value. | |
1202 winBuffer.Format("Joy %d (%d)", d, k); | |
1203 } | |
1204 | |
1205 return winBuffer; | |
1206 } | |
1207 | |
1208 void DirectInput::checkKeys() | |
1209 { | |
1210 ::checkKeys(); | |
1211 } | |
1212 | |
1213 Input *newDirectInput() | |
1214 { | |
1215 return new DirectInput; | |
1216 } | |
1217 | |
1218 void DirectInput::checkDevices() | |
1219 { | |
1220 checkJoypads(); | |
1221 checkKeyboard(); | |
1222 } | |
1223 | |
1224 void DirectInput::activate() | |
1225 { | |
1226 for (int i = 0; i < numDevices; i++) | |
1227 { | |
1228 if (pDevices != NULL && pDevices[i].device != NULL) | |
1229 pDevices[i].device->Acquire(); | |
1230 } | |
1231 } | |
1232 | |
1233 void DirectInput::loadSettings() | |
1234 { | |
1235 winReadKeys(); | |
1236 } | |
1237 | |
1238 void DirectInput::saveSettings() | |
1239 { | |
1240 winSaveKeys(); | |
1241 } | |
1242 |