mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 13:27:45 -07:00
InputCommon: Make the "input gate" not racey.
This commit is contained in:
parent
93d7b3d159
commit
85ceb37ccd
@ -124,11 +124,6 @@ void Host_RequestRenderWindowSize(int width, int height)
|
|||||||
jnicall.join();
|
jnicall.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Host_UINeedsControllerState()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Host_RendererHasFocus()
|
bool Host_RendererHasFocus()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@ -72,6 +72,7 @@
|
|||||||
#include "Core/MemoryWatcher.h"
|
#include "Core/MemoryWatcher.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "InputCommon/ControlReference/ControlReference.h"
|
||||||
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
||||||
#include "InputCommon/GCAdapter.h"
|
#include "InputCommon/GCAdapter.h"
|
||||||
|
|
||||||
@ -1035,4 +1036,11 @@ void DoFrameStep()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateInputGate()
|
||||||
|
{
|
||||||
|
ControlReference::SetInputGate(
|
||||||
|
(SConfig::GetInstance().m_BackgroundInput || Host_RendererHasFocus()) &&
|
||||||
|
!Host_UIBlocksControllerState());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
@ -110,4 +110,6 @@ void HostDispatchJobs();
|
|||||||
|
|
||||||
void DoFrameStep();
|
void DoFrameStep();
|
||||||
|
|
||||||
|
void UpdateInputGate();
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
@ -737,6 +737,7 @@ void Update(u64 ticks)
|
|||||||
|
|
||||||
if (s_half_line_of_next_si_poll == s_half_line_count)
|
if (s_half_line_of_next_si_poll == s_half_line_count)
|
||||||
{
|
{
|
||||||
|
Core::UpdateInputGate();
|
||||||
SerialInterface::UpdateDevices();
|
SerialInterface::UpdateDevices();
|
||||||
s_half_line_of_next_si_poll += 2 * SerialInterface::GetPollXLines();
|
s_half_line_of_next_si_poll += 2 * SerialInterface::GetPollXLines();
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,6 @@ enum class HostMessageID
|
|||||||
WMUserJobDispatch,
|
WMUserJobDispatch,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool Host_UINeedsControllerState();
|
|
||||||
bool Host_UIBlocksControllerState();
|
bool Host_UIBlocksControllerState();
|
||||||
bool Host_RendererHasFocus();
|
bool Host_RendererHasFocus();
|
||||||
bool Host_RendererIsFullscreen();
|
bool Host_RendererIsFullscreen();
|
||||||
|
@ -212,7 +212,7 @@ IPCCommandResult USB_KBD::Write(const ReadWriteRequest& request)
|
|||||||
IPCCommandResult USB_KBD::IOCtl(const IOCtlRequest& request)
|
IPCCommandResult USB_KBD::IOCtl(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
if (SConfig::GetInstance().m_WiiKeyboard && !Core::WantsDeterminism() &&
|
if (SConfig::GetInstance().m_WiiKeyboard && !Core::WantsDeterminism() &&
|
||||||
ControlReference::InputGateOn() && !m_message_queue.empty())
|
ControlReference::GetInputGate() && !m_message_queue.empty())
|
||||||
{
|
{
|
||||||
Memory::CopyToEmu(request.buffer_out, &m_message_queue.front(), sizeof(MessageData));
|
Memory::CopyToEmu(request.buffer_out, &m_message_queue.front(), sizeof(MessageData));
|
||||||
m_message_queue.pop();
|
m_message_queue.pop();
|
||||||
|
@ -82,11 +82,6 @@ void Host_RequestRenderWindowSize(int width, int height)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Host_UINeedsControllerState()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Host_RendererHasFocus()
|
bool Host_RendererHasFocus()
|
||||||
{
|
{
|
||||||
return s_platform->IsWindowFocused();
|
return s_platform->IsWindowFocused();
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
#include "DolphinQt/Config/Mapping/MappingWidget.h"
|
#include "DolphinQt/Config/Mapping/MappingWidget.h"
|
||||||
#include "DolphinQt/QtUtils/ModalMessageBox.h"
|
#include "DolphinQt/QtUtils/ModalMessageBox.h"
|
||||||
#include "DolphinQt/Settings.h"
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -567,9 +566,6 @@ void MappingIndicator::DrawForce(ControllerEmu::Force& force)
|
|||||||
|
|
||||||
void MappingIndicator::paintEvent(QPaintEvent*)
|
void MappingIndicator::paintEvent(QPaintEvent*)
|
||||||
{
|
{
|
||||||
// TODO: The SetControllerStateNeeded interface leaks input into the game.
|
|
||||||
Settings::Instance().SetControllerStateNeeded(true);
|
|
||||||
|
|
||||||
switch (m_group->type)
|
switch (m_group->type)
|
||||||
{
|
{
|
||||||
case ControllerEmu::GroupType::Cursor:
|
case ControllerEmu::GroupType::Cursor:
|
||||||
@ -588,8 +584,6 @@ void MappingIndicator::paintEvent(QPaintEvent*)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings::Instance().SetControllerStateNeeded(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ShakeMappingIndicator::ShakeMappingIndicator(ControllerEmu::Shake* group)
|
ShakeMappingIndicator::ShakeMappingIndicator(ControllerEmu::Shake* group)
|
||||||
@ -599,9 +593,7 @@ ShakeMappingIndicator::ShakeMappingIndicator(ControllerEmu::Shake* group)
|
|||||||
|
|
||||||
void ShakeMappingIndicator::paintEvent(QPaintEvent*)
|
void ShakeMappingIndicator::paintEvent(QPaintEvent*)
|
||||||
{
|
{
|
||||||
Settings::Instance().SetControllerStateNeeded(true);
|
|
||||||
DrawShake();
|
DrawShake();
|
||||||
Settings::Instance().SetControllerStateNeeded(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShakeMappingIndicator::DrawShake()
|
void ShakeMappingIndicator::DrawShake()
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#include "DolphinQt/Config/Mapping/MappingIndicator.h"
|
#include "DolphinQt/Config/Mapping/MappingIndicator.h"
|
||||||
#include "DolphinQt/Config/Mapping/MappingNumeric.h"
|
#include "DolphinQt/Config/Mapping/MappingNumeric.h"
|
||||||
#include "DolphinQt/Config/Mapping/MappingWindow.h"
|
#include "DolphinQt/Config/Mapping/MappingWindow.h"
|
||||||
#include "DolphinQt/Settings.h"
|
|
||||||
|
|
||||||
#include "InputCommon/ControlReference/ControlReference.h"
|
#include "InputCommon/ControlReference/ControlReference.h"
|
||||||
#include "InputCommon/ControllerEmu/Control/Control.h"
|
#include "InputCommon/ControllerEmu/Control/Control.h"
|
||||||
@ -31,11 +30,8 @@ MappingWidget::MappingWidget(MappingWindow* parent) : m_parent(parent)
|
|||||||
|
|
||||||
const auto timer = new QTimer(this);
|
const auto timer = new QTimer(this);
|
||||||
connect(timer, &QTimer::timeout, this, [this] {
|
connect(timer, &QTimer::timeout, this, [this] {
|
||||||
// TODO: The SetControllerStateNeeded interface leaks input into the game.
|
|
||||||
const auto lock = m_parent->GetController()->GetStateLock();
|
const auto lock = m_parent->GetController()->GetStateLock();
|
||||||
Settings::Instance().SetControllerStateNeeded(true);
|
|
||||||
emit Update();
|
emit Update();
|
||||||
Settings::Instance().SetControllerStateNeeded(false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
timer->start(1000 / INDICATOR_UPDATE_FREQ);
|
timer->start(1000 / INDICATOR_UPDATE_FREQ);
|
||||||
|
@ -153,12 +153,6 @@ void Host_RequestRenderWindowSize(int w, int h)
|
|||||||
emit Host::GetInstance()->RequestRenderSize(w, h);
|
emit Host::GetInstance()->RequestRenderSize(w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Host_UINeedsControllerState()
|
|
||||||
{
|
|
||||||
return Settings::Instance().IsControllerStateNeeded() ||
|
|
||||||
(ImGui::GetCurrentContext() && ImGui::GetIO().WantCaptureKeyboard);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Host_UIBlocksControllerState()
|
bool Host_UIBlocksControllerState()
|
||||||
{
|
{
|
||||||
return ImGui::GetCurrentContext() && ImGui::GetIO().WantCaptureKeyboard;
|
return ImGui::GetCurrentContext() && ImGui::GetIO().WantCaptureKeyboard;
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "DolphinQt/Settings.h"
|
#include "DolphinQt/Settings.h"
|
||||||
|
|
||||||
|
#include "InputCommon/ControlReference/ControlReference.h"
|
||||||
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
||||||
|
|
||||||
#include "VideoCommon/OnScreenDisplay.h"
|
#include "VideoCommon/OnScreenDisplay.h"
|
||||||
@ -142,8 +143,14 @@ void HotkeyScheduler::Run()
|
|||||||
|
|
||||||
if (Core::GetState() != Core::State::Stopping)
|
if (Core::GetState() != Core::State::Stopping)
|
||||||
{
|
{
|
||||||
|
// Obey window focus before checking hotkeys.
|
||||||
|
Core::UpdateInputGate();
|
||||||
|
|
||||||
HotkeyManagerEmu::GetStatus();
|
HotkeyManagerEmu::GetStatus();
|
||||||
|
|
||||||
|
// Everything else on the host thread (controller config dialog) should always get input.
|
||||||
|
ControlReference::SetInputGate(true);
|
||||||
|
|
||||||
if (!Core::IsRunningAndStarted())
|
if (!Core::IsRunningAndStarted())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -388,16 +388,6 @@ bool Settings::IsBreakpointsVisible() const
|
|||||||
return GetQSettings().value(QStringLiteral("debugger/showbreakpoints")).toBool();
|
return GetQSettings().value(QStringLiteral("debugger/showbreakpoints")).toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Settings::IsControllerStateNeeded() const
|
|
||||||
{
|
|
||||||
return m_controller_state_needed;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::SetControllerStateNeeded(bool needed)
|
|
||||||
{
|
|
||||||
m_controller_state_needed = needed;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::SetCodeVisible(bool enabled)
|
void Settings::SetCodeVisible(bool enabled)
|
||||||
{
|
{
|
||||||
if (IsCodeVisible() != enabled)
|
if (IsCodeVisible() != enabled)
|
||||||
|
@ -57,8 +57,6 @@ public:
|
|||||||
void SetLogVisible(bool visible);
|
void SetLogVisible(bool visible);
|
||||||
bool IsLogConfigVisible() const;
|
bool IsLogConfigVisible() const;
|
||||||
void SetLogConfigVisible(bool visible);
|
void SetLogConfigVisible(bool visible);
|
||||||
bool IsControllerStateNeeded() const;
|
|
||||||
void SetControllerStateNeeded(bool needed);
|
|
||||||
void SetToolBarVisible(bool visible);
|
void SetToolBarVisible(bool visible);
|
||||||
bool IsToolBarVisible() const;
|
bool IsToolBarVisible() const;
|
||||||
void SetWidgetsLocked(bool visible);
|
void SetWidgetsLocked(bool visible);
|
||||||
@ -179,7 +177,6 @@ signals:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_batch = false;
|
bool m_batch = false;
|
||||||
bool m_controller_state_needed = false;
|
|
||||||
std::shared_ptr<NetPlay::NetPlayClient> m_client;
|
std::shared_ptr<NetPlay::NetPlayClient> m_client;
|
||||||
std::shared_ptr<NetPlay::NetPlayServer> m_server;
|
std::shared_ptr<NetPlay::NetPlayServer> m_server;
|
||||||
Settings();
|
Settings();
|
||||||
|
@ -4,19 +4,18 @@
|
|||||||
|
|
||||||
#include "InputCommon/ControlReference/ControlReference.h"
|
#include "InputCommon/ControlReference/ControlReference.h"
|
||||||
|
|
||||||
// For InputGateOn()
|
|
||||||
// This is a bad layering violation, but it's the cleanest
|
|
||||||
// place I could find to put it.
|
|
||||||
#include "Core/ConfigManager.h"
|
|
||||||
#include "Core/Host.h"
|
|
||||||
|
|
||||||
using namespace ciface::ExpressionParser;
|
using namespace ciface::ExpressionParser;
|
||||||
|
|
||||||
bool ControlReference::InputGateOn()
|
static thread_local bool tls_input_gate = true;
|
||||||
|
|
||||||
|
void ControlReference::SetInputGate(bool enable)
|
||||||
{
|
{
|
||||||
return (SConfig::GetInstance().m_BackgroundInput || Host_RendererHasFocus() ||
|
tls_input_gate = enable;
|
||||||
Host_UINeedsControllerState()) &&
|
}
|
||||||
!Host_UIBlocksControllerState();
|
|
||||||
|
bool ControlReference::GetInputGate()
|
||||||
|
{
|
||||||
|
return tls_input_gate;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -90,7 +89,7 @@ bool OutputReference::IsInput() const
|
|||||||
//
|
//
|
||||||
ControlState InputReference::State(const ControlState ignore)
|
ControlState InputReference::State(const ControlState ignore)
|
||||||
{
|
{
|
||||||
if (m_parsed_expression && InputGateOn())
|
if (m_parsed_expression && GetInputGate())
|
||||||
return m_parsed_expression->GetValue() * range;
|
return m_parsed_expression->GetValue() * range;
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,9 @@
|
|||||||
class ControlReference
|
class ControlReference
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static bool InputGateOn();
|
// Note: this is per thread.
|
||||||
|
static void SetInputGate(bool enable);
|
||||||
|
static bool GetInputGate();
|
||||||
|
|
||||||
virtual ~ControlReference();
|
virtual ~ControlReference();
|
||||||
virtual ControlState State(const ControlState state = 0) = 0;
|
virtual ControlState State(const ControlState state = 0) = 0;
|
||||||
|
@ -34,10 +34,6 @@ void Host_UpdateMainFrame()
|
|||||||
void Host_RequestRenderWindowSize(int, int)
|
void Host_RequestRenderWindowSize(int, int)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
bool Host_UINeedsControllerState()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool Host_RendererHasFocus()
|
bool Host_RendererHasFocus()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -31,10 +31,6 @@ void Host_UpdateMainFrame()
|
|||||||
void Host_RequestRenderWindowSize(int, int)
|
void Host_RequestRenderWindowSize(int, int)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
bool Host_UINeedsControllerState()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool Host_UIBlocksControllerState()
|
bool Host_UIBlocksControllerState()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
Reference in New Issue
Block a user