summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/ControllerInterface/DInput
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/InputCommon/ControllerInterface/DInput')
-rw-r--r--Source/Core/InputCommon/ControllerInterface/DInput/DInput.cpp19
-rw-r--r--Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.cpp43
-rw-r--r--Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.h6
-rw-r--r--Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp17
-rw-r--r--Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.h6
5 files changed, 71 insertions, 20 deletions
diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInput.cpp b/Source/Core/InputCommon/ControllerInterface/DInput/DInput.cpp
index e65da0eb78..cb484cc6ca 100644
--- a/Source/Core/InputCommon/ControllerInterface/DInput/DInput.cpp
+++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInput.cpp
@@ -3,9 +3,11 @@
// Refer to the license.txt file included.
#include "InputCommon/ControllerInterface/DInput/DInput.h"
+
+#include "Common/Logging/Log.h"
#include "Common/StringUtil.h"
-#include "InputCommon/ControllerInterface/ControllerInterface.h"
+#include "InputCommon/ControllerInterface/ControllerInterface.h"
#include "InputCommon/ControllerInterface/DInput/DInputJoystick.h"
#include "InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.h"
@@ -40,25 +42,32 @@ std::string GetDeviceName(const LPDIRECTINPUTDEVICE8 device)
{
result = StripSpaces(UTF16ToUTF8(str.wsz));
}
+ else
+ {
+ ERROR_LOG(PAD, "GetProperty(DIPROP_PRODUCTNAME) failed.");
+ }
return result;
}
void PopulateDevices(HWND hwnd)
{
- g_controller_interface.RemoveDevice([](const auto* dev) { return dev->GetSource() == "DInput"; });
+ // Remove unplugged devices.
+ g_controller_interface.RemoveDevice(
+ [](const auto* dev) { return dev->GetSource() == DINPUT_SOURCE_NAME && !dev->IsValid(); });
IDirectInput8* idi8;
if (FAILED(DirectInput8Create(GetModuleHandle(nullptr), DIRECTINPUT_VERSION, IID_IDirectInput8,
(LPVOID*)&idi8, nullptr)))
{
+ ERROR_LOG(PAD, "DirectInput8Create failed.");
return;
}
- InitKeyboardMouse(idi8, hwnd);
+ InitKeyboardMouse(idi8);
InitJoystick(idi8, hwnd);
idi8->Release();
}
-}
-}
+} // namespace DInput
+} // namespace ciface
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()
{
diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.h b/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.h
index 82a6b61f0f..074b879051 100644
--- a/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.h
+++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.h
@@ -68,6 +68,8 @@ public:
std::string GetName() const override;
std::string GetSource() const override;
+ bool IsValid() const final override;
+
private:
const LPDIRECTINPUTDEVICE8 m_device;
@@ -75,5 +77,5 @@ private:
bool m_buffered;
};
-}
-}
+} // namespace DInput
+} // namespace ciface
diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp
index 384174a3f1..23746e61db 100644
--- a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp
+++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp
@@ -29,12 +29,13 @@ static const struct
#include "InputCommon/ControllerInterface/DInput/NamedKeys.h" // NOLINT
};
-// lil silly
-static HWND m_hwnd;
+// Prevent duplicate keyboard/mouse devices.
+static bool s_keyboard_mouse_exists = false;
-void InitKeyboardMouse(IDirectInput8* const idi8, HWND _hwnd)
+void InitKeyboardMouse(IDirectInput8* const idi8)
{
- m_hwnd = _hwnd;
+ if (s_keyboard_mouse_exists)
+ return;
// mouse and keyboard are a combined device, to allow shift+click and stuff
// if that's dumb, I will make a VirtualDevice class that just uses ranges of inputs/outputs from
@@ -63,6 +64,8 @@ void InitKeyboardMouse(IDirectInput8* const idi8, HWND _hwnd)
KeyboardMouse::~KeyboardMouse()
{
+ s_keyboard_mouse_exists = false;
+
// kb
m_kb_device->Unacquire();
m_kb_device->Release();
@@ -75,6 +78,8 @@ KeyboardMouse::KeyboardMouse(const LPDIRECTINPUTDEVICE8 kb_device,
const LPDIRECTINPUTDEVICE8 mo_device)
: m_kb_device(kb_device), m_mo_device(mo_device)
{
+ s_keyboard_mouse_exists = true;
+
m_kb_device->Acquire();
m_mo_device->Acquire();
@@ -237,5 +242,5 @@ ControlState KeyboardMouse::Cursor::GetState() const
{
return std::max(0.0, ControlState(m_axis) / (m_positive ? 1.0 : -1.0));
}
-}
-}
+} // namespace DInput
+} // namespace ciface
diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.h b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.h
index c80a13e343..a8de55fe7a 100644
--- a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.h
+++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.h
@@ -13,7 +13,7 @@ namespace ciface
{
namespace DInput
{
-void InitKeyboardMouse(IDirectInput8* const idi8, HWND _hwnd);
+void InitKeyboardMouse(IDirectInput8* const idi8);
class KeyboardMouse : public Core::Device
{
@@ -98,5 +98,5 @@ private:
DWORD m_last_update;
State m_state_in;
};
-}
-}
+} // namespace DInput
+} // namespace ciface