diff options
| -rw-r--r-- | src/input_common/sdl/sdl_impl.cpp | 25 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_input_player.cpp | 23 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_input_player.h | 2 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_input_player.ui | 63 |
4 files changed, 99 insertions, 14 deletions
diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp index 675b477fa..20a658a26 100644 --- a/src/input_common/sdl/sdl_impl.cpp +++ b/src/input_common/sdl/sdl_impl.cpp | |||
| @@ -66,14 +66,14 @@ public: | |||
| 66 | state.axes.insert_or_assign(axis, value); | 66 | state.axes.insert_or_assign(axis, value); |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | float GetAxis(int axis) const { | 69 | float GetAxis(int axis, float range) const { |
| 70 | std::lock_guard lock{mutex}; | 70 | std::lock_guard lock{mutex}; |
| 71 | return state.axes.at(axis) / 32767.0f; | 71 | return state.axes.at(axis) / (32767.0f * range); |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | std::tuple<float, float> GetAnalog(int axis_x, int axis_y) const { | 74 | std::tuple<float, float> GetAnalog(int axis_x, int axis_y, float range) const { |
| 75 | float x = GetAxis(axis_x); | 75 | float x = GetAxis(axis_x, range); |
| 76 | float y = GetAxis(axis_y); | 76 | float y = GetAxis(axis_y, range); |
| 77 | y = -y; // 3DS uses an y-axis inverse from SDL | 77 | y = -y; // 3DS uses an y-axis inverse from SDL |
| 78 | 78 | ||
| 79 | // Make sure the coordinates are in the unit circle, | 79 | // Make sure the coordinates are in the unit circle, |
| @@ -313,7 +313,7 @@ public: | |||
| 313 | trigger_if_greater(trigger_if_greater_) {} | 313 | trigger_if_greater(trigger_if_greater_) {} |
| 314 | 314 | ||
| 315 | bool GetStatus() const override { | 315 | bool GetStatus() const override { |
| 316 | const float axis_value = joystick->GetAxis(axis); | 316 | const float axis_value = joystick->GetAxis(axis, 1.0f); |
| 317 | if (trigger_if_greater) { | 317 | if (trigger_if_greater) { |
| 318 | return axis_value > threshold; | 318 | return axis_value > threshold; |
| 319 | } | 319 | } |
| @@ -329,11 +329,13 @@ private: | |||
| 329 | 329 | ||
| 330 | class SDLAnalog final : public Input::AnalogDevice { | 330 | class SDLAnalog final : public Input::AnalogDevice { |
| 331 | public: | 331 | public: |
| 332 | SDLAnalog(std::shared_ptr<SDLJoystick> joystick_, int axis_x_, int axis_y_, float deadzone_) | 332 | SDLAnalog(std::shared_ptr<SDLJoystick> joystick_, int axis_x_, int axis_y_, float deadzone_, |
| 333 | : joystick(std::move(joystick_)), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_) {} | 333 | float range_) |
| 334 | : joystick(std::move(joystick_)), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_), | ||
| 335 | range(range_) {} | ||
| 334 | 336 | ||
| 335 | std::tuple<float, float> GetStatus() const override { | 337 | std::tuple<float, float> GetStatus() const override { |
| 336 | const auto [x, y] = joystick->GetAnalog(axis_x, axis_y); | 338 | const auto [x, y] = joystick->GetAnalog(axis_x, axis_y, range); |
| 337 | const float r = std::sqrt((x * x) + (y * y)); | 339 | const float r = std::sqrt((x * x) + (y * y)); |
| 338 | if (r > deadzone) { | 340 | if (r > deadzone) { |
| 339 | return std::make_tuple(x / r * (r - deadzone) / (1 - deadzone), | 341 | return std::make_tuple(x / r * (r - deadzone) / (1 - deadzone), |
| @@ -363,6 +365,7 @@ private: | |||
| 363 | const int axis_x; | 365 | const int axis_x; |
| 364 | const int axis_y; | 366 | const int axis_y; |
| 365 | const float deadzone; | 367 | const float deadzone; |
| 368 | const float range; | ||
| 366 | }; | 369 | }; |
| 367 | 370 | ||
| 368 | /// A button device factory that creates button devices from SDL joystick | 371 | /// A button device factory that creates button devices from SDL joystick |
| @@ -458,13 +461,13 @@ public: | |||
| 458 | const int axis_x = params.Get("axis_x", 0); | 461 | const int axis_x = params.Get("axis_x", 0); |
| 459 | const int axis_y = params.Get("axis_y", 1); | 462 | const int axis_y = params.Get("axis_y", 1); |
| 460 | const float deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, .99f); | 463 | const float deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, .99f); |
| 461 | 464 | const float range = std::clamp(params.Get("range", 0.0f), 0.0f, .99f) + 0.50f; | |
| 462 | auto joystick = state.GetSDLJoystickByGUID(guid, port); | 465 | auto joystick = state.GetSDLJoystickByGUID(guid, port); |
| 463 | 466 | ||
| 464 | // This is necessary so accessing GetAxis with axis_x and axis_y won't crash | 467 | // This is necessary so accessing GetAxis with axis_x and axis_y won't crash |
| 465 | joystick->SetAxis(axis_x, 0); | 468 | joystick->SetAxis(axis_x, 0); |
| 466 | joystick->SetAxis(axis_y, 0); | 469 | joystick->SetAxis(axis_y, 0); |
| 467 | return std::make_unique<SDLAnalog>(joystick, axis_x, axis_y, deadzone); | 470 | return std::make_unique<SDLAnalog>(joystick, axis_x, axis_y, deadzone, range); |
| 468 | } | 471 | } |
| 469 | 472 | ||
| 470 | private: | 473 | private: |
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index b1850bc95..d60f13ffb 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp | |||
| @@ -272,6 +272,8 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i | |||
| 272 | ui->sliderRStickDeadzoneAndModifier}; | 272 | ui->sliderRStickDeadzoneAndModifier}; |
| 273 | analog_map_deadzone_and_modifier_slider_label = {ui->labelLStickDeadzoneAndModifier, | 273 | analog_map_deadzone_and_modifier_slider_label = {ui->labelLStickDeadzoneAndModifier, |
| 274 | ui->labelRStickDeadzoneAndModifier}; | 274 | ui->labelRStickDeadzoneAndModifier}; |
| 275 | analog_map_range_slider = {ui->sliderLStickRange, ui->sliderRStickRange}; | ||
| 276 | analog_map_range_slider_label = {ui->labelLStickRange, ui->labelRStickRange}; | ||
| 275 | 277 | ||
| 276 | for (int button_id = 0; button_id < Settings::NativeButton::NumButtons; button_id++) { | 278 | for (int button_id = 0; button_id < Settings::NativeButton::NumButtons; button_id++) { |
| 277 | auto* const button = button_map[button_id]; | 279 | auto* const button = button_map[button_id]; |
| @@ -364,7 +366,6 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i | |||
| 364 | InputCommon::Polling::DeviceType::Analog); | 366 | InputCommon::Polling::DeviceType::Analog); |
| 365 | } | 367 | } |
| 366 | }); | 368 | }); |
| 367 | |||
| 368 | connect(analog_map_deadzone_and_modifier_slider[analog_id], &QSlider::valueChanged, | 369 | connect(analog_map_deadzone_and_modifier_slider[analog_id], &QSlider::valueChanged, |
| 369 | [=, this] { | 370 | [=, this] { |
| 370 | const float slider_value = | 371 | const float slider_value = |
| @@ -380,6 +381,15 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i | |||
| 380 | analogs_param[analog_id].Set("modifier_scale", slider_value / 100.0f); | 381 | analogs_param[analog_id].Set("modifier_scale", slider_value / 100.0f); |
| 381 | } | 382 | } |
| 382 | }); | 383 | }); |
| 384 | connect(analog_map_range_slider[analog_id], &QSlider::valueChanged, [=, this] { | ||
| 385 | const float slider_value = analog_map_range_slider[analog_id]->value(); | ||
| 386 | const auto engine = analogs_param[analog_id].Get("engine", ""); | ||
| 387 | if (engine == "sdl" || engine == "gcpad") { | ||
| 388 | analog_map_range_slider_label[analog_id]->setText( | ||
| 389 | tr("Range: %1%").arg(slider_value + 50.0f)); | ||
| 390 | analogs_param[analog_id].Set("range", slider_value / 100.0f); | ||
| 391 | } | ||
| 392 | }); | ||
| 383 | } | 393 | } |
| 384 | 394 | ||
| 385 | connect(ui->buttonClearAll, &QPushButton::clicked, [this] { ClearAll(); }); | 395 | connect(ui->buttonClearAll, &QPushButton::clicked, [this] { ClearAll(); }); |
| @@ -585,6 +595,9 @@ void ConfigureInputPlayer::UpdateButtonLabels() { | |||
| 585 | auto* const analog_stick_slider_label = | 595 | auto* const analog_stick_slider_label = |
| 586 | analog_map_deadzone_and_modifier_slider_label[analog_id]; | 596 | analog_map_deadzone_and_modifier_slider_label[analog_id]; |
| 587 | 597 | ||
| 598 | auto* const analog_stick_range = analog_map_range_slider[analog_id]; | ||
| 599 | auto* const analog_stick_range_label = analog_map_range_slider_label[analog_id]; | ||
| 600 | |||
| 588 | if (param.Has("engine")) { | 601 | if (param.Has("engine")) { |
| 589 | if (param.Get("engine", "") == "sdl" || param.Get("engine", "") == "gcpad") { | 602 | if (param.Get("engine", "") == "sdl" || param.Get("engine", "") == "gcpad") { |
| 590 | if (!param.Has("deadzone")) { | 603 | if (!param.Has("deadzone")) { |
| @@ -595,6 +608,14 @@ void ConfigureInputPlayer::UpdateButtonLabels() { | |||
| 595 | if (analog_stick_slider->value() == 0) { | 608 | if (analog_stick_slider->value() == 0) { |
| 596 | analog_stick_slider_label->setText(tr("Deadzone: 0%")); | 609 | analog_stick_slider_label->setText(tr("Deadzone: 0%")); |
| 597 | } | 610 | } |
| 611 | if (!param.Has("range")) { | ||
| 612 | param.Set("range", 0.50f); | ||
| 613 | } | ||
| 614 | |||
| 615 | analog_stick_range->setValue(static_cast<int>(param.Get("range", 0.1f) * 100)); | ||
| 616 | if (analog_stick_range->value() == 0) { | ||
| 617 | analog_stick_range_label->setText(tr("Range: 0%")); | ||
| 618 | } | ||
| 598 | } else { | 619 | } else { |
| 599 | if (!param.Has("modifier_scale")) { | 620 | if (!param.Has("modifier_scale")) { |
| 600 | param.Set("modifier_scale", 0.5f); | 621 | param.Set("modifier_scale", 0.5f); |
diff --git a/src/yuzu/configuration/configure_input_player.h b/src/yuzu/configuration/configure_input_player.h index 95afa5375..88cc3b3b1 100644 --- a/src/yuzu/configuration/configure_input_player.h +++ b/src/yuzu/configuration/configure_input_player.h | |||
| @@ -101,6 +101,8 @@ private: | |||
| 101 | analog_map_deadzone_and_modifier_slider; | 101 | analog_map_deadzone_and_modifier_slider; |
| 102 | std::array<QLabel*, Settings::NativeAnalog::NumAnalogs> | 102 | std::array<QLabel*, Settings::NativeAnalog::NumAnalogs> |
| 103 | analog_map_deadzone_and_modifier_slider_label; | 103 | analog_map_deadzone_and_modifier_slider_label; |
| 104 | std::array<QSlider*, Settings::NativeAnalog::NumAnalogs> analog_map_range_slider; | ||
| 105 | std::array<QLabel*, Settings::NativeAnalog::NumAnalogs> analog_map_range_slider_label; | ||
| 104 | 106 | ||
| 105 | static const std::array<std::string, ANALOG_SUB_BUTTONS_NUM> analog_sub_buttons; | 107 | static const std::array<std::string, ANALOG_SUB_BUTTONS_NUM> analog_sub_buttons; |
| 106 | 108 | ||
diff --git a/src/yuzu/configuration/configure_input_player.ui b/src/yuzu/configuration/configure_input_player.ui index f27a77180..c68c9228b 100644 --- a/src/yuzu/configuration/configure_input_player.ui +++ b/src/yuzu/configuration/configure_input_player.ui | |||
| @@ -195,7 +195,36 @@ | |||
| 195 | </item> | 195 | </item> |
| 196 | </layout> | 196 | </layout> |
| 197 | </item> | 197 | </item> |
| 198 | <item row="5" column="0"> | 198 | <item row="5" column="0" colspan="2"> |
| 199 | <layout class="QVBoxLayout" name="sliderRStickRangeVerticalLayout"> | ||
| 200 | <property name="sizeConstraint"> | ||
| 201 | <enum>QLayout::SetDefaultConstraint</enum> | ||
| 202 | </property> | ||
| 203 | <item> | ||
| 204 | <layout class="QHBoxLayout" name="sliderRStickRangeHorizontalLayout"> | ||
| 205 | <item> | ||
| 206 | <widget class="QLabel" name="labelRStickRange"> | ||
| 207 | <property name="text"> | ||
| 208 | <string>Range: 0</string> | ||
| 209 | </property> | ||
| 210 | <property name="alignment"> | ||
| 211 | <enum>Qt::AlignHCenter</enum> | ||
| 212 | </property> | ||
| 213 | </widget> | ||
| 214 | </item> | ||
| 215 | </layout> | ||
| 216 | </item> | ||
| 217 | <item> | ||
| 218 | <widget class="QSlider" name="sliderRStickRange"> | ||
| 219 | <property name="orientation"> | ||
| 220 | <enum>Qt::Horizontal</enum> | ||
| 221 | </property> | ||
| 222 | </widget> | ||
| 223 | </item> | ||
| 224 | </layout> | ||
| 225 | |||
| 226 | </item> | ||
| 227 | <item row="6" column="0"> | ||
| 199 | <spacer name="RStick_verticalSpacer"> | 228 | <spacer name="RStick_verticalSpacer"> |
| 200 | <property name="orientation"> | 229 | <property name="orientation"> |
| 201 | <enum>Qt::Vertical</enum> | 230 | <enum>Qt::Vertical</enum> |
| @@ -811,7 +840,37 @@ | |||
| 811 | </item> | 840 | </item> |
| 812 | </layout> | 841 | </layout> |
| 813 | </item> | 842 | </item> |
| 814 | <item row="6" column="1"> | 843 | |
| 844 | <item row="6" column="1" colspan="2"> | ||
| 845 | <layout class="QVBoxLayout" name="sliderLStickRangeVerticalLayout"> | ||
| 846 | <property name="sizeConstraint"> | ||
| 847 | <enum>QLayout::SetDefaultConstraint</enum> | ||
| 848 | </property> | ||
| 849 | <item> | ||
| 850 | <layout class="QHBoxLayout" name="sliderLStickRangeHorizontalLayout"> | ||
| 851 | <item> | ||
| 852 | <widget class="QLabel" name="labelLStickRange"> | ||
| 853 | <property name="text"> | ||
| 854 | <string>Range: 0</string> | ||
| 855 | </property> | ||
| 856 | <property name="alignment"> | ||
| 857 | <enum>Qt::AlignHCenter</enum> | ||
| 858 | </property> | ||
| 859 | </widget> | ||
| 860 | </item> | ||
| 861 | </layout> | ||
| 862 | </item> | ||
| 863 | <item> | ||
| 864 | <widget class="QSlider" name="sliderLStickRange"> | ||
| 865 | <property name="orientation"> | ||
| 866 | <enum>Qt::Horizontal</enum> | ||
| 867 | </property> | ||
| 868 | </widget> | ||
| 869 | </item> | ||
| 870 | </layout> | ||
| 871 | |||
| 872 | </item> | ||
| 873 | <item row="7" column="1"> | ||
| 815 | <spacer name="LStick_verticalSpacer"> | 874 | <spacer name="LStick_verticalSpacer"> |
| 816 | <property name="orientation"> | 875 | <property name="orientation"> |
| 817 | <enum>Qt::Vertical</enum> | 876 | <enum>Qt::Vertical</enum> |