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

◆ GetDeviceForIndex()

static SDL_JoystickDeviceItem* GetDeviceForIndex ( int  device_index)
static

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

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
#define NULL
Definition: begin_code.h:143

◆ SDL_SYS_AccelerometerUpdate()

static void SDL_SYS_AccelerometerUpdate ( SDL_Joystick *  joystick)
static

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

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

◆ SDL_SYS_AddJoystickDevice()

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, 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:349
SDL_JoystickGUID guid
static SDL_JoystickDeviceItem * deviceList
static const char * accelerometerName
struct joystick_hwdata * next
Uint8 data[16]
Definition: SDL_joystick.h:69
#define SDL_zerop(x)
Definition: SDL_stdinc.h:360
#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:501
#define NULL
Definition: begin_code.h:143
static SDL_JoystickID instancecounter
#define SDL_strlen
#define SDL_strdup
static int numjoysticks
#define SDL_malloc
GCController __unsafe_unretained * controller

◆ SDL_SYS_AddMFIJoystickDevice()

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&#39;s joystick axes will automatically match the rotat...
Definition: SDL_hints.h:317
GLuint const GLchar * name
Uint8 data[16]
Definition: SDL_joystick.h:69
#define SDL_GetHintBoolean
#define NULL
Definition: begin_code.h:143
#define SDL_strdup
GCController __unsafe_unretained * controller

◆ SDL_SYS_GetInstanceIdOfDeviceIndex()

SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex ( int  device_index)

Definition at line 347 of file SDL_sysjoystick.m.

References GetDeviceForIndex(), and recDevice::instance_id.

Referenced by SDL_GameControllerOpen(), and SDL_JoystickOpen().

348 {
349  SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
350  return device ? device->instance_id : 0;
351 }
static SDL_JoystickDeviceItem * GetDeviceForIndex(int device_index)

◆ SDL_SYS_JoystickAttached()

SDL_bool SDL_SYS_JoystickAttached ( SDL_Joystick *  joystick)

Definition at line 404 of file SDL_sysjoystick.m.

References NULL.

Referenced by SDL_JoystickGetAttached().

405 {
406  return joystick->hwdata != NULL;
407 }
#define NULL
Definition: begin_code.h:143

◆ SDL_SYS_JoystickClose()

void SDL_SYS_JoystickClose ( SDL_Joystick *  joystick)

Definition at line 639 of file SDL_sysjoystick.m.

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

Referenced by SDL_JoystickClose().

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

◆ SDL_SYS_JoystickDetect()

void SDL_SYS_JoystickDetect ( )

Definition at line 334 of file SDL_sysjoystick.m.

Referenced by SDL_JoystickUpdate().

335 {
336 }

◆ SDL_SYS_JoystickGetDeviceGUID()

SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID ( int  device_index)

Definition at line 701 of file SDL_sysjoystick.m.

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

Referenced by SDL_JoystickGetDeviceGUID().

702 {
703  SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
704  SDL_JoystickGUID guid;
705  if (device) {
706  guid = device->guid;
707  } else {
708  SDL_zero(guid);
709  }
710  return guid;
711 }
SDL_JoystickGUID guid
static SDL_JoystickDeviceItem * GetDeviceForIndex(int device_index)
#define SDL_zero(x)
Definition: SDL_stdinc.h:359

◆ SDL_SYS_JoystickGetGUID()

SDL_JoystickGUID SDL_SYS_JoystickGetGUID ( SDL_Joystick *  joystick)

Definition at line 714 of file SDL_sysjoystick.m.

References recDevice::guid, and SDL_zero.

Referenced by SDL_JoystickGetGUID().

715 {
716  SDL_JoystickGUID guid;
717  if (joystick->hwdata) {
718  guid = joystick->hwdata->guid;
719  } else {
720  SDL_zero(guid);
721  }
722  return guid;
723 }
#define SDL_zero(x)
Definition: SDL_stdinc.h:359

◆ SDL_SYS_JoystickInit()

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&#39;s joystick axes will automatically match the rotat...
Definition: SDL_hints.h:317
#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:328
#define NULL
Definition: begin_code.h:143
#define SDL_AddHintCallback
static int numjoysticks
GLuint in
static void SDL_SYS_AddJoystickDevice(GCController *controller, SDL_bool accelerometer)

◆ SDL_SYS_JoystickNameForDeviceIndex()

const char* SDL_SYS_JoystickNameForDeviceIndex ( int  device_index)

Definition at line 340 of file SDL_sysjoystick.m.

References GetDeviceForIndex(), and recDevice::name.

Referenced by SDL_JoystickNameForIndex(), and SDL_JoystickOpen().

341 {
342  SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
343  return device ? device->name : "Unknown";
344 }
static SDL_JoystickDeviceItem * GetDeviceForIndex(int device_index)

◆ SDL_SYS_JoystickOpen()

int SDL_SYS_JoystickOpen ( SDL_Joystick *  joystick,
int  device_index 
)

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

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

◆ SDL_SYS_JoystickQuit()

void SDL_SYS_JoystickQuit ( void  )

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

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

◆ SDL_SYS_JoystickUpdate()

void SDL_SYS_JoystickUpdate ( SDL_Joystick *  joystick)

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

623 {
624  SDL_JoystickDeviceItem *device = joystick->hwdata;
625 
626  if (device == NULL) {
627  return;
628  }
629 
630  if (device->accelerometer) {
631  SDL_SYS_AccelerometerUpdate(joystick);
632  } else if (device->controller) {
633  SDL_SYS_MFIJoystickUpdate(joystick);
634  }
635 }
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

◆ SDL_SYS_MFIJoystickUpdate()

static void SDL_SYS_MFIJoystickUpdate ( SDL_Joystick *  joystick)
static

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

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

◆ SDL_SYS_NumJoysticks()

int SDL_SYS_NumJoysticks ( )

Definition at line 329 of file SDL_sysjoystick.m.

References numjoysticks.

Referenced by SDL_NumJoysticks().

330 {
331  return numjoysticks;
332 }
static int numjoysticks

◆ SDL_SYS_RemoveJoystickDevice()

static SDL_JoystickDeviceItem* SDL_SYS_RemoveJoystickDevice ( SDL_JoystickDeviceItem device)
static

Definition at line 200 of file SDL_sysjoystick.m.

References recDevice::controller, sort_controllers::controllers, 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:547
static SDL_JoystickDeviceItem * deviceList
SDL_Joystick * joystick
struct joystick_hwdata * next
void SDL_free(void *mem)
#define NULL
Definition: begin_code.h:143
static int numjoysticks
GCController __unsafe_unretained * controller

Variable Documentation

◆ accelerometerName

const char* accelerometerName = "iOS Accelerometer"
static

Definition at line 52 of file SDL_sysjoystick.m.

Referenced by SDL_SYS_AddJoystickDevice().

◆ deviceList

◆ instancecounter

SDL_JoystickID instancecounter = 0
static

Definition at line 59 of file SDL_sysjoystick.m.

Referenced by SDL_SYS_AddJoystickDevice().

◆ motionManager

CMMotionManager* motionManager = nil
static

◆ numjoysticks