33 #define _GLFW_TYPE_AXIS 0 34 #define _GLFW_TYPE_SLIDER 1 35 #define _GLFW_TYPE_BUTTON 2 36 #define _GLFW_TYPE_POV 3 54 {0xbf798031,0x483a,0x4da2,{0xaa,0x99,0x5d,0x64,0xed,0x36,0x97,0x00}};
56 {0xa36d02e0,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
58 {0xa36d02e1,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
60 {0xa36d02e2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
62 {0xa36d02f4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
64 {0xa36d02f5,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
66 {0xa36d02e3,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
68 {0xa36d02e4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
70 {0xa36d02f2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
72 #define IID_IDirectInput8W _glfw_IID_IDirectInput8W 73 #define GUID_XAxis _glfw_GUID_XAxis 74 #define GUID_YAxis _glfw_GUID_YAxis 75 #define GUID_ZAxis _glfw_GUID_ZAxis 76 #define GUID_RxAxis _glfw_GUID_RxAxis 77 #define GUID_RyAxis _glfw_GUID_RyAxis 78 #define GUID_RzAxis _glfw_GUID_RzAxis 79 #define GUID_Slider _glfw_GUID_Slider 80 #define GUID_POV _glfw_GUID_POV 99 { NULL,DIJOFS_BUTTON(0),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
100 { NULL,DIJOFS_BUTTON(1),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
101 { NULL,DIJOFS_BUTTON(2),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
102 { NULL,DIJOFS_BUTTON(3),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
103 { NULL,DIJOFS_BUTTON(4),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
104 { NULL,DIJOFS_BUTTON(5),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
105 { NULL,DIJOFS_BUTTON(6),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
106 { NULL,DIJOFS_BUTTON(7),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
107 { NULL,DIJOFS_BUTTON(8),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
108 { NULL,DIJOFS_BUTTON(9),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
109 { NULL,DIJOFS_BUTTON(10),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
110 { NULL,DIJOFS_BUTTON(11),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
111 { NULL,DIJOFS_BUTTON(12),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
112 { NULL,DIJOFS_BUTTON(13),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
113 { NULL,DIJOFS_BUTTON(14),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
114 { NULL,DIJOFS_BUTTON(15),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
115 { NULL,DIJOFS_BUTTON(16),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
116 { NULL,DIJOFS_BUTTON(17),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
117 { NULL,DIJOFS_BUTTON(18),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
118 { NULL,DIJOFS_BUTTON(19),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
119 { NULL,DIJOFS_BUTTON(20),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
120 { NULL,DIJOFS_BUTTON(21),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
121 { NULL,DIJOFS_BUTTON(22),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
122 { NULL,DIJOFS_BUTTON(23),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
123 { NULL,DIJOFS_BUTTON(24),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
124 { NULL,DIJOFS_BUTTON(25),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
125 { NULL,DIJOFS_BUTTON(26),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
126 { NULL,DIJOFS_BUTTON(27),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
127 { NULL,DIJOFS_BUTTON(28),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
128 { NULL,DIJOFS_BUTTON(29),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
129 { NULL,DIJOFS_BUTTON(30),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
130 { NULL,DIJOFS_BUTTON(31),DIDFT_BUTTON|
DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
137 sizeof(DIDATAFORMAT),
138 sizeof(DIOBJECTDATAFORMAT),
149 switch (xic->SubType)
152 return "XInput Wheel";
154 return "XInput Arcade Stick";
156 return "XInput Flight Stick";
158 return "XInput Dance Pad";
160 return "XInput Guitar";
162 return "XInput Drum Kit";
163 case XINPUT_DEVSUBTYPE_GAMEPAD:
166 return "Wireless Xbox Controller";
168 return "Xbox Controller";
172 return "Unknown XInput Device";
194 RAWINPUTDEVICELIST* ridl;
197 if (GetRawInputDeviceList(NULL, &count,
sizeof(RAWINPUTDEVICELIST)) != 0)
200 ridl = calloc(count,
sizeof(RAWINPUTDEVICELIST));
202 if (GetRawInputDeviceList(ridl, &count,
sizeof(RAWINPUTDEVICELIST)) == (UINT) -1)
208 for (i = 0; i < count; i++)
214 if (ridl[i].dwType != RIM_TYPEHID)
217 ZeroMemory(&rdi,
sizeof(rdi));
218 rdi.cbSize =
sizeof(rdi);
221 if ((INT) GetRawInputDeviceInfoA(ridl[i].hDevice,
228 if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) != (LONG) guid->Data1)
231 memset(name, 0,
sizeof(name));
234 if ((INT) GetRawInputDeviceInfoA(ridl[i].hDevice,
241 name[
sizeof(name) - 1] =
'\0';
242 if (strstr(name,
"IG_"))
257 if (js->win32.device)
259 IDirectInputDevice8_Unacquire(js->win32.device);
260 IDirectInputDevice8_Release(js->win32.device);
263 free(js->win32.objects);
278 if (DIDFT_GETTYPE(doi->dwType) & DIDFT_AXIS)
282 if (memcmp(&doi->guidType, &
GUID_Slider,
sizeof(GUID)) == 0)
284 else if (memcmp(&doi->guidType, &
GUID_XAxis,
sizeof(GUID)) == 0)
285 object->offset = DIJOFS_X;
286 else if (memcmp(&doi->guidType, &
GUID_YAxis,
sizeof(GUID)) == 0)
287 object->offset = DIJOFS_Y;
288 else if (memcmp(&doi->guidType, &
GUID_ZAxis,
sizeof(GUID)) == 0)
289 object->offset = DIJOFS_Z;
290 else if (memcmp(&doi->guidType, &
GUID_RxAxis,
sizeof(GUID)) == 0)
291 object->offset = DIJOFS_RX;
292 else if (memcmp(&doi->guidType, &
GUID_RyAxis,
sizeof(GUID)) == 0)
293 object->offset = DIJOFS_RY;
294 else if (memcmp(&doi->guidType, &
GUID_RzAxis,
sizeof(GUID)) == 0)
295 object->offset = DIJOFS_RZ;
297 return DIENUM_CONTINUE;
299 ZeroMemory(&dipr,
sizeof(dipr));
300 dipr.diph.dwSize =
sizeof(dipr);
301 dipr.diph.dwHeaderSize =
sizeof(dipr.diph);
302 dipr.diph.dwObj = doi->dwType;
303 dipr.diph.dwHow = DIPH_BYID;
307 if (FAILED(IDirectInputDevice8_SetProperty(data->
device,
311 return DIENUM_CONTINUE;
314 if (memcmp(&doi->guidType, &
GUID_Slider,
sizeof(GUID)) == 0)
325 else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_BUTTON)
331 else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_POV)
333 object->offset = DIJOFS_POV(data->
povCount);
339 return DIENUM_CONTINUE;
349 IDirectInputDevice8*
device;
360 if (memcmp(&js->win32.
guid, &di->guidInstance,
sizeof(GUID)) == 0)
361 return DIENUM_CONTINUE;
366 return DIENUM_CONTINUE;
368 if (FAILED(IDirectInput8_CreateDevice(
_glfw.win32.dinput8.api,
374 return DIENUM_CONTINUE;
377 if (FAILED(IDirectInputDevice8_SetDataFormat(device, &
_glfwDataFormat)))
380 "Win32: Failed to set device data format");
382 IDirectInputDevice8_Release(device);
383 return DIENUM_CONTINUE;
386 ZeroMemory(&dc,
sizeof(dc));
387 dc.dwSize =
sizeof(dc);
389 if (FAILED(IDirectInputDevice8_GetCapabilities(device, &dc)))
392 "Win32: Failed to query device capabilities");
394 IDirectInputDevice8_Release(device);
395 return DIENUM_CONTINUE;
398 ZeroMemory(&dipd,
sizeof(dipd));
399 dipd.diph.dwSize =
sizeof(dipd);
400 dipd.diph.dwHeaderSize =
sizeof(dipd.diph);
401 dipd.diph.dwHow = DIPH_DEVICE;
402 dipd.dwData = DIPROPAXISMODE_ABS;
404 if (FAILED(IDirectInputDevice8_SetProperty(device,
409 "Win32: Failed to set device axis mode");
411 IDirectInputDevice8_Release(device);
412 return DIENUM_CONTINUE;
415 memset(&data, 0,
sizeof(data));
417 data.
objects = calloc(dc.dwAxes + dc.dwButtons + dc.dwPOVs,
420 if (FAILED(IDirectInputDevice8_EnumObjects(device,
423 DIDFT_AXIS | DIDFT_BUTTON | DIDFT_POV)))
426 "Win32: Failed to enumerate device objects");
428 IDirectInputDevice8_Release(device);
430 return DIENUM_CONTINUE;
437 if (!WideCharToMultiByte(CP_UTF8, 0,
438 di->tszInstanceName, -1,
443 "Win32: Failed to convert joystick name to UTF-8");
445 IDirectInputDevice8_Release(device);
451 if (memcmp(&di->guidProduct.Data4[2],
"PIDVID", 6) == 0)
453 sprintf(guid,
"03000000%02x%02x0000%02x%02x000000000000",
454 (uint8_t) di->guidProduct.Data1,
455 (uint8_t) (di->guidProduct.Data1 >> 8),
456 (uint8_t) (di->guidProduct.Data1 >> 16),
457 (uint8_t) (di->guidProduct.Data1 >> 24));
461 sprintf(guid,
"05000000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
462 name[0], name[1], name[2], name[3],
463 name[4], name[5], name[6], name[7],
464 name[8], name[9], name[10]);
473 IDirectInputDevice8_Release(device);
478 js->win32.device =
device;
479 js->win32.
guid = di->guidInstance;
480 js->win32.objects = data.
objects;
484 return DIENUM_CONTINUE;
496 if (
_glfw.win32.dinput8.instance)
501 (
void**) &
_glfw.win32.dinput8.api,
505 "Win32: Failed to create interface");
521 if (
_glfw.win32.dinput8.api)
522 IDirectInput8_Release(
_glfw.win32.dinput8.api);
529 if (
_glfw.win32.xinput.instance)
537 XINPUT_CAPABILITIES xic;
557 sprintf(guid,
"78696e707574%02x000000000000000000",
564 js->win32.index = index;
570 if (
_glfw.win32.dinput8.api)
572 if (FAILED(IDirectInput8_EnumDevices(
_glfw.win32.dinput8.api,
573 DI8DEVCLASS_GAMECTRL,
579 "Failed to enumerate DirectInput8 devices");
606 if (js->win32.device)
608 int i, ai = 0, bi = 0, pi = 0;
612 IDirectInputDevice8_Poll(js->win32.device);
613 result = IDirectInputDevice8_GetDeviceState(js->win32.device,
616 if (result == DIERR_NOTACQUIRED || result == DIERR_INPUTLOST)
618 IDirectInputDevice8_Acquire(js->win32.device);
619 IDirectInputDevice8_Poll(js->win32.device);
620 result = IDirectInputDevice8_GetDeviceState(js->win32.device,
634 for (i = 0; i < js->win32.objectCount; i++)
636 const void* data = (
char*) &state + js->win32.objects[i].offset;
638 switch (js->win32.objects[i].type)
643 const float value = (*((LONG*) data) + 0.5f) / 32767.5
f;
651 const char value = (*((
BYTE*) data) & 0x80) != 0;
659 const int states[9] =
673 int state = LOWORD(*(DWORD*) data) / (45 * DI_DEGREES);
674 if (state < 0 || state > 8)
689 const WORD buttons[10] =
695 XINPUT_GAMEPAD_LEFT_SHOULDER,
696 XINPUT_GAMEPAD_RIGHT_SHOULDER,
698 XINPUT_GAMEPAD_START,
699 XINPUT_GAMEPAD_LEFT_THUMB,
700 XINPUT_GAMEPAD_RIGHT_THUMB
704 if (result != ERROR_SUCCESS)
706 if (result == ERROR_DEVICE_NOT_CONNECTED)
722 for (i = 0; i < 10; i++)
724 const char value = (xis.Gamepad.wButtons & buttons[i]) ? 1 : 0;
728 if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)
730 if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
732 if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)
734 if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
745 if (strcmp(guid + 20,
"504944564944") == 0)
748 strcpy(original, guid);
749 sprintf(guid,
"03000000%.4s0000%.4s000000000000",
750 original, original + 4);
static const GUID _glfw_GUID_XAxis
static const GUID _glfw_IID_IDirectInput8W
static const DIDATAFORMAT _glfwDataFormat
static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE *di, void *user)
void _glfwDetectJoystickConnectionWin32(void)
void _glfwTerminateJoysticksWin32(void)
void _glfwPlatformUpdateGamepadGUID(char *guid)
#define _GLFW_POLL_PRESENCE
#define IID_IDirectInput8W
#define _GLFW_TYPE_BUTTON
#define GLFW_DISCONNECTED
static const GUID _glfw_GUID_RzAxis
static int compareJoystickObjects(const void *first, const void *second)
#define GLFW_PLATFORM_ERROR
A platform-specific error occurred that does not match any of the more specific categories.
static const GUID _glfw_GUID_RxAxis
static const GUID _glfw_GUID_Slider
#define GLFW_JOYSTICK_LAST
#define GLFW_HAT_RIGHT_DOWN
void _glfwInputError(int code, const char *format,...)
void _glfwInitJoysticksWin32(void)
_GLFWjoyobjectWin32 * objects
#define _GLFW_TYPE_SLIDER
static DIOBJECTDATAFORMAT _glfwObjectDataFormats[]
#define GLFW_HAT_RIGHT_UP
static const GUID _glfw_GUID_YAxis
int _glfwPlatformPollJoystick(_GLFWjoystick *js, int mode)
IDirectInputDevice8W * device
#define GLFW_HAT_LEFT_DOWN
static const GUID _glfw_GUID_RyAxis
static const GUID _glfw_GUID_POV
static GLFWbool supportsXInput(const GUID *guid)
#define GLFW_HAT_CENTERED
void _glfwDetectJoystickDisconnectionWin32(void)
static const GUID _glfw_GUID_ZAxis
static void closeJoystick(_GLFWjoystick *js)
static const char * getDeviceDescription(const XINPUT_CAPABILITIES *xic)
_GLFWjoystick joysticks[GLFW_JOYSTICK_LAST+1]
static BOOL CALLBACK deviceObjectCallback(const DIDEVICEOBJECTINSTANCEW *doi, void *user)
struct _GLFWobjenumWin32 _GLFWobjenumWin32