21 #include "../../SDL_internal.h" 32 #include "../SDL_sysjoystick.h" 33 #include "../SDL_joystick_c.h" 35 #if !SDL_EVENTS_DISABLED 36 #include "../../events/SDL_events_c.h" 39 #import <CoreMotion/CoreMotion.h> 41 #ifdef SDL_JOYSTICK_MFI 42 #import <GameController/GameController.h> 44 static id connectObserver = nil;
45 static id disconnectObserver = nil;
62 while (i < device_index) {
66 device = device->
next;
76 #ifdef SDL_JOYSTICK_MFI 80 device->
controller = (__bridge GCController *) CFBridgingRetain(controller);
82 if (controller.vendorName) {
83 name = controller.vendorName.UTF8String;
103 if (controller.extendedGamepad) {
105 }
else if (controller.gamepad) {
109 if (controller.extendedGamepad) {
113 }
else if (controller.gamepad) {
122 controller.playerIndex = -1;
130 #if !SDL_EVENTS_DISABLED 134 while (device !=
NULL) {
138 device = device->
next;
142 if (device ==
NULL) {
159 }
else if (controller) {
163 if (deviceList ==
NULL) {
168 lastdevice = lastdevice->
next;
170 lastdevice->
next = device;
175 #if !SDL_EVENTS_DISABLED 194 #if !SDL_EVENTS_DISABLED 198 if (device ==
NULL) {
204 while (item !=
NULL) {
205 if (item == device) {
215 }
else if (device == deviceList) {
216 deviceList = device->
next;
223 #ifdef SDL_JOYSTICK_MFI 229 controller.controllerPausedHandler = nil;
237 #if !SDL_EVENTS_DISABLED 263 NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
271 #ifdef SDL_JOYSTICK_MFI 273 if (![GCController
class]) {
281 connectObserver = [center addObserverForName:GCControllerDidConnectNotification
284 usingBlock:^(NSNotification *note) {
285 GCController *controller = note.object;
286 SDL_SYS_AddJoystickDevice(controller, SDL_FALSE);
289 disconnectObserver = [center addObserverForName:GCControllerDidDisconnectNotification
292 usingBlock:^(NSNotification *note) {
293 GCController *controller = note.object;
294 SDL_JoystickDeviceItem *device = deviceList;
295 while (device != NULL) {
296 if (device->controller == controller) {
297 SDL_SYS_RemoveJoystickDevice(device);
300 device = device->next;
323 return device ? device->
name :
"Unknown";
342 if (device ==
NULL) {
343 return SDL_SetError(
"Could not open Joystick: no hardware device for the specified index");
346 joystick->hwdata = device;
349 joystick->naxes = device->
naxes;
350 joystick->nhats = device->
nhats;
351 joystick->nbuttons = device->
nbuttons;
352 joystick->nballs = 0;
364 [motionManager startAccelerometerUpdates];
366 #ifdef SDL_JOYSTICK_MFI 368 controller.controllerPausedHandler = ^(GCController *
c) {
369 if (joystick->hwdata) {
370 ++joystick->hwdata->num_pause_presses;
384 return joystick->hwdata !=
NULL;
391 const SInt16 maxsint16 = 0x7FFF;
392 CMAcceleration accel;
429 #ifdef SDL_JOYSTICK_MFI 431 SDL_SYS_MFIJoystickHatStateForDPad(GCControllerDirectionPad *dpad)
435 if (dpad.up.isPressed) {
437 }
else if (dpad.down.isPressed) {
441 if (dpad.left.isPressed) {
443 }
else if (dpad.right.isPressed) {
458 #ifdef SDL_JOYSTICK_MFI 460 GCController *
controller = joystick->hwdata->controller;
463 int updateplayerindex = 0;
465 if (controller.extendedGamepad) {
466 GCExtendedGamepad *gamepad = controller.extendedGamepad;
470 (
Sint16) (gamepad.leftThumbstick.xAxis.value * 32767),
471 (
Sint16) (gamepad.leftThumbstick.yAxis.value * -32767),
472 (
Sint16) ((gamepad.leftTrigger.value * 65535) - 32768),
473 (
Sint16) (gamepad.rightThumbstick.xAxis.value * 32767),
474 (
Sint16) (gamepad.rightThumbstick.yAxis.value * -32767),
475 (
Sint16) ((gamepad.rightTrigger.value * 65535) - 32768),
480 gamepad.buttonA.isPressed, gamepad.buttonB.isPressed,
481 gamepad.buttonX.isPressed, gamepad.buttonY.isPressed,
482 gamepad.leftShoulder.isPressed,
483 gamepad.rightShoulder.isPressed,
486 hatstate = SDL_SYS_MFIJoystickHatStateForDPad(gamepad.dpad);
492 if ((i != 2 && i != 5) || axes[i] != -32768) {
493 updateplayerindex |= (joystick->axes[i] != axes[i]);
499 updateplayerindex |= (joystick->buttons[i] != buttons[i]);
502 }
else if (controller.gamepad) {
503 GCGamepad *gamepad = controller.gamepad;
507 gamepad.buttonA.isPressed, gamepad.buttonB.isPressed,
508 gamepad.buttonX.isPressed, gamepad.buttonY.isPressed,
509 gamepad.leftShoulder.isPressed,
510 gamepad.rightShoulder.isPressed,
513 hatstate = SDL_SYS_MFIJoystickHatStateForDPad(gamepad.dpad);
516 updateplayerindex |= (joystick->buttons[i] != buttons[i]);
522 if (joystick->nhats > 0) {
523 updateplayerindex |= (joystick->hats[0] != hatstate);
527 for (i = 0; i < joystick->hwdata->num_pause_presses; i++) {
529 Uint8 pausebutton = joystick->nbuttons - 1;
534 updateplayerindex = YES;
537 joystick->hwdata->num_pause_presses = 0;
539 if (updateplayerindex && controller.playerIndex == -1) {
540 BOOL usedPlayerIndexSlots[4] = {NO, NO, NO, NO};
544 if (
c != controller &&
c.playerIndex >= 0) {
553 if (!usedPlayerIndexSlots[i]) {
554 controller.playerIndex =
i;
573 if (device ==
NULL) {
590 if (device ==
NULL) {
598 [motionManager stopAccelerometerUpdates];
600 #ifdef SDL_JOYSTICK_MFI 602 controller.controllerPausedHandler = nil;
603 controller.playerIndex = -1;
614 #ifdef SDL_JOYSTICK_MFI 615 NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
617 if (connectObserver) {
618 [center removeObserver:connectObserver name:GCControllerDidConnectNotification object:nil];
619 connectObserver = nil;
622 if (disconnectObserver) {
623 [center removeObserver:disconnectObserver name:GCControllerDidDisconnectNotification object:nil];
624 disconnectObserver = nil;
628 while (deviceList !=
NULL) {
655 if (joystick->hwdata) {
656 guid = joystick->hwdata->guid;
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
int SDL_SYS_NumJoysticks()
static SDL_JoystickDeviceItem * deviceList
static void SDL_SYS_MFIJoystickUpdate(SDL_Joystick *joystick)
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
static const char * accelerometerName
struct joystick_hwdata * next
GLuint const GLchar * name
void SDL_SYS_JoystickQuit(void)
static SDL_JoystickDeviceItem * GetDeviceForIndex(int device_index)
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
#define SDL_HINT_ACCELEROMETER_AS_JOYSTICK
A variable controlling whether the Android / iOS built-in accelerometer should be listed as a joystic...
#define SDL_GetEventState(type)
uint8_t Uint8
An unsigned 8-bit integer type.
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
SDL_EventFilter SDL_EventOK
static void SDL_SYS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controller)
void SDL_SYS_JoystickDetect()
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
static void SDL_SYS_AccelerometerUpdate(SDL_Joystick *joystick)
static SDL_JoystickID instancecounter
struct SDL_joylist_item * item
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.
static CMMotionManager * motionManager