diff --git a/src/core/fullscreen_ui.cpp b/src/core/fullscreen_ui.cpp index dd621e20e..8f055d01e 100644 --- a/src/core/fullscreen_ui.cpp +++ b/src/core/fullscreen_ui.cpp @@ -3803,6 +3803,11 @@ void FullscreenUI::DrawControllerSettingsPage() DrawInputBindingButton(bsi, InputBindingInfo::Type::Macro, section.c_str(), TinyString::from_format("Macro{}", macro_index + 1), TinyString::from_format(FSUI_FSTR("Macro {} Trigger"), macro_index + 1), nullptr); + DrawToggleSetting(bsi, + TinyString::from_format(fmt::runtime(FSUI_ICONSTR(ICON_FA_GAMEPAD, "Macro {} Press To Toggle")), + macro_index + 1), + nullptr, section.c_str(), TinyString::from_format("Macro{}Toggle", macro_index + 1), false, + true, false, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY); SmallString binds_string = bsi->GetSmallStringValue(section.c_str(), fmt::format("Macro{}Binds", macro_index + 1).c_str()); diff --git a/src/duckstation-qt/controllerbindingwidgets.cpp b/src/duckstation-qt/controllerbindingwidgets.cpp index 08db8f0e8..4b9283357 100644 --- a/src/duckstation-qt/controllerbindingwidgets.cpp +++ b/src/duckstation-qt/controllerbindingwidgets.cpp @@ -569,7 +569,7 @@ ControllerMacroEditWidget::ControllerMacroEditWidget(ControllerMacroWidget* pare // load binds (single string joined by &) const std::string binds_string( - dialog->getStringValue(section.c_str(), fmt::format("Macro{}Binds", index + 1u).c_str(), "")); + dialog->getStringValue(section.c_str(), TinyString::from_format("Macro{}Binds", index + 1u), "")); const std::vector buttons_split(StringUtil::SplitString(binds_string, '&', true)); for (const std::string_view& button : buttons_split) @@ -597,7 +597,10 @@ ControllerMacroEditWidget::ControllerMacroEditWidget(ControllerMacroWidget* pare m_ui.bindList->addItem(item); } - m_frequency = dialog->getIntValue(section.c_str(), fmt::format("Macro{}Frequency", index + 1u).c_str(), 0); + m_frequency = dialog->getIntValue(section.c_str(), TinyString::from_format("Macro{}Frequency", index + 1u), 0); + ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(dialog->getProfileSettingsInterface(), m_ui.triggerToggle, + section.c_str(), fmt::format("Macro{}Toggle", index + 1u), + false); updateFrequencyText(); m_ui.trigger->initialize(dialog->getProfileSettingsInterface(), InputBindingInfo::Type::Macro, section, diff --git a/src/duckstation-qt/controllermacroeditwidget.ui b/src/duckstation-qt/controllermacroeditwidget.ui index 33cde4ed3..d4f051c2e 100644 --- a/src/duckstation-qt/controllermacroeditwidget.ui +++ b/src/duckstation-qt/controllermacroeditwidget.ui @@ -6,11 +6,11 @@ 0 0 - 595 - 473 + 664 + 420 - + 0 @@ -51,20 +51,31 @@ Trigger - - - - Select the trigger to activate this macro. This can be a single button, or combination of buttons (chord). Shift-click for multiple triggers. - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - true - - + + + + + + Select the trigger to activate this macro. This can be a single button, or combination of buttons (chord). Shift-click for multiple triggers. + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + + Press To Toggle + + + + - + PushButton @@ -127,19 +138,6 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - diff --git a/src/util/imgui_fullscreen.cpp b/src/util/imgui_fullscreen.cpp index df82a8014..7fe712a64 100644 --- a/src/util/imgui_fullscreen.cpp +++ b/src/util/imgui_fullscreen.cpp @@ -1358,7 +1358,7 @@ bool ImGuiFullscreen::ToggleButton(const char* title, const char* summary, bool* const float toggle_width = LayoutScale(50.0f); const float toggle_height = LayoutScale(25.0f); const float toggle_x = LayoutScale(8.0f); - const float toggle_y = (LayoutScale(LAYOUT_MENU_BUTTON_HEIGHT) - toggle_height) * 0.5f; + const float toggle_y = (LayoutScale(height) - toggle_height) * 0.5f; const float toggle_radius = toggle_height * 0.5f; const ImVec2 toggle_pos(bb.Max.x - toggle_width - toggle_x, bb.Min.y + toggle_y); diff --git a/src/util/input_manager.cpp b/src/util/input_manager.cpp index 39aa528c8..df99c1825 100644 --- a/src/util/input_manager.cpp +++ b/src/util/input_manager.cpp @@ -86,10 +86,11 @@ struct PadVibrationBinding struct MacroButton { std::vector buttons; ///< Buttons to activate. - u32 toggle_frequency; ///< Interval at which the buttons will be toggled, if not 0. - u32 toggle_counter; ///< When this counter reaches zero, buttons will be toggled. + u16 toggle_frequency; ///< Interval at which the buttons will be toggled, if not 0. + u16 toggle_counter; ///< When this counter reaches zero, buttons will be toggled. bool toggle_state; ///< Current state for turbo. bool trigger_state; ///< Whether the macro button is active. + bool trigger_toggle; ///< Whether the macro is trigged by holding or press. }; } // namespace @@ -1578,10 +1579,13 @@ void InputManager::LoadMacroButtonConfig(SettingsInterface& si, const std::strin for (u32 i = 0; i < NUM_MACRO_BUTTONS_PER_CONTROLLER; i++) { std::string binds_string; - if (!si.GetStringValue(section.c_str(), fmt::format("Macro{}Binds", i + 1u).c_str(), &binds_string)) + if (!si.GetStringValue(section.c_str(), TinyString::from_format("Macro{}Binds", i + 1u), &binds_string)) continue; - const u32 frequency = si.GetUIntValue(section.c_str(), fmt::format("Macro{}Frequency", i + 1u).c_str(), 0u); + const u32 frequency = + std::min(si.GetUIntValue(section.c_str(), TinyString::from_format("Macro{}Frequency", i + 1u), 0u), + std::numeric_limits::max()); + const bool toggle = si.GetBoolValue(section.c_str(), TinyString::from_format("Macro{}Toggle", i + 1u), false); // convert binds std::vector bind_indices; @@ -1612,7 +1616,8 @@ void InputManager::LoadMacroButtonConfig(SettingsInterface& si, const std::strin continue; s_macro_buttons[pad][i].buttons = std::move(bind_indices); - s_macro_buttons[pad][i].toggle_frequency = frequency; + s_macro_buttons[pad][i].toggle_frequency = static_cast(frequency); + s_macro_buttons[pad][i].trigger_toggle = toggle; } } @@ -1622,14 +1627,18 @@ void InputManager::SetMacroButtonState(u32 pad, u32 index, bool state) return; MacroButton& mb = s_macro_buttons[pad][index]; - if (mb.buttons.empty() || mb.trigger_state == state) + if (mb.buttons.empty()) + return; + + const bool trigger_state = (mb.trigger_toggle ? (state ? !mb.trigger_state : mb.trigger_state) : state); + if (mb.trigger_state == trigger_state) return; mb.toggle_counter = mb.toggle_frequency; - mb.trigger_state = state; - if (mb.toggle_state != state) + mb.trigger_state = trigger_state; + if (mb.toggle_state != trigger_state) { - mb.toggle_state = state; + mb.toggle_state = trigger_state; ApplyMacroButton(pad, mb); } }