diff options
| author | JMC47 <JMC4789@gmail.com> | 2019-04-09 19:30:26 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-04-09 19:30:26 -0400 |
| commit | e10a472134fdf557ec35505eb5fb7c74ba9f2af7 (patch) | |
| tree | 9593eb71abc3f724159693d46eb8504ede9529f0 /Source/Core/InputCommon/ControllerEmu | |
| parent | 0b8ac0a22f2fcebb7cbd00bbb36fd0c89191d34a (diff) | |
| parent | 5efb717873691fa42447ca0d9d9810b5ad501b42 (diff) | |
Merge pull request #7936 from jordan-woyak/numeric-setting-cleanup
InputCommon: Clean up how numeric settings are handled.
Diffstat (limited to 'Source/Core/InputCommon/ControllerEmu')
22 files changed, 319 insertions, 226 deletions
diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/ControlGroup.cpp b/Source/Core/InputCommon/ControllerEmu/ControlGroup/ControlGroup.cpp index 6e8e5cfb70..4e4d515077 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/ControlGroup.cpp +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/ControlGroup.cpp @@ -11,7 +11,6 @@ #include "InputCommon/ControllerEmu/Control/Control.h" #include "InputCommon/ControllerEmu/ControlGroup/Attachments.h" #include "InputCommon/ControllerEmu/ControllerEmu.h" -#include "InputCommon/ControllerEmu/Setting/BooleanSetting.h" #include "InputCommon/ControllerEmu/Setting/NumericSetting.h" namespace ControllerEmu @@ -27,30 +26,26 @@ ControlGroup::ControlGroup(const std::string& name_, const std::string& ui_name_ { } +void ControlGroup::AddDeadzoneSetting(SettingValue<double>* value, double maximum_deadzone) +{ + AddSetting(value, + {_trans("Dead Zone"), + // i18n: The percent symbol. + _trans("%"), + // i18n: Refers to the dead-zone setting of gamepad inputs. + _trans("Input strength to ignore.")}, + 0, 0, maximum_deadzone); +} + ControlGroup::~ControlGroup() = default; void ControlGroup::LoadConfig(IniFile::Section* sec, const std::string& defdev, const std::string& base) { - std::string group(base + name + "/"); + const std::string group(base + name + "/"); - // settings - for (auto& s : numeric_settings) - { - if (s->m_type == SettingType::VIRTUAL) - continue; - - sec->Get(group + s->m_name, &s->m_value, s->m_default_value * 100); - s->m_value /= 100; - } - - for (auto& s : boolean_settings) - { - if (s->m_type == SettingType::VIRTUAL) - continue; - - sec->Get(group + s->m_name, &s->m_value, s->m_default_value); - } + for (auto& setting : numeric_settings) + setting->LoadFromIni(*sec, group); for (auto& c : controls) { @@ -92,23 +87,10 @@ void ControlGroup::LoadConfig(IniFile::Section* sec, const std::string& defdev, void ControlGroup::SaveConfig(IniFile::Section* sec, const std::string& defdev, const std::string& base) { - std::string group(base + name + "/"); - - for (auto& s : numeric_settings) - { - if (s->m_type == SettingType::VIRTUAL) - continue; - - sec->Set(group + s->m_name, s->m_value * 100.0, s->m_default_value * 100.0); - } - - for (auto& s : boolean_settings) - { - if (s->m_type == SettingType::VIRTUAL) - continue; + const std::string group(base + name + "/"); - sec->Set(group + s->m_name, s->m_value, s->m_default_value); - } + for (auto& setting : numeric_settings) + setting->SaveToIni(*sec, group); for (auto& c : controls) { diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/ControlGroup.h b/Source/Core/InputCommon/ControllerEmu/ControlGroup/ControlGroup.h index 8e9fa3f24a..30798b9b4d 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/ControlGroup.h +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/ControlGroup.h @@ -13,10 +13,17 @@ namespace ControllerEmu { -class BooleanSetting; class Control; + +class NumericSettingBase; +struct NumericSettingDetails; + +template <typename T> class NumericSetting; +template <typename T> +class SettingValue; + enum class GroupType { Other, @@ -46,12 +53,22 @@ public: void SetControlExpression(int index, const std::string& expression); + template <typename T> + void AddSetting(SettingValue<T>* value, const NumericSettingDetails& details, + std::common_type_t<T> default_value, std::common_type_t<T> min_value = {}, + std::common_type_t<T> max_value = T(100)) + { + numeric_settings.emplace_back( + std::make_unique<NumericSetting<T>>(value, details, default_value, min_value, max_value)); + } + + void AddDeadzoneSetting(SettingValue<double>* value, double maximum_deadzone); + const std::string name; const std::string ui_name; const GroupType type; std::vector<std::unique_ptr<Control>> controls; - std::vector<std::unique_ptr<NumericSetting>> numeric_settings; - std::vector<std::unique_ptr<BooleanSetting>> boolean_settings; + std::vector<std::unique_ptr<NumericSettingBase>> numeric_settings; }; } // namespace ControllerEmu diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Cursor.cpp b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Cursor.cpp index fda476aac6..f4123154d0 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Cursor.cpp +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Cursor.cpp @@ -16,7 +16,6 @@ #include "InputCommon/ControllerEmu/Control/Control.h" #include "InputCommon/ControllerEmu/Control/Input.h" #include "InputCommon/ControllerEmu/ControllerEmu.h" -#include "InputCommon/ControllerEmu/Setting/BooleanSetting.h" #include "InputCommon/ControllerEmu/Setting/NumericSetting.h" namespace ControllerEmu @@ -32,12 +31,36 @@ Cursor::Cursor(const std::string& name_) controls.emplace_back(std::make_unique<Input>(Translate, _trans("Hide"))); controls.emplace_back(std::make_unique<Input>(Translate, _trans("Recenter"))); - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Center"), 0.5)); - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Width"), 0.5)); - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Height"), 0.5)); - - boolean_settings.emplace_back(std::make_unique<BooleanSetting>(_trans("Relative Input"), false)); - boolean_settings.emplace_back(std::make_unique<BooleanSetting>(_trans("Auto-Hide"), false)); + // Default values are optimized for "Super Mario Galaxy 2". + // This seems to be acceptable for a good number of games. + + AddSetting(&m_vertical_offset_setting, + // i18n: Refers to a positional offset applied to an emulated wiimote. + {_trans("Vertical Offset"), + // i18n: The symbol/abbreviation for centimeters. + _trans("cm")}, + 10, -100, 100); + + AddSetting(&m_yaw_setting, + // i18n: Refers to an amount of rotational movement about the "yaw" axis. + {_trans("Total Yaw"), + // i18n: The symbol/abbreviation for degrees (unit of angular measure). + _trans("°"), + // i18n: Refers to emulated wii remote movements. + _trans("Total rotation about the yaw axis.")}, + 15, 0, 180); + + AddSetting(&m_pitch_setting, + // i18n: Refers to an amount of rotational movement about the "pitch" axis. + {_trans("Total Pitch"), + // i18n: The symbol/abbreviation for degrees (unit of angular measure). + _trans("°"), + // i18n: Refers to emulated wii remote movements. + _trans("Total rotation about the pitch axis.")}, + 15, 0, 180); + + AddSetting(&m_relative_setting, {_trans("Relative Input")}, false); + AddSetting(&m_autohide_setting, {_trans("Auto-Hide")}, false); } Cursor::ReshapeData Cursor::GetReshapableState(bool adjusted) @@ -81,7 +104,7 @@ Cursor::StateData Cursor::GetState(const bool adjusted) const double max_z_step = STEP_Z_PER_SEC / 1000.0 * ms_since_update; // Apply deadzone to z: - const ControlState deadzone = numeric_settings[SETTING_DEADZONE]->GetValue(); + const ControlState deadzone = GetDeadzonePercentage(); z = std::copysign(std::max(0.0, std::abs(z) - deadzone) / (1.0 - deadzone), z); // Smooth out z movement: @@ -89,7 +112,7 @@ Cursor::StateData Cursor::GetState(const bool adjusted) m_state.z += MathUtil::Clamp(z - m_state.z, -max_z_step, max_z_step); // Relative input: - if (boolean_settings[0]->GetValue()) + if (m_relative_setting.GetValue()) { // Recenter: if (controls[7]->control_ref->State() > BUTTON_THRESHOLD) @@ -112,12 +135,7 @@ Cursor::StateData Cursor::GetState(const bool adjusted) StateData result = m_state; - // Adjust cursor according to settings: - result.x *= (numeric_settings[SETTING_WIDTH]->GetValue() * 2); - result.y *= (numeric_settings[SETTING_HEIGHT]->GetValue() * 2); - result.y += (numeric_settings[SETTING_CENTER]->GetValue() - 0.5); - - const bool autohide = boolean_settings[1]->GetValue(); + const bool autohide = m_autohide_setting.GetValue(); // Auto-hide timer: // TODO: should Z movement reset this? @@ -144,4 +162,19 @@ Cursor::StateData Cursor::GetState(const bool adjusted) return result; } +ControlState Cursor::GetTotalYaw() const +{ + return m_yaw_setting.GetValue() * MathUtil::TAU / 360; +} + +ControlState Cursor::GetTotalPitch() const +{ + return m_pitch_setting.GetValue() * MathUtil::TAU / 360; +} + +ControlState Cursor::GetVerticalOffset() const +{ + return m_vertical_offset_setting.GetValue() / 100; +} + } // namespace ControllerEmu diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Cursor.h b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Cursor.h index c66b2b896c..f22172e13d 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Cursor.h +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Cursor.h @@ -22,13 +22,6 @@ public: ControlState z{}; }; - enum - { - SETTING_CENTER = ReshapableInput::SETTING_COUNT, - SETTING_WIDTH, - SETTING_HEIGHT, - }; - explicit Cursor(const std::string& name); ReshapeData GetReshapableState(bool adjusted) final override; @@ -36,6 +29,15 @@ public: StateData GetState(bool adjusted); + // Yaw movement in radians. + ControlState GetTotalYaw() const; + + // Pitch movement in radians. + ControlState GetTotalPitch() const; + + // Vertical offset in meters. + ControlState GetVerticalOffset() const; + private: // This is used to reduce the cursor speed for relative input // to something that makes sense with the default range. @@ -59,5 +61,12 @@ private: using Clock = std::chrono::steady_clock; Clock::time_point m_last_update; + + SettingValue<double> m_yaw_setting; + SettingValue<double> m_pitch_setting; + SettingValue<double> m_vertical_offset_setting; + + SettingValue<bool> m_relative_setting; + SettingValue<bool> m_autohide_setting; }; } // namespace ControllerEmu diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Force.cpp b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Force.cpp index 3b3de522a7..715ae89b5a 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Force.cpp +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Force.cpp @@ -25,15 +25,30 @@ Force::Force(const std::string& name_) : ReshapableInput(name_, name_, GroupType controls.emplace_back(std::make_unique<Input>(Translate, _trans("Forward"))); controls.emplace_back(std::make_unique<Input>(Translate, _trans("Backward"))); - // Maximum swing movement (centimeters). - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Distance"), 0.25, 1, 100)); - - // Maximum jerk (m/s^3). - // i18n: "Jerk" as it relates to physics. The time derivative of acceleration. - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Jerk"), 5.0, 1, 1000)); - - // Angle of twist applied at the extremities of the swing (degrees). - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Angle"), 0.45, 0, 180)); + AddSetting(&m_distance_setting, + {_trans("Distance"), + // i18n: The symbol/abbreviation for centimeters. + _trans("cm"), + // i18n: Refering to emulated wii remote swing movement. + _trans("Distance of travel from neutral position.")}, + 25, 0, 100); + + AddSetting(&m_jerk_setting, + // i18n: "Jerk" as it relates to physics. The time derivative of acceleration. + {_trans("Jerk"), + // i18n: The symbol/abbreviation for meters per second to the 3rd power. + _trans("m/s³"), + // i18n: Refering to emulated wii remote swing movement. + _trans("Maximum change in acceleration.")}, + 500, 1, 1000); + + AddSetting(&m_angle_setting, + {_trans("Angle"), + // i18n: The symbol/abbreviation for degrees (unit of angular measure). + _trans("°"), + // i18n: Refering to emulated wii remote swing movement. + _trans("Rotation applied at extremities of swing.")}, + 45, 0, 180); } Force::ReshapeData Force::GetReshapableState(bool adjusted) @@ -56,7 +71,7 @@ Force::StateData Force::GetState(bool adjusted) if (adjusted) { // Apply deadzone to z. - const ControlState deadzone = numeric_settings[SETTING_DEADZONE]->GetValue(); + const ControlState deadzone = GetDeadzonePercentage(); z = std::copysign(std::max(0.0, std::abs(z) - deadzone) / (1.0 - deadzone), z); } @@ -66,22 +81,22 @@ Force::StateData Force::GetState(bool adjusted) ControlState Force::GetGateRadiusAtAngle(double) const { // Just a circle of the configured distance: - return numeric_settings[SETTING_DISTANCE]->GetValue(); + return GetMaxDistance(); } ControlState Force::GetMaxJerk() const { - return numeric_settings[SETTING_JERK]->GetValue() * 100; + return m_jerk_setting.GetValue(); } ControlState Force::GetTwistAngle() const { - return numeric_settings[SETTING_ANGLE]->GetValue() * MathUtil::TAU / 3.60; + return m_angle_setting.GetValue() * MathUtil::TAU / 360; } ControlState Force::GetMaxDistance() const { - return numeric_settings[SETTING_DISTANCE]->GetValue(); + return m_distance_setting.GetValue() / 100; } ControlState Force::GetDefaultInputRadiusAtAngle(double) const diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Force.h b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Force.h index 0b4fdcf634..21aca174a9 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Force.h +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Force.h @@ -36,11 +36,8 @@ public: ControlState GetMaxDistance() const; private: - enum - { - SETTING_DISTANCE = ReshapableInput::SETTING_COUNT, - SETTING_JERK, - SETTING_ANGLE, - }; + SettingValue<double> m_distance_setting; + SettingValue<double> m_jerk_setting; + SettingValue<double> m_angle_setting; }; } // namespace ControllerEmu diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/MixedTriggers.cpp b/Source/Core/InputCommon/ControllerEmu/ControlGroup/MixedTriggers.cpp index 6ae4dfd668..30ff474706 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/MixedTriggers.cpp +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/MixedTriggers.cpp @@ -14,22 +14,28 @@ #include "InputCommon/ControlReference/ControlReference.h" #include "InputCommon/ControllerEmu/Control/Control.h" -#include "InputCommon/ControllerEmu/Setting/NumericSetting.h" namespace ControllerEmu { MixedTriggers::MixedTriggers(const std::string& name_) : ControlGroup(name_, GroupType::MixedTriggers) { - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Threshold"), 0.9)); - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Dead Zone"), 0.0, 0, 25)); + AddSetting(&m_threshold_setting, + {_trans("Threshold"), + // i18n: The percent symbol. + _trans("%"), + // i18n: Refers to the "threshold" setting for pressure sensitive gamepad inputs. + _trans("Input strength required for activation.")}, + 90, 0, 100); + + AddDeadzoneSetting(&m_deadzone_setting, 25); } void MixedTriggers::GetState(u16* const digital, const u16* bitmasks, ControlState* analog, bool adjusted) const { - const ControlState threshold = numeric_settings[SETTING_THRESHOLD]->GetValue(); - ControlState deadzone = numeric_settings[SETTING_DEADZONE]->GetValue(); + const ControlState threshold = GetThreshold(); + ControlState deadzone = GetDeadzone(); // Return raw values. (used in UI) if (!adjusted) @@ -63,12 +69,12 @@ void MixedTriggers::GetState(u16* const digital, const u16* bitmasks, ControlSta ControlState MixedTriggers::GetDeadzone() const { - return numeric_settings[SETTING_DEADZONE]->GetValue(); + return m_deadzone_setting.GetValue() / 100; } ControlState MixedTriggers::GetThreshold() const { - return numeric_settings[SETTING_THRESHOLD]->GetValue(); + return m_threshold_setting.GetValue() / 100; } } // namespace ControllerEmu diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/MixedTriggers.h b/Source/Core/InputCommon/ControllerEmu/ControlGroup/MixedTriggers.h index 4e7b2adafe..250466dc9d 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/MixedTriggers.h +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/MixedTriggers.h @@ -6,6 +6,7 @@ #include <string> #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" +#include "InputCommon/ControllerEmu/Setting/NumericSetting.h" #include "InputCommon/ControllerInterface/Device.h" namespace ControllerEmu @@ -22,10 +23,7 @@ public: ControlState GetThreshold() const; private: - enum - { - SETTING_THRESHOLD, - SETTING_DEADZONE, - }; + SettingValue<double> m_threshold_setting; + SettingValue<double> m_deadzone_setting; }; } // namespace ControllerEmu diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/ModifySettingsButton.cpp b/Source/Core/InputCommon/ControllerEmu/ControlGroup/ModifySettingsButton.cpp index 83e2186d81..908de81a96 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/ModifySettingsButton.cpp +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/ModifySettingsButton.cpp @@ -13,7 +13,6 @@ #include "InputCommon/ControlReference/ControlReference.h" #include "InputCommon/ControllerEmu/Control/Control.h" #include "InputCommon/ControllerEmu/Control/Input.h" -#include "InputCommon/ControllerEmu/Setting/BooleanSetting.h" #include "InputCommon/ControllerEmu/Setting/NumericSetting.h" #include "VideoCommon/OnScreenDisplay.h" diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Slider.cpp b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Slider.cpp index f7e20dc386..f734b46181 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Slider.cpp +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Slider.cpp @@ -13,7 +13,6 @@ #include "InputCommon/ControllerEmu/Control/Control.h" #include "InputCommon/ControllerEmu/Control/Input.h" #include "InputCommon/ControllerEmu/ControllerEmu.h" -#include "InputCommon/ControllerEmu/Setting/NumericSetting.h" namespace ControllerEmu { @@ -23,7 +22,7 @@ Slider::Slider(const std::string& name_, const std::string& ui_name_) controls.emplace_back(std::make_unique<Input>(Translate, _trans("Left"))); controls.emplace_back(std::make_unique<Input>(Translate, _trans("Right"))); - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Dead Zone"), 0, 0, 50)); + AddDeadzoneSetting(&m_deadzone_setting, 50); } Slider::Slider(const std::string& name_) : Slider(name_, name_) @@ -32,7 +31,7 @@ Slider::Slider(const std::string& name_) : Slider(name_, name_) Slider::StateData Slider::GetState() { - const ControlState deadzone = numeric_settings[0]->GetValue(); + const ControlState deadzone = m_deadzone_setting.GetValue() / 100; const ControlState state = controls[1]->control_ref->State() - controls[0]->control_ref->State(); if (fabs(state) > deadzone) diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Slider.h b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Slider.h index 8142415a8f..b3df548ede 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Slider.h +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Slider.h @@ -5,7 +5,9 @@ #pragma once #include <string> + #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" +#include "InputCommon/ControllerEmu/Setting/NumericSetting.h" #include "InputCommon/ControllerInterface/Device.h" namespace ControllerEmu @@ -22,5 +24,8 @@ public: explicit Slider(const std::string& name_); StateData GetState(); + +private: + SettingValue<double> m_deadzone_setting; }; } // namespace ControllerEmu diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.cpp b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.cpp index 8407aa646f..91089455f8 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.cpp +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.cpp @@ -24,7 +24,13 @@ Tilt::Tilt(const std::string& name_) : ReshapableInput(name_, name_, GroupType:: controls.emplace_back(std::make_unique<Input>(Translate, _trans("Modifier"))); - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Angle"), 0.9, 0, 180)); + AddSetting(&m_max_angle_setting, + {_trans("Angle"), + // i18n: The symbol/abbreviation for degrees (unit of angular measure). + _trans("°"), + // i18n: Refers to emulated wii remote movement. + _trans("Maximum tilt angle.")}, + 90, 0, 180); } Tilt::ReshapeData Tilt::GetReshapableState(bool adjusted) @@ -48,7 +54,7 @@ Tilt::StateData Tilt::GetState() ControlState Tilt::GetGateRadiusAtAngle(double ang) const { - const ControlState max_tilt_angle = numeric_settings[SETTING_MAX_ANGLE]->GetValue() / 1.8; + const ControlState max_tilt_angle = m_max_angle_setting.GetValue() / 180; return SquareStickGate(max_tilt_angle).GetRadiusAtAngle(ang); } diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.h b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.h index 6a01a575a6..68281083ea 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.h +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.h @@ -6,6 +6,7 @@ #include <string> +#include "InputCommon/ControllerEmu/Setting/NumericSetting.h" #include "InputCommon/ControllerEmu/StickGate.h" #include "InputCommon/ControllerInterface/Device.h" @@ -28,9 +29,6 @@ public: StateData GetState(); private: - enum - { - SETTING_MAX_ANGLE = ReshapableInput::SETTING_COUNT, - }; + SettingValue<double> m_max_angle_setting; }; } // namespace ControllerEmu diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Triggers.cpp b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Triggers.cpp index f950e5b24c..e4a359eeba 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Triggers.cpp +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Triggers.cpp @@ -18,13 +18,13 @@ namespace ControllerEmu { Triggers::Triggers(const std::string& name_) : ControlGroup(name_, GroupType::Triggers) { - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Dead Zone"), 0, 0, 50)); + AddDeadzoneSetting(&m_deadzone_setting, 50); } Triggers::StateData Triggers::GetState() { const size_t trigger_count = controls.size(); - const ControlState deadzone = numeric_settings[0]->GetValue(); + const ControlState deadzone = m_deadzone_setting.GetValue() / 100; StateData result(trigger_count); for (size_t i = 0; i < trigger_count; ++i) diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Triggers.h b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Triggers.h index 561eb4f7ef..107b94c6f8 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Triggers.h +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Triggers.h @@ -8,6 +8,7 @@ #include <vector> #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" +#include "InputCommon/ControllerEmu/Setting/NumericSetting.h" #include "InputCommon/ControllerInterface/Device.h" namespace ControllerEmu @@ -26,5 +27,8 @@ public: explicit Triggers(const std::string& name); StateData GetState(); + +private: + SettingValue<double> m_deadzone_setting; }; } // namespace ControllerEmu diff --git a/Source/Core/InputCommon/ControllerEmu/Setting/BooleanSetting.cpp b/Source/Core/InputCommon/ControllerEmu/Setting/BooleanSetting.cpp deleted file mode 100644 index d9aa61b9f6..0000000000 --- a/Source/Core/InputCommon/ControllerEmu/Setting/BooleanSetting.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2017 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include "InputCommon/ControllerEmu/Setting/BooleanSetting.h" - -namespace ControllerEmu -{ -BooleanSetting::BooleanSetting(const std::string& setting_name, const std::string& ui_name, - const bool default_value, const SettingType setting_type, - const bool exclusive) - : m_type(setting_type), m_name(setting_name), m_ui_name(ui_name), - m_default_value(default_value), m_value(default_value), m_exclusive(exclusive) -{ -} - -BooleanSetting::BooleanSetting(const std::string& setting_name, const bool default_value, - const SettingType setting_type, const bool exclusive) - : BooleanSetting(setting_name, setting_name, default_value, setting_type, exclusive) -{ -} - -bool BooleanSetting::GetValue() const -{ - return m_value; -} - -bool BooleanSetting::IsExclusive() const -{ - return m_exclusive; -} - -void BooleanSetting::SetValue(bool value) -{ - m_value = value; -} - -} // namespace ControllerEmu diff --git a/Source/Core/InputCommon/ControllerEmu/Setting/BooleanSetting.h b/Source/Core/InputCommon/ControllerEmu/Setting/BooleanSetting.h deleted file mode 100644 index a2729a588e..0000000000 --- a/Source/Core/InputCommon/ControllerEmu/Setting/BooleanSetting.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2017 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include <string> - -#include "InputCommon/ControllerEmu/Setting/Setting.h" -#include "InputCommon/ControllerInterface/Device.h" - -namespace ControllerEmu -{ -class BooleanSetting -{ -public: - BooleanSetting(const std::string& setting_name, const std::string& ui_name, - const bool default_value, const SettingType setting_type = SettingType::NORMAL, - const bool exclusive = false); - BooleanSetting(const std::string& setting_name, const bool default_value, - const SettingType setting_type = SettingType::NORMAL, - const bool exclusive = false); - - bool GetValue() const; - void SetValue(bool value); - bool IsExclusive() const; - - const SettingType m_type; - const std::string m_name; - const std::string m_ui_name; - const bool m_default_value; - bool m_value; - -private: - const bool m_exclusive; -}; - -} // namespace ControllerEmu diff --git a/Source/Core/InputCommon/ControllerEmu/Setting/NumericSetting.cpp b/Source/Core/InputCommon/ControllerEmu/Setting/NumericSetting.cpp index a15dd13f2f..3459040824 100644 --- a/Source/Core/InputCommon/ControllerEmu/Setting/NumericSetting.cpp +++ b/Source/Core/InputCommon/ControllerEmu/Setting/NumericSetting.cpp @@ -6,20 +6,35 @@ namespace ControllerEmu { -NumericSetting::NumericSetting(const std::string& setting_name, const ControlState default_value, - const u32 low, const u32 high, const SettingType setting_type) - : m_type(setting_type), m_name(setting_name), m_default_value(default_value), m_low(low), - m_high(high), m_value(default_value) +NumericSettingBase::NumericSettingBase(const NumericSettingDetails& details) : m_details(details) { } -ControlState NumericSetting::GetValue() const +const char* NumericSettingBase::GetUIName() const { - return m_value; + return m_details.ui_name; } -void NumericSetting::SetValue(ControlState value) + +const char* NumericSettingBase::GetUISuffix() const +{ + return m_details.ui_suffix; +} + +const char* NumericSettingBase::GetUIDescription() const +{ + return m_details.ui_description; +} + +template <> +SettingType NumericSetting<double>::GetType() const +{ + return SettingType::Double; +} + +template <> +SettingType NumericSetting<bool>::GetType() const { - m_value = value; + return SettingType::Bool; } } // namespace ControllerEmu diff --git a/Source/Core/InputCommon/ControllerEmu/Setting/NumericSetting.h b/Source/Core/InputCommon/ControllerEmu/Setting/NumericSetting.h index 2e84d383ba..ccc46634ed 100644 --- a/Source/Core/InputCommon/ControllerEmu/Setting/NumericSetting.h +++ b/Source/Core/InputCommon/ControllerEmu/Setting/NumericSetting.h @@ -4,29 +4,127 @@ #pragma once +#include <atomic> #include <string> #include "Common/CommonTypes.h" -#include "InputCommon/ControllerEmu/Setting/Setting.h" +#include "Common/IniFile.h" #include "InputCommon/ControllerInterface/Device.h" namespace ControllerEmu { -class NumericSetting +enum class SettingType +{ + Double, + Bool, +}; + +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) + : ini_name(_ini_name), ui_suffix(_ui_suffix), ui_description(_ui_description), + ui_name(_ui_name ? _ui_name : _ini_name) + { + } + + // The name used in ini files. + const char* const ini_name; + + // A string applied to the number in the UI (unit of measure). + const char* const ui_suffix; + + // Detailed description of the setting. + const char* const ui_description; + + // The name used in the UI (if different from ini file). + const char* const ui_name; +}; + +class NumericSettingBase { public: - NumericSetting(const std::string& setting_name, const ControlState default_value, - const u32 low = 0, const u32 high = 100, - const SettingType setting_type = SettingType::NORMAL); - - ControlState GetValue() const; - void SetValue(ControlState value); - const SettingType m_type; - const std::string m_name; - const ControlState m_default_value; - const u32 m_low; - const u32 m_high; - ControlState m_value; + NumericSettingBase(const NumericSettingDetails& details); + + virtual ~NumericSettingBase() = default; + + virtual void LoadFromIni(const IniFile::Section& section, const std::string& group_name) = 0; + virtual void SaveToIni(IniFile::Section& section, const std::string& group_name) const = 0; + + virtual SettingType GetType() const = 0; + + const char* GetUIName() const; + const char* GetUISuffix() const; + const char* GetUIDescription() const; + +protected: + NumericSettingDetails m_details; +}; + +template <typename T> +class SettingValue; + +template <typename T> +class NumericSetting : public NumericSettingBase +{ +public: + using ValueType = T; + + static_assert(std::is_same<ValueType, double>() || std::is_same<ValueType, bool>(), + "NumericSetting is only implemented for double and bool."); + + NumericSetting(SettingValue<ValueType>* value, const NumericSettingDetails& details, + ValueType default_value, ValueType min_value, ValueType max_value) + : NumericSettingBase(details), m_value(*value), m_default_value(default_value), + m_min_value(min_value), m_max_value(max_value) + { + } + + void LoadFromIni(const IniFile::Section& section, const std::string& group_name) override + { + ValueType value; + section.Get(group_name + m_details.ini_name, &value, m_default_value); + SetValue(value); + } + + void SaveToIni(IniFile::Section& section, const std::string& group_name) const override + { + section.Set(group_name + m_details.ini_name, GetValue(), m_default_value); + } + + ValueType GetValue() const { return m_value.GetValue(); } + void SetValue(ValueType value) { m_value.SetValue(value); } + + ValueType GetDefaultValue() const { return m_default_value; } + ValueType GetMinValue() const { return m_min_value; } + ValueType GetMaxValue() const { return m_max_value; } + + SettingType GetType() const override; + +private: + SettingValue<ValueType>& m_value; + + const ValueType m_default_value; + const ValueType m_min_value; + const ValueType m_max_value; +}; + +template <typename T> +class SettingValue +{ + using ValueType = T; + + friend class NumericSetting<T>; + +public: + ValueType GetValue() const { return m_value; } + +private: + void SetValue(ValueType value) { m_value = value; } + + // Values are R/W by both UI and CPU threads. + std::atomic<ValueType> m_value; }; } // namespace ControllerEmu diff --git a/Source/Core/InputCommon/ControllerEmu/Setting/Setting.h b/Source/Core/InputCommon/ControllerEmu/Setting/Setting.h deleted file mode 100644 index 955e3d8c8b..0000000000 --- a/Source/Core/InputCommon/ControllerEmu/Setting/Setting.h +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2017 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -namespace ControllerEmu -{ -enum class SettingType -{ - NORMAL, // normal settings are saved to configuration files - VIRTUAL, // virtual settings are not saved at all -}; - -} // namespace ControllerEmu diff --git a/Source/Core/InputCommon/ControllerEmu/StickGate.cpp b/Source/Core/InputCommon/ControllerEmu/StickGate.cpp index 06abc4a64b..8e9d48467a 100644 --- a/Source/Core/InputCommon/ControllerEmu/StickGate.cpp +++ b/Source/Core/InputCommon/ControllerEmu/StickGate.cpp @@ -100,13 +100,13 @@ std::optional<u32> SquareStickGate::GetIdealCalibrationSampleCount() const ReshapableInput::ReshapableInput(std::string name, std::string ui_name, GroupType type) : ControlGroup(std::move(name), std::move(ui_name), type) { - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Dead Zone"), 0, 0, 50)); + AddDeadzoneSetting(&m_deadzone_setting, 50); } ControlState ReshapableInput::GetDeadzoneRadiusAtAngle(double angle) const { // FYI: deadzone is scaled by input radius which allows the shape to match. - return GetInputRadiusAtAngle(angle) * numeric_settings[SETTING_DEADZONE]->GetValue(); + return GetInputRadiusAtAngle(angle) * GetDeadzonePercentage(); } ControlState ReshapableInput::GetInputRadiusAtAngle(double angle) const @@ -120,6 +120,11 @@ ControlState ReshapableInput::GetInputRadiusAtAngle(double angle) const return GetCalibrationDataRadiusAtAngle(m_calibration, angle); } +ControlState ReshapableInput::GetDeadzonePercentage() const +{ + return m_deadzone_setting.GetValue() / 100; +} + ControlState ReshapableInput::GetCalibrationDataRadiusAtAngle(const CalibrationData& data, double angle) { @@ -267,7 +272,7 @@ ReshapableInput::ReshapeData ReshapableInput::Reshape(ControlState x, ControlSta } // Apply deadzone as a percentage of the user-defined calibration shape/size: - const ControlState deadzone = numeric_settings[SETTING_DEADZONE]->GetValue(); + const ControlState deadzone = GetDeadzonePercentage(); dist = std::max(0.0, dist - deadzone) / (1.0 - deadzone); // Scale to the gate shape/radius: diff --git a/Source/Core/InputCommon/ControllerEmu/StickGate.h b/Source/Core/InputCommon/ControllerEmu/StickGate.h index 38ad57a8b3..c022cc86fb 100644 --- a/Source/Core/InputCommon/ControllerEmu/StickGate.h +++ b/Source/Core/InputCommon/ControllerEmu/StickGate.h @@ -11,6 +11,7 @@ #include "InputCommon/ControlReference/ControlReference.h" #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" +#include "InputCommon/ControllerEmu/Setting/NumericSetting.h" namespace ControllerEmu { @@ -77,16 +78,12 @@ public: using ReshapeData = Common::DVec2; - enum - { - SETTING_DEADZONE, - SETTING_COUNT, - }; - // Angle is in radians and should be non-negative ControlState GetDeadzoneRadiusAtAngle(double angle) const; ControlState GetInputRadiusAtAngle(double angle) const; + ControlState GetDeadzonePercentage() const; + virtual ControlState GetGateRadiusAtAngle(double angle) const = 0; virtual ReshapeData GetReshapableState(bool adjusted) = 0; virtual ControlState GetDefaultInputRadiusAtAngle(double ang) const; @@ -108,6 +105,7 @@ private: void SaveConfig(IniFile::Section*, const std::string&, const std::string&) override; CalibrationData m_calibration; + SettingValue<double> m_deadzone_setting; }; } // namespace ControllerEmu |
