SDL  2.0
SDL_sysjoystick.m File Reference
#include "../../SDL_internal.h"
#include "SDL_sysjoystick_c.h"
#include "SDL_config_iphoneos.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 SDL_SYS_JoystickDetect ()
 
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 57 of file SDL_sysjoystick.m.

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

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

58 {
60  int i = 0;
61 
62  while (i < device_index) {
63  if (device == NULL) {
64  return NULL;
65  }
66  device = device->next;
67  i++;
68  }
69 
70  return device;
71 }
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:42
#define NULL
Definition: begin_code.h:143
static void SDL_SYS_AccelerometerUpdate ( SDL_Joystick *  joystick)
static

Definition at line 388 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 SDL_SYS_JoystickUpdate().

389 {
390  const float maxgforce = SDL_IPHONE_MAX_GFORCE;
391  const SInt16 maxsint16 = 0x7FFF;
392  CMAcceleration accel;
393 
394  @autoreleasepool {
395  if (!motionManager.isAccelerometerActive) {
396  return;
397  }
398 
399  accel = motionManager.accelerometerData.acceleration;
400  }
401 
402  /*
403  Convert accelerometer data from floating point to Sint16, which is what
404  the joystick system expects.
405 
406  To do the conversion, the data is first clamped onto the interval
407  [-SDL_IPHONE_MAX_G_FORCE, SDL_IPHONE_MAX_G_FORCE], then the data is multiplied
408  by MAX_SINT16 so that it is mapped to the full range of an Sint16.
409 
410  You can customize the clamped range of this function by modifying the
411  SDL_IPHONE_MAX_GFORCE macro in SDL_config_iphoneos.h.
412 
413  Once converted to Sint16, the accelerometer data no longer has coherent
414  units. You can convert the data back to units of g-force by multiplying
415  it in your application's code by SDL_IPHONE_MAX_GFORCE / 0x7FFF.
416  */
417 
418  /* clamp the data */
419  accel.x = SDL_min(SDL_max(accel.x, -maxgforce), maxgforce);
420  accel.y = SDL_min(SDL_max(accel.y, -maxgforce), maxgforce);
421  accel.z = SDL_min(SDL_max(accel.z, -maxgforce), maxgforce);
422 
423  /* pass in data mapped to range of SInt16 */
424  SDL_PrivateJoystickAxis(joystick, 0, (accel.x / maxgforce) * maxsint16);
425  SDL_PrivateJoystickAxis(joystick, 1, -(accel.y / maxgforce) * maxsint16);
426  SDL_PrivateJoystickAxis(joystick, 2, (accel.z / maxgforce) * maxsint16);
427 }
#define SDL_min(x, y)
Definition: SDL_stdinc.h:345
#define SDL_max(x, y)
Definition: SDL_stdinc.h:346
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
Definition: SDL_joystick.c:501
#define SDL_IPHONE_MAX_GFORCE
static CMMotionManager * motionManager
static void SDL_SYS_AddJoystickDevice ( GCController *  controller,
SDL_bool  accelerometer 
)
static

Definition at line 127 of file SDL_sysjoystick.m.

References recDevice::accelerometer, accelerometerName, recDevice::controller, SDL_JoystickGUID::data, deviceList, recDevice::guid, recDevice::instance_id, instancecounter, recDevice::name, recDevice::naxes, recDevice::nbuttons, recDevice::next, recDevice::nhats, NULL, numjoysticks, SDL_ENABLE, SDL_EventOK, SDL_EventOKParam, SDL_GetEventState, SDL_JOYDEVICEADDED, SDL_malloc, SDL_memcpy, SDL_min, SDL_PushEvent, SDL_strdup, SDL_strlen, SDL_SYS_AddMFIJoystickDevice(), SDL_zerop, and SDL_Event::type.

Referenced by SDL_SYS_JoystickInit().

128 {
130 #if !SDL_EVENTS_DISABLED
132 #endif
133 
134  while (device != NULL) {
135  if (device->controller == controller) {
136  return;
137  }
138  device = device->next;
139  }
140 
142  if (device == NULL) {
143  return;
144  }
145 
146  SDL_zerop(device);
147 
148  device->accelerometer = accelerometer;
149  device->instance_id = instancecounter++;
150 
151  if (accelerometer) {
152  device->name = SDL_strdup(accelerometerName);
153  device->naxes = 3; /* Device acceleration in the x, y, and z axes. */
154  device->nhats = 0;
155  device->nbuttons = 0;
156 
157  /* Use the accelerometer name as a GUID. */
158  SDL_memcpy(&device->guid.data, device->name, SDL_min(sizeof(SDL_JoystickGUID), SDL_strlen(device->name)));
159  } else if (controller) {
160  SDL_SYS_AddMFIJoystickDevice(device, controller);
161  }
162 
163  if (deviceList == NULL) {
164  deviceList = device;
165  } else {
166  SDL_JoystickDeviceItem *lastdevice = deviceList;
167  while (lastdevice->next != NULL) {
168  lastdevice = lastdevice->next;
169  }
170  lastdevice->next = device;
171  }
172 
173  ++numjoysticks;
174 
175 #if !SDL_EVENTS_DISABLED
176  event.type = SDL_JOYDEVICEADDED;
177 
178  if (SDL_GetEventState(event.type) == SDL_ENABLE) {
179  event.jdevice.which = numjoysticks - 1;
180  if ((SDL_EventOK == NULL) ||
181  (*SDL_EventOK)(SDL_EventOKParam, &event)) {
182  SDL_PushEvent(&event);
183  }
184  }
185 #endif /* !SDL_EVENTS_DISABLED */
186 }
#define SDL_min(x, y)
Definition: SDL_stdinc.h:345
SDL_JoystickGUID guid
static SDL_JoystickDeviceItem * deviceList
#define SDL_ENABLE
Definition: SDL_events.h:718
static const char * accelerometerName
struct joystick_hwdata * next
Uint8 data[16]
Definition: SDL_joystick.h:69
#define SDL_zerop(x)
Definition: SDL_stdinc.h:356
#define SDL_memcpy
#define SDL_GetEventState(type)
Definition: SDL_events.h:731
struct _cl_event * event
SDL_EventFilter SDL_EventOK
Definition: SDL_events.c:40
static void SDL_SYS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controller)
#define SDL_PushEvent
void * SDL_EventOKParam
Definition: SDL_events.c:41
#define NULL
Definition: begin_code.h:143
static SDL_JoystickID instancecounter
#define SDL_strlen
#define SDL_strdup
static int numjoysticks
General event structure.
Definition: SDL_events.h:521
#define SDL_malloc
GCController __unsafe_unretained * controller
Uint32 type
Definition: SDL_events.h:523
static void SDL_SYS_AddMFIJoystickDevice ( SDL_JoystickDeviceItem device,
GCController *  controller 
)
static

Definition at line 74 of file SDL_sysjoystick.m.

References recDevice::controller, SDL_JoystickGUID::data, recDevice::guid, recDevice::name, recDevice::naxes, recDevice::nbuttons, recDevice::nhats, NULL, and SDL_strdup.

Referenced by SDL_SYS_AddJoystickDevice().

75 {
76 #ifdef SDL_JOYSTICK_MFI
77  const char *name = NULL;
78  /* Explicitly retain the controller because SDL_JoystickDeviceItem is a
79  * struct, and ARC doesn't work with structs. */
80  device->controller = (__bridge GCController *) CFBridgingRetain(controller);
81 
82  if (controller.vendorName) {
83  name = controller.vendorName.UTF8String;
84  }
85 
86  if (!name) {
87  name = "MFi Gamepad";
88  }
89 
90  device->name = SDL_strdup(name);
91 
92  device->guid.data[0] = 'M';
93  device->guid.data[1] = 'F';
94  device->guid.data[2] = 'i';
95  device->guid.data[3] = 'G';
96  device->guid.data[4] = 'a';
97  device->guid.data[5] = 'm';
98  device->guid.data[6] = 'e';
99  device->guid.data[7] = 'p';
100  device->guid.data[8] = 'a';
101  device->guid.data[9] = 'd';
102 
103  if (controller.extendedGamepad) {
104  device->guid.data[10] = 1;
105  } else if (controller.gamepad) {
106  device->guid.data[10] = 2;
107  }
108 
109  if (controller.extendedGamepad) {
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  device->naxes = 0; /* no traditional analog inputs */
115  device->nhats = 1; /* d-pad */
116  device->nbuttons = 7; /* ABXY, shoulder buttons, pause button */
117  }
118  /* TODO: Handle micro profiles on tvOS. */
119 
120  /* This will be set when the first button press of the controller is
121  * detected. */
122  controller.playerIndex = -1;
123 #endif
124 }
SDL_JoystickGUID guid
GLuint const GLchar * name
Uint8 data[16]
Definition: SDL_joystick.h:69
#define NULL
Definition: begin_code.h:143
#define SDL_strdup
GCController __unsafe_unretained * controller
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex ( int  device_index)

Definition at line 327 of file SDL_sysjoystick.m.

References GetDeviceForIndex(), and recDevice::instance_id.

Referenced by SDL_GameControllerOpen(), and SDL_JoystickOpen().

328 {
329  SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
330  return device ? device->instance_id : 0;
331 }
static SDL_JoystickDeviceItem * GetDeviceForIndex(int device_index)
SDL_bool SDL_SYS_JoystickAttached ( SDL_Joystick *  joystick)

Definition at line 382 of file SDL_sysjoystick.m.

References NULL.

Referenced by SDL_JoystickGetAttached().

383 {
384  return joystick->hwdata != NULL;
385 }
#define NULL
Definition: begin_code.h:143
void SDL_SYS_JoystickClose ( SDL_Joystick *  joystick)

Definition at line 586 of file SDL_sysjoystick.m.

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

Referenced by SDL_JoystickClose().

587 {
588  SDL_JoystickDeviceItem *device = joystick->hwdata;
589 
590  if (device == NULL) {
591  return;
592  }
593 
594  device->joystick = NULL;
595 
596  @autoreleasepool {
597  if (device->accelerometer) {
598  [motionManager stopAccelerometerUpdates];
599  } else if (device->controller) {
600 #ifdef SDL_JOYSTICK_MFI
601  GCController *controller = device->controller;
602  controller.controllerPausedHandler = nil;
603  controller.playerIndex = -1;
604 #endif
605  }
606  }
607 }
SDL_Joystick * joystick
#define NULL
Definition: begin_code.h:143
GCController __unsafe_unretained * controller
void SDL_SYS_JoystickDetect ( )

Definition at line 314 of file SDL_sysjoystick.m.

Referenced by SDL_JoystickUpdate().

315 {
316 }
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID ( int  device_index)

Definition at line 639 of file SDL_sysjoystick.m.

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

Referenced by SDL_JoystickGetDeviceGUID().

640 {
641  SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
642  SDL_JoystickGUID guid;
643  if (device) {
644  guid = device->guid;
645  } else {
646  SDL_zero(guid);
647  }
648  return guid;
649 }
SDL_JoystickGUID guid
static SDL_JoystickDeviceItem * GetDeviceForIndex(int device_index)
#define SDL_zero(x)
Definition: SDL_stdinc.h:355
SDL_JoystickGUID SDL_SYS_JoystickGetGUID ( SDL_Joystick *  joystick)

Definition at line 652 of file SDL_sysjoystick.m.

References recDevice::guid, and SDL_zero.

Referenced by SDL_JoystickGetGUID().

653 {
654  SDL_JoystickGUID guid;
655  if (joystick->hwdata) {
656  guid = joystick->hwdata->guid;
657  } else {
658  SDL_zero(guid);
659  }
660  return guid;
661 }
#define SDL_zero(x)
Definition: SDL_stdinc.h:355
int SDL_SYS_JoystickInit ( void  )

Definition at line 260 of file SDL_sysjoystick.m.

References recDevice::controller, sort_controllers::controllers, numjoysticks, SDL_atoi, SDL_FALSE, SDL_GetHint, SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_SYS_AddJoystickDevice(), and SDL_TRUE.

Referenced by SDL_JoystickInit().

261 {
262  @autoreleasepool {
263  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
265 
266  if (!hint || SDL_atoi(hint)) {
267  /* Default behavior, accelerometer as joystick */
269  }
270 
271 #ifdef SDL_JOYSTICK_MFI
272  /* GameController.framework was added in iOS 7. */
273  if (![GCController class]) {
274  return numjoysticks;
275  }
276 
277  for (GCController *controller in [GCController controllers]) {
279  }
280 
281  connectObserver = [center addObserverForName:GCControllerDidConnectNotification
282  object:nil
283  queue:nil
284  usingBlock:^(NSNotification *note) {
285  GCController *controller = note.object;
286  SDL_SYS_AddJoystickDevice(controller, SDL_FALSE);
287  }];
288 
289  disconnectObserver = [center addObserverForName:GCControllerDidDisconnectNotification
290  object:nil
291  queue:nil
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);
298  break;
299  }
300  device = device->next;
301  }
302  }];
303 #endif /* SDL_JOYSTICK_MFI */
304  }
305 
306  return numjoysticks;
307 }
#define SDL_GetHint
#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:289
#define SDL_atoi
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 320 of file SDL_sysjoystick.m.

References GetDeviceForIndex(), and recDevice::name.

Referenced by SDL_JoystickNameForIndex(), and SDL_JoystickOpen().

321 {
322  SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
323  return device ? device->name : "Unknown";
324 }
static SDL_JoystickDeviceItem * GetDeviceForIndex(int device_index)
int SDL_SYS_JoystickOpen ( SDL_Joystick *  joystick,
int  device_index 
)

Definition at line 339 of file SDL_sysjoystick.m.

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

Referenced by SDL_JoystickOpen().

340 {
341  SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
342  if (device == NULL) {
343  return SDL_SetError("Could not open Joystick: no hardware device for the specified index");
344  }
345 
346  joystick->hwdata = device;
347  joystick->instance_id = device->instance_id;
348 
349  joystick->naxes = device->naxes;
350  joystick->nhats = device->nhats;
351  joystick->nbuttons = device->nbuttons;
352  joystick->nballs = 0;
353 
354  device->joystick = joystick;
355 
356  @autoreleasepool {
357  if (device->accelerometer) {
358  if (motionManager == nil) {
359  motionManager = [[CMMotionManager alloc] init];
360  }
361 
362  /* Shorter times between updates can significantly increase CPU usage. */
363  motionManager.accelerometerUpdateInterval = 0.1;
364  [motionManager startAccelerometerUpdates];
365  } else {
366 #ifdef SDL_JOYSTICK_MFI
367  GCController *controller = device->controller;
368  controller.controllerPausedHandler = ^(GCController *c) {
369  if (joystick->hwdata) {
370  ++joystick->hwdata->num_pause_presses;
371  }
372  };
373 #endif /* SDL_JOYSTICK_MFI */
374  }
375  }
376 
377  return 0;
378 }
SDL_Joystick * joystick
static SDL_JoystickDeviceItem * GetDeviceForIndex(int device_index)
const GLubyte * c
#define NULL
Definition: begin_code.h:143
#define SDL_SetError
GCController __unsafe_unretained * controller
static CMMotionManager * motionManager
void SDL_SYS_JoystickQuit ( void  )

Definition at line 611 of file SDL_sysjoystick.m.

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

Referenced by SDL_JoystickQuit().

612 {
613  @autoreleasepool {
614 #ifdef SDL_JOYSTICK_MFI
615  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
616 
617  if (connectObserver) {
618  [center removeObserver:connectObserver name:GCControllerDidConnectNotification object:nil];
619  connectObserver = nil;
620  }
621 
622  if (disconnectObserver) {
623  [center removeObserver:disconnectObserver name:GCControllerDidDisconnectNotification object:nil];
624  disconnectObserver = nil;
625  }
626 #endif /* SDL_JOYSTICK_MFI */
627 
628  while (deviceList != NULL) {
630  }
631 
632  motionManager = nil;
633  }
634 
635  numjoysticks = 0;
636 }
static SDL_JoystickDeviceItem * deviceList
#define NULL
Definition: begin_code.h:143
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 569 of file SDL_sysjoystick.m.

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

Referenced by SDL_GameControllerOpen(), SDL_JoystickOpen(), and SDL_JoystickUpdate().

570 {
571  SDL_JoystickDeviceItem *device = joystick->hwdata;
572 
573  if (device == NULL) {
574  return;
575  }
576 
577  if (device->accelerometer) {
578  SDL_SYS_AccelerometerUpdate(joystick);
579  } else if (device->controller) {
580  SDL_SYS_MFIJoystickUpdate(joystick);
581  }
582 }
static void SDL_SYS_MFIJoystickUpdate(SDL_Joystick *joystick)
#define NULL
Definition: begin_code.h:143
static void SDL_SYS_AccelerometerUpdate(SDL_Joystick *joystick)
GCController __unsafe_unretained * controller
static void SDL_SYS_MFIJoystickUpdate ( SDL_Joystick *  joystick)
static

Definition at line 456 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().

457 {
458 #ifdef SDL_JOYSTICK_MFI
459  @autoreleasepool {
460  GCController *controller = joystick->hwdata->controller;
461  Uint8 hatstate = SDL_HAT_CENTERED;
462  int i;
463  int updateplayerindex = 0;
464 
465  if (controller.extendedGamepad) {
466  GCExtendedGamepad *gamepad = controller.extendedGamepad;
467 
468  /* Axis order matches the XInput Windows mappings. */
469  Sint16 axes[] = {
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),
476  };
477 
478  /* Button order matches the XInput Windows mappings. */
479  Uint8 buttons[] = {
480  gamepad.buttonA.isPressed, gamepad.buttonB.isPressed,
481  gamepad.buttonX.isPressed, gamepad.buttonY.isPressed,
482  gamepad.leftShoulder.isPressed,
483  gamepad.rightShoulder.isPressed,
484  };
485 
486  hatstate = SDL_SYS_MFIJoystickHatStateForDPad(gamepad.dpad);
487 
488  for (i = 0; i < SDL_arraysize(axes); i++) {
489  /* The triggers (axes 2 and 5) are resting at -32768 but SDL
490  * initializes its values to 0. We only want to make sure the
491  * player index is up to date if the user actually moves an axis. */
492  if ((i != 2 && i != 5) || axes[i] != -32768) {
493  updateplayerindex |= (joystick->axes[i] != axes[i]);
494  }
495  SDL_PrivateJoystickAxis(joystick, i, axes[i]);
496  }
497 
498  for (i = 0; i < SDL_arraysize(buttons); i++) {
499  updateplayerindex |= (joystick->buttons[i] != buttons[i]);
500  SDL_PrivateJoystickButton(joystick, i, buttons[i]);
501  }
502  } else if (controller.gamepad) {
503  GCGamepad *gamepad = controller.gamepad;
504 
505  /* Button order matches the XInput Windows mappings. */
506  Uint8 buttons[] = {
507  gamepad.buttonA.isPressed, gamepad.buttonB.isPressed,
508  gamepad.buttonX.isPressed, gamepad.buttonY.isPressed,
509  gamepad.leftShoulder.isPressed,
510  gamepad.rightShoulder.isPressed,
511  };
512 
513  hatstate = SDL_SYS_MFIJoystickHatStateForDPad(gamepad.dpad);
514 
515  for (i = 0; i < SDL_arraysize(buttons); i++) {
516  updateplayerindex |= (joystick->buttons[i] != buttons[i]);
517  SDL_PrivateJoystickButton(joystick, i, buttons[i]);
518  }
519  }
520  /* TODO: Handle micro profiles on tvOS. */
521 
522  if (joystick->nhats > 0) {
523  updateplayerindex |= (joystick->hats[0] != hatstate);
524  SDL_PrivateJoystickHat(joystick, 0, hatstate);
525  }
526 
527  for (i = 0; i < joystick->hwdata->num_pause_presses; i++) {
528  /* The pause button is always last. */
529  Uint8 pausebutton = joystick->nbuttons - 1;
530 
531  SDL_PrivateJoystickButton(joystick, pausebutton, SDL_PRESSED);
532  SDL_PrivateJoystickButton(joystick, pausebutton, SDL_RELEASED);
533 
534  updateplayerindex = YES;
535  }
536 
537  joystick->hwdata->num_pause_presses = 0;
538 
539  if (updateplayerindex && controller.playerIndex == -1) {
540  BOOL usedPlayerIndexSlots[4] = {NO, NO, NO, NO};
541 
542  /* Find the player index of all other connected controllers. */
543  for (GCController *c in [GCController controllers]) {
544  if (c != controller && c.playerIndex >= 0) {
545  usedPlayerIndexSlots[c.playerIndex] = YES;
546  }
547  }
548 
549  /* Set this controller's player index to the first unused index.
550  * FIXME: This logic isn't great... but SDL doesn't expose this
551  * concept in its external API, so we don't have much to go on. */
552  for (i = 0; i < SDL_arraysize(usedPlayerIndexSlots); i++) {
553  if (!usedPlayerIndexSlots[i]) {
554  controller.playerIndex = i;
555  break;
556  }
557  }
558  }
559  }
560 #endif
561 }
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
Definition: SDL_joystick.c:542
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
Definition: SDL_joystick.c:618
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
Definition: SDL_joystick.c:501
GLsizei const GLfloat * value
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:139
const GLubyte * c
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:42
#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:207
#define SDL_RELEASED
Definition: SDL_events.h:49
GLuint in
int16_t Sint16
A signed 16-bit integer type.
Definition: SDL_stdinc.h:143
int SDL_SYS_NumJoysticks ( )

Definition at line 309 of file SDL_sysjoystick.m.

References numjoysticks.

Referenced by SDL_NumJoysticks().

310 {
311  return numjoysticks;
312 }
static int numjoysticks
static SDL_JoystickDeviceItem* SDL_SYS_RemoveJoystickDevice ( SDL_JoystickDeviceItem device)
static

Definition at line 189 of file SDL_sysjoystick.m.

References recDevice::controller, deviceList, recDevice::instance_id, recDevice::item, recDevice::joystick, recDevice::name, recDevice::next, NULL, numjoysticks, SDL_ENABLE, SDL_EventOK, SDL_EventOKParam, SDL_free(), SDL_GetEventState, SDL_JOYDEVICEREMOVED, SDL_PushEvent, and SDL_Event::type.

Referenced by SDL_SYS_JoystickQuit().

190 {
194 #if !SDL_EVENTS_DISABLED
196 #endif
197 
198  if (device == NULL) {
199  return NULL;
200  }
201 
202  next = device->next;
203 
204  while (item != NULL) {
205  if (item == device) {
206  break;
207  }
208  prev = item;
209  item = item->next;
210  }
211 
212  /* Unlink the device item from the device list. */
213  if (prev) {
214  prev->next = device->next;
215  } else if (device == deviceList) {
216  deviceList = device->next;
217  }
218 
219  if (device->joystick) {
220  device->joystick->hwdata = NULL;
221  }
222 
223 #ifdef SDL_JOYSTICK_MFI
224  @autoreleasepool {
225  if (device->controller) {
226  /* The controller was explicitly retained in the struct, so it
227  * should be explicitly released before freeing the struct. */
228  GCController *controller = CFBridgingRelease((__bridge CFTypeRef)(device->controller));
229  controller.controllerPausedHandler = nil;
230  device->controller = nil;
231  }
232  }
233 #endif /* SDL_JOYSTICK_MFI */
234 
235  --numjoysticks;
236 
237 #if !SDL_EVENTS_DISABLED
238  event.type = SDL_JOYDEVICEREMOVED;
239 
240  if (SDL_GetEventState(event.type) == SDL_ENABLE) {
241  event.jdevice.which = device->instance_id;
242  if ((SDL_EventOK == NULL) ||
243  (*SDL_EventOK)(SDL_EventOKParam, &event)) {
244  SDL_PushEvent(&event);
245  }
246  }
247 #endif /* !SDL_EVENTS_DISABLED */
248 
249  SDL_free(device->name);
250  SDL_free(device);
251 
252  return next;
253 }
static SDL_JoystickDeviceItem * deviceList
SDL_Joystick * joystick
#define SDL_ENABLE
Definition: SDL_events.h:718
struct joystick_hwdata * next
#define SDL_GetEventState(type)
Definition: SDL_events.h:731
struct _cl_event * event
void SDL_free(void *mem)
SDL_EventFilter SDL_EventOK
Definition: SDL_events.c:40
#define SDL_PushEvent
void * SDL_EventOKParam
Definition: SDL_events.c:41
#define NULL
Definition: begin_code.h:143
static int numjoysticks
General event structure.
Definition: SDL_events.h:521
GCController __unsafe_unretained * controller
Uint32 type
Definition: SDL_events.h:523

Variable Documentation

const char* accelerometerName = "iOS Accelerometer"
static

Definition at line 48 of file SDL_sysjoystick.m.

Referenced by SDL_SYS_AddJoystickDevice().

SDL_JoystickID instancecounter = 0
static

Definition at line 54 of file SDL_sysjoystick.m.

Referenced by SDL_SYS_AddJoystickDevice().

CMMotionManager* motionManager = nil
static