mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 21:37:52 -07:00
Merge pull request #925 from shuffle2/xbcd-compat
Revert changes to how DInput filters out XInput devices.
This commit is contained in:
commit
de71db4864
@ -8,6 +8,7 @@
|
||||
|
||||
#include "InputCommon/ControllerInterface/DInput/DInput.h"
|
||||
#include "InputCommon/ControllerInterface/DInput/DInputJoystick.h"
|
||||
#include "InputCommon/ControllerInterface/DInput/XInputFilter.h"
|
||||
|
||||
namespace ciface
|
||||
{
|
||||
@ -16,29 +17,22 @@ namespace DInput
|
||||
|
||||
#define DATA_BUFFER_SIZE 32
|
||||
|
||||
static const GUID s_known_xinput_guids[] = {
|
||||
// ValveStreamingGamepad
|
||||
{ MAKELONG(0x28DE, 0x11FF), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } },
|
||||
// IID_X360WiredGamepad
|
||||
{ MAKELONG(0x045E, 0x02A1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } },
|
||||
// IID_X360WirelessGamepad
|
||||
{ MAKELONG(0x045E, 0x028E), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } },
|
||||
};
|
||||
|
||||
void InitJoystick(IDirectInput8* const idi8, std::vector<Core::Device*>& devices, HWND hwnd)
|
||||
{
|
||||
std::list<DIDEVICEINSTANCE> joysticks;
|
||||
idi8->EnumDevices( DI8DEVCLASS_GAMECTRL, DIEnumDevicesCallback, (LPVOID)&joysticks, DIEDFL_ATTACHEDONLY );
|
||||
idi8->EnumDevices(DI8DEVCLASS_GAMECTRL, DIEnumDevicesCallback, (LPVOID)&joysticks, DIEDFL_ATTACHEDONLY);
|
||||
|
||||
// this is used to number the joysticks
|
||||
// multiple joysticks with the same name shall get unique ids starting at 0
|
||||
std::map< std::basic_string<TCHAR>, int> name_counts;
|
||||
|
||||
std::vector<DWORD> xinput_guids;
|
||||
GetXInputGUIDS(&xinput_guids);
|
||||
|
||||
for (DIDEVICEINSTANCE& joystick : joysticks)
|
||||
{
|
||||
// skip XInput Devices
|
||||
if (std::find(std::begin(s_known_xinput_guids), std::end(s_known_xinput_guids),
|
||||
joystick.guidProduct) != std::end(s_known_xinput_guids))
|
||||
if (std::find(xinput_guids.begin(), xinput_guids.end(), joystick.guidProduct.Data1) != xinput_guids.end())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -0,0 +1,123 @@
|
||||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
// This function is contained in a separate file because WbemIdl.h pulls in files which break on
|
||||
// /Zc:strictStrings, so this compilation unit is compiled without /Zc:strictStrings.
|
||||
|
||||
#include <vector>
|
||||
#include <WbemIdl.h>
|
||||
#include <Windows.h>
|
||||
|
||||
#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=nullptr; } }
|
||||
|
||||
namespace ciface
|
||||
{
|
||||
namespace DInput
|
||||
{
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Modified some MSDN code to get all the XInput device GUID.Data1 values in a vector,
|
||||
// faster than checking all the devices for each DirectInput device, like MSDN says to do
|
||||
//-----------------------------------------------------------------------------
|
||||
void GetXInputGUIDS(std::vector<DWORD>* guids)
|
||||
{
|
||||
IWbemLocator* pIWbemLocator = nullptr;
|
||||
IEnumWbemClassObject* pEnumDevices = nullptr;
|
||||
IWbemClassObject* pDevices[20] = {0};
|
||||
IWbemServices* pIWbemServices = nullptr;
|
||||
BSTR bstrNamespace = nullptr;
|
||||
BSTR bstrDeviceID = nullptr;
|
||||
BSTR bstrClassName = nullptr;
|
||||
DWORD uReturned = 0;
|
||||
VARIANT var;
|
||||
HRESULT hr;
|
||||
|
||||
// CoInit if needed
|
||||
hr = CoInitialize(nullptr);
|
||||
bool bCleanupCOM = SUCCEEDED(hr);
|
||||
|
||||
// Create WMI
|
||||
hr = CoCreateInstance(__uuidof(WbemLocator),
|
||||
nullptr,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(IWbemLocator),
|
||||
(LPVOID*) &pIWbemLocator);
|
||||
if (FAILED(hr) || pIWbemLocator == nullptr)
|
||||
goto LCleanup;
|
||||
|
||||
bstrNamespace = SysAllocString(L"\\\\.\\root\\cimv2"); if (bstrNamespace == nullptr) goto LCleanup;
|
||||
bstrClassName = SysAllocString(L"Win32_PNPEntity"); if (bstrClassName == nullptr) goto LCleanup;
|
||||
bstrDeviceID = SysAllocString(L"DeviceID"); if (bstrDeviceID == nullptr) goto LCleanup;
|
||||
|
||||
// Connect to WMI
|
||||
hr = pIWbemLocator->ConnectServer(bstrNamespace, nullptr, nullptr, 0L, 0L, nullptr, nullptr, &pIWbemServices);
|
||||
if (FAILED(hr) || pIWbemServices == nullptr)
|
||||
goto LCleanup;
|
||||
|
||||
// Switch security level to IMPERSONATE.
|
||||
CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr,
|
||||
RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE);
|
||||
|
||||
hr = pIWbemServices->CreateInstanceEnum(bstrClassName, 0, nullptr, &pEnumDevices);
|
||||
if (FAILED(hr) || pEnumDevices == nullptr)
|
||||
goto LCleanup;
|
||||
|
||||
// Loop over all devices
|
||||
while (true)
|
||||
{
|
||||
// Get 20 at a time
|
||||
hr = pEnumDevices->Next(10000, 20, pDevices, &uReturned);
|
||||
if (FAILED(hr) || uReturned == 0)
|
||||
break;
|
||||
|
||||
for (UINT iDevice = 0; iDevice < uReturned; ++iDevice)
|
||||
{
|
||||
// For each device, get its device ID
|
||||
hr = pDevices[iDevice]->Get(bstrDeviceID, 0L, &var, nullptr, nullptr);
|
||||
if (SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != nullptr)
|
||||
{
|
||||
// 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);
|
||||
guids->push_back(dwVidPid);
|
||||
//bIsXinputDevice = true;
|
||||
}
|
||||
}
|
||||
SAFE_RELEASE(pDevices[iDevice]);
|
||||
}
|
||||
}
|
||||
|
||||
LCleanup:
|
||||
if (bstrNamespace)
|
||||
SysFreeString(bstrNamespace);
|
||||
if (bstrDeviceID)
|
||||
SysFreeString(bstrDeviceID);
|
||||
if (bstrClassName)
|
||||
SysFreeString(bstrClassName);
|
||||
for (UINT iDevice = 0; iDevice < 20; iDevice++)
|
||||
SAFE_RELEASE(pDevices[iDevice]);
|
||||
SAFE_RELEASE(pEnumDevices);
|
||||
SAFE_RELEASE(pIWbemLocator);
|
||||
SAFE_RELEASE(pIWbemServices);
|
||||
|
||||
if (bCleanupCOM)
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#undef SAFE_RELEASE
|
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <Windows.h>
|
||||
|
||||
namespace ciface
|
||||
{
|
||||
namespace DInput
|
||||
{
|
||||
|
||||
void GetXInputGUIDS(std::vector<DWORD>* guids);
|
||||
|
||||
}
|
||||
}
|
@ -41,6 +41,14 @@
|
||||
<ClCompile Include="ControllerInterface\DInput\DInput.cpp" />
|
||||
<ClCompile Include="ControllerInterface\DInput\DInputJoystick.cpp" />
|
||||
<ClCompile Include="ControllerInterface\DInput\DInputKeyboardMouse.cpp" />
|
||||
<ClCompile Include="ControllerInterface\DInput\XInputFilter.cpp">
|
||||
<!--Disable /Zc:strictStrings so that wbem headers may compile-->
|
||||
<!--
|
||||
This is somewhat gross as it doesn't dynamically remove the option,
|
||||
I really hope the issue is fixed in next VS release :(
|
||||
-->
|
||||
<AdditionalOptions>/Zo /Zc:inline /Zc:rvalueCast /volatile:iso</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ControllerInterface\ExpressionParser.cpp" />
|
||||
<ClCompile Include="ControllerInterface\ForceFeedback\ForceFeedbackDevice.cpp" />
|
||||
<ClCompile Include="ControllerInterface\XInput\XInput.cpp" />
|
||||
@ -54,6 +62,7 @@
|
||||
<ClInclude Include="ControllerInterface\DInput\DInput8.h" />
|
||||
<ClInclude Include="ControllerInterface\DInput\DInputJoystick.h" />
|
||||
<ClInclude Include="ControllerInterface\DInput\DInputKeyboardMouse.h" />
|
||||
<ClInclude Include="ControllerInterface\DInput\XInputFilter.h" />
|
||||
<ClInclude Include="ControllerInterface\ExpressionParser.h" />
|
||||
<ClInclude Include="ControllerInterface\ForceFeedback\ForceFeedbackDevice.h" />
|
||||
<ClInclude Include="ControllerInterface\XInput\XInput.h" />
|
||||
|
@ -41,6 +41,9 @@
|
||||
<ClCompile Include="ControllerInterface\ForceFeedback\ForceFeedbackDevice.cpp">
|
||||
<Filter>ControllerInterface\ForceFeedback</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ControllerInterface\DInput\XInputFilter.cpp">
|
||||
<Filter>ControllerInterface\DInput</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ControllerEmu.h" />
|
||||
@ -73,6 +76,9 @@
|
||||
<ClInclude Include="ControllerInterface\DInput\DInput8.h">
|
||||
<Filter>ControllerInterface\DInput</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ControllerInterface\DInput\XInputFilter.h">
|
||||
<Filter>ControllerInterface\DInput</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="CMakeLists.txt" />
|
||||
|
Loading…
Reference in New Issue
Block a user