project_files/Android-build/SDL-android-project/jni/SDL/src/core/android/SDL_android.cpp
branchhedgeroid
changeset 5337 16477d1c12b1
child 5389 b3cc5b4099f1
equal deleted inserted replaced
5335:cd9b7b170fbf 5337:16477d1c12b1
       
     1 /*
       
     2     SDL - Simple DirectMedia Layer
       
     3     Copyright (C) 1997-2011 Sam Lantinga
       
     4 
       
     5     This library is free software; you can redistribute it and/or
       
     6     modify it under the terms of the GNU Lesser General Public
       
     7     License as published by the Free Software Foundation; either
       
     8     version 2.1 of the License, or (at your option) any later version.
       
     9 
       
    10     This library is distributed in the hope that it will be useful,
       
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    13     Lesser General Public License for more details.
       
    14 
       
    15     You should have received a copy of the GNU Lesser General Public
       
    16     License along with this library; if not, write to the Free Software
       
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
       
    18 
       
    19     Sam Lantinga
       
    20     slouken@libsdl.org
       
    21 */
       
    22 #include "SDL_config.h"
       
    23 #include "SDL_stdinc.h"
       
    24 
       
    25 #include "SDL_android.h"
       
    26 
       
    27 extern "C" {
       
    28 #include "../../events/SDL_events_c.h"
       
    29 #include "../../video/android/SDL_androidkeyboard.h"
       
    30 #include "../../video/android/SDL_androidtouch.h"
       
    31 #include "../../video/android/SDL_androidvideo.h"
       
    32 
       
    33 /* Impelemented in audio/android/SDL_androidaudio.c */
       
    34 extern void Android_RunAudioThread();
       
    35 } // C
       
    36 
       
    37 /*******************************************************************************
       
    38  This file links the Java side of Android with libsdl
       
    39 *******************************************************************************/
       
    40 #include <jni.h>
       
    41 #include <android/log.h>
       
    42 
       
    43 
       
    44 /*******************************************************************************
       
    45                                Globals
       
    46 *******************************************************************************/
       
    47 static JNIEnv* mEnv = NULL;
       
    48 static JNIEnv* mAudioEnv = NULL;
       
    49 
       
    50 // Main activity
       
    51 static jclass mActivityClass;
       
    52 
       
    53 // method signatures
       
    54 static jmethodID midCreateGLContext;
       
    55 static jmethodID midFlipBuffers;
       
    56 static jmethodID midAudioInit;
       
    57 static jmethodID midAudioWriteShortBuffer;
       
    58 static jmethodID midAudioWriteByteBuffer;
       
    59 static jmethodID midAudioQuit;
       
    60 
       
    61 // Accelerometer data storage
       
    62 static float fLastAccelerometer[3];
       
    63 
       
    64 
       
    65 /*******************************************************************************
       
    66                  Functions called by JNI
       
    67 *******************************************************************************/
       
    68 
       
    69 // Library init
       
    70 extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
       
    71 {
       
    72     return JNI_VERSION_1_4;
       
    73 }
       
    74 
       
    75 // Called before SDL_main() to initialize JNI bindings
       
    76 extern "C" void SDL_Android_Init(JNIEnv* env, jclass cls)
       
    77 {
       
    78     __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL_Android_Init()");
       
    79 
       
    80     mEnv = env;
       
    81     mActivityClass = cls;
       
    82 
       
    83     midCreateGLContext = mEnv->GetStaticMethodID(mActivityClass,
       
    84                                 "createGLContext","(II)Z");
       
    85     midFlipBuffers = mEnv->GetStaticMethodID(mActivityClass,
       
    86                                 "flipBuffers","()V");
       
    87     midAudioInit = mEnv->GetStaticMethodID(mActivityClass, 
       
    88                                 "audioInit", "(IZZI)Ljava/lang/Object;");
       
    89     midAudioWriteShortBuffer = mEnv->GetStaticMethodID(mActivityClass,
       
    90                                 "audioWriteShortBuffer", "([S)V");
       
    91     midAudioWriteByteBuffer = mEnv->GetStaticMethodID(mActivityClass,
       
    92                                 "audioWriteByteBuffer", "([B)V");
       
    93     midAudioQuit = mEnv->GetStaticMethodID(mActivityClass,
       
    94                                 "audioQuit", "()V");
       
    95 
       
    96     if(!midCreateGLContext || !midFlipBuffers || !midAudioInit ||
       
    97        !midAudioWriteShortBuffer || !midAudioWriteByteBuffer || !midAudioQuit) {
       
    98         __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL: Couldn't locate Java callbacks, check that they're named and typed correctly");
       
    99     }
       
   100 }
       
   101 
       
   102 // Resize
       
   103 extern "C" void Java_org_hedgewars_SDLActivity_onNativeResize(
       
   104                                     JNIEnv* env, jclass jcls,
       
   105                                     jint width, jint height, jint format)
       
   106 {
       
   107     Android_SetScreenResolution(width, height, format);
       
   108 }
       
   109 
       
   110 // Keydown
       
   111 extern "C" void Java_org_hedgewars_SDLActivity_onNativeKeyDown(
       
   112                                     JNIEnv* env, jclass jcls, jint keycode)
       
   113 {
       
   114     Android_OnKeyDown(keycode);
       
   115 }
       
   116 
       
   117 // Keyup
       
   118 extern "C" void Java_org_hedgewars_SDLActivity_onNativeKeyUp(
       
   119                                     JNIEnv* env, jclass jcls, jint keycode)
       
   120 {
       
   121     Android_OnKeyUp(keycode);
       
   122 }
       
   123 
       
   124 // Touch
       
   125 extern "C" void Java_org_hedgewars_SDLActivity_onNativeTouch(
       
   126                                     JNIEnv* env, jclass jcls,
       
   127                                     jint action, jfloat x, jfloat y, jfloat p)
       
   128 {
       
   129     Android_OnTouch(action, x, y, p);
       
   130 }
       
   131 
       
   132 // Accelerometer
       
   133 extern "C" void Java_org_hedgewars_SDLActivity_onNativeAccel(
       
   134                                     JNIEnv* env, jclass jcls,
       
   135                                     jfloat x, jfloat y, jfloat z)
       
   136 {
       
   137     fLastAccelerometer[0] = x;
       
   138     fLastAccelerometer[1] = y;
       
   139     fLastAccelerometer[2] = z;   
       
   140 }
       
   141 
       
   142 // Quit
       
   143 extern "C" void Java_org_hedgewars_SDLActivity_nativeQuit(
       
   144                                     JNIEnv* env, jclass cls)
       
   145 {    
       
   146     // Inject a SDL_QUIT event
       
   147     SDL_SendQuit();
       
   148 }
       
   149 
       
   150 extern "C" void Java_org_hedgewars_SDLActivity_nativeRunAudioThread(
       
   151                                     JNIEnv* env, jclass cls)
       
   152 {
       
   153     /* This is the audio thread, with a different environment */
       
   154     mAudioEnv = env;
       
   155 
       
   156     Android_RunAudioThread();
       
   157 }
       
   158 
       
   159 
       
   160 /*******************************************************************************
       
   161              Functions called by SDL into Java
       
   162 *******************************************************************************/
       
   163 extern "C" SDL_bool Android_JNI_CreateContext(int majorVersion, int minorVersion)
       
   164 {
       
   165     if (mEnv->CallStaticBooleanMethod(mActivityClass, midCreateGLContext, majorVersion, minorVersion)) {
       
   166         return SDL_TRUE;
       
   167     } else {
       
   168         return SDL_FALSE;
       
   169     }
       
   170 }
       
   171 
       
   172 extern "C" void Android_JNI_SwapWindow()
       
   173 {
       
   174     mEnv->CallStaticVoidMethod(mActivityClass, midFlipBuffers); 
       
   175 }
       
   176 
       
   177 extern "C" void Android_JNI_SetActivityTitle(const char *title)
       
   178 {
       
   179     jmethodID mid;
       
   180 
       
   181     mid = mEnv->GetStaticMethodID(mActivityClass,"setActivityTitle","(Ljava/lang/String;)V");
       
   182     if (mid) {
       
   183         mEnv->CallStaticVoidMethod(mActivityClass, mid, mEnv->NewStringUTF(title));
       
   184     }
       
   185 }
       
   186 
       
   187 extern "C" void Android_JNI_GetAccelerometerValues(float values[3])
       
   188 {
       
   189     int i;
       
   190     for (i = 0; i < 3; ++i) {
       
   191         values[i] = fLastAccelerometer[i];
       
   192     }
       
   193 }
       
   194 
       
   195 //
       
   196 // Audio support
       
   197 //
       
   198 static jboolean audioBuffer16Bit = JNI_FALSE;
       
   199 static jboolean audioBufferStereo = JNI_FALSE;
       
   200 static jobject audioBuffer = NULL;
       
   201 static void* audioBufferPinned = NULL;
       
   202 
       
   203 extern "C" int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames)
       
   204 {
       
   205     int audioBufferFrames;
       
   206 
       
   207     __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device");
       
   208     audioBuffer16Bit = is16Bit;
       
   209     audioBufferStereo = channelCount > 1;
       
   210 
       
   211     audioBuffer = mEnv->CallStaticObjectMethod(mActivityClass, midAudioInit, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames);
       
   212 
       
   213     if (audioBuffer == NULL) {
       
   214         __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: didn't get back a good audio buffer!");
       
   215         return 0;
       
   216     }
       
   217     audioBuffer = mEnv->NewGlobalRef(audioBuffer);
       
   218 
       
   219     jboolean isCopy = JNI_FALSE;
       
   220     if (audioBuffer16Bit) {
       
   221         audioBufferPinned = mEnv->GetShortArrayElements((jshortArray)audioBuffer, &isCopy);
       
   222         audioBufferFrames = mEnv->GetArrayLength((jshortArray)audioBuffer);
       
   223     } else {
       
   224         audioBufferPinned = mEnv->GetByteArrayElements((jbyteArray)audioBuffer, &isCopy);
       
   225         audioBufferFrames = mEnv->GetArrayLength((jbyteArray)audioBuffer);
       
   226     }
       
   227     if (audioBufferStereo) {
       
   228         audioBufferFrames /= 2;
       
   229     }
       
   230 
       
   231     return audioBufferFrames;
       
   232 }
       
   233 
       
   234 extern "C" void * Android_JNI_GetAudioBuffer()
       
   235 {
       
   236     return audioBufferPinned;
       
   237 }
       
   238 
       
   239 extern "C" void Android_JNI_WriteAudioBuffer()
       
   240 {
       
   241     if (audioBuffer16Bit) {
       
   242         mAudioEnv->ReleaseShortArrayElements((jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT);
       
   243         mAudioEnv->CallStaticVoidMethod(mActivityClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer);
       
   244     } else {
       
   245         mAudioEnv->ReleaseByteArrayElements((jbyteArray)audioBuffer, (jbyte *)audioBufferPinned, JNI_COMMIT);
       
   246         mAudioEnv->CallStaticVoidMethod(mActivityClass, midAudioWriteByteBuffer, (jbyteArray)audioBuffer);
       
   247     }
       
   248 
       
   249     /* JNI_COMMIT means the changes are committed to the VM but the buffer remains pinned */
       
   250 }
       
   251 
       
   252 extern "C" void Android_JNI_CloseAudioDevice()
       
   253 {
       
   254     mEnv->CallStaticVoidMethod(mActivityClass, midAudioQuit); 
       
   255 
       
   256     if (audioBuffer) {
       
   257         mEnv->DeleteGlobalRef(audioBuffer);
       
   258         audioBuffer = NULL;
       
   259         audioBufferPinned = NULL;
       
   260     }
       
   261 }
       
   262 
       
   263 /* vi: set ts=4 sw=4 expandtab: */