summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.cpp
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2019-03-09 09:57:37 -0600
committerJordan Woyak <jordan.woyak@gmail.com>2019-03-29 09:04:16 -0500
commiteadbdd6bc389cd89c3e3e57a31dabaeadf161865 (patch)
treee64941bcb188067cf5355a9cee1a74b42a5ae6ab /Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.cpp
parentd26c1ce24d9108114d7eab97cfc2ab4f3eea28ee (diff)
ControllerInterface/Win32: Prevent devcies from losing their "id" on a hotplug event.
Diffstat (limited to 'Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.cpp')
-rw-r--r--Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.cpp43
1 files changed, 39 insertions, 4 deletions
diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.cpp b/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.cpp
index 3bb8dd64a3..e919952bec 100644
--- a/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.cpp
+++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.cpp
@@ -4,8 +4,9 @@
#include <algorithm>
#include <limits>
-#include <map>
+#include <set>
#include <sstream>
+#include <type_traits>
#include "Common/Logging/Log.h"
#include "InputCommon/ControllerInterface/ControllerInterface.h"
@@ -17,7 +18,19 @@ namespace ciface
{
namespace DInput
{
-#define DATA_BUFFER_SIZE 32
+constexpr DWORD DATA_BUFFER_SIZE = 32;
+
+struct GUIDComparator
+{
+ bool operator()(const GUID& left, const GUID& right) const
+ {
+ static_assert(std::is_trivially_copyable_v<GUID>);
+
+ return memcmp(&left, &right, sizeof(left)) < 0;
+ }
+};
+
+static std::set<GUID, GUIDComparator> s_guids_in_use;
void InitJoystick(IDirectInput8* const idi8, HWND hwnd)
{
@@ -28,12 +41,18 @@ void InitJoystick(IDirectInput8* const idi8, HWND hwnd)
std::unordered_set<DWORD> xinput_guids = GetXInputGUIDS();
for (DIDEVICEINSTANCE& joystick : joysticks)
{
- // skip XInput Devices
+ // Skip XInput Devices
if (xinput_guids.count(joystick.guidProduct.Data1))
{
continue;
}
+ // Skip devices we are already using.
+ if (s_guids_in_use.count(joystick.guidInstance))
+ {
+ continue;
+ }
+
LPDIRECTINPUTDEVICE8 js_device;
if (SUCCEEDED(idi8->CreateDevice(joystick.guidInstance, &js_device, nullptr)))
{
@@ -55,7 +74,9 @@ void InitJoystick(IDirectInput8* const idi8, HWND hwnd)
}
}
+ s_guids_in_use.insert(joystick.guidInstance);
auto js = std::make_shared<Joystick>(js_device);
+
// only add if it has some inputs/outputs
if (js->Inputs().size() || js->Outputs().size())
g_controller_interface.AddDevice(std::move(js));
@@ -161,6 +182,17 @@ Joystick::Joystick(/*const LPCDIDEVICEINSTANCE lpddi, */ const LPDIRECTINPUTDEVI
Joystick::~Joystick()
{
+ DIDEVICEINSTANCE info = {};
+ info.dwSize = sizeof(info);
+ if (SUCCEEDED(m_device->GetDeviceInfo(&info)))
+ {
+ s_guids_in_use.erase(info.guidInstance);
+ }
+ else
+ {
+ ERROR_LOG(PAD, "DInputJoystick: GetDeviceInfo failed.");
+ }
+
DeInitForceFeedback();
m_device->Unacquire();
@@ -177,7 +209,10 @@ std::string Joystick::GetSource() const
return DINPUT_SOURCE_NAME;
}
-// update IO
+bool Joystick::IsValid() const
+{
+ return SUCCEEDED(m_device->Acquire());
+}
void Joystick::UpdateInput()
{