From 9d168228e765ad7f3a0a51c99294de7ec00689be Mon Sep 17 00:00:00 2001 From: rubidium Date: Sun, 4 Mar 2012 16:33:13 +0000 Subject: [PATCH] (svn r24003) [1.2] -Backport from trunk: - Fix: Do not load a game during UpdateWindows as that might trigger changing the blitter which triggers re-entrant locking (r23980, r23977) - Fix: [SDL] Palette update was done too late making switching from 8bpp -> 32bpp look ugly (r23978) - Fix: Sprites of different zoom levels were not always padded correctly to a common size (r23976) - Fix: Also save the maximum travel speed for the current vehicle order (r23973) --- src/gfx.cpp | 9 ++++---- src/saveload/saveload.cpp | 5 +++-- src/saveload/vehicle_sl.cpp | 1 + src/spritecache.cpp | 45 ++++++++++++++++++++----------------- src/video/sdl_v.cpp | 16 ++++++++++++- 5 files changed, 49 insertions(+), 27 deletions(-) diff --git a/src/gfx.cpp b/src/gfx.cpp index 55721e0525..5a5c459728 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -1732,10 +1732,11 @@ void DrawDirtyBlocks() _modal_progress_paint_mutex->BeginCritical(); _modal_progress_work_mutex->BeginCritical(); - if (_switch_mode != SM_NONE && !HasModalProgress()) { - SwitchToMode(_switch_mode); - _switch_mode = SM_NONE; - } + /* When we ended with the modal progress, do not draw the blocks. + * Simply let the next run do so, otherwise we would be loading + * the new state (and possibly change the blitter) when we hold + * the drawing lock, which we must not do. */ + if (_switch_mode != SM_NONE && !HasModalProgress()) return; } y = 0; diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 22725ca005..b834123355 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -236,9 +236,10 @@ * 170 23826 * 171 23835 * 172 23947 - * 173 23967 1.2.x + * 173 23967 1.2.0-RC1 + * 174 23973 1.2.x */ -extern const uint16 SAVEGAME_VERSION = 173; ///< Current savegame version of OpenTTD. +extern const uint16 SAVEGAME_VERSION = 174; ///< Current savegame version of OpenTTD. SavegameType _savegame_type; ///< type of savegame we are loading diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 6087c347fe..416b0f0e9c 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -628,6 +628,7 @@ const SaveLoad *GetVehicleDescription(VehicleType vt) /* Timetable in current order */ SLE_CONDVAR(Vehicle, current_order.wait_time, SLE_UINT16, 67, SL_MAX_VERSION), SLE_CONDVAR(Vehicle, current_order.travel_time, SLE_UINT16, 67, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, current_order.max_speed, SLE_UINT16, 174, SL_MAX_VERSION), SLE_CONDVAR(Vehicle, timetable_start, SLE_INT32, 129, SL_MAX_VERSION), SLE_CONDREF(Vehicle, orders, REF_ORDER, 0, 104), diff --git a/src/spritecache.cpp b/src/spritecache.cpp index d4f23d0e0e..c77d3c5460 100644 --- a/src/spritecache.cpp +++ b/src/spritecache.cpp @@ -264,33 +264,37 @@ static bool PadSingleSprite(SpriteLoader::Sprite *sprite, ZoomLevel zoom, uint p static bool PadSprites(SpriteLoader::Sprite *sprite, uint8 sprite_avail) { - int left = sprite[ZOOM_LVL_NORMAL].x_offs; - int top = sprite[ZOOM_LVL_NORMAL].y_offs; - int right = sprite[ZOOM_LVL_NORMAL].x_offs + sprite[ZOOM_LVL_NORMAL].width; - int bottom = sprite[ZOOM_LVL_NORMAL].y_offs + sprite[ZOOM_LVL_NORMAL].height; - - /* Find combined bounds of all zoom levels.*/ - for (ZoomLevel zoom = ZOOM_LVL_OUT_2X; zoom != ZOOM_LVL_END; zoom++) { + /* Get minimum top left corner coordinates. */ + int min_xoffs = INT32_MAX; + int min_yoffs = INT32_MAX; + for (ZoomLevel zoom = ZOOM_LVL_BEGIN; zoom != ZOOM_LVL_END; zoom++) { if (HasBit(sprite_avail, zoom)) { - uint8 scaled_1 = ScaleByZoom(1, zoom); - - left = min(left, sprite[zoom].x_offs * scaled_1); - top = min(top, sprite[zoom].y_offs * scaled_1); - right = max(right, (sprite[zoom].x_offs + sprite[zoom].width - 1) * scaled_1); - bottom = max(bottom, (sprite[zoom].y_offs + sprite[zoom].height - 1) * scaled_1); + min_xoffs = min(min_xoffs, ScaleByZoom(sprite[zoom].x_offs, zoom)); + min_yoffs = min(min_yoffs, ScaleByZoom(sprite[zoom].y_offs, zoom)); } } - /* Pad too small sprites. */ - SetBit(sprite_avail, ZOOM_LVL_NORMAL); + /* Get maximum dimensions taking necessary padding at the top left into account. */ + int max_width = INT32_MIN; + int max_height = INT32_MIN; for (ZoomLevel zoom = ZOOM_LVL_BEGIN; zoom != ZOOM_LVL_END; zoom++) { if (HasBit(sprite_avail, zoom)) { - int pad_left = sprite[zoom].x_offs - UnScaleByZoom(left, zoom); - int pad_top = sprite[zoom].y_offs - UnScaleByZoom(top, zoom); - int pad_right = UnScaleByZoom(right, zoom) - (sprite[zoom].x_offs + sprite[zoom].width); - int pad_bottom = UnScaleByZoom(bottom, zoom) - (sprite[zoom].y_offs + sprite[zoom].height); + max_width = max(max_width, ScaleByZoom(sprite[zoom].width + sprite[zoom].x_offs - UnScaleByZoom(min_xoffs, zoom), zoom)); + max_height = max(max_height, ScaleByZoom(sprite[zoom].height + sprite[zoom].y_offs - UnScaleByZoom(min_yoffs, zoom), zoom)); + } + } - if (pad_left != 0 || pad_right != 0 || pad_top != 0 || pad_bottom != 0) { + /* Pad sprites where needed. */ + for (ZoomLevel zoom = ZOOM_LVL_BEGIN; zoom != ZOOM_LVL_END; zoom++) { + if (HasBit(sprite_avail, zoom)) { + /* Scaling the sprite dimensions in the blitter is done with rounding up, + * so a negative padding here is not an error. */ + int pad_left = max(0, sprite[zoom].x_offs - UnScaleByZoom(min_xoffs, zoom)); + int pad_top = max(0, sprite[zoom].y_offs - UnScaleByZoom(min_yoffs, zoom)); + int pad_right = max(0, UnScaleByZoom(max_width, zoom) - sprite[zoom].width - pad_left); + int pad_bottom = max(0, UnScaleByZoom(max_height, zoom) - sprite[zoom].height - pad_top); + + if (pad_left > 0 || pad_right > 0 || pad_top > 0 || pad_bottom > 0) { if (!PadSingleSprite(&sprite[zoom], zoom, pad_left, pad_top, pad_right, pad_bottom)) return false; } } @@ -305,6 +309,7 @@ static bool ResizeSprites(SpriteLoader::Sprite *sprite, uint8 sprite_avail, uint ZoomLevel first_avail = static_cast(FIND_FIRST_BIT(sprite_avail)); if (first_avail != ZOOM_LVL_NORMAL) { if (!ResizeSpriteIn(sprite, first_avail, ZOOM_LVL_NORMAL)) return false; + SetBit(sprite_avail, ZOOM_LVL_NORMAL); } /* Pad sprites to make sizes match. */ diff --git a/src/video/sdl_v.cpp b/src/video/sdl_v.cpp index 663de4ebf2..34d31212ec 100644 --- a/src/video/sdl_v.cpp +++ b/src/video/sdl_v.cpp @@ -258,9 +258,23 @@ static bool CreateMainSurface(uint w, uint h) _screen.dst_ptr = newscreen->pixels; _sdl_screen = newscreen; - BlitterFactoryBase::GetCurrentBlitter()->PostResize(); + Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter(); + blitter->PostResize(); InitPalette(); + switch (blitter->UsePaletteAnimation()) { + case Blitter::PALETTE_ANIMATION_NONE: + case Blitter::PALETTE_ANIMATION_VIDEO_BACKEND: + UpdatePalette(); + break; + + case Blitter::PALETTE_ANIMATION_BLITTER: + if (_video_driver != NULL) blitter->PaletteAnimate(_local_palette); + break; + + default: + NOT_REACHED(); + } snprintf(caption, sizeof(caption), "OpenTTD %s", _openttd_revision); SDL_CALL SDL_WM_SetCaption(caption, caption);