Controller: Add invert and button deadzone options

This commit is contained in:
Connor McLaughlin 2022-09-22 13:50:31 +10:00
parent 1a6bc86136
commit 736996ab38
12 changed files with 299 additions and 232 deletions

View file

@ -136,7 +136,7 @@ void AnalogController::SetBindState(u32 index, float value)
if (index == static_cast<s32>(Button::Analog))
{
// analog toggle
if (value >= 0.5f)
if (value >= m_button_deadzone)
{
if (m_command == Command::Idle)
ProcessAnalogModeToggle();
@ -168,22 +168,30 @@ void AnalogController::SetBindState(u32 index, float value)
{
case HalfAxis::LLeft:
case HalfAxis::LRight:
m_axis_state[static_cast<u8>(Axis::LeftX)] = MERGE(HalfAxis::LRight, HalfAxis::LLeft);
m_axis_state[static_cast<u8>(Axis::LeftX)] = ((m_invert_left_stick & 1u) != 0u) ?
MERGE(HalfAxis::LLeft, HalfAxis::LRight) :
MERGE(HalfAxis::LRight, HalfAxis::LLeft);
break;
case HalfAxis::LDown:
case HalfAxis::LUp:
m_axis_state[static_cast<u8>(Axis::LeftY)] = MERGE(HalfAxis::LDown, HalfAxis::LUp);
m_axis_state[static_cast<u8>(Axis::LeftY)] = ((m_invert_left_stick & 2u) != 0u) ?
MERGE(HalfAxis::LUp, HalfAxis::LDown) :
MERGE(HalfAxis::LDown, HalfAxis::LUp);
break;
case HalfAxis::RLeft:
case HalfAxis::RRight:
m_axis_state[static_cast<u8>(Axis::RightX)] = MERGE(HalfAxis::RRight, HalfAxis::RLeft);
m_axis_state[static_cast<u8>(Axis::RightX)] = ((m_invert_right_stick & 1u) != 0u) ?
MERGE(HalfAxis::RLeft, HalfAxis::RRight) :
MERGE(HalfAxis::RRight, HalfAxis::RLeft);
break;
case HalfAxis::RDown:
case HalfAxis::RUp:
m_axis_state[static_cast<u8>(Axis::RightY)] = MERGE(HalfAxis::RDown, HalfAxis::RUp);
m_axis_state[static_cast<u8>(Axis::RightY)] = ((m_invert_right_stick & 2u) != 0u) ?
MERGE(HalfAxis::RUp, HalfAxis::RDown) :
MERGE(HalfAxis::RDown, HalfAxis::RUp);
break;
default:
@ -197,7 +205,7 @@ void AnalogController::SetBindState(u32 index, float value)
const u16 bit = u16(1) << static_cast<u8>(index);
if (value >= 0.5f)
if (value >= m_button_deadzone)
{
if (m_button_state & bit)
System::SetRunaheadReplayFlag();
@ -779,6 +787,11 @@ static const Controller::ControllerBindingInfo s_binding_info[] = {
#undef BUTTON
};
static const char* s_invert_settings[] = {TRANSLATABLE("AnalogController", "Not Inverted"),
TRANSLATABLE("AnalogController", "Invert Left/Right"),
TRANSLATABLE("AnalogController", "Invert Up/Down"),
TRANSLATABLE("AnalogController", "Invert Left/Right + Up/Down"), nullptr};
static const SettingInfo s_settings[] = {
{SettingInfo::Type::Boolean, "ForceAnalogOnReset", TRANSLATABLE("AnalogController", "Force Analog Mode on Reset"),
TRANSLATABLE("AnalogController", "Forces the controller to analog mode when the console is reset/powered on. May "
@ -792,17 +805,26 @@ static const SettingInfo s_settings[] = {
{SettingInfo::Type::Float, "AnalogDeadzone", TRANSLATABLE("AnalogController", "Analog Deadzone"),
TRANSLATABLE("AnalogController",
"Sets the analog stick deadzone, i.e. the fraction of the stick movement which will be ignored."),
"0.00f", "0.00f", "1.00f", "0.01f", "%.0f%%", 100.0f},
"0.00f", "0.00f", "1.00f", "0.01f", "%.0f%%", nullptr, 100.0f},
{SettingInfo::Type::Float, "AnalogSensitivity", TRANSLATABLE("AnalogController", "Analog Sensitivity"),
TRANSLATABLE(
"AnalogController",
"Sets the analog stick axis scaling factor. A value between 130% and 140% is recommended when using recent "
"controllers, e.g. DualShock 4, Xbox One Controller."),
"1.33f", "0.01f", "2.00f", "0.01f", "%.0f%%", 100.0f},
"1.33f", "0.01f", "2.00f", "0.01f", "%.0f%%", nullptr, 100.0f},
{SettingInfo::Type::Float, "ButtonDeadzone", "Button/Trigger Deadzone",
"Sets the deadzone for activating buttons/triggers, i.e. the fraction of the trigger which will be ignored.", "0.25",
"0.00", "1.00", "0.01", "%.0f%%", nullptr, 100.0f},
{SettingInfo::Type::Integer, "VibrationBias", TRANSLATABLE("AnalogController", "Vibration Bias"),
TRANSLATABLE("AnalogController", "Sets the rumble bias value. If rumble in some games is too weak or not "
"functioning, try increasing this value."),
"8", "0", "255", "1", "%d", 1.0f}};
"8", "0", "255", "1", "%d", nullptr, 1.0f},
{SettingInfo::Type::IntegerList, "InvertLeftStick", "Invert Left Stick",
"Inverts the direction of the left analog stick.", "0", "0", "3", nullptr, nullptr, s_invert_settings, 0.0f},
{SettingInfo::Type::IntegerList, "InvertRightStick", "Invert Right Stick",
"Inverts the direction of the right analog stick.", "0", "0", "3", nullptr, nullptr, s_invert_settings, 0.0f},
};
const Controller::ControllerInfo AnalogController::INFO = {ControllerType::AnalogController,
"AnalogController",
@ -821,5 +843,8 @@ void AnalogController::LoadSettings(SettingsInterface& si, const char* section)
m_analog_deadzone = std::clamp(si.GetFloatValue(section, "AnalogDeadzone", DEFAULT_STICK_DEADZONE), 0.0f, 1.0f);
m_analog_sensitivity =
std::clamp(si.GetFloatValue(section, "AnalogSensitivity", DEFAULT_STICK_SENSITIVITY), 0.01f, 3.0f);
m_button_deadzone = std::clamp(si.GetFloatValue(section, "ButtonDeadzone", DEFAULT_BUTTON_DEADZONE), 0.0f, 1.0f);
m_rumble_bias = static_cast<u8>(std::min<u32>(si.GetIntValue(section, "VibrationBias", 8), 255));
m_invert_left_stick = static_cast<u8>(si.GetIntValue(section, "InvertLeftStick", 0));
m_invert_right_stick = static_cast<u8>(si.GetIntValue(section, "InvertRightStick", 0));
}

View file

@ -121,7 +121,10 @@ private:
bool m_analog_dpad_in_digital_mode = false;
float m_analog_deadzone = 0.0f;
float m_analog_sensitivity = 1.33f;
float m_button_deadzone = 0.0f;
u8 m_rumble_bias = 8;
u8 m_invert_left_stick = 0;
u8 m_invert_right_stick = 0;
bool m_analog_mode = false;
bool m_analog_locked = false;

View file

@ -328,13 +328,13 @@ static const SettingInfo s_settings[] = {
{SettingInfo::Type::Float, "AnalogDeadzone", TRANSLATABLE("AnalogJoystick", "Analog Deadzone"),
TRANSLATABLE("AnalogJoystick",
"Sets the analog stick deadzone, i.e. the fraction of the stick movement which will be ignored."),
"1.00f", "0.00f", "1.00f", "0.01f", "%.0f%%", 100.0f},
"1.00f", "0.00f", "1.00f", "0.01f", "%.0f%%", nullptr, 100.0f},
{SettingInfo::Type::Float, "AnalogSensitivity", TRANSLATABLE("AnalogJoystick", "Analog Sensitivity"),
TRANSLATABLE(
"AnalogJoystick",
"Sets the analog stick axis scaling factor. A value between 130% and 140% is recommended when using recent "
"controllers, e.g. DualShock 4, Xbox One Controller."),
"1.33f", "0.01f", "2.00f", "0.01f", "%.0f%%", 100.0f}};
"1.33f", "0.01f", "2.00f", "0.01f", "%.0f%%", nullptr, 100.0f}};
const Controller::ControllerInfo AnalogJoystick::INFO = {ControllerType::AnalogJoystick,
"AnalogJoystick",

View file

@ -60,6 +60,7 @@ public:
/// Default stick deadzone/sensitivity.
static constexpr float DEFAULT_STICK_DEADZONE = 0.0f;
static constexpr float DEFAULT_STICK_SENSITIVITY = 1.33f;
static constexpr float DEFAULT_BUTTON_DEADZONE = 0.25f;
Controller(u32 index);
virtual ~Controller();

View file

@ -220,10 +220,11 @@ static const SettingInfo s_settings[] = {
{SettingInfo::Type::Path, "CrosshairImagePath", TRANSLATABLE("GunCon", "Crosshair Image Path"),
TRANSLATABLE("GunCon", "Path to an image to use as a crosshair/cursor.")},
{SettingInfo::Type::Float, "CrosshairScale", TRANSLATABLE("GunCon", "Crosshair Image Scale"),
TRANSLATABLE("GunCon", "Scale of crosshair image on screen."), "1.0", "0.0001", "100.0", "0.10", "%.0f%%", 100.0f},
TRANSLATABLE("GunCon", "Scale of crosshair image on screen."), "1.0", "0.0001", "100.0", "0.10", "%.0f%%", nullptr,
100.0f},
{SettingInfo::Type::Float, "XScale", TRANSLATABLE("GunCon", "X Scale"),
TRANSLATABLE("GunCon", "Scales X coordinates relative to the center of the screen."), "1.0", "0.01", "2.0",
"0.01", "%.0f%%", 100.0f}};
TRANSLATABLE("GunCon", "Scales X coordinates relative to the center of the screen."), "1.0", "0.01", "2.0", "0.01",
"%.0f%%", nullptr, 100.0f}};
const Controller::ControllerInfo GunCon::INFO = {ControllerType::GunCon,
"GunCon",

View file

@ -249,9 +249,10 @@ static const Controller::ControllerBindingInfo s_binding_info[] = {
#undef BUTTON
};
static const SettingInfo s_settings[] = {
{SettingInfo::Type::Float, "SteeringDeadzone", TRANSLATABLE("NeGcon", "Steering Axis Deadzone"),
TRANSLATABLE("NeGcon", "Sets deadzone size for steering axis."), "0.00f", "0.00f", "0.99f", "0.01f", "%.0f%%", 100.0f}};
static const SettingInfo s_settings[] = {{SettingInfo::Type::Float, "SteeringDeadzone",
TRANSLATABLE("NeGcon", "Steering Axis Deadzone"),
TRANSLATABLE("NeGcon", "Sets deadzone size for steering axis."), "0.00f",
"0.00f", "0.99f", "0.01f", "%.0f%%", nullptr, 100.0f}};
const Controller::ControllerInfo NeGcon::INFO = {ControllerType::NeGcon,
"NeGcon",

View file

@ -17,6 +17,7 @@ struct SettingInfo
{
Boolean,
Integer,
IntegerList,
Float,
String,
Path,
@ -31,6 +32,7 @@ struct SettingInfo
const char* max_value;
const char* step_value;
const char* format;
const char** options;
float multiplier;
const char* StringDefaultValue() const;

View file

@ -554,6 +554,20 @@ void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidge
}
break;
case SettingInfo::Type::IntegerList:
{
QComboBox* cb = new QComboBox(this);
cb->setObjectName(QString::fromUtf8(si.name));
for (u32 j = 0; si.options[j] != nullptr; j++)
cb->addItem(qApp->translate(cinfo->name, si.options[j]));
SettingWidgetBinder::BindWidgetToIntSetting(sif, cb, section, std::move(key_name), si.IntegerDefaultValue(),
si.IntegerMinValue());
layout->addWidget(new QLabel(qApp->translate(cinfo->name, si.display_name), this), current_row, 0);
layout->addWidget(cb, current_row, 1, 1, 3);
current_row++;
}
break;
case SettingInfo::Type::Float:
{
QDoubleSpinBox* sb = new QDoubleSpinBox(this);
@ -639,6 +653,14 @@ void ControllerCustomSettingsWidget::restoreDefaults()
}
break;
case SettingInfo::Type::IntegerList:
{
QComboBox* widget = findChild<QComboBox*>(QString::fromStdString(si.name));
if (widget)
widget->setCurrentIndex(si.IntegerDefaultValue() - si.IntegerMinValue());
}
break;
case SettingInfo::Type::Float:
{
QDoubleSpinBox* widget = findChild<QDoubleSpinBox*>(QString::fromStdString(si.name));

View file

@ -27,10 +27,6 @@ ControllerGlobalSettingsWidget::ControllerGlobalSettingsWidget(QWidget* parent,
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.multitapMode, "ControllerPorts", "MultitapMode",
&Settings::ParseMultitapModeName, &Settings::GetMultitapModeName,
Settings::DEFAULT_MULTITAP_MODE);
ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.pointerXInvert, "ControllerPorts",
"PointerXInvert", false);
ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.pointerYInvert, "ControllerPorts",
"PointerYInvert", false);
ControllerSettingWidgetBinder::BindWidgetToInputProfileFloat(sif, m_ui.pointerXScale, "ControllerPorts",
"PointerXScale", 8.0f);
ControllerSettingWidgetBinder::BindWidgetToInputProfileFloat(sif, m_ui.pointerYScale, "ControllerPorts",

View file

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>902</width>
<height>677</height>
<height>673</height>
</rect>
</property>
<property name="windowTitle">
@ -26,6 +26,57 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item row="2" column="0">
<widget class="QGroupBox" name="dinputGroup">
<property name="title">
<string>DInput Source</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>The DInput source provides support for legacy controllers which do not support XInput. Accessing these controllers via SDL instead is recommended.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="enableDInputSource">
<property name="text">
<string>Enable DInput Input Source</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1" rowspan="7">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Detected Devices</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<widget class="QListWidget" name="deviceList">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="4" column="0">
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
@ -76,16 +127,16 @@
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QGroupBox" name="dinputGroup">
<item row="0" column="0">
<widget class="QGroupBox" name="sdlGroup">
<property name="title">
<string>DInput Source</string>
<string>SDL Input Source</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="label_9">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_2">
<property name="text">
<string>The DInput source provides support for legacy controllers which do not support XInput. Accessing these controllers via SDL instead is recommended.</string>
<string>The SDL input source supports most controllers, and provides advanced functionality for DualShock 4 / DualSense pads in Bluetooth mode (Vibration / LED Control).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@ -93,25 +144,32 @@
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="enableDInputSource">
<widget class="QCheckBox" name="enableSDLSource">
<property name="text">
<string>Enable DInput Input Source</string>
<string>Enable SDL Input Source</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="enableSDLEnhancedMode">
<property name="text">
<string>DualShock 4 / DualSense Enhanced Mode</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="sdlGroup">
<item row="1" column="0">
<widget class="QGroupBox" name="xinputGroup">
<property name="title">
<string>SDL Input Source</string>
<string>XInput Source</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_2">
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>The SDL input source supports most controllers, and provides advanced functionality for DualShock 4 / DualSense pads in Bluetooth mode (Vibration / LED Control).</string>
<string>The XInput source provides support for XBox 360 / XBox One / XBox Series controllers, and third party controllers which implement the XInput protocol.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@ -119,41 +177,35 @@
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="enableSDLSource">
<property name="text">
<string>Enable SDL Input Source</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="enableSDLEnhancedMode">
<widget class="QCheckBox" name="enableXInputSource">
<property name="text">
<string>DualShock 4 / DualSense Enhanced Mode</string>
<string>Enable XInput Input Source</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1" rowspan="7">
<widget class="QGroupBox" name="groupBox_3">
<item row="5" column="0">
<widget class="QGroupBox" name="profileSettings">
<property name="title">
<string>Detected Devices</string>
<string>Profile Settings</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<widget class="QListWidget" name="deviceList">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>When this option is enabled, hotkeys can be set in this input profile, and will be used instead of the global hotkeys. By default, hotkeys are always shared between all profiles.</string>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="useProfileHotkeyBindings">
<property name="text">
<string>Use Per-Profile Hotkeys</string>
</property>
</widget>
</item>
@ -165,27 +217,27 @@
<property name="title">
<string>Mouse/Pointer Source</string>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<item row="1" column="2">
<widget class="QLabel" name="pointerXScaleLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Using raw input improves precision when you bind controller sticks to the mouse pointer. Also enables multiple mice to be used.</string>
</property>
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>10</string>
<string>Horizontal Sensitivity:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSlider" name="pointerXScale">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@ -210,14 +262,37 @@
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QCheckBox" name="pointerYInvert">
<item>
<widget class="QLabel" name="pointerXScaleLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>10</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Invert</string>
<string>Vertical Sensitivity:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QSlider" name="pointerYScale">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@ -242,7 +317,7 @@
</property>
</widget>
</item>
<item row="2" column="2">
<item>
<widget class="QLabel" name="pointerYScaleLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
@ -261,45 +336,18 @@
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QCheckBox" name="pointerXInvert">
<property name="text">
<string>Invert</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="4">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Using raw input improves precision when you bind controller sticks to the mouse pointer. Also enables multiple mice to be used.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Vertical Sensitivity:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Horizontal Sensitivity:</string>
</property>
</widget>
</layout>
</item>
<item row="3" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="enableMouseMapping">
<property name="text">
<string>Enable Mouse Mapping</string>
</property>
</widget>
</item>
<item row="3" column="2" colspan="2">
<item>
<widget class="QCheckBox" name="enableRawInput">
<property name="text">
<string>Use Raw Input</string>
@ -307,56 +355,6 @@
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="xinputGroup">
<property name="title">
<string>XInput Source</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>The XInput source provides support for XBox 360 / XBox One / XBox Series controllers, and third party controllers which implement the XInput protocol.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="enableXInputSource">
<property name="text">
<string>Enable XInput Input Source</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="5" column="0">
<widget class="QGroupBox" name="profileSettings">
<property name="title">
<string>Profile Settings</string>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>When this option is enabled, hotkeys can be set in this input profile, and will be used instead of the global hotkeys. By default, hotkeys are always shared between all profiles.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="useProfileHotkeyBindings">
<property name="text">
<string>Use Per-Profile Hotkeys</string>
</property>
</widget>
</item>
</layout>
</widget>

View file

@ -3018,6 +3018,10 @@ void FullscreenUI::DrawControllerSettingsPage()
DrawIntRangeSetting(bsi, title, si.description, section.c_str(), si.name, si.IntegerDefaultValue(),
si.IntegerMinValue(), si.IntegerMaxValue(), si.format, true);
break;
case SettingInfo::Type::IntegerList:
DrawIntListSetting(bsi, title, si.description, section.c_str(), si.name, si.IntegerDefaultValue(),
si.options, 0, si.IntegerMinValue(), true);
break;
case SettingInfo::Type::Float:
DrawFloatRangeSetting(bsi, title, si.description, section.c_str(), si.name, si.FloatDefaultValue(),
si.FloatMinValue(), si.FloatMaxValue(), si.format, si.multiplier, true);

View file

@ -962,12 +962,28 @@ void InputManager::CopyConfiguration(SettingsInterface* dest_si, const SettingsI
if (copy_pad_config)
{
dest_si->CopyFloatValue(src_si, section.c_str(), "AxisScale");
if (info->vibration_caps != Controller::VibrationCapabilities::NoVibration)
for (u32 i = 0; i < info->num_settings; i++)
{
const SettingInfo& csi = info->settings[i];
switch (csi.type)
{
dest_si->CopyFloatValue(src_si, section.c_str(), "LargeMotorScale");
dest_si->CopyFloatValue(src_si, section.c_str(), "SmallMotorScale");
case SettingInfo::Type::Boolean:
dest_si->CopyBoolValue(src_si, section.c_str(), csi.name);
break;
case SettingInfo::Type::Integer:
case SettingInfo::Type::IntegerList:
dest_si->CopyIntValue(src_si, section.c_str(), csi.name);
break;
case SettingInfo::Type::Float:
dest_si->CopyFloatValue(src_si, section.c_str(), csi.name);
break;
case SettingInfo::Type::String:
case SettingInfo::Type::Path:
dest_si->CopyStringValue(src_si, section.c_str(), csi.name);
break;
default:
break;
}
}
}
}
@ -1350,10 +1366,8 @@ void InputManager::ReloadBindings(SettingsInterface& si, SettingsInterface& bind
{
// From lilypad: 1 mouse pixel = 1/8th way down.
const float default_scale = (axis <= static_cast<u32>(InputPointerAxis::Y)) ? 8.0f : 1.0f;
const float invert =
si.GetBoolValue("Pad", fmt::format("Pointer{}Invert", s_pointer_axis_names[axis]).c_str(), false) ? -1.0f : 1.0f;
s_pointer_axis_scale[axis] =
invert / std::max(si.GetFloatValue("Pad", fmt::format("Pointer{}Scale", s_pointer_axis_names[axis]).c_str(),
1.0f / std::max(si.GetFloatValue("Pad", fmt::format("Pointer{}Scale", s_pointer_axis_names[axis]).c_str(),
default_scale),
1.0f);
}