Controller: Add invert and button deadzone options

pull/2893/head
Connor McLaughlin 3 years ago
parent 1a6bc86136
commit 736996ab38

@ -136,7 +136,7 @@ void AnalogController::SetBindState(u32 index, float value)
if (index == static_cast<s32>(Button::Analog)) if (index == static_cast<s32>(Button::Analog))
{ {
// analog toggle // analog toggle
if (value >= 0.5f) if (value >= m_button_deadzone)
{ {
if (m_command == Command::Idle) if (m_command == Command::Idle)
ProcessAnalogModeToggle(); ProcessAnalogModeToggle();
@ -168,22 +168,30 @@ void AnalogController::SetBindState(u32 index, float value)
{ {
case HalfAxis::LLeft: case HalfAxis::LLeft:
case HalfAxis::LRight: 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; break;
case HalfAxis::LDown: case HalfAxis::LDown:
case HalfAxis::LUp: 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; break;
case HalfAxis::RLeft: case HalfAxis::RLeft:
case HalfAxis::RRight: 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; break;
case HalfAxis::RDown: case HalfAxis::RDown:
case HalfAxis::RUp: 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; break;
default: default:
@ -197,7 +205,7 @@ void AnalogController::SetBindState(u32 index, float value)
const u16 bit = u16(1) << static_cast<u8>(index); const u16 bit = u16(1) << static_cast<u8>(index);
if (value >= 0.5f) if (value >= m_button_deadzone)
{ {
if (m_button_state & bit) if (m_button_state & bit)
System::SetRunaheadReplayFlag(); System::SetRunaheadReplayFlag();
@ -779,6 +787,11 @@ static const Controller::ControllerBindingInfo s_binding_info[] = {
#undef BUTTON #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[] = { static const SettingInfo s_settings[] = {
{SettingInfo::Type::Boolean, "ForceAnalogOnReset", TRANSLATABLE("AnalogController", "Force Analog Mode on Reset"), {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 " 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"), {SettingInfo::Type::Float, "AnalogDeadzone", TRANSLATABLE("AnalogController", "Analog Deadzone"),
TRANSLATABLE("AnalogController", TRANSLATABLE("AnalogController",
"Sets the analog stick deadzone, i.e. the fraction of the stick movement which will be ignored."), "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"), {SettingInfo::Type::Float, "AnalogSensitivity", TRANSLATABLE("AnalogController", "Analog Sensitivity"),
TRANSLATABLE( TRANSLATABLE(
"AnalogController", "AnalogController",
"Sets the analog stick axis scaling factor. A value between 130% and 140% is recommended when using recent " "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."), "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"), {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 " TRANSLATABLE("AnalogController", "Sets the rumble bias value. If rumble in some games is too weak or not "
"functioning, try increasing this value."), "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, const Controller::ControllerInfo AnalogController::INFO = {ControllerType::AnalogController,
"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_deadzone = std::clamp(si.GetFloatValue(section, "AnalogDeadzone", DEFAULT_STICK_DEADZONE), 0.0f, 1.0f);
m_analog_sensitivity = m_analog_sensitivity =
std::clamp(si.GetFloatValue(section, "AnalogSensitivity", DEFAULT_STICK_SENSITIVITY), 0.01f, 3.0f); 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_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));
} }

@ -121,7 +121,10 @@ private:
bool m_analog_dpad_in_digital_mode = false; bool m_analog_dpad_in_digital_mode = false;
float m_analog_deadzone = 0.0f; float m_analog_deadzone = 0.0f;
float m_analog_sensitivity = 1.33f; float m_analog_sensitivity = 1.33f;
float m_button_deadzone = 0.0f;
u8 m_rumble_bias = 8; 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_mode = false;
bool m_analog_locked = false; bool m_analog_locked = false;

@ -328,13 +328,13 @@ static const SettingInfo s_settings[] = {
{SettingInfo::Type::Float, "AnalogDeadzone", TRANSLATABLE("AnalogJoystick", "Analog Deadzone"), {SettingInfo::Type::Float, "AnalogDeadzone", TRANSLATABLE("AnalogJoystick", "Analog Deadzone"),
TRANSLATABLE("AnalogJoystick", TRANSLATABLE("AnalogJoystick",
"Sets the analog stick deadzone, i.e. the fraction of the stick movement which will be ignored."), "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"), {SettingInfo::Type::Float, "AnalogSensitivity", TRANSLATABLE("AnalogJoystick", "Analog Sensitivity"),
TRANSLATABLE( TRANSLATABLE(
"AnalogJoystick", "AnalogJoystick",
"Sets the analog stick axis scaling factor. A value between 130% and 140% is recommended when using recent " "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."), "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, const Controller::ControllerInfo AnalogJoystick::INFO = {ControllerType::AnalogJoystick,
"AnalogJoystick", "AnalogJoystick",

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

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

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

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

@ -554,6 +554,20 @@ void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidge
} }
break; 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: case SettingInfo::Type::Float:
{ {
QDoubleSpinBox* sb = new QDoubleSpinBox(this); QDoubleSpinBox* sb = new QDoubleSpinBox(this);
@ -639,6 +653,14 @@ void ControllerCustomSettingsWidget::restoreDefaults()
} }
break; 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: case SettingInfo::Type::Float:
{ {
QDoubleSpinBox* widget = findChild<QDoubleSpinBox*>(QString::fromStdString(si.name)); QDoubleSpinBox* widget = findChild<QDoubleSpinBox*>(QString::fromStdString(si.name));

@ -27,10 +27,6 @@ ControllerGlobalSettingsWidget::ControllerGlobalSettingsWidget(QWidget* parent,
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.multitapMode, "ControllerPorts", "MultitapMode", SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.multitapMode, "ControllerPorts", "MultitapMode",
&Settings::ParseMultitapModeName, &Settings::GetMultitapModeName, &Settings::ParseMultitapModeName, &Settings::GetMultitapModeName,
Settings::DEFAULT_MULTITAP_MODE); 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", ControllerSettingWidgetBinder::BindWidgetToInputProfileFloat(sif, m_ui.pointerXScale, "ControllerPorts",
"PointerXScale", 8.0f); "PointerXScale", 8.0f);
ControllerSettingWidgetBinder::BindWidgetToInputProfileFloat(sif, m_ui.pointerYScale, "ControllerPorts", ControllerSettingWidgetBinder::BindWidgetToInputProfileFloat(sif, m_ui.pointerYScale, "ControllerPorts",

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>902</width> <width>902</width>
<height>677</height> <height>673</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -26,56 +26,6 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item row="4" column="0">
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Controller Multitap</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label">
<property name="text">
<string>The multitap enables up to 8 controllers to be connected to the console. Each multitap provides 4 ports. Multitap is not supported by all games.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Multitap Mode:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="multitapMode">
<item>
<property name="text">
<string>Disabled</string>
</property>
</item>
<item>
<property name="text">
<string>Enable on Port 1 Only</string>
</property>
</item>
<item>
<property name="text">
<string>Enable on Port 2 Only</string>
</property>
</item>
<item>
<property name="text">
<string>Enable on Ports 1 and 2</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0"> <item row="2" column="0">
<widget class="QGroupBox" name="dinputGroup"> <widget class="QGroupBox" name="dinputGroup">
<property name="title"> <property name="title">
@ -102,39 +52,6 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="0" column="0">
<widget class="QGroupBox" name="sdlGroup">
<property name="title">
<string>SDL Input Source</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_2">
<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>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</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">
<property name="text">
<string>DualShock 4 / DualSense Enhanced Mode</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1" rowspan="7"> <item row="0" column="1" rowspan="7">
<widget class="QGroupBox" name="groupBox_3"> <widget class="QGroupBox" name="groupBox_3">
<property name="title"> <property name="title">
@ -160,149 +77,83 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="4" column="0">
<widget class="QGroupBox" name="groupBox_5"> <widget class="QGroupBox" name="groupBox_4">
<property name="title"> <property name="title">
<string>Mouse/Pointer Source</string> <string>Controller Multitap</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_6"> <layout class="QFormLayout" name="formLayout">
<item row="1" column="2"> <item row="0" column="0" colspan="2">
<widget class="QLabel" name="pointerXScaleLabel"> <widget class="QLabel" name="label">
<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>
<item row="1" column="1">
<widget class="QSlider" name="pointerXScale">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>30</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QCheckBox" name="pointerYInvert">
<property name="text"> <property name="text">
<string>Invert</string> <string>The multitap enables up to 8 controllers to be connected to the console. Each multitap provides 4 ports. Multitap is not supported by all games.</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSlider" name="pointerYScale">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>30</number>
</property> </property>
<property name="orientation"> <property name="wordWrap">
<enum>Qt::Horizontal</enum> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="2"> <item row="1" column="0">
<widget class="QLabel" name="pointerYScaleLabel"> <widget class="QLabel" name="label_8">
<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"> <property name="text">
<string>10</string> <string>Multitap Mode:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="3"> <item row="1" column="1">
<widget class="QCheckBox" name="pointerXInvert"> <widget class="QComboBox" name="multitapMode">
<property name="text"> <item>
<string>Invert</string> <property name="text">
</property> <string>Disabled</string>
</property>
</item>
<item>
<property name="text">
<string>Enable on Port 1 Only</string>
</property>
</item>
<item>
<property name="text">
<string>Enable on Port 2 Only</string>
</property>
</item>
<item>
<property name="text">
<string>Enable on Ports 1 and 2</string>
</property>
</item>
</widget> </widget>
</item> </item>
<item row="0" column="0" colspan="4"> </layout>
<widget class="QLabel" name="label_7"> </widget>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="sdlGroup">
<property name="title">
<string>SDL Input Source</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_2">
<property name="text"> <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> <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>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </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"> <item row="1" column="0">
<widget class="QLabel" name="label_5"> <widget class="QCheckBox" name="enableSDLSource">
<property name="text">
<string>Horizontal Sensitivity:</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="enableMouseMapping">
<property name="text"> <property name="text">
<string>Enable Mouse Mapping</string> <string>Enable SDL Input Source</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="2" colspan="2"> <item row="1" column="1">
<widget class="QCheckBox" name="enableRawInput"> <widget class="QCheckBox" name="enableSDLEnhancedMode">
<property name="text"> <property name="text">
<string>Use Raw Input</string> <string>DualShock 4 / DualSense Enhanced Mode</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -361,6 +212,153 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="3" column="0">
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>Mouse/Pointer Source</string>
</property>
<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="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<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">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>30</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<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>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">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>30</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="pointerYScaleLabel">
<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="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>
<widget class="QCheckBox" name="enableRawInput">
<property name="text">
<string>Use Raw Input</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="6" column="0"> <item row="6" column="0">
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">

@ -3018,6 +3018,10 @@ void FullscreenUI::DrawControllerSettingsPage()
DrawIntRangeSetting(bsi, title, si.description, section.c_str(), si.name, si.IntegerDefaultValue(), DrawIntRangeSetting(bsi, title, si.description, section.c_str(), si.name, si.IntegerDefaultValue(),
si.IntegerMinValue(), si.IntegerMaxValue(), si.format, true); si.IntegerMinValue(), si.IntegerMaxValue(), si.format, true);
break; 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: case SettingInfo::Type::Float:
DrawFloatRangeSetting(bsi, title, si.description, section.c_str(), si.name, si.FloatDefaultValue(), DrawFloatRangeSetting(bsi, title, si.description, section.c_str(), si.name, si.FloatDefaultValue(),
si.FloatMinValue(), si.FloatMaxValue(), si.format, si.multiplier, true); si.FloatMinValue(), si.FloatMaxValue(), si.format, si.multiplier, true);

@ -962,12 +962,28 @@ void InputManager::CopyConfiguration(SettingsInterface* dest_si, const SettingsI
if (copy_pad_config) if (copy_pad_config)
{ {
dest_si->CopyFloatValue(src_si, section.c_str(), "AxisScale"); for (u32 i = 0; i < info->num_settings; i++)
if (info->vibration_caps != Controller::VibrationCapabilities::NoVibration)
{ {
dest_si->CopyFloatValue(src_si, section.c_str(), "LargeMotorScale"); const SettingInfo& csi = info->settings[i];
dest_si->CopyFloatValue(src_si, section.c_str(), "SmallMotorScale"); switch (csi.type)
{
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,12 +1366,10 @@ void InputManager::ReloadBindings(SettingsInterface& si, SettingsInterface& bind
{ {
// From lilypad: 1 mouse pixel = 1/8th way down. // 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 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] = 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), default_scale),
1.0f); 1.0f);
} }
} }

Loading…
Cancel
Save