fixed removing potential multiple screen redraw in the same video frame
[rocksndiamonds.git] / src / tools.c
index 76fa6c484a282c8a2170ac80b5a997b7d66d6e46..30e9cd5660b5de185b254e3600845d92d49b29e3 100644 (file)
@@ -550,6 +550,10 @@ void BackToFront()
   if (redraw_mask & REDRAW_FPS)
     DrawFramesPerSecond();
 
+  // remove playfield redraw before potentially merging with doors redraw
+  if (DrawingDeactivated(REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE))
+    redraw_mask &= ~REDRAW_FIELD;
+
   // redraw complete window if both playfield and (some) doors need redraw
   if (redraw_mask & REDRAW_FIELD && redraw_mask & REDRAW_DOORS)
     redraw_mask = REDRAW_ALL;
@@ -570,14 +574,37 @@ void BackToFront()
   }
   else if (redraw_mask & REDRAW_DOORS)
   {
+    // merge door areas to prevent calling screen redraw more than once
+    int x1 = WIN_XSIZE;
+    int y1 = WIN_YSIZE;
+    int x2 = 0;
+    int y2 = 0;
+
     if (redraw_mask & REDRAW_DOOR_1)
-      BlitBitmap(backbuffer, window, DX, DY, DXSIZE, DYSIZE, DX, DY);
+    {
+      x1 = MIN(x1, DX);
+      y1 = MIN(y1, DY);
+      x2 = MAX(x2, DX + DXSIZE);
+      y2 = MAX(y2, DY + DYSIZE);
+    }
 
     if (redraw_mask & REDRAW_DOOR_2)
-      BlitBitmap(backbuffer, window, VX, VY, VXSIZE, VYSIZE, VX, VY);
+    {
+      x1 = MIN(x1, VX);
+      y1 = MIN(y1, VY);
+      x2 = MAX(x2, VX + VXSIZE);
+      y2 = MAX(y2, VY + VYSIZE);
+    }
 
     if (redraw_mask & REDRAW_DOOR_3)
-      BlitBitmap(backbuffer, window, EX, EY, EXSIZE, EYSIZE, EX, EY);
+    {
+      x1 = MIN(x1, EX);
+      y1 = MIN(y1, EY);
+      x2 = MAX(x2, EX + EXSIZE);
+      y2 = MAX(y2, EY + EYSIZE);
+    }
+
+    BlitBitmap(backbuffer, window, x1, y1, x2 - x1, y2 - y1, x1, y1);
   }
 
   redraw_mask = REDRAW_NONE;