From 5efb717873691fa42447ca0d9d9810b5ad501b42 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Tue, 26 Mar 2019 19:31:03 -0500 Subject: [PATCH] InputCommon: Clean up how numeric settings are handled. Add units of measure to UI. Eliminate hidden magic values of the IR cursor. --- .../app/src/main/assets/WiimoteNew.ini | 24 ++-- .../app/src/main/assets/WiimoteProfile.ini | 8 +- .../activities/EmulationActivity.java | 94 ++++++------- .../features/settings/utils/SettingsFile.java | 6 +- .../main/res/layout/dialog_ir_sensitivity.xml | 34 ++--- .../app/src/main/res/values/strings.xml | 6 +- Source/Core/Core/HW/GCKeyboardEmu.cpp | 1 - Source/Core/Core/HW/GCPadEmu.cpp | 11 +- Source/Core/Core/HW/GCPadEmu.h | 4 +- Source/Core/Core/HW/WiimoteEmu/Camera.cpp | 9 +- Source/Core/Core/HW/WiimoteEmu/Dynamics.cpp | 26 ++-- .../Core/HW/WiimoteEmu/EmuSubroutines.cpp | 5 +- Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp | 48 +++---- Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h | 12 +- Source/Core/DolphinQt/CMakeLists.txt | 2 - .../DolphinQt/Config/Mapping/GCPadEmu.cpp | 1 - .../DolphinQt/Config/Mapping/MappingBool.cpp | 29 ---- .../DolphinQt/Config/Mapping/MappingBool.h | 25 ---- .../Config/Mapping/MappingIndicator.cpp | 25 +--- .../Config/Mapping/MappingIndicator.h | 1 - .../Config/Mapping/MappingNumeric.cpp | 50 +++++-- .../DolphinQt/Config/Mapping/MappingNumeric.h | 25 +++- .../DolphinQt/Config/Mapping/MappingRadio.cpp | 29 ---- .../DolphinQt/Config/Mapping/MappingRadio.h | 25 ---- .../Config/Mapping/MappingWidget.cpp | 40 +++--- .../DolphinQt/Config/Mapping/MappingWidget.h | 2 - .../Config/Mapping/MappingWindow.cpp | 2 +- .../Config/Mapping/WiimoteEmuGeneral.cpp | 1 - Source/Core/DolphinQt/DolphinQt.vcxproj | 5 - Source/Core/InputCommon/CMakeLists.txt | 1 - .../ControlGroup/ControlGroup.cpp | 52 +++----- .../ControllerEmu/ControlGroup/ControlGroup.h | 23 +++- .../ControllerEmu/ControlGroup/Cursor.cpp | 63 ++++++--- .../ControllerEmu/ControlGroup/Cursor.h | 23 +++- .../ControllerEmu/ControlGroup/Force.cpp | 43 ++++-- .../ControllerEmu/ControlGroup/Force.h | 9 +- .../ControlGroup/MixedTriggers.cpp | 20 ++- .../ControlGroup/MixedTriggers.h | 8 +- .../ControlGroup/ModifySettingsButton.cpp | 1 - .../ControllerEmu/ControlGroup/Slider.cpp | 5 +- .../ControllerEmu/ControlGroup/Slider.h | 5 + .../ControllerEmu/ControlGroup/Tilt.cpp | 10 +- .../ControllerEmu/ControlGroup/Tilt.h | 6 +- .../ControllerEmu/ControlGroup/Triggers.cpp | 4 +- .../ControllerEmu/ControlGroup/Triggers.h | 4 + .../ControllerEmu/Setting/BooleanSetting.cpp | 38 ------ .../ControllerEmu/Setting/BooleanSetting.h | 38 ------ .../ControllerEmu/Setting/NumericSetting.cpp | 31 +++-- .../ControllerEmu/Setting/NumericSetting.h | 126 ++++++++++++++++-- .../ControllerEmu/Setting/Setting.h | 15 --- .../InputCommon/ControllerEmu/StickGate.cpp | 11 +- .../InputCommon/ControllerEmu/StickGate.h | 10 +- Source/Core/InputCommon/InputCommon.vcxproj | 5 +- .../InputCommon/InputCommon.vcxproj.filters | 11 +- Source/Core/InputCommon/InputConfig.cpp | 17 +-- 55 files changed, 557 insertions(+), 572 deletions(-) delete mode 100644 Source/Core/DolphinQt/Config/Mapping/MappingBool.cpp delete mode 100644 Source/Core/DolphinQt/Config/Mapping/MappingBool.h delete mode 100644 Source/Core/DolphinQt/Config/Mapping/MappingRadio.cpp delete mode 100644 Source/Core/DolphinQt/Config/Mapping/MappingRadio.h delete mode 100644 Source/Core/InputCommon/ControllerEmu/Setting/BooleanSetting.cpp delete mode 100644 Source/Core/InputCommon/ControllerEmu/Setting/BooleanSetting.h delete mode 100644 Source/Core/InputCommon/ControllerEmu/Setting/Setting.h diff --git a/Source/Android/app/src/main/assets/WiimoteNew.ini b/Source/Android/app/src/main/assets/WiimoteNew.ini index e1a38045878d..2ebd9d61d908 100644 --- a/Source/Android/app/src/main/assets/WiimoteNew.ini +++ b/Source/Android/app/src/main/assets/WiimoteNew.ini @@ -18,9 +18,9 @@ IR/Right = `Axis 115` IR/Forward = `Axis 116` IR/Backward = `Axis 117` IR/Hide = `Button 118` -IR/Height = 50 -IR/Width = 50 -IR/Center = 50 +IR/Total Pitch = 15 +IR/Total Yaw = 15 +IR/Vertical Offset = 10 Swing/Up = `Axis 120` Swing/Down = `Axis 121` Swing/Left = `Axis 122` @@ -157,9 +157,9 @@ IR/Right = `Axis 115` IR/Forward = `Axis 116` IR/Backward = `Axis 117` IR/Hide = `Button 118` -IR/Height = 50 -IR/Width = 50 -IR/Center = 50 +IR/Total Pitch = 15 +IR/Total Yaw = 15 +IR/Vertical Offset = 10 Swing/Up = `Axis 120` Swing/Down = `Axis 121` Swing/Left = `Axis 122` @@ -296,9 +296,9 @@ IR/Right = `Axis 115` IR/Forward = `Axis 116` IR/Backward = `Axis 117` IR/Hide = `Button 118` -IR/Height = 50 -IR/Width = 50 -IR/Center = 50 +IR/Total Pitch = 15 +IR/Total Yaw = 15 +IR/Vertical Offset = 10 Swing/Up = `Axis 120` Swing/Down = `Axis 121` Swing/Left = `Axis 122` @@ -435,9 +435,9 @@ IR/Right = `Axis 115` IR/Forward = `Axis 116` IR/Backward = `Axis 117` IR/Hide = `Button 118` -IR/Height = 50 -IR/Width = 50 -IR/Center = 50 +IR/Total Pitch = 15 +IR/Total Yaw = 15 +IR/Vertical Offset = 10 Swing/Up = `Axis 120` Swing/Down = `Axis 121` Swing/Left = `Axis 122` diff --git a/Source/Android/app/src/main/assets/WiimoteProfile.ini b/Source/Android/app/src/main/assets/WiimoteProfile.ini index 2283a1add265..2546736d13ae 100644 --- a/Source/Android/app/src/main/assets/WiimoteProfile.ini +++ b/Source/Android/app/src/main/assets/WiimoteProfile.ini @@ -18,9 +18,9 @@ IR/Right = `Axis 115` IR/Forward = `Axis 116` IR/Backward = `Axis 117` IR/Hide = `Button 118` -IR/Height = 50 -IR/Width = 50 -IR/Center = 50 +IR/Total Pitch = 15 +IR/Total Yaw = 15 +IR/Vertical Offset = 10 Swing/Up = `Axis 120` Swing/Down = `Axis 121` Swing/Left = `Axis 122` @@ -135,4 +135,4 @@ Turntable/Stick/Radius = 100,000000 Turntable/Effect/Dial = `Axis 621` Turntable/Crossfade/Left = `Axis 623` Turntable/Crossfade/Right = `Axis 624` -Rumble/Motor = `Rumble 700` \ No newline at end of file +Rumble/Motor = `Rumble 700` diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java index 880487c00e5a..3ba7e5f893c4 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java @@ -842,26 +842,26 @@ private void chooseController() private void setIRSensitivity() { - int irHeight = Integer.valueOf( - mPreferences.getString(SettingsFile.KEY_WIIBIND_IR_HEIGHT + mSelectedGameId, "50")); + int ir_pitch = Integer.valueOf( + mPreferences.getString(SettingsFile.KEY_WIIBIND_IR_PITCH + mSelectedGameId, "15")); LayoutInflater inflater = LayoutInflater.from(this); View view = inflater.inflate(R.layout.dialog_ir_sensitivity, null); - TextView mTextSliderValueHeight = (TextView) view.findViewById(R.id.text_ir_height); - TextView units = (TextView) view.findViewById(R.id.text_ir_height_units); - SeekBar seekbarHeight = view.findViewById(R.id.seekbar_height); + TextView text_slider_value_pitch = (TextView) view.findViewById(R.id.text_ir_pitch); + TextView units = (TextView) view.findViewById(R.id.text_ir_pitch_units); + SeekBar seekbar_pitch = view.findViewById(R.id.seekbar_pitch); - mTextSliderValueHeight.setText(String.valueOf(irHeight)); - units.setText(getString(R.string.height)); - seekbarHeight.setMax(100); - seekbarHeight.setProgress(irHeight); - seekbarHeight.setKeyProgressIncrement(5); - seekbarHeight.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() + text_slider_value_pitch.setText(String.valueOf(ir_pitch)); + units.setText(getString(R.string.pitch)); + seekbar_pitch.setMax(100); + seekbar_pitch.setProgress(ir_pitch); + seekbar_pitch.setKeyProgressIncrement(5); + seekbar_pitch.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - mTextSliderValueHeight.setText(String.valueOf(progress)); + text_slider_value_pitch.setText(String.valueOf(progress)); } @Override public void onStartTrackingTouch(SeekBar seekBar) @@ -875,23 +875,23 @@ private void setIRSensitivity() } }); - int irWidth = Integer.valueOf( - mPreferences.getString(SettingsFile.KEY_WIIBIND_IR_WIDTH + mSelectedGameId, "50")); + int ir_yaw = Integer.valueOf( + mPreferences.getString(SettingsFile.KEY_WIIBIND_IR_YAW + mSelectedGameId, "15")); - TextView mTextSliderValueWidth = (TextView) view.findViewById(R.id.text_ir_width); - TextView unitsWidth = (TextView) view.findViewById(R.id.text_ir_width_units); - SeekBar seekbarWidth = view.findViewById(R.id.seekbar_width); + TextView text_slider_value_yaw = (TextView) view.findViewById(R.id.text_ir_yaw); + TextView units_yaw = (TextView) view.findViewById(R.id.text_ir_yaw_units); + SeekBar seekbar_yaw = view.findViewById(R.id.seekbar_width); - mTextSliderValueWidth.setText(String.valueOf(irWidth)); - unitsWidth.setText(getString(R.string.width)); - seekbarWidth.setMax(100); - seekbarWidth.setProgress(irWidth); - seekbarWidth.setKeyProgressIncrement(5); - seekbarWidth.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() + text_slider_value_yaw.setText(String.valueOf(ir_yaw)); + units_yaw.setText(getString(R.string.yaw)); + seekbar_yaw.setMax(100); + seekbar_yaw.setProgress(ir_yaw); + seekbar_yaw.setKeyProgressIncrement(5); + seekbar_yaw.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - mTextSliderValueWidth.setText(String.valueOf(progress)); + text_slider_value_yaw.setText(String.valueOf(progress)); } @Override public void onStartTrackingTouch(SeekBar seekBar) @@ -906,23 +906,26 @@ private void setIRSensitivity() }); - int irCenter = Integer.valueOf( - mPreferences.getString(SettingsFile.KEY_WIIBIND_IR_CENTER + mSelectedGameId, "50")); + int ir_vertical_offset = Integer.valueOf( + mPreferences.getString(SettingsFile.KEY_WIIBIND_IR_VERTICAL_OFFSET + mSelectedGameId, + "10")); - TextView mTextSliderValueCenter = (TextView) view.findViewById(R.id.text_ir_center); - TextView unitsCenter = (TextView) view.findViewById(R.id.text_ir_center_units); - SeekBar seekbarCenter = view.findViewById(R.id.seekbar_center); + TextView text_slider_value_vertical_offset = + (TextView) view.findViewById(R.id.text_ir_vertical_offset); + TextView units_vertical_offset = + (TextView) view.findViewById(R.id.text_ir_vertical_offset_units); + SeekBar seekbar_vertical_offset = view.findViewById(R.id.seekbar_vertical_offset); - mTextSliderValueCenter.setText(String.valueOf(irCenter)); - unitsCenter.setText(getString(R.string.center)); - seekbarCenter.setMax(100); - seekbarCenter.setProgress(irCenter); - seekbarCenter.setKeyProgressIncrement(5); - seekbarCenter.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() + text_slider_value_vertical_offset.setText(String.valueOf(ir_vertical_offset)); + units_vertical_offset.setText(getString(R.string.vertical_offset)); + seekbar_vertical_offset.setMax(100); + seekbar_vertical_offset.setProgress(ir_vertical_offset); + seekbar_vertical_offset.setKeyProgressIncrement(5); + seekbar_vertical_offset.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - mTextSliderValueCenter.setText(String.valueOf(progress)); + text_slider_value_vertical_offset.setText(String.valueOf(progress)); } @Override public void onStartTrackingTouch(SeekBar seekBar) @@ -942,21 +945,22 @@ private void setIRSensitivity() builder.setPositiveButton(R.string.ok, (dialogInterface, i) -> { SettingsFile.saveSingleCustomSetting(mSelectedGameId, Settings.SECTION_CONTROLS, - SettingsFile.KEY_WIIBIND_IR_HEIGHT, mTextSliderValueHeight.getText().toString()); + SettingsFile.KEY_WIIBIND_IR_PITCH, text_slider_value_pitch.getText().toString()); SettingsFile.saveSingleCustomSetting(mSelectedGameId, Settings.SECTION_CONTROLS, - SettingsFile.KEY_WIIBIND_IR_WIDTH, mTextSliderValueWidth.getText().toString()); + SettingsFile.KEY_WIIBIND_IR_YAW, text_slider_value_yaw.getText().toString()); SettingsFile.saveSingleCustomSetting(mSelectedGameId, Settings.SECTION_CONTROLS, - SettingsFile.KEY_WIIBIND_IR_CENTER, mTextSliderValueCenter.getText().toString()); + SettingsFile.KEY_WIIBIND_IR_VERTICAL_OFFSET, + text_slider_value_vertical_offset.getText().toString()); NativeLibrary.ReloadWiimoteConfig(); SharedPreferences.Editor editor = mPreferences.edit(); - editor.putString(SettingsFile.KEY_WIIBIND_IR_HEIGHT + mSelectedGameId, - mTextSliderValueHeight.getText().toString()); - editor.putString(SettingsFile.KEY_WIIBIND_IR_WIDTH + mSelectedGameId, - mTextSliderValueWidth.getText().toString()); - editor.putString(SettingsFile.KEY_WIIBIND_IR_CENTER + mSelectedGameId, - mTextSliderValueCenter.getText().toString()); + editor.putString(SettingsFile.KEY_WIIBIND_IR_PITCH + mSelectedGameId, + text_slider_value_pitch.getText().toString()); + editor.putString(SettingsFile.KEY_WIIBIND_IR_YAW + mSelectedGameId, + text_slider_value_yaw.getText().toString()); + editor.putString(SettingsFile.KEY_WIIBIND_IR_VERTICAL_OFFSET + mSelectedGameId, + text_slider_value_vertical_offset.getText().toString()); editor.apply(); }); builder.setNegativeButton(R.string.cancel, (dialogInterface, i) -> diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java index 5ac2a2193a09..ff24a7a6d3e6 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java @@ -153,9 +153,9 @@ public final class SettingsFile public static final String KEY_WIIBIND_IR_FORWARD = "IRForward_"; public static final String KEY_WIIBIND_IR_BACKWARD = "IRBackward_"; public static final String KEY_WIIBIND_IR_HIDE = "IRHide_"; - public static final String KEY_WIIBIND_IR_HEIGHT = "IRHeight"; - public static final String KEY_WIIBIND_IR_WIDTH = "IRWidth"; - public static final String KEY_WIIBIND_IR_CENTER = "IRCenter"; + public static final String KEY_WIIBIND_IR_PITCH = "IRTotalPitch"; + public static final String KEY_WIIBIND_IR_YAW = "IRTotalYaw"; + public static final String KEY_WIIBIND_IR_VERTICAL_OFFSET = "IRVerticalOffset"; public static final String KEY_WIIBIND_SWING_UP = "SwingUp_"; public static final String KEY_WIIBIND_SWING_DOWN = "SwingDown_"; public static final String KEY_WIIBIND_SWING_LEFT = "SwingLeft_"; diff --git a/Source/Android/app/src/main/res/layout/dialog_ir_sensitivity.xml b/Source/Android/app/src/main/res/layout/dialog_ir_sensitivity.xml index 8f60d318e2d7..49f3434a3830 100644 --- a/Source/Android/app/src/main/res/layout/dialog_ir_sensitivity.xml +++ b/Source/Android/app/src/main/res/layout/dialog_ir_sensitivity.xml @@ -16,13 +16,13 @@ android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_alignParentStart="true" - android:layout_below="@+id/text_ir_width" + android:layout_below="@+id/text_ir_yaw" android:layout_marginBottom="@dimen/spacing_medlarge" android:layout_marginLeft="@dimen/spacing_large" android:layout_marginRight="@dimen/spacing_large"/> @@ -46,18 +46,18 @@ android:layout_weight="1"> @@ -82,18 +82,18 @@ android:layout_weight="1"> diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml index 9cf0ac1d45d9..cc54d46d983b 100644 --- a/Source/Android/app/src/main/res/values/strings.xml +++ b/Source/Android/app/src/main/res/values/strings.xml @@ -330,8 +330,8 @@ Select This Directory - Height - Width - Center + Total Pitch + Total Yaw + Vertical Offset diff --git a/Source/Core/Core/HW/GCKeyboardEmu.cpp b/Source/Core/Core/HW/GCKeyboardEmu.cpp index 4f3db82f00e1..0eb73737ba8a 100644 --- a/Source/Core/Core/HW/GCKeyboardEmu.cpp +++ b/Source/Core/Core/HW/GCKeyboardEmu.cpp @@ -10,7 +10,6 @@ #include "InputCommon/ControllerEmu/ControlGroup/Buttons.h" #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" #include "InputCommon/ControllerEmu/ControllerEmu.h" -#include "InputCommon/ControllerEmu/Setting/BooleanSetting.h" #include "InputCommon/KeyboardStatus.h" static const u16 keys0_bitmasks[] = {KEYMASK_HOME, KEYMASK_END, KEYMASK_PGUP, KEYMASK_PGDN, diff --git a/Source/Core/Core/HW/GCPadEmu.cpp b/Source/Core/Core/HW/GCPadEmu.cpp index 61bf120336c4..c2f2108edce4 100644 --- a/Source/Core/Core/HW/GCPadEmu.cpp +++ b/Source/Core/Core/HW/GCPadEmu.cpp @@ -15,7 +15,6 @@ #include "InputCommon/ControllerEmu/ControlGroup/Buttons.h" #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" #include "InputCommon/ControllerEmu/ControlGroup/MixedTriggers.h" -#include "InputCommon/ControllerEmu/Setting/BooleanSetting.h" #include "InputCommon/ControllerEmu/StickGate.h" #include "InputCommon/GCPadStatus.h" @@ -102,10 +101,10 @@ GCPad::GCPad(const unsigned int index) : m_index(index) // options groups.emplace_back(m_options = new ControllerEmu::ControlGroup(_trans("Options"))); - m_options->boolean_settings.emplace_back( - // i18n: Treat a controller as always being connected regardless of what - // devices the user actually has plugged in - m_always_connected = new ControllerEmu::BooleanSetting(_trans("Always Connected"), false)); + m_options->AddSetting(&m_always_connected_setting, + // i18n: Treat a controller as always being connected regardless of what + // devices the user actually has plugged in + _trans("Always Connected"), false); } std::string GCPad::GetName() const @@ -143,7 +142,7 @@ GCPadStatus GCPad::GetInput() const const auto lock = GetStateLock(); GCPadStatus pad = {}; - if (!(m_always_connected->GetValue() || IsDefaultDeviceConnected())) + if (!(m_always_connected_setting.GetValue() || IsDefaultDeviceConnected())) { pad.isConnected = false; return pad; diff --git a/Source/Core/Core/HW/GCPadEmu.h b/Source/Core/Core/HW/GCPadEmu.h index 58272dc74a3b..9134ba9eeeeb 100644 --- a/Source/Core/Core/HW/GCPadEmu.h +++ b/Source/Core/Core/HW/GCPadEmu.h @@ -8,6 +8,7 @@ #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" #include "InputCommon/ControllerEmu/ControllerEmu.h" +#include "InputCommon/ControllerEmu/Setting/NumericSetting.h" struct GCPadStatus; @@ -57,7 +58,8 @@ class GCPad : public ControllerEmu::EmulatedController ControllerEmu::ControlGroup* m_rumble; ControllerEmu::Buttons* m_mic; ControllerEmu::ControlGroup* m_options; - ControllerEmu::BooleanSetting* m_always_connected; + + ControllerEmu::SettingValue m_always_connected_setting; const unsigned int m_index; }; diff --git a/Source/Core/Core/HW/WiimoteEmu/Camera.cpp b/Source/Core/Core/HW/WiimoteEmu/Camera.cpp index 8355c5d3775e..7a182e5db3ed 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Camera.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Camera.cpp @@ -12,7 +12,6 @@ #include "Common/MathUtil.h" #include "Common/Matrix.h" -#include "Core/Config/SYSCONFSettings.h" #include "Core/HW/WiimoteCommon/WiimoteReport.h" namespace WiimoteEmu @@ -84,13 +83,9 @@ void CameraLogic::Update(const Common::Matrix44& transform) // This seems to be acceptable for a good number of games. constexpr float SENSOR_BAR_LED_SEPARATION = 0.2f; - // Emulate a sensor bar height that matches the config. - const bool sensor_bar_on_top = Config::Get(Config::SYSCONF_SENSOR_BAR_POSITION) != 0; - const float sensor_bar_height = sensor_bar_on_top ? 0.11 : -0.11; - const std::array leds{ - Vec3{-SENSOR_BAR_LED_SEPARATION / 2, 0, sensor_bar_height}, - Vec3{SENSOR_BAR_LED_SEPARATION / 2, 0, sensor_bar_height}, + Vec3{-SENSOR_BAR_LED_SEPARATION / 2, 0, 0}, + Vec3{SENSOR_BAR_LED_SEPARATION / 2, 0, 0}, }; const auto camera_view = Matrix44::Perspective(CAMERA_FOV_Y, CAMERA_ASPECT_RATIO, 0.001f, 1000) * diff --git a/Source/Core/Core/HW/WiimoteEmu/Dynamics.cpp b/Source/Core/Core/HW/WiimoteEmu/Dynamics.cpp index 2f364171bd0f..b2af4d671f79 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Dynamics.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Dynamics.cpp @@ -7,6 +7,7 @@ #include #include "Common/MathUtil.h" +#include "Core/Config/SYSCONFSettings.h" #include "Core/Config/WiimoteInputSettings.h" #include "Core/HW/Wiimote.h" #include "Core/HW/WiimoteEmu/WiimoteEmu.h" @@ -186,25 +187,28 @@ WiimoteCommon::DataReportBuilder::AccelData ConvertAccelData(const Common::Vec3& Common::Matrix44 EmulateCursorMovement(ControllerEmu::Cursor* ir_group) { - const auto cursor = ir_group->GetState(true); - using Common::Matrix33; using Common::Matrix44; - // Values are optimized for default settings in "Super Mario Galaxy 2" - // This seems to be acceptable for a good number of games. - constexpr float YAW_ANGLE = 0.1472f; - constexpr float PITCH_ANGLE = 0.121f; - // Nintendo recommends a distance of 1-3 meters. constexpr float NEUTRAL_DISTANCE = 2.f; - constexpr float MOVE_DISTANCE = 1.f; + // When the sensor bar position is on bottom, apply the "offset" setting negatively. + // This is kinda odd but it does seem to maintain consistent cursor behavior. + const bool sensor_bar_on_top = Config::Get(Config::SYSCONF_SENSOR_BAR_POSITION) != 0; + + const float height = ir_group->GetVerticalOffset() * (sensor_bar_on_top ? 1 : -1); + + const float yaw_scale = ir_group->GetTotalYaw() / 2; + const float pitch_scale = ir_group->GetTotalPitch() / 2; + + const auto cursor = ir_group->GetState(true); + return Matrix44::Translate({0, MOVE_DISTANCE * float(cursor.z), 0}) * - Matrix44::FromMatrix33(Matrix33::RotateX(PITCH_ANGLE * cursor.y) * - Matrix33::RotateZ(YAW_ANGLE * cursor.x)) * - Matrix44::Translate({0, -NEUTRAL_DISTANCE, 0}); + Matrix44::FromMatrix33(Matrix33::RotateX(pitch_scale * cursor.y) * + Matrix33::RotateZ(yaw_scale * cursor.x)) * + Matrix44::Translate({0, -NEUTRAL_DISTANCE, height}); } void ApproachAngleWithAccel(RotationalState* state, const Common::Vec3& angle_target, diff --git a/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp b/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp index 30f0871042e7..a3c8b507cccb 100644 --- a/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp @@ -18,7 +18,6 @@ #include "Core/HW/WiimoteReal/WiimoteReal.h" #include "InputCommon/ControllerEmu/ControlGroup/Attachments.h" #include "InputCommon/ControllerEmu/ControlGroup/ModifySettingsButton.h" -#include "InputCommon/ControllerEmu/Setting/BooleanSetting.h" namespace WiimoteEmu { @@ -233,7 +232,7 @@ void Wiimote::HandleRequestStatus(const OutputReportRequestStatus&) // Max battery level seems to be 0xc8 (decimal 200) constexpr u8 MAX_BATTERY_LEVEL = 0xc8; - m_status.battery = u8(std::lround(m_battery_setting->GetValue() * MAX_BATTERY_LEVEL)); + m_status.battery = u8(std::lround(m_battery_setting.GetValue() / 100 * MAX_BATTERY_LEVEL)); if (Core::WantsDeterminism()) { @@ -394,7 +393,7 @@ void Wiimote::HandleSpeakerData(const WiimoteCommon::OutputReportSpeakerData& rp else { // Speaker Pan - const auto pan = m_options->numeric_settings[0]->GetValue(); + const auto pan = m_speaker_pan_setting.GetValue() / 100; m_speaker_logic.SpeakerData(rpt.data, rpt.length, pan); } diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp index e17553bebb27..084d29032755 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp @@ -41,8 +41,6 @@ #include "InputCommon/ControllerEmu/ControlGroup/Force.h" #include "InputCommon/ControllerEmu/ControlGroup/ModifySettingsButton.h" #include "InputCommon/ControllerEmu/ControlGroup/Tilt.h" -#include "InputCommon/ControllerEmu/Setting/BooleanSetting.h" -#include "InputCommon/ControllerEmu/Setting/NumericSetting.h" namespace WiimoteEmu { @@ -212,26 +210,28 @@ Wiimote::Wiimote(const unsigned int index) : m_index(index) // options groups.emplace_back(m_options = new ControllerEmu::ControlGroup(_trans("Options"))); - // m_options->boolean_settings.emplace_back( - // m_motion_plus_setting = - // new ControllerEmu::BooleanSetting("Attach MotionPlus", _trans("Attach MotionPlus"), - // true, - // ControllerEmu::SettingType::NORMAL, false)); - - m_options->boolean_settings.emplace_back( - new ControllerEmu::BooleanSetting("Forward Wiimote", _trans("Forward Wii Remote"), true, - ControllerEmu::SettingType::NORMAL, true)); - m_options->boolean_settings.emplace_back(m_upright_setting = new ControllerEmu::BooleanSetting( - "Upright Wiimote", _trans("Upright Wii Remote"), - false, ControllerEmu::SettingType::NORMAL, true)); - m_options->boolean_settings.emplace_back(m_sideways_setting = new ControllerEmu::BooleanSetting( - "Sideways Wiimote", _trans("Sideways Wii Remote"), - false, ControllerEmu::SettingType::NORMAL, true)); - - m_options->numeric_settings.emplace_back( - std::make_unique(_trans("Speaker Pan"), 0, -100, 100)); - m_options->numeric_settings.emplace_back( - m_battery_setting = new ControllerEmu::NumericSetting(_trans("Battery"), 95.0 / 100, 0, 100)); + m_options->AddSetting(&m_speaker_pan_setting, + {_trans("Speaker Pan"), + // i18n: The percent symbol. + _trans("%")}, + 0, -100, 100); + + m_options->AddSetting(&m_battery_setting, + {_trans("Battery"), + // i18n: The percent symbol. + _trans("%")}, + 95, 0, 100); + + // m_options->AddSetting(&m_motion_plus_setting, {_trans("Attach MotionPlus")}, true); + + // Note: "Upright" and "Sideways" options can be enabled at the same time which produces an + // orientation where the wiimote points towards the left with the buttons towards you. + m_options->AddSetting(&m_upright_setting, + {"Upright Wiimote", nullptr, nullptr, _trans("Upright Wii Remote")}, false); + + m_options->AddSetting(&m_sideways_setting, + {"Sideways Wiimote", nullptr, nullptr, _trans("Sideways Wii Remote")}, + false); // hotkeys groups.emplace_back(m_hotkeys = new ControllerEmu::ModifySettingsButton(_trans("Hotkeys"))); @@ -667,14 +667,14 @@ bool Wiimote::IsSideways() const { const bool sideways_modifier_toggle = m_hotkeys->getSettingsModifier()[0]; const bool sideways_modifier_switch = m_hotkeys->getSettingsModifier()[2]; - return m_sideways_setting->GetValue() ^ sideways_modifier_toggle ^ sideways_modifier_switch; + return m_sideways_setting.GetValue() ^ sideways_modifier_toggle ^ sideways_modifier_switch; } bool Wiimote::IsUpright() const { const bool upright_modifier_toggle = m_hotkeys->getSettingsModifier()[1]; const bool upright_modifier_switch = m_hotkeys->getSettingsModifier()[3]; - return m_upright_setting->GetValue() ^ upright_modifier_toggle ^ upright_modifier_switch; + return m_upright_setting.GetValue() ^ upright_modifier_toggle ^ upright_modifier_switch; } void Wiimote::SetRumble(bool on) diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h index 1ff17505db33..68a56fd26c7a 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h @@ -23,14 +23,12 @@ class PointerWrap; namespace ControllerEmu { class Attachments; -class BooleanSetting; class Buttons; class ControlGroup; class Cursor; class Extension; class Force; class ModifySettingsButton; -class NumericSetting; class Output; class Tilt; } // namespace ControllerEmu @@ -235,12 +233,14 @@ class Wiimote : public ControllerEmu::EmulatedController ControllerEmu::Output* m_motor; ControllerEmu::Attachments* m_attachments; ControllerEmu::ControlGroup* m_options; - ControllerEmu::BooleanSetting* m_sideways_setting; - ControllerEmu::BooleanSetting* m_upright_setting; - ControllerEmu::NumericSetting* m_battery_setting; - // ControllerEmu::BooleanSetting* m_motion_plus_setting; ControllerEmu::ModifySettingsButton* m_hotkeys; + ControllerEmu::SettingValue m_sideways_setting; + ControllerEmu::SettingValue m_upright_setting; + ControllerEmu::SettingValue m_battery_setting; + ControllerEmu::SettingValue m_speaker_pan_setting; + // ControllerEmu::SettingValue m_motion_plus_setting; + SpeakerLogic m_speaker_logic; MotionPlus m_motion_plus; CameraLogic m_camera_logic; diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt index 551a7e04d828..b0154ceb4d9d 100644 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ b/Source/Core/DolphinQt/CMakeLists.txt @@ -63,12 +63,10 @@ add_executable(dolphin-emu Config/Mapping/HotkeyTAS.cpp Config/Mapping/HotkeyWii.cpp Config/Mapping/IOWindow.cpp - Config/Mapping/MappingBool.cpp Config/Mapping/MappingButton.cpp Config/Mapping/MappingCommon.cpp Config/Mapping/MappingIndicator.cpp Config/Mapping/MappingNumeric.cpp - Config/Mapping/MappingRadio.cpp Config/Mapping/MappingWidget.cpp Config/Mapping/MappingWindow.cpp Config/Mapping/WiimoteEmuExtension.cpp diff --git a/Source/Core/DolphinQt/Config/Mapping/GCPadEmu.cpp b/Source/Core/DolphinQt/Config/Mapping/GCPadEmu.cpp index fe9ac2025adf..a00d5fcdc596 100644 --- a/Source/Core/DolphinQt/Config/Mapping/GCPadEmu.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/GCPadEmu.cpp @@ -10,7 +10,6 @@ #include "Core/HW/GCPad.h" #include "Core/HW/GCPadEmu.h" -#include "InputCommon/ControllerEmu/Setting/BooleanSetting.h" #include "InputCommon/ControllerEmu/Setting/NumericSetting.h" #include "InputCommon/InputConfig.h" diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingBool.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingBool.cpp deleted file mode 100644 index 1112f3b5e29e..000000000000 --- a/Source/Core/DolphinQt/Config/Mapping/MappingBool.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2017 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include "DolphinQt/Config/Mapping/MappingBool.h" - -#include "DolphinQt/Config/Mapping/MappingWidget.h" - -#include "InputCommon/ControllerEmu/ControllerEmu.h" -#include "InputCommon/ControllerEmu/Setting/BooleanSetting.h" -#include "InputCommon/ControllerInterface/ControllerInterface.h" - -MappingBool::MappingBool(MappingWidget* parent, ControllerEmu::BooleanSetting* setting) - : QCheckBox(tr(setting->m_ui_name.c_str())), m_setting(*setting) -{ - connect(this, &QCheckBox::stateChanged, this, [this, parent](int value) { - m_setting.SetValue(value); - parent->SaveSettings(); - }); - - connect(parent, &MappingWidget::ConfigChanged, this, &MappingBool::ConfigChanged); -} - -void MappingBool::ConfigChanged() -{ - const bool old_state = blockSignals(true); - setChecked(m_setting.GetValue()); - blockSignals(old_state); -} diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingBool.h b/Source/Core/DolphinQt/Config/Mapping/MappingBool.h deleted file mode 100644 index df3693d580c2..000000000000 --- a/Source/Core/DolphinQt/Config/Mapping/MappingBool.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2017 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include - -class MappingWidget; - -namespace ControllerEmu -{ -class BooleanSetting; -}; - -class MappingBool : public QCheckBox -{ -public: - MappingBool(MappingWidget* widget, ControllerEmu::BooleanSetting* setting); - -private: - void ConfigChanged(); - - ControllerEmu::BooleanSetting& m_setting; -}; diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp index 44e86a9feb9b..1d297922b8d9 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp @@ -158,7 +158,7 @@ void MappingIndicator::DrawCursor(ControllerEmu::Cursor& cursor) } // Deadzone for Z (forward/backward): - const double deadzone = cursor.numeric_settings[cursor.SETTING_DEADZONE]->GetValue(); + const double deadzone = cursor.GetDeadzonePercentage(); if (deadzone > 0.0) { p.setPen(DEADZONE_COLOR); @@ -181,23 +181,12 @@ void MappingIndicator::DrawCursor(ControllerEmu::Cursor& cursor) } // TV screen or whatever you want to call this: - constexpr double tv_scale = 0.75; - constexpr double center_scale = 2.0 / 3.0; - - const double tv_center = (cursor.numeric_settings[cursor.SETTING_CENTER]->GetValue() - 0.5); - const double tv_width = cursor.numeric_settings[cursor.SETTING_WIDTH]->GetValue(); - const double tv_height = cursor.numeric_settings[cursor.SETTING_HEIGHT]->GetValue(); + constexpr double TV_SCALE = 0.75; p.setPen(tv_pen_color); p.setBrush(tv_brush_color); - auto gate_polygon = GetPolygonFromRadiusGetter( - [&cursor](double ang) { return cursor.GetGateRadiusAtAngle(ang); }, scale); - for (auto& pt : gate_polygon) - { - pt = {pt.x() * tv_width, pt.y() * tv_height + tv_center * center_scale * scale}; - pt *= tv_scale; - } - p.drawPolygon(gate_polygon); + p.drawPolygon(GetPolygonFromRadiusGetter( + [&cursor](double ang) { return cursor.GetGateRadiusAtAngle(ang); }, scale * TV_SCALE)); // Deadzone. p.setPen(DEADZONE_COLOR); @@ -221,8 +210,8 @@ void MappingIndicator::DrawCursor(ControllerEmu::Cursor& cursor) { p.setPen(Qt::NoPen); p.setBrush(ADJ_INPUT_COLOR); - const QPointF pt(adj_coord.x / 2.0, (adj_coord.y - tv_center) / 2.0 + tv_center * center_scale); - p.drawEllipse(pt * scale * tv_scale, INPUT_DOT_RADIUS, INPUT_DOT_RADIUS); + p.drawEllipse(QPointF{adj_coord.x, adj_coord.y} * scale * TV_SCALE, INPUT_DOT_RADIUS, + INPUT_DOT_RADIUS); } } @@ -444,7 +433,7 @@ void MappingIndicator::DrawForce(ControllerEmu::Force& force) } // Deadzone for Z (forward/backward): - const double deadzone = force.numeric_settings[force.SETTING_DEADZONE]->GetValue(); + const double deadzone = force.GetDeadzonePercentage(); if (deadzone > 0.0) { p.setPen(DEADZONE_COLOR); diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.h b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.h index 4a630eac28dc..0952fa353771 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.h +++ b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.h @@ -16,7 +16,6 @@ class Control; class ControlGroup; class Cursor; class Force; -class NumericSetting; } // namespace ControllerEmu class QPainter; diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingNumeric.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingNumeric.cpp index 0de807d68c0e..2c7b1fd4e8d0 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingNumeric.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/MappingNumeric.cpp @@ -7,26 +7,56 @@ #include "DolphinQt/Config/Mapping/MappingWidget.h" #include "InputCommon/ControllerEmu/ControllerEmu.h" -#include "InputCommon/ControllerEmu/Setting/NumericSetting.h" #include "InputCommon/ControllerInterface/ControllerInterface.h" -MappingNumeric::MappingNumeric(MappingWidget* parent, ControllerEmu::NumericSetting* setting) - : m_setting(*setting) +MappingDouble::MappingDouble(MappingWidget* parent, ControllerEmu::NumericSetting* setting) + : QDoubleSpinBox(parent), m_setting(*setting) { - setRange(setting->m_low, setting->m_high); + setRange(m_setting.GetMinValue(), m_setting.GetMaxValue()); + setDecimals(2); - connect(this, static_cast(&QSpinBox::valueChanged), this, - [this, parent](int value) { - m_setting.SetValue(static_cast(value) / 100); + if (const auto ui_suffix = m_setting.GetUISuffix()) + setSuffix(QStringLiteral(" ") + tr(ui_suffix)); + + if (const auto ui_description = m_setting.GetUIDescription()) + setToolTip(tr(ui_description)); + + connect(this, QOverload::of(&QDoubleSpinBox::valueChanged), this, + [this, parent](double value) { + m_setting.SetValue(value); parent->SaveSettings(); }); - connect(parent, &MappingWidget::ConfigChanged, this, &MappingNumeric::ConfigChanged); + connect(parent, &MappingWidget::ConfigChanged, this, &MappingDouble::ConfigChanged); +} + +// Overriding QDoubleSpinBox's fixup to set the default value when input is cleared. +void MappingDouble::fixup(QString& input) const +{ + input = QString::number(m_setting.GetDefaultValue()); +} + +void MappingDouble::ConfigChanged() +{ + const bool old_state = blockSignals(true); + setValue(m_setting.GetValue()); + blockSignals(old_state); +} + +MappingBool::MappingBool(MappingWidget* parent, ControllerEmu::NumericSetting* setting) + : QCheckBox(parent), m_setting(*setting) +{ + connect(this, &QCheckBox::stateChanged, this, [this, parent](int value) { + m_setting.SetValue(value != 0); + parent->SaveSettings(); + }); + + connect(parent, &MappingWidget::ConfigChanged, this, &MappingBool::ConfigChanged); } -void MappingNumeric::ConfigChanged() +void MappingBool::ConfigChanged() { const bool old_state = blockSignals(true); - setValue(m_setting.GetValue() * 100); + setChecked(m_setting.GetValue()); blockSignals(old_state); } diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingNumeric.h b/Source/Core/DolphinQt/Config/Mapping/MappingNumeric.h index 2120e972c5ac..49817ea40c47 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingNumeric.h +++ b/Source/Core/DolphinQt/Config/Mapping/MappingNumeric.h @@ -4,23 +4,34 @@ #pragma once -#include +#include +#include #include +#include "InputCommon/ControllerEmu/Setting/NumericSetting.h" + class MappingWidget; -namespace ControllerEmu +class MappingDouble : public QDoubleSpinBox { -class NumericSetting; -} +public: + MappingDouble(MappingWidget* parent, ControllerEmu::NumericSetting* setting); + +private: + void fixup(QString& input) const override; + + void ConfigChanged(); + + ControllerEmu::NumericSetting& m_setting; +}; -class MappingNumeric : public QSpinBox +class MappingBool : public QCheckBox { public: - MappingNumeric(MappingWidget* widget, ControllerEmu::NumericSetting* ref); + MappingBool(MappingWidget* widget, ControllerEmu::NumericSetting* setting); private: void ConfigChanged(); - ControllerEmu::NumericSetting& m_setting; + ControllerEmu::NumericSetting& m_setting; }; diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingRadio.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingRadio.cpp deleted file mode 100644 index 162a18bae9a9..000000000000 --- a/Source/Core/DolphinQt/Config/Mapping/MappingRadio.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2017 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include "DolphinQt/Config/Mapping/MappingRadio.h" - -#include "DolphinQt/Config/Mapping/MappingWidget.h" - -#include "InputCommon/ControllerEmu/ControllerEmu.h" -#include "InputCommon/ControllerEmu/Setting/BooleanSetting.h" -#include "InputCommon/ControllerInterface/ControllerInterface.h" - -MappingRadio::MappingRadio(MappingWidget* parent, ControllerEmu::BooleanSetting* setting) - : QRadioButton(tr(setting->m_ui_name.c_str())), m_setting(*setting) -{ - connect(this, &QRadioButton::toggled, this, [this, parent](int value) { - m_setting.SetValue(value); - parent->SaveSettings(); - }); - - connect(parent, &MappingWidget::ConfigChanged, this, &MappingRadio::ConfigChanged); -} - -void MappingRadio::ConfigChanged() -{ - const bool old_state = blockSignals(true); - setChecked(m_setting.GetValue()); - blockSignals(old_state); -} diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingRadio.h b/Source/Core/DolphinQt/Config/Mapping/MappingRadio.h deleted file mode 100644 index 230a311a2660..000000000000 --- a/Source/Core/DolphinQt/Config/Mapping/MappingRadio.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2017 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include - -class MappingWidget; - -namespace ControllerEmu -{ -class BooleanSetting; -}; - -class MappingRadio : public QRadioButton -{ -public: - MappingRadio(MappingWidget* widget, ControllerEmu::BooleanSetting* setting); - -private: - void ConfigChanged(); - - ControllerEmu::BooleanSetting& m_setting; -}; diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp index 8e8067286073..1e968c2ed2fa 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp @@ -10,11 +10,9 @@ #include #include "DolphinQt/Config/Mapping/IOWindow.h" -#include "DolphinQt/Config/Mapping/MappingBool.h" #include "DolphinQt/Config/Mapping/MappingButton.h" #include "DolphinQt/Config/Mapping/MappingIndicator.h" #include "DolphinQt/Config/Mapping/MappingNumeric.h" -#include "DolphinQt/Config/Mapping/MappingRadio.h" #include "DolphinQt/Config/Mapping/MappingWindow.h" #include "DolphinQt/Settings.h" @@ -22,7 +20,6 @@ #include "InputCommon/ControllerEmu/Control/Control.h" #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" #include "InputCommon/ControllerEmu/ControllerEmu.h" -#include "InputCommon/ControllerEmu/Setting/BooleanSetting.h" #include "InputCommon/ControllerEmu/Setting/NumericSetting.h" #include "InputCommon/ControllerEmu/StickGate.h" @@ -109,30 +106,25 @@ QGroupBox* MappingWidget::CreateGroupBox(const QString& name, ControllerEmu::Con m_buttons.push_back(button); } - for (auto& numeric : group->numeric_settings) + for (auto& setting : group->numeric_settings) { - auto* spinbox = new MappingNumeric(this, numeric.get()); - form_layout->addRow(tr(numeric->m_name.c_str()), spinbox); - } - - for (auto& boolean : group->boolean_settings) - { - if (!boolean->IsExclusive()) - continue; - - auto* checkbox = new MappingRadio(this, boolean.get()); - - form_layout->addRow(checkbox); - } - - for (auto& boolean : group->boolean_settings) - { - if (boolean->IsExclusive()) - continue; + QWidget* setting_widget = nullptr; - auto* checkbox = new MappingBool(this, boolean.get()); + switch (setting->GetType()) + { + case ControllerEmu::SettingType::Double: + setting_widget = new MappingDouble( + this, static_cast*>(setting.get())); + break; + + case ControllerEmu::SettingType::Bool: + setting_widget = + new MappingBool(this, static_cast*>(setting.get())); + break; + } - form_layout->addRow(checkbox); + if (setting_widget) + form_layout->addRow(tr(setting->GetUIName()), setting_widget); } if (need_indicator) diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingWidget.h b/Source/Core/DolphinQt/Config/Mapping/MappingWidget.h index 80000e047a8a..84a2cf4e64ac 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingWidget.h +++ b/Source/Core/DolphinQt/Config/Mapping/MappingWidget.h @@ -13,11 +13,9 @@ class ControlGroupBox; class InputConfig; class IOWindow; -class MappingBool; class MappingButton; class MappingNumeric; class MappingWindow; -class MappingRadio; class QGroupBox; namespace ControllerEmu diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp index 403fbed993c4..eb049b65f679 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp @@ -239,7 +239,7 @@ void MappingWindow::OnSaveProfilePressed() } } -void MappingWindow::OnSelectDevice(int index) +void MappingWindow::OnSelectDevice(int) { if (IsMappingAllDevices()) return; diff --git a/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuGeneral.cpp b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuGeneral.cpp index 466ba7566786..0c3ffe5deb91 100644 --- a/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuGeneral.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuGeneral.cpp @@ -16,7 +16,6 @@ #include "DolphinQt/Config/Mapping/WiimoteEmuExtension.h" #include "InputCommon/ControllerEmu/ControlGroup/Attachments.h" -#include "InputCommon/ControllerEmu/Setting/BooleanSetting.h" #include "InputCommon/InputConfig.h" WiimoteEmuGeneral::WiimoteEmuGeneral(MappingWindow* window, WiimoteEmuExtension* extension) diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj b/Source/Core/DolphinQt/DolphinQt.vcxproj index 5886ba91377a..a80a94b0ad7e 100644 --- a/Source/Core/DolphinQt/DolphinQt.vcxproj +++ b/Source/Core/DolphinQt/DolphinQt.vcxproj @@ -81,7 +81,6 @@ - @@ -239,7 +238,6 @@ - @@ -316,12 +314,10 @@ - - @@ -402,7 +398,6 @@ - diff --git a/Source/Core/InputCommon/CMakeLists.txt b/Source/Core/InputCommon/CMakeLists.txt index 454e6a21ac02..a3df1a2d22f4 100644 --- a/Source/Core/InputCommon/CMakeLists.txt +++ b/Source/Core/InputCommon/CMakeLists.txt @@ -17,7 +17,6 @@ add_library(inputcommon ControllerEmu/ControlGroup/Slider.cpp ControllerEmu/ControlGroup/Tilt.cpp ControllerEmu/ControlGroup/Triggers.cpp - ControllerEmu/Setting/BooleanSetting.cpp ControllerEmu/Setting/NumericSetting.cpp ControllerInterface/ControllerInterface.cpp ControllerInterface/Device.cpp diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/ControlGroup.cpp b/Source/Core/InputCommon/ControllerEmu/ControlGroup/ControlGroup.cpp index 6e8e5cfb7092..4e4d51507739 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* 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 8e9fa3f24af7..30798b9b4d1a 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 class NumericSetting; +template +class SettingValue; + enum class GroupType { Other, @@ -46,12 +53,22 @@ class ControlGroup void SetControlExpression(int index, const std::string& expression); + template + void AddSetting(SettingValue* value, const NumericSettingDetails& details, + std::common_type_t default_value, std::common_type_t min_value = {}, + std::common_type_t max_value = T(100)) + { + numeric_settings.emplace_back( + std::make_unique>(value, details, default_value, min_value, max_value)); + } + + void AddDeadzoneSetting(SettingValue* value, double maximum_deadzone); + const std::string name; const std::string ui_name; const GroupType type; std::vector> controls; - std::vector> numeric_settings; - std::vector> boolean_settings; + std::vector> numeric_settings; }; } // namespace ControllerEmu diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Cursor.cpp b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Cursor.cpp index fda476aac608..f4123154d06f 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(Translate, _trans("Hide"))); controls.emplace_back(std::make_unique(Translate, _trans("Recenter"))); - numeric_settings.emplace_back(std::make_unique(_trans("Center"), 0.5)); - numeric_settings.emplace_back(std::make_unique(_trans("Width"), 0.5)); - numeric_settings.emplace_back(std::make_unique(_trans("Height"), 0.5)); - - boolean_settings.emplace_back(std::make_unique(_trans("Relative Input"), false)); - boolean_settings.emplace_back(std::make_unique(_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 c66b2b896cee..f22172e13d17 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Cursor.h +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Cursor.h @@ -22,13 +22,6 @@ class Cursor : public ReshapableInput 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 @@ class Cursor : public ReshapableInput 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 @@ class Cursor : public ReshapableInput using Clock = std::chrono::steady_clock; Clock::time_point m_last_update; + + SettingValue m_yaw_setting; + SettingValue m_pitch_setting; + SettingValue m_vertical_offset_setting; + + SettingValue m_relative_setting; + SettingValue m_autohide_setting; }; } // namespace ControllerEmu diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Force.cpp b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Force.cpp index 3b3de522a737..715ae89b5ac7 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(Translate, _trans("Forward"))); controls.emplace_back(std::make_unique(Translate, _trans("Backward"))); - // Maximum swing movement (centimeters). - numeric_settings.emplace_back(std::make_unique(_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(_trans("Jerk"), 5.0, 1, 1000)); - - // Angle of twist applied at the extremities of the swing (degrees). - numeric_settings.emplace_back(std::make_unique(_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 0b4fdcf63497..21aca174a9bd 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Force.h +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Force.h @@ -36,11 +36,8 @@ class Force : public ReshapableInput ControlState GetMaxDistance() const; private: - enum - { - SETTING_DISTANCE = ReshapableInput::SETTING_COUNT, - SETTING_JERK, - SETTING_ANGLE, - }; + SettingValue m_distance_setting; + SettingValue m_jerk_setting; + SettingValue m_angle_setting; }; } // namespace ControllerEmu diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/MixedTriggers.cpp b/Source/Core/InputCommon/ControllerEmu/ControlGroup/MixedTriggers.cpp index 6ae4dfd6681a..30ff47470691 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(_trans("Threshold"), 0.9)); - numeric_settings.emplace_back(std::make_unique(_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 4e7b2adafecf..250466dc9d2b 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/MixedTriggers.h +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/MixedTriggers.h @@ -6,6 +6,7 @@ #include #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" +#include "InputCommon/ControllerEmu/Setting/NumericSetting.h" #include "InputCommon/ControllerInterface/Device.h" namespace ControllerEmu @@ -22,10 +23,7 @@ class MixedTriggers : public ControlGroup ControlState GetThreshold() const; private: - enum - { - SETTING_THRESHOLD, - SETTING_DEADZONE, - }; + SettingValue m_threshold_setting; + SettingValue m_deadzone_setting; }; } // namespace ControllerEmu diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/ModifySettingsButton.cpp b/Source/Core/InputCommon/ControllerEmu/ControlGroup/ModifySettingsButton.cpp index 83e2186d8127..908de81a966a 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 f7e20dc38673..f734b4618171 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(Translate, _trans("Left"))); controls.emplace_back(std::make_unique(Translate, _trans("Right"))); - numeric_settings.emplace_back(std::make_unique(_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 8142415a8f0f..b3df548ede82 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Slider.h +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Slider.h @@ -5,7 +5,9 @@ #pragma once #include + #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" +#include "InputCommon/ControllerEmu/Setting/NumericSetting.h" #include "InputCommon/ControllerInterface/Device.h" namespace ControllerEmu @@ -22,5 +24,8 @@ class Slider : public ControlGroup explicit Slider(const std::string& name_); StateData GetState(); + +private: + SettingValue m_deadzone_setting; }; } // namespace ControllerEmu diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.cpp b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.cpp index 8407aa646ff9..91089455f8ae 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(Translate, _trans("Modifier"))); - numeric_settings.emplace_back(std::make_unique(_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 6a01a575a64a..68281083ea54 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.h +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.h @@ -6,6 +6,7 @@ #include +#include "InputCommon/ControllerEmu/Setting/NumericSetting.h" #include "InputCommon/ControllerEmu/StickGate.h" #include "InputCommon/ControllerInterface/Device.h" @@ -28,9 +29,6 @@ class Tilt : public ReshapableInput StateData GetState(); private: - enum - { - SETTING_MAX_ANGLE = ReshapableInput::SETTING_COUNT, - }; + SettingValue 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 f950e5b24c0d..e4a359eebadd 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(_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 561eb4f7ef36..107b94c6f8e5 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Triggers.h +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Triggers.h @@ -8,6 +8,7 @@ #include #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" +#include "InputCommon/ControllerEmu/Setting/NumericSetting.h" #include "InputCommon/ControllerInterface/Device.h" namespace ControllerEmu @@ -26,5 +27,8 @@ class Triggers : public ControlGroup explicit Triggers(const std::string& name); StateData GetState(); + +private: + SettingValue 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 d9aa61b9f69d..000000000000 --- 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 a2729a588eb6..000000000000 --- 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 - -#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 a15dd13f2f9b..345904082492 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::GetType() const +{ + return SettingType::Double; +} + +template <> +SettingType NumericSetting::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 2e84d383ba5e..ccc46634ed91 100644 --- a/Source/Core/InputCommon/ControllerEmu/Setting/NumericSetting.h +++ b/Source/Core/InputCommon/ControllerEmu/Setting/NumericSetting.h @@ -4,29 +4,127 @@ #pragma once +#include #include #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 +class SettingValue; + +template +class NumericSetting : public NumericSettingBase +{ +public: + using ValueType = T; + + static_assert(std::is_same() || std::is_same(), + "NumericSetting is only implemented for double and bool."); + + NumericSetting(SettingValue* 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& m_value; + + const ValueType m_default_value; + const ValueType m_min_value; + const ValueType m_max_value; +}; + +template +class SettingValue +{ + using ValueType = T; + + friend class NumericSetting; + +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 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 955e3d8c8b57..000000000000 --- 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 06abc4a64b9b..8e9d48467aef 100644 --- a/Source/Core/InputCommon/ControllerEmu/StickGate.cpp +++ b/Source/Core/InputCommon/ControllerEmu/StickGate.cpp @@ -100,13 +100,13 @@ std::optional 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(_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 38ad57a8b3e8..c022cc86fb42 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 @@ class ReshapableInput : public ControlGroup 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 @@ class ReshapableInput : public ControlGroup void SaveConfig(IniFile::Section*, const std::string&, const std::string&) override; CalibrationData m_calibration; + SettingValue m_deadzone_setting; }; } // namespace ControllerEmu diff --git a/Source/Core/InputCommon/InputCommon.vcxproj b/Source/Core/InputCommon/InputCommon.vcxproj index 6bf821f03264..8d0b0b375966 100644 --- a/Source/Core/InputCommon/InputCommon.vcxproj +++ b/Source/Core/InputCommon/InputCommon.vcxproj @@ -52,7 +52,6 @@ - @@ -92,9 +91,7 @@ - - @@ -123,4 +120,4 @@ - \ No newline at end of file + diff --git a/Source/Core/InputCommon/InputCommon.vcxproj.filters b/Source/Core/InputCommon/InputCommon.vcxproj.filters index 00a6211e96b6..76195f56270a 100644 --- a/Source/Core/InputCommon/InputCommon.vcxproj.filters +++ b/Source/Core/InputCommon/InputCommon.vcxproj.filters @@ -77,9 +77,6 @@ ControllerEmu\ControlGroup - - ControllerEmu\Setting - ControllerEmu\Setting @@ -170,15 +167,9 @@ ControllerEmu\ControlGroup - - ControllerEmu\Setting - ControllerEmu\Setting - - ControllerEmu\Setting - ControllerInterface\DInput @@ -223,4 +214,4 @@ - \ No newline at end of file + diff --git a/Source/Core/InputCommon/InputConfig.cpp b/Source/Core/InputCommon/InputConfig.cpp index 0a6a82d54000..a1826f46d103 100644 --- a/Source/Core/InputCommon/InputConfig.cpp +++ b/Source/Core/InputCommon/InputConfig.cpp @@ -13,6 +13,7 @@ #include "Core/HW/Wiimote.h" #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" #include "InputCommon/ControllerEmu/ControllerEmu.h" +#include "InputCommon/ControllerEmu/Setting/NumericSetting.h" #include "InputCommon/ControllerInterface/ControllerInterface.h" #include "InputCommon/InputConfig.h" #include "InputCommon/InputProfile.h" @@ -81,13 +82,13 @@ bool InputConfig::LoadConfig(bool isGC) #if defined(ANDROID) // For use on android touchscreen IR pointer // Check for IR values - if (control_section->Exists("IRWidth") && control_section->Exists("IRHeight") && - control_section->Exists("IRCenter")) + if (control_section->Exists("IRTotalYaw") && control_section->Exists("IRTotalPitch") && + control_section->Exists("IRVerticalOffset")) { use_ir_config = true; - control_section->Get("IRWidth", &ir_values[0]); - control_section->Get("IRHeight", &ir_values[1]); - control_section->Get("IRCenter", &ir_values[2]); + control_section->Get("IRTotalYaw", &ir_values[0]); + control_section->Get("IRTotalPitch", &ir_values[1]); + control_section->Get("IRVerticalOffset", &ir_values[2]); } #endif } @@ -119,9 +120,9 @@ bool InputConfig::LoadConfig(bool isGC) // Only set for wii pads if (!isGC && use_ir_config) { - config.Set("IR/Width", ir_values[0]); - config.Set("IR/Height", ir_values[1]); - config.Set("IR/Center", ir_values[2]); + config.Set("IR/Total Yaw", ir_values[0]); + config.Set("IR/Total Pitch", ir_values[1]); + config.Set("IR/Vertical Offset", ir_values[2]); } #endif controller->LoadConfig(&config);