Skip to content

Latest commit

 

History

History
734 lines (612 loc) · 22.3 KB

SDL_sysjoystick.m

File metadata and controls

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