sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

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: */