From fd41a03480c4ff23325eb9ab6b7eba4daff80314 Mon Sep 17 00:00:00 2001 From: pelya Date: Wed, 29 Sep 2010 15:32:40 +0300 Subject: [PATCH] SDL 1.3 WILL NOT COMPILE! OpenTyrian can be successfully put to background and restored, yay! However music keeps playing while on background, little annoying. Also I'm not sure how my code will behave on Android 1.6 --- .../src/video/android/SDL_androidvideo-1.2.c | 79 ++++++++++++++++++- .../sdl/sdl-1.3/src/video/SDL_renderer_gles.c | 10 ++- .../src/video/android/SDL_androidvideo.c | 5 +- .../src/video/android/SDL_androidvideo.h | 2 + project/src/GLSurfaceView_SDL.java | 6 +- project/src/MainActivity.java | 6 +- project/src/Settings.java | 60 ++++++++------ project/src/Video.java | 16 ++-- 8 files changed, 144 insertions(+), 40 deletions(-) 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