src/joystick/android/SDL_sysjoystick.c
author Philipp Wiesemann <philipp.wiesemann@arcor.de>
Sat, 23 Nov 2013 18:29:36 +0100
changeset 8025 a867f1891d2a
parent 8024 ffbdb99af7bd
child 8057 801d84e26f91
child 8543 b9dd3cf38585
permissions -rw-r--r--
Removed include of no more needed header.
     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_assert.h"
    34 #include "../SDL_sysjoystick.h"
    35 #include "../SDL_joystick_c.h"
    36 #include "../../core/android/SDL_android.h"
    37 
    38 #include "android/keycodes.h"
    39 
    40 /* As of platform android-14, android/keycodes.h is missing these defines */
    41 #ifndef AKEYCODE_BUTTON_1
    42 #define AKEYCODE_BUTTON_1 188
    43 #define AKEYCODE_BUTTON_2 189
    44 #define AKEYCODE_BUTTON_3 190
    45 #define AKEYCODE_BUTTON_4 191
    46 #define AKEYCODE_BUTTON_5 192
    47 #define AKEYCODE_BUTTON_6 193
    48 #define AKEYCODE_BUTTON_7 194
    49 #define AKEYCODE_BUTTON_8 195
    50 #define AKEYCODE_BUTTON_9 196
    51 #define AKEYCODE_BUTTON_10 197
    52 #define AKEYCODE_BUTTON_11 198
    53 #define AKEYCODE_BUTTON_12 199
    54 #define AKEYCODE_BUTTON_13 200
    55 #define AKEYCODE_BUTTON_14 201
    56 #define AKEYCODE_BUTTON_15 202
    57 #define AKEYCODE_BUTTON_16 203
    58 #endif
    59 
    60 #define ANDROID_ACCELEROMETER_INDEX (SYS_numjoysticks - 1)
    61 #define ANDROID_ACCELEROMETER_NAME "Android Accelerometer"
    62 #define ANDROID_MAX_NBUTTONS 36
    63 
    64 static SDL_Joystick **SYS_Joysticks;
    65 static char **SYS_JoystickNames;
    66 static int SYS_numjoysticks;
    67 static SDL_bool SYS_accelAsJoy;
    68 
    69 /* Function to convert Android keyCodes into SDL ones.
    70  * This code manipulation is done to get a sequential list of codes.
    71  * FIXME: This is only suited for the case where we use a fixed number of buttons determined by ANDROID_MAX_NBUTTONS
    72  */
    73 static int
    74 keycode_to_SDL(int keycode)
    75 {
    76     /* FIXME: If this function gets too unwiedly in the future, replace with a lookup table */
    77     int button = 0;
    78     switch(keycode) 
    79     {
    80         /* D-Pad key codes (API 1), these get mapped to 0...4 */
    81         case AKEYCODE_DPAD_UP:
    82         case AKEYCODE_DPAD_DOWN:
    83         case AKEYCODE_DPAD_LEFT:
    84         case AKEYCODE_DPAD_RIGHT:
    85         case AKEYCODE_DPAD_CENTER:
    86             button = keycode - AKEYCODE_DPAD_UP;
    87             break;
    88         
    89         /* Some gamepad buttons (API 9), these get mapped to 5...19*/
    90         case AKEYCODE_BUTTON_A:
    91         case AKEYCODE_BUTTON_B:
    92         case AKEYCODE_BUTTON_C:
    93         case AKEYCODE_BUTTON_X:
    94         case AKEYCODE_BUTTON_Y:
    95         case AKEYCODE_BUTTON_Z:
    96         case AKEYCODE_BUTTON_L1:
    97         case AKEYCODE_BUTTON_L2:
    98         case AKEYCODE_BUTTON_R1:
    99         case AKEYCODE_BUTTON_R2:
   100         case AKEYCODE_BUTTON_THUMBL:
   101         case AKEYCODE_BUTTON_THUMBR:
   102         case AKEYCODE_BUTTON_START:
   103         case AKEYCODE_BUTTON_SELECT:
   104         case AKEYCODE_BUTTON_MODE:
   105             button = keycode - AKEYCODE_BUTTON_A + 5;
   106             break;
   107             
   108         
   109         /* More gamepad buttons (API 12), these get mapped to 20...35*/
   110         case AKEYCODE_BUTTON_1:
   111         case AKEYCODE_BUTTON_2:
   112         case AKEYCODE_BUTTON_3:
   113         case AKEYCODE_BUTTON_4:
   114         case AKEYCODE_BUTTON_5:
   115         case AKEYCODE_BUTTON_6:
   116         case AKEYCODE_BUTTON_7:
   117         case AKEYCODE_BUTTON_8:
   118         case AKEYCODE_BUTTON_9:
   119         case AKEYCODE_BUTTON_10:
   120         case AKEYCODE_BUTTON_11:
   121         case AKEYCODE_BUTTON_12:
   122         case AKEYCODE_BUTTON_13:
   123         case AKEYCODE_BUTTON_14:
   124         case AKEYCODE_BUTTON_15:
   125         case AKEYCODE_BUTTON_16:
   126             button = keycode - AKEYCODE_BUTTON_1 + 20;
   127             break;
   128             
   129         default:
   130             return -1;
   131             break;
   132     }
   133     
   134     /* This is here in case future generations, probably with six fingers per hand, 
   135      * happily add new cases up above and forget to update the max number of buttons. 
   136      */
   137     SDL_assert(button < ANDROID_MAX_NBUTTONS);
   138     return button;
   139     
   140 }
   141 
   142 /* Function to scan the system for joysticks.
   143  * This function should set SDL_numjoysticks to the number of available
   144  * joysticks.  Joystick 0 should be the system default joystick.
   145  * It should return 0, or -1 on an unrecoverable fatal error.
   146  */
   147 int
   148 SDL_SYS_JoystickInit(void)
   149 {
   150     int i = 0;
   151     const char *env;
   152     
   153     env = SDL_GetHint(SDL_HINT_ACCEL_AS_JOY);
   154     if (env && !SDL_atoi(env))
   155         SYS_accelAsJoy = SDL_FALSE;
   156     else
   157         SYS_accelAsJoy = SDL_TRUE; /* Default behavior */
   158     
   159     SYS_numjoysticks = Android_JNI_GetNumJoysticks();
   160     if (SYS_accelAsJoy) {
   161         SYS_numjoysticks++;
   162     }
   163     SYS_Joysticks = (SDL_Joystick **)SDL_calloc(1, SYS_numjoysticks*sizeof(SDL_Joystick *));
   164     if (SYS_Joysticks == NULL)
   165     {
   166         return SDL_OutOfMemory();
   167     }
   168     SYS_JoystickNames = (char **)SDL_calloc(1, SYS_numjoysticks*sizeof(char *));
   169     if (SYS_JoystickNames == NULL)
   170     {
   171         SDL_free(SYS_Joysticks);
   172         SYS_Joysticks = NULL;
   173         return SDL_OutOfMemory();
   174     }
   175     
   176     for (i = 0; i < SYS_numjoysticks; i++)
   177     {
   178         if ( SYS_accelAsJoy && i == ANDROID_ACCELEROMETER_INDEX ) {
   179             SYS_JoystickNames[i] = ANDROID_ACCELEROMETER_NAME;
   180         } else {
   181             SYS_JoystickNames[i] = Android_JNI_GetJoystickName(i);
   182         }
   183     }
   184    
   185     return (SYS_numjoysticks);
   186 }
   187 
   188 int SDL_SYS_NumJoysticks()
   189 {
   190     return SYS_numjoysticks;
   191 }
   192 
   193 void SDL_SYS_JoystickDetect()
   194 {
   195 }
   196 
   197 /* TODO: Hotplugging support */
   198 SDL_bool SDL_SYS_JoystickNeedsPolling()
   199 {
   200     return SDL_FALSE;
   201 }
   202 
   203 /* Function to get the device-dependent name of a joystick */
   204 const char *
   205 SDL_SYS_JoystickNameForDeviceIndex(int device_index)
   206 {
   207     return SYS_JoystickNames[device_index];
   208 }
   209 
   210 /* Function to perform the mapping from device index to the instance id for this index */
   211 SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
   212 {
   213     return device_index;
   214 }
   215 
   216 /* Function to open a joystick for use.
   217    The joystick to open is specified by the index field of the joystick.
   218    This should fill the nbuttons and naxes fields of the joystick structure.
   219    It returns 0, or -1 if there is an error.
   220  */
   221 int
   222 SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
   223 {
   224     if (device_index < SYS_numjoysticks) {
   225         joystick->nhats = 0;
   226         joystick->nballs = 0;
   227         if (SYS_accelAsJoy && device_index == ANDROID_ACCELEROMETER_INDEX) {
   228             joystick->nbuttons = 0;
   229             joystick->naxes = 3;
   230         } else {
   231             /* FIXME: Get the real number of buttons in the device? */
   232             joystick->nbuttons = ANDROID_MAX_NBUTTONS;
   233             joystick->naxes = Android_JNI_GetJoystickAxes(device_index);
   234         }
   235         
   236         SYS_Joysticks[device_index] = joystick;
   237         return 0;
   238     } else {
   239         return SDL_SetError("No joystick available with that index");
   240     }
   241 }
   242 
   243 /* Function to determine is this joystick is attached to the system right now */
   244 SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
   245 {
   246     return SDL_TRUE;
   247 }
   248 
   249 /* Function to update the state of a joystick - called as a device poll.
   250  * This function shouldn't update the joystick structure directly,
   251  * but instead should call SDL_PrivateJoystick*() to deliver events
   252  * and update joystick device state.
   253  */
   254 void
   255 SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
   256 {
   257     int i;
   258     Sint16 value;
   259     float values[3];
   260 
   261     if (SYS_accelAsJoy && Android_JNI_GetAccelerometerValues(values) &&
   262         joystick->instance_id == ANDROID_ACCELEROMETER_INDEX) {
   263         for ( i = 0; i < 3; i++ ) {
   264             value = (Sint16)(values[i] * 32767.0f);
   265             SDL_PrivateJoystickAxis(joystick, i, value);
   266         }
   267     }
   268 }
   269 
   270 /* Function to close a joystick after use */
   271 void
   272 SDL_SYS_JoystickClose(SDL_Joystick * joystick)
   273 {
   274     int device_index;
   275     
   276     for (device_index = 0; device_index < SYS_numjoysticks; device_index++) {
   277         if ( SYS_Joysticks[device_index] == joystick ) {
   278             SYS_Joysticks[device_index] = NULL;
   279         }
   280     }
   281     
   282     joystick->closed = 1;
   283 }
   284 
   285 /* Function to perform any system-specific joystick related cleanup */
   286 void
   287 SDL_SYS_JoystickQuit(void)
   288 {
   289     SDL_free(SYS_JoystickNames);
   290     SDL_free(SYS_Joysticks);
   291     SYS_JoystickNames = NULL;
   292     SYS_Joysticks = NULL;
   293 }
   294 
   295 SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
   296 {
   297     SDL_JoystickGUID guid;
   298     /* the GUID is just the first 16 chars of the name for now */
   299     const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index );
   300     SDL_zero( guid );
   301     SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
   302     return guid;
   303 }
   304 
   305 SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
   306 {
   307     SDL_JoystickGUID guid;
   308     /* the GUID is just the first 16 chars of the name for now */
   309     const char *name = joystick->name;
   310     SDL_zero( guid );
   311     SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
   312     return guid;
   313 }
   314 
   315 int
   316 Android_OnPadDown(int padId, int keycode)
   317 {
   318     int button = keycode_to_SDL(keycode);
   319     if (button >= 0) {
   320         if (SYS_Joysticks[padId]) {
   321             SDL_PrivateJoystickButton(SYS_Joysticks[padId], button , SDL_PRESSED);
   322         }
   323         return 0;
   324     }
   325     
   326     return -1;
   327 }
   328 
   329 int
   330 Android_OnPadUp(int padId, int keycode)
   331 {
   332     int button = keycode_to_SDL(keycode);
   333     if (button >= 0) {
   334         if (SYS_Joysticks[padId]) {
   335             SDL_PrivateJoystickButton(SYS_Joysticks[padId], button, SDL_RELEASED);
   336         }
   337         return 0;
   338     }
   339     
   340     return -1;
   341 }
   342 
   343 int
   344 Android_OnJoy(int joyId, int axis, float value)
   345 {
   346     /* Android gives joy info normalized as [-1.0, 1.0] or [0.0, 1.0] */
   347     /* TODO: Are the reported values right? */
   348     if (SYS_Joysticks[joyId]) {
   349         SDL_PrivateJoystickAxis(SYS_Joysticks[joyId], axis, (Sint16) (32767.*value) );
   350     }
   351     
   352     return 0;
   353 }
   354 
   355 #endif /* SDL_JOYSTICK_ANDROID */
   356 
   357 /* vi: set ts=4 sw=4 expandtab: */