SDL  2.0
SDL_sysjoystick.m File Reference
#include "../../SDL_internal.h"
#include "SDL_sysjoystick_c.h"
#include "SDL_config_iphoneos.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 SDL_SYS_AddMFIJoystickDevice (SDL_JoystickDeviceItem *device, GCController *controller)
 
static void SDL_SYS_AddJoystickDevice (GCController *controller, SDL_bool accelerometer)
 
static SDL_JoystickDeviceItemSDL_SYS_RemoveJoystickDevice (SDL_JoystickDeviceItem *device)
 
int SDL_SYS_JoystickInit (void)
 
int SDL_SYS_NumJoysticks (void)
 
void SDL_SYS_JoystickDetect (void)
 
const char * SDL_SYS_JoystickNameForDeviceIndex (int device_index)
 
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex (int device_index)
 
int SDL_SYS_JoystickOpen (SDL_Joystick *joystick, int device_index)
 
SDL_bool SDL_SYS_JoystickAttached (SDL_Joystick *joystick)
 
static void SDL_SYS_AccelerometerUpdate (SDL_Joystick *joystick)
 
static void SDL_SYS_MFIJoystickUpdate (SDL_Joystick *joystick)
 
void SDL_SYS_JoystickUpdate (SDL_Joystick *joystick)
 
void SDL_SYS_JoystickClose (SDL_Joystick *joystick)
 
void SDL_SYS_JoystickQuit (void)
 
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID (int device_index)
 
SDL_JoystickGUID SDL_SYS_JoystickGetGUID (SDL_Joystick *joystick)
 

Variables

static const char * accelerometerName = "iOS Accelerometer"
 
static CMMotionManager * motionManager = nil
 
static SDL_JoystickDeviceItemdeviceList = NULL
 
static int numjoysticks = 0
 
static SDL_JoystickID instancecounter = 0
 

Function Documentation

static SDL_JoystickDeviceItem* GetDeviceForIndex ( int  device_index)
static

Definition at line 62 of file SDL_sysjoystick.m.

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

Referenced by SDL_SYS_GetInstanceIdOfDeviceIndex(), SDL_SYS_JoystickGetDeviceGUID(), SDL_SYS_JoystickNameForDeviceIndex(), and SDL_SYS_JoystickOpen().

63 {
65  int i = 0;
66 
67  while (i < device_index) {
68  if (device == NULL) {
69  return NULL;
70  }
71  device = device->next;
72  i++;
73  }
74 
75  return device;
76 }
static SDL_JoystickDeviceItem * deviceList
struct joystick_hwdata * next
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
static SDL_AudioDeviceID device
Definition: loopwave.c:37
#define NULL
Definition: begin_code.h:164
static void SDL_SYS_AccelerometerUpdate ( SDL_Joystick *  joystick)
static

Definition at line 412 of file SDL_sysjoystick.m.

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

Referenced by SDL_SYS_JoystickUpdate().

413 {
414 #if !TARGET_OS_TV
415  const float maxgforce = SDL_IPHONE_MAX_GFORCE;
416  const SInt16 maxsint16 = 0x7FFF;
417  CMAcceleration accel;
418 
419  @autoreleasepool {
420  if (!motionManager.isAccelerometerActive) {
421  return;
422  }
423 
424  accel = motionManager.accelerometerData.acceleration;
425  }
426 
427  /*
428  Convert accelerometer data from floating point to Sint16, which is what
429  the joystick system expects.
430 
431  To do the conversion, the data is first clamped onto the interval
432  [-SDL_IPHONE_MAX_G_FORCE, SDL_IPHONE_MAX_G_FORCE], then the data is multiplied
433  by MAX_SINT16 so that it is mapped to the full range of an Sint16.
434 
435  You can customize the clamped range of this function by modifying the
436  SDL_IPHONE_MAX_GFORCE macro in SDL_config_iphoneos.h.
437 
438  Once converted to Sint16, the accelerometer data no longer has coherent
439  units. You can convert the data back to units of g-force by multiplying
440  it in your application's code by SDL_IPHONE_MAX_GFORCE / 0x7FFF.
441  */
442 
443  /* clamp the data */
444  accel.x = SDL_min(SDL_max(accel.x, -maxgforce), maxgforce);
445  accel.y = SDL_min(SDL_max(accel.y, -maxgforce), maxgforce);
446  accel.z = SDL_min(SDL_max(accel.z, -maxgforce), maxgforce);
447 
448  /* pass in data mapped to range of SInt16 */
449  SDL_PrivateJoystickAxis(joystick, 0, (accel.x / maxgforce) * maxsint16);
450  SDL_PrivateJoystickAxis(joystick, 1, -(accel.y / maxgforce) * maxsint16);
451  SDL_PrivateJoystickAxis(joystick, 2, (accel.z / maxgforce) * maxsint16);
452 #endif /* !TARGET_OS_TV */
453 }
#define SDL_min(x, y)
Definition: SDL_stdinc.h:375
#define SDL_max(x, y)
Definition: SDL_stdinc.h:376
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
Definition: SDL_joystick.c:661
#define SDL_IPHONE_MAX_GFORCE
static CMMotionManager * motionManager
static void SDL_SYS_AddJoystickDevice ( GCController *  controller,
SDL_bool  accelerometer 
)
static

Definition at line 146 of file SDL_sysjoystick.m.

References recDevice::accelerometer, accelerometerName, recDevice::controller, SDL_JoystickGUID::data, device, deviceList, recDevice::guid, recDevice::instance_id, instancecounter, recDevice::name, recDevice::naxes, recDevice::nbuttons, recDevice::next, recDevice::nhats, NULL, numjoysticks, SDL_free(), SDL_malloc, SDL_memcpy, SDL_min, SDL_PrivateJoystickAdded(), SDL_strdup, SDL_strlen, SDL_SYS_AddMFIJoystickDevice(), and SDL_zerop.

Referenced by SDL_SYS_JoystickInit().

147 {
149 
150  while (device != NULL) {
151  if (device->controller == controller) {
152  return;
153  }
154  device = device->next;
155  }
156 
158  if (device == NULL) {
159  return;
160  }
161 
162  SDL_zerop(device);
163 
164  device->accelerometer = accelerometer;
165  device->instance_id = instancecounter++;
166 
167  if (accelerometer) {
168 #if TARGET_OS_TV
169  SDL_free(device);
170  return;
171 #else
172  device->name = SDL_strdup(accelerometerName);
173  device->naxes = 3; /* Device acceleration in the x, y, and z axes. */
174  device->nhats = 0;
175  device->nbuttons = 0;
176 
177  /* Use the accelerometer name as a GUID. */
178  SDL_memcpy(&device->guid.data, device->name, SDL_min(sizeof(SDL_JoystickGUID), SDL_strlen(device->name)));
179 #endif /* TARGET_OS_TV */
180  } else if (controller) {
181  SDL_SYS_AddMFIJoystickDevice(device, controller);
182  }
183 
184  if (deviceList == NULL) {
185  deviceList = device;
186  } else {
187  SDL_JoystickDeviceItem *lastdevice = deviceList;
188  while (lastdevice->next != NULL) {
189  lastdevice = lastdevice->next;
190  }
191  lastdevice->next = device;
192  }
193 
194  ++numjoysticks;
195 
197 }
#define SDL_min(x, y)
Definition: SDL_stdinc.h:375
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_zerop(x)
Definition: SDL_stdinc.h:386
static SDL_AudioDeviceID device
Definition: loopwave.c:37
#define SDL_memcpy
void SDL_free(void *mem)
static void SDL_SYS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controller)
void SDL_PrivateJoystickAdded(int device_index)
Definition: SDL_joystick.c:595
#define NULL
Definition: begin_code.h:164
static SDL_JoystickID instancecounter
#define SDL_strlen
#define SDL_strdup
static int numjoysticks
#define SDL_malloc
GCController __unsafe_unretained * controller
static void SDL_SYS_AddMFIJoystickDevice ( SDL_JoystickDeviceItem device,
GCController *  controller 
)
static

Definition at line 79 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_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION, and SDL_strdup.

Referenced by SDL_SYS_AddJoystickDevice().

80 {
81 #ifdef SDL_JOYSTICK_MFI
82  const char *name = NULL;
83  /* Explicitly retain the controller because SDL_JoystickDeviceItem is a
84  * struct, and ARC doesn't work with structs. */
85  device->controller = (__bridge GCController *) CFBridgingRetain(controller);
86 
87  if (controller.vendorName) {
88  name = controller.vendorName.UTF8String;
89  }
90 
91  if (!name) {
92  name = "MFi Gamepad";
93  }
94 
95  device->name = SDL_strdup(name);
96 
97  device->guid.data[0] = 'M';
98  device->guid.data[1] = 'F';
99  device->guid.data[2] = 'i';
100  device->guid.data[3] = 'G';
101  device->guid.data[4] = 'a';
102  device->guid.data[5] = 'm';
103  device->guid.data[6] = 'e';
104  device->guid.data[7] = 'p';
105  device->guid.data[8] = 'a';
106  device->guid.data[9] = 'd';
107 
108  if (controller.extendedGamepad) {
109  device->guid.data[10] = 1;
110  } else if (controller.gamepad) {
111  device->guid.data[10] = 2;
112  }
113 #if TARGET_OS_TV
114  else if (controller.microGamepad) {
115  device->guid.data[10] = 3;
116  }
117 #endif /* TARGET_OS_TV */
118 
119  if (controller.extendedGamepad) {
120  device->naxes = 6; /* 2 thumbsticks and 2 triggers */
121  device->nhats = 1; /* d-pad */
122  device->nbuttons = 7; /* ABXY, shoulder buttons, pause button */
123  } else if (controller.gamepad) {
124  device->naxes = 0; /* no traditional analog inputs */
125  device->nhats = 1; /* d-pad */
126  device->nbuttons = 7; /* ABXY, shoulder buttons, pause button */
127  }
128 #if TARGET_OS_TV
129  else if (controller.microGamepad) {
130  device->naxes = 2; /* treat the touch surface as two axes */
131  device->nhats = 0; /* apparently the touch surface-as-dpad is buggy */
132  device->nbuttons = 3; /* AX, pause button */
133 
134  controller.microGamepad.allowsRotation = SDL_GetHintBoolean(SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION, SDL_FALSE);
135  }
136 #endif /* TARGET_OS_TV */
137 
138  /* This will be set when the first button press of the controller is
139  * detected. */
140  controller.playerIndex = -1;
141 
142 #endif /* SDL_JOYSTICK_MFI */
143 }
SDL_JoystickGUID guid
#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:355
Uint8 data[16]
Definition: SDL_joystick.h:71
GLuint const GLchar * name
#define SDL_GetHintBoolean
#define NULL
Definition: begin_code.h:164
#define SDL_strdup
GCController __unsafe_unretained * controller
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex ( int  device_index)

Definition at line 349 of file SDL_sysjoystick.m.

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

Referenced by SDL_GameControllerOpen(), and SDL_JoystickGetDeviceInstanceID().

350 {
352  return device ? device->instance_id : 0;
353 }
static SDL_JoystickDeviceItem * GetDeviceForIndex(int device_index)
static SDL_AudioDeviceID device
Definition: loopwave.c:37
SDL_bool SDL_SYS_JoystickAttached ( SDL_Joystick *  joystick)

Definition at line 406 of file SDL_sysjoystick.m.

References NULL.

Referenced by SDL_JoystickGetAttached().

407 {
408  return joystick->hwdata != NULL;
409 }
#define NULL
Definition: begin_code.h:164
void SDL_SYS_JoystickClose ( SDL_Joystick *  joystick)

Definition at line 641 of file SDL_sysjoystick.m.

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

Referenced by SDL_JoystickClose().

642 {
643  SDL_JoystickDeviceItem *device = joystick->hwdata;
644 
645  if (device == NULL) {
646  return;
647  }
648 
649  device->joystick = NULL;
650 
651  @autoreleasepool {
652  if (device->accelerometer) {
653 #if !TARGET_OS_TV
654  [motionManager stopAccelerometerUpdates];
655 #endif /* !TARGET_OS_TV */
656  } else if (device->controller) {
657 #ifdef SDL_JOYSTICK_MFI
658  GCController *controller = device->controller;
659  controller.controllerPausedHandler = nil;
660  controller.playerIndex = -1;
661 #endif
662  }
663  }
664 }
SDL_Joystick * joystick
static SDL_AudioDeviceID device
Definition: loopwave.c:37
#define NULL
Definition: begin_code.h:164
GCController __unsafe_unretained * controller
void SDL_SYS_JoystickDetect ( void  )

Definition at line 336 of file SDL_sysjoystick.m.

Referenced by SDL_JoystickUpdate().

337 {
338 }
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID ( int  device_index)

Definition at line 703 of file SDL_sysjoystick.m.

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

Referenced by SDL_JoystickGetDeviceGUID().

704 {
706  SDL_JoystickGUID guid;
707  if (device) {
708  guid = device->guid;
709  } else {
710  SDL_zero(guid);
711  }
712  return guid;
713 }
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:385
SDL_JoystickGUID SDL_SYS_JoystickGetGUID ( SDL_Joystick *  joystick)

Definition at line 716 of file SDL_sysjoystick.m.

References recDevice::guid, and SDL_zero.

Referenced by SDL_JoystickGetGUID().

717 {
718  SDL_JoystickGUID guid;
719  if (joystick->hwdata) {
720  guid = joystick->hwdata->guid;
721  } else {
722  SDL_zero(guid);
723  }
724  return guid;
725 }
#define SDL_zero(x)
Definition: SDL_stdinc.h:385
int SDL_SYS_JoystickInit ( void  )

Definition at line 274 of file SDL_sysjoystick.m.

References recDevice::controller, sort_controllers::controllers, NULL, numjoysticks, SDL_AddHintCallback, SDL_FALSE, SDL_GetHintBoolean, SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION, SDL_SYS_AddJoystickDevice(), and SDL_TRUE.

Referenced by SDL_JoystickInit().

275 {
276  @autoreleasepool {
277  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
278 
279 #if !TARGET_OS_TV
281  /* Default behavior, accelerometer as joystick */
283  }
284 #endif /* !TARGET_OS_TV */
285 
286 #ifdef SDL_JOYSTICK_MFI
287  /* GameController.framework was added in iOS 7. */
288  if (![GCController class]) {
289  return numjoysticks;
290  }
291 
292  for (GCController *controller in [GCController controllers]) {
294  }
295 
296 #if TARGET_OS_TV
298  SDL_AppleTVRemoteRotationHintChanged, NULL);
299 #endif /* TARGET_OS_TV */
300 
301  connectObserver = [center addObserverForName:GCControllerDidConnectNotification
302  object:nil
303  queue:nil
304  usingBlock:^(NSNotification *note) {
305  GCController *controller = note.object;
306  SDL_SYS_AddJoystickDevice(controller, SDL_FALSE);
307  }];
308 
309  disconnectObserver = [center addObserverForName:GCControllerDidDisconnectNotification
310  object:nil
311  queue:nil
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);
318  break;
319  }
320  device = device->next;
321  }
322  }];
323 #endif /* SDL_JOYSTICK_MFI */
324  }
325 
326  return numjoysticks;
327 }
#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:355
#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:366
#define NULL
Definition: begin_code.h:164
#define SDL_AddHintCallback
static int numjoysticks
GLuint in
static void SDL_SYS_AddJoystickDevice(GCController *controller, SDL_bool accelerometer)
const char* SDL_SYS_JoystickNameForDeviceIndex ( int  device_index)

Definition at line 342 of file SDL_sysjoystick.m.

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

Referenced by SDL_JoystickNameForIndex(), and SDL_JoystickOpen().

343 {
345  return device ? device->name : "Unknown";
346 }
static SDL_JoystickDeviceItem * GetDeviceForIndex(int device_index)
static SDL_AudioDeviceID device
Definition: loopwave.c:37
int SDL_SYS_JoystickOpen ( SDL_Joystick *  joystick,
int  device_index 
)

Definition at line 361 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, and SDL_SetError.

Referenced by SDL_JoystickOpen().

362 {
364  if (device == NULL) {
365  return SDL_SetError("Could not open Joystick: no hardware device for the specified index");
366  }
367 
368  joystick->hwdata = device;
369  joystick->instance_id = device->instance_id;
370 
371  joystick->naxes = device->naxes;
372  joystick->nhats = device->nhats;
373  joystick->nbuttons = device->nbuttons;
374  joystick->nballs = 0;
375 
376  device->joystick = joystick;
377 
378  @autoreleasepool {
379  if (device->accelerometer) {
380 #if !TARGET_OS_TV
381  if (motionManager == nil) {
382  motionManager = [[CMMotionManager alloc] init];
383  }
384 
385  /* Shorter times between updates can significantly increase CPU usage. */
386  motionManager.accelerometerUpdateInterval = 0.1;
387  [motionManager startAccelerometerUpdates];
388 #endif /* !TARGET_OS_TV */
389  } else {
390 #ifdef SDL_JOYSTICK_MFI
391  GCController *controller = device->controller;
392  controller.controllerPausedHandler = ^(GCController *c) {
393  if (joystick->hwdata) {
394  ++joystick->hwdata->num_pause_presses;
395  }
396  };
397 #endif /* SDL_JOYSTICK_MFI */
398  }
399  }
400 
401  return 0;
402 }
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
GCController __unsafe_unretained * controller
static CMMotionManager * motionManager
void SDL_SYS_JoystickQuit ( void  )

Definition at line 668 of file SDL_sysjoystick.m.

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

Referenced by SDL_JoystickQuit().

669 {
670  @autoreleasepool {
671 #ifdef SDL_JOYSTICK_MFI
672  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
673 
674  if (connectObserver) {
675  [center removeObserver:connectObserver name:GCControllerDidConnectNotification object:nil];
676  connectObserver = nil;
677  }
678 
679  if (disconnectObserver) {
680  [center removeObserver:disconnectObserver name:GCControllerDidDisconnectNotification object:nil];
681  disconnectObserver = nil;
682  }
683 
684 #if TARGET_OS_TV
686  SDL_AppleTVRemoteRotationHintChanged, NULL);
687 #endif /* TARGET_OS_TV */
688 #endif /* SDL_JOYSTICK_MFI */
689 
690  while (deviceList != NULL) {
692  }
693 
694 #if !TARGET_OS_TV
695  motionManager = nil;
696 #endif /* !TARGET_OS_TV */
697  }
698 
699  numjoysticks = 0;
700 }
static SDL_JoystickDeviceItem * deviceList
#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:355
#define NULL
Definition: begin_code.h:164
#define SDL_DelHintCallback
static SDL_JoystickDeviceItem * SDL_SYS_RemoveJoystickDevice(SDL_JoystickDeviceItem *device)
static int numjoysticks
static CMMotionManager * motionManager
void SDL_SYS_JoystickUpdate ( SDL_Joystick *  joystick)

Definition at line 624 of file SDL_sysjoystick.m.

References recDevice::accelerometer, recDevice::controller, device, NULL, SDL_SYS_AccelerometerUpdate(), and SDL_SYS_MFIJoystickUpdate().

Referenced by SDL_JoystickOpen(), and SDL_JoystickUpdate().

625 {
626  SDL_JoystickDeviceItem *device = joystick->hwdata;
627 
628  if (device == NULL) {
629  return;
630  }
631 
632  if (device->accelerometer) {
633  SDL_SYS_AccelerometerUpdate(joystick);
634  } else if (device->controller) {
635  SDL_SYS_MFIJoystickUpdate(joystick);
636  }
637 }
static void SDL_SYS_MFIJoystickUpdate(SDL_Joystick *joystick)
static SDL_AudioDeviceID device
Definition: loopwave.c:37
#define NULL
Definition: begin_code.h:164
static void SDL_SYS_AccelerometerUpdate(SDL_Joystick *joystick)
GCController __unsafe_unretained * controller
static void SDL_SYS_MFIJoystickUpdate ( SDL_Joystick *  joystick)
static

Definition at line 482 of file SDL_sysjoystick.m.

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

Referenced by SDL_SYS_JoystickUpdate().

483 {
484 #if SDL_JOYSTICK_MFI
485  @autoreleasepool {
486  GCController *controller = joystick->hwdata->controller;
487  Uint8 hatstate = SDL_HAT_CENTERED;
488  int i;
489  int updateplayerindex = 0;
490 
491  if (controller.extendedGamepad) {
492  GCExtendedGamepad *gamepad = controller.extendedGamepad;
493 
494  /* Axis order matches the XInput Windows mappings. */
495  Sint16 axes[] = {
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),
502  };
503 
504  /* Button order matches the XInput Windows mappings. */
505  Uint8 buttons[] = {
506  gamepad.buttonA.isPressed, gamepad.buttonB.isPressed,
507  gamepad.buttonX.isPressed, gamepad.buttonY.isPressed,
508  gamepad.leftShoulder.isPressed,
509  gamepad.rightShoulder.isPressed,
510  };
511 
512  hatstate = SDL_SYS_MFIJoystickHatStateForDPad(gamepad.dpad);
513 
514  for (i = 0; i < SDL_arraysize(axes); i++) {
515  /* The triggers (axes 2 and 5) are resting at -32768 but SDL
516  * initializes its values to 0. We only want to make sure the
517  * player index is up to date if the user actually moves an axis. */
518  if ((i != 2 && i != 5) || axes[i] != -32768) {
519  updateplayerindex |= (joystick->axes[i].value != axes[i]);
520  }
521  SDL_PrivateJoystickAxis(joystick, i, axes[i]);
522  }
523 
524  for (i = 0; i < SDL_arraysize(buttons); i++) {
525  updateplayerindex |= (joystick->buttons[i] != buttons[i]);
526  SDL_PrivateJoystickButton(joystick, i, buttons[i]);
527  }
528  } else if (controller.gamepad) {
529  GCGamepad *gamepad = controller.gamepad;
530 
531  /* Button order matches the XInput Windows mappings. */
532  Uint8 buttons[] = {
533  gamepad.buttonA.isPressed, gamepad.buttonB.isPressed,
534  gamepad.buttonX.isPressed, gamepad.buttonY.isPressed,
535  gamepad.leftShoulder.isPressed,
536  gamepad.rightShoulder.isPressed,
537  };
538 
539  hatstate = SDL_SYS_MFIJoystickHatStateForDPad(gamepad.dpad);
540 
541  for (i = 0; i < SDL_arraysize(buttons); i++) {
542  updateplayerindex |= (joystick->buttons[i] != buttons[i]);
543  SDL_PrivateJoystickButton(joystick, i, buttons[i]);
544  }
545  }
546 #if TARGET_OS_TV
547  else if (controller.microGamepad) {
548  GCMicroGamepad *gamepad = controller.microGamepad;
549 
550  Sint16 axes[] = {
551  (Sint16) (gamepad.dpad.xAxis.value * 32767),
552  (Sint16) (gamepad.dpad.yAxis.value * -32767),
553  };
554 
555  for (i = 0; i < SDL_arraysize(axes); i++) {
556  updateplayerindex |= (joystick->axes[i].value != axes[i]);
557  SDL_PrivateJoystickAxis(joystick, i, axes[i]);
558  }
559 
560  /* Apparently the dpad values are not accurate enough to be useful. */
561  /* hatstate = SDL_SYS_MFIJoystickHatStateForDPad(gamepad.dpad); */
562 
563  Uint8 buttons[] = {
564  gamepad.buttonA.isPressed,
565  gamepad.buttonX.isPressed,
566  };
567 
568  for (i = 0; i < SDL_arraysize(buttons); i++) {
569  updateplayerindex |= (joystick->buttons[i] != buttons[i]);
570  SDL_PrivateJoystickButton(joystick, i, buttons[i]);
571  }
572 
573  /* TODO: Figure out what to do with reportsAbsoluteDpadValues */
574  }
575 #endif /* TARGET_OS_TV */
576 
577  if (joystick->nhats > 0) {
578  updateplayerindex |= (joystick->hats[0] != hatstate);
579  SDL_PrivateJoystickHat(joystick, 0, hatstate);
580  }
581 
582  for (i = 0; i < joystick->hwdata->num_pause_presses; i++) {
583  /* The pause button is always last. */
584  Uint8 pausebutton = joystick->nbuttons - 1;
585 
586  SDL_PrivateJoystickButton(joystick, pausebutton, SDL_PRESSED);
587  SDL_PrivateJoystickButton(joystick, pausebutton, SDL_RELEASED);
588 
589  updateplayerindex = YES;
590  }
591 
592  joystick->hwdata->num_pause_presses = 0;
593 
594  if (updateplayerindex && controller.playerIndex == -1) {
595  BOOL usedPlayerIndexSlots[4] = {NO, NO, NO, NO};
596 
597  /* Find the player index of all other connected controllers. */
598  for (GCController *c in [GCController controllers]) {
599  if (c != controller && c.playerIndex >= 0) {
600  usedPlayerIndexSlots[c.playerIndex] = YES;
601  }
602  }
603 
604  /* Set this controller's player index to the first unused index.
605  * FIXME: This logic isn't great... but SDL doesn't expose this
606  * concept in its external API, so we don't have much to go on. */
607  for (i = 0; i < SDL_arraysize(usedPlayerIndexSlots); i++) {
608  if (!usedPlayerIndexSlots[i]) {
609  controller.playerIndex = i;
610  break;
611  }
612  }
613  }
614  }
615 #endif /* SDL_JOYSTICK_MFI */
616 }
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
Definition: SDL_joystick.c:718
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
Definition: SDL_joystick.c:794
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
Definition: SDL_joystick.c:661
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
uint8_t Uint8
Definition: SDL_stdinc.h:157
const GLubyte * c
GLsizei const GLfloat * value
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:93
#define SDL_PRESSED
Definition: SDL_events.h:50
#define SDL_HAT_CENTERED
Definition: SDL_joystick.h:302
#define SDL_RELEASED
Definition: SDL_events.h:49
GLuint in
int16_t Sint16
Definition: SDL_stdinc.h:163
int SDL_SYS_NumJoysticks ( void  )

Definition at line 330 of file SDL_sysjoystick.m.

References numjoysticks.

Referenced by SDL_NumJoysticks().

331 {
332  return numjoysticks;
333 }
static int numjoysticks
static SDL_JoystickDeviceItem* SDL_SYS_RemoveJoystickDevice ( SDL_JoystickDeviceItem device)
static

Definition at line 200 of file SDL_sysjoystick.m.

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

Referenced by SDL_SYS_JoystickQuit().

201 {
205 
206  if (device == NULL) {
207  return NULL;
208  }
209 
210  next = device->next;
211 
212  while (item != NULL) {
213  if (item == device) {
214  break;
215  }
216  prev = item;
217  item = item->next;
218  }
219 
220  /* Unlink the device item from the device list. */
221  if (prev) {
222  prev->next = device->next;
223  } else if (device == deviceList) {
224  deviceList = device->next;
225  }
226 
227  if (device->joystick) {
228  device->joystick->hwdata = NULL;
229  }
230 
231 #ifdef SDL_JOYSTICK_MFI
232  @autoreleasepool {
233  if (device->controller) {
234  /* The controller was explicitly retained in the struct, so it
235  * should be explicitly released before freeing the struct. */
236  GCController *controller = CFBridgingRelease((__bridge CFTypeRef)(device->controller));
237  controller.controllerPausedHandler = nil;
238  device->controller = nil;
239  }
240  }
241 #endif /* SDL_JOYSTICK_MFI */
242 
243  --numjoysticks;
244 
246 
247  SDL_free(device->name);
248  SDL_free(device);
249 
250  return next;
251 }
void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
Definition: SDL_joystick.c:641
static SDL_JoystickDeviceItem * deviceList
SDL_Joystick * joystick
struct joystick_hwdata * next
void SDL_free(void *mem)
#define NULL
Definition: begin_code.h:164
static int numjoysticks
GCController __unsafe_unretained * controller

Variable Documentation

const char* accelerometerName = "iOS Accelerometer"
static

Definition at line 52 of file SDL_sysjoystick.m.

Referenced by SDL_SYS_AddJoystickDevice().

SDL_JoystickID instancecounter = 0
static

Definition at line 59 of file SDL_sysjoystick.m.

Referenced by SDL_SYS_AddJoystickDevice().

CMMotionManager* motionManager = nil
static