diff options
author | 2023-02-28 05:16:13 +1100 | |
---|---|---|
committer | 2023-02-28 05:29:22 +1100 | |
commit | 42e759ade491813588fda7cb185878d80a831a05 (patch) | |
tree | 3ac72bab96675ae38062da992b42204a5bdbfef5 /src/osd/modules/input/input_dinput.cpp | |
parent | 410a3dbeae2021a357dc2da96c17e189adb715cf (diff) |
osd/modules/input: Always use DirectInput with desktop window in background mode.
There are multiple issues with what MAME was doing, but the most glaring
is that it violates the DirectInput interface contract that requires the
window associated with an open device must not be destroyed. See
documentation for IDirectInputDevice8::SetCooperativeLevel: "This
parameter must be a valid top-level window handle that belongs to the
process. The window associated with the device must not be destroyed
while it is still active in a DirectInput device."
The previous code also prevented DirectInput controllers from working
when using multiple windows if any window other than the first window
had focus.
Also fixed SDL builds not correctly recognising when all windows lose
focus, and save state menu not appearing.
Diffstat (limited to 'src/osd/modules/input/input_dinput.cpp')
-rw-r--r-- | src/osd/modules/input/input_dinput.cpp | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/src/osd/modules/input/input_dinput.cpp b/src/osd/modules/input/input_dinput.cpp index 9bc417caf0f..6cbe668c108 100644 --- a/src/osd/modules/input/input_dinput.cpp +++ b/src/osd/modules/input/input_dinput.cpp @@ -1221,7 +1221,7 @@ std::pair<Microsoft::WRL::ComPtr<IDirectInputDevice8>, LPCDIDATAFORMAT> dinput_a // attempt to create a device Microsoft::WRL::ComPtr<IDirectInputDevice8> device; - result = m_dinput->CreateDevice(instance->guidInstance, device.GetAddressOf(), nullptr); + result = m_dinput->CreateDevice(instance->guidInstance, &device, nullptr); if (result != DI_OK) { osd_printf_error("DirectInput: Unable to create device.\n"); @@ -1245,7 +1245,13 @@ std::pair<Microsoft::WRL::ComPtr<IDirectInputDevice8>, LPCDIDATAFORMAT> dinput_a } // default window to the first window in the list - HWND window_handle; + // For now, we always use the desktop window due to multiple issues: + // * MAME recreates windows on toggling fullscreen. DirectInput really doesn't like this. + // * DirectInput doesn't like the window used for D3D fullscreen exclusive mode. + // * With multiple windows, the first window needs to have focus when using foreground mode. + // This makes it impossible to use force feedback as that requires foreground exclusive mode. + // The only way to get around this would be to reopen devices on focus changes. + [[maybe_unused]] HWND window_handle; DWORD di_cooperative_level; #if defined(OSD_WINDOWS) auto const &window = dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()); @@ -1278,7 +1284,8 @@ std::pair<Microsoft::WRL::ComPtr<IDirectInputDevice8>, LPCDIDATAFORMAT> dinput_a di_cooperative_level = DISCL_BACKGROUND | DISCL_NONEXCLUSIVE; break; case dinput_cooperative_level::FOREGROUND: - di_cooperative_level = DISCL_FOREGROUND | DISCL_NONEXCLUSIVE; + //di_cooperative_level = DISCL_FOREGROUND | DISCL_NONEXCLUSIVE; + di_cooperative_level = DISCL_BACKGROUND | DISCL_NONEXCLUSIVE; break; default: throw false; @@ -1286,7 +1293,7 @@ std::pair<Microsoft::WRL::ComPtr<IDirectInputDevice8>, LPCDIDATAFORMAT> dinput_a } // set the cooperative level - result = device->SetCooperativeLevel(window_handle, di_cooperative_level); + result = device->SetCooperativeLevel(GetDesktopWindow(), di_cooperative_level); if (result != DI_OK) { osd_printf_error("DirectInput: Unable to set cooperative level.\n"); |