SDL  2.0
SDL_sysjoystick.m File Reference
#include "../../SDL_internal.h"
#include "SDL_sysjoystick_c.h"
#include "SDL_config_iphoneos.h"
#include "SDL_assert.h"
#include "SDL_events.h"
#include "SDL_joystick.h"
#include "SDL_hints.h"
#include "SDL_stdinc.h"
#include "../SDL_sysjoystick.h"
#include "../SDL_joystick_c.h"
#include "../../events/SDL_events_c.h"
#import <CoreMotion/CoreMotion.h>
+ Include dependency graph for SDL_sysjoystick.m:

Go to the source code of this file.

Functions

static SDL_JoystickDeviceItemGetDeviceForIndex (int device_index)
 
static void IOS_AddMFIJoystickDevice (SDL_JoystickDeviceItem *device, GCController *controller)
 
static void IOS_AddJoystickDevice (GCController *controller, SDL_bool accelerometer)
 
static SDL_JoystickDeviceItemIOS_RemoveJoystickDevice (SDL_JoystickDeviceItem *device)
 
static int IOS_JoystickInit (void)
 
static int IOS_JoystickGetCount (void)
 
static void IOS_JoystickDetect (void)
 
static const char * IOS_JoystickGetDeviceName (int device_index)
 
static int IOS_JoystickGetDevicePlayerIndex (int device_index)
 
static SDL_JoystickGUID IOS_JoystickGetDeviceGUID (int device_index)
 
static SDL_JoystickID IOS_JoystickGetDeviceInstanceID (int device_index)
 
static int IOS_JoystickOpen (SDL_Joystick *joystick, int device_index)
 
static void IOS_AccelerometerUpdate (SDL_Joystick *joystick)
 
static void IOS_MFIJoystickUpdate (SDL_Joystick *joystick)
 
static int IOS_JoystickRumble (SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
 
static void IOS_JoystickUpdate (SDL_Joystick *joystick)
 
static void IOS_JoystickClose (SDL_Joystick *joystick)
 
static void IOS_JoystickQuit (void)
 

Variables

static const char * accelerometerName = "iOS Accelerometer"
 
static CMMotionManager * motionManager = nil
 
static SDL_JoystickDeviceItemdeviceList = NULL
 
static int numjoysticks = 0
 
int SDL_AppleTVRemoteOpenedAsJoystick = 0
 
SDL_JoystickDriver SDL_IOS_JoystickDriver
 

Function Documentation

◆ GetDeviceForIndex()

static SDL_JoystickDeviceItem* GetDeviceForIndex ( int  device_index)
static

Definition at line 64 of file SDL_sysjoystick.m.

65 {
67  int i = 0;
68 
69  while (i < device_index) {
70  if (device == NULL) {
71  return NULL;
72  }
73  device = device->next;
74  i++;
75  }
76 
77  return device;
78 }

References device, deviceList, i, and NULL.

Referenced by IOS_JoystickGetDeviceGUID(), IOS_JoystickGetDeviceInstanceID(), IOS_JoystickGetDeviceName(), and IOS_JoystickOpen().

◆ IOS_AccelerometerUpdate()

static void IOS_AccelerometerUpdate ( SDL_Joystick *  joystick)
static

Definition at line 435 of file SDL_sysjoystick.m.

436 {
437 #if !TARGET_OS_TV
438  const float maxgforce = SDL_IPHONE_MAX_GFORCE;
439  const SInt16 maxsint16 = 0x7FFF;
440  CMAcceleration accel;
441 
442  @autoreleasepool {
443  if (!motionManager.isAccelerometerActive) {
444  return;
445  }
446 
447  accel = motionManager.accelerometerData.acceleration;
448  }
449 
450  /*
451  Convert accelerometer data from floating point to Sint16, which is what
452  the joystick system expects.
453 
454  To do the conversion, the data is first clamped onto the interval
455  [-SDL_IPHONE_MAX_G_FORCE, SDL_IPHONE_MAX_G_FORCE], then the data is multiplied
456  by MAX_SINT16 so that it is mapped to the full range of an Sint16.
457 
458  You can customize the clamped range of this function by modifying the
459  SDL_IPHONE_MAX_GFORCE macro in SDL_config_iphoneos.h.
460 
461  Once converted to Sint16, the accelerometer data no longer has coherent
462  units. You can convert the data back to units of g-force by multiplying
463  it in your application's code by SDL_IPHONE_MAX_GFORCE / 0x7FFF.
464  */
465 
466  /* clamp the data */
467  accel.x = SDL_min(SDL_max(accel.x, -maxgforce), maxgforce);
468  accel.y = SDL_min(SDL_max(accel.y, -maxgforce), maxgforce);
469  accel.z = SDL_min(SDL_max(accel.z, -maxgforce), maxgforce);
470 
471  /* pass in data mapped to range of SInt16 */
472  SDL_PrivateJoystickAxis(joystick, 0, (accel.x / maxgforce) * maxsint16);
473  SDL_PrivateJoystickAxis(joystick, 1, -(accel.y / maxgforce) * maxsint16);
474  SDL_PrivateJoystickAxis(joystick, 2, (accel.z / maxgforce) * maxsint16);
475 #endif /* !TARGET_OS_TV */
476 }

References motionManager, SDL_IPHONE_MAX_GFORCE, SDL_max, SDL_min, and SDL_PrivateJoystickAxis().

Referenced by IOS_JoystickUpdate().

◆ IOS_AddJoystickDevice()

static void IOS_AddJoystickDevice ( GCController *  controller,
SDL_bool  accelerometer 
)
static

Definition at line 157 of file SDL_sysjoystick.m.

158 {
160 
161 #if TARGET_OS_TV
163  /* Ignore devices that aren't actually controllers (e.g. remotes), they'll be handled as keyboard input */
164  if (controller && !controller.extendedGamepad && !controller.gamepad && controller.microGamepad) {
165  return;
166  }
167  }
168 #endif
169 
170  while (device != NULL) {
171  if (device->controller == controller) {
172  return;
173  }
174  device = device->next;
175  }
176 
178  if (device == NULL) {
179  return;
180  }
181 
182  device->accelerometer = accelerometer;
183  device->instance_id = SDL_GetNextJoystickInstanceID();
184 
185  if (accelerometer) {
186 #if TARGET_OS_TV
187  SDL_free(device);
188  return;
189 #else
191  device->naxes = 3; /* Device acceleration in the x, y, and z axes. */
192  device->nhats = 0;
193  device->nbuttons = 0;
194 
195  /* Use the accelerometer name as a GUID. */
196  SDL_memcpy(&device->guid.data, device->name, SDL_min(sizeof(SDL_JoystickGUID), SDL_strlen(device->name)));
197 #endif /* TARGET_OS_TV */
198  } else if (controller) {
199  IOS_AddMFIJoystickDevice(device, controller);
200  }
201 
202  if (deviceList == NULL) {
203  deviceList = device;
204  } else {
205  SDL_JoystickDeviceItem *lastdevice = deviceList;
206  while (lastdevice->next != NULL) {
207  lastdevice = lastdevice->next;
208  }
209  lastdevice->next = device;
210  }
211 
212  ++numjoysticks;
213 
214  SDL_PrivateJoystickAdded(device->instance_id);
215 }

References accelerometerName, device, deviceList, IOS_AddMFIJoystickDevice(), recDevice::next, NULL, numjoysticks, SDL_calloc, SDL_free, SDL_GetHintBoolean, SDL_GetNextJoystickInstanceID(), SDL_HINT_TV_REMOTE_AS_JOYSTICK, SDL_memcpy, SDL_min, SDL_PrivateJoystickAdded(), SDL_strdup, SDL_strlen, and SDL_TRUE.

Referenced by IOS_JoystickInit().

◆ IOS_AddMFIJoystickDevice()

static void IOS_AddMFIJoystickDevice ( SDL_JoystickDeviceItem device,
GCController *  controller 
)
static

Definition at line 81 of file SDL_sysjoystick.m.

82 {
83 #ifdef SDL_JOYSTICK_MFI
84  const Uint16 VENDOR_APPLE = 0x05AC;
85  Uint16 *guid16 = (Uint16 *)device->guid.data;
86  Uint16 vendor = 0;
87  Uint16 product = 0;
88  Uint16 version = 0;
89  Uint8 subtype = 0;
90 
91  const char *name = NULL;
92  /* Explicitly retain the controller because SDL_JoystickDeviceItem is a
93  * struct, and ARC doesn't work with structs. */
94  device->controller = (__bridge GCController *) CFBridgingRetain(controller);
95 
96  if (controller.vendorName) {
97  name = controller.vendorName.UTF8String;
98  }
99 
100  if (!name) {
101  name = "MFi Gamepad";
102  }
103 
104  device->name = SDL_strdup(name);
105 
106  if (controller.extendedGamepad) {
107  vendor = VENDOR_APPLE;
108  product = 1;
109  subtype = 1;
110  device->naxes = 6; /* 2 thumbsticks and 2 triggers */
111  device->nhats = 1; /* d-pad */
112  device->nbuttons = 7; /* ABXY, shoulder buttons, pause button */
113  } else if (controller.gamepad) {
114  vendor = VENDOR_APPLE;
115  product = 2;
116  subtype = 2;
117  device->naxes = 0; /* no traditional analog inputs */
118  device->nhats = 1; /* d-pad */
119  device->nbuttons = 7; /* ABXY, shoulder buttons, pause button */
120  }
121 #if TARGET_OS_TV
122  else if (controller.microGamepad) {
123  vendor = VENDOR_APPLE;
124  product = 3;
125  subtype = 3;
126  device->naxes = 2; /* treat the touch surface as two axes */
127  device->nhats = 0; /* apparently the touch surface-as-dpad is buggy */
128  device->nbuttons = 3; /* AX, pause button */
129 
130  controller.microGamepad.allowsRotation = SDL_GetHintBoolean(SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION, SDL_FALSE);
131  }
132 #endif /* TARGET_OS_TV */
133 
134  /* We only need 16 bits for each of these; space them out to fill 128. */
135  /* Byteswap so devices get same GUID on little/big endian platforms. */
137  *guid16++ = 0;
138  *guid16++ = SDL_SwapLE16(vendor);
139  *guid16++ = 0;
140  *guid16++ = SDL_SwapLE16(product);
141  *guid16++ = 0;
142  *guid16++ = SDL_SwapLE16(version);
143  *guid16++ = 0;
144 
145  /* Note that this is an MFI controller and what subtype it is */
146  device->guid.data[14] = 'm';
147  device->guid.data[15] = subtype;
148 
149  /* This will be set when the first button press of the controller is
150  * detected. */
151  controller.playerIndex = -1;
152 
153 #endif /* SDL_JOYSTICK_MFI */
154 }

References device, NULL, SDL_FALSE, SDL_GetHintBoolean, SDL_HARDWARE_BUS_BLUETOOTH, SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION, SDL_strdup, and SDL_SwapLE16.

Referenced by IOS_AddJoystickDevice().

◆ IOS_JoystickClose()

static void IOS_JoystickClose ( SDL_Joystick *  joystick)
static

Definition at line 655 of file SDL_sysjoystick.m.

656 {
657  SDL_JoystickDeviceItem *device = joystick->hwdata;
658 
659  if (device == NULL) {
660  return;
661  }
662 
663  device->joystick = NULL;
664 
665  @autoreleasepool {
666  if (device->accelerometer) {
667 #if !TARGET_OS_TV
668  [motionManager stopAccelerometerUpdates];
669 #endif /* !TARGET_OS_TV */
670  } else if (device->controller) {
671 #ifdef SDL_JOYSTICK_MFI
672  GCController *controller = device->controller;
673  controller.controllerPausedHandler = nil;
674  controller.playerIndex = -1;
675 #endif
676  }
677  }
678  if (device->remote) {
680  }
681 }

References device, NULL, and SDL_AppleTVRemoteOpenedAsJoystick.

◆ IOS_JoystickDetect()

static void IOS_JoystickDetect ( void  )
static

Definition at line 350 of file SDL_sysjoystick.m.

351 {
352 }

◆ IOS_JoystickGetCount()

static int IOS_JoystickGetCount ( void  )
static

Definition at line 344 of file SDL_sysjoystick.m.

345 {
346  return numjoysticks;
347 }

References numjoysticks.

◆ IOS_JoystickGetDeviceGUID()

static SDL_JoystickGUID IOS_JoystickGetDeviceGUID ( int  device_index)
static

Definition at line 368 of file SDL_sysjoystick.m.

369 {
371  SDL_JoystickGUID guid;
372  if (device) {
373  guid = device->guid;
374  } else {
375  SDL_zero(guid);
376  }
377  return guid;
378 }

References device, GetDeviceForIndex(), and SDL_zero.

◆ IOS_JoystickGetDeviceInstanceID()

static SDL_JoystickID IOS_JoystickGetDeviceInstanceID ( int  device_index)
static

Definition at line 381 of file SDL_sysjoystick.m.

382 {
384  return device ? device->instance_id : -1;
385 }

References device, and GetDeviceForIndex().

◆ IOS_JoystickGetDeviceName()

static const char* IOS_JoystickGetDeviceName ( int  device_index)
static

Definition at line 355 of file SDL_sysjoystick.m.

356 {
358  return device ? device->name : "Unknown";
359 }

References device, and GetDeviceForIndex().

◆ IOS_JoystickGetDevicePlayerIndex()

static int IOS_JoystickGetDevicePlayerIndex ( int  device_index)
static

Definition at line 362 of file SDL_sysjoystick.m.

363 {
364  return -1;
365 }

◆ IOS_JoystickInit()

static int IOS_JoystickInit ( void  )
static

Definition at line 288 of file SDL_sysjoystick.m.

289 {
290  @autoreleasepool {
291  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
292 
293 #if !TARGET_OS_TV
295  /* Default behavior, accelerometer as joystick */
297  }
298 #endif /* !TARGET_OS_TV */
299 
300 #ifdef SDL_JOYSTICK_MFI
301  /* GameController.framework was added in iOS 7. */
302  if (![GCController class]) {
303  return 0;
304  }
305 
306  for (GCController *controller in [GCController controllers]) {
307  IOS_AddJoystickDevice(controller, SDL_FALSE);
308  }
309 
310 #if TARGET_OS_TV
312  SDL_AppleTVRemoteRotationHintChanged, NULL);
313 #endif /* TARGET_OS_TV */
314 
315  connectObserver = [center addObserverForName:GCControllerDidConnectNotification
316  object:nil
317  queue:nil
318  usingBlock:^(NSNotification *note) {
319  GCController *controller = note.object;
320  IOS_AddJoystickDevice(controller, SDL_FALSE);
321  }];
322 
323  disconnectObserver = [center addObserverForName:GCControllerDidDisconnectNotification
324  object:nil
325  queue:nil
326  usingBlock:^(NSNotification *note) {
327  GCController *controller = note.object;
328  SDL_JoystickDeviceItem *device = deviceList;
329  while (device != NULL) {
330  if (device->controller == controller) {
331  IOS_RemoveJoystickDevice(device);
332  break;
333  }
334  device = device->next;
335  }
336  }];
337 #endif /* SDL_JOYSTICK_MFI */
338  }
339 
340  return 0;
341 }

References sort_controllers::controllers, IOS_AddJoystickDevice(), NULL, SDL_AddHintCallback, SDL_FALSE, SDL_GetHintBoolean, SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION, and SDL_TRUE.

◆ IOS_JoystickOpen()

static int IOS_JoystickOpen ( SDL_Joystick *  joystick,
int  device_index 
)
static

Definition at line 388 of file SDL_sysjoystick.m.

389 {
391  if (device == NULL) {
392  return SDL_SetError("Could not open Joystick: no hardware device for the specified index");
393  }
394 
395  joystick->hwdata = device;
396  joystick->instance_id = device->instance_id;
397 
398  joystick->naxes = device->naxes;
399  joystick->nhats = device->nhats;
400  joystick->nbuttons = device->nbuttons;
401  joystick->nballs = 0;
402 
403  device->joystick = joystick;
404 
405  @autoreleasepool {
406  if (device->accelerometer) {
407 #if !TARGET_OS_TV
408  if (motionManager == nil) {
409  motionManager = [[CMMotionManager alloc] init];
410  }
411 
412  /* Shorter times between updates can significantly increase CPU usage. */
413  motionManager.accelerometerUpdateInterval = 0.1;
414  [motionManager startAccelerometerUpdates];
415 #endif /* !TARGET_OS_TV */
416  } else {
417 #ifdef SDL_JOYSTICK_MFI
418  GCController *controller = device->controller;
419  controller.controllerPausedHandler = ^(GCController *c) {
420  if (joystick->hwdata) {
421  ++joystick->hwdata->num_pause_presses;
422  }
423  };
424 #endif /* SDL_JOYSTICK_MFI */
425  }
426  }
427  if (device->remote) {
429  }
430 
431  return 0;
432 }

References device, GetDeviceForIndex(), motionManager, NULL, SDL_AppleTVRemoteOpenedAsJoystick, and SDL_SetError.

◆ IOS_JoystickQuit()

static void IOS_JoystickQuit ( void  )
static

Definition at line 684 of file SDL_sysjoystick.m.

685 {
686  @autoreleasepool {
687 #ifdef SDL_JOYSTICK_MFI
688  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
689 
690  if (connectObserver) {
691  [center removeObserver:connectObserver name:GCControllerDidConnectNotification object:nil];
692  connectObserver = nil;
693  }
694 
695  if (disconnectObserver) {
696  [center removeObserver:disconnectObserver name:GCControllerDidDisconnectNotification object:nil];
697  disconnectObserver = nil;
698  }
699 
700 #if TARGET_OS_TV
702  SDL_AppleTVRemoteRotationHintChanged, NULL);
703 #endif /* TARGET_OS_TV */
704 #endif /* SDL_JOYSTICK_MFI */
705 
706  while (deviceList != NULL) {
708  }
709 
710 #if !TARGET_OS_TV
711  motionManager = nil;
712 #endif /* !TARGET_OS_TV */
713  }
714 
715  numjoysticks = 0;
716 }

References deviceList, IOS_RemoveJoystickDevice(), motionManager, NULL, numjoysticks, SDL_DelHintCallback, and SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION.

◆ IOS_JoystickRumble()

static int IOS_JoystickRumble ( SDL_Joystick *  joystick,
Uint16  low_frequency_rumble,
Uint16  high_frequency_rumble,
Uint32  duration_ms 
)
static

Definition at line 633 of file SDL_sysjoystick.m.

634 {
635  return SDL_Unsupported();
636 }

References SDL_Unsupported.

◆ IOS_JoystickUpdate()

static void IOS_JoystickUpdate ( SDL_Joystick *  joystick)
static

Definition at line 639 of file SDL_sysjoystick.m.

640 {
641  SDL_JoystickDeviceItem *device = joystick->hwdata;
642 
643  if (device == NULL) {
644  return;
645  }
646 
647  if (device->accelerometer) {
648  IOS_AccelerometerUpdate(joystick);
649  } else if (device->controller) {
650  IOS_MFIJoystickUpdate(joystick);
651  }
652 }

References device, IOS_AccelerometerUpdate(), IOS_MFIJoystickUpdate(), and NULL.

◆ IOS_MFIJoystickUpdate()

static void IOS_MFIJoystickUpdate ( SDL_Joystick *  joystick)
static

Definition at line 505 of file SDL_sysjoystick.m.

506 {
507 #if SDL_JOYSTICK_MFI
508  @autoreleasepool {
509  GCController *controller = joystick->hwdata->controller;
510  Uint8 hatstate = SDL_HAT_CENTERED;
511  int i;
512  int updateplayerindex = 0;
513 
514  if (controller.extendedGamepad) {
515  GCExtendedGamepad *gamepad = controller.extendedGamepad;
516 
517  /* Axis order matches the XInput Windows mappings. */
518  Sint16 axes[] = {
519  (Sint16) (gamepad.leftThumbstick.xAxis.value * 32767),
520  (Sint16) (gamepad.leftThumbstick.yAxis.value * -32767),
521  (Sint16) ((gamepad.leftTrigger.value * 65535) - 32768),
522  (Sint16) (gamepad.rightThumbstick.xAxis.value * 32767),
523  (Sint16) (gamepad.rightThumbstick.yAxis.value * -32767),
524  (Sint16) ((gamepad.rightTrigger.value * 65535) - 32768),
525  };
526 
527  /* Button order matches the XInput Windows mappings. */
528  Uint8 buttons[] = {
529  gamepad.buttonA.isPressed, gamepad.buttonB.isPressed,
530  gamepad.buttonX.isPressed, gamepad.buttonY.isPressed,
531  gamepad.leftShoulder.isPressed,
532  gamepad.rightShoulder.isPressed,
533  };
534 
535  hatstate = IOS_MFIJoystickHatStateForDPad(gamepad.dpad);
536 
537  for (i = 0; i < SDL_arraysize(axes); i++) {
538  /* The triggers (axes 2 and 5) are resting at -32768 but SDL
539  * initializes its values to 0. We only want to make sure the
540  * player index is up to date if the user actually moves an axis. */
541  if ((i != 2 && i != 5) || axes[i] != -32768) {
542  updateplayerindex |= (joystick->axes[i].value != axes[i]);
543  }
544  SDL_PrivateJoystickAxis(joystick, i, axes[i]);
545  }
546 
547  for (i = 0; i < SDL_arraysize(buttons); i++) {
548  updateplayerindex |= (joystick->buttons[i] != buttons[i]);
549  SDL_PrivateJoystickButton(joystick, i, buttons[i]);
550  }
551  } else if (controller.gamepad) {
552  GCGamepad *gamepad = controller.gamepad;
553 
554  /* Button order matches the XInput Windows mappings. */
555  Uint8 buttons[] = {
556  gamepad.buttonA.isPressed, gamepad.buttonB.isPressed,
557  gamepad.buttonX.isPressed, gamepad.buttonY.isPressed,
558  gamepad.leftShoulder.isPressed,
559  gamepad.rightShoulder.isPressed,
560  };
561 
562  hatstate = IOS_MFIJoystickHatStateForDPad(gamepad.dpad);
563 
564  for (i = 0; i < SDL_arraysize(buttons); i++) {
565  updateplayerindex |= (joystick->buttons[i] != buttons[i]);
566  SDL_PrivateJoystickButton(joystick, i, buttons[i]);
567  }
568  }
569 #if TARGET_OS_TV
570  else if (controller.microGamepad) {
571  GCMicroGamepad *gamepad = controller.microGamepad;
572 
573  Sint16 axes[] = {
574  (Sint16) (gamepad.dpad.xAxis.value * 32767),
575  (Sint16) (gamepad.dpad.yAxis.value * -32767),
576  };
577 
578  for (i = 0; i < SDL_arraysize(axes); i++) {
579  updateplayerindex |= (joystick->axes[i].value != axes[i]);
580  SDL_PrivateJoystickAxis(joystick, i, axes[i]);
581  }
582 
583  Uint8 buttons[] = {
584  gamepad.buttonA.isPressed,
585  gamepad.buttonX.isPressed,
586  };
587 
588  for (i = 0; i < SDL_arraysize(buttons); i++) {
589  updateplayerindex |= (joystick->buttons[i] != buttons[i]);
590  SDL_PrivateJoystickButton(joystick, i, buttons[i]);
591  }
592  }
593 #endif /* TARGET_OS_TV */
594 
595  if (joystick->nhats > 0) {
596  updateplayerindex |= (joystick->hats[0] != hatstate);
597  SDL_PrivateJoystickHat(joystick, 0, hatstate);
598  }
599 
600  for (i = 0; i < joystick->hwdata->num_pause_presses; i++) {
601  const Uint8 pausebutton = joystick->nbuttons - 1; /* The pause button is always last. */
602  SDL_PrivateJoystickButton(joystick, pausebutton, SDL_PRESSED);
603  SDL_PrivateJoystickButton(joystick, pausebutton, SDL_RELEASED);
604  updateplayerindex = YES;
605  }
606  joystick->hwdata->num_pause_presses = 0;
607 
608  if (updateplayerindex && controller.playerIndex == -1) {
609  BOOL usedPlayerIndexSlots[4] = {NO, NO, NO, NO};
610 
611  /* Find the player index of all other connected controllers. */
612  for (GCController *c in [GCController controllers]) {
613  if (c != controller && c.playerIndex >= 0) {
614  usedPlayerIndexSlots[c.playerIndex] = YES;
615  }
616  }
617 
618  /* Set this controller's player index to the first unused index.
619  * FIXME: This logic isn't great... but SDL doesn't expose this
620  * concept in its external API, so we don't have much to go on. */
621  for (i = 0; i < SDL_arraysize(usedPlayerIndexSlots); i++) {
622  if (!usedPlayerIndexSlots[i]) {
623  controller.playerIndex = i;
624  break;
625  }
626  }
627  }
628  }
629 #endif /* SDL_JOYSTICK_MFI */
630 }

References sort_controllers::controllers, i, SDL_arraysize, SDL_HAT_CENTERED, SDL_PRESSED, SDL_PrivateJoystickAxis(), SDL_PrivateJoystickButton(), SDL_PrivateJoystickHat(), and SDL_RELEASED.

Referenced by IOS_JoystickUpdate().

◆ IOS_RemoveJoystickDevice()

static SDL_JoystickDeviceItem* IOS_RemoveJoystickDevice ( SDL_JoystickDeviceItem device)
static

Definition at line 218 of file SDL_sysjoystick.m.

219 {
223 
224  if (device == NULL) {
225  return NULL;
226  }
227 
228  next = device->next;
229 
230  while (item != NULL) {
231  if (item == device) {
232  break;
233  }
234  prev = item;
235  item = item->next;
236  }
237 
238  /* Unlink the device item from the device list. */
239  if (prev) {
240  prev->next = device->next;
241  } else if (device == deviceList) {
242  deviceList = device->next;
243  }
244 
245  if (device->joystick) {
246  device->joystick->hwdata = NULL;
247  }
248 
249 #ifdef SDL_JOYSTICK_MFI
250  @autoreleasepool {
251  if (device->controller) {
252  /* The controller was explicitly retained in the struct, so it
253  * should be explicitly released before freeing the struct. */
254  GCController *controller = CFBridgingRelease((__bridge CFTypeRef)(device->controller));
255  controller.controllerPausedHandler = nil;
256  device->controller = nil;
257  }
258  }
259 #endif /* SDL_JOYSTICK_MFI */
260 
261  --numjoysticks;
262 
263  SDL_PrivateJoystickRemoved(device->instance_id);
264 
265  SDL_free(device->name);
266  SDL_free(device);
267 
268  return next;
269 }

References device, deviceList, recDevice::next, NULL, numjoysticks, SDL_free, and SDL_PrivateJoystickRemoved().

Referenced by IOS_JoystickQuit().

Variable Documentation

◆ accelerometerName

const char* accelerometerName = "iOS Accelerometer"
static

Definition at line 54 of file SDL_sysjoystick.m.

Referenced by IOS_AddJoystickDevice().

◆ deviceList

◆ motionManager

CMMotionManager* motionManager = nil
static

Definition at line 55 of file SDL_sysjoystick.m.

Referenced by IOS_AccelerometerUpdate(), IOS_JoystickOpen(), and IOS_JoystickQuit().

◆ numjoysticks

int numjoysticks = 0
static

◆ SDL_AppleTVRemoteOpenedAsJoystick

int SDL_AppleTVRemoteOpenedAsJoystick = 0

Definition at line 61 of file SDL_sysjoystick.m.

Referenced by IOS_JoystickClose(), and IOS_JoystickOpen().

◆ SDL_IOS_JoystickDriver

SDL_zero
#define SDL_zero(x)
Definition: SDL_stdinc.h:416
IOS_JoystickGetDeviceInstanceID
static SDL_JoystickID IOS_JoystickGetDeviceInstanceID(int device_index)
Definition: SDL_sysjoystick.m:381
Uint8
uint8_t Uint8
Definition: SDL_stdinc.h:179
c
const GLubyte * c
Definition: SDL_opengl_glext.h:11093
IOS_AddMFIJoystickDevice
static void IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controller)
Definition: SDL_sysjoystick.m:81
Uint16
uint16_t Uint16
Definition: SDL_stdinc.h:191
SDL_HINT_TV_REMOTE_AS_JOYSTICK
#define SDL_HINT_TV_REMOTE_AS_JOYSTICK
A variable controlling whether the Android / tvOS remotes should be listed as joystick devices,...
Definition: SDL_hints.h:409
IOS_JoystickRumble
static int IOS_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
Definition: SDL_sysjoystick.m:633
in
GLuint in
Definition: SDL_opengl_glext.h:7940
numjoysticks
static int numjoysticks
Definition: SDL_sysjoystick.m:60
SDL_HAT_CENTERED
#define SDL_HAT_CENTERED
Definition: SDL_joystick.h:329
NULL
#define NULL
Definition: begin_code.h:164
GetDeviceForIndex
static SDL_JoystickDeviceItem * GetDeviceForIndex(int device_index)
Definition: SDL_sysjoystick.m:64
IOS_JoystickGetDeviceGUID
static SDL_JoystickGUID IOS_JoystickGetDeviceGUID(int device_index)
Definition: SDL_sysjoystick.m:368
IOS_MFIJoystickUpdate
static void IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
Definition: SDL_sysjoystick.m:505
IOS_AccelerometerUpdate
static void IOS_AccelerometerUpdate(SDL_Joystick *joystick)
Definition: SDL_sysjoystick.m:435
SDL_PrivateJoystickAdded
void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance)
Definition: SDL_joystick.c:751
IOS_JoystickDetect
static void IOS_JoystickDetect(void)
Definition: SDL_sysjoystick.m:350
deviceList
static SDL_JoystickDeviceItem * deviceList
Definition: SDL_sysjoystick.m:58
SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION
#define SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION
A variable controlling whether the Apple TV remote's joystick axes will automatically match the rotat...
Definition: SDL_hints.h:378
SDL_GetNextJoystickInstanceID
SDL_JoystickID SDL_GetNextJoystickInstanceID()
Definition: SDL_joystick.c:163
IOS_JoystickClose
static void IOS_JoystickClose(SDL_Joystick *joystick)
Definition: SDL_sysjoystick.m:655
SDL_RELEASED
#define SDL_RELEASED
Definition: SDL_events.h:49
SDL_SwapLE16
#define SDL_SwapLE16(X)
Definition: SDL_endian.h:232
IOS_JoystickOpen
static int IOS_JoystickOpen(SDL_Joystick *joystick, int device_index)
Definition: SDL_sysjoystick.m:388
SDL_PrivateJoystickRemoved
void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
Definition: SDL_joystick.c:800
SDL_PrivateJoystickAxis
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
Definition: SDL_joystick.c:828
hid_device_info::next
struct hid_device_info * next
Definition: hidapi.h:82
SDL_PRESSED
#define SDL_PRESSED
Definition: SDL_events.h:50
Sint16
int16_t Sint16
Definition: SDL_stdinc.h:185
joystick_hwdata::next
struct joystick_hwdata * next
Definition: SDL_sysjoystick_c.h:49
SDL_HINT_ACCELEROMETER_AS_JOYSTICK
#define SDL_HINT_ACCELEROMETER_AS_JOYSTICK
A variable controlling whether the Android / iOS built-in accelerometer should be listed as a joystic...
Definition: SDL_hints.h:399
SDL_memcpy
#define SDL_memcpy
Definition: SDL_dynapi_overrides.h:387
SDL_GetHintBoolean
#define SDL_GetHintBoolean
Definition: SDL_dynapi_overrides.h:608
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
IOS_JoystickGetDeviceName
static const char * IOS_JoystickGetDeviceName(int device_index)
Definition: SDL_sysjoystick.m:355
SDL_max
#define SDL_max(x, y)
Definition: SDL_stdinc.h:407
IOS_JoystickQuit
static void IOS_JoystickQuit(void)
Definition: SDL_sysjoystick.m:684
name
GLuint const GLchar * name
Definition: SDL_opengl_glext.h:660
SDL_IPHONE_MAX_GFORCE
#define SDL_IPHONE_MAX_GFORCE
Definition: SDL_config_iphoneos.h:196
SDL_PrivateJoystickButton
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
Definition: SDL_joystick.c:961
SDL_min
#define SDL_min(x, y)
Definition: SDL_stdinc.h:406
SDL_AppleTVRemoteOpenedAsJoystick
int SDL_AppleTVRemoteOpenedAsJoystick
Definition: SDL_sysjoystick.m:61
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
IOS_JoystickInit
static int IOS_JoystickInit(void)
Definition: SDL_sysjoystick.m:288
SDL_PrivateJoystickHat
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
Definition: SDL_joystick.c:885
SDL_arraysize
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115
SDL_calloc
#define SDL_calloc
Definition: SDL_dynapi_overrides.h:375
sort_controllers.controllers
list controllers
Definition: sort_controllers.py:12
motionManager
static CMMotionManager * motionManager
Definition: SDL_sysjoystick.m:55
IOS_JoystickGetCount
static int IOS_JoystickGetCount(void)
Definition: SDL_sysjoystick.m:344
SDL_AddHintCallback
#define SDL_AddHintCallback
Definition: SDL_dynapi_overrides.h:192
value
GLsizei const GLfloat * value
Definition: SDL_opengl_glext.h:698
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
IOS_JoystickGetDevicePlayerIndex
static int IOS_JoystickGetDevicePlayerIndex(int device_index)
Definition: SDL_sysjoystick.m:362
IOS_JoystickUpdate
static void IOS_JoystickUpdate(SDL_Joystick *joystick)
Definition: SDL_sysjoystick.m:639
SDL_strdup
#define SDL_strdup
Definition: SDL_dynapi_overrides.h:397
SDL_strlen
#define SDL_strlen
Definition: SDL_dynapi_overrides.h:393
SDL_HARDWARE_BUS_BLUETOOTH
#define SDL_HARDWARE_BUS_BLUETOOTH
Definition: SDL_sysjoystick.h:87
IOS_RemoveJoystickDevice
static SDL_JoystickDeviceItem * IOS_RemoveJoystickDevice(SDL_JoystickDeviceItem *device)
Definition: SDL_sysjoystick.m:218
SDL_DelHintCallback
#define SDL_DelHintCallback
Definition: SDL_dynapi_overrides.h:193
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
SDL_Unsupported
#define SDL_Unsupported()
Definition: SDL_error.h:53
device
static SDL_AudioDeviceID device
Definition: loopwave.c:37
SDL_JoystickGUID
Definition: SDL_joystick.h:70
i
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)
Definition: SDL_x11sym.h:50
accelerometerName
static const char * accelerometerName
Definition: SDL_sysjoystick.m:54
IOS_AddJoystickDevice
static void IOS_AddJoystickDevice(GCController *controller, SDL_bool accelerometer)
Definition: SDL_sysjoystick.m:157
joystick_hwdata
Definition: SDL_sysjoystick_c.h:47