From b83c805bb78b77da4025118110523c1c3eaef600 Mon Sep 17 00:00:00 2001 From: pelya Date: Fri, 1 Oct 2010 19:15:23 +0300 Subject: [PATCH] Implemented SDL_ACTIVEEVENT, did not test it and cannot say if it will work, also SDL 1.3 compilation is broken (use previous commit) --- ChangeAppSettings.sh | 18 ++++++++- project/AndroidManifest.xml | 6 +-- project/jni/Android.mk | 8 ++-- project/jni/Application.mk | 2 +- .../opentyrian/AndroidAppSettings.cfg | 3 +- project/jni/application/src | 2 +- project/jni/sdl | 2 +- project/res/values/strings.xml | 2 +- .../src/video/android/SDL_androidvideo.c | 7 +++- project/src/Accelerometer.java | 2 +- project/src/AssetExtract.java | 2 +- project/src/Audio.java | 2 +- project/src/DataDownloader.java | 2 +- project/src/GLSurfaceView_SDL.java | 6 ++- project/src/Globals.java | 14 ++++--- project/src/MainActivity.java | 2 +- project/src/Settings.java | 2 +- project/src/Video.java | 7 ++-- readme.txt | 37 +++++++++++++++---- 19 files changed, 88 insertions(+), 38 deletions(-) diff --git a/ChangeAppSettings.sh b/ChangeAppSettings.sh index 7843b1bb7..87dde537c 100755 --- a/ChangeAppSettings.sh +++ b/ChangeAppSettings.sh @@ -1,6 +1,6 @@ #!/bin/sh -CHANGE_APP_SETTINGS_VERSION=8 +CHANGE_APP_SETTINGS_VERSION=9 AUTO= if [ "X$1" = "X-a" ]; then @@ -104,6 +104,14 @@ if [ -n "$var" ] ; then AppUsesMultitouch="$var" fi +echo -n "\nApplication implements Android-specific routines to put to background, and will not draw anything to screen\n" +echo -n "between SDL_ACTIVEEVENT->SDL_APPACTIVE lost / gained notifications - you should check for them\n" +echo -n "rigth after SDL_Flip(), if (n) then SDL_Flip() will block till app in background (y) or (n) ($NonBlockingSwapBuffers): " +read var +if [ -n "$var" ] ; then + NonBlockingSwapBuffers="$var" +fi + echo -n "\nRedefine common keys to SDL keysyms: TOUCHSCREEN SEARCH/CALL/DPAD_CENTER VOLUMEUP VOLUMEDOWN MENU BACK CAMERA ENTER DEL" echo -n "\nMENU and BACK hardware keys and TOUCHSCREEN virtual 'key' are available on all devices, other keys may be absent" echo -n "\nThe same key values are used if touchscreen keyboard is enabled, except for MENU and BACK\n($RedefinedKeys)\n: " @@ -211,6 +219,7 @@ echo AppUsesMouse=$AppUsesMouse >> AndroidAppSettings.cfg echo AppNeedsArrowKeys=$AppNeedsArrowKeys >> AndroidAppSettings.cfg echo AppUsesJoystick=$AppUsesJoystick >> AndroidAppSettings.cfg echo AppUsesMultitouch=$AppUsesMultitouch >> AndroidAppSettings.cfg +echo NonBlockingSwapBuffers=$NonBlockingSwapBuffers >> AndroidAppSettings.cfg echo RedefinedKeys=\"$RedefinedKeys\" >> AndroidAppSettings.cfg echo AppTouchscreenKeyboardKeysAmount=$AppTouchscreenKeyboardKeysAmount >> AndroidAppSettings.cfg echo AppTouchscreenKeyboardKeysAmountAutoFire=$AppTouchscreenKeyboardKeysAmountAutoFire >> AndroidAppSettings.cfg @@ -270,6 +279,12 @@ else AppUsesMultitouch=false fi +if [ "$NonBlockingSwapBuffers" = "y" ] ; then + NonBlockingSwapBuffers=true +else + NonBlockingSwapBuffers=false +fi + RedefinedKeycodes="-DSDL_ANDROID_KEYCODE_MOUSE=$MouseKeycode" KEY2=0 for KEY in $RedefinedKeys; do @@ -326,6 +341,7 @@ cat project/src/Globals.java | \ sed "s/public static boolean AppNeedsArrowKeys = .*;/public static boolean AppNeedsArrowKeys = $AppNeedsArrowKeys;/" | \ sed "s/public static boolean AppUsesJoystick = .*;/public static boolean AppUsesJoystick = $AppUsesJoystick;/" | \ sed "s/public static boolean AppUsesMultitouch = .*;/public static boolean AppUsesMultitouch = $AppUsesMultitouch;/" | \ + sed "s/public static boolean NonBlockingSwapBuffers = .*;/public static boolean NonBlockingSwapBuffers = $NonBlockingSwapBuffers;/" | \ sed "s/public static int AppTouchscreenKeyboardKeysAmount = .*;/public static int AppTouchscreenKeyboardKeysAmount = $AppTouchscreenKeyboardKeysAmount;/" | \ sed "s/public static int AppTouchscreenKeyboardKeysAmountAutoFire = .*;/public static int AppTouchscreenKeyboardKeysAmountAutoFire = $AppTouchscreenKeyboardKeysAmountAutoFire;/" | \ sed "s%public static String ReadmeText = .*%public static String ReadmeText = \"$ReadmeText\".replace(\"^\",\"\\\n\");%" | \ diff --git a/project/AndroidManifest.xml b/project/AndroidManifest.xml index 656163597..725c6a77f 100644 --- a/project/AndroidManifest.xml +++ b/project/AndroidManifest.xml @@ -1,8 +1,8 @@ - Alien Blaster + OpenTyrian diff --git a/project/sdl/sdl-1.3/src/video/android/SDL_androidvideo.c b/project/sdl/sdl-1.3/src/video/android/SDL_androidvideo.c index b02860fd0..180857883 100644 --- a/project/sdl/sdl-1.3/src/video/android/SDL_androidvideo.c +++ b/project/sdl/sdl-1.3/src/video/android/SDL_androidvideo.c @@ -71,17 +71,19 @@ static SDL_ANDROID_ApplicationPutToBackgroundCallback_t appRestoredCallback = ap int SDL_ANDROID_CallJavaSwapBuffers() { - glContextLost = 0; SDL_ANDROID_drawTouchscreenKeyboard(); SDL_ANDROID_processAndroidTrackballDampening(); - (*JavaEnv)->CallIntMethod( JavaEnv, JavaRenderer, JavaSwapBuffers ); + if( ! (*JavaEnv)->CallIntMethod( JavaEnv, JavaRenderer, JavaSwapBuffers ) ) + return 0; if( glContextLost ) { glContextLost = 0; __android_log_print(ANDROID_LOG_INFO, "libSDL", "OpenGL context recreated, refreshing textures"); SDL_ANDROID_VideoContextRecreated(); appRestoredCallback(); + SDL_PrivateAppActive(1, SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS); } + return 1; } @@ -114,6 +116,7 @@ JAVA_EXPORT_NAME(DemoRenderer_nativeGlContextLost) ( JNIEnv* env, jobject thiz __android_log_print(ANDROID_LOG_INFO, "libSDL", "OpenGL context lost, waiting for new OpenGL context"); glContextLost = 1; appPutToBackgroundCallback(); + SDL_PrivateAppActive(0, SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS); SDL_ANDROID_VideoContextLost(); } diff --git a/project/src/Accelerometer.java b/project/src/Accelerometer.java index 8218593d2..b46b829e0 100644 --- a/project/src/Accelerometer.java +++ b/project/src/Accelerometer.java @@ -1,5 +1,5 @@ // This string is autogenerated by ChangeAppSettings.sh, do not change spaces amount -package de.schwardtnet.alienblaster; +package com.googlecode.opentyrian; import android.app.Activity; import android.content.Context; diff --git a/project/src/AssetExtract.java b/project/src/AssetExtract.java index 72f535f7e..e664c297d 100644 --- a/project/src/AssetExtract.java +++ b/project/src/AssetExtract.java @@ -1,6 +1,6 @@ // This string is autogenerated by ChangeAppSettings.sh, do not change // spaces amount -package de.schwardtnet.alienblaster; +package com.googlecode.opentyrian; import java.util.zip.*; import java.io.*; diff --git a/project/src/Audio.java b/project/src/Audio.java index a7a3bf744..9f29bfcb5 100644 --- a/project/src/Audio.java +++ b/project/src/Audio.java @@ -1,5 +1,5 @@ // This string is autogenerated by ChangeAppSettings.sh, do not change spaces amount -package de.schwardtnet.alienblaster; +package com.googlecode.opentyrian; import android.app.Activity; diff --git a/project/src/DataDownloader.java b/project/src/DataDownloader.java index 8362a8d44..5fb78f0d4 100644 --- a/project/src/DataDownloader.java +++ b/project/src/DataDownloader.java @@ -1,5 +1,5 @@ // This string is autogenerated by ChangeAppSettings.sh, do not change spaces amount -package de.schwardtnet.alienblaster; +package com.googlecode.opentyrian; import android.app.Activity; import android.content.Context; diff --git a/project/src/GLSurfaceView_SDL.java b/project/src/GLSurfaceView_SDL.java index 31e6563d7..bc2a20aed 100644 --- a/project/src/GLSurfaceView_SDL.java +++ b/project/src/GLSurfaceView_SDL.java @@ -18,7 +18,7 @@ fixed with a hammer and rasp to work with libSDL port */ // This string is autogenerated by ChangeAppSettings.sh, do not change spaces amount -package de.schwardtnet.alienblaster; +package com.googlecode.opentyrian; import java.io.Writer; import java.util.ArrayList; @@ -950,6 +950,8 @@ public class GLSurfaceView_SDL extends SurfaceView implements SurfaceHolder.Call mRenderer.onSurfaceDestroyed(); mEglHelper.finish(); mNeedStart = true; + if( Globals.NonBlockingSwapBuffers ) + return false; } while (needToWait()) { //Log.v("SDL", "GLSurfaceView_SDL::run(): paused"); @@ -992,6 +994,8 @@ public class GLSurfaceView_SDL extends SurfaceView implements SurfaceHolder.Call mRenderer.onSurfaceDestroyed(); mEglHelper.finish(); mNeedStart = true; + if( Globals.NonBlockingSwapBuffers ) + return false; } } catch (java.lang.InterruptedException e) { diff --git a/project/src/Globals.java b/project/src/Globals.java index 4a48484e5..687832bb9 100644 --- a/project/src/Globals.java +++ b/project/src/Globals.java @@ -1,14 +1,14 @@ // This string is autogenerated by ChangeAppSettings.sh, do not change spaces amount anywhere -package de.schwardtnet.alienblaster; +package com.googlecode.opentyrian; import android.app.Activity; import android.content.Context; class Globals { - public static String ApplicationName = "AlienBlaster"; + public static String ApplicationName = "OpenTyrian"; // Should be zip file - public static String DataDownloadUrl = "Data size is 2 Mb|http://sites.google.com/site/xpelyax/Home/alienblaster110_data.zip?attredirects=0%26d=1|http://sitesproxy.goapk.com/site/xpelyax/Home/alienblaster110_data.zip"; + public static String DataDownloadUrl = "Data files size is 11 Mb|http://sites.google.com/site/xpelyax/Home/tyrian21-data.zip?attredirects=0%26d=1|http://sitesproxy.goapk.com/site/xpelyax/Home/tyrian21-data.zip"; // Set this value to true if you're planning to render 3D using OpenGL - it eats some GFX resources, so disabled for 2D public static boolean NeedDepthBuffer = false; @@ -17,15 +17,17 @@ class Globals { public static boolean HorizontalOrientation = true; // Readme text to be shown on download page - public static String ReadmeText = "^You can press \"Home\" now - the data will be downloaded in background^In game press \"Menu\" for secondary fire, \"Volume Up/Down\" to cycle weapons".replace("^","\n"); + public static String ReadmeText = "^You may press \"Home\" now - the data will be downloaded in background".replace("^","\n"); - public static boolean AppUsesMouse = false; + public static boolean AppUsesMouse = true; public static boolean AppNeedsArrowKeys = true; public static boolean AppUsesJoystick = false; public static boolean AppUsesMultitouch = false; + + public static boolean NonBlockingSwapBuffers = false; public static int AppTouchscreenKeyboardKeysAmount = 4; @@ -48,5 +50,5 @@ class Globals { } class LoadLibrary { - public LoadLibrary() { System.loadLibrary("sdl"); System.loadLibrary("sdl_mixer"); System.loadLibrary("sdl_image"); }; + public LoadLibrary() { System.loadLibrary("sdl"); System.loadLibrary("sdl_net"); }; } diff --git a/project/src/MainActivity.java b/project/src/MainActivity.java index d7addfc83..1c5a7f3d4 100644 --- a/project/src/MainActivity.java +++ b/project/src/MainActivity.java @@ -1,5 +1,5 @@ // This string is autogenerated by ChangeAppSettings.sh, do not change spaces amount -package de.schwardtnet.alienblaster; +package com.googlecode.opentyrian; import android.app.Activity; import android.content.Context; diff --git a/project/src/Settings.java b/project/src/Settings.java index 007deaa36..a664b30c3 100644 --- a/project/src/Settings.java +++ b/project/src/Settings.java @@ -1,5 +1,5 @@ // This string is autogenerated by ChangeAppSettings.sh, do not change spaces amount -package de.schwardtnet.alienblaster; +package com.googlecode.opentyrian; import android.app.Activity; import android.content.Context; diff --git a/project/src/Video.java b/project/src/Video.java index dcf31b911..148fa9222 100644 --- a/project/src/Video.java +++ b/project/src/Video.java @@ -1,5 +1,5 @@ // This string is autogenerated by ChangeAppSettings.sh, do not change spaces amount -package de.schwardtnet.alienblaster; +package com.googlecode.opentyrian; import javax.microedition.khronos.opengles.GL10; @@ -111,6 +111,7 @@ class DemoRenderer extends GLSurfaceView_SDL.Renderer { // Make main thread priority lower so audio thread won't get underrun // Thread.currentThread().setPriority((Thread.currentThread().getPriority() + Thread.MIN_PRIORITY)/2); + mGlContextLost = false; System.loadLibrary("application"); System.loadLibrary("sdl_main"); Settings.Apply(context); @@ -126,8 +127,8 @@ class DemoRenderer extends GLSurfaceView_SDL.Renderer { synchronized (this) { this.notify(); } - mGlContextLost = false; - super.SwapBuffers(); + if( ! super.SwapBuffers() && Globals.NonBlockingSwapBuffers ) + return 0; if(mGlContextLost) { mGlContextLost = false; Settings.SetupTouchscreenKeyboardGraphics(context); // Reload on-screen buttons graphics diff --git a/readme.txt b/readme.txt index cd68a16a2..424a22651 100644 --- a/readme.txt +++ b/readme.txt @@ -168,6 +168,7 @@ where callback_t is function pointer of type "void (*) void". The default callbacks will call another Android-specific functions: SDL_ANDROID_PauseAudioPlayback() and SDL_ANDROID_ResumeAudioPlayback() which will pause and resume audio from HW layer, so appplication does not need to destroy and re-init audio. +Also, the usual event SDL_ACTIVEEVENT with flag SDL_APPACTIVE will be sent when that happens. If you're using pure SDL 1.2 API (with or without HW acceleration) you don't need to worry about anything - the SDL itself will re-create GL textures and fill them with pixel data from existing SDL HW surfaces, @@ -191,19 +192,41 @@ and want a beep when someone connects to you) - you may unpause audio for some s that will require another thread to watch the network, because main thread will be blocked inside SDL_Flip(). The application is not allowed to do any GFX output without OpenGL context (or it will crash), -that's why SDL_Flip() call will block until we're re-acquired context, and the callbacks will be called -from inside SDL_Flip(). so you won't receive SDL_WINDOWEVENT_HIDDEN / SDL_WINDOWEVENT_SHOWN, -because if SDL sends them the application will get them only after SDL_Flip() successfully -re-acquired GL context, and it's too late to pause audio and save application state, -so please use callbacks instead of SDL window events on Android OS (also if your application -is single-threaded you don't need any mutexes inside callbacks). - +that's why SDL_Flip() call will block until we're re-acquired context, and the callbacks will be called +from inside SDL_Flip(). The whole idea behind callbacks is that the existing application should not be modified to operate correctly - the whole time in background will just look to app as one very long SDL_Flip(), so it's good idea to implement some maximum time cap on game frame, so it won't process the game to the end level 'till the app is in background, or calculate the difference in time between appPutToBackground() and appRestored() and update game time variables. +Alternatively, you may enable option for unblocked SDL_Flip() in ChangeAppSettings script, +then you'll have to implement special event loop right after each SDL_Flip() call: + +SDL_Flip(); +SDL_Event evt; +while( SDL_PollEvent(&evt) ) +{ + if( evt.type == SDL_ACTIVEEVENT->SDL_APPACTIVE && evt.active.gain == 0 && evt.active.state == SDL_APPACTIVE ) + { + // We've lost GL context, we are not allowed to do any GFX output here, or app will crash! + while( 1 ) + { + SDL_PollEvent(&evt); + if( evt.type == SDL_ACTIVEEVENT->SDL_APPACTIVE && evt.active.gain && evt.active.state == SDL_APPACTIVE ) + { + SDL_Flip(); // One SDL_Flip() call is required here to restore OpenGL context + // Re-load our textures if we're in SDL+OpenGL mode + // Now we can draw + break; + } + + // Process network stuff, maybe play some sounds using SDL_ANDROID_PauseAudioPlayback() / SDL_ANDROID_ResumeAudioPlayback() + SDL_Sleep(200); + } + } +} + Known bugs ==========