diff --git a/project/sdl/sdl-1.2/src/video/android/SDL_androidvideo-1.2.c b/project/sdl/sdl-1.2/src/video/android/SDL_androidvideo-1.2.c index c4ca7fb66..6f9698d8e 100644 --- a/project/sdl/sdl-1.2/src/video/android/SDL_androidvideo-1.2.c +++ b/project/sdl/sdl-1.2/src/video/android/SDL_androidvideo-1.2.c @@ -111,6 +111,8 @@ int SDL_ANDROID_sFakeWindowHeight = 480; static int sdl_opengl = 0; static SDL_Window *SDL_VideoWindow = NULL; static SDL_Surface *SDL_CurrentVideoSurface = NULL; +static int HwSurfaceCount = 0; +static SDL_Surface ** HwSurfaceList = NULL; static void SdlGlRenderInit(); @@ -256,6 +258,9 @@ SDL_Surface *ANDROID_SetVideoMode(_THIS, SDL_Surface *current, current->h = height; current->pitch = SDL_ANDROID_sFakeWindowWidth * ANDROID_BYTESPERPIXEL; current->pixels = NULL; + current->hwdata = NULL; + HwSurfaceCount = 0; + HwSurfaceList = NULL; if( ! sdl_opengl ) { @@ -292,6 +297,10 @@ SDL_Surface *ANDROID_SetVideoMode(_THIS, SDL_Surface *current, SDL_OutOfMemory(); return(NULL); } + // Register main video texture to be recreated when needed + HwSurfaceCount++; + HwSurfaceList = SDL_realloc( HwSurfaceList, HwSurfaceCount * sizeof(SDL_Surface *) ); + HwSurfaceList[HwSurfaceCount-1] = current; } } @@ -311,6 +320,7 @@ SDL_Surface *ANDROID_SetVideoMode(_THIS, SDL_Surface *current, /* Set up the new mode framebuffer */ SDL_CurrentVideoSurface = current; + /* We're done */ return(current); @@ -323,6 +333,11 @@ void ANDROID_VideoQuit(_THIS) { if( ! sdl_opengl ) { + HwSurfaceCount = 0; + if(HwSurfaceList) + SDL_free(HwSurfaceList); + HwSurfaceList = NULL; + if( SDL_CurrentVideoSurface->hwdata ) SDL_DestroyTexture((struct SDL_Texture *)SDL_CurrentVideoSurface->hwdata); if( SDL_CurrentVideoSurface->pixels ) @@ -402,14 +417,35 @@ static int ANDROID_AllocHWSurface(_THIS, SDL_Surface *surface) surface->flags |= SDL_HWSURFACE | SDL_HWACCEL; + HwSurfaceCount++; + HwSurfaceList = SDL_realloc( HwSurfaceList, HwSurfaceCount * sizeof(SDL_Surface *) ); + HwSurfaceList[HwSurfaceCount-1] = surface; + return 0; } static void ANDROID_FreeHWSurface(_THIS, SDL_Surface *surface) { + int i; if( !surface->hwdata ) return; SDL_DestroyTexture((struct SDL_Texture *)surface->hwdata); + + for( i = 0; i < HwSurfaceCount; i++ ) + { + if( HwSurfaceList[i] == surface ) + { + HwSurfaceCount--; + memmove(HwSurfaceList + i, HwSurfaceList + i + 1, sizeof(SDL_Surface *) * (HwSurfaceCount - i) ); + HwSurfaceList = SDL_realloc( HwSurfaceList, HwSurfaceCount * sizeof(SDL_Surface *) ); + i = -1; + break; + } + } + if( i != -1 ) + { + SDL_SetError("ANDROID_FreeHWSurface: cannot find freed HW surface in HwSurfaceList array"); + } } static int ANDROID_LockHWSurface(_THIS, SDL_Surface *surface) @@ -446,7 +482,6 @@ static int ANDROID_LockHWSurface(_THIS, SDL_Surface *surface) static void ANDROID_UnlockHWSurface(_THIS, SDL_Surface *surface) { SDL_PixelFormat format; - //Uint32 hwformat = SDL_PIXELFORMAT_RGB565; Uint32 hwformat = SDL_PIXELFORMAT_RGBA5551; int bpp; SDL_Surface * converted = NULL; @@ -456,6 +491,9 @@ static void ANDROID_UnlockHWSurface(_THIS, SDL_Surface *surface) if( surface->format->Amask ) hwformat = SDL_PIXELFORMAT_RGBA4444; + + if( surface == SDL_CurrentVideoSurface ) // Special case - we're restoring GL video context + hwformat = SDL_PIXELFORMAT_RGB565; /* Allocate the new pixel format for the screen */ SDL_zero(format); @@ -471,7 +509,7 @@ static void ANDROID_UnlockHWSurface(_THIS, SDL_Surface *surface) format.Bmask == surface->format->Bmask && format.Amask == surface->format->Amask ) { - converted = surface; // This is alpha-surface + converted = surface; // No need for conversion } else { @@ -673,3 +711,40 @@ int ANDROID_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) return(1); } +void SDL_ANDROID_VideoContextLost() +{ + if( ! sdl_opengl ) + { + int i; + for( i = 0; i < HwSurfaceCount; i++ ) + { + SDL_DestroyTexture((struct SDL_Texture *)HwSurfaceList[i]->hwdata); + HwSurfaceList[i]->hwdata = NULL; + } + } +}; + +void SDL_ANDROID_VideoContextRecreated() +{ + if( ! sdl_opengl ) + { + int i; + SDL_SelectRenderer(SDL_VideoWindow); // Re-apply glOrtho() and blend modes + for( i = 0; i < HwSurfaceCount; i++ ) + { + // Allocate HW texture + Uint32 format = SDL_PIXELFORMAT_RGBA5551; // 1-bit alpha for color key, every surface will have colorkey so it's easier for us + if( HwSurfaceList[i]->format->Amask ) + format = SDL_PIXELFORMAT_RGBA4444; + if( HwSurfaceList[i] == SDL_CurrentVideoSurface ) + format = SDL_PIXELFORMAT_RGB565; + HwSurfaceList[i]->hwdata = (struct private_hwdata *)SDL_CreateTexture(format, SDL_TEXTUREACCESS_STATIC, HwSurfaceList[i]->w, HwSurfaceList[i]->h); + if( !HwSurfaceList[i]->hwdata ) + { + SDL_OutOfMemory(); + return; + } + ANDROID_UnlockHWSurface(NULL, HwSurfaceList[i]); // Re-fill texture with graphics + } + } +}; diff --git a/project/sdl/sdl-1.3/src/video/SDL_renderer_gles.c b/project/sdl/sdl-1.3/src/video/SDL_renderer_gles.c index 0b25eb5a2..1250edfc1 100644 --- a/project/sdl/sdl-1.3/src/video/SDL_renderer_gles.c +++ b/project/sdl/sdl-1.3/src/video/SDL_renderer_gles.c @@ -364,6 +364,13 @@ GLES_ActivateRenderer(SDL_Renderer * renderer) if (SDL_GL_MakeCurrent(window, data->context) < 0) { return -1; } + + /* Set up parameters for rendering */ + data->blendMode = -1; + data->glDisable(GL_DEPTH_TEST); + data->glDisable(GL_CULL_FACE); + data->updateSize = SDL_TRUE; + if (data->updateSize) { data->glMatrixMode(GL_PROJECTION); data->glLoadIdentity(); @@ -467,7 +474,8 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) return -1; } - if (texture->access == SDL_TEXTUREACCESS_STREAMING) { + if (texture->access == SDL_TEXTUREACCESS_STREAMING) + { data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format); data->pixels = SDL_malloc(texture->h * data->pitch); if (!data->pixels) { 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 56809fc00..07c4cef4e 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 @@ -66,6 +66,8 @@ int SDL_ANDROID_CallJavaSwapBuffers() if( glContextLost ) { glContextLost = 0; + __android_log_print(ANDROID_LOG_INFO, "libSDL", "OpenGL context recreated, refreshing textures"); + SDL_ANDROID_VideoContextRecreated(); } } @@ -91,10 +93,11 @@ JAVA_EXPORT_NAME(DemoRenderer_nativeDone) ( JNIEnv* env, jobject thiz ) } JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(DemoRenderer_nativeGlContextLost ( JNIEnv* env, jobject thiz ) +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; + SDL_ANDROID_VideoContextLost(); } JNIEXPORT void JNICALL diff --git a/project/sdl/sdl-1.3/src/video/android/SDL_androidvideo.h b/project/sdl/sdl-1.3/src/video/android/SDL_androidvideo.h index 4d674e8f3..f0ca0e619 100644 --- a/project/sdl/sdl-1.3/src/video/android/SDL_androidvideo.h +++ b/project/sdl/sdl-1.3/src/video/android/SDL_androidvideo.h @@ -33,6 +33,8 @@ extern int SDL_ANDROID_sFakeWindowWidth; // SDL 1.2 only extern int SDL_ANDROID_sFakeWindowHeight; // SDL 1.2 only extern int SDL_ANDROID_CallJavaSwapBuffers(); extern int SDL_ANDROID_drawTouchscreenKeyboard(); +extern void SDL_ANDROID_VideoContextLost(); +extern void SDL_ANDROID_VideoContextRecreated(); extern void SDL_ANDROID_processAndroidTrackballDampening(); extern SDL_VideoDevice *ANDROID_CreateDevice_1_3(int devindex); diff --git a/project/src/GLSurfaceView_SDL.java b/project/src/GLSurfaceView_SDL.java index a7a90c140..888acc3f2 100644 --- a/project/src/GLSurfaceView_SDL.java +++ b/project/src/GLSurfaceView_SDL.java @@ -938,12 +938,14 @@ public class GLSurfaceView_SDL extends SurfaceView implements SurfaceHolder.Call while(true) { // Loop until we're re-created GL context and successfully called swap() int w, h; - boolean changed; + boolean changed = false; synchronized (this) { + /* Runnable r; while ((r = getEvent()) != null) { r.run(); } + */ if (mPaused) { mRenderer.onSurfaceDestroyed(); mEglHelper.finish(); @@ -956,7 +958,7 @@ public class GLSurfaceView_SDL extends SurfaceView implements SurfaceHolder.Call if (mDone) { return false; } - changed = mSizeChanged; + // changed = mSizeChanged; w = mWidth; h = mHeight; mSizeChanged = false; diff --git a/project/src/MainActivity.java b/project/src/MainActivity.java index 6c32f7996..1c5a7f3d4 100644 --- a/project/src/MainActivity.java +++ b/project/src/MainActivity.java @@ -80,7 +80,7 @@ public class MainActivity extends Activity { } @Override - protected void onStop() + protected void onDestroy() { if( downloader != null ) { synchronized( downloader ) { @@ -89,8 +89,8 @@ public class MainActivity extends Activity { } if( mGLView != null ) mGLView.exitApp(); - super.onStop(); - finish(); + super.onDestroy(); + System.exit(0); } @Override diff --git a/project/src/Settings.java b/project/src/Settings.java index e36544f93..5e57ff068 100644 --- a/project/src/Settings.java +++ b/project/src/Settings.java @@ -432,6 +432,37 @@ class Settings alert.show(); } + static void Apply(Activity p) + { + nativeIsSdcardUsed( Globals.DownloadToSdcard ? 1 : 0 ); + + if( Globals.PhoneHasTrackball ) + nativeSetTrackballUsed(); + if( Globals.AppUsesMouse ) + nativeSetMouseUsed(); + if( Globals.AppUsesJoystick && !Globals.UseAccelerometerAsArrowKeys ) + nativeSetJoystickUsed(); + if( Globals.AppUsesMultitouch ) + nativeSetMultitouchUsed(); + nativeSetAccelerometerSensitivity(Globals.AccelerometerSensitivity); + nativeSetTrackballDampening(Globals.TrackballDampening); + if( Globals.UseTouchscreenKeyboard ) + { + nativeSetTouchscreenKeyboardUsed(); + nativeSetupScreenKeyboard( Globals.TouchscreenKeyboardSize, + Globals.TouchscreenKeyboardTheme, + Globals.AppTouchscreenKeyboardKeysAmount, + Globals.AppTouchscreenKeyboardKeysAmountAutoFire); + } + SetupTouchscreenKeyboardGraphics(p); + String lang = new String(Locale.getDefault().getLanguage()); + if( Locale.getDefault().getCountry().length() > 0 ) + lang = lang + "_" + Locale.getDefault().getCountry(); + System.out.println( "libSDL: setting envvar LANG to '" + lang + "'"); + nativeSetEnv( "LANG", lang ); + // TODO: get current user name and set envvar USER, the API is not availalbe on Android 1.6 so I don't bother with this + } + static byte [] loadRaw(Activity p,int res) { byte [] buf = new byte[128]; @@ -452,25 +483,10 @@ class Settings return a; } - static void Apply(Activity p) + static void SetupTouchscreenKeyboardGraphics(Activity p) { - nativeIsSdcardUsed( Globals.DownloadToSdcard ? 1 : 0 ); - - if( Globals.PhoneHasTrackball ) - nativeSetTrackballUsed(); - if( Globals.AppUsesMouse ) - nativeSetMouseUsed(); - if( Globals.AppUsesJoystick && !Globals.UseAccelerometerAsArrowKeys ) - nativeSetJoystickUsed(); - if( Globals.AppUsesMultitouch ) - nativeSetMultitouchUsed(); if( Globals.UseTouchscreenKeyboard ) { - nativeSetTouchscreenKeyboardUsed(); - nativeSetupScreenKeyboard( Globals.TouchscreenKeyboardSize, - Globals.TouchscreenKeyboardTheme, - Globals.AppTouchscreenKeyboardKeysAmount, - Globals.AppTouchscreenKeyboardKeysAmountAutoFire); if( Globals.TouchscreenKeyboardTheme == 1 ) { // DPAD @@ -486,8 +502,8 @@ class Settings nativeSetupScreenKeyboardButton(8, loadRaw(p, R.raw.ultimatedroidbutton2autoanim)); // Other buttons nativeSetupScreenKeyboardButton(9, loadRaw(p, R.raw.ultimatedroidbutton1)); - nativeSetupScreenKeyboardButton(10, loadRaw(p, R.raw.ultimatedroidbutton1pressed)); - nativeSetupScreenKeyboardButton(11, loadRaw(p, R.raw.ultimatedroidbutton2)); + nativeSetupScreenKeyboardButton(10, loadRaw(p, R.raw.ultimatedroidbutton1pressed)); + nativeSetupScreenKeyboardButton(11, loadRaw(p, R.raw.ultimatedroidbutton2)); nativeSetupScreenKeyboardButton(12, loadRaw(p, R.raw.ultimatedroidbutton2pressed)); nativeSetupScreenKeyboardButton(13, loadRaw(p, R.raw.ultimatedroidbutton3)); nativeSetupScreenKeyboardButton(14, loadRaw(p, R.raw.ultimatedroidbutton3pressed)); @@ -501,14 +517,6 @@ class Settings nativeSetupScreenKeyboardButton(22, loadRaw(p, R.raw.ultimatedroidbutton7)); } } - nativeSetAccelerometerSensitivity(Globals.AccelerometerSensitivity); - nativeSetTrackballDampening(Globals.TrackballDampening); - String lang = new String(Locale.getDefault().getLanguage()); - if( Locale.getDefault().getCountry().length() > 0 ) - lang = lang + "_" + Locale.getDefault().getCountry(); - System.out.println( "libSDL: setting envvar LANG to '" + lang + "'"); - nativeSetEnv( "LANG", lang ); - // TODO: get current user name and set envvar USER, the API is not availalbe on Android 1.6 so I don't bother with this } static void startDownloader(MainActivity p) diff --git a/project/src/Video.java b/project/src/Video.java index 00aa551f4..5008d5997 100644 --- a/project/src/Video.java +++ b/project/src/Video.java @@ -89,6 +89,7 @@ class DemoRenderer extends GLSurfaceView_SDL.Renderer { public DemoRenderer(Activity _context) { context = _context; + mGlContextLost = false; } public void onSurfaceCreated(GL10 gl, EGLConfig config) { @@ -99,6 +100,7 @@ class DemoRenderer extends GLSurfaceView_SDL.Renderer { } public void onSurfaceDestroyed() { + mGlContextLost = true; nativeGlContextLost(); }; @@ -119,12 +121,18 @@ class DemoRenderer extends GLSurfaceView_SDL.Renderer { System.exit(0); // The main() returns here - I don't bother with deinit stuff, just terminate process } - public int swapBuffers() // Called from native code, returns 1 on success, 0 when GL context lost (user put app to background) + public int swapBuffers() // Called from native code { synchronized (this) { this.notify(); } - return super.SwapBuffers() ? 1 : 0; + mGlContextLost = false; + super.SwapBuffers(); + if(mGlContextLost) { + mGlContextLost = false; + Settings.SetupTouchscreenKeyboardGraphics(context); // Reload on-screen buttons graphics + } + return 1; } public void exitApp() { @@ -143,6 +151,7 @@ class DemoRenderer extends GLSurfaceView_SDL.Renderer { private EGLDisplay mEglDisplay = null; private EGLSurface mEglSurface = null; private EGLContext mEglContext = null; + private boolean mGlContextLost = false; } class DemoGLSurfaceView extends GLSurfaceView_SDL { @@ -156,7 +165,6 @@ class DemoGLSurfaceView extends GLSurfaceView_SDL { setRenderer(mRenderer); } - @Override public boolean onTouchEvent(final MotionEvent event) { @@ -172,8 +180,6 @@ class DemoGLSurfaceView extends GLSurfaceView_SDL { public void exitApp() { mRenderer.exitApp(); - accelerometer.stop(); - accelerometer = null; }; @Override