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