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