From 5096ff64968435e823e2d4afe963a2cf998d7672 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 25 Dec 2020 22:21:20 -0600 Subject: [PATCH] Add options to invert scroll direction and swap gamepad buttons Fixes #463 Fixes #467 --- app/cli/commandlineparser.cpp | 10 +++++++- app/gui/SettingsView.qml | 36 +++++++++++++++++++++++++++ app/gui/sdlgamepadkeynavigation.cpp | 20 +++++++++++++++ app/settings/streamingpreferences.cpp | 6 +++++ app/settings/streamingpreferences.h | 6 +++++ app/streaming/input/gamepad.cpp | 17 +++++++++++++ app/streaming/input/input.cpp | 2 ++ app/streaming/input/input.h | 2 ++ app/streaming/input/mouse.cpp | 5 ++++ 9 files changed, 103 insertions(+), 1 deletion(-) diff --git a/app/cli/commandlineparser.cpp b/app/cli/commandlineparser.cpp index cf01d175..9c1d62aa 100644 --- a/app/cli/commandlineparser.cpp +++ b/app/cli/commandlineparser.cpp @@ -303,8 +303,10 @@ void StreamCommandLineParser::parse(const QStringList &args, StreamingPreference parser.addToggleOption("game-optimization", "game optimizations"); parser.addToggleOption("audio-on-host", "audio on host PC"); parser.addToggleOption("frame-pacing", "frame pacing"); - parser.addToggleOption("mute-on-minimize", "mute audio whe minimized"); + parser.addToggleOption("mute-on-minimize", "mute audio when minimized"); parser.addToggleOption("background-gamepad", "background gamepad input"); + parser.addToggleOption("reverse-scroll-direction", "inverted scroll direction"); + parser.addToggleOption("swap-gamepad-buttons", "swap A/B and X/Y gamepad buttons (Nintendo-style)"); parser.addChoiceOption("video-codec", "video codec", m_VideoCodecMap.keys()); parser.addChoiceOption("video-decoder", "video decoder", m_VideoDecoderMap.keys()); @@ -413,6 +415,12 @@ void StreamCommandLineParser::parse(const QStringList &args, StreamingPreference // Resolve --background-gamepad and --no-background-gamepad options preferences->backgroundGamepad = parser.getToggleOptionValue("background-gamepad", preferences->backgroundGamepad); + // Resolve --reverse-scroll-direction and --no-reverse-scroll-direction options + preferences->reverseScrollDirection = parser.getToggleOptionValue("reverse-scroll-direction", preferences->reverseScrollDirection); + + // Resolve --swap-gamepad-buttons and --no-swap-gamepad-buttons options + preferences->swapFaceButtons = parser.getToggleOptionValue("swap-gamepad-buttons", preferences->swapFaceButtons); + // Resolve --video-codec option if (parser.isSet("video-codec")) { preferences->videoCodecConfig = mapValue(m_VideoCodecMap, parser.getChoiceOptionValue("video-codec")); diff --git a/app/gui/SettingsView.qml b/app/gui/SettingsView.qml index 88b6377d..ced83250 100644 --- a/app/gui/SettingsView.qml +++ b/app/gui/SettingsView.qml @@ -817,6 +817,18 @@ Flickable { StreamingPreferences.swapMouseButtons = checked } } + + CheckBox { + id: reverseScrollButtonsCheck + hoverEnabled: true + width: parent.width + text: qsTr("Reverse mouse scrolling direction") + font.pointSize: 12 + checked: StreamingPreferences.reverseScrollDirection + onCheckedChanged: { + StreamingPreferences.reverseScrollDirection = checked + } + } } } @@ -831,6 +843,30 @@ Flickable { anchors.fill: parent spacing: 5 + CheckBox { + id: swapFaceButtonsCheck + width: parent.width + text: qsTr("Swap A/B and X/Y gamepad buttons") + font.pointSize: 12 + checked: StreamingPreferences.swapFaceButtons + onCheckedChanged: { + // Check if the value changed (this is called on init too) + if (StreamingPreferences.swapFaceButtons !== checked) { + StreamingPreferences.swapFaceButtons = checked + + // Save and restart SdlGamepadKeyNavigation so it can pull the new value + StreamingPreferences.save() + SdlGamepadKeyNavigation.disable() + SdlGamepadKeyNavigation.enable() + } + } + + ToolTip.delay: 1000 + ToolTip.timeout: 5000 + ToolTip.visible: hovered + ToolTip.text: qsTr("This switches gamepads into a Nintendo-style button layout") + } + CheckBox { id: singleControllerCheck width: parent.width diff --git a/app/gui/sdlgamepadkeynavigation.cpp b/app/gui/sdlgamepadkeynavigation.cpp index a6001485..006032b7 100644 --- a/app/gui/sdlgamepadkeynavigation.cpp +++ b/app/gui/sdlgamepadkeynavigation.cpp @@ -4,6 +4,7 @@ #include #include +#include "settings/streamingpreferences.h" #include "settings/mappingmanager.h" #define AXIS_NAVIGATION_REPEAT_DELAY 150 @@ -88,6 +89,7 @@ void SdlGamepadKeyNavigation::disable() void SdlGamepadKeyNavigation::onPollingTimerFired() { SDL_Event event; + StreamingPreferences prefs; while (SDL_PollEvent(&event)) { switch (event.type) { @@ -104,6 +106,24 @@ void SdlGamepadKeyNavigation::onPollingTimerFired() event.type == SDL_CONTROLLERBUTTONDOWN ? QEvent::Type::KeyPress : QEvent::Type::KeyRelease; + // Swap face buttons if needed + if (prefs.swapFaceButtons) { + switch (event.cbutton.button) { + case SDL_CONTROLLER_BUTTON_A: + event.cbutton.button = SDL_CONTROLLER_BUTTON_B; + break; + case SDL_CONTROLLER_BUTTON_B: + event.cbutton.button = SDL_CONTROLLER_BUTTON_A; + break; + case SDL_CONTROLLER_BUTTON_X: + event.cbutton.button = SDL_CONTROLLER_BUTTON_Y; + break; + case SDL_CONTROLLER_BUTTON_Y: + event.cbutton.button = SDL_CONTROLLER_BUTTON_X; + break; + } + } + switch (event.cbutton.button) { case SDL_CONTROLLER_BUTTON_DPAD_UP: if (m_UiNavMode) { diff --git a/app/settings/streamingpreferences.cpp b/app/settings/streamingpreferences.cpp index aacfd04d..5ec67702 100644 --- a/app/settings/streamingpreferences.cpp +++ b/app/settings/streamingpreferences.cpp @@ -32,6 +32,8 @@ #define SER_SWAPMOUSEBUTTONS "swapmousebuttons" #define SER_MUTEONMINIMIZE "muteonminimize" #define SER_BACKGROUNDGAMEPAD "backgroundgamepad" +#define SER_REVERSESCROLL "reversescroll" +#define SER_SWAPFACEBUTTONS "swapfacebuttons" #define CURRENT_DEFAULT_VER 1 @@ -76,6 +78,8 @@ void StreamingPreferences::reload() swapMouseButtons = settings.value(SER_SWAPMOUSEBUTTONS, false).toBool(); muteOnMinimize = settings.value(SER_MUTEONMINIMIZE, false).toBool(); backgroundGamepad = settings.value(SER_BACKGROUNDGAMEPAD, false).toBool(); + reverseScrollDirection = settings.value(SER_REVERSESCROLL, false).toBool(); + swapFaceButtons = settings.value(SER_SWAPFACEBUTTONS, false).toBool(); audioConfig = static_cast(settings.value(SER_AUDIOCFG, static_cast(AudioConfig::AC_STEREO)).toInt()); videoCodecConfig = static_cast(settings.value(SER_VIDEOCFG, @@ -130,6 +134,8 @@ void StreamingPreferences::save() settings.setValue(SER_SWAPMOUSEBUTTONS, swapMouseButtons); settings.setValue(SER_MUTEONMINIMIZE, muteOnMinimize); settings.setValue(SER_BACKGROUNDGAMEPAD, backgroundGamepad); + settings.setValue(SER_REVERSESCROLL, reverseScrollDirection); + settings.setValue(SER_SWAPFACEBUTTONS, swapFaceButtons); } int StreamingPreferences::getDefaultBitrate(int width, int height, int fps) diff --git a/app/settings/streamingpreferences.h b/app/settings/streamingpreferences.h index 8504b189..05dd235c 100644 --- a/app/settings/streamingpreferences.h +++ b/app/settings/streamingpreferences.h @@ -77,6 +77,8 @@ public: Q_PROPERTY(bool swapMouseButtons MEMBER swapMouseButtons NOTIFY mouseButtonsChanged) Q_PROPERTY(bool muteOnMinimize MEMBER muteOnMinimize NOTIFY muteOnMinimizeChanged) Q_PROPERTY(bool backgroundGamepad MEMBER backgroundGamepad NOTIFY backgroundGamepadChanged) + Q_PROPERTY(bool reverseScrollDirection MEMBER reverseScrollDirection NOTIFY reverseScrollDirectionChanged) + Q_PROPERTY(bool swapFaceButtons MEMBER swapFaceButtons NOTIFY swapFaceButtonsChanged) // Directly accessible members for preferences int width; @@ -101,6 +103,8 @@ public: bool swapMouseButtons; bool muteOnMinimize; bool backgroundGamepad; + bool reverseScrollDirection; + bool swapFaceButtons; int packetSize; AudioConfig audioConfig; VideoCodecConfig videoCodecConfig; @@ -133,5 +137,7 @@ signals: void mouseButtonsChanged(); void muteOnMinimizeChanged(); void backgroundGamepadChanged(); + void reverseScrollDirectionChanged(); + void swapFaceButtonsChanged(); }; diff --git a/app/streaming/input/gamepad.cpp b/app/streaming/input/gamepad.cpp index 2c2ed981..7968e3fc 100644 --- a/app/streaming/input/gamepad.cpp +++ b/app/streaming/input/gamepad.cpp @@ -167,6 +167,23 @@ void SdlInputHandler::handleControllerButtonEvent(SDL_ControllerButtonEvent* eve return; } + if (m_SwapFaceButtons) { + switch (event->button) { + case SDL_CONTROLLER_BUTTON_A: + event->button = SDL_CONTROLLER_BUTTON_B; + break; + case SDL_CONTROLLER_BUTTON_B: + event->button = SDL_CONTROLLER_BUTTON_A; + break; + case SDL_CONTROLLER_BUTTON_X: + event->button = SDL_CONTROLLER_BUTTON_Y; + break; + case SDL_CONTROLLER_BUTTON_Y: + event->button = SDL_CONTROLLER_BUTTON_X; + break; + } + } + if (event->state == SDL_PRESSED) { state->buttons |= k_ButtonMap[event->button]; diff --git a/app/streaming/input/input.cpp b/app/streaming/input/input.cpp index 3428e50d..6bd106ee 100644 --- a/app/streaming/input/input.cpp +++ b/app/streaming/input/input.cpp @@ -13,6 +13,8 @@ SdlInputHandler::SdlInputHandler(StreamingPreferences& prefs, NvComputer*, int s : m_MultiController(prefs.multiController), m_GamepadMouse(prefs.gamepadMouse), m_SwapMouseButtons(prefs.swapMouseButtons), + m_ReverseScrollDirection(prefs.reverseScrollDirection), + m_SwapFaceButtons(prefs.swapFaceButtons), m_MouseMoveTimer(0), m_MousePositionLock(0), m_MouseWasInVideoRegion(false), diff --git a/app/streaming/input/input.h b/app/streaming/input/input.h index 495db017..6b183f18 100644 --- a/app/streaming/input/input.h +++ b/app/streaming/input/input.h @@ -121,6 +121,8 @@ private: bool m_MultiController; bool m_GamepadMouse; bool m_SwapMouseButtons; + bool m_ReverseScrollDirection; + bool m_SwapFaceButtons; SDL_TimerID m_MouseMoveTimer; SDL_atomic_t m_MouseDeltaX; SDL_atomic_t m_MouseDeltaY; diff --git a/app/streaming/input/mouse.cpp b/app/streaming/input/mouse.cpp index eb578c3c..80650de6 100644 --- a/app/streaming/input/mouse.cpp +++ b/app/streaming/input/mouse.cpp @@ -204,6 +204,11 @@ void SdlInputHandler::handleMouseWheelEvent(SDL_MouseWheelEvent* event) } if (event->y != 0) { + // Invert the scroll direction if needed + if (m_ReverseScrollDirection) { + event->y = -event->y; + } + LiSendScrollEvent((signed char)event->y); } }