mirror of
https://github.com/moonlight-stream/moonlight-ios.git
synced 2026-06-17 14:11:35 +00:00
Implement extended gamepad buttons and controller metadata support
This commit is contained in:
@@ -30,4 +30,6 @@
|
|||||||
@property (nonatomic) HapticContext* _Nullable leftTriggerMotor;
|
@property (nonatomic) HapticContext* _Nullable leftTriggerMotor;
|
||||||
@property (nonatomic) HapticContext* _Nullable rightTriggerMotor;
|
@property (nonatomic) HapticContext* _Nullable rightTriggerMotor;
|
||||||
|
|
||||||
|
@property (nonatomic) BOOL reportedArrival;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -219,6 +219,11 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-(uint16_t) getActiveGamepadMask
|
||||||
|
{
|
||||||
|
return (_multiController ? _controllerNumbers : 1) | (_oscEnabled ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
-(void) updateFinished:(Controller*)controller
|
-(void) updateFinished:(Controller*)controller
|
||||||
{
|
{
|
||||||
BOOL exitRequested = NO;
|
BOOL exitRequested = NO;
|
||||||
@@ -231,9 +236,14 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
|
|||||||
exitRequested = YES;
|
exitRequested = YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!controller.reportedArrival && controller.gamepad) {
|
||||||
|
[self reportControllerArrival:controller.gamepad];
|
||||||
|
controller.reportedArrival = YES;
|
||||||
|
}
|
||||||
|
|
||||||
// Player 1 is always present for OSC
|
// Player 1 is always present for OSC
|
||||||
LiSendMultiControllerEvent(_multiController ? controller.playerIndex : 0,
|
LiSendMultiControllerEvent(_multiController ? controller.playerIndex : 0, [self getActiveGamepadMask],
|
||||||
(_multiController ? _controllerNumbers : 1) | (_oscEnabled ? 1 : 0), controller.lastButtonFlags, controller.lastLeftTrigger, controller.lastRightTrigger, controller.lastLeftStickX, controller.lastLeftStickY, controller.lastRightStickX, controller.lastRightStickY);
|
controller.lastButtonFlags, controller.lastLeftTrigger, controller.lastRightTrigger, controller.lastLeftStickX, controller.lastLeftStickY, controller.lastRightStickX, controller.lastRightStickY);
|
||||||
}
|
}
|
||||||
[_controllerStreamLock unlock];
|
[_controllerStreamLock unlock];
|
||||||
|
|
||||||
@@ -293,6 +303,122 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
|
|||||||
[controller.leftTriggerMotor cleanup];
|
[controller.leftTriggerMotor cleanup];
|
||||||
[controller.rightTriggerMotor cleanup];
|
[controller.rightTriggerMotor cleanup];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-(void) reportControllerArrival:(GCController*) controller
|
||||||
|
{
|
||||||
|
if (controller == nil || controller.extendedGamepad == nil) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t type = LI_CTYPE_UNKNOWN;
|
||||||
|
uint16_t capabilities = 0;
|
||||||
|
uint32_t supportedButtonFlags = 0;
|
||||||
|
|
||||||
|
// Start is always present
|
||||||
|
supportedButtonFlags |= PLAY_FLAG;
|
||||||
|
|
||||||
|
// Detect buttons present in the GCExtendedGamepad profile
|
||||||
|
if (controller.extendedGamepad.dpad) {
|
||||||
|
supportedButtonFlags |= UP_FLAG | DOWN_FLAG | LEFT_FLAG | RIGHT_FLAG;
|
||||||
|
}
|
||||||
|
if (controller.extendedGamepad.leftShoulder) {
|
||||||
|
supportedButtonFlags |= LB_FLAG;
|
||||||
|
}
|
||||||
|
if (controller.extendedGamepad.rightShoulder) {
|
||||||
|
supportedButtonFlags |= RB_FLAG;
|
||||||
|
}
|
||||||
|
if (@available(iOS 13.0, tvOS 13.0, *)) {
|
||||||
|
if (controller.extendedGamepad.buttonOptions) {
|
||||||
|
supportedButtonFlags |= BACK_FLAG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (@available(iOS 14.0, tvOS 14.0, *)) {
|
||||||
|
if (controller.extendedGamepad.buttonHome) {
|
||||||
|
supportedButtonFlags |= SPECIAL_FLAG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (controller.extendedGamepad.buttonA) {
|
||||||
|
supportedButtonFlags |= A_FLAG;
|
||||||
|
}
|
||||||
|
if (controller.extendedGamepad.buttonB) {
|
||||||
|
supportedButtonFlags |= B_FLAG;
|
||||||
|
}
|
||||||
|
if (controller.extendedGamepad.buttonX) {
|
||||||
|
supportedButtonFlags |= X_FLAG;
|
||||||
|
}
|
||||||
|
if (controller.extendedGamepad.buttonY) {
|
||||||
|
supportedButtonFlags |= Y_FLAG;
|
||||||
|
}
|
||||||
|
if (@available(iOS 12.1, tvOS 12.1, *)) {
|
||||||
|
if (controller.extendedGamepad.leftThumbstickButton) {
|
||||||
|
supportedButtonFlags |= LS_CLK_FLAG;
|
||||||
|
}
|
||||||
|
if (controller.extendedGamepad.rightThumbstickButton) {
|
||||||
|
supportedButtonFlags |= RS_CLK_FLAG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (@available(iOS 14.0, tvOS 14.0, *)) {
|
||||||
|
if ([controller.extendedGamepad isKindOfClass:[GCXboxGamepad class]]) {
|
||||||
|
GCXboxGamepad* xboxGamepad = (GCXboxGamepad*)controller.extendedGamepad;
|
||||||
|
|
||||||
|
if (xboxGamepad.paddleButton1) {
|
||||||
|
supportedButtonFlags |= PADDLE1_FLAG;
|
||||||
|
}
|
||||||
|
if (xboxGamepad.paddleButton2) {
|
||||||
|
supportedButtonFlags |= PADDLE2_FLAG;
|
||||||
|
}
|
||||||
|
if (xboxGamepad.paddleButton3) {
|
||||||
|
supportedButtonFlags |= PADDLE3_FLAG;
|
||||||
|
}
|
||||||
|
if (xboxGamepad.paddleButton4) {
|
||||||
|
supportedButtonFlags |= PADDLE4_FLAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (@available(iOS 15.0, tvOS 15.0, *)) {
|
||||||
|
if (xboxGamepad.buttonShare) {
|
||||||
|
supportedButtonFlags |= MISC_FLAG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type = LI_CTYPE_XBOX;
|
||||||
|
}
|
||||||
|
else if ([controller.extendedGamepad isKindOfClass:[GCDualShockGamepad class]]) {
|
||||||
|
GCDualShockGamepad* dualShockGamepad = (GCDualShockGamepad*)controller.extendedGamepad;
|
||||||
|
|
||||||
|
if (dualShockGamepad.touchpadButton) {
|
||||||
|
supportedButtonFlags |= TOUCHPAD_FLAG;
|
||||||
|
capabilities |= LI_CCAP_TOUCHPAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
type = LI_CTYPE_PS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (@available(iOS 14.5, tvOS 14.5, *)) {
|
||||||
|
if ([controller.extendedGamepad isKindOfClass:[GCDualSenseGamepad class]]) {
|
||||||
|
GCDualSenseGamepad* dualSenseGamepad = (GCDualSenseGamepad*)controller.extendedGamepad;
|
||||||
|
|
||||||
|
if (dualSenseGamepad.touchpadButton) {
|
||||||
|
supportedButtonFlags |= TOUCHPAD_FLAG;
|
||||||
|
capabilities |= LI_CCAP_TOUCHPAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
type = LI_CTYPE_PS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect supported haptics localities
|
||||||
|
if (controller.haptics) {
|
||||||
|
if ([controller.haptics.supportedLocalities containsObject:GCHapticsLocalityHandles]) {
|
||||||
|
capabilities |= LI_CCAP_RUMBLE;
|
||||||
|
}
|
||||||
|
if ([controller.haptics.supportedLocalities containsObject:GCHapticsLocalityTriggers]) {
|
||||||
|
capabilities |= LI_CCAP_TRIGGER_RUMBLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LiSendControllerArrivalEvent(controller.playerIndex, [self getActiveGamepadMask], type, supportedButtonFlags, capabilities);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void) registerControllerCallbacks:(GCController*) controller
|
-(void) registerControllerCallbacks:(GCController*) controller
|
||||||
@@ -392,6 +518,47 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
|
|||||||
if (gamepad.buttonHome != nil) {
|
if (gamepad.buttonHome != nil) {
|
||||||
UPDATE_BUTTON_FLAG(limeController, SPECIAL_FLAG, gamepad.buttonHome.pressed);
|
UPDATE_BUTTON_FLAG(limeController, SPECIAL_FLAG, gamepad.buttonHome.pressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// iOS 14 adds specific profiles for DualShock and Xbox gamepads with additional buttons
|
||||||
|
if ([gamepad isKindOfClass:[GCXboxGamepad class]]) {
|
||||||
|
GCXboxGamepad* xboxGamepad = (GCXboxGamepad*)gamepad;
|
||||||
|
|
||||||
|
if (xboxGamepad.paddleButton1) {
|
||||||
|
UPDATE_BUTTON_FLAG(limeController, PADDLE1_FLAG, xboxGamepad.paddleButton1.pressed);
|
||||||
|
}
|
||||||
|
if (xboxGamepad.paddleButton2) {
|
||||||
|
UPDATE_BUTTON_FLAG(limeController, PADDLE2_FLAG, xboxGamepad.paddleButton2.pressed);
|
||||||
|
}
|
||||||
|
if (xboxGamepad.paddleButton3) {
|
||||||
|
UPDATE_BUTTON_FLAG(limeController, PADDLE3_FLAG, xboxGamepad.paddleButton3.pressed);
|
||||||
|
}
|
||||||
|
if (xboxGamepad.paddleButton4) {
|
||||||
|
UPDATE_BUTTON_FLAG(limeController, PADDLE4_FLAG, xboxGamepad.paddleButton4.pressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (@available(iOS 15.0, tvOS 15.0, *)) {
|
||||||
|
if (xboxGamepad.buttonShare) {
|
||||||
|
UPDATE_BUTTON_FLAG(limeController, MISC_FLAG, xboxGamepad.buttonShare.pressed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ([gamepad isKindOfClass:[GCDualShockGamepad class]]) {
|
||||||
|
GCDualShockGamepad* dualShockGamepad = (GCDualShockGamepad*)gamepad;
|
||||||
|
|
||||||
|
if (dualShockGamepad.touchpadButton) {
|
||||||
|
UPDATE_BUTTON_FLAG(limeController, MISC_FLAG, dualShockGamepad.touchpadButton.pressed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (@available(iOS 14.5, tvOS 14.5, *)) {
|
||||||
|
if ([gamepad isKindOfClass:[GCDualSenseGamepad class]]) {
|
||||||
|
GCDualSenseGamepad* dualSenseGamepad = (GCDualSenseGamepad*)gamepad;
|
||||||
|
|
||||||
|
if (dualSenseGamepad.touchpadButton) {
|
||||||
|
UPDATE_BUTTON_FLAG(limeController, MISC_FLAG, dualSenseGamepad.touchpadButton.pressed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
leftStickX = gamepad.leftThumbstick.xAxis.value * 0x7FFE;
|
leftStickX = gamepad.leftThumbstick.xAxis.value * 0x7FFE;
|
||||||
@@ -739,6 +906,9 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
|
|||||||
// Register callbacks on the new controller
|
// Register callbacks on the new controller
|
||||||
[self registerControllerCallbacks:controller];
|
[self registerControllerCallbacks:controller];
|
||||||
|
|
||||||
|
// Report the controller arrival to the host
|
||||||
|
[self reportControllerArrival:controller];
|
||||||
|
|
||||||
// Re-evaluate the on-screen control mode
|
// Re-evaluate the on-screen control mode
|
||||||
[self updateAutoOnScreenControlMode];
|
[self updateAutoOnScreenControlMode];
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user