comparison android/project/src/org/libsdl/app/SDLActivity.java @ 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
comparison
equal deleted inserted replaced
4725:4eb9d3c7fdd2 4726:9076cdb027af
1 package org.libsdl.app;
2
3 import javax.microedition.khronos.egl.EGLConfig;
4 import javax.microedition.khronos.opengles.GL10;
5 import javax.microedition.khronos.egl.*;
6
7 import android.app.*;
8 import android.content.*;
9 import android.view.*;
10 import android.os.*;
11 import android.util.Log;
12 import android.graphics.*;
13 import android.text.method.*;
14 import android.text.*;
15 import android.media.*;
16 import android.hardware.*;
17 import android.content.*;
18
19 import java.lang.*;
20
21
22 /**
23 SDL Activity
24 */
25 public class SDLActivity extends Activity {
26
27 //Main components
28 private static SDLActivity mSingleton;
29 private static SDLSurface mSurface;
30
31 //Audio
32 private static AudioTrack mAudioTrack;
33 private static boolean bAudioIsEnabled;
34
35 //Sensors
36 private static boolean bAccelIsEnabled;
37
38 //feature IDs. Must match up on the C side as well.
39 private static int FEATURE_AUDIO = 1;
40 private static int FEATURE_ACCEL = 2;
41
42 //Load the .so
43 static {
44 System.loadLibrary("sdlapp");
45 }
46
47 //Setup
48 protected void onCreate(Bundle savedInstanceState) {
49 super.onCreate(savedInstanceState);
50
51 //So we can call stuff from static callbacks
52 mSingleton = this;
53
54 //Set up the surface
55 mSurface = new SDLSurface(getApplication());
56 setContentView(mSurface);
57 SurfaceHolder holder = mSurface.getHolder();
58 holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
59
60 }
61
62 //Audio
63 public static boolean initAudio(){
64
65 //blah. Hardcoded things are bad. FIXME when we have more sound stuff
66 //working properly.
67 mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
68 11025,
69 AudioFormat.CHANNEL_CONFIGURATION_MONO,
70 AudioFormat.ENCODING_PCM_8BIT,
71 2048,
72 AudioTrack.MODE_STREAM);
73 bAudioIsEnabled = true;
74 return true;
75 }
76
77 //Accel
78 public static boolean initAccel(){
79 mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, true);
80 bAccelIsEnabled = true;
81 return true;
82 }
83
84 public static boolean closeAccel(){
85 mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, false);
86 bAccelIsEnabled = false;
87 return true;
88 }
89
90
91 //Events
92 protected void onPause() {
93 super.onPause();
94 }
95
96 protected void onResume() {
97 super.onResume();
98 }
99
100
101
102
103
104 //C functions we call
105 public static native void nativeInit();
106 public static native void nativeQuit();
107 public static native void nativeSetScreenSize(int width, int height);
108 public static native void onNativeKeyDown(int keycode);
109 public static native void onNativeKeyUp(int keycode);
110 public static native void onNativeTouch(int action, float x,
111 float y, float p);
112 public static native void onNativeResize(int x, int y, int format);
113 public static native void onNativeAccel(float x, float y, float z);
114
115
116
117 //Java functions called from C
118 private static void createGLContext(){
119 mSurface.initEGL();
120 }
121
122 public static void flipBuffers(){
123 mSurface.flipEGL();
124 }
125
126 public static void updateAudio(byte [] buf){
127
128 if(mAudioTrack == null){
129 return;
130 }
131
132 mAudioTrack.write(buf, 0, buf.length);
133 mAudioTrack.play();
134
135 Log.v("SDL","Played some audio");
136 }
137
138 public static void enableFeature(int featureid, int enabled){
139 Log.v("SDL","Feature " + featureid + " = " + enabled);
140
141 //Yuck. This is all horribly inelegent. If it gets to more than a few
142 //'features' I'll rip this out and make something nicer, I promise :)
143 if(featureid == FEATURE_AUDIO){
144 if(enabled == 1){
145 initAudio();
146 }else{
147 //We don't have one of these yet...
148 //closeAudio();
149 }
150 }
151
152 else if(featureid == FEATURE_ACCEL){
153 if(enabled == 1){
154 initAccel();
155 }else{
156 closeAccel();
157 }
158 }
159 }
160
161
162
163
164
165
166
167 }
168
169 /**
170 Simple nativeInit() runnable
171 */
172 class SDLRunner implements Runnable{
173 public void run(){
174 //SDLActivity.initAudio();
175
176 //Runs SDL_main()
177 SDLActivity.nativeInit();
178
179 Log.v("SDL","SDL thread terminated");
180 }
181 }
182
183
184 /**
185 SDLSurface. This is what we draw on, so we need to know when it's created
186 in order to do anything useful.
187
188 Because of this, that's where we set up the SDL thread
189 */
190 class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
191 View.OnKeyListener, View.OnTouchListener, SensorEventListener {
192
193 //This is what SDL runs in. It invokes SDL_main(), eventually
194 private Thread mSDLThread;
195
196 //EGL private objects
197 private EGLContext mEGLContext;
198 private EGLSurface mEGLSurface;
199 private EGLDisplay mEGLDisplay;
200
201 //Sensors
202 private static SensorManager mSensorManager;
203
204 //Startup
205 public SDLSurface(Context context) {
206 super(context);
207 getHolder().addCallback(this);
208
209 setFocusable(true);
210 setFocusableInTouchMode(true);
211 requestFocus();
212 setOnKeyListener(this);
213 setOnTouchListener(this);
214
215 mSensorManager = (SensorManager)context.getSystemService("sensor");
216 }
217
218 //Called when we have a valid drawing surface
219 public void surfaceCreated(SurfaceHolder holder) {
220 Log.v("SDL","Surface created");
221
222 int width = getWidth();
223 int height = getHeight();
224
225 //Set the width and height variables in C before we start SDL so we have
226 //it available on init
227 SDLActivity.nativeSetScreenSize(width, height);
228
229 //Now start up the C app thread
230 mSDLThread = new Thread(new SDLRunner(), "SDLThread");
231 mSDLThread.start();
232 }
233
234 //Called when we lose the surface
235 public void surfaceDestroyed(SurfaceHolder holder) {
236 Log.v("SDL","Surface destroyed");
237
238 SDLActivity.nativeQuit();
239
240 //Now wait for the SDL thread to quit
241 try{
242 mSDLThread.wait();
243 }catch(Exception e){
244 Log.v("SDL","Problem stopping thread: " + e);
245 }
246 }
247
248 //Called when the surface is resized
249 public void surfaceChanged(SurfaceHolder holder, int format,
250 int width, int height) {
251 Log.v("SDL","Surface resized");
252
253 SDLActivity.onNativeResize(width, height, format);
254 }
255
256 //unused
257 public void onDraw(Canvas canvas) {}
258
259
260 //EGL functions
261 public boolean initEGL(){
262 Log.v("SDL","Starting up");
263
264 try{
265
266 EGL10 egl = (EGL10)EGLContext.getEGL();
267
268 EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
269
270 int[] version = new int[2];
271 egl.eglInitialize(dpy, version);
272
273 int[] configSpec = {
274 //EGL10.EGL_DEPTH_SIZE, 16,
275 EGL10.EGL_NONE
276 };
277 EGLConfig[] configs = new EGLConfig[1];
278 int[] num_config = new int[1];
279 egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config);
280 EGLConfig config = configs[0];
281
282 EGLContext ctx = egl.eglCreateContext(dpy, config, EGL10.EGL_NO_CONTEXT, null);
283
284 EGLSurface surface = egl.eglCreateWindowSurface(dpy, config, this, null);
285
286 egl.eglMakeCurrent(dpy, surface, surface, ctx);
287
288 mEGLContext = ctx;
289 mEGLDisplay = dpy;
290 mEGLSurface = surface;
291
292
293 }catch(Exception e){
294 Log.v("SDL", e + "");
295 for(StackTraceElement s : e.getStackTrace()){
296 Log.v("SDL", s.toString());
297 }
298 }
299 Log.v("SDL","Done making!");
300
301 return true;
302 }
303
304 //EGL buffer flip
305 public void flipEGL(){
306 try{
307
308 EGL10 egl = (EGL10)EGLContext.getEGL();
309 GL10 gl = (GL10)mEGLContext.getGL();
310
311 egl.eglWaitNative(EGL10.EGL_NATIVE_RENDERABLE, null);
312
313 //drawing here
314
315 egl.eglWaitGL();
316
317 egl.eglSwapBuffers(mEGLDisplay, mEGLSurface);
318
319
320 }catch(Exception e){
321 Log.v("SDL", "flipEGL(): " + e);
322
323 for(StackTraceElement s : e.getStackTrace()){
324 Log.v("SDL", s.toString());
325 }
326 }
327 }
328
329
330
331 //Key events
332 public boolean onKey(View v, int keyCode, KeyEvent event){
333
334 if(event.getAction() == KeyEvent.ACTION_DOWN){
335 SDLActivity.onNativeKeyDown(keyCode);
336 return true;
337 }
338
339 else if(event.getAction() == KeyEvent.ACTION_UP){
340 SDLActivity.onNativeKeyUp(keyCode);
341 return true;
342 }
343
344 return false;
345 }
346
347 //Touch events
348 public boolean onTouch(View v, MotionEvent event){
349
350 int action = event.getAction();
351 float x = event.getX();
352 float y = event.getY();
353 float p = event.getPressure();
354
355 //TODO: Anything else we need to pass?
356 SDLActivity.onNativeTouch(action, x, y, p);
357 return true;
358 }
359
360 //Sensor events
361 public void enableSensor(int sensortype, boolean enabled){
362 //TODO: This uses getDefaultSensor - what if we have >1 accels?
363 if(enabled){
364 mSensorManager.registerListener(this,
365 mSensorManager.getDefaultSensor(sensortype),
366 SensorManager.SENSOR_DELAY_GAME, null);
367 }else{
368 mSensorManager.unregisterListener(this,
369 mSensorManager.getDefaultSensor(sensortype));
370 }
371 }
372
373 public void onAccuracyChanged(Sensor sensor, int accuracy){
374 //TODO
375 }
376
377 public void onSensorChanged(SensorEvent event){
378 if(event.sensor.getType() == Sensor.TYPE_ACCELEROMETER){
379 SDLActivity.onNativeAccel( event.values[0],
380 event.values[1],
381 event.values[2] );
382 }
383 }
384
385
386 }
387
388