+++ /dev/null
-//========================================================================
-// GLFW 3.4 Win32 - www.glfw.org
-//------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Marcus Geelnard
-// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would
-// be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such, and must not
-// be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source
-// distribution.
-//
-//========================================================================
-// Please use C89 style variable declarations in this file because VS 2010
-//========================================================================
-
-#include "internal.h"
-
-#include <stdio.h>
-#include <math.h>
-
-#define _GLFW_TYPE_AXIS 0
-#define _GLFW_TYPE_SLIDER 1
-#define _GLFW_TYPE_BUTTON 2
-#define _GLFW_TYPE_POV 3
-
-// Data produced with DirectInput device object enumeration
-//
-typedef struct _GLFWobjenumWin32
-{
- IDirectInputDevice8W* device;
- _GLFWjoyobjectWin32* objects;
- int objectCount;
- int axisCount;
- int sliderCount;
- int buttonCount;
- int povCount;
-} _GLFWobjenumWin32;
-
-// Define local copies of the necessary GUIDs
-//
-static const GUID _glfw_IID_IDirectInput8W =
- {0xbf798031,0x483a,0x4da2,{0xaa,0x99,0x5d,0x64,0xed,0x36,0x97,0x00}};
-static const GUID _glfw_GUID_XAxis =
- {0xa36d02e0,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
-static const GUID _glfw_GUID_YAxis =
- {0xa36d02e1,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
-static const GUID _glfw_GUID_ZAxis =
- {0xa36d02e2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
-static const GUID _glfw_GUID_RxAxis =
- {0xa36d02f4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
-static const GUID _glfw_GUID_RyAxis =
- {0xa36d02f5,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
-static const GUID _glfw_GUID_RzAxis =
- {0xa36d02e3,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
-static const GUID _glfw_GUID_Slider =
- {0xa36d02e4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
-static const GUID _glfw_GUID_POV =
- {0xa36d02f2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
-
-#define IID_IDirectInput8W _glfw_IID_IDirectInput8W
-#define GUID_XAxis _glfw_GUID_XAxis
-#define GUID_YAxis _glfw_GUID_YAxis
-#define GUID_ZAxis _glfw_GUID_ZAxis
-#define GUID_RxAxis _glfw_GUID_RxAxis
-#define GUID_RyAxis _glfw_GUID_RyAxis
-#define GUID_RzAxis _glfw_GUID_RzAxis
-#define GUID_Slider _glfw_GUID_Slider
-#define GUID_POV _glfw_GUID_POV
-
-// Object data array for our clone of c_dfDIJoystick
-// Generated with https://github.com/elmindreda/c_dfDIJoystick2
-//
-static DIOBJECTDATAFORMAT _glfwObjectDataFormats[] =
-{
- { &GUID_XAxis,DIJOFS_X,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
- { &GUID_YAxis,DIJOFS_Y,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
- { &GUID_ZAxis,DIJOFS_Z,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
- { &GUID_RxAxis,DIJOFS_RX,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
- { &GUID_RyAxis,DIJOFS_RY,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
- { &GUID_RzAxis,DIJOFS_RZ,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
- { &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
- { &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
- { &GUID_POV,DIJOFS_POV(0),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { &GUID_POV,DIJOFS_POV(1),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { &GUID_POV,DIJOFS_POV(2),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { &GUID_POV,DIJOFS_POV(3),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(0),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(1),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(2),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(3),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(4),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(5),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(6),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(7),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(8),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(9),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(10),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(11),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(12),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(13),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(14),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(15),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(16),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(17),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(18),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(19),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(20),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(21),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(22),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(23),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(24),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(25),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(26),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(27),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(28),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(29),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(30),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
- { NULL,DIJOFS_BUTTON(31),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
-};
-
-// Our clone of c_dfDIJoystick
-//
-static const DIDATAFORMAT _glfwDataFormat =
-{
- sizeof(DIDATAFORMAT),
- sizeof(DIOBJECTDATAFORMAT),
- DIDFT_ABSAXIS,
- sizeof(DIJOYSTATE),
- sizeof(_glfwObjectDataFormats) / sizeof(DIOBJECTDATAFORMAT),
- _glfwObjectDataFormats
-};
-
-// Returns a description fitting the specified XInput capabilities
-//
-static const char* getDeviceDescription(const XINPUT_CAPABILITIES* xic)
-{
- switch (xic->SubType)
- {
- case XINPUT_DEVSUBTYPE_WHEEL:
- return "XInput Wheel";
- case XINPUT_DEVSUBTYPE_ARCADE_STICK:
- return "XInput Arcade Stick";
- case XINPUT_DEVSUBTYPE_FLIGHT_STICK:
- return "XInput Flight Stick";
- case XINPUT_DEVSUBTYPE_DANCE_PAD:
- return "XInput Dance Pad";
- case XINPUT_DEVSUBTYPE_GUITAR:
- return "XInput Guitar";
- case XINPUT_DEVSUBTYPE_DRUM_KIT:
- return "XInput Drum Kit";
- case XINPUT_DEVSUBTYPE_GAMEPAD:
- {
- if (xic->Flags & XINPUT_CAPS_WIRELESS)
- return "Wireless Xbox Controller";
- else
- return "Xbox Controller";
- }
- }
-
- return "Unknown XInput Device";
-}
-
-// Lexically compare device objects
-//
-static int compareJoystickObjects(const void* first, const void* second)
-{
- const _GLFWjoyobjectWin32* fo = first;
- const _GLFWjoyobjectWin32* so = second;
-
- if (fo->type != so->type)
- return fo->type - so->type;
-
- return fo->offset - so->offset;
-}
-
-// Checks whether the specified device supports XInput
-// Technique from FDInputJoystickManager::IsXInputDeviceFast in ZDoom
-//
-static GLFWbool supportsXInput(const GUID* guid)
-{
- UINT i, count = 0;
- RAWINPUTDEVICELIST* ridl;
- GLFWbool result = GLFW_FALSE;
-
- if (GetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)) != 0)
- return GLFW_FALSE;
-
- ridl = calloc(count, sizeof(RAWINPUTDEVICELIST));
-
- if (GetRawInputDeviceList(ridl, &count, sizeof(RAWINPUTDEVICELIST)) == (UINT) -1)
- {
- free(ridl);
- return GLFW_FALSE;
- }
-
- for (i = 0; i < count; i++)
- {
- RID_DEVICE_INFO rdi;
- char name[256];
- UINT size;
-
- if (ridl[i].dwType != RIM_TYPEHID)
- continue;
-
- ZeroMemory(&rdi, sizeof(rdi));
- rdi.cbSize = sizeof(rdi);
- size = sizeof(rdi);
-
- if ((INT) GetRawInputDeviceInfoA(ridl[i].hDevice,
- RIDI_DEVICEINFO,
- &rdi, &size) == -1)
- {
- continue;
- }
-
- if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) != (LONG) guid->Data1)
- continue;
-
- memset(name, 0, sizeof(name));
- size = sizeof(name);
-
- if ((INT) GetRawInputDeviceInfoA(ridl[i].hDevice,
- RIDI_DEVICENAME,
- name, &size) == -1)
- {
- break;
- }
-
- name[sizeof(name) - 1] = '\0';
- if (strstr(name, "IG_"))
- {
- result = GLFW_TRUE;
- break;
- }
- }
-
- free(ridl);
- return result;
-}
-
-// Frees all resources associated with the specified joystick
-//
-static void closeJoystick(_GLFWjoystick* js)
-{
- if (js->win32.device)
- {
- IDirectInputDevice8_Unacquire(js->win32.device);
- IDirectInputDevice8_Release(js->win32.device);
- }
-
- free(js->win32.objects);
-
- _glfwFreeJoystick(js);
- _glfwInputJoystick(js, GLFW_DISCONNECTED);
-}
-
-// DirectInput device object enumeration callback
-// Insights gleaned from SDL
-//
-static BOOL CALLBACK deviceObjectCallback(const DIDEVICEOBJECTINSTANCEW* doi,
- void* user)
-{
- _GLFWobjenumWin32* data = user;
- _GLFWjoyobjectWin32* object = data->objects + data->objectCount;
-
- if (DIDFT_GETTYPE(doi->dwType) & DIDFT_AXIS)
- {
- DIPROPRANGE dipr;
-
- if (memcmp(&doi->guidType, &GUID_Slider, sizeof(GUID)) == 0)
- object->offset = DIJOFS_SLIDER(data->sliderCount);
- else if (memcmp(&doi->guidType, &GUID_XAxis, sizeof(GUID)) == 0)
- object->offset = DIJOFS_X;
- else if (memcmp(&doi->guidType, &GUID_YAxis, sizeof(GUID)) == 0)
- object->offset = DIJOFS_Y;
- else if (memcmp(&doi->guidType, &GUID_ZAxis, sizeof(GUID)) == 0)
- object->offset = DIJOFS_Z;
- else if (memcmp(&doi->guidType, &GUID_RxAxis, sizeof(GUID)) == 0)
- object->offset = DIJOFS_RX;
- else if (memcmp(&doi->guidType, &GUID_RyAxis, sizeof(GUID)) == 0)
- object->offset = DIJOFS_RY;
- else if (memcmp(&doi->guidType, &GUID_RzAxis, sizeof(GUID)) == 0)
- object->offset = DIJOFS_RZ;
- else
- return DIENUM_CONTINUE;
-
- ZeroMemory(&dipr, sizeof(dipr));
- dipr.diph.dwSize = sizeof(dipr);
- dipr.diph.dwHeaderSize = sizeof(dipr.diph);
- dipr.diph.dwObj = doi->dwType;
- dipr.diph.dwHow = DIPH_BYID;
- dipr.lMin = -32768;
- dipr.lMax = 32767;
-
- if (FAILED(IDirectInputDevice8_SetProperty(data->device,
- DIPROP_RANGE,
- &dipr.diph)))
- {
- return DIENUM_CONTINUE;
- }
-
- if (memcmp(&doi->guidType, &GUID_Slider, sizeof(GUID)) == 0)
- {
- object->type = _GLFW_TYPE_SLIDER;
- data->sliderCount++;
- }
- else
- {
- object->type = _GLFW_TYPE_AXIS;
- data->axisCount++;
- }
- }
- else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_BUTTON)
- {
- object->offset = DIJOFS_BUTTON(data->buttonCount);
- object->type = _GLFW_TYPE_BUTTON;
- data->buttonCount++;
- }
- else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_POV)
- {
- object->offset = DIJOFS_POV(data->povCount);
- object->type = _GLFW_TYPE_POV;
- data->povCount++;
- }
-
- data->objectCount++;
- return DIENUM_CONTINUE;
-}
-
-// DirectInput device enumeration callback
-//
-static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
-{
- int jid = 0;
- DIDEVCAPS dc;
- DIPROPDWORD dipd;
- IDirectInputDevice8* device;
- _GLFWobjenumWin32 data;
- _GLFWjoystick* js;
- char guid[33];
- char name[256];
-
- for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
- {
- js = _glfw.joysticks + jid;
- if (js->present)
- {
- if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
- return DIENUM_CONTINUE;
- }
- }
-
- if (supportsXInput(&di->guidProduct))
- return DIENUM_CONTINUE;
-
- if (FAILED(IDirectInput8_CreateDevice(_glfw.win32.dinput8.api,
- &di->guidInstance,
- &device,
- NULL)))
- {
- _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create device");
- return DIENUM_CONTINUE;
- }
-
- if (FAILED(IDirectInputDevice8_SetDataFormat(device, &_glfwDataFormat)))
- {
- _glfwInputError(GLFW_PLATFORM_ERROR,
- "Win32: Failed to set device data format");
-
- IDirectInputDevice8_Release(device);
- return DIENUM_CONTINUE;
- }
-
- ZeroMemory(&dc, sizeof(dc));
- dc.dwSize = sizeof(dc);
-
- if (FAILED(IDirectInputDevice8_GetCapabilities(device, &dc)))
- {
- _glfwInputError(GLFW_PLATFORM_ERROR,
- "Win32: Failed to query device capabilities");
-
- IDirectInputDevice8_Release(device);
- return DIENUM_CONTINUE;
- }
-
- ZeroMemory(&dipd, sizeof(dipd));
- dipd.diph.dwSize = sizeof(dipd);
- dipd.diph.dwHeaderSize = sizeof(dipd.diph);
- dipd.diph.dwHow = DIPH_DEVICE;
- dipd.dwData = DIPROPAXISMODE_ABS;
-
- if (FAILED(IDirectInputDevice8_SetProperty(device,
- DIPROP_AXISMODE,
- &dipd.diph)))
- {
- _glfwInputError(GLFW_PLATFORM_ERROR,
- "Win32: Failed to set device axis mode");
-
- IDirectInputDevice8_Release(device);
- return DIENUM_CONTINUE;
- }
-
- memset(&data, 0, sizeof(data));
- data.device = device;
- data.objects = calloc(dc.dwAxes + (size_t) dc.dwButtons + dc.dwPOVs,
- sizeof(_GLFWjoyobjectWin32));
-
- if (FAILED(IDirectInputDevice8_EnumObjects(device,
- deviceObjectCallback,
- &data,
- DIDFT_AXIS | DIDFT_BUTTON | DIDFT_POV)))
- {
- _glfwInputError(GLFW_PLATFORM_ERROR,
- "Win32: Failed to enumerate device objects");
-
- IDirectInputDevice8_Release(device);
- free(data.objects);
- return DIENUM_CONTINUE;
- }
-
- qsort(data.objects, data.objectCount,
- sizeof(_GLFWjoyobjectWin32),
- compareJoystickObjects);
-
- if (!WideCharToMultiByte(CP_UTF8, 0,
- di->tszInstanceName, -1,
- name, sizeof(name),
- NULL, NULL))
- {
- _glfwInputError(GLFW_PLATFORM_ERROR,
- "Win32: Failed to convert joystick name to UTF-8");
-
- IDirectInputDevice8_Release(device);
- free(data.objects);
- return DIENUM_STOP;
- }
-
- // Generate a joystick GUID that matches the SDL 2.0.5+ one
- if (memcmp(&di->guidProduct.Data4[2], "PIDVID", 6) == 0)
- {
- sprintf(guid, "03000000%02x%02x0000%02x%02x000000000000",
- (uint8_t) di->guidProduct.Data1,
- (uint8_t) (di->guidProduct.Data1 >> 8),
- (uint8_t) (di->guidProduct.Data1 >> 16),
- (uint8_t) (di->guidProduct.Data1 >> 24));
- }
- else
- {
- sprintf(guid, "05000000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
- name[0], name[1], name[2], name[3],
- name[4], name[5], name[6], name[7],
- name[8], name[9], name[10]);
- }
-
- js = _glfwAllocJoystick(name, guid,
- data.axisCount + data.sliderCount,
- data.buttonCount,
- data.povCount);
- if (!js)
- {
- IDirectInputDevice8_Release(device);
- free(data.objects);
- return DIENUM_STOP;
- }
-
- js->win32.device = device;
- js->win32.guid = di->guidInstance;
- js->win32.objects = data.objects;
- js->win32.objectCount = data.objectCount;
-
- _glfwInputJoystick(js, GLFW_CONNECTED);
- return DIENUM_CONTINUE;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-////// GLFW internal API //////
-//////////////////////////////////////////////////////////////////////////
-
-// Checks for new joysticks after DBT_DEVICEARRIVAL
-//
-void _glfwDetectJoystickConnectionWin32(void)
-{
- if (_glfw.win32.xinput.instance)
- {
- DWORD index;
-
- for (index = 0; index < XUSER_MAX_COUNT; index++)
- {
- int jid;
- char guid[33];
- XINPUT_CAPABILITIES xic;
- _GLFWjoystick* js;
-
- for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
- {
- if (_glfw.joysticks[jid].present &&
- _glfw.joysticks[jid].win32.device == NULL &&
- _glfw.joysticks[jid].win32.index == index)
- {
- break;
- }
- }
-
- if (jid <= GLFW_JOYSTICK_LAST)
- continue;
-
- if (XInputGetCapabilities(index, 0, &xic) != ERROR_SUCCESS)
- continue;
-
- // Generate a joystick GUID that matches the SDL 2.0.5+ one
- sprintf(guid, "78696e707574%02x000000000000000000",
- xic.SubType & 0xff);
-
- js = _glfwAllocJoystick(getDeviceDescription(&xic), guid, 6, 10, 1);
- if (!js)
- continue;
-
- js->win32.index = index;
-
- _glfwInputJoystick(js, GLFW_CONNECTED);
- }
- }
-
- if (_glfw.win32.dinput8.api)
- {
- if (FAILED(IDirectInput8_EnumDevices(_glfw.win32.dinput8.api,
- DI8DEVCLASS_GAMECTRL,
- deviceCallback,
- NULL,
- DIEDFL_ALLDEVICES)))
- {
- _glfwInputError(GLFW_PLATFORM_ERROR,
- "Failed to enumerate DirectInput8 devices");
- return;
- }
- }
-}
-
-// Checks for joystick disconnection after DBT_DEVICEREMOVECOMPLETE
-//
-void _glfwDetectJoystickDisconnectionWin32(void)
-{
- int jid;
-
- for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
- {
- _GLFWjoystick* js = _glfw.joysticks + jid;
- if (js->present)
- _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-////// GLFW platform API //////
-//////////////////////////////////////////////////////////////////////////
-
-GLFWbool _glfwPlatformInitJoysticks(void)
-{
- if (_glfw.win32.dinput8.instance)
- {
- if (FAILED(DirectInput8Create(GetModuleHandle(NULL),
- DIRECTINPUT_VERSION,
- &IID_IDirectInput8W,
- (void**) &_glfw.win32.dinput8.api,
- NULL)))
- {
- _glfwInputError(GLFW_PLATFORM_ERROR,
- "Win32: Failed to create interface");
- return GLFW_FALSE;
- }
- }
-
- _glfwDetectJoystickConnectionWin32();
- return GLFW_TRUE;
-}
-
-void _glfwPlatformTerminateJoysticks(void)
-{
- int jid;
-
- for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
- closeJoystick(_glfw.joysticks + jid);
-
- if (_glfw.win32.dinput8.api)
- IDirectInput8_Release(_glfw.win32.dinput8.api);
-}
-
-int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
-{
- if (js->win32.device)
- {
- int i, ai = 0, bi = 0, pi = 0;
- HRESULT result;
- DIJOYSTATE state;
-
- IDirectInputDevice8_Poll(js->win32.device);
- result = IDirectInputDevice8_GetDeviceState(js->win32.device,
- sizeof(state),
- &state);
- if (result == DIERR_NOTACQUIRED || result == DIERR_INPUTLOST)
- {
- IDirectInputDevice8_Acquire(js->win32.device);
- IDirectInputDevice8_Poll(js->win32.device);
- result = IDirectInputDevice8_GetDeviceState(js->win32.device,
- sizeof(state),
- &state);
- }
-
- if (FAILED(result))
- {
- closeJoystick(js);
- return GLFW_FALSE;
- }
-
- if (mode == _GLFW_POLL_PRESENCE)
- return GLFW_TRUE;
-
- for (i = 0; i < js->win32.objectCount; i++)
- {
- const void* data = (char*) &state + js->win32.objects[i].offset;
-
- switch (js->win32.objects[i].type)
- {
- case _GLFW_TYPE_AXIS:
- case _GLFW_TYPE_SLIDER:
- {
- const float value = (*((LONG*) data) + 0.5f) / 32767.5f;
- _glfwInputJoystickAxis(js, ai, value);
- ai++;
- break;
- }
-
- case _GLFW_TYPE_BUTTON:
- {
- const char value = (*((BYTE*) data) & 0x80) != 0;
- _glfwInputJoystickButton(js, bi, value);
- bi++;
- break;
- }
-
- case _GLFW_TYPE_POV:
- {
- const int states[9] =
- {
- GLFW_HAT_UP,
- GLFW_HAT_RIGHT_UP,
- GLFW_HAT_RIGHT,
- GLFW_HAT_RIGHT_DOWN,
- GLFW_HAT_DOWN,
- GLFW_HAT_LEFT_DOWN,
- GLFW_HAT_LEFT,
- GLFW_HAT_LEFT_UP,
- GLFW_HAT_CENTERED
- };
-
- // Screams of horror are appropriate at this point
- int stateIndex = LOWORD(*(DWORD*) data) / (45 * DI_DEGREES);
- if (stateIndex < 0 || stateIndex > 8)
- stateIndex = 8;
-
- _glfwInputJoystickHat(js, pi, states[stateIndex]);
- pi++;
- break;
- }
- }
- }
- }
- else
- {
- int i, dpad = 0;
- DWORD result;
- XINPUT_STATE xis;
- const WORD buttons[10] =
- {
- XINPUT_GAMEPAD_A,
- XINPUT_GAMEPAD_B,
- XINPUT_GAMEPAD_X,
- XINPUT_GAMEPAD_Y,
- XINPUT_GAMEPAD_LEFT_SHOULDER,
- XINPUT_GAMEPAD_RIGHT_SHOULDER,
- XINPUT_GAMEPAD_BACK,
- XINPUT_GAMEPAD_START,
- XINPUT_GAMEPAD_LEFT_THUMB,
- XINPUT_GAMEPAD_RIGHT_THUMB
- };
-
- result = XInputGetState(js->win32.index, &xis);
- if (result != ERROR_SUCCESS)
- {
- if (result == ERROR_DEVICE_NOT_CONNECTED)
- closeJoystick(js);
-
- return GLFW_FALSE;
- }
-
- if (mode == _GLFW_POLL_PRESENCE)
- return GLFW_TRUE;
-
- _glfwInputJoystickAxis(js, 0, (xis.Gamepad.sThumbLX + 0.5f) / 32767.5f);
- _glfwInputJoystickAxis(js, 1, -(xis.Gamepad.sThumbLY + 0.5f) / 32767.5f);
- _glfwInputJoystickAxis(js, 2, (xis.Gamepad.sThumbRX + 0.5f) / 32767.5f);
- _glfwInputJoystickAxis(js, 3, -(xis.Gamepad.sThumbRY + 0.5f) / 32767.5f);
- _glfwInputJoystickAxis(js, 4, xis.Gamepad.bLeftTrigger / 127.5f - 1.f);
- _glfwInputJoystickAxis(js, 5, xis.Gamepad.bRightTrigger / 127.5f - 1.f);
-
- for (i = 0; i < 10; i++)
- {
- const char value = (xis.Gamepad.wButtons & buttons[i]) ? 1 : 0;
- _glfwInputJoystickButton(js, i, value);
- }
-
- if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)
- dpad |= GLFW_HAT_UP;
- if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
- dpad |= GLFW_HAT_RIGHT;
- if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)
- dpad |= GLFW_HAT_DOWN;
- if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
- dpad |= GLFW_HAT_LEFT;
-
- _glfwInputJoystickHat(js, 0, dpad);
- }
-
- return GLFW_TRUE;
-}
-
-void _glfwPlatformUpdateGamepadGUID(char* guid)
-{
- if (strcmp(guid + 20, "504944564944") == 0)
- {
- char original[33];
- strncpy(original, guid, sizeof(original) - 1);
- sprintf(guid, "03000000%.4s0000%.4s000000000000",
- original, original + 4);
- }
-}
-