src/joystick/android/SDL_sysjoystick.c
author Philipp Wiesemann <philipp.wiesemann@arcor.de>
Sun, 10 Nov 2013 14:47:05 +0100
changeset 7930 5a1a7cdf3fa2
parent 7929 e3b38a3cdd60
child 7944 f19c0aca56aa
permissions -rw-r--r--
Changed function to return -1 through SDL_Error() instead of plain -1.
gabomdq@7041
     1
/*
gabomdq@7041
     2
  Simple DirectMedia Layer
gabomdq@7041
     3
  Copyright (C) 1997-2013 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
gabomdq@7041
    22
#include "SDL_config.h"
gabomdq@7041
    23
gabomdq@7041
    24
#ifdef SDL_JOYSTICK_ANDROID
gabomdq@7041
    25
gabomdq@7041
    26
/* This is the system specific header for the SDL joystick API */
gabomdq@7041
    27
#include <stdio.h>              /* For the definition of NULL */
gabomdq@7041
    28
gabomdq@7041
    29
#include "SDL_error.h"
gabomdq@7041
    30
#include "SDL_events.h"
gabomdq@7041
    31
#include "SDL_joystick.h"
gabomdq@7907
    32
#include "SDL_hints.h"
gabomdq@7041
    33
#include "../SDL_sysjoystick.h"
gabomdq@7041
    34
#include "../SDL_joystick_c.h"
gabomdq@7041
    35
#include "../../core/android/SDL_android.h"
gabomdq@7041
    36
gabomdq@7907
    37
#define ANDROID_ACCELEROMETER_INDEX (SYS_numjoysticks - 1)
gabomdq@7907
    38
#define ANDROID_ACCELEROMETER_NAME "Android Accelerometer"
gabomdq@7907
    39
gabomdq@7907
    40
static SDL_Joystick **SYS_Joysticks;
gabomdq@7907
    41
static char **SYS_JoystickNames;
gabomdq@7907
    42
static int SYS_numjoysticks;
gabomdq@7907
    43
static SDL_bool SYS_accelAsJoy;
gabomdq@7907
    44
gabomdq@7907
    45
/* Function to convert Android keyCodes into SDL ones.
gabomdq@7907
    46
 * This code manipulation is done to get a sequential list of codes.
gabomdq@7907
    47
 */
philipp@7929
    48
static int
gabomdq@7907
    49
keycode_to_SDL(int keycode)
gabomdq@7907
    50
{
gabomdq@7907
    51
    /* D-Pad key codes (API 1):
gabomdq@7907
    52
     * KEYCODE_DPAD_UP=19, KEYCODE_DPAD_DOWN
gabomdq@7907
    53
     * KEYCODE_DPAD_LEFT, KEYCODE_DPAD_RIGHT, KEYCODE_DPAD_CENTER
gabomdq@7907
    54
     */
gabomdq@7907
    55
    if(keycode < 96)
gabomdq@7907
    56
        return keycode-19;
gabomdq@7907
    57
    /* Some gamepad buttons (API 9):
gabomdq@7907
    58
     * KEYCODE_BUTTON_A=96, KEYCODE_BUTTON_B, KEYCODE_BUTTON_C,
gabomdq@7907
    59
     * KEYCODE_BUTTON_X, KEYCODE_BUTTON_Y, KEYCODE_BUTTON_Z,
gabomdq@7907
    60
     * KEYCODE_BUTTON_L1, KEYCODE_BUTTON_L2,
gabomdq@7907
    61
     * KEYCODE_BUTTON_R1, KEYCODE_BUTTON_R2,
gabomdq@7907
    62
     * KEYCODE_BUTTON_THUMBL, KEYCODE_BUTTON_THUMBR,
gabomdq@7907
    63
     * KEYCODE_BUTTON_START, KEYCODE_BUTTON_SELECT, KEYCODE_BUTTON_MODE
gabomdq@7907
    64
     */
gabomdq@7907
    65
    else if(keycode < 188)
gabomdq@7907
    66
        return keycode-91;
gabomdq@7907
    67
    /* More gamepad buttons (API 12):
gabomdq@7907
    68
     * KEYCODE_BUTTON_1=188 to KEYCODE_BUTTON_16
gabomdq@7907
    69
     */
gabomdq@7907
    70
    else
gabomdq@7907
    71
        return keycode-168;
gabomdq@7907
    72
}
gabomdq@7041
    73
gabomdq@7041
    74
/* Function to scan the system for joysticks.
gabomdq@7041
    75
 * This function should set SDL_numjoysticks to the number of available
gabomdq@7041
    76
 * joysticks.  Joystick 0 should be the system default joystick.
gabomdq@7041
    77
 * It should return 0, or -1 on an unrecoverable fatal error.
gabomdq@7041
    78
 */
gabomdq@7041
    79
int
gabomdq@7041
    80
SDL_SYS_JoystickInit(void)
gabomdq@7041
    81
{
gabomdq@7907
    82
    int i = 0;
gabomdq@7907
    83
    const char *env;
gabomdq@7907
    84
    
gabomdq@7907
    85
    env = SDL_GetHint(SDL_HINT_ACCEL_AS_JOY);
gabomdq@7907
    86
    if (env && !SDL_atoi(env))
gabomdq@7907
    87
        SYS_accelAsJoy = SDL_FALSE;
gabomdq@7907
    88
    else
gabomdq@7907
    89
        SYS_accelAsJoy = SDL_TRUE; /* Default behavior */
gabomdq@7907
    90
    
gabomdq@7907
    91
    SYS_numjoysticks = Android_JNI_GetNumJoysticks();
gabomdq@7907
    92
    if (SYS_accelAsJoy) {
gabomdq@7907
    93
        SYS_numjoysticks++;
gabomdq@7907
    94
    }
gabomdq@7907
    95
    SYS_Joysticks = (SDL_Joystick **)SDL_malloc(SYS_numjoysticks*sizeof(SDL_Joystick *));
gabomdq@7907
    96
    if (SYS_Joysticks == NULL)
gabomdq@7907
    97
    {
gabomdq@7907
    98
        return SDL_OutOfMemory();
gabomdq@7907
    99
    }
gabomdq@7907
   100
    SYS_JoystickNames = (char **)SDL_malloc(SYS_numjoysticks*sizeof(char *));
gabomdq@7907
   101
    if (SYS_JoystickNames == NULL)
gabomdq@7907
   102
    {
gabomdq@7907
   103
        SDL_free(SYS_Joysticks);
gabomdq@7907
   104
        SYS_Joysticks = NULL;
gabomdq@7907
   105
        return SDL_OutOfMemory();
gabomdq@7907
   106
    }
gabomdq@7907
   107
    SDL_memset(SYS_JoystickNames, 0, (SYS_numjoysticks*sizeof(char *)));
gabomdq@7907
   108
    SDL_memset(SYS_Joysticks, 0, (SYS_numjoysticks*sizeof(SDL_Joystick *)));
gabomdq@7907
   109
    
gabomdq@7907
   110
    for (i = 0; i < SYS_numjoysticks; i++)
gabomdq@7907
   111
    {
gabomdq@7907
   112
        if ( SYS_accelAsJoy && i == ANDROID_ACCELEROMETER_INDEX ) {
gabomdq@7907
   113
            SYS_JoystickNames[i] = ANDROID_ACCELEROMETER_NAME;
gabomdq@7907
   114
        } else {
gabomdq@7907
   115
            SYS_JoystickNames[i] = Android_JNI_GetJoystickName(i);
gabomdq@7907
   116
        }
gabomdq@7907
   117
    }
gabomdq@7907
   118
   
gabomdq@7907
   119
    return (SYS_numjoysticks);
gabomdq@7041
   120
}
gabomdq@7041
   121
gabomdq@7041
   122
int SDL_SYS_NumJoysticks()
gabomdq@7041
   123
{
gabomdq@7907
   124
    return SYS_numjoysticks;
gabomdq@7041
   125
}
gabomdq@7041
   126
gabomdq@7041
   127
void SDL_SYS_JoystickDetect()
gabomdq@7041
   128
{
gabomdq@7041
   129
}
gabomdq@7041
   130
gabomdq@7907
   131
/* TODO: Hotplugging support */
gabomdq@7041
   132
SDL_bool SDL_SYS_JoystickNeedsPolling()
gabomdq@7041
   133
{
gabomdq@7041
   134
    return SDL_FALSE;
gabomdq@7041
   135
}
gabomdq@7041
   136
gabomdq@7041
   137
/* Function to get the device-dependent name of a joystick */
gabomdq@7041
   138
const char *
gabomdq@7041
   139
SDL_SYS_JoystickNameForDeviceIndex(int device_index)
gabomdq@7041
   140
{
gabomdq@7907
   141
    return SYS_JoystickNames[device_index];
gabomdq@7041
   142
}
gabomdq@7041
   143
gabomdq@7041
   144
/* Function to perform the mapping from device index to the instance id for this index */
gabomdq@7041
   145
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
gabomdq@7041
   146
{
gabomdq@7041
   147
    return device_index;
gabomdq@7041
   148
}
gabomdq@7041
   149
gabomdq@7041
   150
/* Function to open a joystick for use.
gabomdq@7041
   151
   The joystick to open is specified by the index field of the joystick.
gabomdq@7041
   152
   This should fill the nbuttons and naxes fields of the joystick structure.
gabomdq@7041
   153
   It returns 0, or -1 if there is an error.
gabomdq@7041
   154
 */
gabomdq@7041
   155
int
gabomdq@7041
   156
SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
gabomdq@7041
   157
{
gabomdq@7907
   158
    if (device_index < SYS_numjoysticks) {
gabomdq@7041
   159
        joystick->nhats = 0;
gabomdq@7041
   160
        joystick->nballs = 0;
gabomdq@7907
   161
        if (SYS_accelAsJoy && device_index == ANDROID_ACCELEROMETER_INDEX) {
gabomdq@7907
   162
            joystick->nbuttons = 0;
gabomdq@7907
   163
            joystick->naxes = 3;
gabomdq@7907
   164
        } else {
gabomdq@7907
   165
            /* TODO: Get the real number of buttons in the device */
gabomdq@7907
   166
            joystick->nbuttons = 36;
gabomdq@7907
   167
            joystick->naxes = Android_JNI_GetJoystickAxes(device_index);
gabomdq@7907
   168
        }
gabomdq@7907
   169
        
gabomdq@7907
   170
        SYS_Joysticks[device_index] = joystick;
gabomdq@7041
   171
        return 0;
slouken@7191
   172
    } else {
philipp@7930
   173
        return SDL_SetError("No joystick available with that index");
slouken@7191
   174
    }
gabomdq@7041
   175
}
gabomdq@7041
   176
gabomdq@7041
   177
/* Function to determine is this joystick is attached to the system right now */
gabomdq@7041
   178
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
gabomdq@7041
   179
{
gabomdq@7041
   180
    return SDL_TRUE;
gabomdq@7041
   181
}
gabomdq@7041
   182
gabomdq@7041
   183
/* Function to update the state of a joystick - called as a device poll.
gabomdq@7041
   184
 * This function shouldn't update the joystick structure directly,
gabomdq@7041
   185
 * but instead should call SDL_PrivateJoystick*() to deliver events
gabomdq@7041
   186
 * and update joystick device state.
gabomdq@7041
   187
 */
gabomdq@7041
   188
void
gabomdq@7041
   189
SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
gabomdq@7041
   190
{
gabomdq@7041
   191
    int i;
gabomdq@7041
   192
    Sint16 value;
gabomdq@7041
   193
    float values[3];
gabomdq@7041
   194
gabomdq@7907
   195
    if (SYS_accelAsJoy && Android_JNI_GetAccelerometerValues(values) &&
gabomdq@7907
   196
        joystick->instance_id == ANDROID_ACCELEROMETER_INDEX) {
gabomdq@7041
   197
        for ( i = 0; i < 3; i++ ) {
gabomdq@7041
   198
            value = (Sint16)(values[i] * 32767.0f);
gabomdq@7041
   199
            SDL_PrivateJoystickAxis(joystick, i, value);
gabomdq@7041
   200
        }
gabomdq@7041
   201
    }
gabomdq@7041
   202
}
gabomdq@7041
   203
gabomdq@7041
   204
/* Function to close a joystick after use */
gabomdq@7041
   205
void
gabomdq@7041
   206
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
gabomdq@7041
   207
{
gabomdq@7041
   208
}
gabomdq@7041
   209
gabomdq@7041
   210
/* Function to perform any system-specific joystick related cleanup */
gabomdq@7041
   211
void
gabomdq@7041
   212
SDL_SYS_JoystickQuit(void)
gabomdq@7041
   213
{
gabomdq@7907
   214
    SDL_free(SYS_JoystickNames);
gabomdq@7907
   215
    SDL_free(SYS_Joysticks);
gabomdq@7907
   216
    SYS_JoystickNames = NULL;
gabomdq@7907
   217
    SYS_Joysticks = NULL;
gabomdq@7041
   218
}
gabomdq@7041
   219
gabomdq@7041
   220
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
gabomdq@7041
   221
{
gabomdq@7041
   222
    SDL_JoystickGUID guid;
slouken@7191
   223
    /* the GUID is just the first 16 chars of the name for now */
gabomdq@7041
   224
    const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index );
gabomdq@7041
   225
    SDL_zero( guid );
gabomdq@7041
   226
    SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
gabomdq@7041
   227
    return guid;
gabomdq@7041
   228
}
gabomdq@7041
   229
gabomdq@7041
   230
SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
gabomdq@7041
   231
{
gabomdq@7041
   232
    SDL_JoystickGUID guid;
slouken@7191
   233
    /* the GUID is just the first 16 chars of the name for now */
gabomdq@7041
   234
    const char *name = joystick->name;
gabomdq@7041
   235
    SDL_zero( guid );
gabomdq@7041
   236
    SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
gabomdq@7041
   237
    return guid;
gabomdq@7041
   238
}
gabomdq@7041
   239
gabomdq@7907
   240
int
gabomdq@7907
   241
Android_OnPadDown(int padId, int keycode)
gabomdq@7907
   242
{
gabomdq@7907
   243
    SDL_PrivateJoystickButton(SYS_Joysticks[padId], keycode_to_SDL(keycode), SDL_PRESSED);
gabomdq@7907
   244
    
gabomdq@7907
   245
    return 0;
gabomdq@7907
   246
}
gabomdq@7907
   247
gabomdq@7907
   248
int
gabomdq@7907
   249
Android_OnPadUp(int padId, int keycode)
gabomdq@7907
   250
{
gabomdq@7907
   251
    SDL_PrivateJoystickButton(SYS_Joysticks[padId], keycode_to_SDL(keycode), SDL_RELEASED);
gabomdq@7907
   252
    
gabomdq@7907
   253
    return 0;
gabomdq@7907
   254
}
gabomdq@7907
   255
gabomdq@7907
   256
int
gabomdq@7907
   257
Android_OnJoy(int joyId, int axis, float value)
gabomdq@7907
   258
{
gabomdq@7907
   259
    /* Android gives joy info normalized as [-1.0, 1.0] or [0.0, 1.0] */
gabomdq@7907
   260
    /* TODO: Are the reported values right? */
gabomdq@7907
   261
    SDL_PrivateJoystickAxis(SYS_Joysticks[joyId], axis, (Sint16) (32767.*value) );
gabomdq@7907
   262
    
gabomdq@7907
   263
    return 0;
gabomdq@7907
   264
}
gabomdq@7907
   265
gabomdq@7041
   266
#endif /* SDL_JOYSTICK_ANDROID */
gabomdq@7041
   267
gabomdq@7041
   268
/* vi: set ts=4 sw=4 expandtab: */