summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/joystick/android
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/SDL-3.2.8/src/joystick/android')
-rw-r--r--contrib/SDL-3.2.8/src/joystick/android/SDL_sysjoystick.c681
-rw-r--r--contrib/SDL-3.2.8/src/joystick/android/SDL_sysjoystick_c.h57
2 files changed, 738 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/joystick/android/SDL_sysjoystick.c b/contrib/SDL-3.2.8/src/joystick/android/SDL_sysjoystick.c
new file mode 100644
index 0000000..9a3402e
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/joystick/android/SDL_sysjoystick.c
@@ -0,0 +1,681 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 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#ifdef SDL_JOYSTICK_ANDROID
24
25#include <stdio.h> // For the definition of NULL
26
27#include "SDL_sysjoystick_c.h"
28#include "../SDL_joystick_c.h"
29#include "../../events/SDL_keyboard_c.h"
30#include "../../core/android/SDL_android.h"
31#include "../hidapi/SDL_hidapijoystick_c.h"
32
33#include "android/keycodes.h"
34
35// As of platform android-14, android/keycodes.h is missing these defines
36#ifndef AKEYCODE_BUTTON_1
37#define AKEYCODE_BUTTON_1 188
38#define AKEYCODE_BUTTON_2 189
39#define AKEYCODE_BUTTON_3 190
40#define AKEYCODE_BUTTON_4 191
41#define AKEYCODE_BUTTON_5 192
42#define AKEYCODE_BUTTON_6 193
43#define AKEYCODE_BUTTON_7 194
44#define AKEYCODE_BUTTON_8 195
45#define AKEYCODE_BUTTON_9 196
46#define AKEYCODE_BUTTON_10 197
47#define AKEYCODE_BUTTON_11 198
48#define AKEYCODE_BUTTON_12 199
49#define AKEYCODE_BUTTON_13 200
50#define AKEYCODE_BUTTON_14 201
51#define AKEYCODE_BUTTON_15 202
52#define AKEYCODE_BUTTON_16 203
53#endif
54
55#define ANDROID_MAX_NBUTTONS 36
56
57static SDL_joylist_item *JoystickByDeviceId(int device_id);
58
59static SDL_joylist_item *SDL_joylist = NULL;
60static SDL_joylist_item *SDL_joylist_tail = NULL;
61static int numjoysticks = 0;
62
63/* Function to convert Android keyCodes into SDL ones.
64 * This code manipulation is done to get a sequential list of codes.
65 * FIXME: This is only suited for the case where we use a fixed number of buttons determined by ANDROID_MAX_NBUTTONS
66 */
67static int keycode_to_SDL(int keycode)
68{
69 // FIXME: If this function gets too unwieldy in the future, replace with a lookup table
70 int button = 0;
71 switch (keycode) {
72 // Some gamepad buttons (API 9)
73 case AKEYCODE_BUTTON_A:
74 button = SDL_GAMEPAD_BUTTON_SOUTH;
75 break;
76 case AKEYCODE_BUTTON_B:
77 button = SDL_GAMEPAD_BUTTON_EAST;
78 break;
79 case AKEYCODE_BUTTON_X:
80 button = SDL_GAMEPAD_BUTTON_WEST;
81 break;
82 case AKEYCODE_BUTTON_Y:
83 button = SDL_GAMEPAD_BUTTON_NORTH;
84 break;
85 case AKEYCODE_BUTTON_L1:
86 button = SDL_GAMEPAD_BUTTON_LEFT_SHOULDER;
87 break;
88 case AKEYCODE_BUTTON_R1:
89 button = SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER;
90 break;
91 case AKEYCODE_BUTTON_THUMBL:
92 button = SDL_GAMEPAD_BUTTON_LEFT_STICK;
93 break;
94 case AKEYCODE_BUTTON_THUMBR:
95 button = SDL_GAMEPAD_BUTTON_RIGHT_STICK;
96 break;
97 case AKEYCODE_MENU:
98 case AKEYCODE_BUTTON_START:
99 button = SDL_GAMEPAD_BUTTON_START;
100 break;
101 case AKEYCODE_BACK:
102 case AKEYCODE_BUTTON_SELECT:
103 button = SDL_GAMEPAD_BUTTON_BACK;
104 break;
105 case AKEYCODE_BUTTON_MODE:
106 button = SDL_GAMEPAD_BUTTON_GUIDE;
107 break;
108 case AKEYCODE_BUTTON_L2:
109 button = 15;
110 break;
111 case AKEYCODE_BUTTON_R2:
112 button = 16;
113 break;
114 case AKEYCODE_BUTTON_C:
115 button = 17;
116 break;
117 case AKEYCODE_BUTTON_Z:
118 button = 18;
119 break;
120
121 // D-Pad key codes (API 1)
122 case AKEYCODE_DPAD_UP:
123 button = SDL_GAMEPAD_BUTTON_DPAD_UP;
124 break;
125 case AKEYCODE_DPAD_DOWN:
126 button = SDL_GAMEPAD_BUTTON_DPAD_DOWN;
127 break;
128 case AKEYCODE_DPAD_LEFT:
129 button = SDL_GAMEPAD_BUTTON_DPAD_LEFT;
130 break;
131 case AKEYCODE_DPAD_RIGHT:
132 button = SDL_GAMEPAD_BUTTON_DPAD_RIGHT;
133 break;
134 case AKEYCODE_DPAD_CENTER:
135 // This is handled better by applications as the A button
136 // button = 19;
137 button = SDL_GAMEPAD_BUTTON_SOUTH;
138 break;
139
140 // More gamepad buttons (API 12), these get mapped to 20...35
141 case AKEYCODE_BUTTON_1:
142 case AKEYCODE_BUTTON_2:
143 case AKEYCODE_BUTTON_3:
144 case AKEYCODE_BUTTON_4:
145 case AKEYCODE_BUTTON_5:
146 case AKEYCODE_BUTTON_6:
147 case AKEYCODE_BUTTON_7:
148 case AKEYCODE_BUTTON_8:
149 case AKEYCODE_BUTTON_9:
150 case AKEYCODE_BUTTON_10:
151 case AKEYCODE_BUTTON_11:
152 case AKEYCODE_BUTTON_12:
153 case AKEYCODE_BUTTON_13:
154 case AKEYCODE_BUTTON_14:
155 case AKEYCODE_BUTTON_15:
156 case AKEYCODE_BUTTON_16:
157 button = 20 + (keycode - AKEYCODE_BUTTON_1);
158 break;
159
160 default:
161 return -1;
162 // break; -Wunreachable-code-break
163 }
164
165 /* This is here in case future generations, probably with six fingers per hand,
166 * happily add new cases up above and forget to update the max number of buttons.
167 */
168 SDL_assert(button < ANDROID_MAX_NBUTTONS);
169 return button;
170}
171
172static SDL_Scancode button_to_scancode(int button)
173{
174 switch (button) {
175 case SDL_GAMEPAD_BUTTON_SOUTH:
176 return SDL_SCANCODE_RETURN;
177 case SDL_GAMEPAD_BUTTON_EAST:
178 return SDL_SCANCODE_ESCAPE;
179 case SDL_GAMEPAD_BUTTON_BACK:
180 return SDL_SCANCODE_ESCAPE;
181 case SDL_GAMEPAD_BUTTON_START:
182 return SDL_SCANCODE_MENU;
183 case SDL_GAMEPAD_BUTTON_DPAD_UP:
184 return SDL_SCANCODE_UP;
185 case SDL_GAMEPAD_BUTTON_DPAD_DOWN:
186 return SDL_SCANCODE_DOWN;
187 case SDL_GAMEPAD_BUTTON_DPAD_LEFT:
188 return SDL_SCANCODE_LEFT;
189 case SDL_GAMEPAD_BUTTON_DPAD_RIGHT:
190 return SDL_SCANCODE_RIGHT;
191 }
192
193 // Unsupported button
194 return SDL_SCANCODE_UNKNOWN;
195}
196
197bool Android_OnPadDown(int device_id, int keycode)
198{
199 Uint64 timestamp = SDL_GetTicksNS();
200 SDL_joylist_item *item;
201 int button = keycode_to_SDL(keycode);
202 if (button >= 0) {
203 SDL_LockJoysticks();
204 item = JoystickByDeviceId(device_id);
205 if (item && item->joystick) {
206 SDL_SendJoystickButton(timestamp, item->joystick, button, true);
207 } else {
208 SDL_SendKeyboardKey(timestamp, SDL_GLOBAL_KEYBOARD_ID, keycode, button_to_scancode(button), true);
209 }
210 SDL_UnlockJoysticks();
211 return true;
212 }
213
214 return false;
215}
216
217bool Android_OnPadUp(int device_id, int keycode)
218{
219 Uint64 timestamp = SDL_GetTicksNS();
220 SDL_joylist_item *item;
221 int button = keycode_to_SDL(keycode);
222 if (button >= 0) {
223 SDL_LockJoysticks();
224 item = JoystickByDeviceId(device_id);
225 if (item && item->joystick) {
226 SDL_SendJoystickButton(timestamp, item->joystick, button, false);
227 } else {
228 SDL_SendKeyboardKey(timestamp, SDL_GLOBAL_KEYBOARD_ID, keycode, button_to_scancode(button), false);
229 }
230 SDL_UnlockJoysticks();
231 return true;
232 }
233
234 return false;
235}
236
237bool Android_OnJoy(int device_id, int axis, float value)
238{
239 Uint64 timestamp = SDL_GetTicksNS();
240 // Android gives joy info normalized as [-1.0, 1.0] or [0.0, 1.0]
241 SDL_joylist_item *item;
242
243 SDL_LockJoysticks();
244 item = JoystickByDeviceId(device_id);
245 if (item && item->joystick) {
246 SDL_SendJoystickAxis(timestamp, item->joystick, axis, (Sint16)(32767. * value));
247 }
248 SDL_UnlockJoysticks();
249
250 return true;
251}
252
253bool Android_OnHat(int device_id, int hat_id, int x, int y)
254{
255 Uint64 timestamp = SDL_GetTicksNS();
256 const int DPAD_UP_MASK = (1 << SDL_GAMEPAD_BUTTON_DPAD_UP);
257 const int DPAD_DOWN_MASK = (1 << SDL_GAMEPAD_BUTTON_DPAD_DOWN);
258 const int DPAD_LEFT_MASK = (1 << SDL_GAMEPAD_BUTTON_DPAD_LEFT);
259 const int DPAD_RIGHT_MASK = (1 << SDL_GAMEPAD_BUTTON_DPAD_RIGHT);
260
261 if (x >= -1 && x <= 1 && y >= -1 && y <= 1) {
262 SDL_joylist_item *item;
263
264 SDL_LockJoysticks();
265 item = JoystickByDeviceId(device_id);
266 if (item && item->joystick) {
267 int dpad_state = 0;
268 int dpad_delta;
269 if (x < 0) {
270 dpad_state |= DPAD_LEFT_MASK;
271 } else if (x > 0) {
272 dpad_state |= DPAD_RIGHT_MASK;
273 }
274 if (y < 0) {
275 dpad_state |= DPAD_UP_MASK;
276 } else if (y > 0) {
277 dpad_state |= DPAD_DOWN_MASK;
278 }
279
280 dpad_delta = (dpad_state ^ item->dpad_state);
281 if (dpad_delta) {
282 if (dpad_delta & DPAD_UP_MASK) {
283 bool down = ((dpad_state & DPAD_UP_MASK) != 0);
284 SDL_SendJoystickButton(timestamp, item->joystick, SDL_GAMEPAD_BUTTON_DPAD_UP, down);
285 }
286 if (dpad_delta & DPAD_DOWN_MASK) {
287 bool down = ((dpad_state & DPAD_DOWN_MASK) != 0);
288 SDL_SendJoystickButton(timestamp, item->joystick, SDL_GAMEPAD_BUTTON_DPAD_DOWN, down);
289 }
290 if (dpad_delta & DPAD_LEFT_MASK) {
291 bool down = ((dpad_state & DPAD_LEFT_MASK) != 0);
292 SDL_SendJoystickButton(timestamp, item->joystick, SDL_GAMEPAD_BUTTON_DPAD_LEFT, down);
293 }
294 if (dpad_delta & DPAD_RIGHT_MASK) {
295 bool down = ((dpad_state & DPAD_RIGHT_MASK) != 0);
296 SDL_SendJoystickButton(timestamp, item->joystick, SDL_GAMEPAD_BUTTON_DPAD_RIGHT, down);
297 }
298 item->dpad_state = dpad_state;
299 }
300 }
301 SDL_UnlockJoysticks();
302 return true;
303 }
304
305 return false;
306}
307
308void Android_AddJoystick(int device_id, const char *name, const char *desc, int vendor_id, int product_id, int button_mask, int naxes, int axis_mask, int nhats, bool can_rumble)
309{
310 SDL_joylist_item *item;
311 SDL_GUID guid;
312 int i;
313
314 SDL_LockJoysticks();
315
316 if (!SDL_GetHintBoolean(SDL_HINT_TV_REMOTE_AS_JOYSTICK, true)) {
317 // Ignore devices that aren't actually controllers (e.g. remotes), they'll be handled as keyboard input
318 if (naxes < 2 && nhats < 1) {
319 goto done;
320 }
321 }
322
323 if (JoystickByDeviceId(device_id) != NULL || !name) {
324 goto done;
325 }
326
327 if (SDL_JoystickHandledByAnotherDriver(&SDL_ANDROID_JoystickDriver, vendor_id, product_id, 0, name)) {
328 goto done;
329 }
330
331#ifdef DEBUG_JOYSTICK
332 SDL_Log("Joystick: %s, descriptor %s, vendor = 0x%.4x, product = 0x%.4x, %d axes, %d hats", name, desc, vendor_id, product_id, naxes, nhats);
333#endif
334
335 if (nhats > 0) {
336 // Hat is translated into DPAD buttons
337 button_mask |= ((1 << SDL_GAMEPAD_BUTTON_DPAD_UP) |
338 (1 << SDL_GAMEPAD_BUTTON_DPAD_DOWN) |
339 (1 << SDL_GAMEPAD_BUTTON_DPAD_LEFT) |
340 (1 << SDL_GAMEPAD_BUTTON_DPAD_RIGHT));
341 nhats = 0;
342 }
343
344 guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_BLUETOOTH, vendor_id, product_id, 0, NULL, desc, 0, 0);
345
346 // Update the GUID with capability bits
347 {
348 Uint16 *guid16 = (Uint16 *)guid.data;
349 guid16[6] = SDL_Swap16LE(button_mask);
350 guid16[7] = SDL_Swap16LE(axis_mask);
351 }
352
353 item = (SDL_joylist_item *)SDL_malloc(sizeof(SDL_joylist_item));
354 if (!item) {
355 goto done;
356 }
357
358 SDL_zerop(item);
359 item->guid = guid;
360 item->device_id = device_id;
361 item->name = SDL_CreateJoystickName(vendor_id, product_id, NULL, name);
362 if (!item->name) {
363 SDL_free(item);
364 goto done;
365 }
366
367 if (button_mask == 0xFFFFFFFF) {
368 item->nbuttons = ANDROID_MAX_NBUTTONS;
369 } else {
370 for (i = 0; i < sizeof(button_mask) * 8; ++i) {
371 if (button_mask & (1 << i)) {
372 item->nbuttons = i + 1;
373 }
374 }
375 }
376 item->naxes = naxes;
377 item->nhats = nhats;
378 item->can_rumble = can_rumble;
379 item->device_instance = SDL_GetNextObjectID();
380 if (!SDL_joylist_tail) {
381 SDL_joylist = SDL_joylist_tail = item;
382 } else {
383 SDL_joylist_tail->next = item;
384 SDL_joylist_tail = item;
385 }
386
387 // Need to increment the joystick count before we post the event
388 ++numjoysticks;
389
390 SDL_PrivateJoystickAdded(item->device_instance);
391
392#ifdef DEBUG_JOYSTICK
393 SDL_Log("Added joystick %s with device_id %d", item->name, device_id);
394#endif
395
396done:
397 SDL_UnlockJoysticks();
398}
399
400void Android_RemoveJoystick(int device_id)
401{
402 SDL_joylist_item *item = SDL_joylist;
403 SDL_joylist_item *prev = NULL;
404
405 SDL_LockJoysticks();
406
407 // Don't call JoystickByDeviceId here or there'll be an infinite loop!
408 while (item) {
409 if (item->device_id == device_id) {
410 break;
411 }
412 prev = item;
413 item = item->next;
414 }
415
416 if (!item) {
417 goto done;
418 }
419
420 if (item->joystick) {
421 item->joystick->hwdata = NULL;
422 }
423
424 if (prev) {
425 prev->next = item->next;
426 } else {
427 SDL_assert(SDL_joylist == item);
428 SDL_joylist = item->next;
429 }
430 if (item == SDL_joylist_tail) {
431 SDL_joylist_tail = prev;
432 }
433
434 // Need to decrement the joystick count before we post the event
435 --numjoysticks;
436
437 SDL_PrivateJoystickRemoved(item->device_instance);
438
439#ifdef DEBUG_JOYSTICK
440 SDL_Log("Removed joystick with device_id %d", device_id);
441#endif
442
443 SDL_free(item->name);
444 SDL_free(item);
445
446done:
447 SDL_UnlockJoysticks();
448}
449
450static void ANDROID_JoystickDetect(void);
451
452static bool ANDROID_JoystickInit(void)
453{
454 ANDROID_JoystickDetect();
455 return true;
456}
457
458static int ANDROID_JoystickGetCount(void)
459{
460 return numjoysticks;
461}
462
463static void ANDROID_JoystickDetect(void)
464{
465 /* Support for device connect/disconnect is API >= 16 only,
466 * so we poll every three seconds
467 * Ref: http://developer.android.com/reference/android/hardware/input/InputManager.InputDeviceListener.html
468 */
469 static Uint64 timeout = 0;
470 Uint64 now = SDL_GetTicks();
471 if (!timeout || now >= timeout) {
472 timeout = now + 3000;
473 Android_JNI_PollInputDevices();
474 }
475}
476
477static bool ANDROID_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name)
478{
479 // We don't override any other drivers
480 return false;
481}
482
483static SDL_joylist_item *GetJoystickByDevIndex(int device_index)
484{
485 SDL_joylist_item *item = SDL_joylist;
486
487 if ((device_index < 0) || (device_index >= numjoysticks)) {
488 return NULL;
489 }
490
491 while (device_index > 0) {
492 SDL_assert(item != NULL);
493 device_index--;
494 item = item->next;
495 }
496
497 return item;
498}
499
500static SDL_joylist_item *JoystickByDeviceId(int device_id)
501{
502 SDL_joylist_item *item = SDL_joylist;
503
504 while (item) {
505 if (item->device_id == device_id) {
506 return item;
507 }
508 item = item->next;
509 }
510
511 // Joystick not found, try adding it
512 ANDROID_JoystickDetect();
513
514 while (item) {
515 if (item->device_id == device_id) {
516 return item;
517 }
518 item = item->next;
519 }
520
521 return NULL;
522}
523
524static const char *ANDROID_JoystickGetDeviceName(int device_index)
525{
526 return GetJoystickByDevIndex(device_index)->name;
527}
528
529static const char *ANDROID_JoystickGetDevicePath(int device_index)
530{
531 return NULL;
532}
533
534static int ANDROID_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index)
535{
536 return -1;
537}
538
539static int ANDROID_JoystickGetDevicePlayerIndex(int device_index)
540{
541 return -1;
542}
543
544static void ANDROID_JoystickSetDevicePlayerIndex(int device_index, int player_index)
545{
546}
547
548static SDL_GUID ANDROID_JoystickGetDeviceGUID(int device_index)
549{
550 return GetJoystickByDevIndex(device_index)->guid;
551}
552
553static SDL_JoystickID ANDROID_JoystickGetDeviceInstanceID(int device_index)
554{
555 return GetJoystickByDevIndex(device_index)->device_instance;
556}
557
558static bool ANDROID_JoystickOpen(SDL_Joystick *joystick, int device_index)
559{
560 SDL_joylist_item *item = GetJoystickByDevIndex(device_index);
561
562 if (!item) {
563 return SDL_SetError("No such device");
564 }
565
566 if (item->joystick) {
567 return SDL_SetError("Joystick already opened");
568 }
569
570 joystick->hwdata = (struct joystick_hwdata *)item;
571 item->joystick = joystick;
572 joystick->nhats = item->nhats;
573 joystick->nbuttons = item->nbuttons;
574 joystick->naxes = item->naxes;
575
576 if (item->can_rumble) {
577 SDL_SetBooleanProperty(SDL_GetJoystickProperties(joystick), SDL_PROP_JOYSTICK_CAP_RUMBLE_BOOLEAN, true);
578 }
579
580 return true;
581}
582
583static bool ANDROID_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
584{
585 SDL_joylist_item *item = (SDL_joylist_item *)joystick->hwdata;
586 if (!item) {
587 return SDL_SetError("Rumble failed, device disconnected");
588 }
589 if (!item->can_rumble) {
590 return SDL_Unsupported();
591 }
592
593 float low_frequency_intensity = (float)low_frequency_rumble / SDL_MAX_UINT16;
594 float high_frequency_intensity = (float)high_frequency_rumble / SDL_MAX_UINT16;
595 Android_JNI_HapticRumble(item->device_id, low_frequency_intensity, high_frequency_intensity, 5000);
596 return true;
597}
598
599static bool ANDROID_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
600{
601 return SDL_Unsupported();
602}
603
604static bool ANDROID_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
605{
606 return SDL_Unsupported();
607}
608
609static bool ANDROID_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
610{
611 return SDL_Unsupported();
612}
613
614static bool ANDROID_JoystickSetSensorsEnabled(SDL_Joystick *joystick, bool enabled)
615{
616 return SDL_Unsupported();
617}
618
619static void ANDROID_JoystickUpdate(SDL_Joystick *joystick)
620{
621}
622
623static void ANDROID_JoystickClose(SDL_Joystick *joystick)
624{
625 SDL_joylist_item *item = (SDL_joylist_item *)joystick->hwdata;
626 if (item) {
627 item->joystick = NULL;
628 }
629}
630
631static void ANDROID_JoystickQuit(void)
632{
633/* We don't have any way to scan for joysticks at init, so don't wipe the list
634 * of joysticks here in case this is a reinit.
635 */
636#if 0
637 SDL_joylist_item *item = NULL;
638 SDL_joylist_item *next = NULL;
639
640 for (item = SDL_joylist; item; item = next) {
641 next = item->next;
642 SDL_free(item->name);
643 SDL_free(item);
644 }
645
646 SDL_joylist = SDL_joylist_tail = NULL;
647
648 numjoysticks = 0;
649#endif // 0
650}
651
652static bool ANDROID_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
653{
654 return false;
655}
656
657SDL_JoystickDriver SDL_ANDROID_JoystickDriver = {
658 ANDROID_JoystickInit,
659 ANDROID_JoystickGetCount,
660 ANDROID_JoystickDetect,
661 ANDROID_JoystickIsDevicePresent,
662 ANDROID_JoystickGetDeviceName,
663 ANDROID_JoystickGetDevicePath,
664 ANDROID_JoystickGetDeviceSteamVirtualGamepadSlot,
665 ANDROID_JoystickGetDevicePlayerIndex,
666 ANDROID_JoystickSetDevicePlayerIndex,
667 ANDROID_JoystickGetDeviceGUID,
668 ANDROID_JoystickGetDeviceInstanceID,
669 ANDROID_JoystickOpen,
670 ANDROID_JoystickRumble,
671 ANDROID_JoystickRumbleTriggers,
672 ANDROID_JoystickSetLED,
673 ANDROID_JoystickSendEffect,
674 ANDROID_JoystickSetSensorsEnabled,
675 ANDROID_JoystickUpdate,
676 ANDROID_JoystickClose,
677 ANDROID_JoystickQuit,
678 ANDROID_JoystickGetGamepadMapping
679};
680
681#endif // SDL_JOYSTICK_ANDROID
diff --git a/contrib/SDL-3.2.8/src/joystick/android/SDL_sysjoystick_c.h b/contrib/SDL-3.2.8/src/joystick/android/SDL_sysjoystick_c.h
new file mode 100644
index 0000000..febb228
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/joystick/android/SDL_sysjoystick_c.h
@@ -0,0 +1,57 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 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
22#include "SDL_internal.h"
23
24#ifdef SDL_JOYSTICK_ANDROID
25
26#ifndef SDL_sysjoystick_c_h_
27#define SDL_sysjoystick_c_h_
28
29#include "../SDL_sysjoystick.h"
30
31extern bool Android_OnPadDown(int device_id, int keycode);
32extern bool Android_OnPadUp(int device_id, int keycode);
33extern bool Android_OnJoy(int device_id, int axisnum, float value);
34extern bool Android_OnHat(int device_id, int hat_id, int x, int y);
35extern void Android_AddJoystick(int device_id, const char *name, const char *desc, int vendor_id, int product_id, int button_mask, int naxes, int axis_mask, int nhats, bool can_rumble);
36extern void Android_RemoveJoystick(int device_id);
37
38// A linked list of available joysticks
39typedef struct SDL_joylist_item
40{
41 int device_instance;
42 int device_id; // Android's device id
43 char *name; // "SideWinder 3D Pro" or whatever
44 SDL_GUID guid;
45 SDL_Joystick *joystick;
46 int nbuttons, naxes, nhats;
47 int dpad_state;
48 bool can_rumble;
49
50 struct SDL_joylist_item *next;
51} SDL_joylist_item;
52
53typedef SDL_joylist_item joystick_hwdata;
54
55#endif // SDL_sysjoystick_c_h_
56
57#endif // SDL_JOYSTICK_ANDROID