SDL  2.0
SDL_mfijoystick.m File Reference
#include "../../SDL_internal.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 "../usb_ids.h"
#include "SDL_mfijoystick_c.h"
#include "../../events/SDL_events_c.h"
+ Include dependency graph for SDL_mfijoystick.m:

Go to the source code of this file.

Functions

static SDL_JoystickDeviceItemGetDeviceForIndex (int device_index)
 
static SDL_JoystickDeviceItemIOS_RemoveJoystickDevice (SDL_JoystickDeviceItem *device)
 
static int IOS_JoystickInit (void)
 
static int IOS_JoystickGetCount (void)
 
static void IOS_JoystickDetect (void)
 
static const char * IOS_JoystickGetDeviceName (int device_index)
 
static int IOS_JoystickGetDevicePlayerIndex (int device_index)
 
static void IOS_JoystickSetDevicePlayerIndex (int device_index, int player_index)
 
static SDL_JoystickGUID IOS_JoystickGetDeviceGUID (int device_index)
 
static SDL_JoystickID IOS_JoystickGetDeviceInstanceID (int device_index)
 
static int IOS_JoystickOpen (SDL_Joystick *joystick, int device_index)
 
static void IOS_AccelerometerUpdate (SDL_Joystick *joystick)
 
static void IOS_MFIJoystickUpdate (SDL_Joystick *joystick)
 
static int IOS_JoystickRumble (SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
 
static int IOS_JoystickRumbleTriggers (SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
 
static SDL_bool IOS_JoystickHasLED (SDL_Joystick *joystick)
 
static int IOS_JoystickSetLED (SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
 
static int IOS_JoystickSetSensorsEnabled (SDL_Joystick *joystick, SDL_bool enabled)
 
static void IOS_JoystickUpdate (SDL_Joystick *joystick)
 
static void IOS_JoystickClose (SDL_Joystick *joystick)
 
static void IOS_JoystickQuit (void)
 
static SDL_bool IOS_JoystickGetGamepadMapping (int device_index, SDL_GamepadMapping *out)
 

Variables

static SDL_JoystickDeviceItemdeviceList = NULL
 
static int numjoysticks = 0
 
int SDL_AppleTVRemoteOpenedAsJoystick = 0
 
SDL_JoystickDriver SDL_IOS_JoystickDriver
 

Function Documentation

◆ GetDeviceForIndex()

static SDL_JoystickDeviceItem* GetDeviceForIndex ( int  device_index)
static

Definition at line 112 of file SDL_mfijoystick.m.

113 {
115  int i = 0;
116 
117  while (i < device_index) {
118  if (device == NULL) {
119  return NULL;
120  }
121  device = device->next;
122  i++;
123  }
124 
125  return device;
126 }
static SDL_JoystickDeviceItem * deviceList
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:163
static SDL_AudioDeviceID device
Definition: loopwave.c:37

References device, deviceList, i, and NULL.

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

◆ IOS_AccelerometerUpdate()

static void IOS_AccelerometerUpdate ( SDL_Joystick *  joystick)
static

Definition at line 670 of file SDL_mfijoystick.m.

671 {
672 #ifdef SDL_JOYSTICK_iOS_ACCELEROMETER
673  const float maxgforce = SDL_IPHONE_MAX_GFORCE;
674  const SInt16 maxsint16 = 0x7FFF;
675  CMAcceleration accel;
676 
677  @autoreleasepool {
678  if (!motionManager.isAccelerometerActive) {
679  return;
680  }
681 
682  accel = motionManager.accelerometerData.acceleration;
683  }
684 
685  /*
686  Convert accelerometer data from floating point to Sint16, which is what
687  the joystick system expects.
688 
689  To do the conversion, the data is first clamped onto the interval
690  [-SDL_IPHONE_MAX_G_FORCE, SDL_IPHONE_MAX_G_FORCE], then the data is multiplied
691  by MAX_SINT16 so that it is mapped to the full range of an Sint16.
692 
693  You can customize the clamped range of this function by modifying the
694  SDL_IPHONE_MAX_GFORCE macro in SDL_config_iphoneos.h.
695 
696  Once converted to Sint16, the accelerometer data no longer has coherent
697  units. You can convert the data back to units of g-force by multiplying
698  it in your application's code by SDL_IPHONE_MAX_GFORCE / 0x7FFF.
699  */
700 
701  /* clamp the data */
702  accel.x = SDL_min(SDL_max(accel.x, -maxgforce), maxgforce);
703  accel.y = SDL_min(SDL_max(accel.y, -maxgforce), maxgforce);
704  accel.z = SDL_min(SDL_max(accel.z, -maxgforce), maxgforce);
705 
706  /* pass in data mapped to range of SInt16 */
707  SDL_PrivateJoystickAxis(joystick, 0, (accel.x / maxgforce) * maxsint16);
708  SDL_PrivateJoystickAxis(joystick, 1, -(accel.y / maxgforce) * maxsint16);
709  SDL_PrivateJoystickAxis(joystick, 2, (accel.z / maxgforce) * maxsint16);
710 #endif /* SDL_JOYSTICK_iOS_ACCELEROMETER */
711 }
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
#define SDL_IPHONE_MAX_GFORCE
Definition: SDL_joystick.h:111
#define SDL_min(x, y)
Definition: SDL_stdinc.h:412
#define SDL_max(x, y)
Definition: SDL_stdinc.h:413
static SDL_Joystick * joystick
Definition: testjoystick.c:37

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

Referenced by IOS_JoystickUpdate().

◆ IOS_JoystickClose()

static void IOS_JoystickClose ( SDL_Joystick *  joystick)
static

Definition at line 1304 of file SDL_mfijoystick.m.

1305 {
1307 
1308  if (device == NULL) {
1309  return;
1310  }
1311 
1312  device->joystick = NULL;
1313 
1314  @autoreleasepool {
1315 #ifdef ENABLE_MFI_RUMBLE
1316  if (device->rumble) {
1317  SDL_RumbleContext *rumble = (__bridge SDL_RumbleContext *)device->rumble;
1318 
1319  [rumble cleanup];
1320  CFRelease(device->rumble);
1321  device->rumble = NULL;
1322  }
1323 #endif /* ENABLE_MFI_RUMBLE */
1324 
1325  if (device->accelerometer) {
1326 #ifdef SDL_JOYSTICK_iOS_ACCELEROMETER
1327  [motionManager stopAccelerometerUpdates];
1328 #endif
1329  } else if (device->controller) {
1330 #ifdef SDL_JOYSTICK_MFI
1331  GCController *controller = device->controller;
1332  controller.controllerPausedHandler = nil;
1333  controller.playerIndex = -1;
1334 #endif
1335  }
1336  }
1337  if (device->remote) {
1339  }
1340 }
int SDL_AppleTVRemoteOpenedAsJoystick
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld cleanup[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld_src SRC pixld MASK if DST_R else pixld DST_R endif if src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head if pixblock_size cache_preload_simple endif process_pixblock_tail pixinterleave dst_w_basereg irp if pixblock_size chunk_size tst beq if DST_W else pixst DST_W else mov ORIG_W endif add lsl if lsl endif if lsl endif lsl endif lsl endif lsl endif subs mov DST_W if regs_shortage str endif bge start_of_loop_label endm macro generate_composite_function

References cleanup, device, joystick, NULL, and SDL_AppleTVRemoteOpenedAsJoystick.

◆ IOS_JoystickDetect()

static void IOS_JoystickDetect ( void  )
static

Definition at line 548 of file SDL_mfijoystick.m.

549 {
550 }

◆ IOS_JoystickGetCount()

static int IOS_JoystickGetCount ( void  )
static

Definition at line 542 of file SDL_mfijoystick.m.

543 {
544  return numjoysticks;
545 }
static int numjoysticks

References numjoysticks.

◆ IOS_JoystickGetDeviceGUID()

static SDL_JoystickGUID IOS_JoystickGetDeviceGUID ( int  device_index)
static

Definition at line 583 of file SDL_mfijoystick.m.

584 {
586  SDL_JoystickGUID guid;
587  if (device) {
588  guid = device->guid;
589  } else {
590  SDL_zero(guid);
591  }
592  return guid;
593 }
static SDL_JoystickDeviceItem * GetDeviceForIndex(int device_index)
#define SDL_zero(x)
Definition: SDL_stdinc.h:426

References device, GetDeviceForIndex(), and SDL_zero.

◆ IOS_JoystickGetDeviceInstanceID()

static SDL_JoystickID IOS_JoystickGetDeviceInstanceID ( int  device_index)
static

Definition at line 596 of file SDL_mfijoystick.m.

597 {
599  return device ? device->instance_id : -1;
600 }

References device, and GetDeviceForIndex().

◆ IOS_JoystickGetDeviceName()

static const char* IOS_JoystickGetDeviceName ( int  device_index)
static

Definition at line 553 of file SDL_mfijoystick.m.

554 {
556  return device ? device->name : "Unknown";
557 }

References device, and GetDeviceForIndex().

◆ IOS_JoystickGetDevicePlayerIndex()

static int IOS_JoystickGetDevicePlayerIndex ( int  device_index)
static

Definition at line 560 of file SDL_mfijoystick.m.

561 {
562 #ifdef SDL_JOYSTICK_MFI
564  if (device && device->controller) {
565  return (int)device->controller.playerIndex;
566  }
567 #endif
568  return -1;
569 }

References device, and GetDeviceForIndex().

◆ IOS_JoystickGetGamepadMapping()

static SDL_bool IOS_JoystickGetGamepadMapping ( int  device_index,
SDL_GamepadMapping out 
)
static

Definition at line 1378 of file SDL_mfijoystick.m.

1379 {
1380  return SDL_FALSE;
1381 }
@ SDL_FALSE
Definition: SDL_stdinc.h:169

References SDL_FALSE.

◆ IOS_JoystickHasLED()

static SDL_bool IOS_JoystickHasLED ( SDL_Joystick *  joystick)
static

Definition at line 1230 of file SDL_mfijoystick.m.

1231 {
1232 #ifdef ENABLE_MFI_LIGHT
1233  @autoreleasepool {
1234  if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) {
1235  GCController *controller = joystick->hwdata->controller;
1236  GCDeviceLight *light = controller.light;
1237  if (light) {
1238  return SDL_TRUE;
1239  }
1240  }
1241  }
1242 #endif /* ENABLE_MFI_LIGHT */
1243 
1244  return SDL_FALSE;
1245 }
const GLubyte GLuint GLuint GLuint GLuint alpha GLboolean GLboolean GLboolean GLboolean alpha GLint GLint GLsizei GLsizei GLenum type GLenum GLint GLenum GLint GLint GLsizei GLsizei GLint border GLenum GLint GLint GLint GLint GLint GLsizei GLsizei height GLsizei GLsizei GLenum GLenum const GLvoid *pixels GLenum GLint GLint GLint GLint j2 GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble zFar GLenum light
Definition: SDL_glfuncs.h:167
@ SDL_TRUE
Definition: SDL_stdinc.h:170

References joystick, light, SDL_FALSE, and SDL_TRUE.

◆ IOS_JoystickInit()

static int IOS_JoystickInit ( void  )
static

Definition at line 478 of file SDL_mfijoystick.m.

479 {
480 #if defined(__MACOSX__)
481  if (!is_macos11()) {
482  return 0;
483  }
484 #endif
485 
486  @autoreleasepool {
487 #ifdef SDL_JOYSTICK_iOS_ACCELEROMETER
489  /* Default behavior, accelerometer as joystick */
490  IOS_AddJoystickDevice(nil, SDL_TRUE);
491  }
492 #endif
493 
494 #ifdef SDL_JOYSTICK_MFI
495  /* GameController.framework was added in iOS 7. */
496  if (![GCController class]) {
497  return 0;
498  }
499 
500  /* For whatever reason, this always returns an empty array on
501  macOS 11.0.1 */
502  for (GCController *controller in [GCController controllers]) {
503  IOS_AddJoystickDevice(controller, SDL_FALSE);
504  }
505 
506 #if TARGET_OS_TV
508  SDL_AppleTVRemoteRotationHintChanged, NULL);
509 #endif /* TARGET_OS_TV */
510 
511  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
512 
513  connectObserver = [center addObserverForName:GCControllerDidConnectNotification
514  object:nil
515  queue:nil
516  usingBlock:^(NSNotification *note) {
517  GCController *controller = note.object;
518  IOS_AddJoystickDevice(controller, SDL_FALSE);
519  }];
520 
521  disconnectObserver = [center addObserverForName:GCControllerDidDisconnectNotification
522  object:nil
523  queue:nil
524  usingBlock:^(NSNotification *note) {
525  GCController *controller = note.object;
526  SDL_JoystickDeviceItem *device = deviceList;
527  while (device != NULL) {
528  if (device->controller == controller) {
529  IOS_RemoveJoystickDevice(device);
530  break;
531  }
532  device = device->next;
533  }
534  }];
535 #endif /* SDL_JOYSTICK_MFI */
536  }
537 
538  return 0;
539 }
#define SDL_GetHintBoolean
#define SDL_AddHintCallback
#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:454
#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:433
GLuint in

References sort_controllers::controllers, NULL, SDL_AddHintCallback, SDL_FALSE, SDL_GetHintBoolean, SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION, and SDL_TRUE.

◆ IOS_JoystickOpen()

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

Definition at line 603 of file SDL_mfijoystick.m.

604 {
606  if (device == NULL) {
607  return SDL_SetError("Could not open Joystick: no hardware device for the specified index");
608  }
609 
610  joystick->hwdata = device;
611  joystick->instance_id = device->instance_id;
612 
613  joystick->naxes = device->naxes;
614  joystick->nhats = device->nhats;
615  joystick->nbuttons = device->nbuttons;
616  joystick->nballs = 0;
617 
618  if (device->has_dualshock_touchpad) {
620  }
621 
622  device->joystick = joystick;
623 
624  @autoreleasepool {
625  if (device->accelerometer) {
626 #ifdef SDL_JOYSTICK_iOS_ACCELEROMETER
627  if (motionManager == nil) {
628  motionManager = [[CMMotionManager alloc] init];
629  }
630 
631  /* Shorter times between updates can significantly increase CPU usage. */
632  motionManager.accelerometerUpdateInterval = 0.1;
633  [motionManager startAccelerometerUpdates];
634 #endif
635  } else {
636 #ifdef SDL_JOYSTICK_MFI
637  if (device->uses_pause_handler) {
638  GCController *controller = device->controller;
639  controller.controllerPausedHandler = ^(GCController *c) {
640  if (joystick->hwdata) {
641  ++joystick->hwdata->num_pause_presses;
642  }
643  };
644  }
645 
646 #ifdef ENABLE_MFI_SENSORS
647  if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
648  GCController *controller = joystick->hwdata->controller;
649  GCMotion *motion = controller.motion;
650  if (motion && motion.hasRotationRate) {
652  }
653  if (motion && motion.hasGravityAndUserAcceleration) {
655  }
656  }
657 #endif /* ENABLE_MFI_SENSORS */
658 
659 #endif /* SDL_JOYSTICK_MFI */
660  }
661  }
662  if (device->remote) {
664  }
665 
666  return 0;
667 }
#define SDL_SetError
void SDL_PrivateJoystickAddTouchpad(SDL_Joystick *joystick, int nfingers)
void SDL_PrivateJoystickAddSensor(SDL_Joystick *joystick, SDL_SensorType type)
const GLubyte * c
@ SDL_SENSOR_GYRO
Definition: SDL_sensor.h:74
@ SDL_SENSOR_ACCEL
Definition: SDL_sensor.h:73

References device, GetDeviceForIndex(), joystick, NULL, SDL_AppleTVRemoteOpenedAsJoystick, SDL_PrivateJoystickAddSensor(), SDL_PrivateJoystickAddTouchpad(), SDL_SENSOR_ACCEL, SDL_SENSOR_GYRO, and SDL_SetError.

◆ IOS_JoystickQuit()

static void IOS_JoystickQuit ( void  )
static

Definition at line 1343 of file SDL_mfijoystick.m.

1344 {
1345  @autoreleasepool {
1346 #ifdef SDL_JOYSTICK_MFI
1347  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
1348 
1349  if (connectObserver) {
1350  [center removeObserver:connectObserver name:GCControllerDidConnectNotification object:nil];
1351  connectObserver = nil;
1352  }
1353 
1354  if (disconnectObserver) {
1355  [center removeObserver:disconnectObserver name:GCControllerDidDisconnectNotification object:nil];
1356  disconnectObserver = nil;
1357  }
1358 
1359 #if TARGET_OS_TV
1361  SDL_AppleTVRemoteRotationHintChanged, NULL);
1362 #endif /* TARGET_OS_TV */
1363 #endif /* SDL_JOYSTICK_MFI */
1364 
1365  while (deviceList != NULL) {
1367  }
1368 
1369 #ifdef SDL_JOYSTICK_iOS_ACCELEROMETER
1370  motionManager = nil;
1371 #endif
1372  }
1373 
1374  numjoysticks = 0;
1375 }
#define SDL_DelHintCallback
static SDL_JoystickDeviceItem * IOS_RemoveJoystickDevice(SDL_JoystickDeviceItem *device)

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

◆ IOS_JoystickRumble()

static int IOS_JoystickRumble ( SDL_Joystick *  joystick,
Uint16  low_frequency_rumble,
Uint16  high_frequency_rumble 
)
static

Definition at line 1178 of file SDL_mfijoystick.m.

1179 {
1180 #ifdef ENABLE_MFI_RUMBLE
1182 
1183  if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
1184  if (!device->rumble && device->controller && device->controller.haptics) {
1185  SDL_RumbleContext *rumble = IOS_JoystickInitRumble(device->controller);
1186  if (rumble) {
1187  device->rumble = (void *)CFBridgingRetain(rumble);
1188  }
1189  }
1190  }
1191 
1192  if (device->rumble) {
1193  SDL_RumbleContext *rumble = (__bridge SDL_RumbleContext *)device->rumble;
1194  return [rumble rumbleWithLowFrequency:low_frequency_rumble andHighFrequency:high_frequency_rumble];
1195  } else {
1196  return SDL_Unsupported();
1197  }
1198 #else
1199  return SDL_Unsupported();
1200 #endif
1201 }
#define SDL_Unsupported()
Definition: SDL_error.h:89

References device, joystick, and SDL_Unsupported.

◆ IOS_JoystickRumbleTriggers()

static int IOS_JoystickRumbleTriggers ( SDL_Joystick *  joystick,
Uint16  left_rumble,
Uint16  right_rumble 
)
static

Definition at line 1204 of file SDL_mfijoystick.m.

1205 {
1206 #ifdef ENABLE_MFI_RUMBLE
1208 
1209  if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
1210  if (!device->rumble && device->controller && device->controller.haptics) {
1211  SDL_RumbleContext *rumble = IOS_JoystickInitRumble(device->controller);
1212  if (rumble) {
1213  device->rumble = (void *)CFBridgingRetain(rumble);
1214  }
1215  }
1216  }
1217 
1218  if (device->rumble) {
1219  SDL_RumbleContext *rumble = (__bridge SDL_RumbleContext *)device->rumble;
1220  return [rumble rumbleLeftTrigger:left_rumble andRightTrigger:right_rumble];
1221  } else {
1222  return SDL_Unsupported();
1223  }
1224 #else
1225  return SDL_Unsupported();
1226 #endif
1227 }

References device, joystick, and SDL_Unsupported.

◆ IOS_JoystickSetDevicePlayerIndex()

static void IOS_JoystickSetDevicePlayerIndex ( int  device_index,
int  player_index 
)
static

Definition at line 572 of file SDL_mfijoystick.m.

573 {
574 #ifdef SDL_JOYSTICK_MFI
576  if (device && device->controller) {
577  device->controller.playerIndex = player_index;
578  }
579 #endif
580 }

References device, and GetDeviceForIndex().

◆ IOS_JoystickSetLED()

static int IOS_JoystickSetLED ( SDL_Joystick *  joystick,
Uint8  red,
Uint8  green,
Uint8  blue 
)
static

Definition at line 1248 of file SDL_mfijoystick.m.

1249 {
1250 #ifdef ENABLE_MFI_LIGHT
1251  @autoreleasepool {
1252  if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) {
1253  GCController *controller = joystick->hwdata->controller;
1254  GCDeviceLight *light = controller.light;
1255  if (light) {
1256  light.color = [[GCColor alloc] initWithRed:(float)red / 255.0f
1257  green:(float)green / 255.0f
1258  blue:(float)blue / 255.0f];
1259  return 0;
1260  }
1261  }
1262  }
1263 #endif /* ENABLE_MFI_LIGHT */
1264 
1265  return SDL_Unsupported();
1266 }

References joystick, light, and SDL_Unsupported.

◆ IOS_JoystickSetSensorsEnabled()

static int IOS_JoystickSetSensorsEnabled ( SDL_Joystick *  joystick,
SDL_bool  enabled 
)
static

Definition at line 1269 of file SDL_mfijoystick.m.

1270 {
1271 #ifdef ENABLE_MFI_SENSORS
1272  @autoreleasepool {
1273  if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
1274  GCController *controller = joystick->hwdata->controller;
1275  GCMotion *motion = controller.motion;
1276  if (motion) {
1277  motion.sensorsActive = enabled ? YES : NO;
1278  return 0;
1279  }
1280  }
1281  }
1282 #endif /* ENABLE_MFI_SENSORS */
1283 
1284  return SDL_Unsupported();
1285 }
GLenum GLenum GLsizei const GLuint GLboolean enabled

References joystick, and SDL_Unsupported.

◆ IOS_JoystickUpdate()

static void IOS_JoystickUpdate ( SDL_Joystick *  joystick)
static

Definition at line 1288 of file SDL_mfijoystick.m.

1289 {
1291 
1292  if (device == NULL) {
1293  return;
1294  }
1295 
1296  if (device->accelerometer) {
1298  } else if (device->controller) {
1300  }
1301 }
static void IOS_AccelerometerUpdate(SDL_Joystick *joystick)
static void IOS_MFIJoystickUpdate(SDL_Joystick *joystick)

References device, IOS_AccelerometerUpdate(), IOS_MFIJoystickUpdate(), joystick, and NULL.

◆ IOS_MFIJoystickUpdate()

static void IOS_MFIJoystickUpdate ( SDL_Joystick *  joystick)
static

Definition at line 740 of file SDL_mfijoystick.m.

741 {
742 #if SDL_JOYSTICK_MFI
743  @autoreleasepool {
744  GCController *controller = joystick->hwdata->controller;
745  Uint8 hatstate = SDL_HAT_CENTERED;
746  int i;
747  int pause_button_index = 0;
748 
749  if (controller.extendedGamepad) {
750  GCExtendedGamepad *gamepad = controller.extendedGamepad;
751 
752  /* Axis order matches the XInput Windows mappings. */
753  Sint16 axes[] = {
754  (Sint16) (gamepad.leftThumbstick.xAxis.value * 32767),
755  (Sint16) (gamepad.leftThumbstick.yAxis.value * -32767),
756  (Sint16) ((gamepad.leftTrigger.value * 65535) - 32768),
757  (Sint16) (gamepad.rightThumbstick.xAxis.value * 32767),
758  (Sint16) (gamepad.rightThumbstick.yAxis.value * -32767),
759  (Sint16) ((gamepad.rightTrigger.value * 65535) - 32768),
760  };
761 
762  /* Button order matches the XInput Windows mappings. */
763  Uint8 buttons[joystick->nbuttons];
764  int button_count = 0;
765 
766  /* These buttons are part of the original MFi spec */
767  buttons[button_count++] = gamepad.buttonA.isPressed;
768  buttons[button_count++] = gamepad.buttonB.isPressed;
769  buttons[button_count++] = gamepad.buttonX.isPressed;
770  buttons[button_count++] = gamepad.buttonY.isPressed;
771  buttons[button_count++] = gamepad.leftShoulder.isPressed;
772  buttons[button_count++] = gamepad.rightShoulder.isPressed;
773 
774  /* These buttons are available on some newer controllers */
775 #pragma clang diagnostic push
776 #pragma clang diagnostic ignored "-Wunguarded-availability-new"
777  if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSTICK)) {
778  buttons[button_count++] = gamepad.leftThumbstickButton.isPressed;
779  }
780  if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSTICK)) {
781  buttons[button_count++] = gamepad.rightThumbstickButton.isPressed;
782  }
783  if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_BACK)) {
784  buttons[button_count++] = gamepad.buttonOptions.isPressed;
785  }
786  if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_GUIDE)) {
787  buttons[button_count++] = gamepad.buttonHome.isPressed;
788  }
789  /* This must be the last button, so we can optionally handle it with pause_button_index below */
790  if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_START)) {
791  if (joystick->hwdata->uses_pause_handler) {
792  pause_button_index = button_count;
793  buttons[button_count++] = joystick->delayed_guide_button;
794  } else {
795  buttons[button_count++] = gamepad.buttonMenu.isPressed;
796  }
797  }
798 
799 #ifdef ENABLE_PHYSICAL_INPUT_PROFILE
800  if (joystick->hwdata->has_dualshock_touchpad) {
801  buttons[button_count++] = controller.physicalInputProfile.buttons[GCInputDualShockTouchpadButton].isPressed;
802 
803  GCControllerDirectionPad *dpad;
804 
805  dpad = controller.physicalInputProfile.dpads[GCInputDualShockTouchpadOne];
806  if (dpad.xAxis.value || dpad.yAxis.value) {
807  SDL_PrivateJoystickTouchpad(joystick, 0, 0, SDL_PRESSED, (1.0f + dpad.xAxis.value) * 0.5f, 1.0f - (1.0f + dpad.yAxis.value) * 0.5f, 1.0f);
808  } else {
810  }
811 
812  dpad = controller.physicalInputProfile.dpads[GCInputDualShockTouchpadTwo];
813  if (dpad.xAxis.value || dpad.yAxis.value) {
814  SDL_PrivateJoystickTouchpad(joystick, 0, 1, SDL_PRESSED, (1.0f + dpad.xAxis.value) * 0.5f, 1.0f - (1.0f + dpad.yAxis.value) * 0.5f, 1.0f);
815  } else {
817  }
818  }
819 
820  if (joystick->hwdata->has_xbox_paddles) {
821  if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_PADDLE1)) {
822  buttons[button_count++] = controller.physicalInputProfile.buttons[GCInputXboxPaddleOne].isPressed;
823  }
824  if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_PADDLE2)) {
825  buttons[button_count++] = controller.physicalInputProfile.buttons[GCInputXboxPaddleTwo].isPressed;
826  }
827  if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_PADDLE3)) {
828  buttons[button_count++] = controller.physicalInputProfile.buttons[GCInputXboxPaddleThree].isPressed;
829  }
830  if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_PADDLE4)) {
831  buttons[button_count++] = controller.physicalInputProfile.buttons[GCInputXboxPaddleFour].isPressed;
832  }
833 
834  /*
835  SDL_Log("Paddles: [%d,%d,%d,%d]",
836  controller.physicalInputProfile.buttons[GCInputXboxPaddleOne].isPressed,
837  controller.physicalInputProfile.buttons[GCInputXboxPaddleTwo].isPressed,
838  controller.physicalInputProfile.buttons[GCInputXboxPaddleThree].isPressed,
839  controller.physicalInputProfile.buttons[GCInputXboxPaddleFour].isPressed);
840  */
841  }
842 #endif
843 #pragma clang diagnostic pop
844 
845  hatstate = IOS_MFIJoystickHatStateForDPad(gamepad.dpad);
846 
847  for (i = 0; i < SDL_arraysize(axes); i++) {
849  }
850 
851  for (i = 0; i < button_count; i++) {
853  }
854 
855 #ifdef ENABLE_MFI_SENSORS
856  if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
857  GCMotion *motion = controller.motion;
858  if (motion && motion.sensorsActive) {
859  float data[3];
860 
861  if (motion.hasRotationRate) {
862  GCRotationRate rate = motion.rotationRate;
863  data[0] = rate.x;
864  data[1] = rate.z;
865  data[2] = -rate.y;
867  }
868  if (motion.hasGravityAndUserAcceleration) {
869  GCAcceleration accel = motion.acceleration;
870  data[0] = -accel.x * SDL_STANDARD_GRAVITY;
871  data[1] = -accel.y * SDL_STANDARD_GRAVITY;
872  data[2] = -accel.z * SDL_STANDARD_GRAVITY;
874  }
875  }
876  }
877 #endif /* ENABLE_MFI_SENSORS */
878 
879  } else if (controller.gamepad) {
880  GCGamepad *gamepad = controller.gamepad;
881 
882  /* Button order matches the XInput Windows mappings. */
883  Uint8 buttons[joystick->nbuttons];
884  int button_count = 0;
885  buttons[button_count++] = gamepad.buttonA.isPressed;
886  buttons[button_count++] = gamepad.buttonB.isPressed;
887  buttons[button_count++] = gamepad.buttonX.isPressed;
888  buttons[button_count++] = gamepad.buttonY.isPressed;
889  buttons[button_count++] = gamepad.leftShoulder.isPressed;
890  buttons[button_count++] = gamepad.rightShoulder.isPressed;
891  pause_button_index = button_count;
892  buttons[button_count++] = joystick->delayed_guide_button;
893 
894  hatstate = IOS_MFIJoystickHatStateForDPad(gamepad.dpad);
895 
896  for (i = 0; i < button_count; i++) {
898  }
899  }
900 #if TARGET_OS_TV
901  else if (controller.microGamepad) {
902  GCMicroGamepad *gamepad = controller.microGamepad;
903 
904  Sint16 axes[] = {
905  (Sint16) (gamepad.dpad.xAxis.value * 32767),
906  (Sint16) (gamepad.dpad.yAxis.value * -32767),
907  };
908 
909  for (i = 0; i < SDL_arraysize(axes); i++) {
911  }
912 
913  Uint8 buttons[joystick->nbuttons];
914  int button_count = 0;
915  buttons[button_count++] = gamepad.buttonA.isPressed;
916  buttons[button_count++] = gamepad.buttonX.isPressed;
917 #pragma clang diagnostic push
918 #pragma clang diagnostic ignored "-Wunguarded-availability-new"
919  /* This must be the last button, so we can optionally handle it with pause_button_index below */
920  if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_START)) {
921  if (joystick->hwdata->uses_pause_handler) {
922  pause_button_index = button_count;
923  buttons[button_count++] = joystick->delayed_guide_button;
924  } else {
925  buttons[button_count++] = gamepad.buttonMenu.isPressed;
926  }
927  }
928 #pragma clang diagnostic pop
929 
930  for (i = 0; i < button_count; i++) {
932  }
933  }
934 #endif /* TARGET_OS_TV */
935 
936  if (joystick->nhats > 0) {
937  SDL_PrivateJoystickHat(joystick, 0, hatstate);
938  }
939 
940  if (joystick->hwdata->uses_pause_handler) {
941  for (i = 0; i < joystick->hwdata->num_pause_presses; i++) {
942  SDL_PrivateJoystickButton(joystick, pause_button_index, SDL_PRESSED);
943  SDL_PrivateJoystickButton(joystick, pause_button_index, SDL_RELEASED);
944  }
945  joystick->hwdata->num_pause_presses = 0;
946  }
947 
948 #ifdef ENABLE_MFI_BATTERY
949  if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) {
950  GCDeviceBattery *battery = controller.battery;
951  if (battery) {
953 
954  switch (battery.batteryState) {
955  case GCDeviceBatteryStateDischarging:
956  {
957  float power_level = battery.batteryLevel;
958  if (power_level <= 0.05f) {
959  ePowerLevel = SDL_JOYSTICK_POWER_EMPTY;
960  } else if (power_level <= 0.20f) {
961  ePowerLevel = SDL_JOYSTICK_POWER_LOW;
962  } else if (power_level <= 0.70f) {
963  ePowerLevel = SDL_JOYSTICK_POWER_MEDIUM;
964  } else {
965  ePowerLevel = SDL_JOYSTICK_POWER_FULL;
966  }
967  }
968  break;
969  case GCDeviceBatteryStateCharging:
970  ePowerLevel = SDL_JOYSTICK_POWER_WIRED;
971  break;
972  case GCDeviceBatteryStateFull:
973  ePowerLevel = SDL_JOYSTICK_POWER_FULL;
974  break;
975  default:
976  break;
977  }
978 
980  }
981  }
982 #endif /* ENABLE_MFI_BATTERY */
983  }
984 #endif /* SDL_JOYSTICK_MFI */
985 }
#define SDL_RELEASED
Definition: SDL_events.h:49
#define SDL_PRESSED
Definition: SDL_events.h:50
@ SDL_CONTROLLER_BUTTON_BACK
@ SDL_CONTROLLER_BUTTON_LEFTSTICK
@ SDL_CONTROLLER_BUTTON_START
@ SDL_CONTROLLER_BUTTON_PADDLE2
@ SDL_CONTROLLER_BUTTON_PADDLE1
@ SDL_CONTROLLER_BUTTON_GUIDE
@ SDL_CONTROLLER_BUTTON_RIGHTSTICK
@ SDL_CONTROLLER_BUTTON_PADDLE3
@ SDL_CONTROLLER_BUTTON_PADDLE4
int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick, int touchpad, int finger, Uint8 state, float x, float y, float pressure)
void SDL_PrivateJoystickBatteryLevel(SDL_Joystick *joystick, SDL_JoystickPowerLevel ePowerLevel)
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
int SDL_PrivateJoystickSensor(SDL_Joystick *joystick, SDL_SensorType type, const float *data, int num_values)
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
SDL_JoystickPowerLevel
Definition: SDL_joystick.h:98
@ SDL_JOYSTICK_POWER_FULL
Definition: SDL_joystick.h:103
@ SDL_JOYSTICK_POWER_MEDIUM
Definition: SDL_joystick.h:102
@ SDL_JOYSTICK_POWER_EMPTY
Definition: SDL_joystick.h:100
@ SDL_JOYSTICK_POWER_UNKNOWN
Definition: SDL_joystick.h:99
@ SDL_JOYSTICK_POWER_WIRED
Definition: SDL_joystick.h:104
@ SDL_JOYSTICK_POWER_LOW
Definition: SDL_joystick.h:101
#define SDL_HAT_CENTERED
Definition: SDL_joystick.h:386
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLfloat f
GLdouble GLdouble z
GLsizei const GLfloat * value
#define SDL_STANDARD_GRAVITY
Definition: SDL_sensor.h:99
int16_t Sint16
Definition: SDL_stdinc.h:191
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:121
uint8_t Uint8
Definition: SDL_stdinc.h:185

References i, joystick, SDL_arraysize, SDL_CONTROLLER_BUTTON_BACK, SDL_CONTROLLER_BUTTON_GUIDE, SDL_CONTROLLER_BUTTON_LEFTSTICK, SDL_CONTROLLER_BUTTON_PADDLE1, SDL_CONTROLLER_BUTTON_PADDLE2, SDL_CONTROLLER_BUTTON_PADDLE3, SDL_CONTROLLER_BUTTON_PADDLE4, SDL_CONTROLLER_BUTTON_RIGHTSTICK, SDL_CONTROLLER_BUTTON_START, SDL_HAT_CENTERED, SDL_JOYSTICK_POWER_EMPTY, SDL_JOYSTICK_POWER_FULL, SDL_JOYSTICK_POWER_LOW, SDL_JOYSTICK_POWER_MEDIUM, SDL_JOYSTICK_POWER_UNKNOWN, SDL_JOYSTICK_POWER_WIRED, SDL_PRESSED, SDL_PrivateJoystickAxis(), SDL_PrivateJoystickBatteryLevel(), SDL_PrivateJoystickButton(), SDL_PrivateJoystickHat(), SDL_PrivateJoystickSensor(), SDL_PrivateJoystickTouchpad(), SDL_RELEASED, SDL_SENSOR_ACCEL, SDL_SENSOR_GYRO, and SDL_STANDARD_GRAVITY.

Referenced by IOS_JoystickUpdate().

◆ IOS_RemoveJoystickDevice()

static SDL_JoystickDeviceItem* IOS_RemoveJoystickDevice ( SDL_JoystickDeviceItem device)
static

Definition at line 401 of file SDL_mfijoystick.m.

402 {
406 
407  if (device == NULL) {
408  return NULL;
409  }
410 
411  next = device->next;
412 
413  while (item != NULL) {
414  if (item == device) {
415  break;
416  }
417  prev = item;
418  item = item->next;
419  }
420 
421  /* Unlink the device item from the device list. */
422  if (prev) {
423  prev->next = device->next;
424  } else if (device == deviceList) {
425  deviceList = device->next;
426  }
427 
428  if (device->joystick) {
429  device->joystick->hwdata = NULL;
430  }
431 
432 #ifdef SDL_JOYSTICK_MFI
433  @autoreleasepool {
434  if (device->controller) {
435  /* The controller was explicitly retained in the struct, so it
436  * should be explicitly released before freeing the struct. */
437  GCController *controller = CFBridgingRelease((__bridge CFTypeRef)(device->controller));
438  controller.controllerPausedHandler = nil;
439  device->controller = nil;
440  }
441  }
442 #endif /* SDL_JOYSTICK_MFI */
443 
444  --numjoysticks;
445 
446  SDL_PrivateJoystickRemoved(device->instance_id);
447 
448  SDL_free(device->name);
449  SDL_free(device);
450 
451  return next;
452 }
#define SDL_free
void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
struct joystick_hwdata * next

References device, deviceList, recDevice::next, NULL, numjoysticks, SDL_free, and SDL_PrivateJoystickRemoved().

Referenced by IOS_JoystickQuit().

Variable Documentation

◆ deviceList

SDL_JoystickDeviceItem* deviceList = NULL
static

◆ numjoysticks

int numjoysticks = 0
static

◆ SDL_AppleTVRemoteOpenedAsJoystick

int SDL_AppleTVRemoteOpenedAsJoystick = 0

Definition at line 109 of file SDL_mfijoystick.m.

Referenced by IOS_JoystickClose(), and IOS_JoystickOpen().

◆ SDL_IOS_JoystickDriver

SDL_JoystickDriver SDL_IOS_JoystickDriver
Initial value:
=
{
}
static int IOS_JoystickGetDevicePlayerIndex(int device_index)
static void IOS_JoystickDetect(void)
static int IOS_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
static void IOS_JoystickClose(SDL_Joystick *joystick)
static SDL_JoystickGUID IOS_JoystickGetDeviceGUID(int device_index)
static void IOS_JoystickSetDevicePlayerIndex(int device_index, int player_index)
static void IOS_JoystickUpdate(SDL_Joystick *joystick)
static int IOS_JoystickOpen(SDL_Joystick *joystick, int device_index)
static int IOS_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
static int IOS_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
static int IOS_JoystickGetCount(void)
static int IOS_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
static const char * IOS_JoystickGetDeviceName(int device_index)
static void IOS_JoystickQuit(void)
static int IOS_JoystickInit(void)
static SDL_bool IOS_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
static SDL_bool IOS_JoystickHasLED(SDL_Joystick *joystick)
static SDL_JoystickID IOS_JoystickGetDeviceInstanceID(int device_index)

Definition at line 1393 of file SDL_mfijoystick.m.