From b9e0b28adc7e2bf493d79aea5213c62dbf06e4bd Mon Sep 17 00:00:00 2001 From: IonBlade2K <20538376+IonBlade2K@users.noreply.github.com> Date: Thu, 21 Jul 2022 20:09:22 -0500 Subject: [PATCH] Add setting to swap A<->B and X<->Y buttons (#513) * Added toggle for swapping A<->B and X<->Y buttons to enable proper button mapping for combined Joy-Cons in iOS16, where iOS level remapping is not supported and pushing Switch B (bottom face button) sends Xbox B (right face button) instead of Xbox A (bottom face button), etc. Allows user to select between current behavior (button letter matches output) and muscle-memory behavior (face button pressed matches location of face button output) --- Limelight/Database/DataManager.h | 1 + Limelight/Database/DataManager.m | 2 + Limelight/Database/TemporarySettings.h | 1 + Limelight/Database/TemporarySettings.m | 2 + Limelight/Input/ControllerSupport.m | 34 ++++++--- .../Moonlight v1.7.xcdatamodel/contents | 5 +- Limelight/Stream/StreamConfiguration.h | 1 + Limelight/Stream/StreamConfiguration.m | 2 +- .../ViewControllers/MainFrameViewController.m | 3 +- .../ViewControllers/SettingsViewController.h | 1 + .../ViewControllers/SettingsViewController.m | 3 + iPad.storyboard | 72 ++++++++++++------- iPhone.storyboard | 44 ++++++++---- 13 files changed, 119 insertions(+), 52 deletions(-) diff --git a/Limelight/Database/DataManager.h b/Limelight/Database/DataManager.h index 24aeb035..d7d4d5ec 100644 --- a/Limelight/Database/DataManager.h +++ b/Limelight/Database/DataManager.h @@ -21,6 +21,7 @@ onscreenControls:(NSInteger)onscreenControls optimizeGames:(BOOL)optimizeGames multiController:(BOOL)multiController + swapABXYButtons:(BOOL)swapABXYButtons audioOnPC:(BOOL)audioOnPC useHevc:(BOOL)useHevc useFramePacing:(BOOL)useFramePacing diff --git a/Limelight/Database/DataManager.m b/Limelight/Database/DataManager.m index 57f3e63f..3b04c350 100644 --- a/Limelight/Database/DataManager.m +++ b/Limelight/Database/DataManager.m @@ -60,6 +60,7 @@ onscreenControls:(NSInteger)onscreenControls optimizeGames:(BOOL)optimizeGames multiController:(BOOL)multiController + swapABXYButtons:(BOOL)swapABXYButtons audioOnPC:(BOOL)audioOnPC useHevc:(BOOL)useHevc useFramePacing:(BOOL)useFramePacing @@ -78,6 +79,7 @@ settingsToSave.onscreenControls = [NSNumber numberWithInteger:onscreenControls]; settingsToSave.optimizeGames = optimizeGames; settingsToSave.multiController = multiController; + settingsToSave.swapABXYButtons = swapABXYButtons; settingsToSave.playAudioOnPC = audioOnPC; settingsToSave.useHevc = useHevc; settingsToSave.useFramePacing = useFramePacing; diff --git a/Limelight/Database/TemporarySettings.h b/Limelight/Database/TemporarySettings.h index bb38a659..196c6892 100644 --- a/Limelight/Database/TemporarySettings.h +++ b/Limelight/Database/TemporarySettings.h @@ -22,6 +22,7 @@ @property (nonatomic) BOOL useHevc; @property (nonatomic) BOOL useFramePacing; @property (nonatomic) BOOL multiController; +@property (nonatomic) BOOL swapABXYButtons; @property (nonatomic) BOOL playAudioOnPC; @property (nonatomic) BOOL optimizeGames; @property (nonatomic) BOOL enableHdr; diff --git a/Limelight/Database/TemporarySettings.m b/Limelight/Database/TemporarySettings.m index 90720fe4..2b0b803d 100644 --- a/Limelight/Database/TemporarySettings.m +++ b/Limelight/Database/TemporarySettings.m @@ -42,6 +42,7 @@ self.enableHdr = [[NSUserDefaults standardUserDefaults] boolForKey:@"enableHdr"]; self.optimizeGames = [[NSUserDefaults standardUserDefaults] boolForKey:@"optimizeGames"]; self.multiController = [[NSUserDefaults standardUserDefaults] boolForKey:@"multipleControllers"]; + self.swapABXYButtons = [[NSUserDefaults standardUserDefaults] boolForKey:@"swapABXYButtons"]; self.btMouseSupport = [[NSUserDefaults standardUserDefaults] boolForKey:@"btMouseSupport"]; self.statsOverlay = [[NSUserDefaults standardUserDefaults] boolForKey:@"statsOverlay"]; @@ -75,6 +76,7 @@ self.enableHdr = settings.enableHdr; self.optimizeGames = settings.optimizeGames; self.multiController = settings.multiController; + self.swapABXYButtons = settings.swapABXYButtons; self.onscreenControls = settings.onscreenControls; self.btMouseSupport = settings.btMouseSupport; self.absoluteTouchMode = settings.absoluteTouchMode; diff --git a/Limelight/Input/ControllerSupport.m b/Limelight/Input/ControllerSupport.m index f5f6ffa2..2c53460f 100644 --- a/Limelight/Input/ControllerSupport.m +++ b/Limelight/Input/ControllerSupport.m @@ -47,6 +47,7 @@ static const double MOUSE_SPEED_DIVISOR = 2.5; bool _oscEnabled; char _controllerNumbers; bool _multiController; + bool _swapABXYButtons; } // UPDATE_BUTTON_FLAG(controller, flag, pressed) @@ -302,10 +303,18 @@ static const double MOUSE_SPEED_DIVISOR = 2.5; short rightStickX, rightStickY; unsigned char leftTrigger, rightTrigger; - UPDATE_BUTTON_FLAG(limeController, A_FLAG, gamepad.buttonA.pressed); - UPDATE_BUTTON_FLAG(limeController, B_FLAG, gamepad.buttonB.pressed); - UPDATE_BUTTON_FLAG(limeController, X_FLAG, gamepad.buttonX.pressed); - UPDATE_BUTTON_FLAG(limeController, Y_FLAG, gamepad.buttonY.pressed); + if (_swapABXYButtons) { + UPDATE_BUTTON_FLAG(limeController, B_FLAG, gamepad.buttonA.pressed); + UPDATE_BUTTON_FLAG(limeController, A_FLAG, gamepad.buttonB.pressed); + UPDATE_BUTTON_FLAG(limeController, Y_FLAG, gamepad.buttonX.pressed); + UPDATE_BUTTON_FLAG(limeController, X_FLAG, gamepad.buttonY.pressed); + } + else { + UPDATE_BUTTON_FLAG(limeController, A_FLAG, gamepad.buttonA.pressed); + UPDATE_BUTTON_FLAG(limeController, B_FLAG, gamepad.buttonB.pressed); + UPDATE_BUTTON_FLAG(limeController, X_FLAG, gamepad.buttonX.pressed); + UPDATE_BUTTON_FLAG(limeController, Y_FLAG, gamepad.buttonY.pressed); + } UPDATE_BUTTON_FLAG(limeController, UP_FLAG, gamepad.dpad.up.pressed); UPDATE_BUTTON_FLAG(limeController, DOWN_FLAG, gamepad.dpad.down.pressed); @@ -361,10 +370,18 @@ static const double MOUSE_SPEED_DIVISOR = 2.5; else if (controller.gamepad != NULL) { controller.gamepad.valueChangedHandler = ^(GCGamepad *gamepad, GCControllerElement *element) { Controller* limeController = [self->_controllers objectForKey:[NSNumber numberWithInteger:gamepad.controller.playerIndex]]; - UPDATE_BUTTON_FLAG(limeController, A_FLAG, gamepad.buttonA.pressed); - UPDATE_BUTTON_FLAG(limeController, B_FLAG, gamepad.buttonB.pressed); - UPDATE_BUTTON_FLAG(limeController, X_FLAG, gamepad.buttonX.pressed); - UPDATE_BUTTON_FLAG(limeController, Y_FLAG, gamepad.buttonY.pressed); + if (_swapABXYButtons) { + UPDATE_BUTTON_FLAG(limeController, B_FLAG, gamepad.buttonA.pressed); + UPDATE_BUTTON_FLAG(limeController, A_FLAG, gamepad.buttonB.pressed); + UPDATE_BUTTON_FLAG(limeController, Y_FLAG, gamepad.buttonX.pressed); + UPDATE_BUTTON_FLAG(limeController, X_FLAG, gamepad.buttonY.pressed); + } + else { + UPDATE_BUTTON_FLAG(limeController, A_FLAG, gamepad.buttonA.pressed); + UPDATE_BUTTON_FLAG(limeController, B_FLAG, gamepad.buttonB.pressed); + UPDATE_BUTTON_FLAG(limeController, X_FLAG, gamepad.buttonX.pressed); + UPDATE_BUTTON_FLAG(limeController, Y_FLAG, gamepad.buttonY.pressed); + } UPDATE_BUTTON_FLAG(limeController, UP_FLAG, gamepad.dpad.up.pressed); UPDATE_BUTTON_FLAG(limeController, DOWN_FLAG, gamepad.dpad.down.pressed); @@ -623,6 +640,7 @@ static const double MOUSE_SPEED_DIVISOR = 2.5; _controllers = [[NSMutableDictionary alloc] init]; _controllerNumbers = 0; _multiController = streamConfig.multiController; + _swapABXYButtons = streamConfig.swapABXYButtons; _presenceDelegate = delegate; _player0osc = [[Controller alloc] init]; diff --git a/Limelight/Limelight.xcdatamodeld/Moonlight v1.7.xcdatamodel/contents b/Limelight/Limelight.xcdatamodeld/Moonlight v1.7.xcdatamodel/contents index 712c76a7..a99fd78b 100644 --- a/Limelight/Limelight.xcdatamodeld/Moonlight v1.7.xcdatamodel/contents +++ b/Limelight/Limelight.xcdatamodeld/Moonlight v1.7.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -33,6 +33,7 @@ + @@ -41,6 +42,6 @@ - + \ No newline at end of file diff --git a/Limelight/Stream/StreamConfiguration.h b/Limelight/Stream/StreamConfiguration.h index 7a207594..ba3e533b 100644 --- a/Limelight/Stream/StreamConfiguration.h +++ b/Limelight/Stream/StreamConfiguration.h @@ -23,6 +23,7 @@ @property int gamepadMask; @property BOOL optimizeGameSettings; @property BOOL playAudioOnPC; +@property BOOL swapABXYButtons; @property int audioConfiguration; @property BOOL enableHdr; @property BOOL multiController; diff --git a/Limelight/Stream/StreamConfiguration.m b/Limelight/Stream/StreamConfiguration.m index fe7e0e44..5a857450 100644 --- a/Limelight/Stream/StreamConfiguration.m +++ b/Limelight/Stream/StreamConfiguration.m @@ -9,5 +9,5 @@ #import "StreamConfiguration.h" @implementation StreamConfiguration -@synthesize host, appID, width, height, frameRate, bitRate, riKeyId, riKey, gamepadMask, appName, optimizeGameSettings, playAudioOnPC, audioConfiguration, enableHdr, multiController, allowHevc, serverCert, rtspSessionUrl; +@synthesize host, appID, width, height, frameRate, bitRate, riKeyId, riKey, gamepadMask, appName, optimizeGameSettings, playAudioOnPC, swapABXYButtons, audioConfiguration, enableHdr, multiController, allowHevc, serverCert, rtspSessionUrl; @end diff --git a/Limelight/ViewControllers/MainFrameViewController.m b/Limelight/ViewControllers/MainFrameViewController.m index 40bd653e..c1f1c067 100644 --- a/Limelight/ViewControllers/MainFrameViewController.m +++ b/Limelight/ViewControllers/MainFrameViewController.m @@ -627,11 +627,12 @@ static NSMutableSet* hostList; _streamConfig.playAudioOnPC = streamSettings.playAudioOnPC; _streamConfig.allowHevc = streamSettings.useHevc; _streamConfig.useFramePacing = streamSettings.useFramePacing; + _streamConfig.swapABXYButtons = streamSettings.swapABXYButtons; // multiController must be set before calling getConnectedGamepadMask _streamConfig.multiController = streamSettings.multiController; _streamConfig.gamepadMask = [ControllerSupport getConnectedGamepadMask:_streamConfig]; - + // Probe for supported channel configurations int physicalOutputChannels = (int)[AVAudioSession sharedInstance].maximumOutputNumberOfChannels; Log(LOG_I, @"Audio device supports %d channels", physicalOutputChannels); diff --git a/Limelight/ViewControllers/SettingsViewController.h b/Limelight/ViewControllers/SettingsViewController.h index 9a12d328..af3caff0 100644 --- a/Limelight/ViewControllers/SettingsViewController.h +++ b/Limelight/ViewControllers/SettingsViewController.h @@ -18,6 +18,7 @@ @property (strong, nonatomic) IBOutlet UISegmentedControl *onscreenControlSelector; @property (strong, nonatomic) IBOutlet UISegmentedControl *optimizeSettingsSelector; @property (strong, nonatomic) IBOutlet UISegmentedControl *multiControllerSelector; +@property (strong, nonatomic) IBOutlet UISegmentedControl *swapABXYButtonsSelector; @property (strong, nonatomic) IBOutlet UISegmentedControl *audioOnPCSelector; @property (strong, nonatomic) IBOutlet UISegmentedControl *hevcSelector; @property (strong, nonatomic) IBOutlet UISegmentedControl *hdrSelector; diff --git a/Limelight/ViewControllers/SettingsViewController.m b/Limelight/ViewControllers/SettingsViewController.m index f53b9417..49be8632 100644 --- a/Limelight/ViewControllers/SettingsViewController.m +++ b/Limelight/ViewControllers/SettingsViewController.m @@ -242,6 +242,7 @@ BOOL isCustomResolution(CGSize res) { [self.optimizeSettingsSelector setSelectedSegmentIndex:currentSettings.optimizeGames ? 1 : 0]; [self.framePacingSelector setSelectedSegmentIndex:currentSettings.useFramePacing ? 1 : 0]; [self.multiControllerSelector setSelectedSegmentIndex:currentSettings.multiController ? 1 : 0]; + [self.swapABXYButtonsSelector setSelectedSegmentIndex:currentSettings.swapABXYButtons ? 1 : 0]; [self.audioOnPCSelector setSelectedSegmentIndex:currentSettings.playAudioOnPC ? 1 : 0]; NSInteger onscreenControls = [currentSettings.onscreenControls integerValue]; _lastSelectedResolutionIndex = resolution; @@ -463,6 +464,7 @@ BOOL isCustomResolution(CGSize res) { NSInteger onscreenControls = [self.onscreenControlSelector selectedSegmentIndex]; BOOL optimizeGames = [self.optimizeSettingsSelector selectedSegmentIndex] == 1; BOOL multiController = [self.multiControllerSelector selectedSegmentIndex] == 1; + BOOL swapABXYButtons = [self.swapABXYButtonsSelector selectedSegmentIndex] == 1; BOOL audioOnPC = [self.audioOnPCSelector selectedSegmentIndex] == 1; BOOL useHevc = [self.hevcSelector selectedSegmentIndex] == 1; BOOL btMouseSupport = [self.btMouseSelector selectedSegmentIndex] == 1; @@ -478,6 +480,7 @@ BOOL isCustomResolution(CGSize res) { onscreenControls:onscreenControls optimizeGames:optimizeGames multiController:multiController + swapABXYButtons:swapABXYButtons audioOnPC:audioOnPC useHevc:useHevc useFramePacing:useFramePacing diff --git a/iPad.storyboard b/iPad.storyboard index 919053d0..cf9e8220 100644 --- a/iPad.storyboard +++ b/iPad.storyboard @@ -186,31 +186,31 @@ + + + + + + + + + + + - - - - - - - - - - - @@ -220,15 +220,32 @@ + + + + + + + + + + + - + @@ -238,14 +255,14 @@ - + @@ -255,14 +272,14 @@ - + @@ -272,14 +289,14 @@ - + @@ -306,12 +323,13 @@ + - + diff --git a/iPhone.storyboard b/iPhone.storyboard index a3435248..d7ce373a 100644 --- a/iPhone.storyboard +++ b/iPhone.storyboard @@ -205,15 +205,32 @@ + + + + + + + + + + + - + @@ -223,14 +240,14 @@ - + @@ -240,14 +257,14 @@ - + @@ -257,14 +274,14 @@ - + @@ -274,14 +291,14 @@ - + @@ -291,14 +308,14 @@ - + @@ -326,11 +343,12 @@ + - +