Skip to content

Commit

Permalink
InputManager: Add pressure/deadzone to macros
Browse files Browse the repository at this point in the history
Arguably less useful than on the PS2, but is still applicable
to the left/right analog sticks.
  • Loading branch information
stenzek committed Oct 22, 2024
1 parent 396e7d9 commit 164c043
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 41 deletions.
69 changes: 43 additions & 26 deletions src/core/fullscreen_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3815,16 +3815,10 @@ void FullscreenUI::DrawControllerSettingsPage()
continue;

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);
TinyString::from_format("Macro{}", macro_index + 1), FSUI_CSTR("Trigger"), nullptr, true);

SmallString binds_string =
bsi->GetSmallStringValue(section.c_str(), fmt::format("Macro{}Binds", macro_index + 1).c_str());
bsi->GetSmallStringValue(section.c_str(), TinyString::from_format("Macro{}Binds", macro_index + 1).c_str());
TinyString pretty_binds_string;
if (!binds_string.empty())
{
Expand All @@ -3842,10 +3836,9 @@ void FullscreenUI::DrawControllerSettingsPage()
pretty_binds_string.append_format("{}{}", pretty_binds_string.empty() ? "" : " ", dispname);
}
}
if (MenuButtonWithValue(
TinyString::from_format(fmt::runtime(FSUI_ICONSTR(ICON_FA_KEYBOARD, "Macro {} Buttons")), macro_index + 1),
nullptr, pretty_binds_string.empty() ? FSUI_CSTR("-") : pretty_binds_string.c_str(), true,
LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY))
if (MenuButtonWithValue(FSUI_ICONSTR(ICON_FA_KEYBOARD, "Buttons"), nullptr,
pretty_binds_string.empty() ? FSUI_CSTR("-") : pretty_binds_string.c_str(), true,
LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY))
{
std::vector<std::string_view> buttons_split(StringUtil::SplitString(binds_string, '&', true));
ImGuiFullscreen::ChoiceDialogOptions options;
Expand Down Expand Up @@ -3906,27 +3899,45 @@ void FullscreenUI::DrawControllerSettingsPage()
});
}

DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_GAMEPAD, "Press To Toggle"),
FSUI_CSTR("Toggles the macro when the button is pressed, instead of held."), section.c_str(),
TinyString::from_format("Macro{}Toggle", macro_index + 1), false, true, false);

const TinyString freq_key = TinyString::from_format("Macro{}Frequency", macro_index + 1);
const SmallString freq_title =
SmallString::from_format(fmt::runtime(FSUI_ICONSTR(ICON_FA_LIGHTBULB, "Macro {} Frequency")), macro_index + 1);
const TinyString freq_label =
TinyString::from_format(ICON_FA_CLOCK " {}##macro_{}_frequency", FSUI_VSTR("Frequency"), macro_index + 1);
s32 frequency = bsi->GetIntValue(section.c_str(), freq_key.c_str(), 0);
SmallString freq_summary;
if (frequency == 0)
freq_summary = FSUI_VSTR("Disabled");
else
freq_summary.format(FSUI_FSTR("{} Frames"), frequency);
if (MenuButtonWithValue(freq_title, nullptr, freq_summary, true, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY))
ImGui::OpenPopup(freq_title);
const TinyString freq_summary = ((frequency == 0) ? TinyString(FSUI_VSTR("Disabled")) :
TinyString::from_format(FSUI_FSTR("{} Frames"), frequency));
if (MenuButtonWithValue(
freq_label,
FSUI_CSTR(
"Determines the frequency at which the macro will toggle the buttons on and off (aka auto fire)."),
freq_summary, true))
{
ImGui::OpenPopup(freq_label.c_str());
}

DrawFloatSpinBoxSetting(bsi, FSUI_ICONSTR(ICON_FA_ARROW_DOWN, "Pressure"),
FSUI_CSTR("Determines how much pressure is simulated when macro is active."), section,
TinyString::from_format("Macro{}Pressure", macro_index + 1), 1.0f, 0.01f, 1.0f, 0.01f,
100.0f, "%.0f%%");

DrawFloatSpinBoxSetting(bsi, FSUI_ICONSTR(ICON_FA_SKULL, "Deadzone"),
FSUI_CSTR("Determines how much button pressure is ignored before activating the macro."),
section, TinyString::from_format("Macro{}Deadzone", macro_index + 1).c_str(), 0.0f, 0.00f,
1.0f, 0.01f, 100.0f, "%.0f%%");

ImGui::SetNextWindowSize(LayoutScale(500.0f, 180.0f));
ImGui::SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f));

ImGui::PushFont(g_large_font);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, LayoutScale(10.0f));
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, LayoutScale(ImGuiFullscreen::LAYOUT_MENU_BUTTON_X_PADDING,
ImGuiFullscreen::LAYOUT_MENU_BUTTON_Y_PADDING));
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, LayoutScale(20.0f, 20.0f));

if (ImGui::BeginPopupModal(freq_title, nullptr,
if (ImGui::BeginPopupModal(freq_label, nullptr,
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove))
{
ImGui::SetNextItemWidth(LayoutScale(450.0f));
Expand Down Expand Up @@ -7445,6 +7456,7 @@ TRANSLATE_NOOP("FullscreenUI", "Backend Settings");
TRANSLATE_NOOP("FullscreenUI", "Behavior");
TRANSLATE_NOOP("FullscreenUI", "Borderless Fullscreen");
TRANSLATE_NOOP("FullscreenUI", "Buffer Size");
TRANSLATE_NOOP("FullscreenUI", "Buttons");
TRANSLATE_NOOP("FullscreenUI", "CD-ROM Emulation");
TRANSLATE_NOOP("FullscreenUI", "CPU Emulation");
TRANSLATE_NOOP("FullscreenUI", "CPU Mode");
Expand Down Expand Up @@ -7496,6 +7508,7 @@ TRANSLATE_NOOP("FullscreenUI", "Create Save State Backups");
TRANSLATE_NOOP("FullscreenUI", "Crop Mode");
TRANSLATE_NOOP("FullscreenUI", "Culling Correction");
TRANSLATE_NOOP("FullscreenUI", "Current Game");
TRANSLATE_NOOP("FullscreenUI", "Deadzone");
TRANSLATE_NOOP("FullscreenUI", "Debugging Settings");
TRANSLATE_NOOP("FullscreenUI", "Default");
TRANSLATE_NOOP("FullscreenUI", "Default Boot");
Expand All @@ -7510,15 +7523,18 @@ TRANSLATE_NOOP("FullscreenUI", "Desktop Mode");
TRANSLATE_NOOP("FullscreenUI", "Details");
TRANSLATE_NOOP("FullscreenUI", "Details unavailable for game not scanned in game list.");
TRANSLATE_NOOP("FullscreenUI", "Determines how large the on-screen messages and monitor are.");
TRANSLATE_NOOP("FullscreenUI", "Determines how much button pressure is ignored before activating the macro.");
TRANSLATE_NOOP("FullscreenUI", "Determines how much latency there is between the audio being picked up by the host API, and played through speakers.");
TRANSLATE_NOOP("FullscreenUI", "Determines how much of the area typically not visible on a consumer TV set to crop/hide.");
TRANSLATE_NOOP("FullscreenUI", "Determines how much pressure is simulated when macro is active.");
TRANSLATE_NOOP("FullscreenUI", "Determines how the emulated CPU executes instructions.");
TRANSLATE_NOOP("FullscreenUI", "Determines how the emulated console's output is upscaled or downscaled to your monitor's resolution.");
TRANSLATE_NOOP("FullscreenUI", "Determines quality of audio when not running at 100% speed.");
TRANSLATE_NOOP("FullscreenUI", "Determines that field that the game list will be sorted by.");
TRANSLATE_NOOP("FullscreenUI", "Determines the amount of audio buffered before being pulled by the host API.");
TRANSLATE_NOOP("FullscreenUI", "Determines the emulated hardware type.");
TRANSLATE_NOOP("FullscreenUI", "Determines the format that screenshots will be saved/compressed with.");
TRANSLATE_NOOP("FullscreenUI", "Determines the frequency at which the macro will toggle the buttons on and off (aka auto fire).");
TRANSLATE_NOOP("FullscreenUI", "Determines the margin between the edge of the screen and on-screen messages.");
TRANSLATE_NOOP("FullscreenUI", "Determines the position on the screen when black borders must be added.");
TRANSLATE_NOOP("FullscreenUI", "Determines the rotation of the simulated TV screen.");
Expand Down Expand Up @@ -7616,6 +7632,7 @@ TRANSLATE_NOOP("FullscreenUI", "Forces blending to be done in the shader at 16-b
TRANSLATE_NOOP("FullscreenUI", "Forces the use of FIFO over Mailbox presentation, i.e. double buffering instead of triple buffering. Usually results in worse frame pacing.");
TRANSLATE_NOOP("FullscreenUI", "Forcibly mutes both CD-DA and XA audio from the CD-ROM. Can be used to disable background music in some games.");
TRANSLATE_NOOP("FullscreenUI", "Frame Time Buffer");
TRANSLATE_NOOP("FullscreenUI", "Frequency");
TRANSLATE_NOOP("FullscreenUI", "From File...");
TRANSLATE_NOOP("FullscreenUI", "Fullscreen Resolution");
TRANSLATE_NOOP("FullscreenUI", "GPU Adapter");
Expand Down Expand Up @@ -7700,10 +7717,6 @@ TRANSLATE_NOOP("FullscreenUI", "Logs messages to the console window.");
TRANSLATE_NOOP("FullscreenUI", "Logs messages to the debug console where supported.");
TRANSLATE_NOOP("FullscreenUI", "Logs out of RetroAchievements.");
TRANSLATE_NOOP("FullscreenUI", "Macro Button {}");
TRANSLATE_NOOP("FullscreenUI", "Macro {} Buttons");
TRANSLATE_NOOP("FullscreenUI", "Macro {} Frequency");
TRANSLATE_NOOP("FullscreenUI", "Macro {} Press To Toggle");
TRANSLATE_NOOP("FullscreenUI", "Macro {} Trigger");
TRANSLATE_NOOP("FullscreenUI", "Makes games run closer to their console framerate, at a small cost to performance.");
TRANSLATE_NOOP("FullscreenUI", "Memory Card Busy");
TRANSLATE_NOOP("FullscreenUI", "Memory Card Directory");
Expand Down Expand Up @@ -7773,6 +7786,8 @@ TRANSLATE_NOOP("FullscreenUI", "Post-processing shaders reloaded.");
TRANSLATE_NOOP("FullscreenUI", "Preload Images to RAM");
TRANSLATE_NOOP("FullscreenUI", "Preload Replacement Textures");
TRANSLATE_NOOP("FullscreenUI", "Preserve Projection Precision");
TRANSLATE_NOOP("FullscreenUI", "Press To Toggle");
TRANSLATE_NOOP("FullscreenUI", "Pressure");
TRANSLATE_NOOP("FullscreenUI", "Prevents the emulator from producing any audible sound.");
TRANSLATE_NOOP("FullscreenUI", "Prevents the screen saver from activating and the host from sleeping while emulation is running.");
TRANSLATE_NOOP("FullscreenUI", "Provides vibration and LED control support over Bluetooth.");
Expand Down Expand Up @@ -7962,6 +7977,8 @@ TRANSLATE_NOOP("FullscreenUI", "Toggle Analog");
TRANSLATE_NOOP("FullscreenUI", "Toggle Fast Forward");
TRANSLATE_NOOP("FullscreenUI", "Toggle Fullscreen");
TRANSLATE_NOOP("FullscreenUI", "Toggle every %d frames");
TRANSLATE_NOOP("FullscreenUI", "Toggles the macro when the button is pressed, instead of held.");
TRANSLATE_NOOP("FullscreenUI", "Trigger");
TRANSLATE_NOOP("FullscreenUI", "True Color Rendering");
TRANSLATE_NOOP("FullscreenUI", "Turbo Speed");
TRANSLATE_NOOP("FullscreenUI", "Type");
Expand Down
21 changes: 21 additions & 0 deletions src/duckstation-qt/controllerbindingwidgets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,17 @@ ControllerMacroEditWidget::ControllerMacroEditWidget(ControllerMacroWidget* pare
m_ui.bindList->addItem(item);
}

ControllerSettingWidgetBinder::BindWidgetToInputProfileNormalized(
dialog->getEditingSettingsInterface(), m_ui.pressure, section, fmt::format("Macro{}Pressure", index + 1u), 100.0f,
1.0f);
ControllerSettingWidgetBinder::BindWidgetToInputProfileNormalized(
dialog->getEditingSettingsInterface(), m_ui.deadzone, section, fmt::format("Macro{}Deadzone", index + 1u), 100.0f,
0.0f);
connect(m_ui.pressure, &QSlider::valueChanged, this, &ControllerMacroEditWidget::onPressureChanged);
connect(m_ui.deadzone, &QSlider::valueChanged, this, &ControllerMacroEditWidget::onDeadzoneChanged);
onPressureChanged();
onDeadzoneChanged();

m_frequency = dialog->getIntValue(section.c_str(), TinyString::from_format("Macro{}Frequency", index + 1u), 0);
ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(dialog->getEditingSettingsInterface(), m_ui.triggerToggle,
section.c_str(), fmt::format("Macro{}Toggle", index + 1u),
Expand Down Expand Up @@ -634,6 +645,16 @@ QString ControllerMacroEditWidget::getSummary() const
return str.empty() ? tr("Not Configured") : QString::fromUtf8(str.c_str(), static_cast<int>(str.length()));
}

void ControllerMacroEditWidget::onPressureChanged()
{
m_ui.pressureValue->setText(tr("%1%").arg(m_ui.pressure->value()));
}

void ControllerMacroEditWidget::onDeadzoneChanged()
{
m_ui.deadzoneValue->setText(tr("%1%").arg(m_ui.deadzone->value()));
}

void ControllerMacroEditWidget::onSetFrequencyClicked()
{
bool okay;
Expand Down
2 changes: 2 additions & 0 deletions src/duckstation-qt/controllerbindingwidgets.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ class ControllerMacroEditWidget : public QWidget
QString getSummary() const;

private Q_SLOTS:
void onPressureChanged();
void onDeadzoneChanged();
void onSetFrequencyClicked();
void updateBinds();

Expand Down
110 changes: 101 additions & 9 deletions src/duckstation-qt/controllermacroeditwidget.ui
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>664</width>
<height>420</height>
<width>691</width>
<height>433</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,0,0">
Expand All @@ -29,6 +29,9 @@
<string>Binds/Buttons</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="0">
<widget class="QListWidget" name="bindList"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
Expand All @@ -39,8 +42,57 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QListWidget" name="bindList"/>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Pressure</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>For buttons which are pressure sensitive, this slider controls how much force will be simulated when the macro is active.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="pressureLayout">
<item>
<widget class="QSlider" name="pressure">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>10</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="pressureValue">
<property name="text">
<string>100%</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
Expand All @@ -51,10 +103,10 @@
<string>Trigger</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_5" stretch="1,0">
<item>
<widget class="QLabel" name="label_5">
<widget class="QLabel" name="label">
<property name="text">
<string>Select the trigger to activate this macro. This can be a single button, or combination of buttons (chord). Shift-click for multiple triggers.</string>
</property>
Expand All @@ -67,21 +119,61 @@
</widget>
</item>
<item>
<widget class="QCheckBox" name="triggerToggle">
<widget class="QCheckBox" name="triggerToggle">
<property name="text">
<string>Press To Toggle</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<item row="1" column="0" colspan="2">
<widget class="InputBindingWidget" name="trigger">
<property name="text">
<string>PushButton</string>
<string notr="true">PushButton</string>
</property>
</widget>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="deadzoneLayout" stretch="0,1,0">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Deadzone:</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="deadzone">
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>10</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="deadzoneValue">
<property name="text">
<string>100%</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
Expand Down
Loading

0 comments on commit 164c043

Please sign in to comment.