fixed updating tiled graphics only when needed
[rocksndiamonds.git] / src / tools.c
index c7b1dd35dd7a55b403cb2de9a2f013e43de0ab53..0271abfc43d83eb615b99fe8663df7cd83e0a5d5 100644 (file)
@@ -1481,6 +1481,25 @@ int getGraphicAnimationFrame(int graphic, int sync_frame)
                           sync_frame);
 }
 
+int getGraphicAnimationFrameXY(int graphic, int lx, int ly)
+{
+  if (graphic_info[graphic].anim_mode & ANIM_TILED)
+  {
+    struct GraphicInfo *g = &graphic_info[graphic];
+    int xsize = MAX(1, g->anim_frames_per_line);
+    int ysize = MAX(1, g->anim_frames / xsize);
+    int xoffset = g->anim_start_frame % xsize;
+    int yoffset = g->anim_start_frame % ysize;
+    int x = (lx + xoffset + xsize) % xsize;
+    int y = (ly + yoffset + ysize) % ysize;
+    int sync_frame = y * xsize + x;
+
+    return sync_frame % g->anim_frames;
+  }
+
+  return getGraphicAnimationFrame(graphic, GfxFrame[lx][ly]);
+}
+
 void getGraphicSourceBitmap(int graphic, int tilesize, Bitmap **bitmap)
 {
   struct GraphicInfo *g = &graphic_info[graphic];
@@ -1973,13 +1992,13 @@ void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
     SetRandomAnimationValue(lx, ly);
 
     graphic = el_act_dir2img(element, GfxAction[lx][ly], GfxDir[lx][ly]);
-    frame = getGraphicAnimationFrame(graphic, GfxFrame[lx][ly]);
+    frame = getGraphicAnimationFrameXY(graphic, lx, ly);
 
     // do not use double (EM style) movement graphic when not moving
     if (graphic_info[graphic].double_movement && !dx && !dy)
     {
       graphic = el_act_dir2img(element, ACTION_DEFAULT, GfxDir[lx][ly]);
-      frame = getGraphicAnimationFrame(graphic, GfxFrame[lx][ly]);
+      frame = getGraphicAnimationFrameXY(graphic, lx, ly);
     }
 
     if (game.use_masked_elements && (dx || dy))
@@ -1988,7 +2007,7 @@ void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
   else // border element
   {
     graphic = el2img(element);
-    frame = getGraphicAnimationFrame(graphic, -1);
+    frame = getGraphicAnimationFrameXY(graphic, lx, ly);
   }
 
   if (element == EL_EXPANDABLE_WALL)
@@ -2105,7 +2124,7 @@ static void DrawLevelFieldCrumbledInnerCorners(int x, int y, int dx, int dy,
   if (game.use_masked_elements)
   {
     int graphic0 = el2img(EL_EMPTY);
-    int frame0 = getGraphicAnimationFrame(graphic0, GfxFrame[x][y]);
+    int frame0 = getGraphicAnimationFrameXY(graphic0, x, y);
     Bitmap *src_bitmap0;
     int src_x0, src_y0;
 
@@ -2143,7 +2162,7 @@ static void DrawLevelFieldCrumbledBorders(int x, int y, int graphic, int frame,
 
   // only needed when using masked elements
   int graphic0 = el2img(EL_EMPTY);
-  int frame0 = getGraphicAnimationFrame(graphic0, GfxFrame[x][y]);
+  int frame0 = getGraphicAnimationFrameXY(graphic0, x, y);
   Bitmap *src_bitmap0;
   int src_x0, src_y0;
 
@@ -3840,10 +3859,10 @@ void ClearNetworkPlayers(void)
 }
 
 static void DrawGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y,
-                                   int graphic, int sync_frame,
+                                   int graphic, int lx, int ly,
                                    int mask_mode)
 {
-  int frame = getGraphicAnimationFrame(graphic, sync_frame);
+  int frame = getGraphicAnimationFrameXY(graphic, lx, ly);
 
   if (mask_mode == USE_MASKING)
     DrawGraphicThruMaskExt(dst_bitmap, x, y, graphic, frame);
@@ -3881,7 +3900,7 @@ static void DrawGraphicAnimation(int x, int y, int graphic)
   }
 
   DrawGraphicAnimationExt(drawto_field, FX + x * TILEX_VAR, FY + y * TILEY_VAR,
-                         graphic, GfxFrame[lx][ly], mask_mode);
+                         graphic, lx, ly, mask_mode);
 
   MarkTileDirty(x, y);
 }
@@ -3905,7 +3924,7 @@ void DrawFixedGraphicAnimation(int x, int y, int graphic)
   }
 
   DrawGraphicAnimationExt(drawto_field, FX + x * TILEX, FY + y * TILEY,
-                         graphic, GfxFrame[lx][ly], mask_mode);
+                         graphic, lx, ly, mask_mode);
 
   MarkTileDirty(x, y);
 }
@@ -3932,6 +3951,9 @@ void DrawLevelGraphicAnimationIfNeeded(int x, int y, int graphic)
   if (!IS_NEW_FRAME(GfxFrame[x][y], graphic))
     return;
 
+  if (ANIM_MODE(graphic) & ANIM_TILED)
+    return;
+
   DrawGraphicAnimation(sx, sy, graphic);
 
 #if 1
@@ -4277,7 +4299,7 @@ static void DrawPlayerExt(struct PlayerInfo *player, int drawing_stage)
     if (IS_ACTIVE_BOMB(element))
     {
       int graphic = el2img(element);
-      int frame = getGraphicAnimationFrame(graphic, GfxFrame[jx][jy]);
+      int frame = getGraphicAnimationFrameXY(graphic, jx, jy);
 
       if (game.emulation == EMU_SUPAPLEX)
        DrawGraphic(sx, sy, IMG_SP_DISK_RED, frame);