diff -r afef68703f54 Android.mk --- a/Android.mk Mon Jan 21 09:16:27 2013 -0800 +++ b/Android.mk Mon Jan 21 22:06:43 2013 +0100 @@ -42,6 +42,6 @@ $(wildcard $(LOCAL_PATH)/src/video/android/*.c)) LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -LOCAL_LDLIBS := -ldl -lGLESv1_CM -lGLESv2 -llog +LOCAL_LDLIBS := -ldl -lGLESv1_CM -lGLESv2 -llog -landroid include $(BUILD_SHARED_LIBRARY) diff -r afef68703f54 android-project/src/org/libsdl/app/SDLActivity.java --- a/android-project/src/org/libsdl/app/SDLActivity.java Mon Jan 21 09:16:27 2013 -0800 +++ b/android-project/src/org/libsdl/app/SDLActivity.java Mon Jan 21 22:06:43 2013 +0100 @@ -24,6 +24,8 @@ import android.content.*; import java.lang.*; +import java.util.List; +import java.util.ArrayList; /** @@ -43,6 +45,10 @@ // This is what SDL runs in. It invokes SDL_main(), eventually private static Thread mSDLThread; + // Joystick + private static boolean mJoyListCreated; + private static List mJoyIdList; + // Audio private static Thread mAudioThread; private static AudioTrack mAudioTrack; @@ -156,6 +162,10 @@ public static native void nativePause(); public static native void nativeResume(); public static native void onNativeResize(int x, int y, int format); + public static native void onNativePadDown(int padId, int keycode); + public static native void onNativePadUp(int padId, int keycode); + public static native void onNativeJoy(int joyId, int action, + float x, float y); public static native void onNativeKeyDown(int keycode); public static native void onNativeKeyUp(int keycode); public static native void onNativeTouch(int touchDevId, int pointerFingerId, @@ -180,6 +190,57 @@ mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title); } + // Create a list of valid ID's the first time this function is called + private static void createJoystickList() { + if(mJoyListCreated) { + return; + } + + mJoyIdList = new ArrayList(); + // InputDevice.getDeviceIds requires SDK >= 16 + if(Build.VERSION.SDK_INT >= 16) { + int[] deviceIds = InputDevice.getDeviceIds(); + for(int i=0; i #include +#include /******************************************************************************* @@ -147,6 +149,27 @@ Android_SetScreenResolution(width, height, format); } +// Paddown +extern "C" void Java_org_libsdl_app_SDLActivity_onNativePadDown( + JNIEnv* env, jclass jcls, jint padId, jint keycode) +{ + Android_OnPadDown(padId, keycode); +} + +// Padup +extern "C" void Java_org_libsdl_app_SDLActivity_onNativePadUp( + JNIEnv* env, jclass jcls, jint padId, jint keycode) +{ + Android_OnPadUp(padId, keycode); +} + +// Joysticks +extern "C" void Java_org_libsdl_app_SDLActivity_onNativeJoy( + JNIEnv* env, jclass jcls, jint joyId, jint action, jfloat x, jfloat y) +{ + Android_OnJoy(joyId, action, x, y); +} + // Keydown extern "C" void Java_org_libsdl_app_SDLActivity_onNativeKeyDown( JNIEnv* env, jclass jcls, jint keycode) @@ -1084,6 +1119,67 @@ return 0; } +// return the total number of plugged in joysticks +extern "C" int Android_JNI_GetNumJoysticks() +{ + JNIEnv* env = Android_JNI_GetEnv(); + if (!env) { + return -1; + } + jmethodID mid = env->GetStaticMethodID(mActivityClass, "getNumJoysticks", "()I"); + if (!mid) { + return -1; + } + return env->CallIntMethod(mActivityClass, mid); +} + +// Return the name of joystick number "index" +extern "C" char* Android_JNI_GetJoystickName(int index) +{ + JNIEnv* env = Android_JNI_GetEnv(); + if (!env) { + return SDL_strdup(""); + } + + jmethodID mid = env->GetStaticMethodID(mActivityClass, "getJoystickName", "(I)Ljava/lang/String;"); + if (!mid) { + return SDL_strdup(""); + } + jstring string = reinterpret_cast(env->CallStaticObjectMethod(mActivityClass, mid, index)); + const char* utf = env->GetStringUTFChars(string, 0); + if (!utf) { + return SDL_strdup(""); + } + + char* text = SDL_strdup(utf); + env->ReleaseStringUTFChars(string, utf); + return text; +} + +// return the number of axes in the given joystick +extern "C" int Android_JNI_GetJoystickAxes(int index) +{ + JNIEnv* env = Android_JNI_GetEnv(); + if (!env) { + return -1; + } + jmethodID mid = env->GetStaticMethodID(mActivityClass, "getJoystickAxes", "(I)I"); + if (!mid) { + return -1; + } + return env->CallIntMethod(mActivityClass, mid, index); +} + +// Return the name of the default accelerometer +// This is much easier to be done with NDK than with JNI +extern "C" char* Android_GetAccelName() +{ + ASensorManager* mSensorManager = ASensorManager_getInstance(); + ASensor const* mAccelerometer = ASensorManager_getDefaultSensor(mSensorManager, ASENSOR_TYPE_ACCELEROMETER); + + return SDL_strdup(ASensor_getName(mAccelerometer)); +} + // sends message to be handled on the UI event dispatch thread extern "C" int Android_JNI_SendMessage(int command, int param) { diff -r afef68703f54 src/core/android/SDL_android.h --- a/src/core/android/SDL_android.h Mon Jan 21 09:16:27 2013 -0800 +++ b/src/core/android/SDL_android.h Mon Jan 21 22:06:43 2013 +0100 @@ -60,6 +60,12 @@ /* Power support */ int Android_JNI_GetPowerInfo(int* plugged, int* charged, int* battery, int* seconds, int* percent); +/* Joystick/accelerometer support */ +int Android_JNI_GetNumJoysticks(); +char* Android_JNI_GetJoystickName(int i); +int Android_JNI_GetJoystickAxes(int index); +char* Android_GetAccelName(); + // Threads #include static void Android_JNI_ThreadDestroyed(void*); diff -r afef68703f54 src/joystick/android/SDL_androidjoystick.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/joystick/android/SDL_androidjoystick.c Mon Jan 21 22:06:43 2013 +0100 @@ -0,0 +1,252 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_config.h" + +#ifdef SDL_JOYSTICK_ANDROID + +/* This is the system specific header for the SDL joystick API */ +#include /* For the definition of NULL */ + +#include "SDL_error.h" +#include "SDL_events.h" +#include "SDL_joystick.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" +#include "../../core/android/SDL_android.h" + +#define MAX_JOYSTICKS 8 + +//HACK!! +static SDL_Joystick *SYS_Joysticks[MAX_JOYSTICKS]; +static char *SYS_JoystickNames[MAX_JOYSTICKS]; +static int SYS_numjoysticks; + +/* Function to convert Android keyCodes into SDL ones. + * This code manipulation is done to get a sequential list of codes. + */ +int +keycode_to_SDL(int keycode) +{ + if(keycode < 96) + return keycode-19; + else if(keycode < 188) + return keycode-91; + else + return keycode-168; +} + +/* Function to scan the system for joysticks. + * This function should set SYS_numjoysticks to the number of available + * joysticks. Joystick 0 should be the system default joystick. + * It should return 0, or -1 on an unrecoverable fatal error. + */ +int +SDL_SYS_JoystickInit(void) +{ + int i = 0; + // The latest entry is for the accelerometer + // TODO: handle the case where SYS_numjoysticks > MAX_JOYSTICKS + SYS_numjoysticks = Android_JNI_GetNumJoysticks()+1; + SDL_memset(SYS_JoystickNames, 0, (sizeof SYS_JoystickNames)); + SDL_memset(SYS_Joysticks, 0, (sizeof SYS_Joysticks)); + + for (i = 0; i < (SYS_numjoysticks-1); i++) + { + SYS_JoystickNames[i] = Android_JNI_GetJoystickName(i); + } + SYS_JoystickNames[i] = Android_GetAccelName(); + + return (SYS_numjoysticks); +} + +int SDL_SYS_NumJoysticks() +{ + return SYS_numjoysticks; +} + +void SDL_SYS_JoystickDetect() +{ +} + +SDL_bool SDL_SYS_JoystickNeedsPolling() +{ + return SDL_FALSE; +} + +/* Function to get the device-dependent name of a joystick */ +const char * +SDL_SYS_JoystickNameForDeviceIndex(int device_index) +{ + return SYS_JoystickNames[device_index]; +} + +/* Function to perform the mapping from device index to the instance id for this index */ +SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index) +{ + return device_index; +} + +/* Function to open a joystick for use. + The joystick to open is specified by the index field of the joystick. + This should fill the nbuttons and naxes fields of the joystick structure. + It returns 0, or -1 if there is an error. + */ +int +SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) +{ + // Handle the accelerometer separately + if( device_index < (SYS_numjoysticks-1) ) + { + // TODO: How to get the rest of the info?? + // 36 is the maximum number of handled buttons + joystick->nbuttons = 36; + joystick->nhats = 0; + joystick->nballs = 0; + joystick->naxes = Android_JNI_GetJoystickAxes(device_index); + } + else if( device_index == (SYS_numjoysticks-1) ) + { + joystick->nbuttons = 0; + joystick->nhats = 0; + joystick->nballs = 0; + joystick->naxes = 3; + } + else + { + return -1; + } + + // Extremely hacky + SYS_Joysticks[device_index] = joystick; + + return 0; +} + + +/* Function to update the state of a joystick - called as a device poll. + * This function shouldn't update the joystick structure directly, + * but instead should call SDL_PrivateJoystick*() to deliver events + * and update joystick device state. + */ +void +SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) +{ + int i; + Sint16 value; + float values[3]; + + if( joystick->instance_id == (SYS_numjoysticks-1) ) + { + if (Android_JNI_GetAccelerometerValues(values)) + { + for ( i = 0; i < 3; i++ ) + { + value = (Sint16)(values[i] * 32767.0f); + SDL_PrivateJoystickAxis(joystick, i, value); + } + } + } +} + +/* Function to determine is this joystick is attached to the system right now */ +SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick) +{ + return SDL_TRUE; +} + +/* Function to close a joystick after use */ +void +SDL_SYS_JoystickClose(SDL_Joystick * joystick) +{ +} + +/* Function to perform any system-specific joystick related cleanup */ +void +SDL_SYS_JoystickQuit(void) +{ + int i; + + for (i = 0; iname; + SDL_zero( guid ); + SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); + return guid; +} + +int +Android_OnPadDown(int padId, int keycode) +{ + SDL_PrivateJoystickButton(SYS_Joysticks[padId], keycode_to_SDL(keycode), SDL_PRESSED); + + return 0; +} + +int +Android_OnPadUp(int padId, int keycode) +{ + SDL_PrivateJoystickButton(SYS_Joysticks[padId], keycode_to_SDL(keycode), SDL_RELEASED); + + return 0; +} + +int +Android_OnJoy(int joyId, int action, float x, float y) +{ + // Android gives joy info normalized as [-1.0, 1.0] + // TODO: Are the reported values right? + SDL_PrivateJoystickAxis(SYS_Joysticks[joyId], 0, (Sint16) (32767.*x) ); + SDL_PrivateJoystickAxis(SYS_Joysticks[joyId], 1, (Sint16) (32767.*y) ); + + return 0; +} + +#endif /* SDL_JOYSTICK_ANDROID */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r afef68703f54 src/joystick/android/SDL_androidjoystick.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/joystick/android/SDL_androidjoystick.h Mon Jan 21 22:06:43 2013 +0100 @@ -0,0 +1,27 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_config.h" + +extern int Android_OnPadDown(int padId, int keycode); +extern int Android_OnPadUp(int padId, int keycode); +extern int Android_OnJoy(int joyId, int action, float x, float y); + +/* vi: set ts=4 sw=4 expandtab: */ diff -r afef68703f54 src/joystick/android/SDL_sysjoystick.c --- a/src/joystick/android/SDL_sysjoystick.c Mon Jan 21 09:16:27 2013 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,156 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2012 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "SDL_config.h" - -#ifdef SDL_JOYSTICK_ANDROID - -/* This is the system specific header for the SDL joystick API */ -#include /* For the definition of NULL */ - -#include "SDL_error.h" -#include "SDL_events.h" -#include "SDL_joystick.h" -#include "../SDL_sysjoystick.h" -#include "../SDL_joystick_c.h" -#include "../../core/android/SDL_android.h" - -static const char *accelerometerName = "Android accelerometer"; - -/* Function to scan the system for joysticks. - * This function should set SDL_numjoysticks to the number of available - * joysticks. Joystick 0 should be the system default joystick. - * It should return 0, or -1 on an unrecoverable fatal error. - */ -int -SDL_SYS_JoystickInit(void) -{ - return (1); -} - -int SDL_SYS_NumJoysticks() -{ - return 1; -} - -void SDL_SYS_JoystickDetect() -{ -} - -SDL_bool SDL_SYS_JoystickNeedsPolling() -{ - return SDL_FALSE; -} - -/* Function to get the device-dependent name of a joystick */ -const char * -SDL_SYS_JoystickNameForDeviceIndex(int device_index) -{ - return accelerometerName; -} - -/* Function to perform the mapping from device index to the instance id for this index */ -SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index) -{ - return device_index; -} - -/* Function to open a joystick for use. - The joystick to open is specified by the index field of the joystick. - This should fill the nbuttons and naxes fields of the joystick structure. - It returns 0, or -1 if there is an error. - */ -int -SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) -{ - if (device_index == 0) { - joystick->nbuttons = 0; - joystick->nhats = 0; - joystick->nballs = 0; - joystick->naxes = 3; - return 0; - } else { - SDL_SetError("No joystick available with that index"); - return (-1); - } -} - -/* Function to determine is this joystick is attached to the system right now */ -SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick) -{ - return SDL_TRUE; -} - -/* Function to update the state of a joystick - called as a device poll. - * This function shouldn't update the joystick structure directly, - * but instead should call SDL_PrivateJoystick*() to deliver events - * and update joystick device state. - */ -void -SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) -{ - int i; - Sint16 value; - float values[3]; - - if (Android_JNI_GetAccelerometerValues(values)) { - for ( i = 0; i < 3; i++ ) { - value = (Sint16)(values[i] * 32767.0f); - SDL_PrivateJoystickAxis(joystick, i, value); - } - } -} - -/* Function to close a joystick after use */ -void -SDL_SYS_JoystickClose(SDL_Joystick * joystick) -{ -} - -/* Function to perform any system-specific joystick related cleanup */ -void -SDL_SYS_JoystickQuit(void) -{ -} - -SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index ) -{ - SDL_JoystickGUID guid; - // the GUID is just the first 16 chars of the name for now - const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index ); - SDL_zero( guid ); - SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); - return guid; -} - -SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick) -{ - SDL_JoystickGUID guid; - // the GUID is just the first 16 chars of the name for now - const char *name = joystick->name; - SDL_zero( guid ); - SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); - return guid; -} - -#endif /* SDL_JOYSTICK_ANDROID */ - -/* vi: set ts=4 sw=4 expandtab: */