diff options
author | Max Horn | 2002-11-23 00:13:52 +0000 |
---|---|---|
committer | Max Horn | 2002-11-23 00:13:52 +0000 |
commit | d679af3ec568ca7b7bc4893196d47855e86c875a (patch) | |
tree | 8ae93f65e6363eb5b76c6322003e2225b4070de3 | |
parent | 340a4224253726b3bb9d40608e470038cc7980f1 (diff) | |
download | scummvm-rg350-d679af3ec568ca7b7bc4893196d47855e86c875a.tar.gz scummvm-rg350-d679af3ec568ca7b7bc4893196d47855e86c875a.tar.bz2 scummvm-rg350-d679af3ec568ca7b7bc4893196d47855e86c875a.zip |
fixed bug #621244 (GUI disappeared when screen mode was changed
svn-id: r5697
-rw-r--r-- | backends/sdl/sdl.cpp | 161 |
1 files changed, 84 insertions, 77 deletions
diff --git a/backends/sdl/sdl.cpp b/backends/sdl/sdl.cpp index b4483201a0..70b984c910 100644 --- a/backends/sdl/sdl.cpp +++ b/backends/sdl/sdl.cpp @@ -49,8 +49,8 @@ protected: typedef void ScalerProc(uint8 *srcPtr, uint32 srcPitch, uint8 *deltaPtr, uint8 *dstPtr, uint32 dstPitch, int width, int height); - SDL_Surface *sdl_tmpscreen; // temporary screen (for scalers/overlay) - SDL_Surface *sdl_hwscreen; // hardware screen + SDL_Surface *_tmpscreen; // temporary screen (for scalers/overlay) + SDL_Surface *_hwscreen; // hardware screen bool _overlay_visible; ScalerProc *_scaler_proc; @@ -70,7 +70,7 @@ OSystem_SDL_Common *OSystem_SDL_Common::create() { } OSystem_SDL_Normal::OSystem_SDL_Normal() - : sdl_tmpscreen(0), sdl_hwscreen(0), _overlay_visible(false), + : _tmpscreen(0), _hwscreen(0), _overlay_visible(false), _scaler_proc(0), TMP_SCREEN_WIDTH(0) { } @@ -140,13 +140,13 @@ void OSystem_SDL_Normal::draw_mouse() { // Draw the mouse cursor; backup the covered area in "bak" - if (SDL_LockSurface(sdl_tmpscreen) == -1) + if (SDL_LockSurface(_tmpscreen) == -1) error("SDL_LockSurface failed: %s.\n", SDL_GetError()); // Mark as dirty add_dirty_rect(x, y, w, h); - dst = (uint16 *)sdl_tmpscreen->pixels + (y+1) * TMP_SCREEN_WIDTH + (x+1); + dst = (uint16 *)_tmpscreen->pixels + (y+1) * TMP_SCREEN_WIDTH + (x+1); while (h > 0) { int width = w; while (width > 0) { @@ -163,7 +163,7 @@ void OSystem_SDL_Normal::draw_mouse() { h--; } - SDL_UnlockSurface(sdl_tmpscreen); + SDL_UnlockSurface(_tmpscreen); // Finally, set the flag to indicate the mouse has been drawn _mouseDrawn = true; @@ -178,7 +178,7 @@ void OSystem_SDL_Normal::undraw_mouse() { return; _mouseDrawn = false; - if (SDL_LockSurface(sdl_tmpscreen) == -1) + if (SDL_LockSurface(_tmpscreen) == -1) error("SDL_LockSurface failed: %s.\n", SDL_GetError()); uint16 *dst, *bak = (uint16 *)_mouseBackup; @@ -190,7 +190,7 @@ void OSystem_SDL_Normal::undraw_mouse() { // No need to do clipping here, since draw_mouse() did that already - dst = (uint16 *)sdl_tmpscreen->pixels + (old_mouse_y+1) * TMP_SCREEN_WIDTH + (old_mouse_x+1); + dst = (uint16 *)_tmpscreen->pixels + (old_mouse_y+1) * TMP_SCREEN_WIDTH + (old_mouse_x+1); for (y = 0; y < old_mouse_h; ++y, bak += MAX_MOUSE_W, dst += TMP_SCREEN_WIDTH) { for (x = 0; x < old_mouse_w; ++x) { dst[x] = bak[x]; @@ -199,14 +199,14 @@ void OSystem_SDL_Normal::undraw_mouse() { add_dirty_rect(old_mouse_x, old_mouse_y, old_mouse_w, old_mouse_h); - SDL_UnlockSurface(sdl_tmpscreen); + SDL_UnlockSurface(_tmpscreen); } void OSystem_SDL_Normal::load_gfx_mode() { _forceFull = true; _mode_flags = DF_WANT_RECT_OPTIM | DF_UPDATE_EXPAND_1_PIXEL; - sdl_tmpscreen = NULL; + _tmpscreen = NULL; TMP_SCREEN_WIDTH = (_screenWidth + 3); switch(_mode) { @@ -263,33 +263,33 @@ normal_mode:; // // Create the surface that contains the scaled graphics in 16 bit mode // - sdl_hwscreen = SDL_SetVideoMode(_screenWidth * _scaleFactor, _screenHeight * _scaleFactor, 16, + _hwscreen = SDL_SetVideoMode(_screenWidth * _scaleFactor, _screenHeight * _scaleFactor, 16, _full_screen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE ); - if (sdl_hwscreen == NULL) - error("sdl_hwscreen failed"); + if (_hwscreen == NULL) + error("_hwscreen failed"); // // Create the surface used for the graphics in 16 bit before scaling, and also the overlay // // Distinguish 555 and 565 mode - if (sdl_hwscreen->format->Rmask == 0x7C00) + if (_hwscreen->format->Rmask == 0x7C00) Init_2xSaI(555); else Init_2xSaI(565); // Need some extra bytes around when using 2xSaI - uint16 *tmp_screen = (uint16*)calloc(TMP_SCREEN_WIDTH*(_screenHeight+3),sizeof(uint16)); - sdl_tmpscreen = SDL_CreateRGBSurfaceFrom(tmp_screen, + uint16 *tmp_screen = (uint16*)calloc(TMP_SCREEN_WIDTH*(_screenHeight+3), sizeof(uint16)); + _tmpscreen = SDL_CreateRGBSurfaceFrom(tmp_screen, TMP_SCREEN_WIDTH, _screenHeight + 3, 16, TMP_SCREEN_WIDTH*2, - sdl_hwscreen->format->Rmask, - sdl_hwscreen->format->Gmask, - sdl_hwscreen->format->Bmask, - sdl_hwscreen->format->Amask); + _hwscreen->format->Rmask, + _hwscreen->format->Gmask, + _hwscreen->format->Bmask, + _hwscreen->format->Amask); - if (sdl_tmpscreen == NULL) - error("sdl_tmpscreen failed"); + if (_tmpscreen == NULL) + error("_tmpscreen failed"); // keyboard cursor control, some other better place for it? km.x_max = _screenWidth * _scaleFactor - 1; @@ -305,26 +305,56 @@ void OSystem_SDL_Normal::unload_gfx_mode() { _screen = NULL; } - if (sdl_hwscreen) { - SDL_FreeSurface(sdl_hwscreen); - sdl_hwscreen = NULL; + if (_hwscreen) { + SDL_FreeSurface(_hwscreen); + _hwscreen = NULL; } - if (sdl_tmpscreen) { - free((uint16*)sdl_tmpscreen->pixels); - SDL_FreeSurface(sdl_tmpscreen); - sdl_tmpscreen = NULL; + if (_tmpscreen) { + free(_tmpscreen->pixels); + SDL_FreeSurface(_tmpscreen); + _tmpscreen = NULL; } } +void OSystem_SDL_Normal::hotswap_gfx_mode() { + + + // Keep around the old _screen & _tmpscreen so we can restore the screen data + // after the mode switch. + SDL_Surface *old_screen = _screen; + SDL_Surface *old_tmpscreen = _tmpscreen; + + // Release the HW screen surface + SDL_FreeSurface(_hwscreen); + + // Setup the new GFX mode + load_gfx_mode(); + + // reset palette + SDL_SetColors(_screen, _currentPalette, 0, 256); + + // Restore old screen content + SDL_BlitSurface(old_screen, NULL, _screen, NULL); + SDL_BlitSurface(old_tmpscreen, NULL, _tmpscreen, NULL); + + // Free the old surfaces + SDL_FreeSurface(old_screen); + free(old_tmpscreen->pixels); + SDL_FreeSurface(old_tmpscreen); + + // Finally, blit everything to the screen + update_screen(); +} + void OSystem_SDL_Normal::update_screen() { - assert(sdl_hwscreen != NULL); + assert(_hwscreen != NULL); // If the shake position changed, fill the dirty area with blackness if (_currentShakePos != _newShakePos) { SDL_Rect blackrect = {0, 0, _screenWidth*_scaleFactor, _newShakePos*_scaleFactor}; - SDL_FillRect(sdl_hwscreen, &blackrect, 0); + SDL_FillRect(_hwscreen, &blackrect, 0); _currentShakePos = _newShakePos; @@ -370,16 +400,16 @@ void OSystem_SDL_Normal::update_screen() { dst = *r; dst.x++; // Shift rect by one since 2xSai needs to acces the data around dst.y++; // any pixel to scale it, and we want to avoid mem access crashes. - if (SDL_BlitSurface(_screen, r, sdl_tmpscreen, &dst) != 0) + if (SDL_BlitSurface(_screen, r, _tmpscreen, &dst) != 0) error("SDL_BlitSurface failed: %s", SDL_GetError()); } } - SDL_LockSurface(sdl_tmpscreen); - SDL_LockSurface(sdl_hwscreen); + SDL_LockSurface(_tmpscreen); + SDL_LockSurface(_hwscreen); - srcPitch = sdl_tmpscreen->pitch; - dstPitch = sdl_hwscreen->pitch; + srcPitch = _tmpscreen->pitch; + dstPitch = _hwscreen->pitch; for(r = _dirty_rect_list; r != last_rect; ++r) { register int dst_y = r->y + _currentShakePos; @@ -391,8 +421,8 @@ void OSystem_SDL_Normal::update_screen() { dst_y *= _scaleFactor; - _scaler_proc((byte*)sdl_tmpscreen->pixels + (r->x*2+2) + (r->y+1)*srcPitch, srcPitch, NULL, - (byte*)sdl_hwscreen->pixels + r->x*2*_scaleFactor + dst_y*dstPitch, dstPitch, r->w, dst_h); + _scaler_proc((byte*)_tmpscreen->pixels + (r->x*2+2) + (r->y+1)*srcPitch, srcPitch, NULL, + (byte*)_hwscreen->pixels + r->x*2*_scaleFactor + dst_y*dstPitch, dstPitch, r->w, dst_h); } r->x *= _scaleFactor; @@ -401,8 +431,8 @@ void OSystem_SDL_Normal::update_screen() { r->h = dst_h * _scaleFactor; } - SDL_UnlockSurface(sdl_tmpscreen); - SDL_UnlockSurface(sdl_hwscreen); + SDL_UnlockSurface(_tmpscreen); + SDL_UnlockSurface(_hwscreen); // Readjust the dirty rect list in case we are doing a full update. // This is necessary if shaking is active. @@ -412,50 +442,27 @@ void OSystem_SDL_Normal::update_screen() { } // Finally, blit all our changes to the screen - SDL_UpdateRects(sdl_hwscreen, _num_dirty_rects, _dirty_rect_list); + SDL_UpdateRects(_hwscreen, _num_dirty_rects, _dirty_rect_list); } _num_dirty_rects = 0; _forceFull = false; } -void OSystem_SDL_Normal::hotswap_gfx_mode() { - /* We allocate a screen sized bitmap which contains a "backup" - * of the screen data during the change. Then we draw that to - * the new screen right after it's setup. - */ - - byte *bak_mem = (byte*)malloc(_screenWidth*_screenHeight); - - get_screen_image(bak_mem); - - unload_gfx_mode(); - load_gfx_mode(); - - // reset palette - SDL_SetColors(_screen, _currentPalette, 0, 256); - - // blit image - copy_rect(bak_mem, _screenWidth, 0, 0, _screenWidth, _screenHeight); - free(bak_mem); - - update_screen(); -} - uint32 OSystem_SDL_Normal::property(int param, Property *value) { if (param == PROP_TOGGLE_FULLSCREEN) { - assert(sdl_hwscreen != 0); + assert(_hwscreen != 0); _full_screen ^= true; - if (!SDL_WM_ToggleFullScreen(sdl_hwscreen)) { + if (!SDL_WM_ToggleFullScreen(_hwscreen)) { // if ToggleFullScreen fails, achieve the same effect with hotswap gfx mode hotswap_gfx_mode(); } return 1; } else if (param == PROP_OVERLAY_IS_565) { - assert(sdl_tmpscreen != 0); - return (sdl_tmpscreen->format->Rmask != 0x7C00); + assert(_tmpscreen != 0); + return (_tmpscreen->format->Rmask != 0x7C00); } return OSystem_SDL_Common::property(param, value); @@ -494,7 +501,7 @@ void OSystem_SDL_Normal::clear_overlay() dst.x = dst.y = 1; src.w = dst.w = _screenWidth; src.h = dst.h = _screenHeight; - if (SDL_BlitSurface(_screen, &src, sdl_tmpscreen, &dst) != 0) + if (SDL_BlitSurface(_screen, &src, _tmpscreen, &dst) != 0) error("SDL_BlitSurface failed: %s", SDL_GetError()); _forceFull = true; @@ -505,16 +512,16 @@ void OSystem_SDL_Normal::grab_overlay(int16 *buf, int pitch) if (!_overlay_visible) return; - if (sdl_tmpscreen == NULL) + if (_tmpscreen == NULL) return; // hide the mouse undraw_mouse(); - if (SDL_LockSurface(sdl_tmpscreen) == -1) + if (SDL_LockSurface(_tmpscreen) == -1) error("SDL_LockSurface failed: %s.\n", SDL_GetError()); - int16 *src = (int16 *)sdl_tmpscreen->pixels + TMP_SCREEN_WIDTH + 1; + int16 *src = (int16 *)_tmpscreen->pixels + TMP_SCREEN_WIDTH + 1; int h = _screenHeight; do { memcpy(buf, src, _screenWidth*2); @@ -522,7 +529,7 @@ void OSystem_SDL_Normal::grab_overlay(int16 *buf, int pitch) buf += pitch; } while (--h); - SDL_UnlockSurface(sdl_tmpscreen); + SDL_UnlockSurface(_tmpscreen); } void OSystem_SDL_Normal::copy_rect_overlay(const int16 *buf, int pitch, int x, int y, int w, int h) @@ -530,7 +537,7 @@ void OSystem_SDL_Normal::copy_rect_overlay(const int16 *buf, int pitch, int x, i if (!_overlay_visible) return; - if (sdl_tmpscreen == NULL) + if (_tmpscreen == NULL) return; // Clip the coordinates @@ -548,17 +555,17 @@ void OSystem_SDL_Normal::copy_rect_overlay(const int16 *buf, int pitch, int x, i /* FIXME: undraw mouse only if the draw rect intersects with the mouse rect */ undraw_mouse(); - if (SDL_LockSurface(sdl_tmpscreen) == -1) + if (SDL_LockSurface(_tmpscreen) == -1) error("SDL_LockSurface failed: %s.\n", SDL_GetError()); - int16 *dst = (int16 *)sdl_tmpscreen->pixels + (y+1) * TMP_SCREEN_WIDTH + (x+1); + int16 *dst = (int16 *)_tmpscreen->pixels + (y+1) * TMP_SCREEN_WIDTH + (x+1); do { memcpy(dst, buf, w*2); dst += TMP_SCREEN_WIDTH; buf += pitch; } while (--h); - SDL_UnlockSurface(sdl_tmpscreen); + SDL_UnlockSurface(_tmpscreen); } |