From 6f3c007e3ddc84e4083f161e6337272651fecc0c Mon Sep 17 00:00:00 2001 From: Malcolm Anderson Date: Thu, 6 Mar 2025 19:17:42 -0800 Subject: [PATCH] Support more controllers on macOS 11+ Fix platform availability Make inputs accumulate, matching the `extendedGamepad` implementation --- drivers/apple/joypad_apple.mm | 154 +++++++++++++++++++++++++++++++++- 1 file changed, 153 insertions(+), 1 deletion(-) diff --git a/drivers/apple/joypad_apple.mm b/drivers/apple/joypad_apple.mm index b2b448d64be..0afc5968b30 100644 --- a/drivers/apple/joypad_apple.mm +++ b/drivers/apple/joypad_apple.mm @@ -163,7 +163,159 @@ GameController::GameController(int p_joy_id, GCController *p_controller) : }; }; - if (controller.extendedGamepad != nil) { + if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) { + if (controller.physicalInputProfile != nil) { + GCPhysicalInputProfile *profile = controller.physicalInputProfile; + + GCControllerButtonInput *buttonA = profile.buttons[GCInputButtonA]; + GCControllerButtonInput *buttonB = profile.buttons[GCInputButtonB]; + GCControllerButtonInput *buttonX = profile.buttons[GCInputButtonX]; + GCControllerButtonInput *buttonY = profile.buttons[GCInputButtonY]; + if (nintendo_button_layout) { + if (buttonA) { + buttonA.pressedChangedHandler = BUTTON(JoyButton::B); + } + if (buttonB) { + buttonB.pressedChangedHandler = BUTTON(JoyButton::A); + } + if (buttonX) { + buttonX.pressedChangedHandler = BUTTON(JoyButton::Y); + } + if (buttonY) { + buttonY.pressedChangedHandler = BUTTON(JoyButton::X); + } + } else { + if (buttonA) { + buttonA.pressedChangedHandler = BUTTON(JoyButton::A); + } + if (buttonB) { + buttonB.pressedChangedHandler = BUTTON(JoyButton::B); + } + if (buttonX) { + buttonX.pressedChangedHandler = BUTTON(JoyButton::X); + } + if (buttonY) { + buttonY.pressedChangedHandler = BUTTON(JoyButton::Y); + } + } + + GCControllerButtonInput *leftThumbstickButton = profile.buttons[GCInputLeftThumbstickButton]; + GCControllerButtonInput *rightThumbstickButton = profile.buttons[GCInputRightThumbstickButton]; + if (leftThumbstickButton) { + leftThumbstickButton.pressedChangedHandler = BUTTON(JoyButton::LEFT_STICK); + } + if (rightThumbstickButton) { + rightThumbstickButton.pressedChangedHandler = BUTTON(JoyButton::RIGHT_STICK); + } + + GCControllerButtonInput *leftShoulder = profile.buttons[GCInputLeftShoulder]; + GCControllerButtonInput *rightShoulder = profile.buttons[GCInputRightShoulder]; + if (leftShoulder) { + leftShoulder.pressedChangedHandler = BUTTON(JoyButton::LEFT_SHOULDER); + } + if (rightShoulder) { + rightShoulder.pressedChangedHandler = BUTTON(JoyButton::RIGHT_SHOULDER); + } + + GCControllerButtonInput *leftTrigger = profile.buttons[GCInputLeftTrigger]; + GCControllerButtonInput *rightTrigger = profile.buttons[GCInputRightTrigger]; + if (leftTrigger) { + leftTrigger.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { + if (axis_value[(int)JoyAxis::TRIGGER_LEFT] != value) { + axis_changed[(int)JoyAxis::TRIGGER_LEFT] = true; + axis_value[(int)JoyAxis::TRIGGER_LEFT] = value; + } + }; + } + if (rightTrigger) { + rightTrigger.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { + if (axis_value[(int)JoyAxis::TRIGGER_RIGHT] != value) { + axis_changed[(int)JoyAxis::TRIGGER_RIGHT] = true; + axis_value[(int)JoyAxis::TRIGGER_RIGHT] = value; + } + }; + } + + GCControllerButtonInput *buttonMenu = profile.buttons[GCInputButtonMenu]; + GCControllerButtonInput *buttonHome = profile.buttons[GCInputButtonHome]; + GCControllerButtonInput *buttonOptions = profile.buttons[GCInputButtonOptions]; + if (buttonMenu) { + buttonMenu.pressedChangedHandler = BUTTON(JoyButton::START); + } + if (buttonHome) { + buttonHome.pressedChangedHandler = BUTTON(JoyButton::GUIDE); + } + if (buttonOptions) { + buttonOptions.pressedChangedHandler = BUTTON(JoyButton::BACK); + } + + // Xbox controller buttons. + if (@available(macOS 12.0, iOS 15.0, tvOS 15.0, *)) { + GCControllerButtonInput *buttonShare = profile.buttons[GCInputButtonShare]; + if (buttonShare) { + buttonShare.pressedChangedHandler = BUTTON(JoyButton::MISC1); + } + } + + GCControllerButtonInput *paddleButton1 = profile.buttons[GCInputXboxPaddleOne]; + GCControllerButtonInput *paddleButton2 = profile.buttons[GCInputXboxPaddleTwo]; + GCControllerButtonInput *paddleButton3 = profile.buttons[GCInputXboxPaddleThree]; + GCControllerButtonInput *paddleButton4 = profile.buttons[GCInputXboxPaddleFour]; + if (paddleButton1) { + paddleButton1.pressedChangedHandler = BUTTON(JoyButton::PADDLE1); + } + if (paddleButton2) { + paddleButton2.pressedChangedHandler = BUTTON(JoyButton::PADDLE2); + } + if (paddleButton3) { + paddleButton3.pressedChangedHandler = BUTTON(JoyButton::PADDLE3); + } + if (paddleButton4) { + paddleButton4.pressedChangedHandler = BUTTON(JoyButton::PADDLE4); + } + + GCControllerDirectionPad *leftThumbstick = profile.dpads[GCInputLeftThumbstick]; + if (leftThumbstick) { + leftThumbstick.valueChangedHandler = ^(GCControllerDirectionPad *dpad, float xValue, float yValue) { + if (axis_value[(int)JoyAxis::LEFT_X] != xValue) { + axis_changed[(int)JoyAxis::LEFT_X] = true; + axis_value[(int)JoyAxis::LEFT_X] = xValue; + } + if (axis_value[(int)JoyAxis::LEFT_Y] != -yValue) { + axis_changed[(int)JoyAxis::LEFT_Y] = true; + axis_value[(int)JoyAxis::LEFT_Y] = -yValue; + } + }; + } + + GCControllerDirectionPad *rightThumbstick = profile.dpads[GCInputRightThumbstick]; + if (rightThumbstick) { + rightThumbstick.valueChangedHandler = ^(GCControllerDirectionPad *dpad, float xValue, float yValue) { + if (axis_value[(int)JoyAxis::RIGHT_X] != xValue) { + axis_changed[(int)JoyAxis::RIGHT_X] = true; + axis_value[(int)JoyAxis::RIGHT_X] = xValue; + } + if (axis_value[(int)JoyAxis::RIGHT_Y] != -yValue) { + axis_changed[(int)JoyAxis::RIGHT_Y] = true; + axis_value[(int)JoyAxis::RIGHT_Y] = -yValue; + } + }; + } + + GCControllerDirectionPad *dpad = nil; + if (controller.extendedGamepad != nil) { + dpad = controller.extendedGamepad.dpad; + } else if (controller.microGamepad != nil) { + dpad = controller.microGamepad.dpad; + } + if (dpad) { + dpad.up.pressedChangedHandler = BUTTON(JoyButton::DPAD_UP); + dpad.down.pressedChangedHandler = BUTTON(JoyButton::DPAD_DOWN); + dpad.left.pressedChangedHandler = BUTTON(JoyButton::DPAD_LEFT); + dpad.right.pressedChangedHandler = BUTTON(JoyButton::DPAD_RIGHT); + } + } + } else if (controller.extendedGamepad != nil) { GCExtendedGamepad *gamepad = controller.extendedGamepad; if (nintendo_button_layout) {