20 #define DIRECTINPUT_VERSION 0x0700
24 #define JOY_POVUPRIGHT 4500
25 #define JOY_POVDNRIGHT 13500
26 #define JOY_POVDNLEFT 22500
27 #define JOY_POVUPLEFT 31500
34 static LPDIRECTINPUT7 pdi = 0;
35 static LPDIRECTINPUTDEVICE7 pdev = 0;
39 static int strikes = 3;
50 : x(0), y(0), z(0), p(0), r(0), w(0), t(0)
67 for (
int i = 0; i < 4; i++) {
68 for (
int j = 0; j < 4; j++) {
84 Print(
"Joystick: DI7 not found, using multimedia library\n");
101 Print(
"Joystick: initialized DI7 pdi = %08x\n", (DWORD) pdi);
136 ZeroMemory(
map,
sizeof(
map));
138 for (
int i = 0; i < nkeys; i++) {
209 static inline double sqr(
double a) {
return a*a; }
211 BOOL FAR PASCAL
EnumJoystick(LPCDIDEVICEINSTANCE pdinst, LPVOID pvSelect)
213 CopyMemory(&devices[ndev++], pdinst, pdinst->dwSize);
215 ::Print(
"EnumJoystick %d: '%s'\n", ndev, pdinst->tszInstanceName);
216 ::Print(
" guid: {%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x} \n",
217 (DWORD) pdinst->guidInstance.Data1,
218 (WORD) pdinst->guidInstance.Data2,
219 (WORD) pdinst->guidInstance.Data3,
220 (BYTE) pdinst->guidInstance.Data4[0],
221 (BYTE) pdinst->guidInstance.Data4[1],
222 (BYTE) pdinst->guidInstance.Data4[2],
223 (BYTE) pdinst->guidInstance.Data4[3],
224 (BYTE) pdinst->guidInstance.Data4[4],
225 (BYTE) pdinst->guidInstance.Data4[5]);
228 return DIENUM_CONTINUE;
235 if (!pdi || ndev < select)
238 LPCDIDEVICEINSTANCE pdinst = &devices[select-1];
240 ::Print(
"Joystick CreateDevice(%d)\n", select);
241 ::Print(
" name: %s\n\n", pdinst->tszInstanceName);
252 hr = pdi->CreateDeviceEx(pdinst->guidInstance,
253 IID_IDirectInputDevice7,
257 if (hr != DI_OK || pdev == 0) {
263 hr = pdev->SetDataFormat(&c_dfDIJoystick);
273 hr = pdev->SetCooperativeLevel(
Game::GetHWND(), DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
286 diprg.diph.dwSize =
sizeof(diprg);
287 diprg.diph.dwHeaderSize =
sizeof(diprg.diph);
288 diprg.diph.dwObj = DIJOFS_X;
289 diprg.diph.dwHow = DIPH_BYOFFSET;
290 pdev->SetProperty(DIPROP_RANGE, &diprg.diph);
292 diprg.diph.dwObj = DIJOFS_Y;
293 pdev->SetProperty(DIPROP_RANGE, &diprg.diph);
295 diprg.diph.dwObj = DIJOFS_Z;
296 pdev->SetProperty(DIPROP_RANGE, &diprg.diph);
298 diprg.diph.dwObj = DIJOFS_RX;
299 pdev->SetProperty(DIPROP_RANGE, &diprg.diph);
301 diprg.diph.dwObj = DIJOFS_RY;
302 pdev->SetProperty(DIPROP_RANGE, &diprg.diph);
304 diprg.diph.dwObj = DIJOFS_RZ;
305 pdev->SetProperty(DIPROP_RANGE, &diprg.diph);
307 diprg.diph.dwObj = DIJOFS_SLIDER(0);
308 pdev->SetProperty(DIPROP_RANGE, &diprg.diph);
310 diprg.diph.dwObj = DIJOFS_SLIDER(1);
311 pdev->SetProperty(DIPROP_RANGE, &diprg.diph);
313 ::Print(
"Created joystick %d (pdev = %08x)\n", select, (DWORD) pdev);
322 Print(
"Joystick: no DI7, unable to enumerate devices\n");
327 Print(
"Joystick: preparing to enumerate devices\n");
331 pdi->EnumDevices(DIDEVTYPE_JOYSTICK,
334 DIEDFL_ATTACHEDONLY);
342 Print(
"Joystick: no devices found\n");
357 if (i >= 0 && i < ndev)
358 return devices[i].tszInstanceName;
365 static DIJOYSTATE joystate;
366 static JOYINFOEX joyinfo;
392 if (joyinfo.dwFlags & JOY_RETURNX)
393 result = joyinfo.dwXpos;
397 if (joyinfo.dwFlags & JOY_RETURNY)
398 result = joyinfo.dwYpos;
402 if (joyinfo.dwFlags & JOY_RETURNZ)
403 result = joyinfo.dwZpos;
407 if (joyinfo.dwFlags & JOY_RETURNR)
408 result = joyinfo.dwRpos;
441 double scale = 1.0 / (32768.0-
dead_zone);
444 result = sqr(result * scale);
446 result = sqr(result * scale) * -1.0;
452 result = (result+32768.0) / 65536.0;
472 if (joyinfo.dwFlags & JOY_RETURNX)
473 result = joyinfo.dwXpos - 32768;
477 if (joyinfo.dwFlags & JOY_RETURNY)
478 result = joyinfo.dwYpos - 32768;
482 if (joyinfo.dwFlags & JOY_RETURNZ)
483 result = joyinfo.dwZpos - 32768;
487 if (joyinfo.dwFlags & JOY_RETURNR)
488 result = joyinfo.dwRpos - 32768;
498 double scale = 1.0 / (32768.0-
dead_zone);
501 result = sqr(result * scale);
503 result = sqr(result * scale) * -1.0;
509 result = (result+32768.0) / 65536.0;
527 for (
int i = 0; i < 4; i++)
528 for (
int j = 0; j < 4; j++)
538 bool acquired =
false;
553 hr = pdev->GetDeviceState(
sizeof(joystate), &joystate);
555 if (hr == DIERR_INPUTLOST) {
559 hr = pdev->GetDeviceState(
sizeof(joystate), &joystate);
563 ::Print(
"Joystick could not re-acquire joystick (%08x)\n", hr);
576 for (
int i = 0; i < 32; i++)
577 action[i] = (joystate.rgbButtons[i] & 0x80) != 0;
584 int joy_p = joystate.rgdwPOV[0];
588 for (
int i = 0; i < 4; i++)
600 memset(&joyinfo, 0,
sizeof(JOYINFOEX));
601 joyinfo.dwSize =
sizeof(JOYINFOEX);
602 joyinfo.dwFlags = JOY_RETURNALL;
607 hr = joyGetPosEx(JOYSTICKID1, &joyinfo);
610 hr = joyGetPosEx(JOYSTICKID2, &joyinfo);
613 Print(
"\nJoystick::Acquire() joyGetPosEx %d failed (err=%08x)\n\n",
select, hr);
617 action[0] = (joyinfo.dwButtons & JOY_BUTTON1) ?
true :
false;
618 action[1] = (joyinfo.dwButtons & JOY_BUTTON2) ?
true :
false;
619 action[2] = (joyinfo.dwButtons & JOY_BUTTON3) ?
true :
false;
620 action[3] = (joyinfo.dwButtons & JOY_BUTTON4) ?
true :
false;
642 const double steps=10;
643 static double p1=0, r1=0, w1=0;
716 static double init_throttle = -1;
717 static bool latch_throttle =
false;
719 if (init_throttle < 0)
720 init_throttle = joy_t;
721 else if (init_throttle != joy_t)
722 latch_throttle =
true;
737 if (i < 0 || i > 3)
return;
739 if (LOWORD(joy_pov) == 0xFFFF)
743 case JOY_POVFORWARD:
hat[i][0] =
true;
break;
744 case JOY_POVBACKWARD:
hat[i][1] =
true;
break;
745 case JOY_POVLEFT:
hat[i][2] =
true;
break;
746 case JOY_POVRIGHT:
hat[i][3] =
true;
break;
749 hat[i][3] =
true;
break;
752 hat[i][3] =
true;
break;
755 hat[i][2] =
true;
break;
758 hat[i][2] =
true;
break;
806 if (!joystick || n < 0 || n > 3)
814 if (!joystick || n < 0 || n > 3)
825 static int report = 50;
834 static char errstrbuf[128];
840 sprintf_s(errstrbuf,
"Unrecognized error value = %08x.", hr);
846 case DI_BUFFEROVERFLOW:
847 return "The device buffer overflowed and some input was lost. This value is equal to the S_FALSE standard COM return value.";
848 case DI_DOWNLOADSKIPPED:
849 return "The parameters of the effect were successfully updated, but the effect could not be downloaded because the associated device was not acquired in exclusive mode.";
850 case DI_EFFECTRESTARTED:
851 return "The effect was stopped, the parameters were updated, and the effect was restarted.";
852 case DI_POLLEDDEVICE:
853 return "The device is a polled device. As a result, device buffering does not collect any data and event notifications is not signaled until the IDirectInputDevice7::Poll method is called.";
855 return "The parameters of the effect were successfully updated, but some of them were beyond the capabilities of the device and were truncated to the nearest supported value.";
856 case DI_TRUNCATEDANDRESTARTED:
857 return "Equal to DI_EFFECTRESTARTED | DI_TRUNCATED";
859 return "The operation cannot be performed while the device is acquired.";
860 case DIERR_ALREADYINITIALIZED:
861 return "This object is already initialized";
862 case DIERR_BADDRIVERVER:
863 return "The object could not be created due to an incompatible driver version or mismatched or incomplete driver components.";
864 case DIERR_BETADIRECTINPUTVERSION:
865 return "The application was written for an unsupported prerelease version of DirectInput.";
866 case DIERR_DEVICEFULL:
867 return "The device is full.";
868 case DIERR_DEVICENOTREG:
869 return "The device or device instance is not registered with DirectInput. This value is equal to the REGDB_E_CLASSNOTREG standard COM return value.";
870 case DIERR_EFFECTPLAYING:
871 return "The parameters were updated in memory but were not downloaded to the device because the device does not support updating an effect while it is still playing.";
872 case DIERR_HASEFFECTS:
873 return "The device cannot be reinitialized because there are still effects attached to it.";
875 return "An undetermined error occurred inside the DirectInput subsystem. This value is equal to the E_FAIL standard COM return value.";
876 case DIERR_HANDLEEXISTS:
877 return "The device already has an event notification associated with it. This value is equal to the E_ACCESSDENIED standard COM return value.";
878 case DIERR_INCOMPLETEEFFECT:
879 return "The effect could not be downloaded because essential information is missing. For example, no axes have been associated with the effect, or no type-specific information has been supplied.";
880 case DIERR_INPUTLOST:
881 return "Access to the input device has been lost. It must be reacquired.";
882 case DIERR_INVALIDPARAM:
883 return "An invalid parameter was passed to the returning function, or the object was not in a state that permitted the function to be called. This value is equal to the E_INVALIDARG standard COM return value.";
885 return "Not all the requested information fit into the buffer.";
886 case DIERR_NOAGGREGATION:
887 return "This object does not support aggregation.";
888 case DIERR_NOINTERFACE:
889 return "The specified interface is not supported by the object. This value is equal to the E_NOINTERFACE standard COM return value.";
890 case DIERR_NOTACQUIRED:
891 return "The operation cannot be performed unless the device is acquired.";
892 case DIERR_NOTBUFFERED:
893 return "The device is not buffered. Set the DIPROP_BUFFERSIZE property to enable buffering.";
894 case DIERR_NOTDOWNLOADED:
895 return "The effect is not downloaded.";
896 case DIERR_NOTEXCLUSIVEACQUIRED:
897 return "The operation cannot be performed unless the device is acquired in DISCL_EXCLUSIVE mode.";
899 return "The requested object does not exist.";
900 case DIERR_NOTINITIALIZED:
901 return "This object has not been initialized.";
902 case DIERR_OLDDIRECTINPUTVERSION:
903 return "The application requires a newer version of DirectInput.";
904 case DIERR_OUTOFMEMORY:
905 return "The DirectInput subsystem could not allocate sufficient memory to complete the call. This value is equal to the E_OUTOFMEMORY standard COM return value.";
906 case DIERR_REPORTFULL:
907 return "More information was requested to be sent than can be sent to the device.";
908 case DIERR_UNPLUGGED:
909 return "The operation could not be completed because the device is not plugged in.";
910 case DIERR_UNSUPPORTED:
911 return "The function called is not supported at this time. This value is equal to the E_NOTIMPL standard COM return value.";