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