# HG changeset patch # User Xeli # Date 1327540017 -3600 # Node ID 1d37461381139e6d9654cc8051082e91c27a5245 # Parent 4c06ea12de1cd42fe837bcbd477f1e80b1251100# Parent fa518383563b80a442a8404d67a80ecf21405b0c enable pause/resume on the java side diff -r 4c06ea12de1c -r 1d3746138113 hedgewars/hwengine.pas --- 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); diff -r 4c06ea12de1c -r 1d3746138113 hedgewars/uStore.pas --- 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} diff -r 4c06ea12de1c -r 1d3746138113 project_files/Android-build/SDL-android-project/AndroidManifest.xml --- 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 @@ + android:theme="@android:style/Theme.NoTitleBar.Fullscreen"> diff -r 4c06ea12de1c -r 1d3746138113 project_files/Android-build/SDL-android-project/assets/Data/Graphics/TARDIS.png Binary file project_files/Android-build/SDL-android-project/assets/Data/Graphics/TARDIS.png has changed diff -r 4c06ea12de1c -r 1d3746138113 project_files/Android-build/SDL-android-project/jni/SDL/src/core/android/SDL_android.cpp --- 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 */ diff -r 4c06ea12de1c -r 1d3746138113 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java --- 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); } } } +