Mercurial > sdl-ios-xcode
diff android/project/jni/android-support.cpp @ 4726:9076cdb027af
Cleanups.
- Moved to 'project' instead of 'testproject'
- Removed extraneous .c files
- Removed the android_libs folder (that was against the NDK agreement anyway)
author | Paul Hunkin <paul@bieh.net> |
---|---|
date | Tue, 17 Aug 2010 15:35:56 +1200 |
parents | |
children | 4f40b11e1045 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/android/project/jni/android-support.cpp Tue Aug 17 15:35:56 2010 +1200 @@ -0,0 +1,242 @@ +/******************************************************************************* + This file links the Java side of Android with libsdl +*******************************************************************************/ +#include <jni.h> +#include <sys/time.h> +#include <time.h> +#include <android/log.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <pthread.h> + +#define DEBUG + + +/******************************************************************************* + Globals +*******************************************************************************/ +static long _getTime(void){ + struct timeval now; + gettimeofday(&now, NULL); + return (long)(now.tv_sec*1000 + now.tv_usec/1000); +} + +JNIEnv* mEnv = NULL; +JNIEnv* mAudioThreadEnv = NULL; //See the note below for why this is necessary +JavaVM* mVM = NULL; + +//Main activity +jclass mActivityInstance; + +//method signatures +jmethodID midCreateGLContext; +jmethodID midFlipBuffers; +jmethodID midEnableFeature; +jmethodID midUpdateAudio; + +extern "C" int SDL_main(); +extern "C" int Android_OnKeyDown(int keycode); +extern "C" int Android_OnKeyUp(int keycode); +extern "C" void Android_SetScreenResolution(int width, int height); +extern "C" void Android_OnResize(int width, int height, int format); +extern "C" int SDL_SendQuit(); +extern "C" void Android_EnableFeature(int featureid, bool enabled); + +//If we're not the active app, don't try to render +bool bRenderingEnabled = false; + +//Feature IDs +static const int FEATURE_AUDIO = 1; +static const int FEATURE_ACCEL = 2; + +//Accelerometer data storage +float fLastAccelerometer[3]; + + +/******************************************************************************* + Functions called by JNI +*******************************************************************************/ + +//Library init +extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved){ + + JNIEnv* env = NULL; + jint result = -1; + + if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { + return result; + } + + mEnv = env; + + __android_log_print(ANDROID_LOG_INFO, "SDL", "JNI: OnLoad"); + + jclass cls = mEnv->FindClass ("org/libsdl/app/SDLActivity"); + mActivityInstance = cls; + midCreateGLContext = mEnv->GetStaticMethodID(cls,"createGLContext","()V"); + midFlipBuffers = mEnv->GetStaticMethodID(cls,"flipBuffers","()V"); + midEnableFeature = mEnv->GetStaticMethodID(cls,"enableFeature","(II)V"); + midUpdateAudio = mEnv->GetStaticMethodID(cls,"updateAudio","([B)V"); + + if(!midCreateGLContext || !midFlipBuffers || !midEnableFeature || + !midUpdateAudio){ + __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Bad mids\n"); + }else{ +#ifdef DEBUG + __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Good mids\n"); +#endif + } + + return JNI_VERSION_1_4; +} + +//Start up the SDL app +extern "C" void Java_org_libsdl_app_SDLActivity_nativeInit( JNIEnv* env, + jobject obj ){ + + __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Native Init"); + + mEnv = env; + bRenderingEnabled = true; + + Android_EnableFeature(FEATURE_ACCEL, true); + + SDL_main(); +} + +//Keydown +extern "C" void Java_org_libsdl_app_SDLActivity_onNativeKeyDown(JNIEnv* env, + jobject obj, jint keycode){ + + int r = Android_OnKeyDown(keycode); +#ifdef DEBUG + __android_log_print(ANDROID_LOG_INFO, "SDL", + "SDL: native key down %d, %d\n", keycode, r); +#endif + +} + +//Keyup +extern "C" void Java_org_libsdl_app_SDLActivity_onNativeKeyUp(JNIEnv* env, + jobject obj, jint keycode){ + + int r = Android_OnKeyUp(keycode); +#ifdef DEBUG + __android_log_print(ANDROID_LOG_INFO, "SDL", + "SDL: native key up %d, %d\n", keycode, r); +#endif + +} + +//Touch +extern "C" void Java_org_libsdl_app_SDLActivity_onNativeTouch(JNIEnv* env, + jobject obj, jint action, jfloat x, jfloat y, jfloat p){ + +#ifdef DEBUG + __android_log_print(ANDROID_LOG_INFO, "SDL", + "SDL: native touch event %d @ %f/%f, pressure %f\n", + action, x, y, p); +#endif + + //TODO: Pass this off to the SDL multitouch stuff + +} + +//Quit +extern "C" void Java_org_libsdl_app_SDLActivity_nativeQuit( JNIEnv* env, + jobject obj ){ + + //Stop rendering as we're no longer in the foreground + bRenderingEnabled = false; + + //Inject a SDL_QUIT event + int r = SDL_SendQuit(); + + __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Native quit %d", r); +} + +//Screen size +extern "C" void Java_org_libsdl_app_SDLActivity_nativeSetScreenSize( + JNIEnv* env, jobject obj, jint width, jint height){ + + __android_log_print(ANDROID_LOG_INFO, "SDL", + "SDL: Set screen size on init: %d/%d\n", width, height); + Android_SetScreenResolution(width, height); + +} + +//Resize +extern "C" void Java_org_libsdl_app_SDLActivity_onNativeResize( + JNIEnv* env, jobject obj, jint width, + jint height, jint format){ + Android_OnResize(width, height, format); +} + +extern "C" void Java_org_libsdl_app_SDLActivity_onNativeAccel( + JNIEnv* env, jobject obj, + jfloat x, jfloat y, jfloat z){ + fLastAccelerometer[0] = x; + fLastAccelerometer[1] = y; + fLastAccelerometer[2] = z; +} + + + +/******************************************************************************* + Functions called by SDL into Java +*******************************************************************************/ +extern "C" void Android_CreateContext(){ + __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: sdl_create_context()\n"); + + bRenderingEnabled = true; + + mEnv->CallStaticVoidMethod(mActivityInstance, midCreateGLContext ); +} + +extern "C" void Android_Render(){ + + if(!bRenderingEnabled){ + return; + } + + //When we get here, we've accumulated a full frame + mEnv->CallStaticVoidMethod(mActivityInstance, midFlipBuffers ); +} + +extern "C" void Android_EnableFeature(int featureid, bool enabled){ + + mEnv->CallStaticVoidMethod(mActivityInstance, midEnableFeature, + featureid, (int)enabled); +} + +extern "C" void Android_UpdateAudioBuffer(unsigned char *buf, int len){ + + //Annoyingly we can't just call into Java from any thread. Because the audio + //callback is dispatched from the SDL audio thread (that wasn't made from + //java, we have to do some magic here to let the JVM know about the thread. + //Because everything it touches on the Java side is static anyway, it's + //not a big deal, just annoying. + if(!mAudioThreadEnv){ + __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Need to set up audio thread env\n"); + + mVM->AttachCurrentThread(&mAudioThreadEnv, NULL); + + __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: ok\n"); + } + + jbyteArray arr = mAudioThreadEnv->NewByteArray(len); + + //blah. We probably should rework this so we avoid the copy. + mAudioThreadEnv->SetByteArrayRegion(arr, 0, len, (jbyte *)buf); + + __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: copied\n"); + + mAudioThreadEnv->CallStaticVoidMethod( mActivityInstance, + midUpdateAudio, arr ); + + __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: invoked\n"); + +} +