src/joystick/android/SDL_sysjoystick.c
author Gabriel Jacobo <gabomdq@gmail.com>
Tue, 05 Nov 2013 20:07:39 -0300
changeset 7907 24b4e98c6010
parent 7191 75360622e65f
child 7928 8d4d3fdca1aa
permissions -rw-r--r--
Adds Joystick support for Android

This bumps the build SDK level to 12 (up from 10). Runtime requirements remain
the same (at API level < 12 joystick support is disabled).

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