comparison src/SDL_android.cpp @ 4964:6c645018741e

Build the SDL library as a shared object on Android, so it will work correctly with SDL_image and SDL_ttf.
author Sam Lantinga <slouken@libsdl.org>
date Thu, 06 Jan 2011 16:11:21 -0800
parents
children d9fdff945ec9
comparison
equal deleted inserted replaced
4963:604077962776 4964:6c645018741e
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2010 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
24 /*******************************************************************************
25 This file links the Java side of Android with libsdl
26 *******************************************************************************/
27 #include <jni.h>
28 #include <android/log.h>
29
30
31 /*******************************************************************************
32 Globals
33 *******************************************************************************/
34 JavaVM* mVM = NULL;
35 JNIEnv* mEnv = NULL;
36 JNIEnv* mAudioThreadEnv = NULL; //See the note below for why this is necessary
37
38 //Main activity
39 jclass mActivityInstance;
40
41 //method signatures
42 jmethodID midCreateGLContext;
43 jmethodID midFlipBuffers;
44 jmethodID midEnableFeature;
45 jmethodID midUpdateAudio;
46
47 extern "C" int Android_OnKeyDown(int keycode);
48 extern "C" int Android_OnKeyUp(int keycode);
49 extern "C" void Android_SetScreenResolution(int width, int height);
50 extern "C" void Android_OnResize(int width, int height, int format);
51 extern "C" int SDL_SendQuit();
52 extern "C" void Android_EnableFeature(int featureid, bool enabled);
53
54 //If we're not the active app, don't try to render
55 bool bRenderingEnabled = false;
56
57 //Feature IDs
58 static const int FEATURE_AUDIO = 1;
59 static const int FEATURE_ACCEL = 2;
60
61 //Accelerometer data storage
62 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 mVM = vm;
73
74 return JNI_VERSION_1_4;
75 }
76
77 // Called before SDL_main() to initialize JNI bindings
78 extern "C" void SDL_Android_Init(JNIEnv* env)
79 {
80 mEnv = env;
81
82 __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL_Android_Init()");
83
84 jclass cls = mEnv->FindClass ("org/libsdl/app/SDLActivity");
85 mActivityInstance = cls;
86 midCreateGLContext = mEnv->GetStaticMethodID(cls,"createGLContext","()V");
87 midFlipBuffers = mEnv->GetStaticMethodID(cls,"flipBuffers","()V");
88 midEnableFeature = mEnv->GetStaticMethodID(cls,"enableFeature","(II)V");
89 midUpdateAudio = mEnv->GetStaticMethodID(cls,"updateAudio","([B)V");
90
91 if(!midCreateGLContext || !midFlipBuffers || !midEnableFeature ||
92 !midUpdateAudio) {
93 __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Bad mids\n");
94 } else {
95 #ifdef DEBUG
96 __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Good mids\n");
97 #endif
98 }
99 }
100
101 // Keydown
102 extern "C" void Java_org_libsdl_app_SDLActivity_onNativeKeyDown(JNIEnv* env,
103 jobject obj, jint keycode)
104 {
105 int r = Android_OnKeyDown(keycode);
106 #ifdef DEBUG
107 __android_log_print(ANDROID_LOG_INFO, "SDL",
108 "SDL: native key down %d, %d\n", keycode, r);
109 #endif
110 }
111
112 // Keyup
113 extern "C" void Java_org_libsdl_app_SDLActivity_onNativeKeyUp(JNIEnv* env,
114 jobject obj, jint keycode)
115 {
116 int r = Android_OnKeyUp(keycode);
117 #ifdef DEBUG
118 __android_log_print(ANDROID_LOG_INFO, "SDL",
119 "SDL: native key up %d, %d\n", keycode, r);
120 #endif
121 }
122
123 // Touch
124 extern "C" void Java_org_libsdl_app_SDLActivity_onNativeTouch(JNIEnv* env,
125 jobject obj, jint action, jfloat x, jfloat y, jfloat p)
126 {
127 #ifdef DEBUG
128 __android_log_print(ANDROID_LOG_INFO, "SDL",
129 "SDL: native touch event %d @ %f/%f, pressure %f\n",
130 action, x, y, p);
131 #endif
132
133 //TODO: Pass this off to the SDL multitouch stuff
134 }
135
136 // Quit
137 extern "C" void Java_org_libsdl_app_SDLActivity_nativeQuit( JNIEnv* env,
138 jobject obj )
139 {
140 // Stop rendering as we're no longer in the foreground
141 bRenderingEnabled = false;
142
143 // Inject a SDL_QUIT event
144 SDL_SendQuit();
145 }
146
147 // Screen size
148 extern "C" void Java_org_libsdl_app_SDLActivity_nativeSetScreenSize(
149 JNIEnv* env, jobject obj, jint width, jint height)
150 {
151 __android_log_print(ANDROID_LOG_INFO, "SDL",
152 "SDL: Set screen size on init: %d/%d\n", width, height);
153 Android_SetScreenResolution(width, height);
154 }
155
156 // Resize
157 extern "C" void Java_org_libsdl_app_SDLActivity_onNativeResize(
158 JNIEnv* env, jobject obj, jint width,
159 jint height, jint format)
160 {
161 Android_OnResize(width, height, format);
162 }
163
164 extern "C" void Java_org_libsdl_app_SDLActivity_onNativeAccel(
165 JNIEnv* env, jobject obj,
166 jfloat x, jfloat y, jfloat z)
167 {
168 fLastAccelerometer[0] = x;
169 fLastAccelerometer[1] = y;
170 fLastAccelerometer[2] = z;
171 }
172
173
174
175 /*******************************************************************************
176 Functions called by SDL into Java
177 *******************************************************************************/
178 extern "C" void Android_CreateContext()
179 {
180 __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: sdl_create_context()\n");
181
182 bRenderingEnabled = true;
183
184 mEnv->CallStaticVoidMethod(mActivityInstance, midCreateGLContext );
185 }
186
187 extern "C" void Android_Render()
188 {
189 if (!bRenderingEnabled) {
190 return;
191 }
192
193 // When we get here, we've accumulated a full frame
194 mEnv->CallStaticVoidMethod(mActivityInstance, midFlipBuffers);
195 }
196
197 extern "C" void Android_EnableFeature(int featureid, bool enabled)
198 {
199 mEnv->CallStaticVoidMethod(mActivityInstance, midEnableFeature,
200 featureid, (int)enabled);
201 }
202
203 extern "C" void Android_UpdateAudioBuffer(unsigned char *buf, int len)
204 {
205 //Annoyingly we can't just call into Java from any thread. Because the audio
206 //callback is dispatched from the SDL audio thread (that wasn't made from
207 //java, we have to do some magic here to let the JVM know about the thread.
208 //Because everything it touches on the Java side is static anyway, it's
209 //not a big deal, just annoying.
210 if(!mAudioThreadEnv) {
211 __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Need to set up audio thread env\n");
212
213 mVM->AttachCurrentThread(&mAudioThreadEnv, NULL);
214
215 __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: ok\n");
216 }
217
218 jbyteArray arr = mAudioThreadEnv->NewByteArray(len);
219
220 //blah. We probably should rework this so we avoid the copy.
221 mAudioThreadEnv->SetByteArrayRegion(arr, 0, len, (jbyte *)buf);
222
223 __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: copied\n");
224
225 mAudioThreadEnv->CallStaticVoidMethod( mActivityInstance,
226 midUpdateAudio, arr );
227
228 __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: invoked\n");
229
230 }
231