mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-06-17 14:11:33 +00:00
Add options to invert scroll direction and swap gamepad buttons
Fixes #463 Fixes #467
This commit is contained in:
@@ -303,8 +303,10 @@ void StreamCommandLineParser::parse(const QStringList &args, StreamingPreference
|
|||||||
parser.addToggleOption("game-optimization", "game optimizations");
|
parser.addToggleOption("game-optimization", "game optimizations");
|
||||||
parser.addToggleOption("audio-on-host", "audio on host PC");
|
parser.addToggleOption("audio-on-host", "audio on host PC");
|
||||||
parser.addToggleOption("frame-pacing", "frame pacing");
|
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("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-codec", "video codec", m_VideoCodecMap.keys());
|
||||||
parser.addChoiceOption("video-decoder", "video decoder", m_VideoDecoderMap.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
|
// Resolve --background-gamepad and --no-background-gamepad options
|
||||||
preferences->backgroundGamepad = parser.getToggleOptionValue("background-gamepad", preferences->backgroundGamepad);
|
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
|
// Resolve --video-codec option
|
||||||
if (parser.isSet("video-codec")) {
|
if (parser.isSet("video-codec")) {
|
||||||
preferences->videoCodecConfig = mapValue(m_VideoCodecMap, parser.getChoiceOptionValue("video-codec"));
|
preferences->videoCodecConfig = mapValue(m_VideoCodecMap, parser.getChoiceOptionValue("video-codec"));
|
||||||
|
|||||||
@@ -817,6 +817,18 @@ Flickable {
|
|||||||
StreamingPreferences.swapMouseButtons = checked
|
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
|
anchors.fill: parent
|
||||||
spacing: 5
|
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 {
|
CheckBox {
|
||||||
id: singleControllerCheck
|
id: singleControllerCheck
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QWindow>
|
#include <QWindow>
|
||||||
|
|
||||||
|
#include "settings/streamingpreferences.h"
|
||||||
#include "settings/mappingmanager.h"
|
#include "settings/mappingmanager.h"
|
||||||
|
|
||||||
#define AXIS_NAVIGATION_REPEAT_DELAY 150
|
#define AXIS_NAVIGATION_REPEAT_DELAY 150
|
||||||
@@ -88,6 +89,7 @@ void SdlGamepadKeyNavigation::disable()
|
|||||||
void SdlGamepadKeyNavigation::onPollingTimerFired()
|
void SdlGamepadKeyNavigation::onPollingTimerFired()
|
||||||
{
|
{
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
|
StreamingPreferences prefs;
|
||||||
|
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
@@ -104,6 +106,24 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
|
|||||||
event.type == SDL_CONTROLLERBUTTONDOWN ?
|
event.type == SDL_CONTROLLERBUTTONDOWN ?
|
||||||
QEvent::Type::KeyPress : QEvent::Type::KeyRelease;
|
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) {
|
switch (event.cbutton.button) {
|
||||||
case SDL_CONTROLLER_BUTTON_DPAD_UP:
|
case SDL_CONTROLLER_BUTTON_DPAD_UP:
|
||||||
if (m_UiNavMode) {
|
if (m_UiNavMode) {
|
||||||
|
|||||||
@@ -32,6 +32,8 @@
|
|||||||
#define SER_SWAPMOUSEBUTTONS "swapmousebuttons"
|
#define SER_SWAPMOUSEBUTTONS "swapmousebuttons"
|
||||||
#define SER_MUTEONMINIMIZE "muteonminimize"
|
#define SER_MUTEONMINIMIZE "muteonminimize"
|
||||||
#define SER_BACKGROUNDGAMEPAD "backgroundgamepad"
|
#define SER_BACKGROUNDGAMEPAD "backgroundgamepad"
|
||||||
|
#define SER_REVERSESCROLL "reversescroll"
|
||||||
|
#define SER_SWAPFACEBUTTONS "swapfacebuttons"
|
||||||
|
|
||||||
#define CURRENT_DEFAULT_VER 1
|
#define CURRENT_DEFAULT_VER 1
|
||||||
|
|
||||||
@@ -76,6 +78,8 @@ void StreamingPreferences::reload()
|
|||||||
swapMouseButtons = settings.value(SER_SWAPMOUSEBUTTONS, false).toBool();
|
swapMouseButtons = settings.value(SER_SWAPMOUSEBUTTONS, false).toBool();
|
||||||
muteOnMinimize = settings.value(SER_MUTEONMINIMIZE, false).toBool();
|
muteOnMinimize = settings.value(SER_MUTEONMINIMIZE, false).toBool();
|
||||||
backgroundGamepad = settings.value(SER_BACKGROUNDGAMEPAD, 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<AudioConfig>(settings.value(SER_AUDIOCFG,
|
audioConfig = static_cast<AudioConfig>(settings.value(SER_AUDIOCFG,
|
||||||
static_cast<int>(AudioConfig::AC_STEREO)).toInt());
|
static_cast<int>(AudioConfig::AC_STEREO)).toInt());
|
||||||
videoCodecConfig = static_cast<VideoCodecConfig>(settings.value(SER_VIDEOCFG,
|
videoCodecConfig = static_cast<VideoCodecConfig>(settings.value(SER_VIDEOCFG,
|
||||||
@@ -130,6 +134,8 @@ void StreamingPreferences::save()
|
|||||||
settings.setValue(SER_SWAPMOUSEBUTTONS, swapMouseButtons);
|
settings.setValue(SER_SWAPMOUSEBUTTONS, swapMouseButtons);
|
||||||
settings.setValue(SER_MUTEONMINIMIZE, muteOnMinimize);
|
settings.setValue(SER_MUTEONMINIMIZE, muteOnMinimize);
|
||||||
settings.setValue(SER_BACKGROUNDGAMEPAD, backgroundGamepad);
|
settings.setValue(SER_BACKGROUNDGAMEPAD, backgroundGamepad);
|
||||||
|
settings.setValue(SER_REVERSESCROLL, reverseScrollDirection);
|
||||||
|
settings.setValue(SER_SWAPFACEBUTTONS, swapFaceButtons);
|
||||||
}
|
}
|
||||||
|
|
||||||
int StreamingPreferences::getDefaultBitrate(int width, int height, int fps)
|
int StreamingPreferences::getDefaultBitrate(int width, int height, int fps)
|
||||||
|
|||||||
@@ -77,6 +77,8 @@ public:
|
|||||||
Q_PROPERTY(bool swapMouseButtons MEMBER swapMouseButtons NOTIFY mouseButtonsChanged)
|
Q_PROPERTY(bool swapMouseButtons MEMBER swapMouseButtons NOTIFY mouseButtonsChanged)
|
||||||
Q_PROPERTY(bool muteOnMinimize MEMBER muteOnMinimize NOTIFY muteOnMinimizeChanged)
|
Q_PROPERTY(bool muteOnMinimize MEMBER muteOnMinimize NOTIFY muteOnMinimizeChanged)
|
||||||
Q_PROPERTY(bool backgroundGamepad MEMBER backgroundGamepad NOTIFY backgroundGamepadChanged)
|
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
|
// Directly accessible members for preferences
|
||||||
int width;
|
int width;
|
||||||
@@ -101,6 +103,8 @@ public:
|
|||||||
bool swapMouseButtons;
|
bool swapMouseButtons;
|
||||||
bool muteOnMinimize;
|
bool muteOnMinimize;
|
||||||
bool backgroundGamepad;
|
bool backgroundGamepad;
|
||||||
|
bool reverseScrollDirection;
|
||||||
|
bool swapFaceButtons;
|
||||||
int packetSize;
|
int packetSize;
|
||||||
AudioConfig audioConfig;
|
AudioConfig audioConfig;
|
||||||
VideoCodecConfig videoCodecConfig;
|
VideoCodecConfig videoCodecConfig;
|
||||||
@@ -133,5 +137,7 @@ signals:
|
|||||||
void mouseButtonsChanged();
|
void mouseButtonsChanged();
|
||||||
void muteOnMinimizeChanged();
|
void muteOnMinimizeChanged();
|
||||||
void backgroundGamepadChanged();
|
void backgroundGamepadChanged();
|
||||||
|
void reverseScrollDirectionChanged();
|
||||||
|
void swapFaceButtonsChanged();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -167,6 +167,23 @@ void SdlInputHandler::handleControllerButtonEvent(SDL_ControllerButtonEvent* eve
|
|||||||
return;
|
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) {
|
if (event->state == SDL_PRESSED) {
|
||||||
state->buttons |= k_ButtonMap[event->button];
|
state->buttons |= k_ButtonMap[event->button];
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ SdlInputHandler::SdlInputHandler(StreamingPreferences& prefs, NvComputer*, int s
|
|||||||
: m_MultiController(prefs.multiController),
|
: m_MultiController(prefs.multiController),
|
||||||
m_GamepadMouse(prefs.gamepadMouse),
|
m_GamepadMouse(prefs.gamepadMouse),
|
||||||
m_SwapMouseButtons(prefs.swapMouseButtons),
|
m_SwapMouseButtons(prefs.swapMouseButtons),
|
||||||
|
m_ReverseScrollDirection(prefs.reverseScrollDirection),
|
||||||
|
m_SwapFaceButtons(prefs.swapFaceButtons),
|
||||||
m_MouseMoveTimer(0),
|
m_MouseMoveTimer(0),
|
||||||
m_MousePositionLock(0),
|
m_MousePositionLock(0),
|
||||||
m_MouseWasInVideoRegion(false),
|
m_MouseWasInVideoRegion(false),
|
||||||
|
|||||||
@@ -121,6 +121,8 @@ private:
|
|||||||
bool m_MultiController;
|
bool m_MultiController;
|
||||||
bool m_GamepadMouse;
|
bool m_GamepadMouse;
|
||||||
bool m_SwapMouseButtons;
|
bool m_SwapMouseButtons;
|
||||||
|
bool m_ReverseScrollDirection;
|
||||||
|
bool m_SwapFaceButtons;
|
||||||
SDL_TimerID m_MouseMoveTimer;
|
SDL_TimerID m_MouseMoveTimer;
|
||||||
SDL_atomic_t m_MouseDeltaX;
|
SDL_atomic_t m_MouseDeltaX;
|
||||||
SDL_atomic_t m_MouseDeltaY;
|
SDL_atomic_t m_MouseDeltaY;
|
||||||
|
|||||||
@@ -204,6 +204,11 @@ void SdlInputHandler::handleMouseWheelEvent(SDL_MouseWheelEvent* event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (event->y != 0) {
|
if (event->y != 0) {
|
||||||
|
// Invert the scroll direction if needed
|
||||||
|
if (m_ReverseScrollDirection) {
|
||||||
|
event->y = -event->y;
|
||||||
|
}
|
||||||
|
|
||||||
LiSendScrollEvent((signed char)event->y);
|
LiSendScrollEvent((signed char)event->y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user