4 import javax.microedition.khronos.egl.EGLConfig; |
4 import javax.microedition.khronos.egl.EGLConfig; |
5 import javax.microedition.khronos.egl.EGLContext; |
5 import javax.microedition.khronos.egl.EGLContext; |
6 import javax.microedition.khronos.egl.EGLDisplay; |
6 import javax.microedition.khronos.egl.EGLDisplay; |
7 import javax.microedition.khronos.egl.EGLSurface; |
7 import javax.microedition.khronos.egl.EGLSurface; |
8 |
8 |
9 import org.hedgewars.hedgeroid.EngineProtocol.EngineProtocolNetwork; |
|
10 import org.hedgewars.hedgeroid.EngineProtocol.GameConfig; |
9 import org.hedgewars.hedgeroid.EngineProtocol.GameConfig; |
11 import org.hedgewars.hedgeroid.EngineProtocol.PascalExports; |
10 import org.hedgewars.hedgeroid.EngineProtocol.PascalExports; |
|
11 import org.hedgewars.hedgeroid.frontlib.Flib; |
|
12 import org.hedgewars.hedgeroid.frontlib.Frontlib.GameSetupPtr; |
|
13 import org.hedgewars.hedgeroid.frontlib.Frontlib.GameconnPtr; |
|
14 import org.hedgewars.hedgeroid.netplay.TickHandler; |
12 |
15 |
13 import android.app.Activity; |
16 import android.app.Activity; |
14 import android.content.Context; |
17 import android.content.Context; |
15 import android.graphics.Canvas; |
18 import android.graphics.Canvas; |
16 import android.graphics.PixelFormat; |
19 import android.graphics.PixelFormat; |
21 import android.media.AudioFormat; |
24 import android.media.AudioFormat; |
22 import android.media.AudioManager; |
25 import android.media.AudioManager; |
23 import android.media.AudioTrack; |
26 import android.media.AudioTrack; |
24 import android.os.Bundle; |
27 import android.os.Bundle; |
25 import android.os.Handler; |
28 import android.os.Handler; |
|
29 import android.os.HandlerThread; |
26 import android.os.Message; |
30 import android.os.Message; |
27 import android.util.DisplayMetrics; |
31 import android.util.DisplayMetrics; |
28 import android.util.Log; |
32 import android.util.Log; |
29 import android.view.KeyEvent; |
33 import android.view.KeyEvent; |
30 import android.view.MotionEvent; |
34 import android.view.MotionEvent; |
35 |
39 |
36 /** |
40 /** |
37 SDL Activity |
41 SDL Activity |
38 */ |
42 */ |
39 public class SDLActivity extends Activity { |
43 public class SDLActivity extends Activity { |
40 |
44 /** |
|
45 * Set startConfig to the desired config when starting this activity. This avoids having to parcel all |
|
46 * the config objects into the Intent. Not particularly elegant, but it's actually a recommended |
|
47 * way to do this (http://developer.android.com/guide/faq/framework.html#3) |
|
48 */ |
|
49 public static volatile GameConfig startConfig; |
|
50 |
41 // Main components |
51 // Main components |
42 public static SDLActivity mSingleton; |
52 public static SDLActivity mSingleton; |
43 private static SDLSurface mSurface; |
53 private static SDLSurface mSurface; |
44 |
54 |
45 // This is what SDL runs in. It invokes SDL_main(), eventually |
55 // This is what SDL runs in. It invokes SDL_main(), eventually |
46 private static Thread mSDLThread; |
56 private static Thread mSDLThread; // Guarded by SDLActivity.class |
47 |
57 |
48 // Audio |
58 // Audio |
49 private static Thread mAudioThread; |
59 private static Thread mAudioThread; |
50 private static AudioTrack mAudioTrack; |
60 private static AudioTrack mAudioTrack; |
51 |
61 |
72 |
82 |
73 // So we can call stuff from static callbacks |
83 // So we can call stuff from static callbacks |
74 mSingleton = this; |
84 mSingleton = this; |
75 |
85 |
76 // Set up the surface |
86 // Set up the surface |
77 GameConfig config = getIntent().getParcelableExtra("config"); |
87 mSurface = new SDLSurface(getApplication(), startConfig); |
78 |
|
79 mSurface = new SDLSurface(getApplication(), config); |
|
80 setContentView(mSurface); |
88 setContentView(mSurface); |
81 SurfaceHolder holder = mSurface.getHolder(); |
|
82 } |
89 } |
83 |
90 |
84 // Events |
91 // Events |
85 protected void onPause() { |
92 protected void onPause() { |
86 Log.v("SDL", "onPause()"); |
93 Log.v("SDL", "onPause()"); |
106 Log.v("SDL", "onDestroy()"); |
113 Log.v("SDL", "onDestroy()"); |
107 // Send a quit message to the application |
114 // Send a quit message to the application |
108 SDLActivity.nativeQuit(); |
115 SDLActivity.nativeQuit(); |
109 |
116 |
110 // Now wait for the SDL thread to quit |
117 // Now wait for the SDL thread to quit |
111 if (mSDLThread != null) { |
118 synchronized(SDLActivity.class) { |
112 try { |
119 if (mSDLThread != null) { |
113 mSDLThread.join(); |
120 try { |
114 } catch(Exception e) { |
121 mSDLThread.join(); |
115 Log.v("SDL", "Problem stopping thread: " + e); |
122 } catch(Exception e) { |
116 } |
123 Log.w("SDL", "Problem stopping thread: " + e); |
117 mSDLThread = null; |
124 } |
118 |
125 mSDLThread = null; |
119 //Log.v("SDL", "Finished waiting for SDL thread"); |
126 } |
120 } |
127 } |
121 } |
128 } |
122 |
129 |
123 // Messages from the SDLMain thread |
130 // Messages from the SDLMain thread |
124 static int COMMAND_CHANGE_TITLE = 1; |
131 static int COMMAND_CHANGE_TITLE = 1; |
173 public static Context getContext() { |
180 public static Context getContext() { |
174 return mSingleton; |
181 return mSingleton; |
175 } |
182 } |
176 |
183 |
177 public static void startApp(int width, int height, GameConfig config) { |
184 public static void startApp(int width, int height, GameConfig config) { |
178 // Start up the C app thread |
185 synchronized(SDLActivity.class) { |
179 if (mSDLThread == null) { |
186 // Start up the C app thread |
180 mSDLThread = new Thread(new SDLMain(width, height, config), "SDLThread"); |
187 if (mSDLThread == null) { |
181 mSDLThread.start(); |
188 mSDLThread = new Thread(new SDLMain(width, height, config), "SDLThread"); |
182 } |
189 mSDLThread.start(); |
183 else { |
190 } else { |
184 SDLActivity.nativeResume(); |
191 SDLActivity.nativeResume(); |
|
192 } |
185 } |
193 } |
186 } |
194 } |
187 |
195 |
188 // EGL functions |
196 // EGL functions |
189 public static boolean initEGL(int majorVersion, int minorVersion) { |
197 public static boolean initEGL(int majorVersion, int minorVersion) { |
423 surfaceHeight = height; |
431 surfaceHeight = height; |
424 } |
432 } |
425 |
433 |
426 public void run() { |
434 public void run() { |
427 //Set up the IPC socket server to communicate with the engine |
435 //Set up the IPC socket server to communicate with the engine |
428 EngineProtocolNetwork ipc = new EngineProtocolNetwork(config); |
436 HandlerThread thread = new HandlerThread("IPC thread"); |
|
437 thread.start(); // TODO ensure it gets stopped |
|
438 final GameconnPtr conn = Flib.INSTANCE.flib_gameconn_create("Xeli", GameSetupPtr.createJavaOwned(config), false); |
|
439 if(conn == null) { |
|
440 throw new AssertionError(); |
|
441 } |
|
442 int port = Flib.INSTANCE.flib_gameconn_getport(conn); |
429 |
443 |
430 String path = Utils.getDataPath(SDLActivity.mSingleton);//This represents the data directory |
444 String path = Utils.getDataPath(SDLActivity.mSingleton);//This represents the data directory |
431 path = path.substring(0, path.length()-1);//remove the trailing '/' |
445 path = path.substring(0, path.length()-1);//remove the trailing '/' |
432 |
446 |
433 |
|
434 // Runs SDL_main() with added parameters |
447 // Runs SDL_main() with added parameters |
435 SDLActivity.nativeInit(new String[] { String.valueOf(ipc.port), |
448 SDLActivity.nativeInit(new String[] { String.valueOf(port), |
436 String.valueOf(surfaceWidth), String.valueOf(surfaceHeight), |
449 String.valueOf(surfaceWidth), String.valueOf(surfaceHeight), |
437 "0", "en.txt", "xeli", "1", "1", "1", path, "" }); |
450 "0", "en.txt", "xeli", "1", "1", "1", path, "" }); |
438 |
451 |
|
452 new TickHandler(thread.getLooper(), 50, new Runnable() { |
|
453 public void run() { |
|
454 Flib.INSTANCE.flib_gameconn_tick(conn); |
|
455 } |
|
456 }); |
439 try { |
457 try { |
440 ipc.quitIPC(); |
458 thread.quit(); |
441 ipc.join(); |
459 thread.join(); |
442 } catch (InterruptedException e) { |
460 } catch (InterruptedException e) { |
443 e.printStackTrace(); |
461 throw new AssertionError(); |
444 } |
462 } |
|
463 Flib.INSTANCE.flib_gameconn_destroy(conn); |
445 Log.v("SDL", "SDL thread terminated"); |
464 Log.v("SDL", "SDL thread terminated"); |
446 } |
465 } |
447 } |
466 } |
448 |
467 |
449 |
468 |