src/joystick/android/SDL_sysjoystick.c
changeset 7907 24b4e98c6010
parent 7191 75360622e65f
child 7928 8d4d3fdca1aa
     1.1 --- a/src/joystick/android/SDL_sysjoystick.c	Sun Nov 03 11:34:03 2013 -0800
     1.2 +++ b/src/joystick/android/SDL_sysjoystick.c	Tue Nov 05 20:07:39 2013 -0300
     1.3 @@ -29,11 +29,48 @@
     1.4  #include "SDL_error.h"
     1.5  #include "SDL_events.h"
     1.6  #include "SDL_joystick.h"
     1.7 +#include "SDL_hints.h"
     1.8  #include "../SDL_sysjoystick.h"
     1.9  #include "../SDL_joystick_c.h"
    1.10  #include "../../core/android/SDL_android.h"
    1.11  
    1.12 -static const char *accelerometerName = "Android accelerometer";
    1.13 +#define ANDROID_ACCELEROMETER_INDEX (SYS_numjoysticks - 1)
    1.14 +#define ANDROID_ACCELEROMETER_NAME "Android Accelerometer"
    1.15 +
    1.16 +static SDL_Joystick **SYS_Joysticks;
    1.17 +static char **SYS_JoystickNames;
    1.18 +static int SYS_numjoysticks;
    1.19 +static SDL_bool SYS_accelAsJoy;
    1.20 +
    1.21 +/* Function to convert Android keyCodes into SDL ones.
    1.22 + * This code manipulation is done to get a sequential list of codes.
    1.23 + */
    1.24 +int
    1.25 +keycode_to_SDL(int keycode)
    1.26 +{
    1.27 +    int final = 0;
    1.28 +    /* D-Pad key codes (API 1):
    1.29 +     * KEYCODE_DPAD_UP=19, KEYCODE_DPAD_DOWN
    1.30 +     * KEYCODE_DPAD_LEFT, KEYCODE_DPAD_RIGHT, KEYCODE_DPAD_CENTER
    1.31 +     */
    1.32 +    if(keycode < 96)
    1.33 +        return keycode-19;
    1.34 +    /* Some gamepad buttons (API 9):
    1.35 +     * KEYCODE_BUTTON_A=96, KEYCODE_BUTTON_B, KEYCODE_BUTTON_C,
    1.36 +     * KEYCODE_BUTTON_X, KEYCODE_BUTTON_Y, KEYCODE_BUTTON_Z,
    1.37 +     * KEYCODE_BUTTON_L1, KEYCODE_BUTTON_L2,
    1.38 +     * KEYCODE_BUTTON_R1, KEYCODE_BUTTON_R2,
    1.39 +     * KEYCODE_BUTTON_THUMBL, KEYCODE_BUTTON_THUMBR,
    1.40 +     * KEYCODE_BUTTON_START, KEYCODE_BUTTON_SELECT, KEYCODE_BUTTON_MODE
    1.41 +     */
    1.42 +    else if(keycode < 188)
    1.43 +        return keycode-91;
    1.44 +    /* More gamepad buttons (API 12):
    1.45 +     * KEYCODE_BUTTON_1=188 to KEYCODE_BUTTON_16
    1.46 +     */
    1.47 +    else
    1.48 +        return keycode-168;
    1.49 +}
    1.50  
    1.51  /* Function to scan the system for joysticks.
    1.52   * This function should set SDL_numjoysticks to the number of available
    1.53 @@ -43,18 +80,56 @@
    1.54  int
    1.55  SDL_SYS_JoystickInit(void)
    1.56  {
    1.57 -    return (1);
    1.58 +    int i = 0;
    1.59 +    const char *env;
    1.60 +    
    1.61 +    env = SDL_GetHint(SDL_HINT_ACCEL_AS_JOY);
    1.62 +    if (env && !SDL_atoi(env))
    1.63 +        SYS_accelAsJoy = SDL_FALSE;
    1.64 +    else
    1.65 +        SYS_accelAsJoy = SDL_TRUE; /* Default behavior */
    1.66 +    
    1.67 +    SYS_numjoysticks = Android_JNI_GetNumJoysticks();
    1.68 +    if (SYS_accelAsJoy) {
    1.69 +        SYS_numjoysticks++;
    1.70 +    }
    1.71 +    SYS_Joysticks = (SDL_Joystick **)SDL_malloc(SYS_numjoysticks*sizeof(SDL_Joystick *));
    1.72 +    if (SYS_Joysticks == NULL)
    1.73 +    {
    1.74 +        return SDL_OutOfMemory();
    1.75 +    }
    1.76 +    SYS_JoystickNames = (char **)SDL_malloc(SYS_numjoysticks*sizeof(char *));
    1.77 +    if (SYS_JoystickNames == NULL)
    1.78 +    {
    1.79 +        SDL_free(SYS_Joysticks);
    1.80 +        SYS_Joysticks = NULL;
    1.81 +        return SDL_OutOfMemory();
    1.82 +    }
    1.83 +    SDL_memset(SYS_JoystickNames, 0, (SYS_numjoysticks*sizeof(char *)));
    1.84 +    SDL_memset(SYS_Joysticks, 0, (SYS_numjoysticks*sizeof(SDL_Joystick *)));
    1.85 +    
    1.86 +    for (i = 0; i < SYS_numjoysticks; i++)
    1.87 +    {
    1.88 +        if ( SYS_accelAsJoy && i == ANDROID_ACCELEROMETER_INDEX ) {
    1.89 +            SYS_JoystickNames[i] = ANDROID_ACCELEROMETER_NAME;
    1.90 +        } else {
    1.91 +            SYS_JoystickNames[i] = Android_JNI_GetJoystickName(i);
    1.92 +        }
    1.93 +    }
    1.94 +   
    1.95 +    return (SYS_numjoysticks);
    1.96  }
    1.97  
    1.98  int SDL_SYS_NumJoysticks()
    1.99  {
   1.100 -    return 1;
   1.101 +    return SYS_numjoysticks;
   1.102  }
   1.103  
   1.104  void SDL_SYS_JoystickDetect()
   1.105  {
   1.106  }
   1.107  
   1.108 +/* TODO: Hotplugging support */
   1.109  SDL_bool SDL_SYS_JoystickNeedsPolling()
   1.110  {
   1.111      return SDL_FALSE;
   1.112 @@ -64,7 +139,7 @@
   1.113  const char *
   1.114  SDL_SYS_JoystickNameForDeviceIndex(int device_index)
   1.115  {
   1.116 -    return accelerometerName;
   1.117 +    return SYS_JoystickNames[device_index];
   1.118  }
   1.119  
   1.120  /* Function to perform the mapping from device index to the instance id for this index */
   1.121 @@ -81,11 +156,19 @@
   1.122  int
   1.123  SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
   1.124  {
   1.125 -    if (device_index == 0) {
   1.126 -        joystick->nbuttons = 0;
   1.127 +    if (device_index < SYS_numjoysticks) {
   1.128          joystick->nhats = 0;
   1.129          joystick->nballs = 0;
   1.130 -        joystick->naxes = 3;
   1.131 +        if (SYS_accelAsJoy && device_index == ANDROID_ACCELEROMETER_INDEX) {
   1.132 +            joystick->nbuttons = 0;
   1.133 +            joystick->naxes = 3;
   1.134 +        } else {
   1.135 +            /* TODO: Get the real number of buttons in the device */
   1.136 +            joystick->nbuttons = 36;
   1.137 +            joystick->naxes = Android_JNI_GetJoystickAxes(device_index);
   1.138 +        }
   1.139 +        
   1.140 +        SYS_Joysticks[device_index] = joystick;
   1.141          return 0;
   1.142      } else {
   1.143          SDL_SetError("No joystick available with that index");
   1.144 @@ -111,7 +194,8 @@
   1.145      Sint16 value;
   1.146      float values[3];
   1.147  
   1.148 -    if (Android_JNI_GetAccelerometerValues(values)) {
   1.149 +    if (SYS_accelAsJoy && Android_JNI_GetAccelerometerValues(values) &&
   1.150 +        joystick->instance_id == ANDROID_ACCELEROMETER_INDEX) {
   1.151          for ( i = 0; i < 3; i++ ) {
   1.152              value = (Sint16)(values[i] * 32767.0f);
   1.153              SDL_PrivateJoystickAxis(joystick, i, value);
   1.154 @@ -129,6 +213,10 @@
   1.155  void
   1.156  SDL_SYS_JoystickQuit(void)
   1.157  {
   1.158 +    SDL_free(SYS_JoystickNames);
   1.159 +    SDL_free(SYS_Joysticks);
   1.160 +    SYS_JoystickNames = NULL;
   1.161 +    SYS_Joysticks = NULL;
   1.162  }
   1.163  
   1.164  SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
   1.165 @@ -151,6 +239,32 @@
   1.166      return guid;
   1.167  }
   1.168  
   1.169 +int
   1.170 +Android_OnPadDown(int padId, int keycode)
   1.171 +{
   1.172 +    SDL_PrivateJoystickButton(SYS_Joysticks[padId], keycode_to_SDL(keycode), SDL_PRESSED);
   1.173 +    
   1.174 +    return 0;
   1.175 +}
   1.176 +
   1.177 +int
   1.178 +Android_OnPadUp(int padId, int keycode)
   1.179 +{
   1.180 +    SDL_PrivateJoystickButton(SYS_Joysticks[padId], keycode_to_SDL(keycode), SDL_RELEASED);
   1.181 +    
   1.182 +    return 0;
   1.183 +}
   1.184 +
   1.185 +int
   1.186 +Android_OnJoy(int joyId, int axis, float value)
   1.187 +{
   1.188 +    /* Android gives joy info normalized as [-1.0, 1.0] or [0.0, 1.0] */
   1.189 +    /* TODO: Are the reported values right? */
   1.190 +    SDL_PrivateJoystickAxis(SYS_Joysticks[joyId], axis, (Sint16) (32767.*value) );
   1.191 +    
   1.192 +    return 0;
   1.193 +}
   1.194 +
   1.195  #endif /* SDL_JOYSTICK_ANDROID */
   1.196  
   1.197  /* vi: set ts=4 sw=4 expandtab: */