Atlas - SDL_sysjoystick.c

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