SDL  2.0
SDL_sysjoystick.m
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../../SDL_internal.h"
22 
23 /* This is the iOS implementation of the SDL joystick API */
24 #include "SDL_sysjoystick_c.h"
25 
26 /* needed for SDL_IPHONE_MAX_GFORCE macro */
27 #include "SDL_config_iphoneos.h"
28 
29 #include "SDL_assert.h"
30 #include "SDL_events.h"
31 #include "SDL_joystick.h"
32 #include "SDL_hints.h"
33 #include "SDL_stdinc.h"
34 #include "../SDL_sysjoystick.h"
35 #include "../SDL_joystick_c.h"
36 
37 
38 #if !SDL_EVENTS_DISABLED
39 #include "../../events/SDL_events_c.h"
40 #endif
41 
42 #if !TARGET_OS_TV
43 #import <CoreMotion/CoreMotion.h>
44 #endif
45 
46 #ifdef SDL_JOYSTICK_MFI
47 #import <GameController/GameController.h>
48 
49 static id connectObserver = nil;
50 static id disconnectObserver = nil;
51 #endif /* SDL_JOYSTICK_MFI */
52 
53 #if !TARGET_OS_TV
54 static const char *accelerometerName = "iOS Accelerometer";
55 static CMMotionManager *motionManager = nil;
56 #endif /* !TARGET_OS_TV */
57 
59 
60 static int numjoysticks = 0;
62 
64 GetDeviceForIndex(int device_index)
65 {
67  int i = 0;
68 
69  while (i < device_index) {
70  if (device == NULL) {
71  return NULL;
72  }
73  device = device->next;
74  i++;
75  }
76 
77  return device;
78 }
79 
80 static void
82 {
83 #ifdef SDL_JOYSTICK_MFI
84  const Uint16 VENDOR_APPLE = 0x05AC;
85  Uint16 *guid16 = (Uint16 *)device->guid.data;
86  Uint16 vendor = 0;
87  Uint16 product = 0;
88  Uint16 version = 0;
89  Uint8 subtype = 0;
90 
91  const char *name = NULL;
92  /* Explicitly retain the controller because SDL_JoystickDeviceItem is a
93  * struct, and ARC doesn't work with structs. */
94  device->controller = (__bridge GCController *) CFBridgingRetain(controller);
95 
96  if (controller.vendorName) {
97  name = controller.vendorName.UTF8String;
98  }
99 
100  if (!name) {
101  name = "MFi Gamepad";
102  }
103 
104  device->name = SDL_strdup(name);
105 
106  if (controller.extendedGamepad) {
107  vendor = VENDOR_APPLE;
108  product = 1;
109  subtype = 1;
110  device->naxes = 6; /* 2 thumbsticks and 2 triggers */
111  device->nhats = 1; /* d-pad */
112  device->nbuttons = 7; /* ABXY, shoulder buttons, pause button */
113  } else if (controller.gamepad) {
114  vendor = VENDOR_APPLE;
115  product = 2;
116  subtype = 2;
117  device->naxes = 0; /* no traditional analog inputs */
118  device->nhats = 1; /* d-pad */
119  device->nbuttons = 7; /* ABXY, shoulder buttons, pause button */
120  }
121 #if TARGET_OS_TV
122  else if (controller.microGamepad) {
123  vendor = VENDOR_APPLE;
124  product = 3;
125  subtype = 3;
126  device->naxes = 2; /* treat the touch surface as two axes */
127  device->nhats = 0; /* apparently the touch surface-as-dpad is buggy */
128  device->nbuttons = 3; /* AX, pause button */
129 
130  controller.microGamepad.allowsRotation = SDL_GetHintBoolean(SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION, SDL_FALSE);
131  }
132 #endif /* TARGET_OS_TV */
133 
134  /* We only need 16 bits for each of these; space them out to fill 128. */
135  /* Byteswap so devices get same GUID on little/big endian platforms. */
137  *guid16++ = 0;
138  *guid16++ = SDL_SwapLE16(vendor);
139  *guid16++ = 0;
140  *guid16++ = SDL_SwapLE16(product);
141  *guid16++ = 0;
142  *guid16++ = SDL_SwapLE16(version);
143  *guid16++ = 0;
144 
145  /* Note that this is an MFI controller and what subtype it is */
146  device->guid.data[14] = 'm';
147  device->guid.data[15] = subtype;
148 
149  /* This will be set when the first button press of the controller is
150  * detected. */
151  controller.playerIndex = -1;
152 
153 #endif /* SDL_JOYSTICK_MFI */
154 }
155 
156 static void
157 IOS_AddJoystickDevice(GCController *controller, SDL_bool accelerometer)
158 {
160 
161 #if TARGET_OS_TV
163  /* Ignore devices that aren't actually controllers (e.g. remotes), they'll be handled as keyboard input */
164  if (controller && !controller.extendedGamepad && !controller.gamepad && controller.microGamepad) {
165  return;
166  }
167  }
168 #endif
169 
170  while (device != NULL) {
171  if (device->controller == controller) {
172  return;
173  }
174  device = device->next;
175  }
176 
178  if (device == NULL) {
179  return;
180  }
181 
182  device->accelerometer = accelerometer;
183  device->instance_id = SDL_GetNextJoystickInstanceID();
184 
185  if (accelerometer) {
186 #if TARGET_OS_TV
187  SDL_free(device);
188  return;
189 #else
191  device->naxes = 3; /* Device acceleration in the x, y, and z axes. */
192  device->nhats = 0;
193  device->nbuttons = 0;
194 
195  /* Use the accelerometer name as a GUID. */
196  SDL_memcpy(&device->guid.data, device->name, SDL_min(sizeof(SDL_JoystickGUID), SDL_strlen(device->name)));
197 #endif /* TARGET_OS_TV */
198  } else if (controller) {
199  IOS_AddMFIJoystickDevice(device, controller);
200  }
201 
202  if (deviceList == NULL) {
203  deviceList = device;
204  } else {
205  SDL_JoystickDeviceItem *lastdevice = deviceList;
206  while (lastdevice->next != NULL) {
207  lastdevice = lastdevice->next;
208  }
209  lastdevice->next = device;
210  }
211 
212  ++numjoysticks;
213 
214  SDL_PrivateJoystickAdded(device->instance_id);
215 }
216 
217 static SDL_JoystickDeviceItem *
219 {
223 
224  if (device == NULL) {
225  return NULL;
226  }
227 
228  next = device->next;
229 
230  while (item != NULL) {
231  if (item == device) {
232  break;
233  }
234  prev = item;
235  item = item->next;
236  }
237 
238  /* Unlink the device item from the device list. */
239  if (prev) {
240  prev->next = device->next;
241  } else if (device == deviceList) {
242  deviceList = device->next;
243  }
244 
245  if (device->joystick) {
246  device->joystick->hwdata = NULL;
247  }
248 
249 #ifdef SDL_JOYSTICK_MFI
250  @autoreleasepool {
251  if (device->controller) {
252  /* The controller was explicitly retained in the struct, so it
253  * should be explicitly released before freeing the struct. */
254  GCController *controller = CFBridgingRelease((__bridge CFTypeRef)(device->controller));
255  controller.controllerPausedHandler = nil;
256  device->controller = nil;
257  }
258  }
259 #endif /* SDL_JOYSTICK_MFI */
260 
261  --numjoysticks;
262 
263  SDL_PrivateJoystickRemoved(device->instance_id);
264 
265  SDL_free(device->name);
266  SDL_free(device);
267 
268  return next;
269 }
270 
271 #if TARGET_OS_TV
272 static void SDLCALL
273 SDL_AppleTVRemoteRotationHintChanged(void *udata, const char *name, const char *oldValue, const char *newValue)
274 {
275  BOOL allowRotation = newValue != NULL && *newValue != '0';
276 
277  @autoreleasepool {
278  for (GCController *controller in [GCController controllers]) {
279  if (controller.microGamepad) {
280  controller.microGamepad.allowsRotation = allowRotation;
281  }
282  }
283  }
284 }
285 #endif /* TARGET_OS_TV */
286 
287 static int
289 {
290  @autoreleasepool {
291  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
292 
293 #if !TARGET_OS_TV
295  /* Default behavior, accelerometer as joystick */
297  }
298 #endif /* !TARGET_OS_TV */
299 
300 #ifdef SDL_JOYSTICK_MFI
301  /* GameController.framework was added in iOS 7. */
302  if (![GCController class]) {
303  return 0;
304  }
305 
306  for (GCController *controller in [GCController controllers]) {
307  IOS_AddJoystickDevice(controller, SDL_FALSE);
308  }
309 
310 #if TARGET_OS_TV
312  SDL_AppleTVRemoteRotationHintChanged, NULL);
313 #endif /* TARGET_OS_TV */
314 
315  connectObserver = [center addObserverForName:GCControllerDidConnectNotification
316  object:nil
317  queue:nil
318  usingBlock:^(NSNotification *note) {
319  GCController *controller = note.object;
320  IOS_AddJoystickDevice(controller, SDL_FALSE);
321  }];
322 
323  disconnectObserver = [center addObserverForName:GCControllerDidDisconnectNotification
324  object:nil
325  queue:nil
326  usingBlock:^(NSNotification *note) {
327  GCController *controller = note.object;
328  SDL_JoystickDeviceItem *device = deviceList;
329  while (device != NULL) {
330  if (device->controller == controller) {
331  IOS_RemoveJoystickDevice(device);
332  break;
333  }
334  device = device->next;
335  }
336  }];
337 #endif /* SDL_JOYSTICK_MFI */
338  }
339 
340  return 0;
341 }
342 
343 static int
345 {
346  return numjoysticks;
347 }
348 
349 static void
351 {
352 }
353 
354 static const char *
355 IOS_JoystickGetDeviceName(int device_index)
356 {
358  return device ? device->name : "Unknown";
359 }
360 
361 static int
363 {
364  return -1;
365 }
366 
367 static SDL_JoystickGUID
368 IOS_JoystickGetDeviceGUID( int device_index )
369 {
371  SDL_JoystickGUID guid;
372  if (device) {
373  guid = device->guid;
374  } else {
375  SDL_zero(guid);
376  }
377  return guid;
378 }
379 
380 static SDL_JoystickID
382 {
384  return device ? device->instance_id : -1;
385 }
386 
387 static int
388 IOS_JoystickOpen(SDL_Joystick * joystick, int device_index)
389 {
391  if (device == NULL) {
392  return SDL_SetError("Could not open Joystick: no hardware device for the specified index");
393  }
394 
395  joystick->hwdata = device;
396  joystick->instance_id = device->instance_id;
397 
398  joystick->naxes = device->naxes;
399  joystick->nhats = device->nhats;
400  joystick->nbuttons = device->nbuttons;
401  joystick->nballs = 0;
402 
403  device->joystick = joystick;
404 
405  @autoreleasepool {
406  if (device->accelerometer) {
407 #if !TARGET_OS_TV
408  if (motionManager == nil) {
409  motionManager = [[CMMotionManager alloc] init];
410  }
411 
412  /* Shorter times between updates can significantly increase CPU usage. */
413  motionManager.accelerometerUpdateInterval = 0.1;
414  [motionManager startAccelerometerUpdates];
415 #endif /* !TARGET_OS_TV */
416  } else {
417 #ifdef SDL_JOYSTICK_MFI
418  GCController *controller = device->controller;
419  controller.controllerPausedHandler = ^(GCController *c) {
420  if (joystick->hwdata) {
421  ++joystick->hwdata->num_pause_presses;
422  }
423  };
424 #endif /* SDL_JOYSTICK_MFI */
425  }
426  }
427  if (device->remote) {
429  }
430 
431  return 0;
432 }
433 
434 static void
435 IOS_AccelerometerUpdate(SDL_Joystick * joystick)
436 {
437 #if !TARGET_OS_TV
438  const float maxgforce = SDL_IPHONE_MAX_GFORCE;
439  const SInt16 maxsint16 = 0x7FFF;
440  CMAcceleration accel;
441 
442  @autoreleasepool {
443  if (!motionManager.isAccelerometerActive) {
444  return;
445  }
446 
447  accel = motionManager.accelerometerData.acceleration;
448  }
449 
450  /*
451  Convert accelerometer data from floating point to Sint16, which is what
452  the joystick system expects.
453 
454  To do the conversion, the data is first clamped onto the interval
455  [-SDL_IPHONE_MAX_G_FORCE, SDL_IPHONE_MAX_G_FORCE], then the data is multiplied
456  by MAX_SINT16 so that it is mapped to the full range of an Sint16.
457 
458  You can customize the clamped range of this function by modifying the
459  SDL_IPHONE_MAX_GFORCE macro in SDL_config_iphoneos.h.
460 
461  Once converted to Sint16, the accelerometer data no longer has coherent
462  units. You can convert the data back to units of g-force by multiplying
463  it in your application's code by SDL_IPHONE_MAX_GFORCE / 0x7FFF.
464  */
465 
466  /* clamp the data */
467  accel.x = SDL_min(SDL_max(accel.x, -maxgforce), maxgforce);
468  accel.y = SDL_min(SDL_max(accel.y, -maxgforce), maxgforce);
469  accel.z = SDL_min(SDL_max(accel.z, -maxgforce), maxgforce);
470 
471  /* pass in data mapped to range of SInt16 */
472  SDL_PrivateJoystickAxis(joystick, 0, (accel.x / maxgforce) * maxsint16);
473  SDL_PrivateJoystickAxis(joystick, 1, -(accel.y / maxgforce) * maxsint16);
474  SDL_PrivateJoystickAxis(joystick, 2, (accel.z / maxgforce) * maxsint16);
475 #endif /* !TARGET_OS_TV */
476 }
477 
478 #ifdef SDL_JOYSTICK_MFI
479 static Uint8
480 IOS_MFIJoystickHatStateForDPad(GCControllerDirectionPad *dpad)
481 {
482  Uint8 hat = 0;
483 
484  if (dpad.up.isPressed) {
485  hat |= SDL_HAT_UP;
486  } else if (dpad.down.isPressed) {
487  hat |= SDL_HAT_DOWN;
488  }
489 
490  if (dpad.left.isPressed) {
491  hat |= SDL_HAT_LEFT;
492  } else if (dpad.right.isPressed) {
493  hat |= SDL_HAT_RIGHT;
494  }
495 
496  if (hat == 0) {
497  return SDL_HAT_CENTERED;
498  }
499 
500  return hat;
501 }
502 #endif
503 
504 static void
505 IOS_MFIJoystickUpdate(SDL_Joystick * joystick)
506 {
507 #if SDL_JOYSTICK_MFI
508  @autoreleasepool {
509  GCController *controller = joystick->hwdata->controller;
510  Uint8 hatstate = SDL_HAT_CENTERED;
511  int i;
512  int updateplayerindex = 0;
513 
514  if (controller.extendedGamepad) {
515  GCExtendedGamepad *gamepad = controller.extendedGamepad;
516 
517  /* Axis order matches the XInput Windows mappings. */
518  Sint16 axes[] = {
519  (Sint16) (gamepad.leftThumbstick.xAxis.value * 32767),
520  (Sint16) (gamepad.leftThumbstick.yAxis.value * -32767),
521  (Sint16) ((gamepad.leftTrigger.value * 65535) - 32768),
522  (Sint16) (gamepad.rightThumbstick.xAxis.value * 32767),
523  (Sint16) (gamepad.rightThumbstick.yAxis.value * -32767),
524  (Sint16) ((gamepad.rightTrigger.value * 65535) - 32768),
525  };
526 
527  /* Button order matches the XInput Windows mappings. */
528  Uint8 buttons[] = {
529  gamepad.buttonA.isPressed, gamepad.buttonB.isPressed,
530  gamepad.buttonX.isPressed, gamepad.buttonY.isPressed,
531  gamepad.leftShoulder.isPressed,
532  gamepad.rightShoulder.isPressed,
533  };
534 
535  hatstate = IOS_MFIJoystickHatStateForDPad(gamepad.dpad);
536 
537  for (i = 0; i < SDL_arraysize(axes); i++) {
538  /* The triggers (axes 2 and 5) are resting at -32768 but SDL
539  * initializes its values to 0. We only want to make sure the
540  * player index is up to date if the user actually moves an axis. */
541  if ((i != 2 && i != 5) || axes[i] != -32768) {
542  updateplayerindex |= (joystick->axes[i].value != axes[i]);
543  }
544  SDL_PrivateJoystickAxis(joystick, i, axes[i]);
545  }
546 
547  for (i = 0; i < SDL_arraysize(buttons); i++) {
548  updateplayerindex |= (joystick->buttons[i] != buttons[i]);
549  SDL_PrivateJoystickButton(joystick, i, buttons[i]);
550  }
551  } else if (controller.gamepad) {
552  GCGamepad *gamepad = controller.gamepad;
553 
554  /* Button order matches the XInput Windows mappings. */
555  Uint8 buttons[] = {
556  gamepad.buttonA.isPressed, gamepad.buttonB.isPressed,
557  gamepad.buttonX.isPressed, gamepad.buttonY.isPressed,
558  gamepad.leftShoulder.isPressed,
559  gamepad.rightShoulder.isPressed,
560  };
561 
562  hatstate = IOS_MFIJoystickHatStateForDPad(gamepad.dpad);
563 
564  for (i = 0; i < SDL_arraysize(buttons); i++) {
565  updateplayerindex |= (joystick->buttons[i] != buttons[i]);
566  SDL_PrivateJoystickButton(joystick, i, buttons[i]);
567  }
568  }
569 #if TARGET_OS_TV
570  else if (controller.microGamepad) {
571  GCMicroGamepad *gamepad = controller.microGamepad;
572 
573  Sint16 axes[] = {
574  (Sint16) (gamepad.dpad.xAxis.value * 32767),
575  (Sint16) (gamepad.dpad.yAxis.value * -32767),
576  };
577 
578  for (i = 0; i < SDL_arraysize(axes); i++) {
579  updateplayerindex |= (joystick->axes[i].value != axes[i]);
580  SDL_PrivateJoystickAxis(joystick, i, axes[i]);
581  }
582 
583  Uint8 buttons[] = {
584  gamepad.buttonA.isPressed,
585  gamepad.buttonX.isPressed,
586  };
587 
588  for (i = 0; i < SDL_arraysize(buttons); i++) {
589  updateplayerindex |= (joystick->buttons[i] != buttons[i]);
590  SDL_PrivateJoystickButton(joystick, i, buttons[i]);
591  }
592  }
593 #endif /* TARGET_OS_TV */
594 
595  if (joystick->nhats > 0) {
596  updateplayerindex |= (joystick->hats[0] != hatstate);
597  SDL_PrivateJoystickHat(joystick, 0, hatstate);
598  }
599 
600  for (i = 0; i < joystick->hwdata->num_pause_presses; i++) {
601  const Uint8 pausebutton = joystick->nbuttons - 1; /* The pause button is always last. */
602  SDL_PrivateJoystickButton(joystick, pausebutton, SDL_PRESSED);
603  SDL_PrivateJoystickButton(joystick, pausebutton, SDL_RELEASED);
604  updateplayerindex = YES;
605  }
606  joystick->hwdata->num_pause_presses = 0;
607 
608  if (updateplayerindex && controller.playerIndex == -1) {
609  BOOL usedPlayerIndexSlots[4] = {NO, NO, NO, NO};
610 
611  /* Find the player index of all other connected controllers. */
612  for (GCController *c in [GCController controllers]) {
613  if (c != controller && c.playerIndex >= 0) {
614  usedPlayerIndexSlots[c.playerIndex] = YES;
615  }
616  }
617 
618  /* Set this controller's player index to the first unused index.
619  * FIXME: This logic isn't great... but SDL doesn't expose this
620  * concept in its external API, so we don't have much to go on. */
621  for (i = 0; i < SDL_arraysize(usedPlayerIndexSlots); i++) {
622  if (!usedPlayerIndexSlots[i]) {
623  controller.playerIndex = i;
624  break;
625  }
626  }
627  }
628  }
629 #endif /* SDL_JOYSTICK_MFI */
630 }
631 
632 static int
633 IOS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
634 {
635  return SDL_Unsupported();
636 }
637 
638 static void
639 IOS_JoystickUpdate(SDL_Joystick * joystick)
640 {
641  SDL_JoystickDeviceItem *device = joystick->hwdata;
642 
643  if (device == NULL) {
644  return;
645  }
646 
647  if (device->accelerometer) {
648  IOS_AccelerometerUpdate(joystick);
649  } else if (device->controller) {
650  IOS_MFIJoystickUpdate(joystick);
651  }
652 }
653 
654 static void
655 IOS_JoystickClose(SDL_Joystick * joystick)
656 {
657  SDL_JoystickDeviceItem *device = joystick->hwdata;
658 
659  if (device == NULL) {
660  return;
661  }
662 
663  device->joystick = NULL;
664 
665  @autoreleasepool {
666  if (device->accelerometer) {
667 #if !TARGET_OS_TV
668  [motionManager stopAccelerometerUpdates];
669 #endif /* !TARGET_OS_TV */
670  } else if (device->controller) {
671 #ifdef SDL_JOYSTICK_MFI
672  GCController *controller = device->controller;
673  controller.controllerPausedHandler = nil;
674  controller.playerIndex = -1;
675 #endif
676  }
677  }
678  if (device->remote) {
680  }
681 }
682 
683 static void
685 {
686  @autoreleasepool {
687 #ifdef SDL_JOYSTICK_MFI
688  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
689 
690  if (connectObserver) {
691  [center removeObserver:connectObserver name:GCControllerDidConnectNotification object:nil];
692  connectObserver = nil;
693  }
694 
695  if (disconnectObserver) {
696  [center removeObserver:disconnectObserver name:GCControllerDidDisconnectNotification object:nil];
697  disconnectObserver = nil;
698  }
699 
700 #if TARGET_OS_TV
702  SDL_AppleTVRemoteRotationHintChanged, NULL);
703 #endif /* TARGET_OS_TV */
704 #endif /* SDL_JOYSTICK_MFI */
705 
706  while (deviceList != NULL) {
708  }
709 
710 #if !TARGET_OS_TV
711  motionManager = nil;
712 #endif /* !TARGET_OS_TV */
713  }
714 
715  numjoysticks = 0;
716 }
717 
719 {
732 };
733 
734 /* vi: set ts=4 sw=4 expandtab: */
SDL_zero
#define SDL_zero(x)
Definition: SDL_stdinc.h:416
IOS_JoystickGetDeviceInstanceID
static SDL_JoystickID IOS_JoystickGetDeviceInstanceID(int device_index)
Definition: SDL_sysjoystick.m:381
Uint8
uint8_t Uint8
Definition: SDL_stdinc.h:179
c
const GLubyte * c
Definition: SDL_opengl_glext.h:11093
SDL_events.h
IOS_AddMFIJoystickDevice
static void IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controller)
Definition: SDL_sysjoystick.m:81
Uint16
uint16_t Uint16
Definition: SDL_stdinc.h:191
SDL_HINT_TV_REMOTE_AS_JOYSTICK
#define SDL_HINT_TV_REMOTE_AS_JOYSTICK
A variable controlling whether the Android / tvOS remotes should be listed as joystick devices,...
Definition: SDL_hints.h:409
IOS_JoystickRumble
static int IOS_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
Definition: SDL_sysjoystick.m:633
in
GLuint in
Definition: SDL_opengl_glext.h:7940
numjoysticks
static int numjoysticks
Definition: SDL_sysjoystick.m:60
SDL_HAT_CENTERED
#define SDL_HAT_CENTERED
Definition: SDL_joystick.h:329
NULL
#define NULL
Definition: begin_code.h:164
SDL_HAT_DOWN
#define SDL_HAT_DOWN
Definition: SDL_joystick.h:332
SDL_joystick.h
SDL_JoystickID
Sint32 SDL_JoystickID
Definition: SDL_joystick.h:81
GetDeviceForIndex
static SDL_JoystickDeviceItem * GetDeviceForIndex(int device_index)
Definition: SDL_sysjoystick.m:64
IOS_JoystickGetDeviceGUID
static SDL_JoystickGUID IOS_JoystickGetDeviceGUID(int device_index)
Definition: SDL_sysjoystick.m:368
IOS_MFIJoystickUpdate
static void IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
Definition: SDL_sysjoystick.m:505
IOS_AccelerometerUpdate
static void IOS_AccelerometerUpdate(SDL_Joystick *joystick)
Definition: SDL_sysjoystick.m:435
SDLCALL
#define SDLCALL
Definition: SDL_internal.h:45
SDL_PrivateJoystickAdded
void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance)
Definition: SDL_joystick.c:751
IOS_JoystickDetect
static void IOS_JoystickDetect(void)
Definition: SDL_sysjoystick.m:350
deviceList
static SDL_JoystickDeviceItem * deviceList
Definition: SDL_sysjoystick.m:58
SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION
#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:378
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:203
SDL_GetNextJoystickInstanceID
SDL_JoystickID SDL_GetNextJoystickInstanceID()
Definition: SDL_joystick.c:163
IOS_JoystickClose
static void IOS_JoystickClose(SDL_Joystick *joystick)
Definition: SDL_sysjoystick.m:655
SDL_RELEASED
#define SDL_RELEASED
Definition: SDL_events.h:49
SDL_SwapLE16
#define SDL_SwapLE16(X)
Definition: SDL_endian.h:232
IOS_JoystickOpen
static int IOS_JoystickOpen(SDL_Joystick *joystick, int device_index)
Definition: SDL_sysjoystick.m:388
SDL_PrivateJoystickRemoved
void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
Definition: SDL_joystick.c:800
SDL_PrivateJoystickAxis
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
Definition: SDL_joystick.c:828
SDL_PRESSED
#define SDL_PRESSED
Definition: SDL_events.h:50
Sint16
int16_t Sint16
Definition: SDL_stdinc.h:185
joystick_hwdata::next
struct joystick_hwdata * next
Definition: SDL_sysjoystick_c.h:49
SDL_HINT_ACCELEROMETER_AS_JOYSTICK
#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:399
SDL_memcpy
#define SDL_memcpy
Definition: SDL_dynapi_overrides.h:387
SDL_GetHintBoolean
#define SDL_GetHintBoolean
Definition: SDL_dynapi_overrides.h:608
SDL_config_iphoneos.h
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
IOS_JoystickGetDeviceName
static const char * IOS_JoystickGetDeviceName(int device_index)
Definition: SDL_sysjoystick.m:355
SDL_max
#define SDL_max(x, y)
Definition: SDL_stdinc.h:407
IOS_JoystickQuit
static void IOS_JoystickQuit(void)
Definition: SDL_sysjoystick.m:684
name
GLuint const GLchar * name
Definition: SDL_opengl_glext.h:660
SDL_IPHONE_MAX_GFORCE
#define SDL_IPHONE_MAX_GFORCE
Definition: SDL_config_iphoneos.h:196
SDL_PrivateJoystickButton
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
Definition: SDL_joystick.c:961
SDL_HAT_LEFT
#define SDL_HAT_LEFT
Definition: SDL_joystick.h:333
SDL_assert.h
SDL_min
#define SDL_min(x, y)
Definition: SDL_stdinc.h:406
SDL_AppleTVRemoteOpenedAsJoystick
int SDL_AppleTVRemoteOpenedAsJoystick
Definition: SDL_sysjoystick.m:61
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
IOS_JoystickInit
static int IOS_JoystickInit(void)
Definition: SDL_sysjoystick.m:288
SDL_JoystickDriver
Definition: SDL_sysjoystick.h:93
SDL_PrivateJoystickHat
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
Definition: SDL_joystick.c:885
SDL_sysjoystick_c.h
SDL_arraysize
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115
SDL_calloc
#define SDL_calloc
Definition: SDL_dynapi_overrides.h:375
sort_controllers.controllers
list controllers
Definition: sort_controllers.py:12
motionManager
static CMMotionManager * motionManager
Definition: SDL_sysjoystick.m:55
IOS_JoystickGetCount
static int IOS_JoystickGetCount(void)
Definition: SDL_sysjoystick.m:344
SDL_AddHintCallback
#define SDL_AddHintCallback
Definition: SDL_dynapi_overrides.h:192
SDL_HAT_RIGHT
#define SDL_HAT_RIGHT
Definition: SDL_joystick.h:331
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
IOS_JoystickGetDevicePlayerIndex
static int IOS_JoystickGetDevicePlayerIndex(int device_index)
Definition: SDL_sysjoystick.m:362
SDL_stdinc.h
SDL_hints.h
IOS_JoystickUpdate
static void IOS_JoystickUpdate(SDL_Joystick *joystick)
Definition: SDL_sysjoystick.m:639
SDL_strdup
#define SDL_strdup
Definition: SDL_dynapi_overrides.h:397
SDL_strlen
#define SDL_strlen
Definition: SDL_dynapi_overrides.h:393
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:162
SDL_HAT_UP
#define SDL_HAT_UP
Definition: SDL_joystick.h:330
SDL_HARDWARE_BUS_BLUETOOTH
#define SDL_HARDWARE_BUS_BLUETOOTH
Definition: SDL_sysjoystick.h:87
IOS_RemoveJoystickDevice
static SDL_JoystickDeviceItem * IOS_RemoveJoystickDevice(SDL_JoystickDeviceItem *device)
Definition: SDL_sysjoystick.m:218
SDL_IOS_JoystickDriver
SDL_JoystickDriver SDL_IOS_JoystickDriver
Definition: SDL_sysjoystick.m:718
SDL_DelHintCallback
#define SDL_DelHintCallback
Definition: SDL_dynapi_overrides.h:193
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
SDL_Unsupported
#define SDL_Unsupported()
Definition: SDL_error.h:53
device
static SDL_AudioDeviceID device
Definition: loopwave.c:37
SDL_JoystickGUID
Definition: SDL_joystick.h:70
i
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
accelerometerName
static const char * accelerometerName
Definition: SDL_sysjoystick.m:54
IOS_AddJoystickDevice
static void IOS_AddJoystickDevice(GCController *controller, SDL_bool accelerometer)
Definition: SDL_sysjoystick.m:157
joystick_hwdata
Definition: SDL_sysjoystick_c.h:47