summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorAdmiral H. Curtiss <pikachu025@gmail.com>2022-06-28 02:43:30 +0200
committerGitHub <noreply@github.com>2022-06-28 02:43:30 +0200
commite8965c63e41871538a97630bfdd628119fec6aca (patch)
treea1866071a5a83301e451112ae4525119e2e56f02 /Source/Core
parente18053d3075dd010a3a9db80d1b29b99cf7b69da (diff)
parent4c409411edb2957a0f6505aaf6c93e5c6c71f896 (diff)
Merge pull request #10682 from jordan-woyak/gate-size-setting
ControllerEmu: Allow changing the target gate radius of octagon sticks.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp119
-rw-r--r--Source/Core/DolphinQt/Config/Mapping/MappingWidget.h4
-rw-r--r--Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp17
-rw-r--r--Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.h2
-rw-r--r--Source/Core/InputCommon/ControllerEmu/ControlGroup/ControlGroup.cpp3
-rw-r--r--Source/Core/InputCommon/ControllerEmu/Setting/NumericSetting.cpp5
-rw-r--r--Source/Core/InputCommon/ControllerEmu/Setting/NumericSetting.h21
7 files changed, 143 insertions, 28 deletions
diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp
index 1206ad75ff..a7ea873e41 100644
--- a/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp
+++ b/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp
@@ -4,6 +4,7 @@
#include "DolphinQt/Config/Mapping/MappingWidget.h"
#include <QCheckBox>
+#include <QDialogButtonBox>
#include <QFormLayout>
#include <QGroupBox>
#include <QHBoxLayout>
@@ -121,8 +122,54 @@ QGroupBox* MappingWidget::CreateGroupBox(const QString& name, ControllerEmu::Con
for (auto& control : group->controls)
CreateControl(control.get(), form_layout, !indicator);
+ AddSettingWidgets(form_layout, group, ControllerEmu::SettingVisibility::Normal);
+
+ if (group->default_value != ControllerEmu::ControlGroup::DefaultValue::AlwaysEnabled)
+ {
+ QLabel* group_enable_label = new QLabel(tr("Enable"));
+ QCheckBox* group_enable_checkbox = new QCheckBox();
+ group_enable_checkbox->setChecked(group->enabled);
+ form_layout->insertRow(0, group_enable_label, group_enable_checkbox);
+ auto enable_group_by_checkbox = [group, form_layout, group_enable_label,
+ group_enable_checkbox] {
+ group->enabled = group_enable_checkbox->isChecked();
+ for (int i = 0; i < form_layout->count(); ++i)
+ {
+ QWidget* widget = form_layout->itemAt(i)->widget();
+ if (widget != nullptr && widget != group_enable_label && widget != group_enable_checkbox)
+ widget->setEnabled(group->enabled);
+ }
+ };
+ enable_group_by_checkbox();
+ connect(group_enable_checkbox, &QCheckBox::toggled, this, enable_group_by_checkbox);
+ connect(this, &MappingWidget::ConfigChanged, this,
+ [group_enable_checkbox, group] { group_enable_checkbox->setChecked(group->enabled); });
+ }
+
+ const auto advanced_setting_count = std::count_if(
+ group->numeric_settings.begin(), group->numeric_settings.end(), [](auto& setting) {
+ return setting->GetVisibility() == ControllerEmu::SettingVisibility::Advanced;
+ });
+
+ if (advanced_setting_count != 0)
+ {
+ const auto advanced_button = new QPushButton(tr("Advanced"));
+ form_layout->addRow(advanced_button);
+ connect(advanced_button, &QPushButton::clicked,
+ [this, group] { ShowAdvancedControlGroupDialog(group); });
+ }
+
+ return group_box;
+}
+
+void MappingWidget::AddSettingWidgets(QFormLayout* layout, ControllerEmu::ControlGroup* group,
+ ControllerEmu::SettingVisibility visibility)
+{
for (auto& setting : group->numeric_settings)
{
+ if (setting->GetVisibility() != visibility)
+ continue;
+
QWidget* setting_widget = nullptr;
switch (setting->GetType())
@@ -149,33 +196,59 @@ QGroupBox* MappingWidget::CreateGroupBox(const QString& name, ControllerEmu::Con
hbox->addWidget(setting_widget);
hbox->addWidget(CreateSettingAdvancedMappingButton(*setting));
- form_layout->addRow(tr(setting->GetUIName()), hbox);
+ layout->addRow(tr(setting->GetUIName()), hbox);
}
}
+}
- if (group->default_value != ControllerEmu::ControlGroup::DefaultValue::AlwaysEnabled)
- {
- QLabel* group_enable_label = new QLabel(tr("Enable"));
- QCheckBox* group_enable_checkbox = new QCheckBox();
- group_enable_checkbox->setChecked(group->enabled);
- form_layout->insertRow(0, group_enable_label, group_enable_checkbox);
- auto enable_group_by_checkbox = [group, form_layout, group_enable_label,
- group_enable_checkbox] {
- group->enabled = group_enable_checkbox->isChecked();
- for (int i = 0; i < form_layout->count(); ++i)
- {
- QWidget* widget = form_layout->itemAt(i)->widget();
- if (widget != nullptr && widget != group_enable_label && widget != group_enable_checkbox)
- widget->setEnabled(group->enabled);
- }
- };
- enable_group_by_checkbox();
- connect(group_enable_checkbox, &QCheckBox::toggled, this, enable_group_by_checkbox);
- connect(this, &MappingWidget::ConfigChanged, this,
- [group_enable_checkbox, group] { group_enable_checkbox->setChecked(group->enabled); });
- }
+void MappingWidget::ShowAdvancedControlGroupDialog(ControllerEmu::ControlGroup* group)
+{
+ QDialog dialog{this};
+ dialog.setWindowTitle(tr(group->ui_name.c_str()));
- return group_box;
+ const auto group_box = new QGroupBox(tr("Advanced Settings"));
+
+ QFormLayout* form_layout = new QFormLayout();
+
+ AddSettingWidgets(form_layout, group, ControllerEmu::SettingVisibility::Advanced);
+
+ const auto reset_button = new QPushButton(tr("Reset All"));
+ form_layout->addRow(reset_button);
+
+ connect(reset_button, &QPushButton::clicked, [this, group] {
+ for (auto& setting : group->numeric_settings)
+ {
+ if (setting->GetVisibility() != ControllerEmu::SettingVisibility::Advanced)
+ continue;
+
+ setting->SetToDefault();
+ }
+
+ emit ConfigChanged();
+ });
+
+ const auto main_layout = new QVBoxLayout();
+ const auto button_box = new QDialogButtonBox(QDialogButtonBox::Close);
+
+ group_box->setLayout(form_layout);
+
+ main_layout->addWidget(group_box);
+ main_layout->addWidget(button_box);
+
+ dialog.setLayout(main_layout);
+
+ // Focusing something else by default instead of the first spin box.
+ // Dynamically changing expression-backed settings pause when taking input.
+ // This just avoids that weird edge case behavior when the dialog is first open.
+ button_box->setFocus();
+
+ // Signal the newly created numeric setting widgets to display the current values.
+ emit ConfigChanged();
+
+ // Enable "Close" button functionality.
+ connect(button_box, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
+
+ dialog.exec();
}
QGroupBox* MappingWidget::CreateControlsBox(const QString& name, ControllerEmu::ControlGroup* group,
diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingWidget.h b/Source/Core/DolphinQt/Config/Mapping/MappingWidget.h
index ad55172f4a..941bb09577 100644
--- a/Source/Core/DolphinQt/Config/Mapping/MappingWidget.h
+++ b/Source/Core/DolphinQt/Config/Mapping/MappingWidget.h
@@ -26,6 +26,7 @@ class Control;
class ControlGroup;
class EmulatedController;
class NumericSettingBase;
+enum class SettingVisibility;
} // namespace ControllerEmu
constexpr int INDICATOR_UPDATE_FREQ = 30;
@@ -57,6 +58,9 @@ protected:
int columns);
void CreateControl(const ControllerEmu::Control* control, QFormLayout* layout, bool indicator);
QPushButton* CreateSettingAdvancedMappingButton(ControllerEmu::NumericSettingBase& setting);
+ void AddSettingWidgets(QFormLayout* layout, ControllerEmu::ControlGroup* group,
+ ControllerEmu::SettingVisibility visibility);
+ void ShowAdvancedControlGroupDialog(ControllerEmu::ControlGroup* group);
private:
MappingWindow* m_parent;
diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp b/Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp
index aaabfa5b17..539e02b449 100644
--- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp
+++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp
@@ -65,9 +65,19 @@ OctagonAnalogStick::OctagonAnalogStick(const char* name_, ControlState gate_radi
OctagonAnalogStick::OctagonAnalogStick(const char* name_, const char* ui_name_,
ControlState gate_radius)
- : AnalogStick(name_, ui_name_, std::make_unique<ControllerEmu::OctagonStickGate>(gate_radius))
+ : AnalogStick(name_, ui_name_, std::make_unique<ControllerEmu::OctagonStickGate>(1.0))
{
AddVirtualNotchSetting(&m_virtual_notch_setting, 45);
+
+ AddSetting(
+ &m_gate_size_setting,
+ {_trans("Gate Size"),
+ // i18n: The percent symbol.
+ _trans("%"),
+ // i18n: Refers to plastic shell of game controller (stick gate) that limits stick movements.
+ _trans("Adjusts target radius of simulated stick gate."), nullptr,
+ SettingVisibility::Advanced},
+ gate_radius * 100, 0.01, 100);
}
ControlState OctagonAnalogStick::GetVirtualNotchSize() const
@@ -75,4 +85,9 @@ ControlState OctagonAnalogStick::GetVirtualNotchSize() const
return m_virtual_notch_setting.GetValue() * MathUtil::TAU / 360;
}
+ControlState OctagonAnalogStick::GetGateRadiusAtAngle(double ang) const
+{
+ return AnalogStick::GetGateRadiusAtAngle(ang) * m_gate_size_setting.GetValue() / 100;
+}
+
} // namespace ControllerEmu
diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.h b/Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.h
index d5363cecef..47e3ad5743 100644
--- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.h
+++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.h
@@ -36,9 +36,11 @@ public:
OctagonAnalogStick(const char* name, const char* ui_name, ControlState gate_radius);
ControlState GetVirtualNotchSize() const override;
+ ControlState GetGateRadiusAtAngle(double ang) const override;
private:
SettingValue<double> m_virtual_notch_setting;
+ SettingValue<double> m_gate_size_setting;
};
} // namespace ControllerEmu
diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/ControlGroup.cpp b/Source/Core/InputCommon/ControllerEmu/ControlGroup/ControlGroup.cpp
index 2f1eb25d5e..890c43a848 100644
--- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/ControlGroup.cpp
+++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/ControlGroup.cpp
@@ -32,7 +32,8 @@ void ControlGroup::AddVirtualNotchSetting(SettingValue<double>* value, double ma
AddSetting(value,
{_trans("Virtual Notches"),
// i18n: The degrees symbol.
- _trans("°"), _trans("Snap the thumbstick position to the nearest octagonal axis.")},
+ _trans("°"), _trans("Snap the thumbstick position to the nearest octagonal axis."),
+ nullptr, SettingVisibility::Advanced},
0, 0, max_virtual_notch_deg);
}
diff --git a/Source/Core/InputCommon/ControllerEmu/Setting/NumericSetting.cpp b/Source/Core/InputCommon/ControllerEmu/Setting/NumericSetting.cpp
index 70352ccfd8..f7f2054927 100644
--- a/Source/Core/InputCommon/ControllerEmu/Setting/NumericSetting.cpp
+++ b/Source/Core/InputCommon/ControllerEmu/Setting/NumericSetting.cpp
@@ -26,6 +26,11 @@ const char* NumericSettingBase::GetUIDescription() const
return m_details.ui_description;
}
+SettingVisibility NumericSettingBase::GetVisibility() const
+{
+ return m_details.visibility;
+}
+
template <>
void NumericSetting<int>::SetExpressionFromValue()
{
diff --git a/Source/Core/InputCommon/ControllerEmu/Setting/NumericSetting.h b/Source/Core/InputCommon/ControllerEmu/Setting/NumericSetting.h
index 467e55f039..8b36ab117e 100644
--- a/Source/Core/InputCommon/ControllerEmu/Setting/NumericSetting.h
+++ b/Source/Core/InputCommon/ControllerEmu/Setting/NumericSetting.h
@@ -20,13 +20,20 @@ enum class SettingType
Bool,
};
+enum class SettingVisibility
+{
+ Normal,
+ Advanced,
+};
+
struct NumericSettingDetails
{
NumericSettingDetails(const char* const _ini_name, const char* const _ui_suffix = nullptr,
const char* const _ui_description = nullptr,
- const char* const _ui_name = nullptr)
+ const char* const _ui_name = nullptr,
+ SettingVisibility _visibility = SettingVisibility::Normal)
: ini_name(_ini_name), ui_suffix(_ui_suffix), ui_description(_ui_description),
- ui_name(_ui_name ? _ui_name : _ini_name)
+ ui_name(_ui_name ? _ui_name : _ini_name), visibility(_visibility)
{
}
@@ -41,6 +48,9 @@ struct NumericSettingDetails
// The name used in the UI (if different from ini file).
const char* const ui_name;
+
+ // Advanced settings should be harder to change in the UI. They might confuse users.
+ const SettingVisibility visibility;
};
class NumericSettingBase
@@ -66,9 +76,12 @@ public:
virtual SettingType GetType() const = 0;
+ virtual void SetToDefault() = 0;
+
const char* GetUIName() const;
const char* GetUISuffix() const;
const char* GetUIDescription() const;
+ SettingVisibility GetVisibility() const;
protected:
NumericSettingDetails m_details;
@@ -92,9 +105,11 @@ public:
: NumericSettingBase(details), m_value(*value), m_default_value(default_value),
m_min_value(min_value), m_max_value(max_value)
{
- m_value.SetValue(m_default_value);
+ SetToDefault();
}
+ void SetToDefault() override { m_value.SetValue(m_default_value); }
+
void LoadFromIni(const IniFile::Section& section, const std::string& group_name) override
{
std::string str_value;