From 2d995bbe074cd1badd3cfef05f727de52ec74fa0 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 14 Mar 2022 21:33:38 -0700 Subject: [PATCH] AGS: Simplified use of ReplaceBitmapWithSupportedFormat() From upstream 2132ba833b9d4508ed3f81a65f531b88f6087cb5 --- engines/ags/engine/ac/dialog.cpp | 4 +- engines/ags/engine/ac/draw.cpp | 70 +++++++++---------- engines/ags/engine/ac/draw.h | 10 +-- engines/ags/engine/ac/dynamic_sprite.cpp | 7 +- engines/ags/engine/ac/game.cpp | 2 +- .../ags/engine/ac/global_dynamic_sprite.cpp | 2 +- engines/ags/engine/ac/screen.cpp | 1 - engines/ags/engine/gui/gui_dialog.cpp | 3 +- 8 files changed, 47 insertions(+), 52 deletions(-) diff --git a/engines/ags/engine/ac/dialog.cpp b/engines/ags/engine/ac/dialog.cpp index 98c181a14dc..0e262a32300 100644 --- a/engines/ags/engine/ac/dialog.cpp +++ b/engines/ags/engine/ac/dialog.cpp @@ -766,8 +766,8 @@ void DialogOptions::Redraw() { update_polled_stuff_if_runtime(); - subBitmap = recycle_bitmap(subBitmap, tempScrn->GetColorDepth(), dirtywidth, dirtyheight); - subBitmap = ReplaceBitmapWithSupportedFormat(subBitmap); + subBitmap = recycle_bitmap(subBitmap, + _G(gfxDriver)->GetCompatibleBitmapFormat(tempScrn->GetColorDepth()), dirtywidth, dirtyheight); update_polled_stuff_if_runtime(); diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp index f72ed968335..e0177b19098 100644 --- a/engines/ags/engine/ac/draw.cpp +++ b/engines/ags/engine/ac/draw.cpp @@ -155,8 +155,14 @@ Bitmap *convert_32_to_32bgr(Bitmap *tempbl) { // Bitmap *AdjustBitmapForUseWithDisplayMode(Bitmap *bitmap, bool has_alpha) { const int bmp_col_depth = bitmap->GetColorDepth(); - // const int sys_col_depth = System_GetColorDepth(); + const int sys_col_depth = System_GetColorDepth(); const int game_col_depth = _GP(game).GetColorDepth(); + const int compat_col_depth = _G(gfxDriver)->GetCompatibleBitmapFormat(game_col_depth); + + const bool must_switch_palette = bitmap->GetColorDepth() == 8 && game_col_depth > 8; + if (must_switch_palette) + select_palette(_G(palette)); + Bitmap *new_bitmap = bitmap; // @@ -184,54 +190,48 @@ Bitmap *AdjustBitmapForUseWithDisplayMode(Bitmap *bitmap, bool has_alpha) { } // In 32-bit game hicolor bitmaps must be converted to the true color else if (game_col_depth == 32 && (bmp_col_depth > 8 && bmp_col_depth <= 16)) { - new_bitmap = BitmapHelper::CreateBitmapCopy(bitmap, game_col_depth); + new_bitmap = BitmapHelper::CreateBitmapCopy(bitmap, compat_col_depth); } // In non-32-bit game truecolor bitmaps must be downgraded else if (game_col_depth <= 16 && bmp_col_depth > 16) { if (has_alpha) // if has valid alpha channel, convert it to regular transparency mask new_bitmap = remove_alpha_channel(bitmap); else // else simply convert bitmap - new_bitmap = BitmapHelper::CreateBitmapCopy(bitmap, game_col_depth); + new_bitmap = BitmapHelper::CreateBitmapCopy(bitmap, compat_col_depth); } // Special case when we must convert 16-bit RGB to BGR else if (_G(convert_16bit_bgr) == 1 && bmp_col_depth == 16) { new_bitmap = convert_16_to_16bgr(bitmap); } - return new_bitmap; -} -Bitmap *ReplaceBitmapWithSupportedFormat(Bitmap *bitmap) { - Bitmap *new_bitmap = GfxUtil::ConvertBitmap(bitmap, _G(gfxDriver)->GetCompatibleBitmapFormat(bitmap->GetColorDepth())); - if (new_bitmap != bitmap) - delete bitmap; - return new_bitmap; -} - -Bitmap *PrepareSpriteForUse(Bitmap *bitmap, bool has_alpha) { - bool must_switch_palette = bitmap->GetColorDepth() == 8 && _GP(game).GetColorDepth() > 8; - if (must_switch_palette) - select_palette(_G(palette)); - - Bitmap *new_bitmap = AdjustBitmapForUseWithDisplayMode(bitmap, has_alpha); - if (new_bitmap != bitmap) - delete bitmap; - new_bitmap = ReplaceBitmapWithSupportedFormat(new_bitmap); + // Finally, if we did not create a new copy already, - convert to driver compatible format + if ((new_bitmap == bitmap) && (bmp_col_depth != compat_col_depth)) + new_bitmap = GfxUtil::ConvertBitmap(bitmap, compat_col_depth); if (must_switch_palette) unselect_palette(); + + return new_bitmap; +} + +Bitmap *CreateCompatBitmap(int width, int height, int col_depth) { + return new Bitmap(width, height, + _G(gfxDriver)->GetCompatibleBitmapFormat(col_depth == 0 ? _GP(game).GetColorDepth() : col_depth)); +} + +Bitmap *ReplaceBitmapWithSupportedFormat(Bitmap *bitmap) { + return GfxUtil::ConvertBitmap(bitmap, _G(gfxDriver)->GetCompatibleBitmapFormat(bitmap->GetColorDepth())); +} + +Bitmap *PrepareSpriteForUse(Bitmap *bitmap, bool has_alpha) { + Bitmap *new_bitmap = AdjustBitmapForUseWithDisplayMode(bitmap, has_alpha); + if (new_bitmap != bitmap) + delete bitmap; return new_bitmap; } PBitmap PrepareSpriteForUse(PBitmap bitmap, bool has_alpha) { - bool must_switch_palette = bitmap->GetColorDepth() == 8 && System_GetColorDepth() > 8; - if (must_switch_palette) - select_palette(_G(palette)); - Bitmap *new_bitmap = AdjustBitmapForUseWithDisplayMode(bitmap.get(), has_alpha); - new_bitmap = ReplaceBitmapWithSupportedFormat(new_bitmap); - - if (must_switch_palette) - unselect_palette(); return new_bitmap == bitmap.get() ? bitmap : PBitmap(new_bitmap); // if bitmap is same, don't create new smart ptr! } @@ -349,8 +349,7 @@ void create_blank_image(int coldepth) { // so it's the most likey place for a crash //try //{ - Bitmap *blank = BitmapHelper::CreateBitmap(16, 16, coldepth); - blank = ReplaceBitmapWithSupportedFormat(blank); + Bitmap *blank = CreateCompatBitmap(16, 16, coldepth); blank->Clear(); _G(blankImage) = _G(gfxDriver)->CreateDDBFromBitmap(blank, false, true); _G(blankSidebarImage) = _G(gfxDriver)->CreateDDBFromBitmap(blank, false, true); @@ -1049,8 +1048,7 @@ Bitmap *recycle_bitmap(Bitmap *bimp, int coldep, int wid, int hit, bool make_tra void recreate_guibg_image(GUIMain *tehgui) { int ifn = tehgui->ID; delete _GP(guibg)[ifn]; - _GP(guibg)[ifn] = BitmapHelper::CreateBitmap(tehgui->Width, tehgui->Height, _GP(game).GetColorDepth()); - _GP(guibg)[ifn] = ReplaceBitmapWithSupportedFormat(_GP(guibg)[ifn]); + _GP(guibg)[ifn] = CreateCompatBitmap(tehgui->Width, tehgui->Height); if (_GP(guibgbmp)[ifn] != nullptr) { _G(gfxDriver)->DestroyDDB(_GP(guibgbmp)[ifn]); @@ -1917,8 +1915,7 @@ void draw_fps(const Rect &viewport) { static Bitmap *fpsDisplay = nullptr; const int font = FONT_NORMAL; if (fpsDisplay == nullptr) { - fpsDisplay = BitmapHelper::CreateBitmap(viewport.GetWidth(), (getfontheight_outlined(font) + get_fixed_pixel_size(5)), _GP(game).GetColorDepth()); - fpsDisplay = ReplaceBitmapWithSupportedFormat(fpsDisplay); + fpsDisplay = CreateCompatBitmap(viewport.GetWidth(), (getfontheight_outlined(font) + get_fixed_pixel_size(5)), _GP(game).GetColorDepth()); } fpsDisplay->ClearTransparent(); @@ -2274,8 +2271,7 @@ void construct_engine_overlay() { int barheight = getheightoflines(font, DEBUG_CONSOLE_NUMLINES - 1) + 4; if (_G(debugConsoleBuffer) == nullptr) { - _G(debugConsoleBuffer) = BitmapHelper::CreateBitmap(viewport.GetWidth(), barheight, _GP(game).GetColorDepth()); - _G(debugConsoleBuffer) = ReplaceBitmapWithSupportedFormat(_G(debugConsoleBuffer)); + _G(debugConsoleBuffer) = CreateCompatBitmap(viewport.GetWidth(), barheight); } color_t draw_color = _G(debugConsoleBuffer)->GetCompatibleColor(15); diff --git a/engines/ags/engine/ac/draw.h b/engines/ags/engine/ac/draw.h index 00ec67e08ec..9a5bccce96d 100644 --- a/engines/ags/engine/ac/draw.h +++ b/engines/ags/engine/ac/draw.h @@ -178,11 +178,11 @@ extern AGS_INLINE int game_to_ctx_data_size(int size, bool hires_ctx); // This function converts game coordinates coming from script to the actual game resolution. extern AGS_INLINE void defgame_to_finalgame_coords(int &x, int &y); -// Checks if the bitmap needs to be converted and **deletes original** if a new bitmap -// had to be created (by default). -// TODO: this helper function was meant to remove bitmap deletion from the GraphicsDriver's -// implementations while keeping code changes to minimum. The proper solution would probably -// be to use shared pointers when storing Bitmaps, or make Bitmap reference-counted object. +// Creates bitmap of a format compatible with the gfxdriver; +// if col_depth is 0, uses game's native color depth. +Shared::Bitmap *CreateCompatBitmap(int width, int height, int col_depth = 0); +// Checks if the bitmap is compatible with the gfxdriver; +// returns same bitmap or its copy of a compatible format. Shared::Bitmap *ReplaceBitmapWithSupportedFormat(Shared::Bitmap *bitmap); // Checks if the bitmap needs any kind of adjustments before it may be used // in AGS sprite operations. Also handles number of certain special cases diff --git a/engines/ags/engine/ac/dynamic_sprite.cpp b/engines/ags/engine/ac/dynamic_sprite.cpp index 6e4f68eb0db..f64067144d7 100644 --- a/engines/ags/engine/ac/dynamic_sprite.cpp +++ b/engines/ags/engine/ac/dynamic_sprite.cpp @@ -322,7 +322,7 @@ ScriptDynamicSprite *DynamicSprite_CreateFromScreenShot(int width, int height) { update_polled_stuff_if_runtime(); // replace the bitmap in the sprite set - add_dynamic_sprite(gotSlot, ReplaceBitmapWithSupportedFormat(newPic)); + add_dynamic_sprite(gotSlot, newPic); ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(gotSlot); return new_spr; } @@ -385,14 +385,15 @@ ScriptDynamicSprite *DynamicSprite_Create(int width, int height, int alphaChanne if (gotSlot <= 0) return nullptr; - Bitmap *newPic = BitmapHelper::CreateTransparentBitmap(width, height, _GP(game).GetColorDepth()); + Bitmap *newPic = CreateCompatBitmap(width, height); if (newPic == nullptr) return nullptr; + newPic->ClearTransparent(); if ((alphaChannel) && (_GP(game).GetColorDepth() < 32)) alphaChannel = false; - add_dynamic_sprite(gotSlot, ReplaceBitmapWithSupportedFormat(newPic), alphaChannel != 0); + add_dynamic_sprite(gotSlot, newPic, alphaChannel != 0); ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(gotSlot); return new_spr; } diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index d6ebdf22709..0e55ad221d2 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -961,7 +961,7 @@ bool read_savedgame_screenshot(const String &savedgame, int &want_shot) { int slot = _GP(spriteset).GetFreeIndex(); if (slot > 0) { // add it into the sprite set - add_dynamic_sprite(slot, ReplaceBitmapWithSupportedFormat(desc.UserImage.release())); + add_dynamic_sprite(slot, PrepareSpriteForUse(desc.UserImage.release(), false)); want_shot = slot; } } diff --git a/engines/ags/engine/ac/global_dynamic_sprite.cpp b/engines/ags/engine/ac/global_dynamic_sprite.cpp index 2891916577b..bccc16e00cf 100644 --- a/engines/ags/engine/ac/global_dynamic_sprite.cpp +++ b/engines/ags/engine/ac/global_dynamic_sprite.cpp @@ -48,7 +48,7 @@ int LoadImageFile(const char *filename) { if (gotSlot <= 0) return 0; - add_dynamic_sprite(gotSlot, ReplaceBitmapWithSupportedFormat(loadedFile)); + add_dynamic_sprite(gotSlot, PrepareSpriteForUse(loadedFile, false)); return gotSlot; } diff --git a/engines/ags/engine/ac/screen.cpp b/engines/ags/engine/ac/screen.cpp index 89d01aa4f08..a2fc8de46b1 100644 --- a/engines/ags/engine/ac/screen.cpp +++ b/engines/ags/engine/ac/screen.cpp @@ -85,7 +85,6 @@ IDriverDependantBitmap *prepare_screen_for_transition_in() { if (_G(saved_viewport_bitmap) == nullptr) quit("Crossfade: buffer is null attempting transition"); - _G(saved_viewport_bitmap) = ReplaceBitmapWithSupportedFormat(_G(saved_viewport_bitmap)); const Rect &viewport = _GP(play).GetMainViewport(); if (_G(saved_viewport_bitmap)->GetHeight() < viewport.GetHeight()) { Bitmap *enlargedBuffer = BitmapHelper::CreateBitmap(_G(saved_viewport_bitmap)->GetWidth(), viewport.GetHeight(), _G(saved_viewport_bitmap)->GetColorDepth()); diff --git a/engines/ags/engine/gui/gui_dialog.cpp b/engines/ags/engine/gui/gui_dialog.cpp index 6ee7eb6458c..665d943096d 100644 --- a/engines/ags/engine/gui/gui_dialog.cpp +++ b/engines/ags/engine/gui/gui_dialog.cpp @@ -60,8 +60,7 @@ Bitmap *prepare_gui_screen(int x, int y, int width, int height, bool opaque) { if (_G(windowBuffer)) { _G(windowBuffer) = recycle_bitmap(_G(windowBuffer), _G(windowBuffer)->GetColorDepth(), _G(windowPosWidth), _G(windowPosHeight), !opaque); } else { - _G(windowBuffer) = BitmapHelper::CreateBitmap(_G(windowPosWidth), _G(windowPosHeight), _GP(game).GetColorDepth()); - _G(windowBuffer) = ReplaceBitmapWithSupportedFormat(_G(windowBuffer)); + _G(windowBuffer) = CreateCompatBitmap(_G(windowPosWidth), _G(windowPosHeight)); } _G(dialogDDB) = recycle_ddb_bitmap(_G(dialogDDB), _G(windowBuffer), false, opaque); return _G(windowBuffer);