summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/input/input_dinput.cpp
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2023-02-28 05:16:13 +1100
committer Vas Crabb <vas@vastheman.com>2023-02-28 05:29:22 +1100
commit42e759ade491813588fda7cb185878d80a831a05 (patch)
tree3ac72bab96675ae38062da992b42204a5bdbfef5 /src/osd/modules/input/input_dinput.cpp
parent410a3dbeae2021a357dc2da96c17e189adb715cf (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.cpp15
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");