summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/ControllerInterface/DInput/DInput.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/InputCommon/ControllerInterface/DInput/DInput.cpp')
-rw-r--r--Source/Core/InputCommon/ControllerInterface/DInput/DInput.cpp52
1 files changed, 41 insertions, 11 deletions
diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInput.cpp b/Source/Core/InputCommon/ControllerInterface/DInput/DInput.cpp
index d508de613a..f5e105dc45 100644
--- a/Source/Core/InputCommon/ControllerInterface/DInput/DInput.cpp
+++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInput.cpp
@@ -16,6 +16,8 @@
namespace ciface::DInput
{
+static IDirectInput8* s_idi8 = nullptr;
+
BOOL CALLBACK DIEnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef)
{
((std::list<DIDEVICEOBJECTINSTANCE>*)pvRef)->push_back(*lpddoi);
@@ -42,29 +44,57 @@ std::string GetDeviceName(const LPDIRECTINPUTDEVICE8 device)
}
else
{
- ERROR_LOG_FMT(PAD, "GetProperty(DIPROP_PRODUCTNAME) failed.");
+ ERROR_LOG_FMT(CONTROLLERINTERFACE, "GetProperty(DIPROP_PRODUCTNAME) failed.");
}
return result;
}
+// Assumes hwnd had not changed from the previous call
void PopulateDevices(HWND hwnd)
{
- // Remove unplugged devices.
+ if (!s_idi8 && FAILED(DirectInput8Create(GetModuleHandle(nullptr), DIRECTINPUT_VERSION,
+ IID_IDirectInput8, (LPVOID*)&s_idi8, nullptr)))
+ {
+ ERROR_LOG_FMT(CONTROLLERINTERFACE, "DirectInput8Create failed.");
+ return;
+ }
+
+ // Remove old (invalid) devices. No need to ever remove the KeyboardMouse device.
+ // Note that if we have 2+ DInput controllers, not fully repopulating devices
+ // will mean that a device with index "2" could persist while there is no device with index "0".
+ // This is slightly inconsistent as when we refresh all devices, they will instead reset, and
+ // that happens a lot (for uncontrolled reasons, like starting/stopping the emulation).
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)))
+ InitKeyboardMouse(s_idi8, hwnd);
+ InitJoystick(s_idi8, hwnd);
+}
+
+void ChangeWindow(HWND hwnd)
+{
+ if (s_idi8) // Has init? Ignore if called before the first PopulateDevices()
{
- ERROR_LOG_FMT(PAD, "DirectInput8Create failed.");
- return;
- }
+ // The KeyboardMouse device is marked as virtual device, so we avoid removing it.
+ // We need to force all the DInput joysticks to be destroyed now, or recreation would fail.
+ g_controller_interface.RemoveDevice(
+ [](const auto* dev) {
+ return dev->GetSource() == DINPUT_SOURCE_NAME && !dev->IsVirtualDevice();
+ },
+ true);
- InitKeyboardMouse(idi8, hwnd);
- InitJoystick(idi8, hwnd);
+ SetKeyboardMouseWindow(hwnd);
+ InitJoystick(s_idi8, hwnd);
+ }
+}
- idi8->Release();
+void DeInit()
+{
+ if (s_idi8)
+ {
+ s_idi8->Release();
+ s_idi8 = nullptr;
+ }
}
} // namespace ciface::DInput