diff options
Diffstat (limited to 'Source/Core/InputCommon/ControllerInterface/DInput/DInput.cpp')
| -rw-r--r-- | Source/Core/InputCommon/ControllerInterface/DInput/DInput.cpp | 52 |
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 |
