Mercurial > sdl-ios-xcode
annotate android/project/jni/android-support.cpp @ 4953:4f40b11e1045
Fixed prototype for SDL_main()
FIXME: Still need to pass some arguments - can we get them from the Java class?
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Tue, 04 Jan 2011 11:39:52 -0800 |
parents | 9076cdb027af |
children | 5e42031a8d70 |
rev | line source |
---|---|
4726 | 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 | |
4953
4f40b11e1045
Fixed prototype for SDL_main()
Sam Lantinga <slouken@libsdl.org>
parents:
4726
diff
changeset
|
39 extern "C" int SDL_main(int argc, char *argv[]); |
4726 | 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 | |
4953
4f40b11e1045
Fixed prototype for SDL_main()
Sam Lantinga <slouken@libsdl.org>
parents:
4726
diff
changeset
|
106 SDL_main(0, 0); |
4726 | 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 |