mirror of
https://github.com/holub/mame
synced 2025-04-20 23:42:22 +03:00
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.
This commit is contained in:
parent
410a3dbeae
commit
42e759ade4
@ -53,18 +53,6 @@
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
CONSTANTS
|
||||
***************************************************************************/
|
||||
|
||||
enum
|
||||
{
|
||||
LOADSAVE_NONE,
|
||||
LOADSAVE_LOAD,
|
||||
LOADSAVE_SAVE
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
LOCAL VARIABLES
|
||||
***************************************************************************/
|
||||
@ -1376,15 +1364,17 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container)
|
||||
// handle a save state request
|
||||
if (machine().ui_input().pressed(IPT_UI_SAVE_STATE))
|
||||
{
|
||||
osd_printf_info("Save requested\n");
|
||||
start_save_state();
|
||||
return LOADSAVE_SAVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// handle a load state request
|
||||
if (machine().ui_input().pressed(IPT_UI_LOAD_STATE))
|
||||
{
|
||||
osd_printf_info("Load requested\n");
|
||||
start_load_state();
|
||||
return LOADSAVE_LOAD;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// handle a save snapshot request
|
||||
|
@ -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");
|
||||
|
@ -654,6 +654,8 @@ void sdl_osd_interface::process_window_event(SDL_Event const &event)
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT_FOCUS_LOST:
|
||||
if (window == m_focus_window)
|
||||
m_focus_window = nullptr;
|
||||
machine().ui_input().push_window_defocus_event(window->target());
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user