System: Synchronize input binding state on startup

This means that buttons which are pushed should register as pushed when
the system starts, rather than requiring them to be released and pressed
again.

Hopefully will allow passthrough of controllers that ground/press button
combinations to indicate the type of controller present.
This commit is contained in:
Stenzek
2025-08-13 14:40:54 +10:00
parent 33b3a6efda
commit c0c022591c
3 changed files with 56 additions and 0 deletions

View File

@@ -1857,6 +1857,7 @@ bool System::BootSystem(SystemBootParameters parameters, Error* error)
}
InputManager::UpdateHostMouseMode();
InputManager::SynchronizeBindingHandlerState();
if (g_settings.inhibit_screensaver)
PlatformMisc::SuspendScreensaver();

View File

@@ -1185,6 +1185,58 @@ void InputManager::ClearBindStateFromSource(InputBindingKey key)
} while (matched);
}
void InputManager::SynchronizeBindingHandlerState()
{
// should be called on the main thread, so no need to lock
for (const auto& [key, binding] : s_binding_map)
{
// ignore hotkeys
if (!IsAxisHandler(binding->handler))
continue;
if (key.source_type >= InputSourceType::Count || !s_input_sources[static_cast<u32>(key.source_type)])
continue;
const std::optional<float> value = s_input_sources[static_cast<u32>(key.source_type)]->GetCurrentValue(key);
if (!value.has_value())
continue;
const InputBindingKey masked_key = key.MaskDirection();
for (u32 i = 0; i < binding->num_keys; i++)
{
if (binding->keys[i].MaskDirection() != masked_key)
continue;
float value_to_pass = 0.0f;
switch (binding->keys[i].modifier)
{
case InputModifier::None:
{
if (value > 0.0f)
value_to_pass = value.value();
}
break;
case InputModifier::Negate:
{
if (value < 0.0f)
value_to_pass = -value.value();
}
break;
case InputModifier::FullAxis:
{
value_to_pass = value.value() * 0.5f + 0.5f;
}
break;
}
// handle inverting, needed for some wheels.
value_to_pass = binding->keys[i].invert ? (1.0f - value_to_pass) : value_to_pass;
std::get<InputAxisEventHandler>(binding->handler)(value_to_pass);
}
}
}
bool InputManager::PreprocessEvent(InputBindingKey key, float value, GenericInputBinding generic_key)
{
// does imgui want the event?

View File

@@ -282,6 +282,9 @@ GenericInputBindingMapping GetGenericBindingMapping(std::string_view device);
/// Returns true if the specified input source is enabled.
bool IsInputSourceEnabled(const SettingsInterface& si, InputSourceType type);
/// Synchronizes handlers with the current state of all registered bindings.
void SynchronizeBindingHandlerState();
/// Re-parses the config and registers all hotkey and pad bindings.
void ReloadBindings(const SettingsInterface& si, const SettingsInterface& hotkey_binding_si);