src/joystick/android/SDL_sysjoystick.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 02 Nov 2017 08:48:14 -0700
changeset 11671 3dc400fafd76
parent 11663 0d96acbd34f0
child 11778 db38a635e2c6
permissions -rw-r--r--
Fixed bug 3935 - Not find joysticks if android run 24-48 days.

Alexander Orefkov

In src\joystick\android\SDL_sysjoystick.c in SDL_SYS_JoystickDetect when SDL_GetTicks return number grater 2147483648 (after 24.85 days uptime) SDL_TICKS_PASSED(SDL_GetTicks(), timeout) return FALSE and Android_JNI_PollInputDevices is never calling.
And in JoystickByDeviceId - when search for newly added joystic - after SDL_SYS_JoystickDetect item not reinitilized, and always stay NULL, cause return NULL instead of added joystick.
gabomdq@7041
     1
/*
gabomdq@7041
     2
  Simple DirectMedia Layer
slouken@10737
     3
  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
gabomdq@7041
     4
gabomdq@7041
     5
  This software is provided 'as-is', without any express or implied
gabomdq@7041
     6
  warranty.  In no event will the authors be held liable for any damages
gabomdq@7041
     7
  arising from the use of this software.
gabomdq@7041
     8
gabomdq@7041
     9
  Permission is granted to anyone to use this software for any purpose,
gabomdq@7041
    10
  including commercial applications, and to alter it and redistribute it
gabomdq@7041
    11
  freely, subject to the following restrictions:
gabomdq@7041
    12
gabomdq@7041
    13
  1. The origin of this software must not be misrepresented; you must not
gabomdq@7041
    14
     claim that you wrote the original software. If you use this software
gabomdq@7041
    15
     in a product, an acknowledgment in the product documentation would be
gabomdq@7041
    16
     appreciated but is not required.
gabomdq@7041
    17
  2. Altered source versions must be plainly marked as such, and must not be
gabomdq@7041
    18
     misrepresented as being the original software.
gabomdq@7041
    19
  3. This notice may not be removed or altered from any source distribution.
gabomdq@7041
    20
*/
gabomdq@7041
    21
icculus@8093
    22
#include "../../SDL_internal.h"
gabomdq@7041
    23
gabomdq@7041
    24
#ifdef SDL_JOYSTICK_ANDROID
gabomdq@7041
    25
gabomdq@7041
    26
#include <stdio.h>              /* For the definition of NULL */
gabomdq@7041
    27
#include "SDL_error.h"
gabomdq@7041
    28
#include "SDL_events.h"
gabomdq@8057
    29
gabomdq@7041
    30
#include "SDL_joystick.h"
gabomdq@7907
    31
#include "SDL_hints.h"
gabomdq@7944
    32
#include "SDL_assert.h"
gabomdq@8060
    33
#include "SDL_timer.h"
philipp@8074
    34
#include "SDL_log.h"
gabomdq@8057
    35
#include "SDL_sysjoystick_c.h"
gabomdq@7041
    36
#include "../SDL_joystick_c.h"
gabomdq@7041
    37
#include "../../core/android/SDL_android.h"
slouken@11532
    38
#include "../steam/SDL_steamcontroller.h"
philipp@8008
    39
gabomdq@7944
    40
#include "android/keycodes.h"
gabomdq@7944
    41
gabomdq@7944
    42
/* As of platform android-14, android/keycodes.h is missing these defines */
gabomdq@7944
    43
#ifndef AKEYCODE_BUTTON_1
gabomdq@7944
    44
#define AKEYCODE_BUTTON_1 188
gabomdq@7944
    45
#define AKEYCODE_BUTTON_2 189
gabomdq@7944
    46
#define AKEYCODE_BUTTON_3 190
gabomdq@7944
    47
#define AKEYCODE_BUTTON_4 191
gabomdq@7944
    48
#define AKEYCODE_BUTTON_5 192
gabomdq@7944
    49
#define AKEYCODE_BUTTON_6 193
gabomdq@7944
    50
#define AKEYCODE_BUTTON_7 194
gabomdq@7944
    51
#define AKEYCODE_BUTTON_8 195
gabomdq@7944
    52
#define AKEYCODE_BUTTON_9 196
gabomdq@7944
    53
#define AKEYCODE_BUTTON_10 197
gabomdq@7944
    54
#define AKEYCODE_BUTTON_11 198
gabomdq@7944
    55
#define AKEYCODE_BUTTON_12 199
gabomdq@7944
    56
#define AKEYCODE_BUTTON_13 200
gabomdq@7944
    57
#define AKEYCODE_BUTTON_14 201
gabomdq@7944
    58
#define AKEYCODE_BUTTON_15 202
gabomdq@7944
    59
#define AKEYCODE_BUTTON_16 203
gabomdq@7944
    60
#endif
gabomdq@7041
    61
gabomdq@7907
    62
#define ANDROID_ACCELEROMETER_NAME "Android Accelerometer"
gabomdq@8057
    63
#define ANDROID_ACCELEROMETER_DEVICE_ID INT_MIN
gabomdq@7944
    64
#define ANDROID_MAX_NBUTTONS 36
gabomdq@7907
    65
gabomdq@8057
    66
static SDL_joylist_item * JoystickByDeviceId(int device_id);
gabomdq@8057
    67
gabomdq@8057
    68
static SDL_joylist_item *SDL_joylist = NULL;
gabomdq@8057
    69
static SDL_joylist_item *SDL_joylist_tail = NULL;
gabomdq@8057
    70
static int numjoysticks = 0;
gabomdq@8057
    71
static int instance_counter = 0;
gabomdq@8057
    72
gabomdq@7907
    73
gabomdq@7907
    74
/* Function to convert Android keyCodes into SDL ones.
gabomdq@7907
    75
 * This code manipulation is done to get a sequential list of codes.
gabomdq@7944
    76
 * FIXME: This is only suited for the case where we use a fixed number of buttons determined by ANDROID_MAX_NBUTTONS
gabomdq@7907
    77
 */
philipp@7929
    78
static int
gabomdq@7907
    79
keycode_to_SDL(int keycode)
gabomdq@7907
    80
{
gabomdq@7944
    81
    /* FIXME: If this function gets too unwiedly in the future, replace with a lookup table */
gabomdq@7944
    82
    int button = 0;
gabomdq@7944
    83
    switch(keycode) 
gabomdq@7944
    84
    {
gabomdq@8122
    85
        /* Some gamepad buttons (API 9) */
gabomdq@8122
    86
        case AKEYCODE_BUTTON_A:
gabomdq@8122
    87
            button = SDL_CONTROLLER_BUTTON_A;
gabomdq@8122
    88
            break;
gabomdq@8122
    89
        case AKEYCODE_BUTTON_B:
gabomdq@8122
    90
            button = SDL_CONTROLLER_BUTTON_B;
gabomdq@8122
    91
            break;
gabomdq@8122
    92
        case AKEYCODE_BUTTON_X:
gabomdq@8122
    93
            button = SDL_CONTROLLER_BUTTON_X;
gabomdq@8122
    94
            break;
gabomdq@8122
    95
        case AKEYCODE_BUTTON_Y:
gabomdq@8122
    96
            button = SDL_CONTROLLER_BUTTON_Y;
gabomdq@8122
    97
            break;
gabomdq@8122
    98
        case AKEYCODE_BUTTON_L1:
gabomdq@8122
    99
            button = SDL_CONTROLLER_BUTTON_LEFTSHOULDER;
gabomdq@8122
   100
            break;
gabomdq@8122
   101
        case AKEYCODE_BUTTON_R1:
gabomdq@8122
   102
            button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER;
gabomdq@8122
   103
            break;
gabomdq@8122
   104
        case AKEYCODE_BUTTON_THUMBL:
gabomdq@8122
   105
            button = SDL_CONTROLLER_BUTTON_LEFTSTICK;
gabomdq@8122
   106
            break;
gabomdq@8122
   107
        case AKEYCODE_BUTTON_THUMBR:
gabomdq@8122
   108
            button = SDL_CONTROLLER_BUTTON_RIGHTSTICK;
gabomdq@8122
   109
            break;
gabomdq@8122
   110
        case AKEYCODE_BUTTON_START:
gabomdq@8122
   111
            button = SDL_CONTROLLER_BUTTON_START;
gabomdq@8122
   112
            break;
gabomdq@8122
   113
        case AKEYCODE_BUTTON_SELECT:
gabomdq@8122
   114
            button = SDL_CONTROLLER_BUTTON_BACK;
gabomdq@8122
   115
            break;
gabomdq@8122
   116
        case AKEYCODE_BUTTON_MODE:
gabomdq@8122
   117
            button = SDL_CONTROLLER_BUTTON_GUIDE;
gabomdq@8122
   118
            break;
gabomdq@8122
   119
        case AKEYCODE_BUTTON_L2:
gabomdq@8122
   120
            button = SDL_CONTROLLER_BUTTON_MAX; /* Not supported by GameController */
gabomdq@8122
   121
            break;
gabomdq@8122
   122
        case AKEYCODE_BUTTON_R2:
gabomdq@8122
   123
            button = SDL_CONTROLLER_BUTTON_MAX+1; /* Not supported by GameController */
gabomdq@8122
   124
            break;
gabomdq@8122
   125
        case AKEYCODE_BUTTON_C:
gabomdq@8122
   126
            button = SDL_CONTROLLER_BUTTON_MAX+2; /* Not supported by GameController */
gabomdq@8122
   127
            break;
gabomdq@8122
   128
        case AKEYCODE_BUTTON_Z:
gabomdq@8122
   129
            button = SDL_CONTROLLER_BUTTON_MAX+3; /* Not supported by GameController */
gabomdq@8122
   130
            break;
gabomdq@8122
   131
                        
gabomdq@8122
   132
        /* D-Pad key codes (API 1) */
gabomdq@7944
   133
        case AKEYCODE_DPAD_UP:
gabomdq@8122
   134
            button = SDL_CONTROLLER_BUTTON_DPAD_UP;
gabomdq@8122
   135
            break;
gabomdq@7944
   136
        case AKEYCODE_DPAD_DOWN:
gabomdq@8122
   137
            button = SDL_CONTROLLER_BUTTON_DPAD_DOWN;
gabomdq@8122
   138
            break;
gabomdq@7944
   139
        case AKEYCODE_DPAD_LEFT:
gabomdq@8122
   140
            button = SDL_CONTROLLER_BUTTON_DPAD_LEFT;
gabomdq@8122
   141
            break;
gabomdq@7944
   142
        case AKEYCODE_DPAD_RIGHT:
gabomdq@8122
   143
            button = SDL_CONTROLLER_BUTTON_DPAD_RIGHT;
gabomdq@8122
   144
            break;
gabomdq@7944
   145
        case AKEYCODE_DPAD_CENTER:
slouken@11663
   146
            /* This is handled better by applications as the A button */
slouken@11663
   147
            /*button = SDL_CONTROLLER_BUTTON_MAX+4; /* Not supported by GameController */
slouken@11663
   148
            button = SDL_CONTROLLER_BUTTON_A;
slouken@11663
   149
            break;
slouken@11663
   150
slouken@11663
   151
        case AKEYCODE_BACK:
slouken@11663
   152
            button = SDL_CONTROLLER_BUTTON_B;
gabomdq@7944
   153
            break;
gabomdq@8122
   154
gabomdq@7944
   155
        /* More gamepad buttons (API 12), these get mapped to 20...35*/
gabomdq@7944
   156
        case AKEYCODE_BUTTON_1:
gabomdq@7944
   157
        case AKEYCODE_BUTTON_2:
gabomdq@7944
   158
        case AKEYCODE_BUTTON_3:
gabomdq@7944
   159
        case AKEYCODE_BUTTON_4:
gabomdq@7944
   160
        case AKEYCODE_BUTTON_5:
gabomdq@7944
   161
        case AKEYCODE_BUTTON_6:
gabomdq@7944
   162
        case AKEYCODE_BUTTON_7:
gabomdq@7944
   163
        case AKEYCODE_BUTTON_8:
gabomdq@7944
   164
        case AKEYCODE_BUTTON_9:
gabomdq@7944
   165
        case AKEYCODE_BUTTON_10:
gabomdq@7944
   166
        case AKEYCODE_BUTTON_11:
gabomdq@7944
   167
        case AKEYCODE_BUTTON_12:
gabomdq@7944
   168
        case AKEYCODE_BUTTON_13:
gabomdq@7944
   169
        case AKEYCODE_BUTTON_14:
gabomdq@7944
   170
        case AKEYCODE_BUTTON_15:
gabomdq@7944
   171
        case AKEYCODE_BUTTON_16:
gabomdq@8122
   172
            button = keycode - AKEYCODE_BUTTON_1 + SDL_CONTROLLER_BUTTON_MAX + 5;
gabomdq@7944
   173
            break;
gabomdq@7944
   174
            
gabomdq@7944
   175
        default:
gabomdq@7944
   176
            return -1;
slouken@10672
   177
            /* break; -Wunreachable-code-break */
gabomdq@7944
   178
    }
gabomdq@7944
   179
    
gabomdq@7944
   180
    /* This is here in case future generations, probably with six fingers per hand, 
gabomdq@7944
   181
     * happily add new cases up above and forget to update the max number of buttons. 
gabomdq@7907
   182
     */
gabomdq@7944
   183
    SDL_assert(button < ANDROID_MAX_NBUTTONS);
gabomdq@7944
   184
    return button;
gabomdq@7944
   185
    
gabomdq@7907
   186
}
gabomdq@7041
   187
gabomdq@8057
   188
int
gabomdq@8057
   189
Android_OnPadDown(int device_id, int keycode)
gabomdq@8057
   190
{
gabomdq@8057
   191
    SDL_joylist_item *item;
gabomdq@8057
   192
    int button = keycode_to_SDL(keycode);
gabomdq@8057
   193
    if (button >= 0) {
gabomdq@8057
   194
        item = JoystickByDeviceId(device_id);
gabomdq@8057
   195
        if (item && item->joystick) {
gabomdq@8057
   196
            SDL_PrivateJoystickButton(item->joystick, button , SDL_PRESSED);
gabomdq@8057
   197
        }
slouken@10551
   198
        return 0;
gabomdq@8057
   199
    }
gabomdq@8057
   200
    
gabomdq@8057
   201
    return -1;
gabomdq@8057
   202
}
gabomdq@8057
   203
gabomdq@8057
   204
int
gabomdq@8057
   205
Android_OnPadUp(int device_id, int keycode)
gabomdq@8057
   206
{
gabomdq@8057
   207
    SDL_joylist_item *item;
gabomdq@8057
   208
    int button = keycode_to_SDL(keycode);
gabomdq@8057
   209
    if (button >= 0) {
gabomdq@8057
   210
        item = JoystickByDeviceId(device_id);
gabomdq@8057
   211
        if (item && item->joystick) {
gabomdq@8057
   212
            SDL_PrivateJoystickButton(item->joystick, button, SDL_RELEASED);
gabomdq@8057
   213
        }
slouken@10551
   214
        return 0;
gabomdq@8057
   215
    }
gabomdq@8057
   216
    
gabomdq@8057
   217
    return -1;
gabomdq@8057
   218
}
gabomdq@8057
   219
gabomdq@8057
   220
int
gabomdq@8057
   221
Android_OnJoy(int device_id, int axis, float value)
gabomdq@8057
   222
{
gabomdq@8057
   223
    /* Android gives joy info normalized as [-1.0, 1.0] or [0.0, 1.0] */
gabomdq@8057
   224
    SDL_joylist_item *item = JoystickByDeviceId(device_id);
gabomdq@8057
   225
    if (item && item->joystick) {
slouken@11532
   226
        SDL_PrivateJoystickAxis(item->joystick, axis, (Sint16) (32767.*value));
gabomdq@8057
   227
    }
gabomdq@8057
   228
    
gabomdq@8057
   229
    return 0;
gabomdq@8057
   230
}
gabomdq@8057
   231
dbrady@8140
   232
int
dbrady@8140
   233
Android_OnHat(int device_id, int hat_id, int x, int y)
dbrady@8140
   234
{
dbrady@8140
   235
    const Uint8 position_map[3][3] = {
dbrady@8140
   236
        {SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP},
dbrady@8140
   237
        {SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT},
dbrady@8140
   238
        {SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN}
dbrady@8140
   239
    };
dbrady@8140
   240
dbrady@8140
   241
    if (x >= -1 && x <=1 && y >= -1 && y <= 1) {
dbrady@8140
   242
        SDL_joylist_item *item = JoystickByDeviceId(device_id);
dbrady@8140
   243
        if (item && item->joystick) {
slouken@11532
   244
            SDL_PrivateJoystickHat(item->joystick, hat_id, position_map[y+1][x+1]);
dbrady@8140
   245
        }
dbrady@8140
   246
        return 0;
dbrady@8140
   247
    }
dbrady@8140
   248
dbrady@8140
   249
    return -1;
dbrady@8140
   250
}
dbrady@8140
   251
gabomdq@8057
   252
gabomdq@8057
   253
int
slouken@11393
   254
Android_AddJoystick(int device_id, const char *name, const char *desc, SDL_bool is_accelerometer, int nbuttons, int naxes, int nhats, int nballs)
gabomdq@8057
   255
{
gabomdq@8057
   256
    SDL_JoystickGUID guid;
gabomdq@8057
   257
    SDL_joylist_item *item;
gabomdq@8057
   258
    
gabomdq@8057
   259
    if(JoystickByDeviceId(device_id) != NULL || name == NULL) {
gabomdq@8057
   260
        return -1;
gabomdq@8057
   261
    }
gabomdq@8057
   262
    
gabomdq@8057
   263
    /* the GUID is just the first 16 chars of the name for now */
slouken@11532
   264
    SDL_zero(guid);
slouken@11532
   265
    SDL_memcpy(&guid, desc, SDL_min(sizeof(guid), SDL_strlen(desc)));
gabomdq@8057
   266
gabomdq@8057
   267
    item = (SDL_joylist_item *) SDL_malloc(sizeof (SDL_joylist_item));
gabomdq@8057
   268
    if (item == NULL) {
gabomdq@8057
   269
        return -1;
gabomdq@8057
   270
    }
gabomdq@8057
   271
gabomdq@8057
   272
    SDL_zerop(item);
gabomdq@8057
   273
    item->guid = guid;
gabomdq@8057
   274
    item->device_id = device_id;
gabomdq@8057
   275
    item->name = SDL_strdup(name);
slouken@11532
   276
    if (item->name == NULL) {
gabomdq@8057
   277
         SDL_free(item);
gabomdq@8057
   278
         return -1;
gabomdq@8057
   279
    }
gabomdq@8057
   280
    
gabomdq@8057
   281
    item->is_accelerometer = is_accelerometer;
gabomdq@8057
   282
    if (nbuttons > -1) {
gabomdq@8057
   283
        item->nbuttons = nbuttons;
gabomdq@8057
   284
    }
gabomdq@8057
   285
    else {
gabomdq@8057
   286
        item->nbuttons = ANDROID_MAX_NBUTTONS;
gabomdq@8057
   287
    }
gabomdq@8057
   288
    item->naxes = naxes;
gabomdq@8057
   289
    item->nhats = nhats;
gabomdq@8057
   290
    item->nballs = nballs;
gabomdq@8057
   291
    item->device_instance = instance_counter++;
gabomdq@8057
   292
    if (SDL_joylist_tail == NULL) {
gabomdq@8057
   293
        SDL_joylist = SDL_joylist_tail = item;
gabomdq@8057
   294
    } else {
gabomdq@8057
   295
        SDL_joylist_tail->next = item;
gabomdq@8057
   296
        SDL_joylist_tail = item;
gabomdq@8057
   297
    }
gabomdq@8057
   298
gabomdq@8057
   299
    /* Need to increment the joystick count before we post the event */
gabomdq@8057
   300
    ++numjoysticks;
gabomdq@8057
   301
slouken@10226
   302
    SDL_PrivateJoystickAdded(numjoysticks - 1);
gabomdq@8057
   303
philipp@9579
   304
#ifdef DEBUG_JOYSTICK
gabomdq@8057
   305
    SDL_Log("Added joystick %s with device_id %d", name, device_id);
philipp@9579
   306
#endif
gabomdq@8057
   307
gabomdq@8057
   308
    return numjoysticks;
gabomdq@8057
   309
}
gabomdq@8057
   310
gabomdq@8057
   311
int 
gabomdq@8057
   312
Android_RemoveJoystick(int device_id)
gabomdq@8057
   313
{
gabomdq@8057
   314
    SDL_joylist_item *item = SDL_joylist;
gabomdq@8057
   315
    SDL_joylist_item *prev = NULL;
gabomdq@8057
   316
    
gabomdq@8057
   317
    /* Don't call JoystickByDeviceId here or there'll be an infinite loop! */
gabomdq@8057
   318
    while (item != NULL) {
gabomdq@8057
   319
        if (item->device_id == device_id) {
gabomdq@8057
   320
            break;
gabomdq@8057
   321
        }
gabomdq@8057
   322
        prev = item;
gabomdq@8057
   323
        item = item->next;
gabomdq@8057
   324
    }
gabomdq@8057
   325
    
gabomdq@8057
   326
    if (item == NULL) {
gabomdq@8057
   327
        return -1;
gabomdq@8057
   328
    }
gabomdq@8057
   329
gabomdq@8119
   330
    if (item->joystick) {
gabomdq@8119
   331
        item->joystick->hwdata = NULL;
gabomdq@8119
   332
    }
gabomdq@8119
   333
        
gabomdq@8057
   334
    if (prev != NULL) {
gabomdq@8057
   335
        prev->next = item->next;
gabomdq@8057
   336
    } else {
gabomdq@8057
   337
        SDL_assert(SDL_joylist == item);
gabomdq@8057
   338
        SDL_joylist = item->next;
gabomdq@8057
   339
    }
gabomdq@8057
   340
    if (item == SDL_joylist_tail) {
gabomdq@8057
   341
        SDL_joylist_tail = prev;
gabomdq@8057
   342
    }
gabomdq@8057
   343
gabomdq@8057
   344
    /* Need to decrement the joystick count before we post the event */
gabomdq@8057
   345
    --numjoysticks;
gabomdq@8057
   346
slouken@10226
   347
    SDL_PrivateJoystickRemoved(item->device_instance);
gabomdq@8057
   348
philipp@9579
   349
#ifdef DEBUG_JOYSTICK
gabomdq@8057
   350
    SDL_Log("Removed joystick with device_id %d", device_id);
philipp@9579
   351
#endif
gabomdq@8057
   352
    
gabomdq@8057
   353
    SDL_free(item->name);
gabomdq@8057
   354
    SDL_free(item);
philipp@10073
   355
    return numjoysticks;
gabomdq@8057
   356
}
gabomdq@8057
   357
gabomdq@8057
   358
slouken@11532
   359
static SDL_bool SteamControllerConnectedCallback(const char *name, SDL_JoystickGUID guid, int *device_instance)
slouken@11532
   360
{
slouken@11532
   361
    SDL_joylist_item *item;
slouken@11532
   362
    
slouken@11532
   363
    item = (SDL_joylist_item *)SDL_calloc(1, sizeof (SDL_joylist_item));
slouken@11532
   364
    if (item == NULL) {
slouken@11532
   365
        return SDL_FALSE;
slouken@11532
   366
    }
slouken@11532
   367
slouken@11532
   368
    *device_instance = item->device_instance = instance_counter++;
slouken@11532
   369
    item->device_id = -1;
slouken@11532
   370
    item->name = SDL_strdup(name);
slouken@11532
   371
    item->guid = guid;
slouken@11532
   372
    SDL_GetSteamControllerInputs(&item->nbuttons,
slouken@11532
   373
                                 &item->naxes,
slouken@11532
   374
                                 &item->nhats);
slouken@11532
   375
    item->m_bSteamController = SDL_TRUE;
slouken@11532
   376
slouken@11532
   377
    if (SDL_joylist_tail == NULL) {
slouken@11532
   378
        SDL_joylist = SDL_joylist_tail = item;
slouken@11532
   379
    } else {
slouken@11532
   380
        SDL_joylist_tail->next = item;
slouken@11532
   381
        SDL_joylist_tail = item;
slouken@11532
   382
    }
slouken@11532
   383
slouken@11532
   384
    /* Need to increment the joystick count before we post the event */
slouken@11532
   385
    ++numjoysticks;
slouken@11532
   386
slouken@11532
   387
    SDL_PrivateJoystickAdded(numjoysticks - 1);
slouken@11532
   388
slouken@11532
   389
    return SDL_TRUE;
slouken@11532
   390
}
slouken@11532
   391
slouken@11532
   392
static void SteamControllerDisconnectedCallback(int device_instance)
slouken@11532
   393
{
slouken@11532
   394
    SDL_joylist_item *item = SDL_joylist;
slouken@11532
   395
    SDL_joylist_item *prev = NULL;
slouken@11532
   396
    
slouken@11532
   397
    while (item != NULL) {
slouken@11532
   398
        if (item->device_instance == device_instance) {
slouken@11532
   399
            break;
slouken@11532
   400
        }
slouken@11532
   401
        prev = item;
slouken@11532
   402
        item = item->next;
slouken@11532
   403
    }
slouken@11532
   404
    
slouken@11532
   405
    if (item == NULL) {
slouken@11532
   406
        return;
slouken@11532
   407
    }
slouken@11532
   408
slouken@11532
   409
    if (item->joystick) {
slouken@11532
   410
        item->joystick->hwdata = NULL;
slouken@11532
   411
    }
slouken@11532
   412
        
slouken@11532
   413
    if (prev != NULL) {
slouken@11532
   414
        prev->next = item->next;
slouken@11532
   415
    } else {
slouken@11532
   416
        SDL_assert(SDL_joylist == item);
slouken@11532
   417
        SDL_joylist = item->next;
slouken@11532
   418
    }
slouken@11532
   419
    if (item == SDL_joylist_tail) {
slouken@11532
   420
        SDL_joylist_tail = prev;
slouken@11532
   421
    }
slouken@11532
   422
slouken@11532
   423
    /* Need to decrement the joystick count before we post the event */
slouken@11532
   424
    --numjoysticks;
slouken@11532
   425
slouken@11532
   426
    SDL_PrivateJoystickRemoved(item->device_instance);
slouken@11532
   427
slouken@11532
   428
    SDL_free(item->name);
slouken@11532
   429
    SDL_free(item);
slouken@11532
   430
}
slouken@11532
   431
gabomdq@7041
   432
int
gabomdq@7041
   433
SDL_SYS_JoystickInit(void)
gabomdq@7041
   434
{
gabomdq@8057
   435
    SDL_SYS_JoystickDetect();
gabomdq@7907
   436
    
slouken@10499
   437
    if (SDL_GetHintBoolean(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_TRUE)) {
gabomdq@8057
   438
        /* Default behavior, accelerometer as joystick */
slouken@11393
   439
        Android_AddJoystick(ANDROID_ACCELEROMETER_DEVICE_ID, ANDROID_ACCELEROMETER_NAME, ANDROID_ACCELEROMETER_NAME, SDL_TRUE, 0, 3, 0, 0);
gabomdq@7907
   440
    }
gabomdq@7907
   441
   
slouken@11532
   442
    SDL_InitSteamControllers(SteamControllerConnectedCallback,
slouken@11532
   443
                             SteamControllerDisconnectedCallback);
slouken@11532
   444
gabomdq@8057
   445
    return (numjoysticks);
gabomdq@8057
   446
gabomdq@7041
   447
}
gabomdq@7041
   448
philipp@10617
   449
int
philipp@10617
   450
SDL_SYS_NumJoysticks(void)
gabomdq@7041
   451
{
gabomdq@8057
   452
    return numjoysticks;
gabomdq@7041
   453
}
gabomdq@7041
   454
philipp@10617
   455
void
philipp@10617
   456
SDL_SYS_JoystickDetect(void)
gabomdq@7041
   457
{
gabomdq@8057
   458
    /* Support for device connect/disconnect is API >= 16 only,
gabomdq@8060
   459
     * so we poll every three seconds
gabomdq@8057
   460
     * Ref: http://developer.android.com/reference/android/hardware/input/InputManager.InputDeviceListener.html
gabomdq@8057
   461
     */
gabomdq@8060
   462
    static Uint32 timeout = 0;
slouken@11671
   463
    if (!timeout || SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) {
gabomdq@8060
   464
        timeout = SDL_GetTicks() + 3000;
gabomdq@8060
   465
        Android_JNI_PollInputDevices();
gabomdq@8060
   466
    }
slouken@11532
   467
slouken@11532
   468
    SDL_UpdateSteamControllers();
gabomdq@7041
   469
}
gabomdq@7041
   470
gabomdq@8057
   471
static SDL_joylist_item *
gabomdq@8057
   472
JoystickByDevIndex(int device_index)
gabomdq@8057
   473
{
gabomdq@8057
   474
    SDL_joylist_item *item = SDL_joylist;
gabomdq@8057
   475
gabomdq@8057
   476
    if ((device_index < 0) || (device_index >= numjoysticks)) {
gabomdq@8057
   477
        return NULL;
gabomdq@8057
   478
    }
gabomdq@8057
   479
gabomdq@8057
   480
    while (device_index > 0) {
gabomdq@8057
   481
        SDL_assert(item != NULL);
gabomdq@8057
   482
        device_index--;
gabomdq@8057
   483
        item = item->next;
gabomdq@8057
   484
    }
gabomdq@8057
   485
gabomdq@8057
   486
    return item;
gabomdq@8057
   487
}
gabomdq@8057
   488
gabomdq@8057
   489
static SDL_joylist_item *
gabomdq@8057
   490
JoystickByDeviceId(int device_id)
gabomdq@8057
   491
{
gabomdq@8057
   492
    SDL_joylist_item *item = SDL_joylist;
gabomdq@8057
   493
gabomdq@8057
   494
    while (item != NULL) {
gabomdq@8057
   495
        if (item->device_id == device_id) {
gabomdq@8057
   496
            return item;
gabomdq@8057
   497
        }
gabomdq@8057
   498
        item = item->next;
gabomdq@8057
   499
    }
gabomdq@8057
   500
    
gabomdq@8057
   501
    /* Joystick not found, try adding it */
gabomdq@8057
   502
    SDL_SYS_JoystickDetect();
gabomdq@8057
   503
    
gabomdq@8057
   504
    while (item != NULL) {
gabomdq@8057
   505
        if (item->device_id == device_id) {
gabomdq@8057
   506
            return item;
gabomdq@8057
   507
        }
gabomdq@8057
   508
        item = item->next;
gabomdq@8057
   509
    }
gabomdq@8057
   510
gabomdq@8057
   511
    return NULL;
gabomdq@7041
   512
}
gabomdq@7041
   513
gabomdq@7041
   514
/* Function to get the device-dependent name of a joystick */
gabomdq@7041
   515
const char *
gabomdq@7041
   516
SDL_SYS_JoystickNameForDeviceIndex(int device_index)
gabomdq@7041
   517
{
gabomdq@8057
   518
    return JoystickByDevIndex(device_index)->name;
gabomdq@7041
   519
}
gabomdq@7041
   520
gabomdq@7041
   521
/* Function to perform the mapping from device index to the instance id for this index */
gabomdq@7041
   522
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
gabomdq@7041
   523
{
gabomdq@8057
   524
    return JoystickByDevIndex(device_index)->device_instance;
gabomdq@7041
   525
}
gabomdq@7041
   526
gabomdq@7041
   527
/* Function to open a joystick for use.
philipp@9380
   528
   The joystick to open is specified by the device index.
gabomdq@7041
   529
   This should fill the nbuttons and naxes fields of the joystick structure.
gabomdq@7041
   530
   It returns 0, or -1 if there is an error.
gabomdq@7041
   531
 */
gabomdq@7041
   532
int
gabomdq@7041
   533
SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
gabomdq@7041
   534
{
gabomdq@8057
   535
    SDL_joylist_item *item = JoystickByDevIndex(device_index);
gabomdq@8057
   536
slouken@11532
   537
    if (item == NULL) {
gabomdq@8057
   538
        return SDL_SetError("No such device");
slouken@7191
   539
    }
gabomdq@8057
   540
    
gabomdq@8057
   541
    if (item->joystick != NULL) {
gabomdq@8057
   542
        return SDL_SetError("Joystick already opened");
gabomdq@8057
   543
    }
gabomdq@8057
   544
gabomdq@8057
   545
    joystick->instance_id = item->device_instance;
gabomdq@8057
   546
    joystick->hwdata = (struct joystick_hwdata *) item;
gabomdq@8057
   547
    item->joystick = joystick;
gabomdq@8057
   548
    joystick->nhats = item->nhats;
gabomdq@8057
   549
    joystick->nballs = item->nballs;
gabomdq@8057
   550
    joystick->nbuttons = item->nbuttons;
gabomdq@8057
   551
    joystick->naxes = item->naxes;
gabomdq@8057
   552
gabomdq@8057
   553
    return (0);
gabomdq@7041
   554
}
gabomdq@7041
   555
philipp@9561
   556
/* Function to determine if this joystick is attached to the system right now */
gabomdq@7041
   557
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
gabomdq@7041
   558
{
icculus@9433
   559
    return joystick->hwdata != NULL;
gabomdq@7041
   560
}
gabomdq@7041
   561
gabomdq@7041
   562
void
gabomdq@7041
   563
SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
gabomdq@7041
   564
{
slouken@11532
   565
    SDL_joylist_item *item = (SDL_joylist_item *) joystick->hwdata;
gabomdq@7041
   566
slouken@11532
   567
    if (item == NULL) {
slouken@11532
   568
        return;
slouken@11532
   569
    }
slouken@11532
   570
 
slouken@11532
   571
    if (item->m_bSteamController) {
slouken@11532
   572
        SDL_UpdateSteamController(joystick);
slouken@11532
   573
        return;
slouken@11532
   574
    }
slouken@9741
   575
slouken@11532
   576
    if (item->is_accelerometer) {
slouken@11532
   577
        int i;
slouken@11532
   578
        Sint16 value;
slouken@11532
   579
        float values[3];
slouken@11532
   580
slouken@11532
   581
        if (Android_JNI_GetAccelerometerValues(values)) {
slouken@11532
   582
            for (i = 0; i < 3; i++) {
slouken@11532
   583
                if (values[i] > 1.0f) {
slouken@11532
   584
                    values[i] = 1.0f;
slouken@11532
   585
                } else if (values[i] < -1.0f) {
slouken@11532
   586
                    values[i] = -1.0f;
gabomdq@8057
   587
                }
slouken@11532
   588
slouken@11532
   589
                value = (Sint16)(values[i] * 32767.0f);
slouken@11532
   590
                SDL_PrivateJoystickAxis(item->joystick, i, value);
gabomdq@8057
   591
            }
gabomdq@7041
   592
        }
gabomdq@7041
   593
    }
gabomdq@7041
   594
}
gabomdq@7041
   595
gabomdq@7041
   596
/* Function to close a joystick after use */
gabomdq@7041
   597
void
gabomdq@7041
   598
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
gabomdq@7041
   599
{
philipp@10219
   600
    SDL_joylist_item *item = (SDL_joylist_item *) joystick->hwdata;
philipp@10223
   601
    if (item) {
philipp@10223
   602
        item->joystick = NULL;
philipp@10223
   603
    }
gabomdq@7041
   604
}
gabomdq@7041
   605
gabomdq@7041
   606
/* Function to perform any system-specific joystick related cleanup */
gabomdq@7041
   607
void
gabomdq@7041
   608
SDL_SYS_JoystickQuit(void)
gabomdq@7041
   609
{
slouken@11532
   610
/* We don't have any way to scan for joysticks at init, so don't wipe the list
slouken@11532
   611
 * of joysticks here in case this is a reinit.
slouken@11532
   612
 */
slouken@11532
   613
#if 0
gabomdq@8057
   614
    SDL_joylist_item *item = NULL;
gabomdq@8057
   615
    SDL_joylist_item *next = NULL;
gabomdq@8057
   616
gabomdq@8057
   617
    for (item = SDL_joylist; item; item = next) {
gabomdq@8057
   618
        next = item->next;
gabomdq@8057
   619
        SDL_free(item->name);
gabomdq@8057
   620
        SDL_free(item);
gabomdq@8057
   621
    }
gabomdq@8057
   622
gabomdq@8057
   623
    SDL_joylist = SDL_joylist_tail = NULL;
gabomdq@8057
   624
gabomdq@8057
   625
    numjoysticks = 0;
gabomdq@8057
   626
    instance_counter = 0;
slouken@11532
   627
#endif /* 0 */
slouken@11532
   628
slouken@11532
   629
    SDL_QuitSteamControllers();
gabomdq@7041
   630
}
gabomdq@7041
   631
slouken@11532
   632
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID(int device_index)
gabomdq@7041
   633
{
gabomdq@8057
   634
    return JoystickByDevIndex(device_index)->guid;
gabomdq@7041
   635
}
gabomdq@7041
   636
gabomdq@7041
   637
SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
gabomdq@7041
   638
{
gabomdq@7041
   639
    SDL_JoystickGUID guid;
gabomdq@8119
   640
    
gabomdq@8119
   641
    if (joystick->hwdata != NULL) {
gabomdq@8119
   642
        return ((SDL_joylist_item*)joystick->hwdata)->guid;
gabomdq@7956
   643
    }
gabomdq@7907
   644
    
gabomdq@8119
   645
    SDL_zero(guid);
gabomdq@8119
   646
    return guid;
gabomdq@7907
   647
}
gabomdq@7907
   648
slouken@11663
   649
SDL_bool SDL_SYS_IsDPAD_DeviceIndex(int device_index)
slouken@11663
   650
{
slouken@11663
   651
    return JoystickByDevIndex(device_index)->naxes == 0;
slouken@11663
   652
}
slouken@11663
   653
gabomdq@7041
   654
#endif /* SDL_JOYSTICK_ANDROID */
gabomdq@7041
   655
gabomdq@7041
   656
/* vi: set ts=4 sw=4 expandtab: */