fixed warp-forward to skip redraw of most frames again
[rocksndiamonds.git] / src / tools.c
index 4cf1c874b3a8ca3a00c59ab75a24d21b3e0ec460..f479854086749b99292e5cb40b06b59f14206f7b 100644 (file)
@@ -334,11 +334,6 @@ void DrawMaskedBorder(int redraw_mask)
       effectiveGameStatus() == GAME_MODE_TITLE)
     return;
 
-  /* never draw masked screen borders when displaying request outside door */
-  if (effectiveGameStatus() == GAME_MODE_PSEUDO_DOOR &&
-      global.use_envelope_request)
-    return;
-
   if (redraw_mask & REDRAW_ALL)
     DrawMaskedBorder_ALL();
   else
@@ -420,6 +415,8 @@ void BlitScreenToBitmap(Bitmap *target_bitmap)
     BlitScreenToBitmap_SP(target_bitmap);
   else if (level.game_engine_type == GAME_ENGINE_TYPE_RND)
     BlitScreenToBitmap_RND(target_bitmap);
+
+  redraw_mask |= REDRAW_FIELD;
 }
 
 void BackToFront_OLD()
@@ -563,11 +560,42 @@ void BackToFront()
   if (redraw_mask == REDRAW_NONE)
     return;
 
+  // redraw playfield if anything inside main playfield area needs redraw
+  if (redraw_mask & REDRAW_MAIN)
+    redraw_mask |= REDRAW_FIELD;
+
   // draw masked border to all viewports, if defined
   DrawMaskedBorder(redraw_mask);
 
-  // blit backbuffer to visible screen
-  BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+  // redraw complete window if both playfield and (some) doors need redraw
+  if (redraw_mask & REDRAW_FIELD && redraw_mask & REDRAW_DOORS)
+    redraw_mask = REDRAW_ALL;
+
+  /* although redrawing the whole window would be fine for normal gameplay,
+     being able to only redraw the playfield is required for deactivating
+     certain drawing areas (mainly playfield) to work, which is needed for
+     warp-forward to be fast enough (by skipping redraw of most frames) */
+
+  if (redraw_mask & REDRAW_ALL)
+  {
+    BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+  }
+  else if (redraw_mask & REDRAW_FIELD)
+  {
+    BlitBitmap(backbuffer, window,
+              REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, REAL_SX, REAL_SY);
+  }
+  else if (redraw_mask & REDRAW_DOORS)
+  {
+    if (redraw_mask & REDRAW_DOOR_1)
+      BlitBitmap(backbuffer, window, DX, DY, DXSIZE, DYSIZE, DX, DY);
+
+    if (redraw_mask & REDRAW_DOOR_2)
+      BlitBitmap(backbuffer, window, VX, VY, VXSIZE, VYSIZE, VX, VY);
+
+    if (redraw_mask & REDRAW_DOOR_3)
+      BlitBitmap(backbuffer, window, EX, EY, EXSIZE, EYSIZE, EX, EY);
+  }
 
   redraw_mask = REDRAW_NONE;
 }
@@ -859,7 +887,9 @@ void ClearField()
     SetDrawtoField(DRAW_FIELDBUFFER);
   }
   else
+  {
     SetDrawtoField(DRAW_BACKBUFFER);
+  }
 }
 
 void MarkTileDirty(int x, int y)
@@ -2320,7 +2350,6 @@ void AnimateEnvelopeRequest(int anim_mode, int action)
   }
 }
 
-
 void ShowEnvelopeRequest(char *text, unsigned int req_state, int action)
 {
   int last_game_status = game_status;  /* save current game status */