1 #include "stdafx.h"
2 #include "VBA.h"
3 #include "Input.h"
4 #include "Reg.h"
5 #include "WinResUtil.h"
6
7 #define DIRECTINPUT_VERSION 0x0800
8 #include <dinput.h>
9 #pragma comment( lib, "dinput8" )
10 #pragma comment( lib, "dxguid" )
11
12
13 #ifdef _DEBUG
14 #define new DEBUG_NEW
15 #undef THIS_FILE
16 static char THIS_FILE[] = __FILE__;
17 #endif
18
19 extern void directXMessage(const char *);
20 extern void winlog(const char *msg,...);
21
22 #define POV_UP 1
23 #define POV_DOWN 2
24 #define POV_RIGHT 4
25 #define POV_LEFT 8
26
27 class DirectInput : public Input {
28 public:
29 virtual void checkDevices();
30 DirectInput();
31 virtual ~DirectInput();
32
33 virtual bool initialize();
34 virtual bool readDevices();
35 virtual u32 readDevice(int which);
36 virtual CString getKeyName(LONG_PTR key);
37 virtual void checkKeys();
38 virtual void checkMotionKeys();
39 virtual void activate();
40 virtual void loadSettings();
41 virtual void saveSettings();
42 };
43
44 struct deviceInfo {
45 LPDIRECTINPUTDEVICE8 device;
46 BOOL isPolled;
47 int nButtons;
48 int nAxes;
49 int nPovs;
50 BOOL first;
51 struct {
52 DWORD offset;
53 LONG center;
54 LONG negative;
55 LONG positive;
56 } axis[8];
57 int needed;
58 union {
59 UCHAR data[256];
60 DIJOYSTATE state;
61 };
62 };
63
64 static deviceInfo *currentDevice = NULL;
65 static int numDevices = 1;
66 static deviceInfo *pDevices = NULL;
67 static LPDIRECTINPUT8 pDirectInput = NULL;
68 static int axisNumber = 0;
69
70
71
72
73 LONG_PTR defvalues[JOYPADS * KEYS_PER_PAD + MOTION_KEYS] =
74 {
75 DIK_LEFT, DIK_RIGHT,
76 DIK_UP, DIK_DOWN,
77 DIK_X, DIK_Z,
78 DIK_RETURN,DIK_BACK,
79 DIK_A, DIK_S,
80 DIK_SPACE, DIK_F12,
81 DIK_C,
82 0,0,0,0,0,0,0,0,0,0,0,0,0,
83 0,0,0,0,0,0,0,0,0,0,0,0,0,
84 0,0,0,0,0,0,0,0,0,0,0,0,0,
85 DIK_NUMPAD4, DIK_NUMPAD6, DIK_NUMPAD8, DIK_NUMPAD2
86 };
87
88
winReadKey(const char * name,KeyList & Keys)89 void winReadKey(const char *name, KeyList& Keys)
90 {
91 CString TxtKeyList = regQueryStringValue(name, "");
92 int curPos= 0;
93
94 CString resToken=TxtKeyList.Tokenize(",",curPos);
95 while (resToken != "")
96 {
97 Keys.AddTail(atoi(resToken));
98 resToken= TxtKeyList.Tokenize(",",curPos);
99 };
100 }
101
winReadKey(const char * name,int num,KeyList & Keys)102 void winReadKey(const char *name, int num, KeyList& Keys)
103 {
104 char buffer[80];
105
106 sprintf(buffer, "Joy%d_%s", num, name);
107 winReadKey(buffer, Keys);
108 }
109
110
winReadKeys()111 void winReadKeys()
112 {
113
114 for(int i = 0; i < JOYPADS; i++) {
115 winReadKey("Left", i, theApp.input->joypaddata[JOYPAD(i,KEY_LEFT)]);
116 winReadKey("Right", i, theApp.input->joypaddata[JOYPAD(i, KEY_RIGHT)]);
117 winReadKey("Up", i, theApp.input->joypaddata[JOYPAD(i,KEY_UP)]);
118 winReadKey("Down", i, theApp.input->joypaddata[JOYPAD(i,KEY_DOWN)]);
119 winReadKey("A", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_A)]);
120 winReadKey("B", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_B)]);
121 winReadKey("L", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_L)]);
122 winReadKey("R", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_R)]);
123 winReadKey("Start", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_START)]);
124 winReadKey("Select", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_SELECT)]);
125 winReadKey("Speed", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_SPEED)]);
126 winReadKey("Capture", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_CAPTURE)]);
127 winReadKey("GS", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_GS)]);
128 }
129 winReadKey("Motion_Left", theApp.input->joypaddata[MOTION(KEY_LEFT)]);
130 winReadKey("Motion_Right", theApp.input->joypaddata[MOTION(KEY_RIGHT)]);
131 winReadKey("Motion_Up", theApp.input->joypaddata[MOTION(KEY_UP)]);
132 winReadKey("Motion_Down", theApp.input->joypaddata[MOTION(KEY_DOWN)]);
133 }
134
winSaveKey(char * name,KeyList & value)135 void winSaveKey(char *name, KeyList& value)
136 {
137 CString txtKeys;
138
139 POSITION p = value.GetHeadPosition();
140 while(p!=NULL)
141 {
142 CString tmp;
143 tmp.Format("%d", value.GetNext(p));
144 txtKeys+=tmp;
145 if (p!=NULL)
146 txtKeys+=",";
147 }
148 regSetStringValue(name, txtKeys);
149 }
150
winSaveKey(char * name,int num,KeyList & value)151 static void winSaveKey(char *name, int num, KeyList& value)
152 {
153 char buffer[80];
154
155 sprintf(buffer, "Joy%d_%s", num, name);
156 winSaveKey(buffer, value);
157 }
158
winSaveKeys()159 void winSaveKeys()
160 {
161 for(int i = 0; i < JOYPADS; i++) {
162 winSaveKey("Left", i, theApp.input->joypaddata[JOYPAD(i,KEY_LEFT)]);
163 winSaveKey("Right", i, theApp.input->joypaddata[JOYPAD(i,KEY_RIGHT)]);
164 winSaveKey("Up", i, theApp.input->joypaddata[JOYPAD(i,KEY_UP)]);
165 winSaveKey("Speed", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_SPEED)]);
166 winSaveKey("Capture", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_CAPTURE)]);
167 winSaveKey("GS", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_GS)]);
168 winSaveKey("Down", i, theApp.input->joypaddata[JOYPAD(i,KEY_DOWN)]);
169 winSaveKey("A", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_A)]);
170 winSaveKey("B", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_B)]);
171 winSaveKey("L", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_L)]);
172 winSaveKey("R", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_R)]);
173 winSaveKey("Start", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_START)]);
174 winSaveKey("Select", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_SELECT)]);
175 }
176 regSetDwordValue("joyVersion", 1);
177
178 winSaveKey("Motion_Left",
179 theApp.input->joypaddata[MOTION(KEY_LEFT)]);
180 winSaveKey("Motion_Right",
181 theApp.input->joypaddata[MOTION(KEY_RIGHT)]);
182 winSaveKey("Motion_Up",
183 theApp.input->joypaddata[MOTION(KEY_UP)]);
184 winSaveKey("Motion_Down",
185 theApp.input->joypaddata[MOTION(KEY_DOWN)]);
186 }
187
EnumPovsCallback(const DIDEVICEOBJECTINSTANCE * pdidoi,VOID * pContext)188 static BOOL CALLBACK EnumPovsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
189 VOID* pContext )
190 {
191 return DIENUM_CONTINUE;
192 }
193
DIEnumDevicesCallback(LPCDIDEVICEINSTANCE pInst,LPVOID lpvContext)194 static BOOL CALLBACK DIEnumDevicesCallback(LPCDIDEVICEINSTANCE pInst,
195 LPVOID lpvContext)
196 {
197 ZeroMemory(&pDevices[numDevices],sizeof(deviceInfo));
198
199 HRESULT hRet = pDirectInput->CreateDevice(pInst->guidInstance,
200 &pDevices[numDevices].device,
201 NULL);
202
203 if (hRet != DI_OK)
204 return DIENUM_STOP;
205
206 DIDEVCAPS caps;
207 caps.dwSize=sizeof(DIDEVCAPS);
208
209 hRet = pDevices[numDevices].device->GetCapabilities(&caps);
210
211 if (hRet == DI_OK) {
212 if (caps.dwFlags & DIDC_POLLEDDATAFORMAT ||
213 caps.dwFlags & DIDC_POLLEDDEVICE)
214 pDevices[numDevices].isPolled = TRUE;
215
216 pDevices[numDevices].nButtons = caps.dwButtons;
217 pDevices[numDevices].nAxes = caps.dwAxes;
218 pDevices[numDevices].nPovs = caps.dwPOVs;
219
220 for (int i = 0; i < 6; i++) {
221 pDevices[numDevices].axis[i].center = 0x8000;
222 pDevices[numDevices].axis[i].negative = 0x4000;
223 pDevices[numDevices].axis[i].positive = 0xc000;
224 }
225 }
226
227
228 numDevices++;
229
230
231 return DIENUM_CONTINUE;
232 }
233
DIEnumDevicesCallback2(LPCDIDEVICEINSTANCE pInst,LPVOID lpvContext)234 BOOL CALLBACK DIEnumDevicesCallback2(LPCDIDEVICEINSTANCE pInst,
235 LPVOID lpvContext)
236 {
237 numDevices++;
238
239 return DIENUM_CONTINUE;
240 }
241
getPovState(DWORD value)242 static int getPovState(DWORD value)
243 {
244 int state = 0;
245 if (LOWORD(value) != 0xFFFF) {
246 if (value < 9000 || value > 27000)
247 state |= POV_UP;
248 if (value > 0 && value < 18000)
249 state |= POV_RIGHT;
250 if (value > 9000 && value < 27000)
251 state |= POV_DOWN;
252 if (value > 18000)
253 state |= POV_LEFT;
254 }
255 return state;
256 }
257
checkKeys()258 static void checkKeys()
259 {
260 LONG_PTR dev = 0;
261 int i;
262
263 for(i = 0; i < (sizeof(theApp.input->joypaddata) / sizeof(theApp.input->joypaddata[0])); i++)
264 {
265 if (theApp.input->joypaddata[i].IsEmpty() && defvalues[i])
266 theApp.input->joypaddata[i].AddTail(defvalues[i]);
267 POSITION p = theApp.input->joypaddata[i].GetHeadPosition();
268 while(p!=NULL)
269 {
270 LONG_PTR k = theApp.input->joypaddata[i].GetNext(p);
271 if (k > 0 && DEVICEOF(k) < numDevices)
272 pDevices[DEVICEOF(k)].needed = true;
273 }
274 }
275 }
276
277 #define KEYDOWN(buffer,key) (buffer[key] & 0x80)
278
readKeyboard()279 static bool readKeyboard()
280 {
281 if (pDevices[0].needed) {
282 HRESULT hret = pDevices[0].device->
283 GetDeviceState(256,
284 (LPVOID)pDevices[0].data);
285
286 if (hret == DIERR_INPUTLOST || hret == DIERR_NOTACQUIRED) {
287 hret = pDevices[0].device->Acquire();
288 if (hret != DI_OK)
289 return false;
290 hret = pDevices[0].device->GetDeviceState(256,(LPVOID)pDevices[0].data);
291 }
292
293 return hret == DI_OK;
294 }
295 return true;
296 }
297
readJoystick(int joy)298 static bool readJoystick(int joy)
299 {
300 if (pDevices[joy].needed) {
301 if (pDevices[joy].isPolled)
302 ((LPDIRECTINPUTDEVICE2)pDevices[joy].device)->Poll();
303
304 HRESULT hret = pDevices[joy].device->
305 GetDeviceState(sizeof(DIJOYSTATE),
306 (LPVOID)&pDevices[joy].state);
307
308 if (hret == DIERR_INPUTLOST || hret == DIERR_NOTACQUIRED) {
309 hret = pDevices[joy].device->Acquire();
310
311 if (hret == DI_OK) {
312
313 if (pDevices[joy].isPolled)
314 ((LPDIRECTINPUTDEVICE2)pDevices[joy].device)->Poll();
315
316 hret = pDevices[joy].device->
317 GetDeviceState(sizeof(DIJOYSTATE),
318 (LPVOID)&pDevices[joy].state);
319 }
320 }
321
322 return hret == DI_OK;
323 }
324
325 return true;
326 }
327
checkKeyboard()328 static void checkKeyboard()
329 {
330 // mham fix. Patch #1378104
331 UCHAR keystate[256];
332 HRESULT hret = pDevices[0].device->Acquire();
333
334 if (pDevices[0].first) {
335 pDevices[0].device->GetDeviceState(256, (LPVOID)pDevices[0].data);
336 pDevices[0].first = FALSE;
337 return;
338 }
339
340 hret = pDevices[0].device->
341 GetDeviceState(256, (LPVOID)keystate);
342
343 if (hret == DIERR_INPUTLOST || hret == DIERR_NOTACQUIRED) {
344 return;
345 }
346
347 if (hret == DI_OK) {
348 for (int i = 0; i < 256; i++) {
349 if (keystate[i] == pDevices[0].data[i]) continue;
350 if (KEYDOWN(keystate, i)) {
351 SendMessage(GetFocus(), JOYCONFIG_MESSAGE,0,i);
352 break;
353 }
354 }
355 }
356 memcpy(pDevices[0].data, keystate, sizeof(UCHAR) * 256);
357 }
358
checkJoypads()359 static void checkJoypads()
360 {
361 DIDEVICEOBJECTINSTANCE di;
362
363 ZeroMemory(&di,sizeof(DIDEVICEOBJECTINSTANCE));
364
365 di.dwSize = sizeof(DIDEVICEOBJECTINSTANCE);
366
367 int i =0;
368
369 DIJOYSTATE joystick;
370
371 for (i = 1; i < numDevices; i++) {
372 HRESULT hret = pDevices[i].device->Acquire();
373
374
375 if (pDevices[i].isPolled)
376 ((LPDIRECTINPUTDEVICE2)pDevices[i].device)->Poll();
377
378 hret = pDevices[i].device->GetDeviceState(sizeof(joystick), &joystick);
379
380 int j;
381
382 if (pDevices[i].first) {
383 memcpy(&pDevices[i].state, &joystick, sizeof(joystick));
384 pDevices[i].first = FALSE;
385 continue;
386 }
387
388 for (j = 0; j < pDevices[i].nButtons; j++) {
389 if (((pDevices[i].state.rgbButtons[j] ^ joystick.rgbButtons[j])
390 & joystick.rgbButtons[j]) & 0x80) {
391 HWND focus = GetFocus();
392
393 SendMessage(focus, JOYCONFIG_MESSAGE, i,j+128);
394 }
395 }
396
397 for (j = 0; j < pDevices[i].nAxes && j < 8; j++) {
398 LONG value = pDevices[i].axis[j].center;
399 LONG old = 0;
400
401 const DWORD offset = pDevices[i].axis[j].offset;
402 value = *(LONG*)(((char*)&joystick.lX) + offset);
403 old = *(LONG*)(((char*)&pDevices[i].state.lX) + offset);
404
405 if (value != old) {
406 if (value < pDevices[i].axis[j].negative)
407 SendMessage(GetFocus(), JOYCONFIG_MESSAGE, i, (j<<1));
408 else if (value > pDevices[i].axis[j].positive)
409 SendMessage(GetFocus(), JOYCONFIG_MESSAGE, i, (j<<1)+1);
410 }
411 }
412
413 for (j = 0;j < 4 && j < pDevices[i].nPovs; j++) {
414 if (LOWORD(pDevices[i].state.rgdwPOV[j]) != LOWORD(joystick.rgdwPOV[j])) {
415 int state = getPovState(joystick.rgdwPOV[j]);
416
417 if (state & POV_UP)
418 SendMessage(GetFocus(), JOYCONFIG_MESSAGE, i, (j<<2)+0x20);
419 else if (state & POV_DOWN)
420 SendMessage(GetFocus(), JOYCONFIG_MESSAGE, i, (j<<2)+0x21);
421 else if (state & POV_RIGHT)
422 SendMessage(GetFocus(), JOYCONFIG_MESSAGE, i, (j<<2)+0x22);
423 else if (state & POV_LEFT)
424 SendMessage(GetFocus(), JOYCONFIG_MESSAGE, i, (j<<2)+0x23);
425 }
426 }
427
428 memcpy(&pDevices[i].state, &joystick, sizeof(joystick));
429 }
430 }
431
checkKey(LONG_PTR key)432 BOOL checkKey(LONG_PTR key)
433 {
434 LONG_PTR dev = (key >> 8);
435
436 LONG_PTR k = (key & 255);
437
438 if (dev == 0) {
439 return KEYDOWN(pDevices[0].data,k);
440 } else if (dev >= numDevices) {
441 return FALSE;
442 } else {
443 if (k < 16) {
444 LONG_PTR axis = k >> 1;
445 LONG value = pDevices[dev].axis[axis].center;
446
447 value = *(LONG*)(((char*)&pDevices[dev].state.lX) + pDevices[dev].axis[axis].offset);
448
449 if (k & 1)
450 return value > pDevices[dev].axis[axis].positive;
451 return value < pDevices[dev].axis[axis].negative;
452 } else if (k < 48) {
453 LONG_PTR hat = (k >> 2) & 3;
454 int state = getPovState(pDevices[dev].state.rgdwPOV[hat]);
455 BOOL res = FALSE;
456
457 res = state & (1 << (k & 3));
458
459 return res;
460 } else if (k >= 128) {
461 return pDevices[dev].state.rgbButtons[k-128] & 0x80;
462 }
463 }
464
465 return FALSE;
466 }
467
checkKey(KeyList & k)468 BOOL checkKey(KeyList &k)
469 {
470 POSITION p = k.GetHeadPosition();
471 while(p!=NULL)
472 {
473 if (checkKey(k.GetNext(p)))
474 return TRUE;
475 }
476 return FALSE;
477 }
478
DirectInput()479 DirectInput::DirectInput()
480 {
481 }
482
~DirectInput()483 DirectInput::~DirectInput()
484 {
485 saveSettings();
486 if (pDirectInput != NULL) {
487 if (pDevices) {
488 for (int i = 0; i < numDevices ; i++) {
489 if (pDevices[i].device) {
490 pDevices[i].device->Unacquire();
491 pDevices[i].device->Release();
492 pDevices[i].device = NULL;
493 }
494 }
495 free(pDevices);
496 pDevices = NULL;
497 }
498
499 pDirectInput->Release();
500 pDirectInput = NULL;
501 }
502 }
503
initialize()504 bool DirectInput::initialize()
505 {
506 HRESULT hr;
507
508 hr = DirectInput8Create(
509 GetModuleHandle( NULL ),
510 DIRECTINPUT_VERSION,
511 IID_IDirectInput8,
512 (LPVOID *)&pDirectInput,
513 NULL );
514 ASSERT( hr == DI_OK );
515 if( hr != DI_OK ) return false;
516
517
518 hr = pDirectInput->EnumDevices(DI8DEVCLASS_GAMECTRL,
519 DIEnumDevicesCallback2,
520 NULL,
521 DIEDFL_ATTACHEDONLY);
522
523
524
525 pDevices = (deviceInfo *)calloc(numDevices, sizeof(deviceInfo));
526
527 hr = pDirectInput->CreateDevice(GUID_SysKeyboard,&pDevices[0].device,NULL);
528 pDevices[0].isPolled = false;
529 pDevices[0].needed = true;
530 pDevices[0].first = true;
531
532 if (hr != DI_OK) {
533 return false;
534 }
535
536
537 numDevices = 1;
538
539 hr = pDirectInput->EnumDevices(DI8DEVCLASS_GAMECTRL,
540 DIEnumDevicesCallback,
541 NULL,
542 DIEDFL_ATTACHEDONLY);
543
544
545 if (hr != DI_OK) {
546 return false;
547 }
548
549 hr = pDevices[0].device->SetDataFormat(&c_dfDIKeyboard);
550
551 if (hr != DI_OK) {
552 return false;
553 }
554
555 int i;
556 for (i = 1; i < numDevices; i++) {
557 pDevices[i].device->SetDataFormat(&c_dfDIJoystick);
558 pDevices[i].needed = false;
559 pDevices[i].first = true;
560 currentDevice = &pDevices[i];
561 axisNumber = 0;
562
563 // get up to 6 axes and 2 sliders
564 DIPROPRANGE range;
565 range.diph.dwSize = sizeof(range);
566 range.diph.dwHeaderSize = sizeof(range.diph);
567 range.diph.dwHow = DIPH_BYOFFSET;
568 // screw EnumObjects, just go through all the axis offsets and try to GetProperty
569 // this should be more foolproof, less code, and probably faster
570 for (unsigned int offset = 0; offset < DIJOFS_BUTTON(0); offset += sizeof(LONG))
571 {
572 range.diph.dwObj = offset;
573 // try to set some nice power of 2 values (8192)
574 range.lMin = -(1 << 13);
575 range.lMax = (1 << 13);
576 pDevices[i].device->SetProperty(DIPROP_RANGE, &range.diph);
577 // but i guess not all devices support setting range
578 // so i getproperty right afterward incase it didn't set :P
579 // this also checks that the axis is present
580 if (SUCCEEDED(pDevices[i].device->GetProperty(DIPROP_RANGE, &range.diph)))
581 {
582 const LONG center = (range.lMin + range.lMax)/2;
583 const LONG threshold = (range.lMax - center)/2;
584
585 currentDevice->axis[axisNumber].center = center;
586 currentDevice->axis[axisNumber].negative = center - threshold;
587 currentDevice->axis[axisNumber].positive = center + threshold;
588 currentDevice->axis[axisNumber].offset = offset;
589
590 ++axisNumber;
591 }
592
593 }
594
595 currentDevice->device->EnumObjects(EnumPovsCallback, NULL, DIDFT_POV);
596
597
598 currentDevice = NULL;
599 }
600
601 for (i = 0; i < numDevices; i++)
602 pDevices[i].device->Acquire();
603
604 return true;
605 }
606
readDevices()607 bool DirectInput::readDevices()
608 {
609 bool ok = true;
610 for (int i = 0; i < numDevices; i++) {
611 if (pDevices[i].needed) {
612 if (i) {
613 ok = readJoystick(i);
614 } else
615 ok = readKeyboard();
616 }
617 }
618 return ok;
619 }
620
readDevice(int which)621 u32 DirectInput::readDevice(int which)
622 {
623 u32 res = 0;
624 int i = joypadDefault;
625 if(which >= 0 && which <= 3)
626 i = which;
627
628 if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_A)]))
629 res |= 1;
630 if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_B)]))
631 res |= 2;
632 if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_SELECT)]))
633 res |= 4;
634 if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_START)]))
635 res |= 8;
636 if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_RIGHT)]))
637 res |= 16;
638 if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_LEFT)]))
639 res |= 32;
640 if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_UP)]))
641 res |= 64;
642 if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_DOWN)]))
643 res |= 128;
644 if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_R)]))
645 res |= 256;
646 if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_L)]))
647 res |= 512;
648
649 if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_GS)]))
650 res |= 4096;
651
652 if(autoFire) {
653 res &= (~autoFire);
654 if(autoFireToggle)
655 res |= autoFire;
656 autoFireToggle = !autoFireToggle;
657 }
658
659 // disallow L+R or U+D of being pressed at the same time
660 if((res & 48) == 48)
661 res &= ~16;
662 if((res & 192) == 192)
663 res &= ~128;
664
665 if(movieRecording) {
666 if(i == joypadDefault) {
667 if(res != movieLastJoypad) {
668 fwrite(&movieFrame, 1, sizeof(movieFrame), theApp.movieFile);
669 fwrite(&res, 1, sizeof(res), theApp.movieFile);
670 movieLastJoypad = res;
671 }
672 }
673 }
674 if(moviePlaying) {
675 if(movieFrame == moviePlayFrame) {
676 movieLastJoypad = movieNextJoypad;
677 theApp.movieReadNext();
678 }
679 res = movieLastJoypad;
680 }
681 // we don't record speed up or screen capture buttons
682 if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_SPEED)]) || speedupToggle)
683 res |= 1024;
684 if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_CAPTURE)]))
685 res |= 2048;
686
687 return res;
688 }
689
getKeyName(LONG_PTR key)690 CString DirectInput::getKeyName(LONG_PTR key)
691 {
692 LONG_PTR d = (key >> 8);
693 LONG_PTR k = key & 255;
694
695 DIDEVICEOBJECTINSTANCE di;
696
697 ZeroMemory(&di,sizeof(DIDEVICEOBJECTINSTANCE));
698
699 di.dwSize = sizeof(DIDEVICEOBJECTINSTANCE);
700
701 CString winBuffer = winResLoadString(IDS_ERROR);
702
703 if (d == 0) {
704 pDevices[0].device->GetObjectInfo( &di, (DWORD)key, DIPH_BYOFFSET );
705 winBuffer = di.tszName;
706 } else if (d < numDevices) {
707 if (k < 16)
708 {
709 pDevices[d].device->GetObjectInfo(&di,
710 pDevices[d].axis[k>>1].offset,
711 DIPH_BYOFFSET);
712 if (k & 1)
713 winBuffer.Format("Joy %d %s +", d, di.tszName);
714 else
715 winBuffer.Format("Joy %d %s -", d, di.tszName);
716 } else if (k < 48) {
717 LONG_PTR hat = (k >> 2) & 3;
718 pDevices[d].device->GetObjectInfo(&di,
719 (DWORD)DIJOFS_POV(hat),
720 DIPH_BYOFFSET);
721 char *dir = "up";
722 LONG_PTR dd = k & 3;
723 if (dd == 1)
724 dir = "down";
725 else if (dd == 2)
726 dir = "right";
727 else if (dd == 3)
728 dir = "left";
729 winBuffer.Format("Joy %d %s %s", d, di.tszName, dir);
730 } else {
731 pDevices[d].device->GetObjectInfo(&di,
732 (DWORD)DIJOFS_BUTTON(k-128),
733 DIPH_BYOFFSET);
734 winBuffer.Format(winResLoadString(IDS_JOY_BUTTON),d,di.tszName);
735 }
736 }
737 else
738 {
739 // Joystick isn't plugged in. We can't decipher k, so just show its value.
740 winBuffer.Format("Joy %d (%d)", d, k);
741 }
742
743 return winBuffer;
744 }
745
checkKeys()746 void DirectInput::checkKeys()
747 {
748 ::checkKeys();
749 }
750
checkMotionKeys()751 void DirectInput::checkMotionKeys()
752 {
753 if(checkKey(theApp.input->joypaddata[MOTION(KEY_LEFT)])) {
754 sunBars--;
755 if (sunBars < 1)
756 sunBars = 1;
757
758 sensorX += 3;
759 if(sensorX > 2197)
760 sensorX = 2197;
761 if(sensorX < 2047)
762 sensorX = 2057;
763 } else if(checkKey(theApp.input->joypaddata[MOTION(KEY_RIGHT)])) {
764 sunBars++;
765 if (sunBars > 100)
766 sunBars = 100;
767
768 sensorX -= 3;
769 if(sensorX < 1897)
770 sensorX = 1897;
771 if(sensorX > 2047)
772 sensorX = 2037;
773 } else if(sensorX > 2047) {
774 sensorX -= 2;
775 if(sensorX < 2047)
776 sensorX = 2047;
777 } else {
778 sensorX += 2;
779 if(sensorX > 2047)
780 sensorX = 2047;
781 }
782
783 if(checkKey(theApp.input->joypaddata[MOTION(KEY_UP)])) {
784 sensorY += 3;
785 if(sensorY > 2197)
786 sensorY = 2197;
787 if(sensorY < 2047)
788 sensorY = 2057;
789 } else if(checkKey(theApp.input->joypaddata[MOTION(KEY_DOWN)])) {
790 sensorY -= 3;
791 if(sensorY < 1897)
792 sensorY = 1897;
793 if(sensorY > 2047)
794 sensorY = 2037;
795 } else if(sensorY > 2047) {
796 sensorY -= 2;
797 if(sensorY < 2047)
798 sensorY = 2047;
799 } else {
800 sensorY += 2;
801 if(sensorY > 2047)
802 sensorY = 2047;
803 }
804 }
805
newDirectInput()806 Input *newDirectInput()
807 {
808 return new DirectInput;
809 }
810
811
checkDevices()812 void DirectInput::checkDevices()
813 {
814 checkJoypads();
815 checkKeyboard();
816 }
817
activate()818 void DirectInput::activate()
819 {
820 for (int i = 0; i < numDevices; i++) {
821 if (pDevices != NULL && pDevices[i].device != NULL)
822 pDevices[i].device->Acquire();
823 }
824 }
825
loadSettings()826 void DirectInput::loadSettings()
827 {
828 winReadKeys();
829 }
830
saveSettings()831 void DirectInput::saveSettings()
832 {
833 winSaveKeys();
834 }
835