diff --git a/src/util/input_manager.cpp b/src/util/input_manager.cpp index be35effa5..dbb46589e 100644 --- a/src/util/input_manager.cpp +++ b/src/util/input_manager.cpp @@ -78,6 +78,7 @@ struct InputBinding u8 num_keys = 0; u8 full_mask = 0; u8 current_mask = 0; + bool activate_when_captured = false; }; struct PadVibrationBinding @@ -146,7 +147,8 @@ static std::vector SplitChord(std::string_view binding); static bool SplitBinding(std::string_view binding, std::string_view* source, std::string_view* sub_binding); static void PrettifyInputBindingPart(std::string_view binding, bool allow_icon, BindingIconMappingFunction mapper, SmallString& ret, bool& changed); -static void AddBindings(const std::vector& bindings, const InputEventHandler& handler); +static void AddBindings(const std::vector& bindings, bool activate_when_captured, + const InputEventHandler& handler); static void UpdatePointerCount(); static bool IsAxisHandler(const InputEventHandler& handler); @@ -637,13 +639,14 @@ void InputManager::PrettifyInputBindingPart(const std::string_view binding, bool ret.append(binding); } -void InputManager::AddBindings(const std::vector& bindings, const InputEventHandler& handler) +void InputManager::AddBindings(const std::vector& bindings, bool activate_when_captured, + const InputEventHandler& handler) { for (const std::string& binding : bindings) - AddBinding(binding, handler); + AddBinding(binding, activate_when_captured, handler); } -void InputManager::AddBinding(std::string_view binding, const InputEventHandler& handler) +void InputManager::AddBinding(std::string_view binding, bool activate_when_captured, const InputEventHandler& handler) { std::shared_ptr ibinding; const std::vector chord_bindings(SplitChord(binding)); @@ -662,6 +665,7 @@ void InputManager::AddBinding(std::string_view binding, const InputEventHandler& { ibinding = std::make_shared(); ibinding->handler = handler; + ibinding->activate_when_captured = activate_when_captured; } if (ibinding->num_keys == MAX_KEYS_PER_BINDING) @@ -955,7 +959,7 @@ void InputManager::AddHotkeyBindings(const SettingsInterface& si) if (bindings.empty()) continue; - AddBindings(bindings, InputButtonEventHandler{hotkey.handler}); + AddBindings(bindings, hotkey.activate_when_captured, InputButtonEventHandler{hotkey.handler}); } } @@ -978,15 +982,16 @@ void InputManager::AddPadBindings(const SettingsInterface& si, const std::string si.GetFloatValue(section.c_str(), TinyString::from_format("{}Scale", bi.name), 1.0f); const float deadzone = si.GetFloatValue(section.c_str(), TinyString::from_format("{}Deadzone", bi.name), 0.0f); - AddBindings(bindings, InputAxisEventHandler{[pad_index, bind_index = bi.bind_index, sensitivity, - deadzone](float value) { - if (!System::IsValid()) - return; - - Controller* c = System::GetController(pad_index); - if (c) - c->SetBindState(bind_index, ApplySingleBindingScale(sensitivity, deadzone, value)); - }}); + AddBindings( + bindings, false, + InputAxisEventHandler{[pad_index, bind_index = bi.bind_index, sensitivity, deadzone](float value) { + if (!System::IsValid()) + return; + + Controller* c = System::GetController(pad_index); + if (c) + c->SetBindState(bind_index, ApplySingleBindingScale(sensitivity, deadzone, value)); + }}); } } break; @@ -1243,9 +1248,11 @@ bool InputManager::ProcessEvent(InputBindingKey key, float value, bool skip_butt } else if (binding->num_keys >= min_num_keys) { + const bool skip_button_handler = skip_button_handlers && !binding->activate_when_captured; + // update state based on whether the whole chord was activated const u8 new_mask = - ((new_state && !skip_button_handlers) ? (binding->current_mask | bit) : (binding->current_mask & ~bit)); + ((new_state && !skip_button_handler) ? (binding->current_mask | bit) : (binding->current_mask & ~bit)); const bool prev_full_state = (binding->current_mask == binding->full_mask); const bool new_full_state = (new_mask == binding->full_mask); binding->current_mask = new_mask; @@ -1289,7 +1296,7 @@ bool InputManager::ProcessEvent(InputBindingKey key, float value, bool skip_butt if (prev_full_state != new_full_state && binding->num_keys >= min_num_keys) { - const s32 pressed = skip_button_handlers ? -1 : static_cast(value_to_pass > 0.0f); + const s32 pressed = skip_button_handler ? -1 : static_cast(value_to_pass > 0.0f); std::get(binding->handler)(pressed); } } @@ -1432,7 +1439,7 @@ bool InputManager::PreprocessEvent(InputBindingKey key, float value, GenericInpu if (ImGuiManager::ProcessPointerButtonEvent(key, value)) return true; } - else if (generic_key != GenericInputBinding::Unknown) + else if (key.source_type > InputSourceType::Pointer) { if (ImGuiManager::ProcessGenericInputEvent(generic_key, value) && value != 0.0f) return true; @@ -2143,17 +2150,17 @@ void InputManager::LoadMacroButtonConfig(const SettingsInterface& si, const std: if (deadzone != 0.0f) WARNING_LOG("Chord binding {} not supported with trigger deadzone {}.", trigger_binding, deadzone); - AddBinding(trigger_binding, - InputButtonEventHandler{[pad = macro.pad_index, index = macro.macro_index](bool state) { + AddBinding(trigger_binding, false, + InputButtonEventHandler{[pad = macro.pad_index, index = macro.macro_index](s32 state) { if (!System::IsValid()) return; - SetMacroButtonState(pad, index, state); + SetMacroButtonState(pad, index, (state > 0)); }}); } else { - AddBindings(trigger_bindings, + AddBindings(trigger_bindings, false, InputAxisEventHandler{[pad = macro.pad_index, index = macro.macro_index, deadzone](float value) { if (!System::IsValid()) return; diff --git a/src/util/input_manager.h b/src/util/input_manager.h index 7376b536a..ddae514dc 100644 --- a/src/util/input_manager.h +++ b/src/util/input_manager.h @@ -139,6 +139,7 @@ struct HotkeyInfo const char* category; const char* display_name; void (*handler)(s32 pressed); + bool activate_when_captured = false; }; /// Generic input bindings. These roughly match a DualShock 4 or XBox One controller. @@ -311,7 +312,7 @@ bool HasAnyBindingsForSubclass(InputBindingKey key); bool ParseBindingAndGetSource(std::string_view binding, InputBindingKey* key, InputSource** source); /// Externally adds a fixed binding. Be sure to call *after* ReloadBindings() otherwise it will be lost. -void AddBinding(std::string_view binding, const InputEventHandler& handler); +void AddBinding(std::string_view binding, bool activate_when_captured, const InputEventHandler& handler); /// Adds an external vibration binding. void AddVibrationBinding(u32 pad_index, u32 bind_index, const InputBindingKey& binding, InputSource* source);