fixed fading complete screen if playfield viewport has changed
[rocksndiamonds.git] / src / tools.c
index ee00da19228e710bae0cd5641acf931aaf0b06de..2838908d99e93954787d83d96547b9df58cb95e2 100644 (file)
@@ -2486,12 +2486,14 @@ void DrawLevelField(int x, int y)
 }
 
 static void DrawSizedWallExt_MM(int dst_x, int dst_y, int element, int tilesize,
-                               int (*el2img_function)(int), boolean masked)
+                               int (*el2img_function)(int), boolean masked,
+                               int element_bits_draw)
 {
   int element_base = map_mm_wall_element(element);
   int element_bits = (IS_DF_WALL(element) ?
                      element - EL_DF_WALL_START :
-                     element - EL_MM_WALL_START) & 0x000f;
+                     IS_MM_WALL(element) ?
+                     element - EL_MM_WALL_START : EL_EMPTY) & 0x000f;
   int graphic = el2img_function(element_base);
   int tilesize_draw = tilesize / 2;
   Bitmap *src_bitmap;
@@ -2505,6 +2507,9 @@ static void DrawSizedWallExt_MM(int dst_x, int dst_y, int element, int tilesize,
     int dst_draw_x = dst_x + (i % 2) * tilesize_draw;
     int dst_draw_y = dst_y + (i / 2) * tilesize_draw;
 
+    if (!(element_bits_draw & (1 << i)))
+      continue;
+
     if (element_bits & (1 << i))
     {
       if (masked)
@@ -2523,10 +2528,18 @@ static void DrawSizedWallExt_MM(int dst_x, int dst_y, int element, int tilesize,
   }
 }
 
+void DrawSizedWallParts_MM(int x, int y, int element, int tilesize,
+                          boolean masked, int element_bits_draw)
+{
+  DrawSizedWallExt_MM(SX + x * tilesize, SY + y * tilesize,
+                     element, tilesize, el2edimg, masked, element_bits_draw);
+}
+
 void DrawSizedWall_MM(int dst_x, int dst_y, int element, int tilesize,
                      int (*el2img_function)(int))
 {
-  DrawSizedWallExt_MM(dst_x, dst_y, element, tilesize, el2img_function, FALSE);
+  DrawSizedWallExt_MM(dst_x, dst_y, element, tilesize, el2img_function, FALSE,
+                     0x000f);
 }
 
 void DrawSizedElementExt(int x, int y, int element, int tilesize,
@@ -2535,7 +2548,7 @@ void DrawSizedElementExt(int x, int y, int element, int tilesize,
   if (IS_MM_WALL(element))
   {
     DrawSizedWallExt_MM(SX + x * tilesize, SY + y * tilesize,
-                       element, tilesize, el2edimg, masked);
+                       element, tilesize, el2edimg, masked, 0x000f);
   }
   else
   {
@@ -4849,9 +4862,23 @@ unsigned int MoveDoor(unsigned int door_state)
     {
       /* opening door sound has priority over simultaneously closing door */
       if (door_state & (DOOR_OPEN_1 | DOOR_OPEN_2))
+      {
         PlayMenuSoundStereo(SND_DOOR_OPENING, SOUND_MIDDLE);
+
+       if (door_state & DOOR_OPEN_1)
+         PlayMenuSoundStereo(SND_DOOR_1_OPENING, SOUND_MIDDLE);
+       if (door_state & DOOR_OPEN_2)
+         PlayMenuSoundStereo(SND_DOOR_2_OPENING, SOUND_MIDDLE);
+      }
       else if (door_state & (DOOR_CLOSE_1 | DOOR_CLOSE_2))
+      {
         PlayMenuSoundStereo(SND_DOOR_CLOSING, SOUND_MIDDLE);
+
+       if (door_state & DOOR_CLOSE_1)
+         PlayMenuSoundStereo(SND_DOOR_1_CLOSING, SOUND_MIDDLE);
+       if (door_state & DOOR_CLOSE_2)
+         PlayMenuSoundStereo(SND_DOOR_2_CLOSING, SOUND_MIDDLE);
+      }
     }
 
     for (k = start; k < num_move_steps; k++)
@@ -5028,6 +5055,17 @@ unsigned int MoveDoor(unsigned int door_state)
       if (door_part_done_all)
        break;
     }
+
+    if (!(door_state & DOOR_NO_DELAY))
+    {
+      /* wait for specified door action post delay */
+      if (door_state & DOOR_ACTION_1 && door_state & DOOR_ACTION_2)
+       Delay(MAX(door_1.post_delay, door_2.post_delay));
+      else if (door_state & DOOR_ACTION_1)
+       Delay(door_1.post_delay);
+      else if (door_state & DOOR_ACTION_2)
+       Delay(door_2.post_delay);
+    }
   }
 
   if (door_state & DOOR_ACTION_1)
@@ -7396,6 +7434,27 @@ int map_element_MM_to_RND(int element_mm)
          EL_EMPTY);
 }
 
+int map_action_MM_to_RND(int action_mm)
+{
+  /* all MM actions are defined to exactly match their RND counterparts */
+  return action_mm;
+}
+
+int map_sound_MM_to_RND(int sound_mm)
+{
+  switch (sound_mm)
+  {
+    case SND_MM_GAME_LEVELTIME_CHARGING:
+      return SND_GAME_LEVELTIME_CHARGING;
+
+    case SND_MM_GAME_HEALTH_CHARGING:
+      return SND_GAME_HEALTH_CHARGING;
+
+    default:
+      return SND_UNDEFINED;
+  }
+}
+
 int map_mm_wall_element(int element)
 {
   return (element >= EL_MM_STEEL_WALL_START &&
@@ -8914,6 +8973,31 @@ void ResetFontStatus()
   SetFontStatus(-1);
 }
 
+boolean CheckIfPlayfieldViewportHasChanged()
+{
+  // if game status has not changed, playfield viewport has not changed either
+  if (game_status == game_status_last)
+    return FALSE;
+
+  // check if playfield viewport has changed with current game status
+  struct RectWithBorder *vp_playfield = &viewport.playfield[game_status];
+  int new_real_sx      = vp_playfield->x;
+  int new_real_sy      = vp_playfield->y;
+  int new_full_sxsize  = vp_playfield->width;
+  int new_full_sysize  = vp_playfield->height;
+
+  return (new_real_sx != REAL_SX ||
+         new_real_sy != REAL_SY ||
+         new_full_sxsize != FULL_SXSIZE ||
+         new_full_sysize != FULL_SYSIZE);
+}
+
+boolean CheckIfGlobalBorderOrPlayfieldViewportHasChanged()
+{
+  return (CheckIfGlobalBorderHasChanged() ||
+         CheckIfPlayfieldViewportHasChanged());
+}
+
 void ChangeViewportPropertiesIfNeeded()
 {
   boolean use_mini_tilesize = (level.game_engine_type == GAME_ENGINE_TYPE_MM ?