enable pause/resume on the java side
authorXeli
Thu, 26 Jan 2012 02:06:57 +0100
changeset 6599 1d3746138113
parent 6596 4c06ea12de1c (current diff)
parent 6598 fa518383563b (diff)
child 6600 5810e42d8375
enable pause/resume on the java side
project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java
--- a/hedgewars/hwengine.pas	Tue Jan 24 11:54:53 2012 -0500
+++ b/hedgewars/hwengine.pas	Thu Jan 26 02:06:57 2012 +0100
@@ -167,6 +167,7 @@
     while isTerminated = false do
     begin
         SDL_PumpEvents();
+ 
         while SDL_PeepEvents(@event, 1, SDL_GETEVENT, {$IFDEF SDL13}SDL_FIRSTEVENT, SDL_LASTEVENT{$ELSE}SDL_ALLEVENTS{$ENDIF}) > 0 do
         begin
             case event.type_ of
@@ -190,6 +191,9 @@
                     else if event.window.event = SDL_WINDOWEVENT_RESTORED then
                         begin
                         GameState:= previousGameState;
+{$IFDEF ANDROID}        //This call is used to reinitialize the glcontext and reload the textures
+                        ParseCommand('fullscr '+intToStr(LongInt(cFullScreen)), true);
+{$ENDIF}
                         end
                     else if event.window.event = SDL_WINDOWEVENT_RESIZED then
                         begin
@@ -291,7 +295,7 @@
 begin
 {$IFDEF HWLIBRARY}
     cBits:= 32;
-    cFullScreen:= false;
+    cFullScreen:= true;
     cTimerInterval:= 8;
     cShowFPS:= {$IFDEF DEBUGFILE}true{$ELSE}false{$ENDIF};
     val(gameArgs[0], ipcPort);
--- a/hedgewars/uStore.pas	Tue Jan 24 11:54:53 2012 -0500
+++ b/hedgewars/uStore.pas	Thu Jan 26 02:06:57 2012 +0100
@@ -369,7 +369,7 @@
 // This should maybe be flagged. It wastes quite a bit of memory.
                 if not reload then
                     begin
-{$IF DEFINED(DARWIN) OR DEFINED(WIN32)}
+{$IF DEFINED(DARWIN) OR DEFINED(WIN32) or DEFINED(ANDROID)}
                     Surface:= tmpsurf 
 {$ELSE}
                     if saveSurf then
@@ -998,7 +998,11 @@
 
     AddFileLog('Preparing to change video parameters...');
 {$IFNDEF IPHONEOS}
+    {$IFDEF SDL13}
+    if SDLwindow = nil then
+    {$ELSE}
     if SDLPrimSurface = nil then
+    {$ENDIF}
         begin
         // set window title
         SDL_WM_SetCaption('Hedgewars', nil);
@@ -1006,7 +1010,7 @@
         SDLTry(IMG_Init(IMG_INIT_PNG) <> 0, true);
         WriteLnToConsole(msgOK);
         // load engine icon
-{$IFNDEF DARWIN}
+    {$IFNDEF DARWIN}
         ico:= LoadImage(UserPathz[ptGraphics] + '/hwengine', ifIgnoreCaps);
         if ico = nil then
             ico:= LoadImage(Pathz[ptGraphics] + '/hwengine', ifIgnoreCaps);
@@ -1015,18 +1019,18 @@
             SDL_WM_SetIcon(ico, 0);
             SDL_FreeSurface(ico)
             end;
-{$ENDIF}
+    {$ENDIF}
         end
     else
         begin
         SetScale(cDefaultZoomLevel);
-{$IF DEFINED(DARWIN) OR DEFINED(WIN32)}
+     {$IF DEFINED(DARWIN) OR DEFINED(WIN32) or DEFINED(ANDROID)}
         reinit:= true;
         StoreRelease(true);
         ResetLand;
         ResetWorldTex;
         //uTextures.freeModule; //DEBUG ONLY
-{$ENDIF}
+    {$ENDIF}
         AddFileLog('Freeing old primary surface...');
         SDL_FreeSurface(SDLPrimSurface);
         SDLPrimSurface:= nil;
@@ -1047,14 +1051,14 @@
     y:= SDL_WINDOWPOS_CENTERED_MASK;
     flags:= SDL_WINDOW_OPENGL or SDL_WINDOW_SHOWN;
 
-{$IFDEF MOBILE}
+    {$IFDEF MOBILE}
     // make the sdl window appear on the second monitor when present
     x:= x or (SDL_GetNumVideoDisplays() - 1);
     y:= y or (SDL_GetNumVideoDisplays() - 1);
 
     SDL_SetHint('SDL_IOS_ORIENTATIONS','LandscapeLeft LandscapeRight');
     flags:= flags or SDL_WINDOW_BORDERLESS or SDL_WINDOW_RESIZABLE;
-{$ENDIF}
+    {$ENDIF}
 
     if SDLwindow = nil then
         if cFullScreen then
@@ -1069,13 +1073,13 @@
 
     if not cOnlyStats then
         begin
-{$IFDEF WIN32}
+    {$IFDEF WIN32}
         s:= SDL_getenv('SDL_VIDEO_CENTERED');
         SDL_putenv('SDL_VIDEO_CENTERED=1');
-{$ENDIF}
+    {$ENDIF}
         SDLPrimSurface:= SDL_SetVideoMode(cScreenWidth, cScreenHeight, cBits, flags);
         SDLTry(SDLPrimSurface <> nil, true);
-{$IFDEF WIN32}SDL_putenv(str2pchar('SDL_VIDEO_CENTERED=' + s));{$ENDIF}
+    {$IFDEF WIN32}SDL_putenv(str2pchar('SDL_VIDEO_CENTERED=' + s));{$ENDIF}
         end;
 {$ENDIF}
 
--- a/project_files/Android-build/SDL-android-project/AndroidManifest.xml	Tue Jan 24 11:54:53 2012 -0500
+++ b/project_files/Android-build/SDL-android-project/AndroidManifest.xml	Thu Jan 26 02:06:57 2012 +0100
@@ -9,8 +9,7 @@
     <application android:label="@string/app_name" android:icon="@drawable/icon">
         <activity android:name=".MainActivity"
                   android:label="@string/app_name"
- 		  		  android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
- 		  		  android:launchMode="singleTask">
+ 		  		  android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
Binary file project_files/Android-build/SDL-android-project/assets/Data/Graphics/TARDIS.png has changed
--- a/project_files/Android-build/SDL-android-project/jni/SDL/src/core/android/SDL_android.cpp	Tue Jan 24 11:54:53 2012 -0500
+++ b/project_files/Android-build/SDL-android-project/jni/SDL/src/core/android/SDL_android.cpp	Thu Jan 26 02:06:57 2012 +0100
@@ -171,7 +171,7 @@
 }
 
 // Pause
-extern "C" void Java_org_libsdl_app_SDLActivity_nativePause(
+extern "C" void Java_org_hedgewars_hedgeroid_SDLActivity_nativePause(
                                     JNIEnv* env, jclass cls)
 {
     if (Android_Window) {
@@ -181,7 +181,7 @@
 }
 
 // Resume
-extern "C" void Java_org_libsdl_app_SDLActivity_nativeResume(
+extern "C" void Java_org_hedgewars_hedgeroid_SDLActivity_nativeResume(
                                     JNIEnv* env, jclass cls)
 {
     if (Android_Window) {
@@ -190,7 +190,7 @@
     }
 }
 
-extern "C" void Java_org_libsdl_app_SDLActivity_nativeRunAudioThread(
+extern "C" void Java_org_hedgewars_hedgeroid_SDLActivity_nativeRunAudioThread(
                                     JNIEnv* env, jclass cls)
 {
     /* This is the audio thread, with a different environment */
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java	Tue Jan 24 11:54:53 2012 -0500
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java	Thu Jan 26 02:06:57 2012 +0100
@@ -9,7 +9,6 @@
 import org.hedgewars.hedgeroid.EngineProtocol.EngineProtocolNetwork;
 import org.hedgewars.hedgeroid.EngineProtocol.GameConfig;
 import org.hedgewars.hedgeroid.EngineProtocol.PascalExports;
-import org.hedgewars.hedgeroid.UserInput.TouchInterface;
 
 import android.app.Activity;
 import android.content.Context;
@@ -27,39 +26,47 @@
 import android.os.Message;
 import android.util.Log;
 import android.view.KeyEvent;
+import android.view.MotionEvent;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 import android.view.View;
 
+
 /**
- * SDL Activity
+    SDL Activity
  */
 public class SDLActivity extends Activity {
 
 	// Main components
 	public static SDLActivity mSingleton;
-	public static SDLSurface mSurface;
+	private static SDLSurface mSurface;
+
+	// This is what SDL runs in. It invokes SDL_main(), eventually
+	private static Thread mSDLThread;
 
 	// Audio
 	private static Thread mAudioThread;
 	private static AudioTrack mAudioTrack;
 
+	// EGL private objects
+	private static EGLContext  mEGLContext;
+	private static EGLSurface  mEGLSurface;
+	private static EGLDisplay  mEGLDisplay;
+	private static EGLConfig   mEGLConfig;
+	private static int mGLMajor, mGLMinor;
+
 	// Load the .so
 	static {
 		System.loadLibrary("SDL");
-		System.loadLibrary("SDL_image");
-		System.loadLibrary("mikmod");
-		System.loadLibrary("SDL_net");
-		System.loadLibrary("SDL_mixer");
-		System.loadLibrary("SDL_ttf");
-		System.loadLibrary("lua5.1");
-		System.loadLibrary("hwengine");
+		//System.loadLibrary("SDL_image");
+		//System.loadLibrary("SDL_mixer");
+		//System.loadLibrary("SDL_ttf");
 		System.loadLibrary("main");
 	}
 
 	// Setup
 	protected void onCreate(Bundle savedInstanceState) {
-		// Log.v("SDL", "onCreate()");
+		//Log.v("SDL", "onCreate()");
 		super.onCreate(savedInstanceState);
 
 		// So we can call stuff from static callbacks
@@ -67,27 +74,54 @@
 
 		// Set up the surface
 		GameConfig config = getIntent().getParcelableExtra("config");
+
 		mSurface = new SDLSurface(getApplication(), config);
 		setContentView(mSurface);
 		SurfaceHolder holder = mSurface.getHolder();
-		holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
 	}
 
 	// Events
 	protected void onPause() {
-		// Log.v("SDL", "onPause()");
+		Log.v("SDL", "onPause()");
 		super.onPause();
 
+		if(mEGLDisplay != null && mEGLContext != null){
+			EGL10 egl = (EGL10)EGLContext.getEGL();
+			egl.eglDestroyContext(mEGLDisplay, mEGLContext);
+			mEGLDisplay = null;
+			mEGLContext = null;
+		}
+
+		SDLActivity.nativePause();
 	}
 
 	protected void onResume() {
-		// Log.v("SDL", "onResume()");
+		Log.v("SDL", "onResume()");
 		super.onResume();
 	}
-	
+
 	public void onBackPressed(){
-		nativeQuit();
 		super.onBackPressed();
+		PascalExports.HWterminate(true);
+	}
+
+	protected void onDestroy() {
+		super.onDestroy();
+		Log.v("SDL", "onDestroy()");
+		// Send a quit message to the application
+		SDLActivity.nativeQuit();
+
+		// Now wait for the SDL thread to quit
+		if (mSDLThread != null) {
+			try {
+				mSDLThread.join();
+			} catch(Exception e) {
+				Log.v("SDL", "Problem stopping thread: " + e);
+			}
+			mSDLThread = null;
+
+			//Log.v("SDL", "Finished waiting for SDL thread");
+		}
 	}
 
 	// Messages from the SDLMain thread
@@ -97,7 +131,7 @@
 	Handler commandHandler = new Handler() {
 		public void handleMessage(Message msg) {
 			if (msg.arg1 == COMMAND_CHANGE_TITLE) {
-				setTitle((String) msg.obj);
+				setTitle((String)msg.obj);
 			}
 		}
 	};
@@ -111,31 +145,28 @@
 	}
 
 	// C functions we call
-	public static native void nativeInit(String[] argv);
-
+	public static native void nativeInit(String...args);
 	public static native void nativeQuit();
-
+	public static native void nativePause();
+	public static native void nativeResume();
 	public static native void onNativeResize(int x, int y, int format);
-
 	public static native void onNativeKeyDown(int keycode);
+	public static native void onNativeKeyUp(int keycode);
+	public static native void onNativeTouch(int touchDevId, int pointerFingerId,
+			int action, float x, 
+			float y, float p);
+	public static native void onNativeAccel(float x, float y, float z);
+	public static native void nativeRunAudioThread();
 
-	public static native void onNativeKeyUp(int keycode);
-
-	public static native void onNativeTouch(int touchDevId, int pointerFingerId, int action, float x, float y,
-			float p);
-
-	public static native void onNativeAccel(float x, float y, float z);
-
-	public static native void nativeRunAudioThread();
 
 	// Java functions called from C
 
 	public static boolean createGLContext(int majorVersion, int minorVersion) {
-		return mSurface.initEGL(majorVersion, minorVersion);
+		return initEGL(majorVersion, minorVersion);
 	}
 
 	public static void flipBuffers() {
-		mSurface.flipEGL();
+		flipEGL();
 	}
 
 	public static void setActivityTitle(String title) {
@@ -143,51 +174,168 @@
 		mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title);
 	}
 
+	public static Context getContext() {
+		return mSingleton;
+	}
+
+	public static void startApp(int width, int height, GameConfig config) {
+		// Start up the C app thread
+		if (mSDLThread == null) {
+			mSDLThread = new Thread(new SDLMain(width, height, config), "SDLThread");
+			mSDLThread.start();
+		}
+		else {
+			SDLActivity.nativeResume();
+		}
+	}
+
+	// EGL functions
+	public static boolean initEGL(int majorVersion, int minorVersion) {
+		if (SDLActivity.mEGLDisplay == null) {
+			//Log.v("SDL", "Starting up OpenGL ES " + majorVersion + "." + minorVersion);
+
+			try {
+				EGL10 egl = (EGL10)EGLContext.getEGL();
+
+				EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+
+				int[] version = new int[2];
+				egl.eglInitialize(dpy, version);
+
+				int EGL_OPENGL_ES_BIT = 1;
+				int EGL_OPENGL_ES2_BIT = 4;
+				int renderableType = 0;
+				if (majorVersion == 2) {
+					renderableType = EGL_OPENGL_ES2_BIT;
+				} else if (majorVersion == 1) {
+					renderableType = EGL_OPENGL_ES_BIT;
+				}
+				int[] configSpec = {
+						//EGL10.EGL_DEPTH_SIZE,   16,
+						EGL10.EGL_RENDERABLE_TYPE, renderableType,
+						EGL10.EGL_NONE
+				};
+				EGLConfig[] configs = new EGLConfig[1];
+				int[] num_config = new int[1];
+				if (!egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config) || num_config[0] == 0) {
+					Log.e("SDL", "No EGL config available");
+					return false;
+				}
+				EGLConfig config = configs[0];
+
+				/*int EGL_CONTEXT_CLIENT_VERSION=0x3098;
+                int contextAttrs[] = new int[] { EGL_CONTEXT_CLIENT_VERSION, majorVersion, EGL10.EGL_NONE };
+                EGLContext ctx = egl.eglCreateContext(dpy, config, EGL10.EGL_NO_CONTEXT, contextAttrs);
+
+                if (ctx == EGL10.EGL_NO_CONTEXT) {
+                    Log.e("SDL", "Couldn't create context");
+                    return false;
+                }
+                SDLActivity.mEGLContext = ctx;*/
+				SDLActivity.mEGLDisplay = dpy;
+				SDLActivity.mEGLConfig = config;
+				SDLActivity.mGLMajor = majorVersion;
+				SDLActivity.mGLMinor = minorVersion;
+
+				SDLActivity.createEGLSurface();
+			} catch(Exception e) {
+				Log.v("SDL", e + "");
+				for (StackTraceElement s : e.getStackTrace()) {
+					Log.v("SDL", s.toString());
+				}
+			}
+		}
+		else SDLActivity.createEGLSurface();
+
+		return true;
+	}
+
+	public static boolean createEGLContext() {
+		EGL10 egl = (EGL10)EGLContext.getEGL();
+		int EGL_CONTEXT_CLIENT_VERSION=0x3098;
+		int contextAttrs[] = new int[] { EGL_CONTEXT_CLIENT_VERSION, SDLActivity.mGLMajor, EGL10.EGL_NONE };
+		SDLActivity.mEGLContext = egl.eglCreateContext(SDLActivity.mEGLDisplay, SDLActivity.mEGLConfig, EGL10.EGL_NO_CONTEXT, contextAttrs);
+		if (SDLActivity.mEGLContext == EGL10.EGL_NO_CONTEXT) {
+			Log.e("SDL", "Couldn't create context");
+			return false;
+		}
+		return true;
+	}
+
+	public static boolean createEGLSurface() {
+		if (SDLActivity.mEGLDisplay != null && SDLActivity.mEGLConfig != null) {
+			EGL10 egl = (EGL10)EGLContext.getEGL();
+			if (SDLActivity.mEGLContext == null) createEGLContext();
+
+			Log.v("SDL", "Creating new EGL Surface");
+			EGLSurface surface = egl.eglCreateWindowSurface(SDLActivity.mEGLDisplay, SDLActivity.mEGLConfig, SDLActivity.mSurface, null);
+			if (surface == EGL10.EGL_NO_SURFACE) {
+				Log.e("SDL", "Couldn't create surface");
+				return false;
+			}
+
+			if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, surface, surface, SDLActivity.mEGLContext)) {
+				Log.e("SDL", "Old EGL Context doesnt work, trying with a new one");
+				createEGLContext();
+				if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, surface, surface, SDLActivity.mEGLContext)) {
+					Log.e("SDL", "Failed making EGL Context current");
+					return false;
+				}
+			}
+			SDLActivity.mEGLSurface = surface;
+			return true;
+		}
+		return false;
+	}
+
+	// EGL buffer flip
+	public static void flipEGL() {
+		try {
+			EGL10 egl = (EGL10)EGLContext.getEGL();
+
+			egl.eglWaitNative(EGL10.EGL_CORE_NATIVE_ENGINE, null);
+
+			// drawing here
+
+			egl.eglWaitGL();
+
+			egl.eglSwapBuffers(SDLActivity.mEGLDisplay, SDLActivity.mEGLSurface);
+
+
+		} catch(Exception e) {
+			Log.v("SDL", "flipEGL(): " + e);
+			for (StackTraceElement s : e.getStackTrace()) {
+				Log.v("SDL", s.toString());
+			}
+		}
+	}
+
 	// Audio
 	private static Object buf;
 
-	public static Object audioInit(int sampleRate, boolean is16Bit,
-			boolean isStereo, int desiredFrames) {
-		int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO
-				: AudioFormat.CHANNEL_CONFIGURATION_MONO;
-		int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT
-				: AudioFormat.ENCODING_PCM_8BIT;
+	public static Object audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
+		int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
+		int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
 		int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
 
-		Log.v("SDL", "SDL audio: wanted " + (isStereo ? "stereo" : "mono")
-				+ " " + (is16Bit ? "16-bit" : "8-bit") + " "
-				+ ((float) sampleRate / 1000f) + "kHz, " + desiredFrames
-				+ " frames buffer");
+		Log.v("SDL", "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + ((float)sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer");
 
 		// Let the user pick a larger buffer if they really want -- but ye
 		// gods they probably shouldn't, the minimums are horrifyingly high
 		// latency already
-		desiredFrames = Math.max(
-				desiredFrames,
-				(AudioTrack.getMinBufferSize(sampleRate, channelConfig,
-						audioFormat) + frameSize - 1)
-						/ frameSize);
+		desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize);
 
 		mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
-				channelConfig, audioFormat, desiredFrames * frameSize,
-				AudioTrack.MODE_STREAM);
+				channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM);
 
 		audioStartThread();
 
-		Log.v("SDL",
-				"SDL audio: got "
-						+ ((mAudioTrack.getChannelCount() >= 2) ? "stereo"
-								: "mono")
-						+ " "
-						+ ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit"
-								: "8-bit") + " "
-						+ ((float) mAudioTrack.getSampleRate() / 1000f)
-						+ "kHz, " + desiredFrames + " frames buffer");
+		Log.v("SDL", "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + ((float)mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
 
 		if (is16Bit) {
 			buf = new short[desiredFrames * (isStereo ? 2 : 1)];
 		} else {
-			buf = new byte[desiredFrames * (isStereo ? 2 : 1)];
+			buf = new byte[desiredFrames * (isStereo ? 2 : 1)]; 
 		}
 		return buf;
 	}
@@ -206,14 +354,14 @@
 	}
 
 	public static void audioWriteShortBuffer(short[] buffer) {
-		for (int i = 0; i < buffer.length;) {
+		for (int i = 0; i < buffer.length; ) {
 			int result = mAudioTrack.write(buffer, i, buffer.length - i);
 			if (result > 0) {
 				i += result;
 			} else if (result == 0) {
 				try {
 					Thread.sleep(1);
-				} catch (InterruptedException e) {
+				} catch(InterruptedException e) {
 					// Nom nom
 				}
 			} else {
@@ -224,14 +372,14 @@
 	}
 
 	public static void audioWriteByteBuffer(byte[] buffer) {
-		for (int i = 0; i < buffer.length;) {
+		for (int i = 0; i < buffer.length; ) {
 			int result = mAudioTrack.write(buffer, i, buffer.length - i);
 			if (result > 0) {
 				i += result;
 			} else if (result == 0) {
 				try {
 					Thread.sleep(1);
-				} catch (InterruptedException e) {
+				} catch(InterruptedException e) {
 					// Nom nom
 				}
 			} else {
@@ -245,12 +393,12 @@
 		if (mAudioThread != null) {
 			try {
 				mAudioThread.join();
-			} catch (Exception e) {
+			} catch(Exception e) {
 				Log.v("SDL", "Problem stopping audio thread: " + e);
 			}
 			mAudioThread = null;
 
-			// Log.v("SDL", "Finished waiting for audio thread");
+			//Log.v("SDL", "Finished waiting for audio thread");
 		}
 
 		if (mAudioTrack != null) {
@@ -261,9 +409,10 @@
 }
 
 /**
- * Simple nativeInit() runnable
+    Simple nativeInit() runnable
  */
 class SDLMain implements Runnable {
+
 	private int surfaceWidth, surfaceHeight;
 	private GameConfig config;
 
@@ -280,7 +429,7 @@
 		String path = Utils.getDataPath(SDLActivity.mSingleton);//This represents the data directory
 		path = path.substring(0, path.length()-1);//remove the trailing '/'
 
-		
+
 		// Runs SDL_main() with added parameters
 		SDLActivity.nativeInit(new String[] { String.valueOf(ipc.port),
 				String.valueOf(surfaceWidth), String.valueOf(surfaceHeight),
@@ -293,82 +442,59 @@
 			e.printStackTrace();
 		}
 		//Log.v("SDL", "SDL thread terminated");
-		SDLActivity.mSingleton.finish();
+		//Log.v("SDL", "SDL thread terminated");
 	}
 }
 
+
 /**
- * SDLSurface. This is what we draw on, so we need to know when it's created in
- * order to do anything useful.
- * 
- * Because of this, that's where we set up the SDL thread
+    SDLSurface. This is what we draw on, so we need to know when it's created
+    in order to do anything useful. 
+
+    Because of this, that's where we set up the SDL thread
  */
-class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
-		View.OnKeyListener, SensorEventListener {
+class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, 
+View.OnKeyListener, View.OnTouchListener, SensorEventListener  {
 
-	// This is what SDL runs in. It invokes SDL_main(), eventually
-	private Thread mSDLThread;
-
-	// EGL private objects
-	private EGLContext mEGLContext;
-	private EGLSurface mEGLSurface;
-	private EGLDisplay mEGLDisplay;
+	private GameConfig config;
 
 	// Sensors
 	private static SensorManager mSensorManager;
 
-	private GameConfig config;
-
-	// Startup
+	// Startup    
 	public SDLSurface(Context context, GameConfig _config) {
 		super(context);
-		getHolder().addCallback(this);
+		getHolder().addCallback(this); 
 
 		setFocusable(true);
 		setFocusableInTouchMode(true);
 		requestFocus();
-		setOnKeyListener(this);
-		setOnTouchListener(TouchInterface.getTouchInterface());
+		setOnKeyListener(this); 
+		setOnTouchListener(this);   
 
-		mSensorManager = (SensorManager) context.getSystemService("sensor");
-
+		mSensorManager = (SensorManager)context.getSystemService("sensor");
 		config = _config;
 	}
 
 	// Called when we have a valid drawing surface
 	public void surfaceCreated(SurfaceHolder holder) {
 		Log.v("SDL", "surfaceCreated()");
-
-		//enableSensor(Sensor.TYPE_ACCELEROMETER, true);
+		holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
+		SDLActivity.createEGLSurface();
+		enableSensor(Sensor.TYPE_ACCELEROMETER, true);
 	}
 
 	// Called when we lose the surface
 	public void surfaceDestroyed(SurfaceHolder holder) {
 		Log.v("SDL", "surfaceDestroyed()");
-
-		// Send a quit message to the application
-		//SDLActivity.nativeQuit();
-                PascalExports.HWterminate(true);
-
-		// Now wait for the SDL thread to quit
-		if (mSDLThread != null) {
-			try {
-				mSDLThread.join();
-			} catch (Exception e) {
-				Log.v("SDL", "Problem stopping thread: " + e);
-			}
-			mSDLThread = null;
-
-			Log.v("SDL", "Finished waiting for SDL thread");
-		}
-
-		//enableSensor(Sensor.TYPE_ACCELEROMETER, false);
+		SDLActivity.nativePause();
+		enableSensor(Sensor.TYPE_ACCELEROMETER, false);
 	}
 
 	// Called when the surface is resized
-	public void surfaceChanged(SurfaceHolder holder, int format, int width,
-			int height) {
-		Log.d("SDL", "surfaceChanged()" + width + " + " + height);
+	public void surfaceChanged(SurfaceHolder holder,
+			int format, int width, int height) {
+		Log.v("SDL", "surfaceChanged()");
 
 		int sdlFormat = 0x85151002; // SDL_PIXELFORMAT_RGB565 by default
 		switch (format) {
@@ -415,122 +541,27 @@
 			break;
 		}
 		SDLActivity.onNativeResize(width, height, sdlFormat);
+		Log.v("SDL", "Window size:" + width + "x"+height);
 
-		// Now start up the C app thread
-		if (mSDLThread == null) {
-			mSDLThread = new Thread(new SDLMain(width, height, config),
-					"SDLThread");
-			mSDLThread.start();
-		}
+		SDLActivity.startApp(width, height, config);
 	}
 
 	// unused
-	public void onDraw(Canvas canvas) {
-	}
-
-	// EGL functions
-	public boolean initEGL(int majorVersion, int minorVersion) {
-		Log.v("SDL", "Starting up OpenGL ES " + majorVersion + "."
-				+ minorVersion);
-
-		try {
-			EGL10 egl = (EGL10) EGLContext.getEGL();
-
-			EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
-
-			int[] version = new int[2];
-			egl.eglInitialize(dpy, version);
-
-			int EGL_OPENGL_ES_BIT = 1;
-			int EGL_OPENGL_ES2_BIT = 4;
-			int renderableType = 0;
-			if (majorVersion == 2) {
-				renderableType = EGL_OPENGL_ES2_BIT;
-			} else if (majorVersion == 1) {
-				renderableType = EGL_OPENGL_ES_BIT;
-			}
-			int[] configSpec = {
-					// EGL10.EGL_DEPTH_SIZE, 16,
-					EGL10.EGL_RENDERABLE_TYPE, renderableType, EGL10.EGL_NONE };
-			EGLConfig[] configs = new EGLConfig[1];
-			int[] num_config = new int[1];
-			if (!egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config)
-					|| num_config[0] == 0) {
-				Log.e("SDL", "No EGL config available");
-				return false;
-			}
-			EGLConfig config = configs[0];
-
-			EGLContext ctx = egl.eglCreateContext(dpy, config,
-					EGL10.EGL_NO_CONTEXT, null);
-			if (ctx == EGL10.EGL_NO_CONTEXT) {
-				Log.e("SDL", "Couldn't create context");
-				return false;
-			}
+	public void onDraw(Canvas canvas) {}
 
-			EGLSurface surface = egl.eglCreateWindowSurface(dpy, config, this,
-					null);
-			if (surface == EGL10.EGL_NO_SURFACE) {
-				Log.e("SDL", "Couldn't create surface");
-				return false;
-			}
-
-			if (!egl.eglMakeCurrent(dpy, surface, surface, ctx)) {
-				Log.e("SDL", "Couldn't make context current");
-				return false;
-			}
-
-			mEGLContext = ctx;
-			mEGLDisplay = dpy;
-			mEGLSurface = surface;
-
-		} catch (Exception e) {
-			Log.v("SDL", e + "");
-			for (StackTraceElement s : e.getStackTrace()) {
-				Log.v("SDL", s.toString());
-			}
-		}
 
-		return true;
-	}
 
-	// EGL buffer flip
-	public void flipEGL() {
-		try {
-			EGL10 egl = (EGL10) EGLContext.getEGL();
-
-			egl.eglWaitNative(EGL10.EGL_NATIVE_RENDERABLE, null);
-
-			// drawing here
-
-			egl.eglWaitGL();
-
-			egl.eglSwapBuffers(mEGLDisplay, mEGLSurface);
-
-		} catch (Exception e) {
-			Log.v("SDL", "flipEGL(): " + e);
-			for (StackTraceElement s : e.getStackTrace()) {
-				Log.v("SDL", s.toString());
-			}
-			
-		}
-	}
 
 	// Key events
-	public boolean onKey(View v, int keyCode, KeyEvent event) {
-                if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) return false;
+	public boolean onKey(View  v, int keyCode, KeyEvent event) {
+		if(keyCode == KeyEvent.KEYCODE_BACK) return false;
 		if (event.getAction() == KeyEvent.ACTION_DOWN) {
-			Log.v("SDL", "key down: " + keyCode);
-			if(keyCode == KeyEvent.KEYCODE_BACK){//TODO ask user to quit or not
-				PascalExports.HWterminate(true);
-				//SDLActivity.mSingleton.finish();
-			}else{
-				SDLActivity.onNativeKeyDown(keyCode);	
-			}
-			
+			//Log.v("SDL", "key down: " + keyCode);
+			SDLActivity.onNativeKeyDown(keyCode);
 			return true;
-		} else if (event.getAction() == KeyEvent.ACTION_UP) {
-			Log.v("SDL", "key up: " + keyCode);
+		}
+		else if (event.getAction() == KeyEvent.ACTION_UP) {
+			//Log.v("SDL", "key up: " + keyCode);
 			SDLActivity.onNativeKeyUp(keyCode);
 			return true;
 		}
@@ -538,15 +569,46 @@
 		return false;
 	}
 
+	// Touch events
+	public boolean onTouch(View v, MotionEvent event) {
+		{
+			final int touchDevId = event.getDeviceId();
+			final int pointerCount = event.getPointerCount();
+			// touchId, pointerId, action, x, y, pressure
+			int actionPointerIndex = event.getActionIndex();
+			int pointerFingerId = event.getPointerId(actionPointerIndex);
+			int action = event.getActionMasked();
+
+			float x = event.getX(actionPointerIndex);
+			float y = event.getY(actionPointerIndex);
+			float p = event.getPressure(actionPointerIndex);
+
+			if (action == MotionEvent.ACTION_MOVE && pointerCount > 1) {
+				// TODO send motion to every pointer if its position has
+				// changed since prev event.
+				for (int i = 0; i < pointerCount; i++) {
+					pointerFingerId = event.getPointerId(i);
+					x = event.getX(i);
+					y = event.getY(i);
+					p = event.getPressure(i);
+					SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
+				}
+			} else {
+				SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
+			}
+		}
+		return true;
+	} 
+
 	// Sensor events
 	public void enableSensor(int sensortype, boolean enabled) {
 		// TODO: This uses getDefaultSensor - what if we have >1 accels?
 		if (enabled) {
-			mSensorManager.registerListener(this,
-					mSensorManager.getDefaultSensor(sensortype),
+			mSensorManager.registerListener(this, 
+					mSensorManager.getDefaultSensor(sensortype), 
 					SensorManager.SENSOR_DELAY_GAME, null);
 		} else {
-			mSensorManager.unregisterListener(this,
+			mSensorManager.unregisterListener(this, 
 					mSensorManager.getDefaultSensor(sensortype));
 		}
 	}
@@ -557,9 +619,11 @@
 
 	public void onSensorChanged(SensorEvent event) {
 		if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
-			SDLActivity.onNativeAccel(event.values[0], event.values[1],
-					event.values[2]);
+			SDLActivity.onNativeAccel(event.values[0] / SensorManager.GRAVITY_EARTH,
+					event.values[1] / SensorManager.GRAVITY_EARTH,
+					event.values[2] / SensorManager.GRAVITY_EARTH);
 		}
 	}
 
 }
+