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 "../steam/SDL_steamcontroller.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)
 
static SDL_bool SteamControllerConnectedCallback (const char *name, SDL_JoystickGUID guid, int *device_instance)
 
static void SteamControllerDisconnectedCallback (int device_instance)
 
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

◆ GetDeviceForIndex()

static SDL_JoystickDeviceItem* GetDeviceForIndex ( int  device_index)
static

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

66 {
68  int i = 0;
69 
70  while (i < device_index) {
71  if (device == NULL) {
72  return NULL;
73  }
74  device = device->next;
75  i++;
76  }
77 
78  return device;
79 }
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

◆ SDL_SYS_AccelerometerUpdate()

static void SDL_SYS_AccelerometerUpdate ( SDL_Joystick *  joystick)
static

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

464 {
465 #if !TARGET_OS_TV
466  const float maxgforce = SDL_IPHONE_MAX_GFORCE;
467  const SInt16 maxsint16 = 0x7FFF;
468  CMAcceleration accel;
469 
470  @autoreleasepool {
471  if (!motionManager.isAccelerometerActive) {
472  return;
473  }
474 
475  accel = motionManager.accelerometerData.acceleration;
476  }
477 
478  /*
479  Convert accelerometer data from floating point to Sint16, which is what
480  the joystick system expects.
481 
482  To do the conversion, the data is first clamped onto the interval
483  [-SDL_IPHONE_MAX_G_FORCE, SDL_IPHONE_MAX_G_FORCE], then the data is multiplied
484  by MAX_SINT16 so that it is mapped to the full range of an Sint16.
485 
486  You can customize the clamped range of this function by modifying the
487  SDL_IPHONE_MAX_GFORCE macro in SDL_config_iphoneos.h.
488 
489  Once converted to Sint16, the accelerometer data no longer has coherent
490  units. You can convert the data back to units of g-force by multiplying
491  it in your application's code by SDL_IPHONE_MAX_GFORCE / 0x7FFF.
492  */
493 
494  /* clamp the data */
495  accel.x = SDL_min(SDL_max(accel.x, -maxgforce), maxgforce);
496  accel.y = SDL_min(SDL_max(accel.y, -maxgforce), maxgforce);
497  accel.z = SDL_min(SDL_max(accel.z, -maxgforce), maxgforce);
498 
499  /* pass in data mapped to range of SInt16 */
500  SDL_PrivateJoystickAxis(joystick, 0, (accel.x / maxgforce) * maxsint16);
501  SDL_PrivateJoystickAxis(joystick, 1, -(accel.y / maxgforce) * maxsint16);
502  SDL_PrivateJoystickAxis(joystick, 2, (accel.z / maxgforce) * maxsint16);
503 #endif /* !TARGET_OS_TV */
504 }
#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:655
#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 149 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().

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

◆ SDL_SYS_AddMFIJoystickDevice()

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

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

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

SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex ( int  device_index)

Definition at line 400 of file SDL_sysjoystick.m.

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

Referenced by SDL_GameControllerOpen(), and SDL_JoystickGetDeviceInstanceID().

401 {
403  return device ? device->instance_id : 0;
404 }
static SDL_JoystickDeviceItem * GetDeviceForIndex(int device_index)
static SDL_AudioDeviceID device
Definition: loopwave.c:37

◆ SDL_SYS_JoystickAttached()

SDL_bool SDL_SYS_JoystickAttached ( SDL_Joystick *  joystick)

Definition at line 457 of file SDL_sysjoystick.m.

References NULL.

Referenced by SDL_JoystickGetAttached().

458 {
459  return joystick->hwdata != NULL;
460 }
#define NULL
Definition: begin_code.h:164

◆ SDL_SYS_JoystickClose()

void SDL_SYS_JoystickClose ( SDL_Joystick *  joystick)

Definition at line 697 of file SDL_sysjoystick.m.

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

Referenced by SDL_JoystickClose().

698 {
699  SDL_JoystickDeviceItem *device = joystick->hwdata;
700 
701  if (device == NULL) {
702  return;
703  }
704 
705  device->joystick = NULL;
706 
707  @autoreleasepool {
708  if (device->accelerometer) {
709 #if !TARGET_OS_TV
710  [motionManager stopAccelerometerUpdates];
711 #endif /* !TARGET_OS_TV */
712  } else if (device->controller) {
713 #ifdef SDL_JOYSTICK_MFI
714  GCController *controller = device->controller;
715  controller.controllerPausedHandler = nil;
716  controller.playerIndex = -1;
717 #endif
718  }
719  }
720 }
SDL_Joystick * joystick
static SDL_AudioDeviceID device
Definition: loopwave.c:37
#define NULL
Definition: begin_code.h:164
GCController __unsafe_unretained * controller

◆ SDL_SYS_JoystickDetect()

void SDL_SYS_JoystickDetect ( void  )

Definition at line 386 of file SDL_sysjoystick.m.

References SDL_UpdateSteamControllers().

Referenced by SDL_JoystickUpdate().

387 {
389 }
void SDL_UpdateSteamControllers(void)

◆ SDL_SYS_JoystickGetDeviceGUID()

SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID ( int  device_index)

Definition at line 761 of file SDL_sysjoystick.m.

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

Referenced by SDL_JoystickGetDeviceGUID().

762 {
764  SDL_JoystickGUID guid;
765  if (device) {
766  guid = device->guid;
767  } else {
768  SDL_zero(guid);
769  }
770  return guid;
771 }
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

◆ SDL_SYS_JoystickGetGUID()

SDL_JoystickGUID SDL_SYS_JoystickGetGUID ( SDL_Joystick *  joystick)

Definition at line 774 of file SDL_sysjoystick.m.

References recDevice::guid, and SDL_zero.

Referenced by SDL_JoystickGetGUID().

775 {
776  SDL_JoystickGUID guid;
777  if (joystick->hwdata) {
778  guid = joystick->hwdata->guid;
779  } else {
780  SDL_zero(guid);
781  }
782  return guid;
783 }
#define SDL_zero(x)
Definition: SDL_stdinc.h:416

◆ SDL_SYS_JoystickInit()

int SDL_SYS_JoystickInit ( void  )

Definition at line 321 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_InitSteamControllers(), SDL_SYS_AddJoystickDevice(), SDL_TRUE, SteamControllerConnectedCallback(), and SteamControllerDisconnectedCallback().

Referenced by SDL_JoystickInit().

322 {
323  @autoreleasepool {
324  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
325 
328 
329 #if !TARGET_OS_TV
331  /* Default behavior, accelerometer as joystick */
333  }
334 #endif /* !TARGET_OS_TV */
335 
336 #ifdef SDL_JOYSTICK_MFI
337  /* GameController.framework was added in iOS 7. */
338  if (![GCController class]) {
339  return numjoysticks;
340  }
341 
342  for (GCController *controller in [GCController controllers]) {
344  }
345 
346 #if TARGET_OS_TV
348  SDL_AppleTVRemoteRotationHintChanged, NULL);
349 #endif /* TARGET_OS_TV */
350 
351  connectObserver = [center addObserverForName:GCControllerDidConnectNotification
352  object:nil
353  queue:nil
354  usingBlock:^(NSNotification *note) {
355  GCController *controller = note.object;
356  SDL_SYS_AddJoystickDevice(controller, SDL_FALSE);
357  }];
358 
359  disconnectObserver = [center addObserverForName:GCControllerDidDisconnectNotification
360  object:nil
361  queue:nil
362  usingBlock:^(NSNotification *note) {
363  GCController *controller = note.object;
364  SDL_JoystickDeviceItem *device = deviceList;
365  while (device != NULL) {
366  if (device->controller == controller) {
367  SDL_SYS_RemoveJoystickDevice(device);
368  break;
369  }
370  device = device->next;
371  }
372  }];
373 #endif /* SDL_JOYSTICK_MFI */
374  }
375 
376  return numjoysticks;
377 }
void SDL_InitSteamControllers(SteamControllerConnectedCallback_t connectedCallback, SteamControllerDisconnectedCallback_t disconnectedCallback)
static void SteamControllerDisconnectedCallback(int device_instance)
#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: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
static SDL_bool SteamControllerConnectedCallback(const char *name, SDL_JoystickGUID guid, int *device_instance)
#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)

◆ SDL_SYS_JoystickNameForDeviceIndex()

const char* SDL_SYS_JoystickNameForDeviceIndex ( int  device_index)

Definition at line 393 of file SDL_sysjoystick.m.

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

Referenced by SDL_JoystickNameForIndex(), and SDL_JoystickOpen().

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

◆ SDL_SYS_JoystickOpen()

int SDL_SYS_JoystickOpen ( SDL_Joystick *  joystick,
int  device_index 
)

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

413 {
415  if (device == NULL) {
416  return SDL_SetError("Could not open Joystick: no hardware device for the specified index");
417  }
418 
419  joystick->hwdata = device;
420  joystick->instance_id = device->instance_id;
421 
422  joystick->naxes = device->naxes;
423  joystick->nhats = device->nhats;
424  joystick->nbuttons = device->nbuttons;
425  joystick->nballs = 0;
426 
427  device->joystick = joystick;
428 
429  @autoreleasepool {
430  if (device->accelerometer) {
431 #if !TARGET_OS_TV
432  if (motionManager == nil) {
433  motionManager = [[CMMotionManager alloc] init];
434  }
435 
436  /* Shorter times between updates can significantly increase CPU usage. */
437  motionManager.accelerometerUpdateInterval = 0.1;
438  [motionManager startAccelerometerUpdates];
439 #endif /* !TARGET_OS_TV */
440  } else {
441 #ifdef SDL_JOYSTICK_MFI
442  GCController *controller = device->controller;
443  controller.controllerPausedHandler = ^(GCController *c) {
444  if (joystick->hwdata) {
445  ++joystick->hwdata->num_pause_presses;
446  }
447  };
448 #endif /* SDL_JOYSTICK_MFI */
449  }
450  }
451 
452  return 0;
453 }
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

◆ SDL_SYS_JoystickQuit()

void SDL_SYS_JoystickQuit ( void  )

Definition at line 724 of file SDL_sysjoystick.m.

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

Referenced by SDL_JoystickQuit().

725 {
726  @autoreleasepool {
727 #ifdef SDL_JOYSTICK_MFI
728  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
729 
730  if (connectObserver) {
731  [center removeObserver:connectObserver name:GCControllerDidConnectNotification object:nil];
732  connectObserver = nil;
733  }
734 
735  if (disconnectObserver) {
736  [center removeObserver:disconnectObserver name:GCControllerDidDisconnectNotification object:nil];
737  disconnectObserver = nil;
738  }
739 
740 #if TARGET_OS_TV
742  SDL_AppleTVRemoteRotationHintChanged, NULL);
743 #endif /* TARGET_OS_TV */
744 #endif /* SDL_JOYSTICK_MFI */
745 
746  while (deviceList != NULL) {
748  }
749 
750 #if !TARGET_OS_TV
751  motionManager = nil;
752 #endif /* !TARGET_OS_TV */
753  }
754 
756 
757  numjoysticks = 0;
758 }
void SDL_QuitSteamControllers(void)
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: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

◆ SDL_SYS_JoystickUpdate()

void SDL_SYS_JoystickUpdate ( SDL_Joystick *  joystick)

Definition at line 675 of file SDL_sysjoystick.m.

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

Referenced by SDL_JoystickOpen(), and SDL_JoystickUpdate().

676 {
677  SDL_JoystickDeviceItem *device = joystick->hwdata;
678 
679  if (device == NULL) {
680  return;
681  }
682 
683  if (device->m_bSteamController) {
684  SDL_UpdateSteamController(joystick);
685  return;
686  }
687 
688  if (device->accelerometer) {
689  SDL_SYS_AccelerometerUpdate(joystick);
690  } else if (device->controller) {
691  SDL_SYS_MFIJoystickUpdate(joystick);
692  }
693 }
static void SDL_SYS_MFIJoystickUpdate(SDL_Joystick *joystick)
static SDL_AudioDeviceID device
Definition: loopwave.c:37
#define NULL
Definition: begin_code.h:164
void SDL_UpdateSteamController(SDL_Joystick *joystick)
SDL_bool m_bSteamController
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 533 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().

534 {
535 #if SDL_JOYSTICK_MFI
536  @autoreleasepool {
537  GCController *controller = joystick->hwdata->controller;
538  Uint8 hatstate = SDL_HAT_CENTERED;
539  int i;
540  int updateplayerindex = 0;
541 
542  if (controller.extendedGamepad) {
543  GCExtendedGamepad *gamepad = controller.extendedGamepad;
544 
545  /* Axis order matches the XInput Windows mappings. */
546  Sint16 axes[] = {
547  (Sint16) (gamepad.leftThumbstick.xAxis.value * 32767),
548  (Sint16) (gamepad.leftThumbstick.yAxis.value * -32767),
549  (Sint16) ((gamepad.leftTrigger.value * 65535) - 32768),
550  (Sint16) (gamepad.rightThumbstick.xAxis.value * 32767),
551  (Sint16) (gamepad.rightThumbstick.yAxis.value * -32767),
552  (Sint16) ((gamepad.rightTrigger.value * 65535) - 32768),
553  };
554 
555  /* Button order matches the XInput Windows mappings. */
556  Uint8 buttons[] = {
557  gamepad.buttonA.isPressed, gamepad.buttonB.isPressed,
558  gamepad.buttonX.isPressed, gamepad.buttonY.isPressed,
559  gamepad.leftShoulder.isPressed,
560  gamepad.rightShoulder.isPressed,
561  };
562 
563  hatstate = SDL_SYS_MFIJoystickHatStateForDPad(gamepad.dpad);
564 
565  for (i = 0; i < SDL_arraysize(axes); i++) {
566  /* The triggers (axes 2 and 5) are resting at -32768 but SDL
567  * initializes its values to 0. We only want to make sure the
568  * player index is up to date if the user actually moves an axis. */
569  if ((i != 2 && i != 5) || axes[i] != -32768) {
570  updateplayerindex |= (joystick->axes[i].value != axes[i]);
571  }
572  SDL_PrivateJoystickAxis(joystick, i, axes[i]);
573  }
574 
575  for (i = 0; i < SDL_arraysize(buttons); i++) {
576  updateplayerindex |= (joystick->buttons[i] != buttons[i]);
577  SDL_PrivateJoystickButton(joystick, i, buttons[i]);
578  }
579  } else if (controller.gamepad) {
580  GCGamepad *gamepad = controller.gamepad;
581 
582  /* Button order matches the XInput Windows mappings. */
583  Uint8 buttons[] = {
584  gamepad.buttonA.isPressed, gamepad.buttonB.isPressed,
585  gamepad.buttonX.isPressed, gamepad.buttonY.isPressed,
586  gamepad.leftShoulder.isPressed,
587  gamepad.rightShoulder.isPressed,
588  };
589 
590  hatstate = SDL_SYS_MFIJoystickHatStateForDPad(gamepad.dpad);
591 
592  for (i = 0; i < SDL_arraysize(buttons); i++) {
593  updateplayerindex |= (joystick->buttons[i] != buttons[i]);
594  SDL_PrivateJoystickButton(joystick, i, buttons[i]);
595  }
596  }
597 #if TARGET_OS_TV
598  else if (controller.microGamepad) {
599  GCMicroGamepad *gamepad = controller.microGamepad;
600 
601  Sint16 axes[] = {
602  (Sint16) (gamepad.dpad.xAxis.value * 32767),
603  (Sint16) (gamepad.dpad.yAxis.value * -32767),
604  };
605 
606  for (i = 0; i < SDL_arraysize(axes); i++) {
607  updateplayerindex |= (joystick->axes[i].value != axes[i]);
608  SDL_PrivateJoystickAxis(joystick, i, axes[i]);
609  }
610 
611  /* Apparently the dpad values are not accurate enough to be useful. */
612  /* hatstate = SDL_SYS_MFIJoystickHatStateForDPad(gamepad.dpad); */
613 
614  Uint8 buttons[] = {
615  gamepad.buttonA.isPressed,
616  gamepad.buttonX.isPressed,
617  };
618 
619  for (i = 0; i < SDL_arraysize(buttons); i++) {
620  updateplayerindex |= (joystick->buttons[i] != buttons[i]);
621  SDL_PrivateJoystickButton(joystick, i, buttons[i]);
622  }
623 
624  /* TODO: Figure out what to do with reportsAbsoluteDpadValues */
625  }
626 #endif /* TARGET_OS_TV */
627 
628  if (joystick->nhats > 0) {
629  updateplayerindex |= (joystick->hats[0] != hatstate);
630  SDL_PrivateJoystickHat(joystick, 0, hatstate);
631  }
632 
633  for (i = 0; i < joystick->hwdata->num_pause_presses; i++) {
634  /* The pause button is always last. */
635  Uint8 pausebutton = joystick->nbuttons - 1;
636 
637  SDL_PrivateJoystickButton(joystick, pausebutton, SDL_PRESSED);
638  SDL_PrivateJoystickButton(joystick, pausebutton, SDL_RELEASED);
639 
640  updateplayerindex = YES;
641  }
642 
643  joystick->hwdata->num_pause_presses = 0;
644 
645  if (updateplayerindex && controller.playerIndex == -1) {
646  BOOL usedPlayerIndexSlots[4] = {NO, NO, NO, NO};
647 
648  /* Find the player index of all other connected controllers. */
649  for (GCController *c in [GCController controllers]) {
650  if (c != controller && c.playerIndex >= 0) {
651  usedPlayerIndexSlots[c.playerIndex] = YES;
652  }
653  }
654 
655  /* Set this controller's player index to the first unused index.
656  * FIXME: This logic isn't great... but SDL doesn't expose this
657  * concept in its external API, so we don't have much to go on. */
658  for (i = 0; i < SDL_arraysize(usedPlayerIndexSlots); i++) {
659  if (!usedPlayerIndexSlots[i]) {
660  controller.playerIndex = i;
661  break;
662  }
663  }
664  }
665  }
666 #endif /* SDL_JOYSTICK_MFI */
667 }
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
Definition: SDL_joystick.c:712
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
Definition: SDL_joystick.c:788
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
Definition: SDL_joystick.c:655
uint8_t Uint8
Definition: SDL_stdinc.h:157
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:93
#define SDL_PRESSED
Definition: SDL_events.h:50
#define SDL_HAT_CENTERED
Definition: SDL_joystick.h:316
#define SDL_RELEASED
Definition: SDL_events.h:49
GLuint in
int16_t Sint16
Definition: SDL_stdinc.h:163

◆ SDL_SYS_NumJoysticks()

int SDL_SYS_NumJoysticks ( void  )

Definition at line 380 of file SDL_sysjoystick.m.

References numjoysticks.

Referenced by SDL_NumJoysticks().

381 {
382  return numjoysticks;
383 }
static int numjoysticks

◆ SDL_SYS_RemoveJoystickDevice()

static SDL_JoystickDeviceItem* SDL_SYS_RemoveJoystickDevice ( SDL_JoystickDeviceItem device)
static

Definition at line 203 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, SDL_PrivateJoystickRemoved(), and SDLCALL.

Referenced by SDL_SYS_JoystickQuit(), and SteamControllerDisconnectedCallback().

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

◆ SteamControllerConnectedCallback()

static SDL_bool SteamControllerConnectedCallback ( const char *  name,
SDL_JoystickGUID  guid,
int *  device_instance 
)
static

Definition at line 272 of file SDL_sysjoystick.m.

References device, deviceList, recDevice::guid, recDevice::instance_id, instancecounter, recDevice::m_bSteamController, recDevice::name, recDevice::naxes, recDevice::nbuttons, recDevice::next, recDevice::nhats, NULL, numjoysticks, SDL_calloc, SDL_FALSE, SDL_GetSteamControllerInputs(), SDL_PrivateJoystickAdded(), SDL_strdup, and SDL_TRUE.

Referenced by SDL_SYS_JoystickInit().

273 {
275  if (device == NULL) {
276  return SDL_FALSE;
277  }
278 
279  *device_instance = device->instance_id = instancecounter++;
280  device->name = SDL_strdup(name);
281  device->guid = guid;
283  &device->naxes,
284  &device->nhats);
285  device->m_bSteamController = SDL_TRUE;
286 
287  if (deviceList == NULL) {
288  deviceList = device;
289  } else {
290  SDL_JoystickDeviceItem *lastdevice = deviceList;
291  while (lastdevice->next != NULL) {
292  lastdevice = lastdevice->next;
293  }
294  lastdevice->next = device;
295  }
296 
297  ++numjoysticks;
298 
300 
301  return SDL_TRUE;
302 }
SDL_JoystickGUID guid
static SDL_JoystickDeviceItem * deviceList
struct joystick_hwdata * next
GLuint const GLchar * name
static SDL_AudioDeviceID device
Definition: loopwave.c:37
void SDL_PrivateJoystickAdded(int device_index)
Definition: SDL_joystick.c:595
#define NULL
Definition: begin_code.h:164
SDL_bool m_bSteamController
#define SDL_calloc
static SDL_JoystickID instancecounter
#define SDL_strdup
static int numjoysticks
void SDL_GetSteamControllerInputs(int *nbuttons, int *naxes, int *nhats)

◆ SteamControllerDisconnectedCallback()

static void SteamControllerDisconnectedCallback ( int  device_instance)
static

Definition at line 304 of file SDL_sysjoystick.m.

References recDevice::instance_id, recDevice::item, recDevice::next, and SDL_SYS_RemoveJoystickDevice().

Referenced by SDL_SYS_JoystickInit().

305 {
307 
308  for (item = deviceList; item; item = item->next) {
309  if (item->instance_id == device_instance) {
311  break;
312  }
313  }
314 }
static SDL_JoystickDeviceItem * deviceList
struct joystick_hwdata * next
static SDL_JoystickDeviceItem * SDL_SYS_RemoveJoystickDevice(SDL_JoystickDeviceItem *device)

Variable Documentation

◆ accelerometerName

const char* accelerometerName = "iOS Accelerometer"
static

Definition at line 55 of file SDL_sysjoystick.m.

Referenced by SDL_SYS_AddJoystickDevice().

◆ deviceList

◆ instancecounter

SDL_JoystickID instancecounter = 0
static

◆ motionManager

CMMotionManager* motionManager = nil
static

◆ numjoysticks