diff --git a/Source/Android/app/src/main/assets/WiimoteNew.ini b/Source/Android/app/src/main/assets/WiimoteNew.ini
index e1a3804587..2ebd9d61d9 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 2283a1add2..2546736d13 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 880487c00e..3ba7e5f893 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 @@ public final class EmulationActivity extends AppCompatActivity
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 @@ public final class EmulationActivity extends AppCompatActivity
}
});
- 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 @@ public final class EmulationActivity extends AppCompatActivity
});
- 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 @@ public final class EmulationActivity extends AppCompatActivity
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 5ac2a2193a..ff24a7a6d3 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 8f60d318e2..49f3434a38 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 9cf0ac1d45..cc54d46d98 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 4f3db82f00..0eb73737ba 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 61bf120336..c2f2108edc 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 58272dc74a..9134ba9eee 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 @@ private:
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 8355c5d377..7a182e5db3 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 2f364171bd..b2af4d671f 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 30f0871042..a3c8b507cc 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 e17553bebb..084d290327 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->AddSetting(&m_speaker_pan_setting,
+ {_trans("Speaker Pan"),
+ // i18n: The percent symbol.
+ _trans("%")},
+ 0, -100, 100);
- 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->AddSetting(&m_battery_setting,
+ {_trans("Battery"),
+ // i18n: The percent symbol.
+ _trans("%")},
+ 95, 0, 100);
- 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_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 1ff17505db..68a56fd26c 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 @@ private:
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 551a7e04d8..b0154ceb4d 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 fe9ac2025a..a00d5fcdc5 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 1112f3b5e2..0000000000
--- 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 df3693d580..0000000000
--- 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 44e86a9feb..1d297922b8 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 4a630eac28..0952fa3537 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 0de807d68c..2c7b1fd4e8 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);
}
-void MappingNumeric::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() * 100);
+ 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 MappingBool::ConfigChanged()
+{
+ const bool old_state = blockSignals(true);
+ 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 2120e972c5..49817ea40c 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 NumericSetting;
-}
-
-class MappingNumeric : public QSpinBox
+class MappingDouble : public QDoubleSpinBox
{
public:
- MappingNumeric(MappingWidget* widget, ControllerEmu::NumericSetting* ref);
+ MappingDouble(MappingWidget* parent, ControllerEmu::NumericSetting* setting);
+
+private:
+ void fixup(QString& input) const override;
+
+ void ConfigChanged();
+
+ ControllerEmu::NumericSetting& m_setting;
+};
+
+class MappingBool : public QCheckBox
+{
+public:
+ 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 162a18bae9..0000000000
--- 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 230a311a26..0000000000
--- 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 8e80672860..1e968c2ed2 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);
- }
+ QWidget* setting_widget = nullptr;
- for (auto& boolean : group->boolean_settings)
- {
- if (!boolean->IsExclusive())
- continue;
+ switch (setting->GetType())
+ {
+ case ControllerEmu::SettingType::Double:
+ setting_widget = new MappingDouble(
+ this, static_cast*>(setting.get()));
+ break;
- auto* checkbox = new MappingRadio(this, boolean.get());
+ case ControllerEmu::SettingType::Bool:
+ setting_widget =
+ new MappingBool(this, static_cast*>(setting.get()));
+ break;
+ }
- form_layout->addRow(checkbox);
- }
-
- for (auto& boolean : group->boolean_settings)
- {
- if (boolean->IsExclusive())
- continue;
-
- auto* checkbox = new MappingBool(this, boolean.get());
-
- 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 80000e047a..84a2cf4e64 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 403fbed993..eb049b65f6 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 466ba75667..0c3ffe5deb 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 5886ba9137..a80a94b0ad 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 454e6a21ac..a3df1a2d22 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 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* 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 + "/");
+ const 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;
-
- 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
class NumericSetting;
+template
+class SettingValue;
+
enum class GroupType
{
Other,
@@ -46,12 +53,22 @@ public:
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 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(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));
+ // Default values are optimized for "Super Mario Galaxy 2".
+ // This seems to be acceptable for a good number of games.
- boolean_settings.emplace_back(std::make_unique(_trans("Relative Input"), false));
- boolean_settings.emplace_back(std::make_unique(_trans("Auto-Hide"), false));
+ 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 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 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(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));
+ 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);
- // 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));
+ 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);
- // 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_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 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 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(_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 4e7b2adafe..250466dc9d 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 @@ public:
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 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(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 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
+
#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 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(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 6a01a575a6..68281083ea 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 @@ public:
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 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(_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
#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 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
-
-#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
{
- m_value = value;
+ 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
+{
+ 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
#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);
+ NumericSettingBase(const NumericSettingDetails& details);
- 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;
+ 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 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 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 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 m_deadzone_setting;
};
} // namespace ControllerEmu
diff --git a/Source/Core/InputCommon/InputCommon.vcxproj b/Source/Core/InputCommon/InputCommon.vcxproj
index 6bf821f032..8d0b0b3759 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 00a6211e96..76195f5627 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 0a6a82d540..a1826f46d1 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);