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