added support for accessing (scaled) original size of loaded images
authorHolger Schemel <info@artsoft.org>
Thu, 4 Mar 2021 18:57:56 +0000 (19:57 +0100)
committerHolger Schemel <info@artsoft.org>
Thu, 4 Mar 2021 19:46:27 +0000 (20:46 +0100)
Before, loaded images were stored and accessed in "standard" size,
with an exception for game element graphics in non-standard size (like
using game element graphics with a tile size of 64x64 pixels).

This has the disadvantage that global animations using the same image
file are displayed incorrectly, because of not using the original size
of the image, but the (potentially down-scaled) "standard" image size
(as the original sized graphics are only used for game elements).

This change adds a bitmap pointer to easily access the original sized
bitmap (which can either be the normal, standard-sized bitmap, or the
custom sized bitmap used for in-game element graphics). In addition,
the original sized bitmap is also stored in cases where it would have
been discarded before (like image files with double-sized element
graphics used in graphics sets that only use standard sized element
graphics, which causes the original bitmap to be down-scaled and freed
again, only keeping the down-scaled bitmap, so the bitmap in original
size is not available anymore for global animations using the same
image file).

When talking about "original sized bitmaps" here, this is the size of
the image _after_ applying a possible option "scale_up_factor", which
is always applied first.

Correctly using the "original sized bitmaps" for global animations
will be fixed with the next commit.

src/libgame/image.h
src/libgame/system.c

index 3d2421934465f4e1790628538607925667b65add..cf95a106b44c21f09c7cf263a9d7efb99b6fa184 100644 (file)
 #include "system.h"
 
 
-// these bitmap pointers either point to allocated bitmaps or are NULL
+// bitmap array positions for various element sizes, if available
+//
+// for any loaded image, the "standard" size (which represents the 32x32 pixel
+// size for game elements) is always defined; other bitmap sizes may be NULL
+//
+// formats from 32x32 down to 1x1 are standard bitmap sizes for game elements
+// (used in the game, in the level editor, in the level preview etc.)
+//
+// "CUSTOM" sizes for game elements (like 64x64) may be additionally created;
+// all "OTHER" image sizes are stored if different from all other bitmap sizes,
+// which may be used "as is" by global animations (as the "standard" size used
+// normally may be wrong due to being scaled up or down to a different size if
+// the same image contains game elements in a non-standard size)
+
 #define IMG_BITMAP_32x32       0
 #define IMG_BITMAP_16x16       1
 #define IMG_BITMAP_8x8         2
 #define IMG_BITMAP_2x2         4
 #define IMG_BITMAP_1x1         5
 #define IMG_BITMAP_CUSTOM      6
+#define IMG_BITMAP_OTHER       7
 
-#define NUM_IMG_BITMAPS                7
+#define NUM_IMG_BITMAPS                8
 
-// this bitmap pointer points to one of the above bitmaps (do not free it)
-#define IMG_BITMAP_PTR_GAME    7
+// these bitmap pointers point to one of the above bitmaps (do not free them)
+#define IMG_BITMAP_PTR_GAME    8
+#define IMG_BITMAP_PTR_ORIGINAL        9
 
-#define NUM_IMG_BITMAP_POINTERS        8
+#define NUM_IMG_BITMAP_POINTERS        10
 
 // this bitmap pointer points to the bitmap with default image size
 #define IMG_BITMAP_STANDARD    IMG_BITMAP_32x32
index a615b92fcefbe1c8f974fae1bcd8bdbe5b1f778e..225738cc361ece7da2e18f944cd4082ba529ce6f 100644 (file)
@@ -1244,7 +1244,23 @@ void ReCreateGameTileSizeBitmap(Bitmap **bitmaps)
 {
   if (bitmaps[IMG_BITMAP_CUSTOM])
   {
-    FreeBitmap(bitmaps[IMG_BITMAP_CUSTOM]);
+    // check if original sized bitmap points to custom sized bitmap
+    if (bitmaps[IMG_BITMAP_PTR_ORIGINAL] == bitmaps[IMG_BITMAP_CUSTOM])
+    {
+      SDLFreeBitmapTextures(bitmaps[IMG_BITMAP_PTR_ORIGINAL]);
+
+      // keep pointer of previous custom size bitmap
+      bitmaps[IMG_BITMAP_OTHER] = bitmaps[IMG_BITMAP_CUSTOM];
+
+      // set original bitmap pointer to scaled original bitmap of other size
+      bitmaps[IMG_BITMAP_PTR_ORIGINAL] = bitmaps[IMG_BITMAP_OTHER];
+
+      SDLCreateBitmapTextures(bitmaps[IMG_BITMAP_PTR_ORIGINAL]);
+    }
+    else
+    {
+      FreeBitmap(bitmaps[IMG_BITMAP_CUSTOM]);
+    }
 
     bitmaps[IMG_BITMAP_CUSTOM] = NULL;
   }
@@ -1417,6 +1433,30 @@ static void CreateScaledBitmaps(Bitmap **bitmaps, int zoom_factor,
     else
       bitmaps[IMG_BITMAP_PTR_GAME] = bitmaps[IMG_BITMAP_STANDARD];
 
+    // store the "final" (up-scaled) original bitmap, if not already stored
+
+    int tmp_bitmap_final_nr = -1;
+
+    for (i = 0; i < NUM_IMG_BITMAPS; i++)
+      if (bitmaps[i] == tmp_bitmap_final)
+       tmp_bitmap_final_nr = i;
+
+    if (tmp_bitmap_final_nr == -1)     // scaled original bitmap not stored
+    {
+      // store pointer of scaled original bitmap (not used for any other size)
+      bitmaps[IMG_BITMAP_OTHER] = tmp_bitmap_final;
+
+      // set original bitmap pointer to scaled original bitmap of other size
+      bitmaps[IMG_BITMAP_PTR_ORIGINAL] = bitmaps[IMG_BITMAP_OTHER];
+    }
+    else
+    {
+      // set original bitmap pointer to corresponding sized bitmap
+      bitmaps[IMG_BITMAP_PTR_ORIGINAL] = bitmaps[tmp_bitmap_final_nr];
+    }
+
+    // free the "old" (unscaled) original bitmap, if not already stored
+
     boolean free_old_bitmap = TRUE;
 
     for (i = 0; i < NUM_IMG_BITMAPS; i++)
@@ -1435,6 +1475,9 @@ static void CreateScaledBitmaps(Bitmap **bitmaps, int zoom_factor,
   else
   {
     bitmaps[IMG_BITMAP_32x32] = tmp_bitmap_1;
+
+    // set original bitmap pointer to corresponding sized bitmap
+    bitmaps[IMG_BITMAP_PTR_ORIGINAL] = bitmaps[IMG_BITMAP_32x32];
   }
 
   UPDATE_BUSY_STATE();