src/joystick/android/SDL_sysjoystick.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 26 Aug 2016 12:18:08 -0700
changeset 10226 cb13d22b7f09
parent 10223 74c39dbe8d30
child 10499 363c1c7e7a41
permissions -rw-r--r--
Added SDL_PrivateJoystickAdded() and SDL_PrivateJoystickRemoved()
Updated the removal code to iterate over all joystick add messages instead of just the first one.
gabomdq@7041
     1
/*
gabomdq@7041
     2
  Simple DirectMedia Layer
slouken@9998
     3
  Copyright (C) 1997-2016 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"
philipp@8008
    38
gabomdq@7944
    39
#include "android/keycodes.h"
gabomdq@7944
    40
gabomdq@7944
    41
/* As of platform android-14, android/keycodes.h is missing these defines */
gabomdq@7944
    42
#ifndef AKEYCODE_BUTTON_1
gabomdq@7944
    43
#define AKEYCODE_BUTTON_1 188
gabomdq@7944
    44
#define AKEYCODE_BUTTON_2 189
gabomdq@7944
    45
#define AKEYCODE_BUTTON_3 190
gabomdq@7944
    46
#define AKEYCODE_BUTTON_4 191
gabomdq@7944
    47
#define AKEYCODE_BUTTON_5 192
gabomdq@7944
    48
#define AKEYCODE_BUTTON_6 193
gabomdq@7944
    49
#define AKEYCODE_BUTTON_7 194
gabomdq@7944
    50
#define AKEYCODE_BUTTON_8 195
gabomdq@7944
    51
#define AKEYCODE_BUTTON_9 196
gabomdq@7944
    52
#define AKEYCODE_BUTTON_10 197
gabomdq@7944
    53
#define AKEYCODE_BUTTON_11 198
gabomdq@7944
    54
#define AKEYCODE_BUTTON_12 199
gabomdq@7944
    55
#define AKEYCODE_BUTTON_13 200
gabomdq@7944
    56
#define AKEYCODE_BUTTON_14 201
gabomdq@7944
    57
#define AKEYCODE_BUTTON_15 202
gabomdq@7944
    58
#define AKEYCODE_BUTTON_16 203
gabomdq@7944
    59
#endif
gabomdq@7041
    60
gabomdq@7907
    61
#define ANDROID_ACCELEROMETER_NAME "Android Accelerometer"
gabomdq@8057
    62
#define ANDROID_ACCELEROMETER_DEVICE_ID INT_MIN
gabomdq@7944
    63
#define ANDROID_MAX_NBUTTONS 36
gabomdq@7907
    64
gabomdq@8057
    65
static SDL_joylist_item * JoystickByDeviceId(int device_id);
gabomdq@8057
    66
gabomdq@8057
    67
static SDL_joylist_item *SDL_joylist = NULL;
gabomdq@8057
    68
static SDL_joylist_item *SDL_joylist_tail = NULL;
gabomdq@8057
    69
static int numjoysticks = 0;
gabomdq@8057
    70
static int instance_counter = 0;
gabomdq@8057
    71
gabomdq@7907
    72
gabomdq@7907
    73
/* Function to convert Android keyCodes into SDL ones.
gabomdq@7907
    74
 * This code manipulation is done to get a sequential list of codes.
gabomdq@7944
    75
 * FIXME: This is only suited for the case where we use a fixed number of buttons determined by ANDROID_MAX_NBUTTONS
gabomdq@7907
    76
 */
philipp@7929
    77
static int
gabomdq@7907
    78
keycode_to_SDL(int keycode)
gabomdq@7907
    79
{
gabomdq@7944
    80
    /* FIXME: If this function gets too unwiedly in the future, replace with a lookup table */
gabomdq@7944
    81
    int button = 0;
gabomdq@7944
    82
    switch(keycode) 
gabomdq@7944
    83
    {
gabomdq@8122
    84
        /* Some gamepad buttons (API 9) */
gabomdq@8122
    85
        case AKEYCODE_BUTTON_A:
gabomdq@8122
    86
            button = SDL_CONTROLLER_BUTTON_A;
gabomdq@8122
    87
            break;
gabomdq@8122
    88
        case AKEYCODE_BUTTON_B:
gabomdq@8122
    89
            button = SDL_CONTROLLER_BUTTON_B;
gabomdq@8122
    90
            break;
gabomdq@8122
    91
        case AKEYCODE_BUTTON_X:
gabomdq@8122
    92
            button = SDL_CONTROLLER_BUTTON_X;
gabomdq@8122
    93
            break;
gabomdq@8122
    94
        case AKEYCODE_BUTTON_Y:
gabomdq@8122
    95
            button = SDL_CONTROLLER_BUTTON_Y;
gabomdq@8122
    96
            break;
gabomdq@8122
    97
        case AKEYCODE_BUTTON_L1:
gabomdq@8122
    98
            button = SDL_CONTROLLER_BUTTON_LEFTSHOULDER;
gabomdq@8122
    99
            break;
gabomdq@8122
   100
        case AKEYCODE_BUTTON_R1:
gabomdq@8122
   101
            button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER;
gabomdq@8122
   102
            break;
gabomdq@8122
   103
        case AKEYCODE_BUTTON_THUMBL:
gabomdq@8122
   104
            button = SDL_CONTROLLER_BUTTON_LEFTSTICK;
gabomdq@8122
   105
            break;
gabomdq@8122
   106
        case AKEYCODE_BUTTON_THUMBR:
gabomdq@8122
   107
            button = SDL_CONTROLLER_BUTTON_RIGHTSTICK;
gabomdq@8122
   108
            break;
gabomdq@8122
   109
        case AKEYCODE_BUTTON_START:
gabomdq@8122
   110
            button = SDL_CONTROLLER_BUTTON_START;
gabomdq@8122
   111
            break;
gabomdq@8122
   112
        case AKEYCODE_BUTTON_SELECT:
gabomdq@8122
   113
            button = SDL_CONTROLLER_BUTTON_BACK;
gabomdq@8122
   114
            break;
gabomdq@8122
   115
        case AKEYCODE_BUTTON_MODE:
gabomdq@8122
   116
            button = SDL_CONTROLLER_BUTTON_GUIDE;
gabomdq@8122
   117
            break;
gabomdq@8122
   118
        case AKEYCODE_BUTTON_L2:
gabomdq@8122
   119
            button = SDL_CONTROLLER_BUTTON_MAX; /* Not supported by GameController */
gabomdq@8122
   120
            break;
gabomdq@8122
   121
        case AKEYCODE_BUTTON_R2:
gabomdq@8122
   122
            button = SDL_CONTROLLER_BUTTON_MAX+1; /* Not supported by GameController */
gabomdq@8122
   123
            break;
gabomdq@8122
   124
        case AKEYCODE_BUTTON_C:
gabomdq@8122
   125
            button = SDL_CONTROLLER_BUTTON_MAX+2; /* Not supported by GameController */
gabomdq@8122
   126
            break;
gabomdq@8122
   127
        case AKEYCODE_BUTTON_Z:
gabomdq@8122
   128
            button = SDL_CONTROLLER_BUTTON_MAX+3; /* Not supported by GameController */
gabomdq@8122
   129
            break;
gabomdq@8122
   130
                        
gabomdq@8122
   131
        /* D-Pad key codes (API 1) */
gabomdq@7944
   132
        case AKEYCODE_DPAD_UP:
gabomdq@8122
   133
            button = SDL_CONTROLLER_BUTTON_DPAD_UP;
gabomdq@8122
   134
            break;
gabomdq@7944
   135
        case AKEYCODE_DPAD_DOWN:
gabomdq@8122
   136
            button = SDL_CONTROLLER_BUTTON_DPAD_DOWN;
gabomdq@8122
   137
            break;
gabomdq@7944
   138
        case AKEYCODE_DPAD_LEFT:
gabomdq@8122
   139
            button = SDL_CONTROLLER_BUTTON_DPAD_LEFT;
gabomdq@8122
   140
            break;
gabomdq@7944
   141
        case AKEYCODE_DPAD_RIGHT:
gabomdq@8122
   142
            button = SDL_CONTROLLER_BUTTON_DPAD_RIGHT;
gabomdq@8122
   143
            break;
gabomdq@7944
   144
        case AKEYCODE_DPAD_CENTER:
gabomdq@8122
   145
            button = SDL_CONTROLLER_BUTTON_MAX+4; /* Not supported by GameController */
gabomdq@7944
   146
            break;
gabomdq@8122
   147
gabomdq@7944
   148
        /* More gamepad buttons (API 12), these get mapped to 20...35*/
gabomdq@7944
   149
        case AKEYCODE_BUTTON_1:
gabomdq@7944
   150
        case AKEYCODE_BUTTON_2:
gabomdq@7944
   151
        case AKEYCODE_BUTTON_3:
gabomdq@7944
   152
        case AKEYCODE_BUTTON_4:
gabomdq@7944
   153
        case AKEYCODE_BUTTON_5:
gabomdq@7944
   154
        case AKEYCODE_BUTTON_6:
gabomdq@7944
   155
        case AKEYCODE_BUTTON_7:
gabomdq@7944
   156
        case AKEYCODE_BUTTON_8:
gabomdq@7944
   157
        case AKEYCODE_BUTTON_9:
gabomdq@7944
   158
        case AKEYCODE_BUTTON_10:
gabomdq@7944
   159
        case AKEYCODE_BUTTON_11:
gabomdq@7944
   160
        case AKEYCODE_BUTTON_12:
gabomdq@7944
   161
        case AKEYCODE_BUTTON_13:
gabomdq@7944
   162
        case AKEYCODE_BUTTON_14:
gabomdq@7944
   163
        case AKEYCODE_BUTTON_15:
gabomdq@7944
   164
        case AKEYCODE_BUTTON_16:
gabomdq@8122
   165
            button = keycode - AKEYCODE_BUTTON_1 + SDL_CONTROLLER_BUTTON_MAX + 5;
gabomdq@7944
   166
            break;
gabomdq@7944
   167
            
gabomdq@7944
   168
        default:
gabomdq@7944
   169
            return -1;
gabomdq@7944
   170
            break;
gabomdq@7944
   171
    }
gabomdq@7944
   172
    
gabomdq@7944
   173
    /* This is here in case future generations, probably with six fingers per hand, 
gabomdq@7944
   174
     * happily add new cases up above and forget to update the max number of buttons. 
gabomdq@7907
   175
     */
gabomdq@7944
   176
    SDL_assert(button < ANDROID_MAX_NBUTTONS);
gabomdq@7944
   177
    return button;
gabomdq@7944
   178
    
gabomdq@7907
   179
}
gabomdq@7041
   180
gabomdq@8057
   181
int
gabomdq@8057
   182
Android_OnPadDown(int device_id, int keycode)
gabomdq@8057
   183
{
gabomdq@8057
   184
    SDL_joylist_item *item;
gabomdq@8057
   185
    int button = keycode_to_SDL(keycode);
gabomdq@8057
   186
    if (button >= 0) {
gabomdq@8057
   187
        item = JoystickByDeviceId(device_id);
gabomdq@8057
   188
        if (item && item->joystick) {
gabomdq@8057
   189
            SDL_PrivateJoystickButton(item->joystick, button , SDL_PRESSED);
slouken@9751
   190
            return 0;
gabomdq@8057
   191
        }
gabomdq@8057
   192
    }
gabomdq@8057
   193
    
gabomdq@8057
   194
    return -1;
gabomdq@8057
   195
}
gabomdq@8057
   196
gabomdq@8057
   197
int
gabomdq@8057
   198
Android_OnPadUp(int device_id, int keycode)
gabomdq@8057
   199
{
gabomdq@8057
   200
    SDL_joylist_item *item;
gabomdq@8057
   201
    int button = keycode_to_SDL(keycode);
gabomdq@8057
   202
    if (button >= 0) {
gabomdq@8057
   203
        item = JoystickByDeviceId(device_id);
gabomdq@8057
   204
        if (item && item->joystick) {
gabomdq@8057
   205
            SDL_PrivateJoystickButton(item->joystick, button, SDL_RELEASED);
slouken@9751
   206
            return 0;
gabomdq@8057
   207
        }
gabomdq@8057
   208
    }
gabomdq@8057
   209
    
gabomdq@8057
   210
    return -1;
gabomdq@8057
   211
}
gabomdq@8057
   212
gabomdq@8057
   213
int
gabomdq@8057
   214
Android_OnJoy(int device_id, int axis, float value)
gabomdq@8057
   215
{
gabomdq@8057
   216
    /* Android gives joy info normalized as [-1.0, 1.0] or [0.0, 1.0] */
gabomdq@8057
   217
    SDL_joylist_item *item = JoystickByDeviceId(device_id);
gabomdq@8057
   218
    if (item && item->joystick) {
gabomdq@8057
   219
        SDL_PrivateJoystickAxis(item->joystick, axis, (Sint16) (32767.*value) );
gabomdq@8057
   220
    }
gabomdq@8057
   221
    
gabomdq@8057
   222
    return 0;
gabomdq@8057
   223
}
gabomdq@8057
   224
dbrady@8140
   225
int
dbrady@8140
   226
Android_OnHat(int device_id, int hat_id, int x, int y)
dbrady@8140
   227
{
dbrady@8140
   228
    const Uint8 position_map[3][3] = {
dbrady@8140
   229
        {SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP},
dbrady@8140
   230
        {SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT},
dbrady@8140
   231
        {SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN}
dbrady@8140
   232
    };
dbrady@8140
   233
dbrady@8140
   234
    if (x >= -1 && x <=1 && y >= -1 && y <= 1) {
dbrady@8140
   235
        SDL_joylist_item *item = JoystickByDeviceId(device_id);
dbrady@8140
   236
        if (item && item->joystick) {
dbrady@8140
   237
            SDL_PrivateJoystickHat(item->joystick, hat_id, position_map[y+1][x+1] );
dbrady@8140
   238
        }
dbrady@8140
   239
        return 0;
dbrady@8140
   240
    }
dbrady@8140
   241
dbrady@8140
   242
    return -1;
dbrady@8140
   243
}
dbrady@8140
   244
gabomdq@8057
   245
gabomdq@8057
   246
int
gabomdq@8057
   247
Android_AddJoystick(int device_id, const char *name, SDL_bool is_accelerometer, int nbuttons, int naxes, int nhats, int nballs)
gabomdq@8057
   248
{
gabomdq@8057
   249
    SDL_JoystickGUID guid;
gabomdq@8057
   250
    SDL_joylist_item *item;
gabomdq@8057
   251
    
gabomdq@8057
   252
    if(JoystickByDeviceId(device_id) != NULL || name == NULL) {
gabomdq@8057
   253
        return -1;
gabomdq@8057
   254
    }
gabomdq@8057
   255
    
gabomdq@8057
   256
    /* the GUID is just the first 16 chars of the name for now */
gabomdq@8057
   257
    SDL_zero( guid );
gabomdq@8057
   258
    SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
gabomdq@8057
   259
gabomdq@8057
   260
    item = (SDL_joylist_item *) SDL_malloc(sizeof (SDL_joylist_item));
gabomdq@8057
   261
    if (item == NULL) {
gabomdq@8057
   262
        return -1;
gabomdq@8057
   263
    }
gabomdq@8057
   264
gabomdq@8057
   265
    SDL_zerop(item);
gabomdq@8057
   266
    item->guid = guid;
gabomdq@8057
   267
    item->device_id = device_id;
gabomdq@8057
   268
    item->name = SDL_strdup(name);
gabomdq@8057
   269
    if ( item->name == NULL ) {
gabomdq@8057
   270
         SDL_free(item);
gabomdq@8057
   271
         return -1;
gabomdq@8057
   272
    }
gabomdq@8057
   273
    
gabomdq@8057
   274
    item->is_accelerometer = is_accelerometer;
gabomdq@8057
   275
    if (nbuttons > -1) {
gabomdq@8057
   276
        item->nbuttons = nbuttons;
gabomdq@8057
   277
    }
gabomdq@8057
   278
    else {
gabomdq@8057
   279
        item->nbuttons = ANDROID_MAX_NBUTTONS;
gabomdq@8057
   280
    }
gabomdq@8057
   281
    item->naxes = naxes;
gabomdq@8057
   282
    item->nhats = nhats;
gabomdq@8057
   283
    item->nballs = nballs;
gabomdq@8057
   284
    item->device_instance = instance_counter++;
gabomdq@8057
   285
    if (SDL_joylist_tail == NULL) {
gabomdq@8057
   286
        SDL_joylist = SDL_joylist_tail = item;
gabomdq@8057
   287
    } else {
gabomdq@8057
   288
        SDL_joylist_tail->next = item;
gabomdq@8057
   289
        SDL_joylist_tail = item;
gabomdq@8057
   290
    }
gabomdq@8057
   291
gabomdq@8057
   292
    /* Need to increment the joystick count before we post the event */
gabomdq@8057
   293
    ++numjoysticks;
gabomdq@8057
   294
slouken@10226
   295
    SDL_PrivateJoystickAdded(numjoysticks - 1);
gabomdq@8057
   296
philipp@9579
   297
#ifdef DEBUG_JOYSTICK
gabomdq@8057
   298
    SDL_Log("Added joystick %s with device_id %d", name, device_id);
philipp@9579
   299
#endif
gabomdq@8057
   300
gabomdq@8057
   301
    return numjoysticks;
gabomdq@8057
   302
}
gabomdq@8057
   303
gabomdq@8057
   304
int 
gabomdq@8057
   305
Android_RemoveJoystick(int device_id)
gabomdq@8057
   306
{
gabomdq@8057
   307
    SDL_joylist_item *item = SDL_joylist;
gabomdq@8057
   308
    SDL_joylist_item *prev = NULL;
gabomdq@8057
   309
    
gabomdq@8057
   310
    /* Don't call JoystickByDeviceId here or there'll be an infinite loop! */
gabomdq@8057
   311
    while (item != NULL) {
gabomdq@8057
   312
        if (item->device_id == device_id) {
gabomdq@8057
   313
            break;
gabomdq@8057
   314
        }
gabomdq@8057
   315
        prev = item;
gabomdq@8057
   316
        item = item->next;
gabomdq@8057
   317
    }
gabomdq@8057
   318
    
gabomdq@8057
   319
    if (item == NULL) {
gabomdq@8057
   320
        return -1;
gabomdq@8057
   321
    }
gabomdq@8057
   322
gabomdq@8119
   323
    if (item->joystick) {
gabomdq@8119
   324
        item->joystick->hwdata = NULL;
gabomdq@8119
   325
    }
gabomdq@8119
   326
        
gabomdq@8057
   327
    if (prev != NULL) {
gabomdq@8057
   328
        prev->next = item->next;
gabomdq@8057
   329
    } else {
gabomdq@8057
   330
        SDL_assert(SDL_joylist == item);
gabomdq@8057
   331
        SDL_joylist = item->next;
gabomdq@8057
   332
    }
gabomdq@8057
   333
    if (item == SDL_joylist_tail) {
gabomdq@8057
   334
        SDL_joylist_tail = prev;
gabomdq@8057
   335
    }
gabomdq@8057
   336
gabomdq@8057
   337
    /* Need to decrement the joystick count before we post the event */
gabomdq@8057
   338
    --numjoysticks;
gabomdq@8057
   339
slouken@10226
   340
    SDL_PrivateJoystickRemoved(item->device_instance);
gabomdq@8057
   341
philipp@9579
   342
#ifdef DEBUG_JOYSTICK
gabomdq@8057
   343
    SDL_Log("Removed joystick with device_id %d", device_id);
philipp@9579
   344
#endif
gabomdq@8057
   345
    
gabomdq@8057
   346
    SDL_free(item->name);
gabomdq@8057
   347
    SDL_free(item);
philipp@10073
   348
    return numjoysticks;
gabomdq@8057
   349
}
gabomdq@8057
   350
gabomdq@8057
   351
gabomdq@7041
   352
int
gabomdq@7041
   353
SDL_SYS_JoystickInit(void)
gabomdq@7041
   354
{
slouken@8274
   355
    const char *hint;
gabomdq@8057
   356
    SDL_SYS_JoystickDetect();
gabomdq@7907
   357
    
slouken@8274
   358
    hint = SDL_GetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK);
slouken@8274
   359
    if (!hint || SDL_atoi(hint)) {
gabomdq@8057
   360
        /* Default behavior, accelerometer as joystick */
gabomdq@8057
   361
        Android_AddJoystick(ANDROID_ACCELEROMETER_DEVICE_ID, ANDROID_ACCELEROMETER_NAME, SDL_TRUE, 0, 3, 0, 0);
gabomdq@7907
   362
    }
gabomdq@7907
   363
   
gabomdq@8057
   364
    return (numjoysticks);
gabomdq@8057
   365
gabomdq@7041
   366
}
gabomdq@7041
   367
gabomdq@7041
   368
int SDL_SYS_NumJoysticks()
gabomdq@7041
   369
{
gabomdq@8057
   370
    return numjoysticks;
gabomdq@7041
   371
}
gabomdq@7041
   372
gabomdq@7041
   373
void SDL_SYS_JoystickDetect()
gabomdq@7041
   374
{
gabomdq@8057
   375
    /* Support for device connect/disconnect is API >= 16 only,
gabomdq@8060
   376
     * so we poll every three seconds
gabomdq@8057
   377
     * Ref: http://developer.android.com/reference/android/hardware/input/InputManager.InputDeviceListener.html
gabomdq@8057
   378
     */
gabomdq@8060
   379
    static Uint32 timeout = 0;
gabomdq@8060
   380
    if (SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) {
gabomdq@8060
   381
        timeout = SDL_GetTicks() + 3000;
gabomdq@8060
   382
        Android_JNI_PollInputDevices();
gabomdq@8060
   383
    }
gabomdq@7041
   384
}
gabomdq@7041
   385
gabomdq@8057
   386
static SDL_joylist_item *
gabomdq@8057
   387
JoystickByDevIndex(int device_index)
gabomdq@8057
   388
{
gabomdq@8057
   389
    SDL_joylist_item *item = SDL_joylist;
gabomdq@8057
   390
gabomdq@8057
   391
    if ((device_index < 0) || (device_index >= numjoysticks)) {
gabomdq@8057
   392
        return NULL;
gabomdq@8057
   393
    }
gabomdq@8057
   394
gabomdq@8057
   395
    while (device_index > 0) {
gabomdq@8057
   396
        SDL_assert(item != NULL);
gabomdq@8057
   397
        device_index--;
gabomdq@8057
   398
        item = item->next;
gabomdq@8057
   399
    }
gabomdq@8057
   400
gabomdq@8057
   401
    return item;
gabomdq@8057
   402
}
gabomdq@8057
   403
gabomdq@8057
   404
static SDL_joylist_item *
gabomdq@8057
   405
JoystickByDeviceId(int device_id)
gabomdq@8057
   406
{
gabomdq@8057
   407
    SDL_joylist_item *item = SDL_joylist;
gabomdq@8057
   408
gabomdq@8057
   409
    while (item != NULL) {
gabomdq@8057
   410
        if (item->device_id == device_id) {
gabomdq@8057
   411
            return item;
gabomdq@8057
   412
        }
gabomdq@8057
   413
        item = item->next;
gabomdq@8057
   414
    }
gabomdq@8057
   415
    
gabomdq@8057
   416
    /* Joystick not found, try adding it */
gabomdq@8057
   417
    SDL_SYS_JoystickDetect();
gabomdq@8057
   418
    
gabomdq@8057
   419
    while (item != NULL) {
gabomdq@8057
   420
        if (item->device_id == device_id) {
gabomdq@8057
   421
            return item;
gabomdq@8057
   422
        }
gabomdq@8057
   423
        item = item->next;
gabomdq@8057
   424
    }
gabomdq@8057
   425
gabomdq@8057
   426
    return NULL;
gabomdq@7041
   427
}
gabomdq@7041
   428
gabomdq@7041
   429
/* Function to get the device-dependent name of a joystick */
gabomdq@7041
   430
const char *
gabomdq@7041
   431
SDL_SYS_JoystickNameForDeviceIndex(int device_index)
gabomdq@7041
   432
{
gabomdq@8057
   433
    return JoystickByDevIndex(device_index)->name;
gabomdq@7041
   434
}
gabomdq@7041
   435
gabomdq@7041
   436
/* Function to perform the mapping from device index to the instance id for this index */
gabomdq@7041
   437
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
gabomdq@7041
   438
{
gabomdq@8057
   439
    return JoystickByDevIndex(device_index)->device_instance;
gabomdq@7041
   440
}
gabomdq@7041
   441
gabomdq@7041
   442
/* Function to open a joystick for use.
philipp@9380
   443
   The joystick to open is specified by the device index.
gabomdq@7041
   444
   This should fill the nbuttons and naxes fields of the joystick structure.
gabomdq@7041
   445
   It returns 0, or -1 if there is an error.
gabomdq@7041
   446
 */
gabomdq@7041
   447
int
gabomdq@7041
   448
SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
gabomdq@7041
   449
{
gabomdq@8057
   450
    SDL_joylist_item *item = JoystickByDevIndex(device_index);
gabomdq@8057
   451
gabomdq@8057
   452
    if (item == NULL ) {
gabomdq@8057
   453
        return SDL_SetError("No such device");
slouken@7191
   454
    }
gabomdq@8057
   455
    
gabomdq@8057
   456
    if (item->joystick != NULL) {
gabomdq@8057
   457
        return SDL_SetError("Joystick already opened");
gabomdq@8057
   458
    }
gabomdq@8057
   459
gabomdq@8057
   460
    joystick->instance_id = item->device_instance;
gabomdq@8057
   461
    joystick->hwdata = (struct joystick_hwdata *) item;
gabomdq@8057
   462
    item->joystick = joystick;
gabomdq@8057
   463
    joystick->nhats = item->nhats;
gabomdq@8057
   464
    joystick->nballs = item->nballs;
gabomdq@8057
   465
    joystick->nbuttons = item->nbuttons;
gabomdq@8057
   466
    joystick->naxes = item->naxes;
gabomdq@8057
   467
gabomdq@8057
   468
    return (0);
gabomdq@7041
   469
}
gabomdq@7041
   470
philipp@9561
   471
/* Function to determine if this joystick is attached to the system right now */
gabomdq@7041
   472
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
gabomdq@7041
   473
{
icculus@9433
   474
    return joystick->hwdata != NULL;
gabomdq@7041
   475
}
gabomdq@7041
   476
gabomdq@7041
   477
void
gabomdq@7041
   478
SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
gabomdq@7041
   479
{
gabomdq@7041
   480
    int i;
gabomdq@7041
   481
    Sint16 value;
gabomdq@7041
   482
    float values[3];
gabomdq@8057
   483
    SDL_joylist_item *item = SDL_joylist;
gabomdq@7041
   484
gabomdq@8057
   485
    while (item) {
gabomdq@8057
   486
        if (item->is_accelerometer) {
gabomdq@8057
   487
            if (item->joystick) {
gabomdq@8129
   488
                if (Android_JNI_GetAccelerometerValues(values)) {
gabomdq@8129
   489
                    for ( i = 0; i < 3; i++ ) {
slouken@9742
   490
                        if (values[i] > 1.0f) {
slouken@9741
   491
                            values[i] = 1.0f;
slouken@9742
   492
                        } else if (values[i] < -1.0f) {
slouken@9741
   493
                            values[i] = -1.0f;
slouken@9741
   494
                        }
slouken@9741
   495
gabomdq@8129
   496
                        value = (Sint16)(values[i] * 32767.0f);
gabomdq@8129
   497
                        SDL_PrivateJoystickAxis(item->joystick, i, value);
gabomdq@8129
   498
                    }
gabomdq@8057
   499
                }
gabomdq@8057
   500
            }
gabomdq@8057
   501
            break;
gabomdq@7041
   502
        }
gabomdq@8057
   503
        item = item->next;
gabomdq@7041
   504
    }
gabomdq@7041
   505
}
gabomdq@7041
   506
gabomdq@7041
   507
/* Function to close a joystick after use */
gabomdq@7041
   508
void
gabomdq@7041
   509
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
gabomdq@7041
   510
{
philipp@10219
   511
    SDL_joylist_item *item = (SDL_joylist_item *) joystick->hwdata;
philipp@10223
   512
    if (item) {
philipp@10223
   513
        item->joystick = NULL;
philipp@10223
   514
    }
gabomdq@7041
   515
}
gabomdq@7041
   516
gabomdq@7041
   517
/* Function to perform any system-specific joystick related cleanup */
gabomdq@7041
   518
void
gabomdq@7041
   519
SDL_SYS_JoystickQuit(void)
gabomdq@7041
   520
{
gabomdq@8057
   521
    SDL_joylist_item *item = NULL;
gabomdq@8057
   522
    SDL_joylist_item *next = NULL;
gabomdq@8057
   523
gabomdq@8057
   524
    for (item = SDL_joylist; item; item = next) {
gabomdq@8057
   525
        next = item->next;
gabomdq@8057
   526
        SDL_free(item->name);
gabomdq@8057
   527
        SDL_free(item);
gabomdq@8057
   528
    }
gabomdq@8057
   529
gabomdq@8057
   530
    SDL_joylist = SDL_joylist_tail = NULL;
gabomdq@8057
   531
gabomdq@8057
   532
    numjoysticks = 0;
gabomdq@8057
   533
    instance_counter = 0;
gabomdq@7041
   534
}
gabomdq@7041
   535
gabomdq@7041
   536
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
gabomdq@7041
   537
{
gabomdq@8057
   538
    return JoystickByDevIndex(device_index)->guid;
gabomdq@7041
   539
}
gabomdq@7041
   540
gabomdq@7041
   541
SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
gabomdq@7041
   542
{
gabomdq@7041
   543
    SDL_JoystickGUID guid;
gabomdq@8119
   544
    
gabomdq@8119
   545
    if (joystick->hwdata != NULL) {
gabomdq@8119
   546
        return ((SDL_joylist_item*)joystick->hwdata)->guid;
gabomdq@7956
   547
    }
gabomdq@7907
   548
    
gabomdq@8119
   549
    SDL_zero(guid);
gabomdq@8119
   550
    return guid;
gabomdq@7907
   551
}
gabomdq@7907
   552
gabomdq@7041
   553
#endif /* SDL_JOYSTICK_ANDROID */
gabomdq@7041
   554
gabomdq@7041
   555
/* vi: set ts=4 sw=4 expandtab: */