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.

References device, deviceList, i, recDevice::next, and NULL.

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

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 }
static SDL_JoystickDeviceItem * deviceList
struct joystick_hwdata * next
static SDL_AudioDeviceID device
Definition: loopwave.c:37
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
#define NULL
Definition: begin_code.h:164

◆ IOS_AccelerometerUpdate()

static void IOS_AccelerometerUpdate ( SDL_Joystick *  joystick)
static

Definition at line 435 of file SDL_sysjoystick.m.

References motionManager, SDL_HAT_CENTERED, SDL_HAT_DOWN, SDL_HAT_LEFT, SDL_HAT_RIGHT, SDL_HAT_UP, SDL_IPHONE_MAX_GFORCE, SDL_max, SDL_min, and SDL_PrivateJoystickAxis().

Referenced by IOS_JoystickUpdate().

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 }
#define SDL_min(x, y)
Definition: SDL_stdinc.h:406
#define SDL_max(x, y)
Definition: SDL_stdinc.h:407
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
Definition: SDL_joystick.c:828
#define SDL_IPHONE_MAX_GFORCE
static CMMotionManager * motionManager

◆ IOS_AddJoystickDevice()

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

Definition at line 157 of file SDL_sysjoystick.m.

References recDevice::accelerometer, accelerometerName, recDevice::controller, SDL_JoystickGUID::data, device, deviceList, recDevice::guid, recDevice::instance_id, IOS_AddMFIJoystickDevice(), recDevice::name, recDevice::naxes, recDevice::nbuttons, recDevice::next, recDevice::nhats, 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().

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;
184 
185  if (accelerometer) {
186 #if TARGET_OS_TV
187  SDL_free(device);
188  return;
189 #else
190  device->name = SDL_strdup(accelerometerName);
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 
215 }
#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
#define SDL_min(x, y)
Definition: SDL_stdinc.h:406
SDL_JoystickGUID guid
static SDL_JoystickDeviceItem * deviceList
static const char * accelerometerName
struct joystick_hwdata * next
Uint8 data[16]
Definition: SDL_joystick.h:71
#define SDL_GetHintBoolean
static SDL_AudioDeviceID device
Definition: loopwave.c:37
#define SDL_memcpy
#define SDL_free
static void IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controller)
void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance)
Definition: SDL_joystick.c:751
#define NULL
Definition: begin_code.h:164
#define SDL_calloc
SDL_JoystickID SDL_GetNextJoystickInstanceID()
Definition: SDL_joystick.c:163
#define SDL_strlen
#define SDL_strdup
static int numjoysticks
GCController __unsafe_unretained * controller

◆ IOS_AddMFIJoystickDevice()

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

Definition at line 81 of file SDL_sysjoystick.m.

References recDevice::controller, SDL_JoystickGUID::data, recDevice::guid, recDevice::name, recDevice::naxes, recDevice::nbuttons, recDevice::nhats, 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().

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 }
SDL_JoystickGUID guid
#define SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION
A variable controlling whether the Apple TV remote&#39;s joystick axes will automatically match the rotat...
Definition: SDL_hints.h:378
uint16_t Uint16
Definition: SDL_stdinc.h:191
Uint8 data[16]
Definition: SDL_joystick.h:71
GLuint const GLchar * name
#define SDL_GetHintBoolean
#define SDL_HARDWARE_BUS_BLUETOOTH
uint8_t Uint8
Definition: SDL_stdinc.h:179
#define NULL
Definition: begin_code.h:164
#define SDL_strdup
#define SDL_SwapLE16(X)
Definition: SDL_endian.h:232
GCController __unsafe_unretained * controller

◆ IOS_JoystickClose()

static void IOS_JoystickClose ( SDL_Joystick *  joystick)
static

Definition at line 655 of file SDL_sysjoystick.m.

References recDevice::accelerometer, recDevice::controller, device, recDevice::joystick, NULL, recDevice::remote, and SDL_AppleTVRemoteOpenedAsJoystick.

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 }
SDL_Joystick * joystick
static SDL_AudioDeviceID device
Definition: loopwave.c:37
#define NULL
Definition: begin_code.h:164
int SDL_AppleTVRemoteOpenedAsJoystick
GCController __unsafe_unretained * controller

◆ 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.

References numjoysticks.

345 {
346  return numjoysticks;
347 }
static int numjoysticks

◆ IOS_JoystickGetDeviceGUID()

static SDL_JoystickGUID IOS_JoystickGetDeviceGUID ( int  device_index)
static

Definition at line 368 of file SDL_sysjoystick.m.

References device, GetDeviceForIndex(), recDevice::guid, and SDL_zero.

369 {
371  SDL_JoystickGUID guid;
372  if (device) {
373  guid = device->guid;
374  } else {
375  SDL_zero(guid);
376  }
377  return guid;
378 }
SDL_JoystickGUID guid
static SDL_JoystickDeviceItem * GetDeviceForIndex(int device_index)
static SDL_AudioDeviceID device
Definition: loopwave.c:37
#define SDL_zero(x)
Definition: SDL_stdinc.h:416

◆ IOS_JoystickGetDeviceInstanceID()

static SDL_JoystickID IOS_JoystickGetDeviceInstanceID ( int  device_index)
static

Definition at line 381 of file SDL_sysjoystick.m.

References device, GetDeviceForIndex(), and recDevice::instance_id.

382 {
384  return device ? device->instance_id : -1;
385 }
static SDL_JoystickDeviceItem * GetDeviceForIndex(int device_index)
static SDL_AudioDeviceID device
Definition: loopwave.c:37

◆ IOS_JoystickGetDeviceName()

static const char* IOS_JoystickGetDeviceName ( int  device_index)
static

Definition at line 355 of file SDL_sysjoystick.m.

References device, GetDeviceForIndex(), and recDevice::name.

356 {
358  return device ? device->name : "Unknown";
359 }
static SDL_JoystickDeviceItem * GetDeviceForIndex(int device_index)
static SDL_AudioDeviceID device
Definition: loopwave.c:37

◆ 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.

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.

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 }
#define SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION
A variable controlling whether the Apple TV remote&#39;s joystick axes will automatically match the rotat...
Definition: SDL_hints.h:378
#define SDL_GetHintBoolean
#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
#define NULL
Definition: begin_code.h:164
#define SDL_AddHintCallback
static void IOS_AddJoystickDevice(GCController *controller, SDL_bool accelerometer)
GLuint in

◆ IOS_JoystickOpen()

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

Definition at line 388 of file SDL_sysjoystick.m.

References recDevice::accelerometer, recDevice::controller, device, GetDeviceForIndex(), recDevice::instance_id, recDevice::joystick, motionManager, recDevice::naxes, recDevice::nbuttons, recDevice::nhats, NULL, recDevice::remote, SDL_AppleTVRemoteOpenedAsJoystick, and SDL_SetError.

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 }
SDL_Joystick * joystick
static SDL_JoystickDeviceItem * GetDeviceForIndex(int device_index)
static SDL_AudioDeviceID device
Definition: loopwave.c:37
const GLubyte * c
#define NULL
Definition: begin_code.h:164
#define SDL_SetError
int SDL_AppleTVRemoteOpenedAsJoystick
GCController __unsafe_unretained * controller
static CMMotionManager * motionManager

◆ IOS_JoystickQuit()

static void IOS_JoystickQuit ( void  )
static

Definition at line 684 of file SDL_sysjoystick.m.

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

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 }
static SDL_JoystickDeviceItem * IOS_RemoveJoystickDevice(SDL_JoystickDeviceItem *device)
static SDL_JoystickDeviceItem * deviceList
#define SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION
A variable controlling whether the Apple TV remote&#39;s joystick axes will automatically match the rotat...
Definition: SDL_hints.h:378
#define NULL
Definition: begin_code.h:164
#define SDL_DelHintCallback
static int numjoysticks
static CMMotionManager * motionManager

◆ 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.

References SDL_Unsupported.

634 {
635  return SDL_Unsupported();
636 }
#define SDL_Unsupported()
Definition: SDL_error.h:53

◆ IOS_JoystickUpdate()

static void IOS_JoystickUpdate ( SDL_Joystick *  joystick)
static

Definition at line 639 of file SDL_sysjoystick.m.

References recDevice::accelerometer, recDevice::controller, device, IOS_AccelerometerUpdate(), IOS_MFIJoystickUpdate(), and NULL.

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 }
static void IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
static SDL_AudioDeviceID device
Definition: loopwave.c:37
static void IOS_AccelerometerUpdate(SDL_Joystick *joystick)
#define NULL
Definition: begin_code.h:164
GCController __unsafe_unretained * controller

◆ IOS_MFIJoystickUpdate()

static void IOS_MFIJoystickUpdate ( SDL_Joystick *  joystick)
static

Definition at line 505 of file SDL_sysjoystick.m.

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().

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 }
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
Definition: SDL_joystick.c:885
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
Definition: SDL_joystick.c:961
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
Definition: SDL_joystick.c:828
uint8_t Uint8
Definition: SDL_stdinc.h:179
const GLubyte * c
GLsizei const GLfloat * value
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
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115
#define SDL_PRESSED
Definition: SDL_events.h:50
#define SDL_HAT_CENTERED
Definition: SDL_joystick.h:329
#define SDL_RELEASED
Definition: SDL_events.h:49
GLuint in
int16_t Sint16
Definition: SDL_stdinc.h:185

◆ IOS_RemoveJoystickDevice()

static SDL_JoystickDeviceItem* IOS_RemoveJoystickDevice ( SDL_JoystickDeviceItem device)
static

Definition at line 218 of file SDL_sysjoystick.m.

References recDevice::controller, sort_controllers::controllers, deviceList, recDevice::instance_id, recDevice::joystick, recDevice::name, recDevice::next, NULL, numjoysticks, SDL_free, SDL_PrivateJoystickRemoved(), and SDLCALL.

Referenced by IOS_JoystickQuit().

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 
264 
265  SDL_free(device->name);
266  SDL_free(device);
267 
268  return next;
269 }
void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
Definition: SDL_joystick.c:800
static SDL_JoystickDeviceItem * deviceList
SDL_Joystick * joystick
struct joystick_hwdata * next
struct hid_device_info * next
Definition: hidapi.h:82
#define SDL_free
#define NULL
Definition: begin_code.h:164
static int numjoysticks
GCController __unsafe_unretained * controller

Variable Documentation

◆ accelerometerName

const char* accelerometerName = "iOS Accelerometer"
static

Definition at line 54 of file SDL_sysjoystick.m.

Referenced by IOS_AddJoystickDevice().

◆ deviceList

SDL_JoystickDeviceItem* deviceList = NULL
static

◆ 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_JoystickDriver SDL_IOS_JoystickDriver
Initial value:
=
{
}
static int IOS_JoystickGetCount(void)
static void IOS_JoystickUpdate(SDL_Joystick *joystick)
static int IOS_JoystickInit(void)
static void IOS_JoystickDetect(void)
static SDL_JoystickID IOS_JoystickGetDeviceInstanceID(int device_index)
static const char * IOS_JoystickGetDeviceName(int device_index)
static void IOS_JoystickQuit(void)
static int IOS_JoystickOpen(SDL_Joystick *joystick, int device_index)
static SDL_JoystickGUID IOS_JoystickGetDeviceGUID(int device_index)
static int IOS_JoystickGetDevicePlayerIndex(int device_index)
static int IOS_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
static void IOS_JoystickClose(SDL_Joystick *joystick)

Definition at line 718 of file SDL_sysjoystick.m.