Try to use a Microsoft function to detect XInput devices when using
DirectInput - atm not working yet :(
This commit is contained in:
parent
22208365d2
commit
d3da93f368
@ -23,6 +23,9 @@
|
|||||||
#ifdef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_
|
#ifdef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_
|
||||||
#define DIRECTINPUT_VERSION 0x0800
|
#define DIRECTINPUT_VERSION 0x0800
|
||||||
#include <dinput.h>
|
#include <dinput.h>
|
||||||
|
#include <wbemidl.h>
|
||||||
|
#include <oleauto.h>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma comment(lib, "dinput8.lib")
|
#pragma comment(lib, "dinput8.lib")
|
||||||
#pragma comment(lib, "dxguid.lib")
|
#pragma comment(lib, "dxguid.lib")
|
||||||
@ -123,12 +126,15 @@ struct SJoystickWin32Control
|
|||||||
p->directInputAddJoystick(lpddi);
|
p->directInputAddJoystick(lpddi);
|
||||||
return DIENUM_CONTINUE;
|
return DIENUM_CONTINUE;
|
||||||
}
|
}
|
||||||
|
bool IsXInputDevice(const GUID* pGuidProductFromDirectInput);
|
||||||
|
|
||||||
void directInputAddJoystick(LPCDIDEVICEINSTANCE lpddi)
|
void directInputAddJoystick(LPCDIDEVICEINSTANCE lpddi)
|
||||||
{
|
{
|
||||||
//Get the GUID of the joystuck
|
//Get the GUID of the joystuck
|
||||||
const GUID guid = lpddi->guidInstance;
|
const GUID guid = lpddi->guidInstance;
|
||||||
|
|
||||||
JoystickInfo activeJoystick;
|
JoystickInfo activeJoystick;
|
||||||
|
activeJoystick.m_use_xinput = isXInputDevice(&guid);
|
||||||
|
|
||||||
activeJoystick.Index=ActiveJoysticks.size();
|
activeJoystick.Index=ActiveJoysticks.size();
|
||||||
activeJoystick.guid=guid;
|
activeJoystick.guid=guid;
|
||||||
activeJoystick.Name=lpddi->tszProductName;
|
activeJoystick.Name=lpddi->tszProductName;
|
||||||
@ -193,6 +199,137 @@ struct SJoystickWin32Control
|
|||||||
|
|
||||||
ActiveJoysticks.push_back(activeJoystick);
|
ActiveJoysticks.push_back(activeJoystick);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Taken from:
|
||||||
|
* https://msdn.microsoft.com/en-us/library/windows/desktop/dd940435(v=vs.85).aspx
|
||||||
|
*/
|
||||||
|
template <class T> void SAFE_RELEASE(T **ppT)
|
||||||
|
{
|
||||||
|
if (*ppT)
|
||||||
|
{
|
||||||
|
(*ppT)->Release();
|
||||||
|
*ppT = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Taken from:
|
||||||
|
* https://msdn.microsoft.com/en-us/library/windows/desktop/ee417014(v=vs.85).aspx
|
||||||
|
*/
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Enum each PNP device using WMI and check each device ID to see if it contains
|
||||||
|
// "IG_" (ex. "VID_045E&PID_028E&IG_00"). If it does, then it's an XInput device
|
||||||
|
// Unfortunately this information can not be found by just using DirectInput
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool isXInputDevice(const GUID* pGuidProductFromDirectInput)
|
||||||
|
{
|
||||||
|
IWbemLocator* pIWbemLocator = NULL;
|
||||||
|
IEnumWbemClassObject* pEnumDevices = NULL;
|
||||||
|
IWbemClassObject* pDevices[20] = { 0 };
|
||||||
|
IWbemServices* pIWbemServices = NULL;
|
||||||
|
BSTR bstrNamespace = NULL;
|
||||||
|
BSTR bstrDeviceID = NULL;
|
||||||
|
BSTR bstrClassName = NULL;
|
||||||
|
DWORD uReturned = 0;
|
||||||
|
bool bIsXinputDevice = false;
|
||||||
|
UINT iDevice = 0;
|
||||||
|
VARIANT var;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
// CoInit if needed
|
||||||
|
hr = CoInitialize(NULL);
|
||||||
|
bool bCleanupCOM = SUCCEEDED(hr);
|
||||||
|
|
||||||
|
// Create WMI
|
||||||
|
hr = CoCreateInstance(__uuidof(WbemLocator),
|
||||||
|
NULL,
|
||||||
|
CLSCTX_INPROC_SERVER,
|
||||||
|
__uuidof(IWbemLocator),
|
||||||
|
(LPVOID*)&pIWbemLocator);
|
||||||
|
if (FAILED(hr) || pIWbemLocator == NULL)
|
||||||
|
goto LCleanup;
|
||||||
|
|
||||||
|
bstrNamespace = SysAllocString(L"\\\\.\\root\\cimv2"); if (bstrNamespace == NULL) goto LCleanup;
|
||||||
|
bstrClassName = SysAllocString(L"Win32_PNPEntity"); if (bstrClassName == NULL) goto LCleanup;
|
||||||
|
bstrDeviceID = SysAllocString(L"DeviceID"); if (bstrDeviceID == NULL) goto LCleanup;
|
||||||
|
|
||||||
|
// Connect to WMI
|
||||||
|
hr = pIWbemLocator->ConnectServer(bstrNamespace, NULL, NULL, 0L,
|
||||||
|
0L, NULL, NULL, &pIWbemServices);
|
||||||
|
if (FAILED(hr) || pIWbemServices == NULL)
|
||||||
|
goto LCleanup;
|
||||||
|
|
||||||
|
// Switch security level to IMPERSONATE.
|
||||||
|
CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
|
||||||
|
RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
|
||||||
|
|
||||||
|
hr = pIWbemServices->CreateInstanceEnum(bstrClassName, 0, NULL, &pEnumDevices);
|
||||||
|
if (FAILED(hr) || pEnumDevices == NULL)
|
||||||
|
goto LCleanup;
|
||||||
|
|
||||||
|
// Loop over all devices
|
||||||
|
for (;; )
|
||||||
|
{
|
||||||
|
// Get 20 at a time
|
||||||
|
hr = pEnumDevices->Next(10000, 20, pDevices, &uReturned);
|
||||||
|
if (FAILED(hr))
|
||||||
|
goto LCleanup;
|
||||||
|
if (uReturned == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (iDevice = 0; iDevice<uReturned; iDevice++)
|
||||||
|
{
|
||||||
|
// For each device, get its device ID
|
||||||
|
hr = pDevices[iDevice]->Get(bstrDeviceID, 0L, &var, NULL, NULL);
|
||||||
|
if (SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != NULL)
|
||||||
|
{
|
||||||
|
// Check if the device ID contains "IG_". If it does, then it's an XInput device
|
||||||
|
// This information can not be found from DirectInput
|
||||||
|
if (wcsstr(var.bstrVal, L"IG_"))
|
||||||
|
{
|
||||||
|
// If it does, then get the VID/PID from var.bstrVal
|
||||||
|
DWORD dwPid = 0, dwVid = 0;
|
||||||
|
WCHAR* strVid = wcsstr(var.bstrVal, L"VID_");
|
||||||
|
if (strVid && swscanf(strVid, L"VID_%4X", &dwVid) != 1)
|
||||||
|
dwVid = 0;
|
||||||
|
WCHAR* strPid = wcsstr(var.bstrVal, L"PID_");
|
||||||
|
if (strPid && swscanf(strPid, L"PID_%4X", &dwPid) != 1)
|
||||||
|
dwPid = 0;
|
||||||
|
|
||||||
|
// Compare the VID/PID to the DInput device
|
||||||
|
DWORD dwVidPid = MAKELONG(dwVid, dwPid);
|
||||||
|
if (dwVidPid == pGuidProductFromDirectInput->Data1)
|
||||||
|
{
|
||||||
|
bIsXinputDevice = true;
|
||||||
|
goto LCleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SAFE_RELEASE(&pDevices[iDevice]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LCleanup:
|
||||||
|
if (bstrNamespace)
|
||||||
|
SysFreeString(bstrNamespace);
|
||||||
|
if (bstrDeviceID)
|
||||||
|
SysFreeString(bstrDeviceID);
|
||||||
|
if (bstrClassName)
|
||||||
|
SysFreeString(bstrClassName);
|
||||||
|
for (iDevice = 0; iDevice<20; iDevice++)
|
||||||
|
SAFE_RELEASE(&pDevices[iDevice]);
|
||||||
|
SAFE_RELEASE(&pEnumDevices);
|
||||||
|
SAFE_RELEASE(&pIWbemLocator);
|
||||||
|
SAFE_RELEASE(&pIWbemServices);
|
||||||
|
|
||||||
|
if (bCleanupCOM)
|
||||||
|
CoUninitialize();
|
||||||
|
|
||||||
|
return bIsXinputDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void pollJoysticks()
|
void pollJoysticks()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user