21 #include "../../SDL_internal.h" 34 #include "../SDL_sysjoystick.h" 35 #include "../SDL_joystick_c.h" 36 #include "../steam/SDL_steamcontroller.h" 39 #if !SDL_EVENTS_DISABLED 40 #include "../../events/SDL_events_c.h" 44 #import <CoreMotion/CoreMotion.h> 47 #ifdef SDL_JOYSTICK_MFI 48 #import <GameController/GameController.h> 50 static id connectObserver = nil;
51 static id disconnectObserver = nil;
70 while (i < device_index) {
74 device = device->
next;
84 #ifdef SDL_JOYSTICK_MFI 88 device->
controller = (__bridge GCController *) CFBridgingRetain(controller);
90 if (controller.vendorName) {
91 name = controller.vendorName.UTF8String;
111 if (controller.extendedGamepad) {
113 }
else if (controller.gamepad) {
117 else if (controller.microGamepad) {
122 if (controller.extendedGamepad) {
126 }
else if (controller.gamepad) {
132 else if (controller.microGamepad) {
143 controller.playerIndex = -1;
153 while (device !=
NULL) {
157 device = device->
next;
161 if (device ==
NULL) {
183 }
else if (controller) {
187 if (deviceList ==
NULL) {
192 lastdevice = lastdevice->
next;
209 if (device ==
NULL) {
215 while (item !=
NULL) {
216 if (item == device) {
226 }
else if (device == deviceList) {
227 deviceList = device->
next;
234 #ifdef SDL_JOYSTICK_MFI 240 controller.controllerPausedHandler = nil;
258 SDL_AppleTVRemoteRotationHintChanged(
void *udata,
const char *
name,
const char *oldValue,
const char *newValue)
260 BOOL allowRotation = newValue !=
NULL && *newValue !=
'0';
265 controller.microGamepad.allowsRotation = allowRotation;
275 if (device ==
NULL) {
287 if (deviceList ==
NULL) {
292 lastdevice = lastdevice->
next;
308 for (item = deviceList;
item; item = item->
next) {
324 NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
336 #ifdef SDL_JOYSTICK_MFI 338 if (![GCController
class]) {
348 SDL_AppleTVRemoteRotationHintChanged,
NULL);
351 connectObserver = [center addObserverForName:GCControllerDidConnectNotification
354 usingBlock:^(NSNotification *note) {
355 GCController *controller = note.object;
356 SDL_SYS_AddJoystickDevice(controller, SDL_FALSE);
359 disconnectObserver = [center addObserverForName:GCControllerDidDisconnectNotification
362 usingBlock:^(NSNotification *note) {
363 GCController *controller = note.object;
364 SDL_JoystickDeviceItem *device = deviceList;
365 while (device != NULL) {
366 if (device->controller == controller) {
367 SDL_SYS_RemoveJoystickDevice(device);
370 device = device->next;
396 return device ? device->
name :
"Unknown";
415 if (device ==
NULL) {
416 return SDL_SetError(
"Could not open Joystick: no hardware device for the specified index");
419 joystick->hwdata =
device;
422 joystick->naxes = device->
naxes;
423 joystick->nhats = device->
nhats;
424 joystick->nbuttons = device->
nbuttons;
425 joystick->nballs = 0;
438 [motionManager startAccelerometerUpdates];
441 #ifdef SDL_JOYSTICK_MFI 443 controller.controllerPausedHandler = ^(GCController *
c) {
444 if (joystick->hwdata) {
445 ++joystick->hwdata->num_pause_presses;
459 return joystick->hwdata !=
NULL;
467 const SInt16 maxsint16 = 0x7FFF;
468 CMAcceleration accel;
506 #ifdef SDL_JOYSTICK_MFI 508 SDL_SYS_MFIJoystickHatStateForDPad(GCControllerDirectionPad *dpad)
512 if (dpad.up.isPressed) {
514 }
else if (dpad.down.isPressed) {
518 if (dpad.left.isPressed) {
520 }
else if (dpad.right.isPressed) {
537 GCController *
controller = joystick->hwdata->controller;
540 int updateplayerindex = 0;
542 if (controller.extendedGamepad) {
543 GCExtendedGamepad *gamepad = controller.extendedGamepad;
547 (
Sint16) (gamepad.leftThumbstick.xAxis.value * 32767),
548 (
Sint16) (gamepad.leftThumbstick.yAxis.value * -32767),
549 (
Sint16) ((gamepad.leftTrigger.value * 65535) - 32768),
550 (
Sint16) (gamepad.rightThumbstick.xAxis.value * 32767),
551 (
Sint16) (gamepad.rightThumbstick.yAxis.value * -32767),
552 (
Sint16) ((gamepad.rightTrigger.value * 65535) - 32768),
557 gamepad.buttonA.isPressed, gamepad.buttonB.isPressed,
558 gamepad.buttonX.isPressed, gamepad.buttonY.isPressed,
559 gamepad.leftShoulder.isPressed,
560 gamepad.rightShoulder.isPressed,
563 hatstate = SDL_SYS_MFIJoystickHatStateForDPad(gamepad.dpad);
569 if ((i != 2 && i != 5) || axes[i] != -32768) {
570 updateplayerindex |= (joystick->axes[i].value != axes[i]);
576 updateplayerindex |= (joystick->buttons[i] != buttons[i]);
579 }
else if (controller.gamepad) {
580 GCGamepad *gamepad = controller.gamepad;
584 gamepad.buttonA.isPressed, gamepad.buttonB.isPressed,
585 gamepad.buttonX.isPressed, gamepad.buttonY.isPressed,
586 gamepad.leftShoulder.isPressed,
587 gamepad.rightShoulder.isPressed,
590 hatstate = SDL_SYS_MFIJoystickHatStateForDPad(gamepad.dpad);
593 updateplayerindex |= (joystick->buttons[i] != buttons[i]);
598 else if (controller.microGamepad) {
599 GCMicroGamepad *gamepad = controller.microGamepad;
602 (
Sint16) (gamepad.dpad.xAxis.value * 32767),
603 (
Sint16) (gamepad.dpad.yAxis.value * -32767),
607 updateplayerindex |= (joystick->axes[i].value != axes[i]);
615 gamepad.buttonA.isPressed,
616 gamepad.buttonX.isPressed,
620 updateplayerindex |= (joystick->buttons[i] != buttons[i]);
628 if (joystick->nhats > 0) {
629 updateplayerindex |= (joystick->hats[0] != hatstate);
633 for (i = 0; i < joystick->hwdata->num_pause_presses; i++) {
635 Uint8 pausebutton = joystick->nbuttons - 1;
640 updateplayerindex = YES;
643 joystick->hwdata->num_pause_presses = 0;
645 if (updateplayerindex && controller.playerIndex == -1) {
646 BOOL usedPlayerIndexSlots[4] = {NO, NO, NO, NO};
650 if (
c != controller &&
c.playerIndex >= 0) {
659 if (!usedPlayerIndexSlots[i]) {
660 controller.playerIndex =
i;
679 if (device ==
NULL) {
701 if (device ==
NULL) {
710 [motionManager stopAccelerometerUpdates];
713 #ifdef SDL_JOYSTICK_MFI 715 controller.controllerPausedHandler = nil;
716 controller.playerIndex = -1;
727 #ifdef SDL_JOYSTICK_MFI 728 NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
730 if (connectObserver) {
731 [center removeObserver:connectObserver name:GCControllerDidConnectNotification object:nil];
732 connectObserver = nil;
735 if (disconnectObserver) {
736 [center removeObserver:disconnectObserver name:GCControllerDidDisconnectNotification object:nil];
737 disconnectObserver = nil;
742 SDL_AppleTVRemoteRotationHintChanged,
NULL);
746 while (deviceList !=
NULL) {
777 if (joystick->hwdata) {
778 guid = joystick->hwdata->guid;
void SDL_UpdateSteamControllers(void)
void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
void SDL_InitSteamControllers(SteamControllerConnectedCallback_t connectedCallback, SteamControllerDisconnectedCallback_t disconnectedCallback)
static void SteamControllerDisconnectedCallback(int device_instance)
void SDL_QuitSteamControllers(void)
static SDL_JoystickDeviceItem * deviceList
static void SDL_SYS_MFIJoystickUpdate(SDL_Joystick *joystick)
#define SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION
A variable controlling whether the Apple TV remote's joystick axes will automatically match the rotat...
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
static const char * accelerometerName
struct joystick_hwdata * next
void SDL_SYS_JoystickQuit(void)
static SDL_JoystickDeviceItem * GetDeviceForIndex(int device_index)
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
GLuint const GLchar * name
#define SDL_GetHintBoolean
static SDL_AudioDeviceID device
#define SDL_HINT_ACCELEROMETER_AS_JOYSTICK
A variable controlling whether the Android / iOS built-in accelerometer should be listed as a joystic...
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
static void SDL_SYS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controller)
void SDL_PrivateJoystickAdded(int device_index)
const char * SDL_SYS_JoystickNameForDeviceIndex(int device_index)
void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick *joystick)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
static SDL_bool SteamControllerConnectedCallback(const char *name, SDL_JoystickGUID guid, int *device_instance)
int SDL_SYS_JoystickInit(void)
#define SDL_IPHONE_MAX_GFORCE
void SDL_UpdateSteamController(SDL_Joystick *joystick)
int SDL_SYS_NumJoysticks(void)
SDL_bool m_bSteamController
static void SDL_SYS_AccelerometerUpdate(SDL_Joystick *joystick)
static SDL_JoystickID instancecounter
struct SDL_joylist_item * item
#define SDL_AddHintCallback
#define SDL_DelHintCallback
static SDL_JoystickDeviceItem * SDL_SYS_RemoveJoystickDevice(SDL_JoystickDeviceItem *device)
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
void SDL_GetSteamControllerInputs(int *nbuttons, int *naxes, int *nhats)
#define SDL_arraysize(array)
int SDL_SYS_JoystickOpen(SDL_Joystick *joystick, int device_index)
void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
static void SDL_SYS_AddJoystickDevice(GCController *controller, SDL_bool accelerometer)
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID(int device_index)
GCController __unsafe_unretained * controller
void SDL_SYS_JoystickDetect(void)
static CMMotionManager * motionManager