21 #include "../../SDL_internal.h" 33 #include "../SDL_sysjoystick.h" 34 #include "../SDL_joystick_c.h" 36 #if !SDL_EVENTS_DISABLED 37 #include "../../events/SDL_events_c.h" 41 #import <CoreMotion/CoreMotion.h> 44 #ifdef SDL_JOYSTICK_MFI 45 #import <GameController/GameController.h> 47 static id connectObserver = nil;
48 static id disconnectObserver = nil;
67 while (i < device_index) {
71 device = device->
next;
81 #ifdef SDL_JOYSTICK_MFI 85 device->
controller = (__bridge GCController *) CFBridgingRetain(controller);
87 if (controller.vendorName) {
88 name = controller.vendorName.UTF8String;
108 if (controller.extendedGamepad) {
110 }
else if (controller.gamepad) {
114 else if (controller.microGamepad) {
119 if (controller.extendedGamepad) {
123 }
else if (controller.gamepad) {
129 else if (controller.microGamepad) {
140 controller.playerIndex = -1;
150 while (device !=
NULL) {
154 device = device->
next;
158 if (device ==
NULL) {
180 }
else if (controller) {
184 if (deviceList ==
NULL) {
189 lastdevice = lastdevice->
next;
206 if (device ==
NULL) {
212 while (item !=
NULL) {
213 if (item == device) {
223 }
else if (device == deviceList) {
224 deviceList = device->
next;
231 #ifdef SDL_JOYSTICK_MFI 237 controller.controllerPausedHandler = nil;
255 SDL_AppleTVRemoteRotationHintChanged(
void *udata,
const char *
name,
const char *oldValue,
const char *newValue)
257 BOOL allowRotation = newValue !=
NULL && *newValue !=
'0';
262 controller.microGamepad.allowsRotation = allowRotation;
277 NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
286 #ifdef SDL_JOYSTICK_MFI 288 if (![GCController
class]) {
298 SDL_AppleTVRemoteRotationHintChanged,
NULL);
301 connectObserver = [center addObserverForName:GCControllerDidConnectNotification
304 usingBlock:^(NSNotification *note) {
305 GCController *controller = note.object;
306 SDL_SYS_AddJoystickDevice(controller, SDL_FALSE);
309 disconnectObserver = [center addObserverForName:GCControllerDidDisconnectNotification
312 usingBlock:^(NSNotification *note) {
313 GCController *controller = note.object;
314 SDL_JoystickDeviceItem *device = deviceList;
315 while (device != NULL) {
316 if (device->controller == controller) {
317 SDL_SYS_RemoveJoystickDevice(device);
320 device = device->next;
345 return device ? device->
name :
"Unknown";
364 if (device ==
NULL) {
365 return SDL_SetError(
"Could not open Joystick: no hardware device for the specified index");
368 joystick->hwdata =
device;
371 joystick->naxes = device->
naxes;
372 joystick->nhats = device->
nhats;
373 joystick->nbuttons = device->
nbuttons;
374 joystick->nballs = 0;
387 [motionManager startAccelerometerUpdates];
390 #ifdef SDL_JOYSTICK_MFI 392 controller.controllerPausedHandler = ^(GCController *
c) {
393 if (joystick->hwdata) {
394 ++joystick->hwdata->num_pause_presses;
408 return joystick->hwdata !=
NULL;
416 const SInt16 maxsint16 = 0x7FFF;
417 CMAcceleration accel;
455 #ifdef SDL_JOYSTICK_MFI 457 SDL_SYS_MFIJoystickHatStateForDPad(GCControllerDirectionPad *dpad)
461 if (dpad.up.isPressed) {
463 }
else if (dpad.down.isPressed) {
467 if (dpad.left.isPressed) {
469 }
else if (dpad.right.isPressed) {
486 GCController *
controller = joystick->hwdata->controller;
489 int updateplayerindex = 0;
491 if (controller.extendedGamepad) {
492 GCExtendedGamepad *gamepad = controller.extendedGamepad;
496 (
Sint16) (gamepad.leftThumbstick.xAxis.value * 32767),
497 (
Sint16) (gamepad.leftThumbstick.yAxis.value * -32767),
498 (
Sint16) ((gamepad.leftTrigger.value * 65535) - 32768),
499 (
Sint16) (gamepad.rightThumbstick.xAxis.value * 32767),
500 (
Sint16) (gamepad.rightThumbstick.yAxis.value * -32767),
501 (
Sint16) ((gamepad.rightTrigger.value * 65535) - 32768),
506 gamepad.buttonA.isPressed, gamepad.buttonB.isPressed,
507 gamepad.buttonX.isPressed, gamepad.buttonY.isPressed,
508 gamepad.leftShoulder.isPressed,
509 gamepad.rightShoulder.isPressed,
512 hatstate = SDL_SYS_MFIJoystickHatStateForDPad(gamepad.dpad);
518 if ((i != 2 && i != 5) || axes[i] != -32768) {
519 updateplayerindex |= (joystick->axes[i].value != axes[i]);
525 updateplayerindex |= (joystick->buttons[i] != buttons[i]);
528 }
else if (controller.gamepad) {
529 GCGamepad *gamepad = controller.gamepad;
533 gamepad.buttonA.isPressed, gamepad.buttonB.isPressed,
534 gamepad.buttonX.isPressed, gamepad.buttonY.isPressed,
535 gamepad.leftShoulder.isPressed,
536 gamepad.rightShoulder.isPressed,
539 hatstate = SDL_SYS_MFIJoystickHatStateForDPad(gamepad.dpad);
542 updateplayerindex |= (joystick->buttons[i] != buttons[i]);
547 else if (controller.microGamepad) {
548 GCMicroGamepad *gamepad = controller.microGamepad;
551 (
Sint16) (gamepad.dpad.xAxis.value * 32767),
552 (
Sint16) (gamepad.dpad.yAxis.value * -32767),
556 updateplayerindex |= (joystick->axes[i].value != axes[i]);
564 gamepad.buttonA.isPressed,
565 gamepad.buttonX.isPressed,
569 updateplayerindex |= (joystick->buttons[i] != buttons[i]);
577 if (joystick->nhats > 0) {
578 updateplayerindex |= (joystick->hats[0] != hatstate);
582 for (i = 0; i < joystick->hwdata->num_pause_presses; i++) {
584 Uint8 pausebutton = joystick->nbuttons - 1;
589 updateplayerindex = YES;
592 joystick->hwdata->num_pause_presses = 0;
594 if (updateplayerindex && controller.playerIndex == -1) {
595 BOOL usedPlayerIndexSlots[4] = {NO, NO, NO, NO};
599 if (
c != controller &&
c.playerIndex >= 0) {
608 if (!usedPlayerIndexSlots[i]) {
609 controller.playerIndex =
i;
628 if (device ==
NULL) {
645 if (device ==
NULL) {
654 [motionManager stopAccelerometerUpdates];
657 #ifdef SDL_JOYSTICK_MFI 659 controller.controllerPausedHandler = nil;
660 controller.playerIndex = -1;
671 #ifdef SDL_JOYSTICK_MFI 672 NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
674 if (connectObserver) {
675 [center removeObserver:connectObserver name:GCControllerDidConnectNotification object:nil];
676 connectObserver = nil;
679 if (disconnectObserver) {
680 [center removeObserver:disconnectObserver name:GCControllerDidDisconnectNotification object:nil];
681 disconnectObserver = nil;
686 SDL_AppleTVRemoteRotationHintChanged,
NULL);
690 while (deviceList !=
NULL) {
719 if (joystick->hwdata) {
720 guid = joystick->hwdata->guid;
void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
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...
uint8_t Uint8
An unsigned 8-bit integer type.
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)
int SDL_SYS_JoystickInit(void)
#define SDL_IPHONE_MAX_GFORCE
int SDL_SYS_NumJoysticks(void)
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)
#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
int16_t Sint16
A signed 16-bit integer type.
void SDL_SYS_JoystickDetect(void)
static CMMotionManager * motionManager