PAD: Add analog stick invert and button deadzone options

This commit is contained in:
Connor McLaughlin 2022-09-12 21:40:25 +10:00 committed by refractionpcsx2
parent e28a3ac945
commit c136bb4ea8
9 changed files with 310 additions and 199 deletions

View File

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

View File

@ -36,8 +36,6 @@ ControllerGlobalSettingsWidget::ControllerGlobalSettingsWidget(QWidget* parent,
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableMouseMapping, "UI", "EnableMouseMapping", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableMouseMapping, "UI", "EnableMouseMapping", false);
ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.multitapPort1, "Pad", "MultitapPort1", false); ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.multitapPort1, "Pad", "MultitapPort1", false);
ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.multitapPort2, "Pad", "MultitapPort2", false); ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.multitapPort2, "Pad", "MultitapPort2", false);
ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.pointerXInvert, "Pad", "PointerXInvert", false);
ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.pointerYInvert, "Pad", "PointerYInvert", false);
ControllerSettingWidgetBinder::BindWidgetToInputProfileFloat(sif, m_ui.pointerXScale, "Pad", "PointerXScale", 8.0f); ControllerSettingWidgetBinder::BindWidgetToInputProfileFloat(sif, m_ui.pointerXScale, "Pad", "PointerXScale", 8.0f);
ControllerSettingWidgetBinder::BindWidgetToInputProfileFloat(sif, m_ui.pointerYScale, "Pad", "PointerYScale", 8.0f); ControllerSettingWidgetBinder::BindWidgetToInputProfileFloat(sif, m_ui.pointerYScale, "Pad", "PointerYScale", 8.0f);

View File

@ -26,6 +26,31 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item row="0" column="1" rowspan="6">
<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="0" column="0"> <item row="0" column="0">
<widget class="QGroupBox" name="groupBox"> <widget class="QGroupBox" name="groupBox">
<property name="title"> <property name="title">
@ -85,142 +110,39 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="5" column="0">
<widget class="QGroupBox" name="groupBox_5"> <spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>45</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="0">
<widget class="QGroupBox" name="profileSettings">
<property name="title"> <property name="title">
<string>Mouse/Pointer Source</string> <string>Profile Settings</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>
</property>
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property> </property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text"> <property name="text">
<string>10</string> <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>
</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">
<string>Invert</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 name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="2">
<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>
<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>
<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="useProfileHotkeyBindings">
<property name="text"> <property name="text">
<string>Horizontal Sensitivity:</string> <string>Use Per-Profile Hotkeys</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="4">
<widget class="QCheckBox" name="enableMouseMapping">
<property name="text">
<string>Enable Mouse Mapping</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -260,16 +182,16 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="4" column="0"> <item row="2" column="0">
<widget class="QGroupBox" name="profileSettings"> <widget class="QGroupBox" name="groupBox_5">
<property name="title"> <property name="title">
<string>Profile Settings</string> <string>Mouse/Pointer Source</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_5"> <layout class="QFormLayout" name="formLayout">
<item row="0" column="0"> <item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_4"> <widget class="QLabel" name="label_7">
<property name="text"> <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> <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>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>
@ -277,50 +199,126 @@
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QCheckBox" name="useProfileHotkeyBindings"> <widget class="QLabel" name="label_5">
<property name="text"> <property name="text">
<string>Use Per-Profile Hotkeys</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">
<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="Fixed" 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> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Vertical Sensitivity:</string>
</property>
</widget> </widget>
</item> </item>
<item row="5" column="0"> <item row="2" column="1">
<spacer name="verticalSpacer"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="orientation"> <item>
<enum>Qt::Vertical</enum> <widget class="QSlider" name="pointerYScale">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property> </property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>45</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1" rowspan="6">
<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"> <property name="minimumSize">
<size> <size>
<width>200</width> <width>150</width>
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
<property name="maximumSize"> <property name="minimum">
<size> <number>1</number>
<width>200</width> </property>
<height>16777215</height> <property name="maximum">
</size> <number>30</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QLabel" name="pointerYScaleLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" 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>
</layout>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

View File

@ -1217,6 +1217,12 @@ void FullscreenUI::DrawIntListSetting(SettingsInterface* bsi, const char* title,
int default_value, const char* const* options, size_t option_count, int option_offset, bool enabled, float height, ImFont* font, int default_value, const char* const* options, size_t option_count, int option_offset, bool enabled, float height, ImFont* font,
ImFont* summary_font) ImFont* summary_font)
{ {
if (options && option_count == 0)
{
while (options[option_count] != nullptr)
option_count++;
}
const bool game_settings = IsEditingGameSettings(bsi); const bool game_settings = IsEditingGameSettings(bsi);
const std::optional<int> value = const std::optional<int> value =
bsi->GetOptionalIntValue(section, key, game_settings ? std::nullopt : std::optional<int>(default_value)); bsi->GetOptionalIntValue(section, key, game_settings ? std::nullopt : std::optional<int>(default_value));
@ -3288,6 +3294,10 @@ void FullscreenUI::DrawControllerSettingsPage()
DrawIntRangeSetting(bsi, title.c_str(), si.description, section, si.name, si.IntegerDefaultValue(), DrawIntRangeSetting(bsi, title.c_str(), si.description, section, si.name, si.IntegerDefaultValue(),
si.IntegerMinValue(), si.IntegerMaxValue(), si.format, true); si.IntegerMinValue(), si.IntegerMaxValue(), si.format, true);
break; break;
case PAD::ControllerSettingInfo::Type::IntegerList:
DrawIntListSetting(bsi, title.c_str(), si.description, section, si.name, si.IntegerDefaultValue(), si.options, 0,
si.IntegerMinValue(), true);
break;
case PAD::ControllerSettingInfo::Type::Float: case PAD::ControllerSettingInfo::Type::Float:
DrawFloatRangeSetting(bsi, title.c_str(), si.description, section, si.name, si.FloatDefaultValue(), DrawFloatRangeSetting(bsi, title.c_str(), si.description, section, si.name, si.FloatDefaultValue(),
si.FloatMinValue(), si.FloatMaxValue(), si.format, si.multiplier, true); si.FloatMinValue(), si.FloatMaxValue(), si.format, si.multiplier, true);

View File

@ -1006,10 +1006,8 @@ 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 / 1.0f /
std::max(si.GetFloatValue("Pad", fmt::format("Pointer{}Scale", s_pointer_axis_names[axis]).c_str(), default_scale), 1.0f); std::max(si.GetFloatValue("Pad", fmt::format("Pointer{}Scale", s_pointer_axis_names[axis]).c_str(), default_scale), 1.0f);
} }
} }

View File

@ -24,7 +24,7 @@ using namespace PAD;
KeyStatus::KeyStatus() KeyStatus::KeyStatus()
{ {
Init(); std::memset(&m_analog, 0, sizeof(m_analog));
for (u32 pad = 0; pad < NUM_CONTROLLER_PORTS; pad++) for (u32 pad = 0; pad < NUM_CONTROLLER_PORTS; pad++)
{ {
@ -32,6 +32,8 @@ KeyStatus::KeyStatus()
m_axis_scale[pad][1] = 1.0f; m_axis_scale[pad][1] = 1.0f;
m_pressure_modifier[pad] = 0.5f; m_pressure_modifier[pad] = 0.5f;
} }
Init();
} }
void KeyStatus::Init() void KeyStatus::Init()
@ -70,22 +72,22 @@ void KeyStatus::Set(u32 pad, u32 index, float value)
{ {
case PAD_R_LEFT: case PAD_R_LEFT:
case PAD_R_RIGHT: case PAD_R_RIGHT:
m_analog[pad].rx = MERGE(pad, PAD_R_RIGHT, PAD_R_LEFT); m_analog[pad].rx = m_analog[pad].invert_rx ? MERGE(pad, PAD_R_LEFT, PAD_R_RIGHT) : MERGE(pad, PAD_R_RIGHT, PAD_R_LEFT);
break; break;
case PAD_R_DOWN: case PAD_R_DOWN:
case PAD_R_UP: case PAD_R_UP:
m_analog[pad].ry = MERGE(pad, PAD_R_DOWN, PAD_R_UP); m_analog[pad].ry = m_analog[pad].invert_ry ? MERGE(pad, PAD_R_UP, PAD_R_DOWN) : MERGE(pad, PAD_R_DOWN, PAD_R_UP);
break; break;
case PAD_L_LEFT: case PAD_L_LEFT:
case PAD_L_RIGHT: case PAD_L_RIGHT:
m_analog[pad].lx = MERGE(pad, PAD_L_RIGHT, PAD_L_LEFT); m_analog[pad].lx = m_analog[pad].invert_lx ? MERGE(pad, PAD_L_LEFT, PAD_L_RIGHT) : MERGE(pad, PAD_L_RIGHT, PAD_L_LEFT);
break; break;
case PAD_L_DOWN: case PAD_L_DOWN:
case PAD_L_UP: case PAD_L_UP:
m_analog[pad].ly = MERGE(pad, PAD_L_DOWN, PAD_L_UP); m_analog[pad].ly = m_analog[pad].invert_ly ? MERGE(pad, PAD_L_UP, PAD_L_DOWN) : MERGE(pad, PAD_L_DOWN, PAD_L_UP);
break; break;
default: default:
@ -98,7 +100,8 @@ void KeyStatus::Set(u32 pad, u32 index, float value)
{ {
// Don't affect L2/R2, since they are analog on most pads. // Don't affect L2/R2, since they are analog on most pads.
const float pmod = ((m_button[pad] & (1u << PAD_PRESSURE)) == 0 && !IsTriggerKey(index)) ? m_pressure_modifier[pad] : 1.0f; const float pmod = ((m_button[pad] & (1u << PAD_PRESSURE)) == 0 && !IsTriggerKey(index)) ? m_pressure_modifier[pad] : 1.0f;
m_button_pressure[pad][index] = static_cast<u8>(std::clamp(value * pmod * 255.0f, 0.0f, 255.0f)); const float dz_value = (value < m_button_deadzone[pad]) ? 0.0f : value;
m_button_pressure[pad][index] = static_cast<u8>(std::clamp(dz_value * pmod * 255.0f, 0.0f, 255.0f));
// Since we reordered the buttons for better UI, we need to remap them here. // Since we reordered the buttons for better UI, we need to remap them here.
static constexpr std::array<u8, MAX_KEYS> bitmask_mapping = {{ static constexpr std::array<u8, MAX_KEYS> bitmask_mapping = {{
@ -123,8 +126,7 @@ void KeyStatus::Set(u32 pad, u32 index, float value)
// remainder are analogs and not used here // remainder are analogs and not used here
}}; }};
// TODO: Deadzone here? if (dz_value > 0.0f)
if (value > 0.0f)
m_button[pad] &= ~(1u << bitmask_mapping[index]); m_button[pad] &= ~(1u << bitmask_mapping[index]);
else else
m_button[pad] |= (1u << bitmask_mapping[index]); m_button[pad] |= (1u << bitmask_mapping[index]);

View File

@ -30,6 +30,8 @@ namespace PAD
{ {
u8 lx, ly; u8 lx, ly;
u8 rx, ry; u8 rx, ry;
u8 invert_lx, invert_ly;
u8 invert_rx, invert_ry;
}; };
PAD::ControllerType m_type[NUM_CONTROLLER_PORTS] = {}; PAD::ControllerType m_type[NUM_CONTROLLER_PORTS] = {};
@ -39,6 +41,7 @@ namespace PAD
float m_axis_scale[NUM_CONTROLLER_PORTS][2]; float m_axis_scale[NUM_CONTROLLER_PORTS][2];
float m_vibration_scale[NUM_CONTROLLER_PORTS][2]; float m_vibration_scale[NUM_CONTROLLER_PORTS][2];
float m_pressure_modifier[NUM_CONTROLLER_PORTS]; float m_pressure_modifier[NUM_CONTROLLER_PORTS];
float m_button_deadzone[NUM_CONTROLLER_PORTS];
public: public:
KeyStatus(); KeyStatus();
@ -58,6 +61,17 @@ namespace PAD
__fi void SetVibrationScale(u32 pad, u32 motor, float scale) { m_vibration_scale[pad][motor] = scale; } __fi void SetVibrationScale(u32 pad, u32 motor, float scale) { m_vibration_scale[pad][motor] = scale; }
__fi float GetPressureModifier(u32 pad) const { return m_pressure_modifier[pad]; } __fi float GetPressureModifier(u32 pad) const { return m_pressure_modifier[pad]; }
__fi void SetPressureModifier(u32 pad, float mod) { m_pressure_modifier[pad] = mod; } __fi void SetPressureModifier(u32 pad, float mod) { m_pressure_modifier[pad] = mod; }
__fi void SetButtonDeadzone(u32 pad, float deadzone) { m_button_deadzone[pad] = deadzone; }
__fi void SetAnalogInvertL(u32 pad, bool x, bool y)
{
m_analog[pad].invert_lx = x;
m_analog[pad].invert_ly = y;
}
__fi void SetAnalogInvertR(u32 pad, bool x, bool y)
{
m_analog[pad].invert_rx = x;
m_analog[pad].invert_ry = y;
}
u32 GetButtons(u32 pad); u32 GetButtons(u32 pad);
u8 GetPressure(u32 pad, u32 index); u8 GetPressure(u32 pad, u32 index);

View File

@ -268,7 +268,9 @@ void PAD::LoadConfig(const SettingsInterface& si)
const float axis_deadzone = si.GetFloatValue(section.c_str(), "Deadzone", DEFAULT_STICK_DEADZONE); const float axis_deadzone = si.GetFloatValue(section.c_str(), "Deadzone", DEFAULT_STICK_DEADZONE);
const float axis_scale = si.GetFloatValue(section.c_str(), "AxisScale", DEFAULT_STICK_SCALE); const float axis_scale = si.GetFloatValue(section.c_str(), "AxisScale", DEFAULT_STICK_SCALE);
const float button_deadzone = si.GetFloatValue(section.c_str(), "ButtonDeadzone", DEFAULT_BUTTON_DEADZONE);
g_key_status.SetAxisScale(i, axis_deadzone, axis_scale); g_key_status.SetAxisScale(i, axis_deadzone, axis_scale);
g_key_status.SetButtonDeadzone(i, button_deadzone);
if (ci->vibration_caps != VibrationCapabilities::NoVibration) if (ci->vibration_caps != VibrationCapabilities::NoVibration)
{ {
@ -281,6 +283,11 @@ void PAD::LoadConfig(const SettingsInterface& si)
const float pressure_modifier = si.GetFloatValue(section.c_str(), "PressureModifier", 1.0f); const float pressure_modifier = si.GetFloatValue(section.c_str(), "PressureModifier", 1.0f);
g_key_status.SetPressureModifier(i, pressure_modifier); g_key_status.SetPressureModifier(i, pressure_modifier);
const int invert_l = si.GetIntValue(section.c_str(), "InvertL", 0);
const int invert_r = si.GetIntValue(section.c_str(), "InvertR", 0);
g_key_status.SetAnalogInvertL(i, (invert_l & 1) != 0, (invert_l & 2) != 0);
g_key_status.SetAnalogInvertR(i, (invert_r & 1) != 0, (invert_r & 2) != 0);
LoadMacroButtonConfig(si, i, type, section); LoadMacroButtonConfig(si, i, type, section);
} }
} }
@ -310,20 +317,42 @@ void PAD::SetDefaultControllerConfig(SettingsInterface& si)
si.SetBoolValue("Pad", "MultitapPort2", false); si.SetBoolValue("Pad", "MultitapPort2", false);
si.SetFloatValue("Pad", "PointerXScale", 8.0f); si.SetFloatValue("Pad", "PointerXScale", 8.0f);
si.SetFloatValue("Pad", "PointerYScale", 8.0f); si.SetFloatValue("Pad", "PointerYScale", 8.0f);
si.SetBoolValue("Pad", "PointerXInvert", false);
si.SetBoolValue("Pad", "PointerYInvert", false);
// PCSX2 Controller Settings - Default pad types and parameters. // PCSX2 Controller Settings - Default pad types and parameters.
for (u32 i = 0; i < NUM_CONTROLLER_PORTS; i++) for (u32 i = 0; i < NUM_CONTROLLER_PORTS; i++)
{ {
const char* type = GetDefaultPadType(i);
const std::string section(GetConfigSection(i)); const std::string section(GetConfigSection(i));
si.ClearSection(section.c_str()); si.ClearSection(section.c_str());
si.SetStringValue(section.c_str(), "Type", GetDefaultPadType(i)); si.SetStringValue(section.c_str(), "Type", type);
si.SetFloatValue(section.c_str(), "Deadzone", DEFAULT_STICK_DEADZONE);
si.SetFloatValue(section.c_str(), "AxisScale", DEFAULT_STICK_SCALE); const ControllerInfo* ci = GetControllerInfo(type);
si.SetFloatValue(section.c_str(), "LargeMotorScale", DEFAULT_MOTOR_SCALE); if (ci)
si.SetFloatValue(section.c_str(), "SmallMotorScale", DEFAULT_MOTOR_SCALE); {
si.SetFloatValue(section.c_str(), "PressureModifier", DEFAULT_PRESSURE_MODIFIER); for (u32 i = 0; i < ci->num_settings; i++)
{
const ControllerSettingInfo& csi = ci->settings[i];
switch (csi.type)
{
case ControllerSettingInfo::Type::Boolean:
si.SetBoolValue(section.c_str(), csi.name, csi.BooleanDefaultValue());
break;
case ControllerSettingInfo::Type::Integer:
case ControllerSettingInfo::Type::IntegerList:
si.SetIntValue(section.c_str(), csi.name, csi.IntegerDefaultValue());
break;
case ControllerSettingInfo::Type::Float:
si.SetFloatValue(section.c_str(), csi.name, csi.FloatDefaultValue());
break;
case ControllerSettingInfo::Type::String:
case ControllerSettingInfo::Type::Path:
si.SetStringValue(section.c_str(), csi.name, csi.StringDefaultValue());
break;
default:
break;
}
}
}
} }
// PCSX2 Controller Settings - Controller 1 / Controller 2 / ... // PCSX2 Controller Settings - Controller 1 / Controller 2 / ...
@ -415,26 +444,42 @@ static const PAD::ControllerBindingInfo s_dualshock2_binds[] = {
{"SmallMotor", "Small (High Frequency) Motor", PAD::ControllerBindingType::Motor, GenericInputBinding::SmallMotor}, {"SmallMotor", "Small (High Frequency) Motor", PAD::ControllerBindingType::Motor, GenericInputBinding::SmallMotor},
}; };
static const char* s_dualshock2_invert_entries[] = {
"Not Inverted",
"Invert Left/Right",
"Invert Up/Down",
"Invert Left/Right + Up/Down",
nullptr};
static const PAD::ControllerSettingInfo s_dualshock2_settings[] = { static const PAD::ControllerSettingInfo s_dualshock2_settings[] = {
{PAD::ControllerSettingInfo::Type::IntegerList, "InvertL", "Invert Left Stick",
"Inverts the direction of the left analog stick.",
"0", "0", "3", nullptr, nullptr, s_dualshock2_invert_entries, 0.0f},
{PAD::ControllerSettingInfo::Type::IntegerList, "InvertR", "Invert Right Stick",
"Inverts the direction of the right analog stick.",
"0", "0", "3", nullptr, nullptr, s_dualshock2_invert_entries, 0.0f},
{PAD::ControllerSettingInfo::Type::Float, "Deadzone", "Analog Deadzone", {PAD::ControllerSettingInfo::Type::Float, "Deadzone", "Analog Deadzone",
"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.00", "0.00", "1.00", "0.01", "%.0f%%", 100.0f}, "0.00", "0.00", "1.00", "0.01", "%.0f%%", nullptr, 100.0f},
{PAD::ControllerSettingInfo::Type::Float, "AxisScale", "Analog Sensitivity", {PAD::ControllerSettingInfo::Type::Float, "AxisScale", "Analog Sensitivity",
"Sets the analog stick axis scaling factor. A value between 1.30 and 1.40 is recommended when using recent " "Sets the analog stick axis scaling factor. A value between 1.30 and 1.40 is recommended when using recent "
"controllers, e.g. DualShock 4, Xbox One Controller.", "controllers, e.g. DualShock 4, Xbox One Controller.",
"1.33", "0.01", "2.00", "0.01", "%.0f%%", 100.0f}, "1.33", "0.01", "2.00", "0.01", "%.0f%%", nullptr, 100.0f},
{PAD::ControllerSettingInfo::Type::Float, "LargeMotorScale", "Large Motor Vibration Scale", {PAD::ControllerSettingInfo::Type::Float, "LargeMotorScale", "Large Motor Vibration Scale",
"Increases or decreases the intensity of low frequency vibration sent by the game.", "Increases or decreases the intensity of low frequency vibration sent by the game.",
"1.00", "0.00", "2.00", "0.01", "%.0f%%", 100.0f}, "1.00", "0.00", "2.00", "0.01", "%.0f%%", nullptr, 100.0f},
{PAD::ControllerSettingInfo::Type::Float, "SmallMotorScale", "Small Motor Vibration Scale", {PAD::ControllerSettingInfo::Type::Float, "SmallMotorScale", "Small Motor Vibration Scale",
"Increases or decreases the intensity of high frequency vibration sent by the game.", "Increases or decreases the intensity of high frequency vibration sent by the game.",
"1.00", "0.00", "2.00", "0.01", "%.0f%%", 100.0f}, "1.00", "0.00", "2.00", "0.01", "%.0f%%", nullptr, 100.0f},
{PAD::ControllerSettingInfo::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.00", "0.00", "1.00", "0.01", "%.0f%%", nullptr, 100.0f},
/*{PAD::ControllerSettingInfo::Type::Float, "InitialPressure", "Initial Pressure", /*{PAD::ControllerSettingInfo::Type::Float, "InitialPressure", "Initial Pressure",
"Sets the pressure when the modifier button isn't held.", "Sets the pressure when the modifier button isn't held.",
"1.00", "0.01", "1.00", "0.01", "%.0f%%", 100.0f},*/ "1.00", "0.01", "1.00", "0.01", "%.0f%%", nullptr, 100.0f},*/
{PAD::ControllerSettingInfo::Type::Float, "PressureModifier", "Modifier Pressure", {PAD::ControllerSettingInfo::Type::Float, "PressureModifier", "Modifier Pressure",
"Sets the pressure when the modifier button is held.", "Sets the pressure when the modifier button is held.",
"0.50", "0.01", "1.00", "0.01", "%.0f%%", 100.0f}, "0.50", "0.01", "1.00", "0.01", "%.0f%%", nullptr, 100.0f},
}; };
static const PAD::ControllerInfo s_controller_info[] = { static const PAD::ControllerInfo s_controller_info[] = {
@ -523,8 +568,6 @@ void PAD::CopyConfiguration(SettingsInterface* dest_si, const SettingsInterface&
dest_si->CopyBoolValue(src_si, "Pad", "MultitapPort2"); dest_si->CopyBoolValue(src_si, "Pad", "MultitapPort2");
dest_si->CopyFloatValue(src_si, "Pad", "PointerXScale"); dest_si->CopyFloatValue(src_si, "Pad", "PointerXScale");
dest_si->CopyFloatValue(src_si, "Pad", "PointerYScale"); dest_si->CopyFloatValue(src_si, "Pad", "PointerYScale");
dest_si->CopyBoolValue(src_si, "Pad", "PointerXInvert");
dest_si->CopyBoolValue(src_si, "Pad", "PointerYInvert");
for (u32 i = 0; i < static_cast<u32>(InputSourceType::Count); i++) for (u32 i = 0; i < static_cast<u32>(InputSourceType::Count); i++)
{ {
dest_si->CopyBoolValue(src_si, "InputSources", dest_si->CopyBoolValue(src_si, "InputSources",
@ -571,6 +614,30 @@ void PAD::CopyConfiguration(SettingsInterface* dest_si, const SettingsInterface&
dest_si->CopyFloatValue(src_si, section.c_str(), "LargeMotorScale"); dest_si->CopyFloatValue(src_si, section.c_str(), "LargeMotorScale");
dest_si->CopyFloatValue(src_si, section.c_str(), "SmallMotorScale"); dest_si->CopyFloatValue(src_si, section.c_str(), "SmallMotorScale");
} }
for (u32 i = 0; i < info->num_settings; i++)
{
const ControllerSettingInfo& csi = info->settings[i];
switch (csi.type)
{
case ControllerSettingInfo::Type::Boolean:
dest_si->CopyBoolValue(src_si, section.c_str(), csi.name);
break;
case ControllerSettingInfo::Type::Integer:
case ControllerSettingInfo::Type::IntegerList:
dest_si->CopyIntValue(src_si, section.c_str(), csi.name);
break;
case ControllerSettingInfo::Type::Float:
dest_si->CopyFloatValue(src_si, section.c_str(), csi.name);
break;
case ControllerSettingInfo::Type::String:
case ControllerSettingInfo::Type::Path:
dest_si->CopyStringValue(src_si, section.c_str(), csi.name);
break;
default:
break;
}
}
} }
} }

View File

@ -77,6 +77,7 @@ namespace PAD
{ {
Boolean, Boolean,
Integer, Integer,
IntegerList,
Float, Float,
String, String,
Path, Path,
@ -91,6 +92,7 @@ namespace PAD
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;
@ -129,6 +131,7 @@ namespace PAD
static constexpr float DEFAULT_STICK_SCALE = 1.33f; static constexpr float DEFAULT_STICK_SCALE = 1.33f;
static constexpr float DEFAULT_MOTOR_SCALE = 1.0f; static constexpr float DEFAULT_MOTOR_SCALE = 1.0f;
static constexpr float DEFAULT_PRESSURE_MODIFIER = 0.5f; static constexpr float DEFAULT_PRESSURE_MODIFIER = 0.5f;
static constexpr float DEFAULT_BUTTON_DEADZONE = 0.0f;
/// Returns the default type for the specified port. /// Returns the default type for the specified port.
const char* GetDefaultPadType(u32 pad); const char* GetDefaultPadType(u32 pad);