fixed redraw bug if gadget buttons are defined outside viewports
[rocksndiamonds.git] / src / game.c
index b843cbe7eba99fdda77cd76442011d9834d84221..e50017a9bed88bd57f2cc5403b066657abd53ddf 100644 (file)
@@ -3354,7 +3354,7 @@ void InitGame(void)
   SetGameStatus(GAME_MODE_PLAYING);
 
   if (level_editor_test_game)
-    FadeSkipNextFadeIn();
+    FadeSkipNextFadeOut();
   else
     FadeSetEnterScreen();
 
@@ -3365,8 +3365,10 @@ void InitGame(void)
 
   ExpireSoundLoops(TRUE);
 
-  if (!level_editor_test_game)
-    FadeOut(fade_mask);
+  FadeOut(fade_mask);
+
+  if (level_editor_test_game)
+    FadeSkipNextFadeIn();
 
   // needed if different viewport properties defined for playing
   ChangeViewportPropertiesIfNeeded();
@@ -5273,11 +5275,8 @@ static void DrawRelocateScreen(int old_x, int old_y, int x, int y, int move_dir,
 
   while (scroll_x != new_scroll_x || scroll_y != new_scroll_y)
   {
-    int dx = 0, dy = 0;
-    int fx = FX, fy = FY;
-
-    dx = (new_scroll_x < scroll_x ? +1 : new_scroll_x > scroll_x ? -1 : 0);
-    dy = (new_scroll_y < scroll_y ? +1 : new_scroll_y > scroll_y ? -1 : 0);
+    int dx = (new_scroll_x < scroll_x ? +1 : new_scroll_x > scroll_x ? -1 : 0);
+    int dy = (new_scroll_y < scroll_y ? +1 : new_scroll_y > scroll_y ? -1 : 0);
 
     if (dx == 0 && dy == 0)            // no scrolling needed at all
       break;
@@ -5285,14 +5284,19 @@ static void DrawRelocateScreen(int old_x, int old_y, int x, int y, int move_dir,
     scroll_x -= dx;
     scroll_y -= dy;
 
-    fx += dx * TILEX / 2;
-    fy += dy * TILEY / 2;
+    // set values for horizontal/vertical screen scrolling (half tile size)
+    int dir_x = (dx != 0 ? MV_HORIZONTAL : 0);
+    int dir_y = (dy != 0 ? MV_VERTICAL   : 0);
+    int pos_x = dx * TILEX / 2;
+    int pos_y = dy * TILEY / 2;
+    int fx = getFieldbufferOffsetX_RND(dir_x, pos_x);
+    int fy = getFieldbufferOffsetY_RND(dir_y, pos_y);
 
     ScrollLevel(dx, dy);
     DrawAllPlayers();
 
     // scroll in two steps of half tile size to make things smoother
-    BlitBitmap(drawto_field, window, fx, fy, SXSIZE, SYSIZE, SX, SY);
+    BlitScreenToBitmapExt_RND(window, fx, fy);
 
     // scroll second step to align at full tile size
     BlitScreenToBitmap(window);
@@ -11463,13 +11467,14 @@ static void GameActionsExt(void)
     stored_player[map_player_action[local_player->index_nr]].effective_action =
       summarized_player_action;
 
+  // summarize all actions at centered player in local team mode
   if (tape.recording &&
-      setup.team_mode &&
+      setup.team_mode && !network.enabled &&
       setup.input_on_focus &&
       game.centered_player_nr != -1)
   {
     for (i = 0; i < MAX_PLAYERS; i++)
-      stored_player[i].effective_action =
+      stored_player[map_player_action[i]].effective_action =
        (i == game.centered_player_nr ? summarized_player_action : 0);
   }
 
@@ -12177,12 +12182,17 @@ void GameActions_RND(void)
   DrawAllPlayers();
   PlayAllPlayersSound();
 
-  if (local_player->show_envelope != 0 && (!local_player->active ||
-                                          local_player->MovPos == 0))
+  for (i = 0; i < MAX_PLAYERS; i++)
   {
-    ShowEnvelope(local_player->show_envelope - EL_ENVELOPE_1);
+    struct PlayerInfo *player = &stored_player[i];
 
-    local_player->show_envelope = 0;
+    if (player->show_envelope != 0 && (!player->active ||
+                                      player->MovPos == 0))
+    {
+      ShowEnvelope(player->show_envelope - EL_ENVELOPE_1);
+
+      player->show_envelope = 0;
+    }
   }
 
   // use random number generator in every frame to make it less predictable
@@ -12524,10 +12534,11 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy)
     }
     else
     {
-      int offset = game.scroll_delay_value;
+      int offset_raw = game.scroll_delay_value;
 
       if (jx != old_jx)                // player has moved horizontally
       {
+       int offset = MIN(offset_raw, (SCR_FIELDX - 2) / 2);
        int offset_x = offset * (player->MovDir == MV_LEFT ? +1 : -1);
        int new_scroll_x = jx - MIDPOSX + offset_x;
 
@@ -12548,6 +12559,7 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy)
       }
       else                     // player has moved vertically
       {
+       int offset = MIN(offset_raw, (SCR_FIELDY - 2) / 2);
        int offset_y = offset * (player->MovDir == MV_UP ? +1 : -1);
        int new_scroll_y = jy - MIDPOSY + offset_y;
 
@@ -15747,7 +15759,8 @@ static void RedrawGameButtonsExt(boolean on_tape)
       RedrawGadget(game_gadget[i]);
 
   // RedrawGadget() may have set REDRAW_ALL if buttons are defined off-area
-  redraw_mask &= ~REDRAW_ALL;
+  if (redraw_mask & REDRAW_ALL)
+    redraw_mask = REDRAW_FIELD | REDRAW_DOORS;
 }
 
 static void SetGadgetState(struct GadgetInfo *gi, boolean state)