added ignoring remaining level chunks after chunks with wrong size
[rocksndiamonds.git] / src / files.c
index 1d8ba0269fb377ab486a604d01af18be45fc0fd7..6839934a166cb2252154a2ad45024865a69e1f86 100644 (file)
@@ -3355,6 +3355,10 @@ static int LoadLevel_CUSX(File *file, int chunk_size, struct LevelInfo *level)
 
   while (!checkEndOfFile(file))
   {
+    // level file might contain invalid change page number
+    if (xx_current_change_page >= ei->num_change_pages)
+      break;
+
     struct ElementChangeInfo *change = &ei->change_page[xx_current_change_page];
 
     xx_change = *change;       // copy change data into temporary buffer
@@ -3384,6 +3388,9 @@ static int LoadLevel_GRPX(File *file, int chunk_size, struct LevelInfo *level)
   struct ElementInfo *ei = &element_info[element];
   struct ElementGroupInfo *group = ei->group;
 
+  if (group == NULL)
+    return -1;
+
   xx_ei = *ei;         // copy element data into temporary buffer
   xx_group = *group;   // copy group data into temporary buffer
 
@@ -3584,6 +3591,14 @@ static void LoadLevelFromFileInfo_RND(struct LevelInfo *level,
        int chunk_size_expected =
          (chunk_info[i].loader)(file, chunk_size, level);
 
+       if (chunk_size_expected < 0)
+       {
+         Warn("error reading chunk '%s' in level file '%s'",
+              chunk_name, filename);
+
+         break;
+       }
+
        // the size of some chunks cannot be checked before reading other
        // chunks first (like "HEAD" and "BODY") that contain some header
        // information, so check them here
@@ -3591,6 +3606,8 @@ static void LoadLevelFromFileInfo_RND(struct LevelInfo *level,
        {
          Warn("wrong size (%d) of chunk '%s' in level file '%s'",
               chunk_size, chunk_name, filename);
+
+         break;
        }
       }
     }
@@ -13466,6 +13483,13 @@ void CreateCollectElementImages(void)
           filename_bmp,
           filename_png);
 
+  // force using RGBA surface for destination bitmap
+  SDL_SetColorKey(dst_bitmap->surface, SET_TRANSPARENT_PIXEL,
+                 SDL_MapRGB(dst_bitmap->surface->format, 0x00, 0x00, 0x00));
+
+  dst_bitmap->surface =
+    SDL_ConvertSurfaceFormat(dst_bitmap->surface, SDL_PIXELFORMAT_RGBA32, 0);
+
   for (i = 0; i < MAX_NUM_ELEMENTS; i++)
   {
     if (!createCollectImage(i))
@@ -13486,6 +13510,13 @@ void CreateCollectElementImages(void)
     BlitBitmap(src_bitmap, tmp_bitmap, src_x, src_y,
               tile_size, tile_size, 0, 0);
 
+    // force using RGBA surface for temporary bitmap (using transparent black)
+    SDL_SetColorKey(tmp_bitmap->surface, SET_TRANSPARENT_PIXEL,
+                   SDL_MapRGB(tmp_bitmap->surface->format, 0x00, 0x00, 0x00));
+
+    tmp_bitmap->surface =
+      SDL_ConvertSurfaceFormat(tmp_bitmap->surface, SDL_PIXELFORMAT_RGBA32, 0);
+
     tmp_bitmap->surface_masked = tmp_bitmap->surface;
 
     for (j = 0; j < anim_frames; j++)
@@ -13506,9 +13537,9 @@ void CreateCollectElementImages(void)
        frame_bitmap = half_bitmap;
       }
 
-      BlitBitmap(frame_bitmap, dst_bitmap, 0, 0,
-                frame_size_final, frame_size_final,
-                dst_x + j * tile_size + offset, dst_y + offset);
+      BlitBitmapMasked(frame_bitmap, dst_bitmap, 0, 0,
+                      frame_size_final, frame_size_final,
+                      dst_x + j * tile_size + offset, dst_y + offset);
 
       FreeBitmap(frame_bitmap);
     }