From 80fece4e081323353399fe12a315e02925df778a Mon Sep 17 00:00:00 2001 From: german Date: Sat, 26 Dec 2020 12:17:22 -0600 Subject: [PATCH] Allow to invert analog axis with right click --- src/input_common/gcadapter/gc_poller.cpp | 28 ++++-- src/input_common/mouse/mouse_poller.cpp | 25 ++++-- src/input_common/sdl/sdl_impl.cpp | 26 ++++-- .../configuration/configure_input_player.cpp | 85 ++++++++----------- 4 files changed, 99 insertions(+), 65 deletions(-) diff --git a/src/input_common/gcadapter/gc_poller.cpp b/src/input_common/gcadapter/gc_poller.cpp index 4d1052414c..9670bdeb27 100644 --- a/src/input_common/gcadapter/gc_poller.cpp +++ b/src/input_common/gcadapter/gc_poller.cpp @@ -139,10 +139,10 @@ void GCButtonFactory::EndConfiguration() { class GCAnalog final : public Input::AnalogDevice { public: - explicit GCAnalog(u32 port_, u32 axis_x_, u32 axis_y_, float deadzone_, - const GCAdapter::Adapter* adapter, float range_) - : port(port_), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_), gcadapter(adapter), - range(range_) {} + explicit GCAnalog(u32 port_, u32 axis_x_, u32 axis_y_, bool invert_x_, bool invert_y_, + float deadzone_, float range_, const GCAdapter::Adapter* adapter) + : port(port_), axis_x(axis_x_), axis_y(axis_y_), invert_x(invert_x_), invert_y(invert_y_), + deadzone(deadzone_), range(range_), gcadapter(adapter) {} float GetAxis(u32 axis) const { if (gcadapter->DeviceConnected(port)) { @@ -157,7 +157,12 @@ public: std::pair GetAnalog(u32 analog_axis_x, u32 analog_axis_y) const { float x = GetAxis(analog_axis_x); float y = GetAxis(analog_axis_y); - + if (invert_x) { + x = -x; + } + if (invert_y) { + y = -y; + } // Make sure the coordinates are in the unit circle, // otherwise normalize it. float r = x * x + y * y; @@ -200,9 +205,11 @@ private: const u32 port; const u32 axis_x; const u32 axis_y; + const bool invert_x; + const bool invert_y; const float deadzone; - const GCAdapter::Adapter* gcadapter; const float range; + const GCAdapter::Adapter* gcadapter; mutable std::mutex mutex; }; @@ -223,8 +230,13 @@ std::unique_ptr GCAnalogFactory::Create(const Common::Param const auto axis_y = static_cast(params.Get("axis_y", 1)); const auto deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f); const auto range = std::clamp(params.Get("range", 1.0f), 0.50f, 1.50f); + const std::string invert_x_value = params.Get("invert_x", "+"); + const std::string invert_y_value = params.Get("invert_y", "+"); + const bool invert_x = invert_x_value == "-"; + const bool invert_y = invert_y_value == "-"; - return std::make_unique(port, axis_x, axis_y, deadzone, adapter.get(), range); + return std::make_unique(port, axis_x, axis_y, invert_x, invert_y, deadzone, range, + adapter.get()); } void GCAnalogFactory::BeginConfiguration() { @@ -282,6 +294,8 @@ Common::ParamPackage GCAnalogFactory::GetNextInput() { params.Set("port", controller_number); params.Set("axis_x", analog_x_axis); params.Set("axis_y", analog_y_axis); + params.Set("invert_x", "+"); + params.Set("invert_y", "+"); analog_x_axis = -1; analog_y_axis = -1; controller_number = -1; diff --git a/src/input_common/mouse/mouse_poller.cpp b/src/input_common/mouse/mouse_poller.cpp index 7445ad3ade..508eb0c7d6 100644 --- a/src/input_common/mouse/mouse_poller.cpp +++ b/src/input_common/mouse/mouse_poller.cpp @@ -62,10 +62,10 @@ void MouseButtonFactory::EndConfiguration() { class MouseAnalog final : public Input::AnalogDevice { public: - explicit MouseAnalog(u32 port_, u32 axis_x_, u32 axis_y_, float deadzone_, float range_, - const MouseInput::Mouse* mouse_input_) - : button(port_), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_), range(range_), - mouse_input(mouse_input_) {} + explicit MouseAnalog(u32 port_, u32 axis_x_, u32 axis_y_, bool invert_x_, bool invert_y_, + float deadzone_, float range_, const MouseInput::Mouse* mouse_input_) + : button(port_), axis_x(axis_x_), axis_y(axis_y_), invert_x(invert_x_), invert_y(invert_y_), + deadzone(deadzone_), range(range_), mouse_input(mouse_input_) {} float GetAxis(u32 axis) const { std::lock_guard lock{mutex}; @@ -77,6 +77,12 @@ public: std::pair GetAnalog(u32 analog_axis_x, u32 analog_axis_y) const { float x = GetAxis(analog_axis_x); float y = GetAxis(analog_axis_y); + if (invert_x) { + x = -x; + } + if (invert_y) { + y = -y; + } // Make sure the coordinates are in the unit circle, // otherwise normalize it. @@ -104,6 +110,8 @@ private: const u32 button; const u32 axis_x; const u32 axis_y; + const bool invert_x; + const bool invert_y; const float deadzone; const float range; const MouseInput::Mouse* mouse_input; @@ -128,8 +136,13 @@ std::unique_ptr MouseAnalogFactory::Create( const auto axis_y = static_cast(params.Get("axis_y", 1)); const auto deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f); const auto range = std::clamp(params.Get("range", 1.0f), 0.50f, 1.50f); + const std::string invert_x_value = params.Get("invert_x", "+"); + const std::string invert_y_value = params.Get("invert_y", "+"); + const bool invert_x = invert_x_value == "-"; + const bool invert_y = invert_y_value == "-"; - return std::make_unique(port, axis_x, axis_y, deadzone, range, mouse_input.get()); + return std::make_unique(port, axis_x, axis_y, invert_x, invert_y, deadzone, range, + mouse_input.get()); } void MouseAnalogFactory::BeginConfiguration() { @@ -153,6 +166,8 @@ Common::ParamPackage MouseAnalogFactory::GetNextInput() const { params.Set("port", static_cast(pad.button)); params.Set("axis_x", 0); params.Set("axis_y", 1); + params.Set("invert_x", "+"); + params.Set("invert_y", "+"); return params; } } diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp index 7827e324cb..0b531f6982 100644 --- a/src/input_common/sdl/sdl_impl.cpp +++ b/src/input_common/sdl/sdl_impl.cpp @@ -352,13 +352,20 @@ private: class SDLAnalog final : public Input::AnalogDevice { public: explicit SDLAnalog(std::shared_ptr joystick_, int axis_x_, int axis_y_, - float deadzone_, float range_) - : joystick(std::move(joystick_)), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_), - range(range_) {} + bool invert_x_, bool invert_y_, float deadzone_, float range_) + : joystick(std::move(joystick_)), axis_x(axis_x_), axis_y(axis_y_), invert_x(invert_x_), + invert_y(invert_y_), deadzone(deadzone_), range(range_) {} std::tuple GetStatus() const override { - const auto [x, y] = joystick->GetAnalog(axis_x, axis_y, range); + auto [x, y] = joystick->GetAnalog(axis_x, axis_y, range); const float r = std::sqrt((x * x) + (y * y)); + if (invert_x) { + x = -x; + } + if (invert_y) { + y = -y; + } + if (r > deadzone) { return std::make_tuple(x / r * (r - deadzone) / (1 - deadzone), y / r * (r - deadzone) / (1 - deadzone)); @@ -386,6 +393,8 @@ private: std::shared_ptr joystick; const int axis_x; const int axis_y; + const bool invert_x; + const bool invert_y; const float deadzone; const float range; }; @@ -572,12 +581,17 @@ public: const int axis_y = params.Get("axis_y", 1); const float deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f); const float range = std::clamp(params.Get("range", 1.0f), 0.50f, 1.50f); + const std::string invert_x_value = params.Get("invert_x", "+"); + const std::string invert_y_value = params.Get("invert_y", "+"); + const bool invert_x = invert_x_value == "-"; + const bool invert_y = invert_y_value == "-"; auto joystick = state.GetSDLJoystickByGUID(guid, port); // This is necessary so accessing GetAxis with axis_x and axis_y won't crash joystick->SetAxis(axis_x, 0); joystick->SetAxis(axis_y, 0); - return std::make_unique(joystick, axis_x, axis_y, deadzone, range); + return std::make_unique(joystick, axis_x, axis_y, invert_x, invert_y, deadzone, + range); } private: @@ -886,6 +900,8 @@ Common::ParamPackage BuildParamPackageForAnalog(int port, const std::string& gui params.Set("guid", guid); params.Set("axis_x", axis_x); params.Set("axis_y", axis_y); + params.Set("invert_x", "+"); + params.Set("invert_y", "+"); return params; } } // Anonymous namespace diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index f9915fb7a8..3c7500ee33 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -173,61 +173,31 @@ QString AnalogToText(const Common::ParamPackage& param, const std::string& dir) return ButtonToText(Common::ParamPackage{param.Get(dir, "")}); } - if (param.Get("engine", "") == "sdl") { + const auto engine_str = param.Get("engine", ""); + const QString axis_x_str = QString::fromStdString(param.Get("axis_x", "")); + const QString axis_y_str = QString::fromStdString(param.Get("axis_y", "")); + const bool invert_x = param.Get("invert_x", "+") == "-"; + const bool invert_y = param.Get("invert_y", "+") == "-"; + if (engine_str == "sdl" || engine_str == "gcpad" || engine_str == "mouse") { if (dir == "modifier") { return QObject::tr("[unused]"); } - if (dir == "left" || dir == "right") { - const QString axis_x_str = QString::fromStdString(param.Get("axis_x", "")); - - return QObject::tr("Axis %1").arg(axis_x_str); + if (dir == "left") { + const QString invert_x_str = QString::fromStdString(invert_x ? "+" : "-"); + return QObject::tr("Axis %1%2").arg(axis_x_str, invert_x_str); } - - if (dir == "up" || dir == "down") { - const QString axis_y_str = QString::fromStdString(param.Get("axis_y", "")); - - return QObject::tr("Axis %1").arg(axis_y_str); + if (dir == "right") { + const QString invert_x_str = QString::fromStdString(invert_x ? "-" : "+"); + return QObject::tr("Axis %1%2").arg(axis_x_str, invert_x_str); } - - return {}; - } - - if (param.Get("engine", "") == "gcpad") { - if (dir == "modifier") { - return QObject::tr("[unused]"); + if (dir == "up") { + const QString invert_y_str = QString::fromStdString(invert_y ? "-" : "+"); + return QObject::tr("Axis %1%2").arg(axis_y_str, invert_y_str); } - - if (dir == "left" || dir == "right") { - const QString axis_x_str = QString::fromStdString(param.Get("axis_x", "")); - - return QObject::tr("GC Axis %1").arg(axis_x_str); - } - - if (dir == "up" || dir == "down") { - const QString axis_y_str = QString::fromStdString(param.Get("axis_y", "")); - - return QObject::tr("GC Axis %1").arg(axis_y_str); - } - - return {}; - } - - if (param.Get("engine", "") == "mouse") { - if (dir == "modifier") { - return QObject::tr("[unused]"); - } - - if (dir == "left" || dir == "right") { - const QString axis_x_str = QString::fromStdString(param.Get("axis_x", "")); - - return QObject::tr("Mouse %1").arg(axis_x_str); - } - - if (dir == "up" || dir == "down") { - const QString axis_y_str = QString::fromStdString(param.Get("axis_y", "")); - - return QObject::tr("Mouse %1").arg(axis_y_str); + if (dir == "down") { + const QString invert_y_str = QString::fromStdString(invert_y ? "+" : "-"); + return QObject::tr("Axis %1%2").arg(axis_y_str, invert_y_str); } return {}; @@ -396,6 +366,25 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i analogs_param[analog_id].Clear(); analog_map_buttons[analog_id][sub_button_id]->setText(tr("[not set]")); }); + context_menu.addAction(tr("Invert axis"), [&] { + if (sub_button_id == 2 || sub_button_id == 3) { + const bool invert_value = + analogs_param[analog_id].Get("invert_x", "+") == "-"; + const std::string invert_str = invert_value ? "+" : "-"; + analogs_param[analog_id].Set("invert_x", invert_str); + } + if (sub_button_id == 0 || sub_button_id == 1) { + const bool invert_value = + analogs_param[analog_id].Get("invert_y", "+") == "-"; + const std::string invert_str = invert_value ? "+" : "-"; + analogs_param[analog_id].Set("invert_y", invert_str); + } + for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; + ++sub_button_id) { + analog_map_buttons[analog_id][sub_button_id]->setText(AnalogToText( + analogs_param[analog_id], analog_sub_buttons[sub_button_id])); + } + }); context_menu.exec(analog_map_buttons[analog_id][sub_button_id]->mapToGlobal( menu_location)); });