re-enabled storing selection from "last played level set" menu
[rocksndiamonds.git] / src / tools.c
index 473e652f687d2167c401fd63be5b53f4936340f2..b0df34409cfbc97772af22c78e8815c9ae6c3644 100644 (file)
@@ -4,7 +4,7 @@
 // (c) 1995-2014 by Artsoft Entertainment
 //                         Holger Schemel
 //                 info@artsoft.org
-//                 http://www.artsoft.org/
+//                 https://www.artsoft.org/
 // ----------------------------------------------------------------------------
 // tools.c
 // ============================================================================
@@ -391,41 +391,51 @@ int getLevelFromScreenY(int y)
     return getLevelFromScreenY_RND(y);
 }
 
+int getScreenFieldSizeX(void)
+{
+  return (tape.playing ? tape.scr_fieldx : SCR_FIELDX);
+}
+
+int getScreenFieldSizeY(void)
+{
+  return (tape.playing ? tape.scr_fieldy : SCR_FIELDY);
+}
+
 void DumpTile(int x, int y)
 {
   int sx = SCREENX(x);
   int sy = SCREENY(y);
   char *token_name;
 
-  printf_line("-", 79);
-  printf("Field Info: SCREEN(%d, %d), LEVEL(%d, %d)\n", sx, sy, x, y);
-  printf_line("-", 79);
+  Info("---");
+  Info("Field Info: SCREEN(%d, %d), LEVEL(%d, %d)", sx, sy, x, y);
+  Info("---");
 
   if (!IN_LEV_FIELD(x, y))
   {
-    printf("(not in level field)\n");
-    printf("\n");
+    Info("(not in level field)");
+    Info("");
 
     return;
   }
 
-  token_name = element_info[Feld[x][y]].token_name;
+  token_name = element_info[Tile[x][y]].token_name;
 
-  printf("  Feld:        %d\t['%s']\n", Feld[x][y], token_name);
-  printf("  Back:        %s\n", print_if_not_empty(Back[x][y]));
-  printf("  Store:       %s\n", print_if_not_empty(Store[x][y]));
-  printf("  Store2:      %s\n", print_if_not_empty(Store2[x][y]));
-  printf("  StorePlayer: %s\n", print_if_not_empty(StorePlayer[x][y]));
-  printf("  MovPos:      %d\n", MovPos[x][y]);
-  printf("  MovDir:      %d\n", MovDir[x][y]);
-  printf("  MovDelay:    %d\n", MovDelay[x][y]);
-  printf("  ChangeDelay: %d\n", ChangeDelay[x][y]);
-  printf("  CustomValue: %d\n", CustomValue[x][y]);
-  printf("  GfxElement:  %d\n", GfxElement[x][y]);
-  printf("  GfxAction:   %d\n", GfxAction[x][y]);
-  printf("  GfxFrame:    %d [%d]\n", GfxFrame[x][y], FrameCounter);
-  printf("  Player x/y:  %d, %d\n", local_player->jx, local_player->jy);
-  printf("\n");
+  Info("Tile:        %d\t['%s']",      Tile[x][y], token_name);
+  Info("Back:        %s",              print_if_not_empty(Back[x][y]));
+  Info("Store:       %s",              print_if_not_empty(Store[x][y]));
+  Info("Store2:      %s",              print_if_not_empty(Store2[x][y]));
+  Info("StorePlayer: %s",              print_if_not_empty(StorePlayer[x][y]));
+  Info("MovPos:      %d",              MovPos[x][y]);
+  Info("MovDir:      %d",              MovDir[x][y]);
+  Info("MovDelay:    %d",              MovDelay[x][y]);
+  Info("ChangeDelay: %d",              ChangeDelay[x][y]);
+  Info("CustomValue: %d",              CustomValue[x][y]);
+  Info("GfxElement:  %d",              GfxElement[x][y]);
+  Info("GfxAction:   %d",              GfxAction[x][y]);
+  Info("GfxFrame:    %d [%d]",         GfxFrame[x][y], FrameCounter);
+  Info("Player x/y:  %d, %d",          local_player->jx, local_player->jy);
+  Info("");
 }
 
 void DumpTileFromScreen(int sx, int sy)
@@ -462,6 +472,11 @@ void SetDrawtoField(int mode)
   }
 }
 
+int GetDrawtoField(void)
+{
+  return (drawto_field == fieldbuffer ? DRAW_TO_FIELDBUFFER : DRAW_TO_BACKBUFFER);
+}
+
 static void RedrawPlayfield_RND(void)
 {
   if (game.envelope_active)
@@ -616,60 +631,7 @@ void DrawMaskedBorderToTarget(int draw_target)
 
 void DrawTileCursor(int draw_target)
 {
-  Bitmap *fade_bitmap;
-  Bitmap *src_bitmap;
-  int src_x, src_y;
-  int dst_x, dst_y;
-  int graphic = IMG_GLOBAL_TILE_CURSOR;
-  int frame = 0;
-  int tilesize = TILESIZE_VAR;
-  int width = tilesize;
-  int height = tilesize;
-
-  if (game_status != GAME_MODE_PLAYING)
-    return;
-
-  if (!tile_cursor.enabled ||
-      !tile_cursor.active)
-    return;
-
-  if (tile_cursor.moving)
-  {
-    int step = TILESIZE_VAR / 4;
-    int dx = tile_cursor.target_x - tile_cursor.x;
-    int dy = tile_cursor.target_y - tile_cursor.y;
-
-    if (ABS(dx) < step)
-      tile_cursor.x = tile_cursor.target_x;
-    else
-      tile_cursor.x += SIGN(dx) * step;
-
-    if (ABS(dy) < step)
-      tile_cursor.y = tile_cursor.target_y;
-    else
-      tile_cursor.y += SIGN(dy) * step;
-
-    if (tile_cursor.x == tile_cursor.target_x &&
-       tile_cursor.y == tile_cursor.target_y)
-      tile_cursor.moving = FALSE;
-  }
-
-  dst_x = tile_cursor.x;
-  dst_y = tile_cursor.y;
-
-  frame = getGraphicAnimationFrame(graphic, -1);
-
-  getSizedGraphicSource(graphic, frame, tilesize, &src_bitmap, &src_x, &src_y);
-
-  fade_bitmap =
-    (draw_target == DRAW_TO_FADE_SOURCE ? gfx.fade_bitmap_source :
-     draw_target == DRAW_TO_FADE_TARGET ? gfx.fade_bitmap_target : NULL);
-
-  if (draw_target == DRAW_TO_SCREEN)
-    BlitToScreenMasked(src_bitmap, src_x, src_y, width, height, dst_x, dst_y);
-  else
-    BlitBitmapMasked(src_bitmap, fade_bitmap, src_x, src_y, width, height,
-                    dst_x, dst_y);
+  DrawTileCursor_MM(draw_target, game_status == GAME_MODE_PLAYING);
 }
 
 void BlitScreenToBitmapExt_RND(Bitmap *target_bitmap, int fx, int fy)
@@ -752,7 +714,7 @@ static void PrintFrameTimeDebugging(void)
 
   diff_bar[pos++] = '\0';
 
-  Error(ERR_INFO, "%06d [%02d] [%c%02d] %s",
+  Debug("time:frame", "%06d [%02d] [%c%02d] %s",
        counter,
        diff_1,
        (diff_2 < 0 ? '-' : diff_2 > 0 ? '+' : ' '), ABS(diff_2),
@@ -1337,6 +1299,9 @@ static void RedrawGlobalBorderIfNeeded(void)
 
 #if ONLY_REDRAW_GLOBAL_BORDER_IF_NEEDED
   if (CheckIfGlobalBorderRedrawIsNeeded())
+#else
+  // determine and store new global border bitmap for current game status
+  global_border_bitmap = getGlobalBorderBitmapFromStatus(game_status);
 #endif
   {
     // redraw global screen border (or clear, if defined to be empty)
@@ -1442,7 +1407,7 @@ void SetBorderElement(void)
   {
     for (x = 0; x < lev_fieldx; x++)
     {
-      if (!IS_INDESTRUCTIBLE(Feld[x][y]))
+      if (!IS_INDESTRUCTIBLE(Tile[x][y]))
        BorderElement = EL_STEELWALL;
 
       if (y != 0 && y != lev_fieldy - 1 && x != lev_fieldx - 1)
@@ -1468,7 +1433,7 @@ void FloodFillLevelExt(int from_x, int from_y, int fill_element,
   safety++;
 
   if (safety > max_fieldx * max_fieldy)
-    Error(ERR_EXIT, "Something went wrong in 'FloodFill()'. Please debug.");
+    Fail("Something went wrong in 'FloodFill()'. Please debug.");
 
   old_element = field[from_x][from_y];
   field[from_x][from_y] = fill_element;
@@ -1611,8 +1576,9 @@ void DrawGraphic(int x, int y, int graphic, int frame)
 #if DEBUG
   if (!IN_SCR_FIELD(x, y))
   {
-    printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n", x, y, graphic);
-    printf("DrawGraphic(): This should never happen!\n");
+    Debug("draw:DrawGraphic", "x = %d, y = %d, graphic = %d", x, y, graphic);
+    Debug("draw:DrawGraphic", "This should never happen!");
+
     return;
   }
 #endif
@@ -1628,8 +1594,10 @@ void DrawFixedGraphic(int x, int y, int graphic, int frame)
 #if DEBUG
   if (!IN_SCR_FIELD(x, y))
   {
-    printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n", x, y, graphic);
-    printf("DrawGraphic(): This should never happen!\n");
+    Debug("draw:DrawFixedGraphic", "x = %d, y = %d, graphic = %d",
+         x, y, graphic);
+    Debug("draw:DrawFixedGraphic", "This should never happen!");
+
     return;
   }
 #endif
@@ -1665,8 +1633,10 @@ void DrawGraphicThruMask(int x, int y, int graphic, int frame)
 #if DEBUG
   if (!IN_SCR_FIELD(x, y))
   {
-    printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
-    printf("DrawGraphicThruMask(): This should never happen!\n");
+    Debug("draw:DrawGraphicThruMask", "x = %d,y = %d, graphic = %d",
+         x, y, graphic);
+    Debug("draw:DrawGraphicThruMask", "This should never happen!");
+
     return;
   }
 #endif
@@ -1682,8 +1652,10 @@ void DrawFixedGraphicThruMask(int x, int y, int graphic, int frame)
 #if DEBUG
   if (!IN_SCR_FIELD(x, y))
   {
-    printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
-    printf("DrawGraphicThruMask(): This should never happen!\n");
+    Debug("draw:DrawFixedGraphicThruMask", "x = %d,y = %d, graphic = %d",
+         x, y, graphic);
+    Debug("draw:DrawFixedGraphicThruMask", "This should never happen!");
+
     return;
   }
 #endif
@@ -1844,8 +1816,10 @@ static void DrawGraphicShiftedNormal(int x, int y, int dx, int dy,
 #if DEBUG
   if (!IN_SCR_FIELD(x, y))
   {
-    printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
-    printf("DrawGraphicShifted(): This should never happen!\n");
+    Debug("draw:DrawGraphicShiftedNormal", "x = %d, y = %d, graphic = %d",
+         x, y, graphic);
+    Debug("draw:DrawGraphicShiftedNormal", "This should never happen!");
+
     return;
   }
 #endif
@@ -1986,6 +1960,9 @@ void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
       graphic = el_act_dir2img(element, ACTION_DEFAULT, GfxDir[lx][ly]);
       frame = getGraphicAnimationFrame(graphic, GfxFrame[lx][ly]);
     }
+
+    if (game.use_masked_elements && (dx || dy))
+      mask_mode = USE_MASKING;
   }
   else // border element
   {
@@ -1997,9 +1974,9 @@ void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
   {
     boolean left_stopped = FALSE, right_stopped = FALSE;
 
-    if (!IN_LEV_FIELD(lx - 1, ly) || IS_WALL(Feld[lx - 1][ly]))
+    if (!IN_LEV_FIELD(lx - 1, ly) || IS_WALL(Tile[lx - 1][ly]))
       left_stopped = TRUE;
-    if (!IN_LEV_FIELD(lx + 1, ly) || IS_WALL(Feld[lx + 1][ly]))
+    if (!IN_LEV_FIELD(lx + 1, ly) || IS_WALL(Tile[lx + 1][ly]))
       right_stopped = TRUE;
 
     if (left_stopped && right_stopped)
@@ -2051,7 +2028,7 @@ void DrawLevelElementThruMask(int x, int y, int element)
 
 void DrawLevelFieldThruMask(int x, int y)
 {
-  DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
+  DrawLevelElementExt(x, y, 0, 0, Tile[x][y], NO_CUTTING, USE_MASKING);
 }
 
 // !!! implementation of quicksand is totally broken !!!
@@ -2104,8 +2081,27 @@ static void DrawLevelFieldCrumbledInnerCorners(int x, int y, int dx, int dy,
   cx = (dx > 0 ? TILESIZE_VAR - width  : 0);
   cy = (dy > 0 ? TILESIZE_VAR - height : 0);
 
-  BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy,
-            width, height, FX + sx * TILEX_VAR + cx, FY + sy * TILEY_VAR + cy);
+  if (game.use_masked_elements)
+  {
+    int graphic0 = el2img(EL_EMPTY);
+    int frame0 = getGraphicAnimationFrame(graphic0, GfxFrame[x][y]);
+    Bitmap *src_bitmap0;
+    int src_x0, src_y0;
+
+    getGraphicSource(graphic0, frame0, &src_bitmap0, &src_x0, &src_y0);
+
+    BlitBitmap(src_bitmap0, drawto_field, src_x0 + cx, src_y0 + cy,
+              width, height,
+              FX + sx * TILEX_VAR + cx, FY + sy * TILEY_VAR + cy);
+
+    BlitBitmapMasked(src_bitmap, drawto_field, src_x + cx, src_y + cy,
+                    width, height,
+                    FX + sx * TILEX_VAR + cx, FY + sy * TILEY_VAR + cy);
+  }
+  else
+    BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy,
+              width, height,
+              FX + sx * TILEX_VAR + cx, FY + sy * TILEY_VAR + cy);
 }
 
 static void DrawLevelFieldCrumbledBorders(int x, int y, int graphic, int frame,
@@ -2124,6 +2120,15 @@ static void DrawLevelFieldCrumbledBorders(int x, int y, int graphic, int frame,
 
   getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
 
+  // only needed when using masked elements
+  int graphic0 = el2img(EL_EMPTY);
+  int frame0 = getGraphicAnimationFrame(graphic0, GfxFrame[x][y]);
+  Bitmap *src_bitmap0;
+  int src_x0, src_y0;
+
+  if (game.use_masked_elements)
+    getGraphicSource(graphic0, frame0, &src_bitmap0, &src_x0, &src_y0);
+
   // draw simple, sloppy, non-corner-accurate crumbled border
 
   width  = (dir == 1 || dir == 2 ? crumbled_border_size_var : TILESIZE_VAR);
@@ -2131,9 +2136,23 @@ static void DrawLevelFieldCrumbledBorders(int x, int y, int graphic, int frame,
   cx = (dir == 2 ? crumbled_border_pos_var : 0);
   cy = (dir == 3 ? crumbled_border_pos_var : 0);
 
-  BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy, width, height,
-            FX + sx * TILEX_VAR + cx,
-            FY + sy * TILEY_VAR + cy);
+  if (game.use_masked_elements)
+  {
+    BlitBitmap(src_bitmap0, drawto_field, src_x0 + cx, src_y0 + cy,
+              width, height,
+              FX + sx * TILEX_VAR + cx,
+              FY + sy * TILEY_VAR + cy);
+
+    BlitBitmapMasked(src_bitmap, drawto_field, src_x + cx, src_y + cy,
+                    width, height,
+                    FX + sx * TILEX_VAR + cx,
+                    FY + sy * TILEY_VAR + cy);
+  }
+  else
+    BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy,
+              width, height,
+              FX + sx * TILEX_VAR + cx,
+              FY + sy * TILEY_VAR + cy);
 
   // (remaining middle border part must be at least as big as corner part)
   if (!(graphic_info[graphic].style & STYLE_ACCURATE_BORDERS) ||
@@ -2179,10 +2198,23 @@ static void DrawLevelFieldCrumbledBorders(int x, int y, int graphic, int frame,
        by = cy;
       }
 
-      BlitBitmap(src_bitmap, drawto_field, src_x + bx, src_y + by,
-                width, height,
-                FX + sx * TILEX_VAR + cx,
-                FY + sy * TILEY_VAR + cy);
+      if (game.use_masked_elements)
+      {
+       BlitBitmap(src_bitmap0, drawto_field, src_x0 + bx, src_y0 + by,
+                  width, height,
+                  FX + sx * TILEX_VAR + cx,
+                  FY + sy * TILEY_VAR + cy);
+
+       BlitBitmapMasked(src_bitmap, drawto_field, src_x + bx, src_y + by,
+                        width, height,
+                        FX + sx * TILEX_VAR + cx,
+                        FY + sy * TILEY_VAR + cy);
+      }
+      else
+       BlitBitmap(src_bitmap, drawto_field, src_x + bx, src_y + by,
+                  width, height,
+                  FX + sx * TILEX_VAR + cx,
+                  FY + sy * TILEY_VAR + cy);
     }
   }
 }
@@ -2258,8 +2290,8 @@ static void DrawLevelFieldCrumbledExt(int x, int y, int graphic, int frame)
        continue;
 
       // do not crumble fields that are being digged or snapped
-      if (Feld[xx][yy] == EL_EMPTY ||
-         Feld[xx][yy] == EL_ELEMENT_SNAPPING)
+      if (Tile[xx][yy] == EL_EMPTY ||
+         Tile[xx][yy] == EL_ELEMENT_SNAPPING)
        continue;
 
       element = TILE_GFX_ELEMENT(xx, yy);
@@ -2288,7 +2320,7 @@ static void DrawLevelFieldCrumbledExt(int x, int y, int graphic, int frame)
          !IN_SCR_FIELD(sxx, syy))
        continue;
 
-      if (Feld[xx][yy] == EL_ELEMENT_SNAPPING)
+      if (Tile[xx][yy] == EL_ELEMENT_SNAPPING)
        continue;
 
       element = TILE_GFX_ELEMENT(xx, yy);
@@ -2314,7 +2346,7 @@ void DrawLevelFieldCrumbled(int x, int y)
   if (!IN_LEV_FIELD(x, y))
     return;
 
-  if (Feld[x][y] == EL_ELEMENT_SNAPPING &&
+  if (Tile[x][y] == EL_ELEMENT_SNAPPING &&
       GfxElement[x][y] != EL_UNDEFINED &&
       GFX_CRUMBLED(GfxElement[x][y]))
   {
@@ -2337,7 +2369,7 @@ void DrawLevelFieldCrumbledDigging(int x, int y, int direction,
   int frame2 = getGraphicAnimationFrame(graphic2, step_frame);
   int sx = SCREENX(x), sy = SCREENY(y);
 
-  DrawGraphic(sx, sy, graphic1, frame1);
+  DrawScreenGraphic(sx, sy, graphic1, frame1);
   DrawLevelFieldCrumbledExt(x, y, graphic2, frame2);
 }
 
@@ -2363,7 +2395,7 @@ void DrawLevelFieldCrumbledNeighbours(int x, int y)
 
     if (!IN_LEV_FIELD(xx, yy) ||
        !IN_SCR_FIELD(sxx, syy) ||
-       !GFX_CRUMBLED(Feld[xx][yy]) ||
+       !GFX_CRUMBLED(Tile[xx][yy]) ||
        IS_MOVING(xx, yy))
       continue;
 
@@ -2382,7 +2414,7 @@ void DrawLevelFieldCrumbledNeighbours(int x, int y)
 
     if (!IN_LEV_FIELD(xx, yy) ||
        !IN_SCR_FIELD(sxx, syy) ||
-       !GFX_CRUMBLED(Feld[xx][yy]) ||
+       !GFX_CRUMBLED(Tile[xx][yy]) ||
        IS_MOVING(xx, yy))
       continue;
 
@@ -2418,9 +2450,38 @@ static int getBorderElement(int x, int y)
   return border[steel_position][steel_type];
 }
 
+void DrawScreenGraphic(int x, int y, int graphic, int frame)
+{
+  if (game.use_masked_elements)
+  {
+    if (graphic != el2img(EL_EMPTY))
+      DrawScreenElementExt(x, y, 0, 0, EL_EMPTY, NO_CUTTING, NO_MASKING);
+
+    DrawGraphicThruMask(x, y, graphic, frame);
+  }
+  else
+  {
+    DrawGraphic(x, y, graphic, frame);
+  }
+}
+
 void DrawScreenElement(int x, int y, int element)
 {
-  DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
+  int mask_mode = NO_MASKING;
+
+  if (game.use_masked_elements)
+  {
+    int lx = LEVELX(x), ly = LEVELY(y);
+
+    if (IN_LEV_FIELD(lx, ly) && element != EL_EMPTY)
+    {
+      DrawScreenElementExt(x, y, 0, 0, EL_EMPTY, NO_CUTTING, NO_MASKING);
+
+      mask_mode = USE_MASKING;
+    }
+  }
+
+  DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, mask_mode);
   DrawLevelFieldCrumbled(LEVELX(x), LEVELY(y));
 }
 
@@ -2447,7 +2508,7 @@ void DrawScreenField(int x, int y)
     return;
   }
 
-  element = Feld[lx][ly];
+  element = Tile[lx][ly];
   content = Store[lx][ly];
 
   if (IS_MOVING(lx, ly))
@@ -2514,7 +2575,7 @@ void DrawScreenField(int x, int y)
     horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
                  MovDir[oldx][oldy] == MV_RIGHT);
 
-    element_old = Feld[oldx][oldy];
+    element_old = Tile[oldx][oldy];
     content_old = Store[oldx][oldy];
 
     if (element_old == EL_QUICKSAND_EMPTYING ||
@@ -2667,7 +2728,7 @@ void DrawSizedElementOrWall(int sx, int sy, int scroll_x, int scroll_y,
   if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
     DrawSizedElement(sx, sy, EL_EMPTY, tilesize);
   else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
-    DrawSizedElement(sx, sy, Feld[x][y], tilesize);
+    DrawSizedElement(sx, sy, Tile[x][y], tilesize);
   else
     DrawSizedGraphic(sx, sy, el2edimg(getBorderElement(x, y)), 0, tilesize);
 }
@@ -2679,7 +2740,7 @@ void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
   if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
     DrawMiniElement(sx, sy, EL_EMPTY);
   else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
-    DrawMiniElement(sx, sy, Feld[x][y]);
+    DrawMiniElement(sx, sy, Tile[x][y]);
   else
     DrawMiniGraphic(sx, sy, el2edimg(getBorderElement(x, y)));
 }
@@ -2808,9 +2869,13 @@ void ShowEnvelope(int envelope_nr)
   int anim_mode = graphic_info[graphic].anim_mode;
   int main_anim_mode = (anim_mode == ANIM_NONE ? ANIM_VERTICAL|ANIM_HORIZONTAL:
                        anim_mode == ANIM_DEFAULT ? ANIM_VERTICAL : anim_mode);
+  boolean overlay_enabled = GetOverlayEnabled();
 
   game.envelope_active = TRUE; // needed for RedrawPlayfield() events
 
+  SetOverlayEnabled(FALSE);
+  UnmapAllGadgets();
+
   PlayMenuSoundStereo(sound_opening, SOUND_MIDDLE);
 
   if (anim_mode == ANIM_DEFAULT)
@@ -2823,6 +2888,9 @@ void ShowEnvelope(int envelope_nr)
   else
     WaitForEventToContinue();
 
+  RemapAllGadgets();
+  SetOverlayEnabled(overlay_enabled);
+
   PlayMenuSoundStereo(sound_closing, SOUND_MIDDLE);
 
   if (anim_mode != ANIM_NONE)
@@ -2839,6 +2907,53 @@ void ShowEnvelope(int envelope_nr)
   BackToFront();
 }
 
+static void PrepareEnvelopeRequestToScreen(Bitmap *bitmap, int sx, int sy,
+                                          int xsize, int ysize)
+{
+  if (!global.use_envelope_request ||
+      request.sort_priority <= 0)
+    return;
+
+  if (request.bitmap == NULL ||
+      xsize > request.xsize ||
+      ysize > request.ysize)
+  {
+    if (request.bitmap != NULL)
+      FreeBitmap(request.bitmap);
+
+    request.bitmap = CreateBitmap(xsize, ysize, DEFAULT_DEPTH);
+
+    SDL_Surface *surface = request.bitmap->surface;
+
+    if ((request.bitmap->surface_masked = SDLGetNativeSurface(surface)) == NULL)
+      Fail("SDLGetNativeSurface() failed");
+  }
+
+  BlitBitmap(bitmap, request.bitmap, sx, sy, xsize, ysize, 0, 0);
+
+  SDLFreeBitmapTextures(request.bitmap);
+  SDLCreateBitmapTextures(request.bitmap);
+
+  // set envelope request run-time values
+  request.sx = sx;
+  request.sy = sy;
+  request.xsize = xsize;
+  request.ysize = ysize;
+}
+
+void DrawEnvelopeRequestToScreen(int drawing_target, int drawing_stage)
+{
+  if (global.use_envelope_request &&
+      game.request_active_or_moving &&
+      request.sort_priority > 0 &&
+      drawing_target == DRAW_TO_SCREEN &&
+      drawing_stage == DRAW_GLOBAL_ANIM_STAGE_2)
+  {
+    BlitToScreen(request.bitmap, 0, 0, request.xsize, request.ysize,
+                request.sx, request.sy);
+  }
+}
+
 static void setRequestBasePosition(int *x, int *y)
 {
   int sx_base, sy_base;
@@ -2989,6 +3104,8 @@ static void DrawEnvelopeRequest(char *text)
   // store readily prepared envelope request for later use when animating
   BlitBitmap(backbuffer, bitmap_db_store_2, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
 
+  PrepareEnvelopeRequestToScreen(bitmap_db_store_2, sx, sy, width, height);
+
   if (text_door_style)
     free(text_door_style);
 }
@@ -3070,6 +3187,8 @@ static void AnimateEnvelopeRequest(int anim_mode, int action)
       }
     }
 
+    PrepareEnvelopeRequestToScreen(backbuffer, dst_x, dst_y, width, height);
+
     redraw_mask |= REDRAW_FIELD;
 
     BackToFront();
@@ -3715,12 +3834,23 @@ void DrawFixedGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y,
 static void DrawGraphicAnimation(int x, int y, int graphic)
 {
   int lx = LEVELX(x), ly = LEVELY(y);
+  int mask_mode = NO_MASKING;
 
   if (!IN_SCR_FIELD(x, y))
     return;
 
+  if (game.use_masked_elements)
+  {
+    if (Tile[lx][ly] != EL_EMPTY)
+    {
+      DrawScreenElementExt(x, y, 0, 0, EL_EMPTY, NO_CUTTING, NO_MASKING);
+
+      mask_mode = USE_MASKING;
+    }
+  }
+
   DrawGraphicAnimationExt(drawto_field, FX + x * TILEX_VAR, FY + y * TILEY_VAR,
-                         graphic, GfxFrame[lx][ly], NO_MASKING);
+                         graphic, GfxFrame[lx][ly], mask_mode);
 
   MarkTileDirty(x, y);
 }
@@ -3728,12 +3858,24 @@ static void DrawGraphicAnimation(int x, int y, int graphic)
 void DrawFixedGraphicAnimation(int x, int y, int graphic)
 {
   int lx = LEVELX(x), ly = LEVELY(y);
+  int mask_mode = NO_MASKING;
 
   if (!IN_SCR_FIELD(x, y))
     return;
 
+  if (game.use_masked_elements)
+  {
+    if (Tile[lx][ly] != EL_EMPTY)
+    {
+      DrawScreenElementExt(x, y, 0, 0, EL_EMPTY, NO_CUTTING, NO_MASKING);
+
+      mask_mode = USE_MASKING;
+    }
+  }
+
   DrawGraphicAnimationExt(drawto_field, FX + x * TILEX, FY + y * TILEY,
-                         graphic, GfxFrame[lx][ly], NO_MASKING);
+                         graphic, GfxFrame[lx][ly], mask_mode);
+
   MarkTileDirty(x, y);
 }
 
@@ -3765,7 +3907,7 @@ void DrawLevelGraphicAnimationIfNeeded(int x, int y, int graphic)
   if (GFX_CRUMBLED(TILE_GFX_ELEMENT(x, y)))
     DrawLevelFieldCrumbled(x, y);
 #else
-  if (GFX_CRUMBLED(Feld[x][y]))
+  if (GFX_CRUMBLED(Tile[x][y]))
     DrawLevelFieldCrumbled(x, y);
 #endif
 }
@@ -3869,8 +4011,8 @@ static void DrawPlayerExt(struct PlayerInfo *player, int drawing_stage)
 #if DEBUG
   if (!IN_LEV_FIELD(player->jx, player->jy))
   {
-    printf("DrawPlayerField(): x = %d, y = %d\n", player->jx, player->jy);
-    printf("DrawPlayerField(): This should never happen!\n");
+    Debug("draw:DrawPlayerExt", "x = %d, y = %d", player->jx, player->jy);
+    Debug("draw:DrawPlayerExt", "This should never happen!");
 
     draw_player[pnr] = FALSE;
 
@@ -3896,8 +4038,8 @@ static void DrawPlayerExt(struct PlayerInfo *player, int drawing_stage)
   int sy = SCREENY(jy);
   int sxx = (move_dir == MV_LEFT || move_dir == MV_RIGHT ? player->GfxPos : 0);
   int syy = (move_dir == MV_UP   || move_dir == MV_DOWN  ? player->GfxPos : 0);
-  int element = Feld[jx][jy];
-  int last_element = Feld[last_jx][last_jy];
+  int element = Tile[jx][jy];
+  int last_element = Tile[last_jx][last_jy];
   int action = (player->is_pushing    ? ACTION_PUSHING         :
                player->is_digging    ? ACTION_DIGGING         :
                player->is_collecting ? ACTION_COLLECTING      :
@@ -3992,7 +4134,7 @@ static void DrawPlayerExt(struct PlayerInfo *player, int drawing_stage)
       if (GFX_CRUMBLED(old_element))
        DrawLevelFieldCrumbledDigging(jx, jy, move_dir, player->StepFrame);
       else
-       DrawGraphic(sx, sy, old_graphic, frame);
+       DrawScreenGraphic(sx, sy, old_graphic, frame);
 
       if (graphic_info[old_graphic].anim_mode & ANIM_OPAQUE_PLAYER)
        static_player_is_opaque[pnr] = TRUE;
@@ -4023,7 +4165,7 @@ static void DrawPlayerExt(struct PlayerInfo *player, int drawing_stage)
 
     if (!IS_MOVING(jx, jy))            // push movement already finished
     {
-      element = Feld[next_jx][next_jy];
+      element = Tile[next_jx][next_jy];
       gfx_frame = GfxFrame[next_jx][next_jy];
     }
 
@@ -4057,7 +4199,7 @@ static void DrawPlayerExt(struct PlayerInfo *player, int drawing_stage)
     // do not draw (EM style) pushing animation when pushing is finished
     // (two-tile animations usually do not contain start and end frame)
     if (graphic_info[graphic].double_movement && !IS_MOVING(jx, jy))
-      DrawLevelElement(next_jx, next_jy, Feld[next_jx][next_jy]);
+      DrawLevelElement(next_jx, next_jy, Tile[next_jx][next_jy]);
     else
       DrawGraphicShiftedThruMask(px, py, pxx, pyy, graphic, frame, NO_CUTTING);
 #else
@@ -4184,6 +4326,7 @@ void DrawPlayerField(int x, int y)
 
 void WaitForEventToContinue(void)
 {
+  boolean first_wait = TRUE;
   boolean still_wait = TRUE;
 
   if (program.headless)
@@ -4196,6 +4339,7 @@ void WaitForEventToContinue(void)
   button_status = MB_RELEASED;
 
   ClearEventQueue();
+  ClearPlayerAction();
 
   while (still_wait)
   {
@@ -4205,17 +4349,22 @@ void WaitForEventToContinue(void)
     {
       switch (event.type)
       {
-       case EVENT_BUTTONRELEASE:
+       case EVENT_BUTTONPRESS:
+        case EVENT_FINGERPRESS:
+         first_wait = FALSE;
+         break;
+
+        case EVENT_BUTTONRELEASE:
+        case EVENT_FINGERRELEASE:
+         still_wait = first_wait;
+         break;
+
        case EVENT_KEYPRESS:
         case SDL_CONTROLLERBUTTONDOWN:
         case SDL_JOYBUTTONDOWN:
          still_wait = FALSE;
          break;
 
-       case EVENT_KEYRELEASE:
-         ClearPlayerAction();
-         break;
-
        default:
          HandleOtherEvents(&event);
          break;
@@ -4226,7 +4375,8 @@ void WaitForEventToContinue(void)
       still_wait = FALSE;
     }
 
-    BackToFront();
+    if (!PendingEvent())
+      BackToFront();
   }
 }
 
@@ -4234,10 +4384,11 @@ void WaitForEventToContinue(void)
 #define MAX_REQUEST_LINE_FONT1_LEN     7
 #define MAX_REQUEST_LINE_FONT2_LEN     10
 
-static int RequestHandleEvents(unsigned int req_state)
+static int RequestHandleEvents(unsigned int req_state, int draw_buffer_game)
 {
   boolean game_just_ended = (game_status == GAME_MODE_PLAYING &&
                             checkGameEnded());
+  int draw_buffer_last = GetDrawtoField();
   int width  = request.width;
   int height = request.height;
   int sx, sy;
@@ -4258,11 +4409,11 @@ static int RequestHandleEvents(unsigned int req_state)
 
   while (result < 0)
   {
+    boolean event_handled = FALSE;
+
     if (game_just_ended)
     {
-      // the MM game engine does not use a special (scrollable) field buffer
-      if (level.game_engine_type != GAME_ENGINE_TYPE_MM)
-       SetDrawtoField(DRAW_TO_FIELDBUFFER);
+      SetDrawtoField(draw_buffer_game);
 
       HandleGameActions();
 
@@ -4281,6 +4432,8 @@ static int RequestHandleEvents(unsigned int req_state)
 
       while (NextValidEvent(&event))
       {
+       event_handled = TRUE;
+
        switch (event.type)
        {
          case EVENT_BUTTONPRESS:
@@ -4438,6 +4591,7 @@ static int RequestHandleEvents(unsigned int req_state)
            break;
          }
 
+         case EVENT_FINGERRELEASE:
          case EVENT_KEYRELEASE:
            ClearPlayerAction();
            break;
@@ -4534,18 +4688,25 @@ static int RequestHandleEvents(unsigned int req_state)
       }
     }
 
-    if (game_just_ended)
+    if (event_handled)
     {
-      if (global.use_envelope_request)
+      if (game_just_ended)
       {
-       // copy back current state of pressed buttons inside request area
-       BlitBitmap(drawto, bitmap_db_store_2, sx, sy, width, height, sx, sy);
+       if (global.use_envelope_request)
+       {
+         // copy back current state of pressed buttons inside request area
+         BlitBitmap(drawto, bitmap_db_store_2, sx, sy, width, height, sx, sy);
+       }
       }
+
+      PrepareEnvelopeRequestToScreen(drawto, sx, sy, width, height);
     }
 
     BackToFront();
   }
 
+  SetDrawtoField(draw_buffer_last);
+
   game.request_active = FALSE;
 
   return result;
@@ -4553,6 +4714,7 @@ static int RequestHandleEvents(unsigned int req_state)
 
 static boolean RequestDoor(char *text, unsigned int req_state)
 {
+  int draw_buffer_last = GetDrawtoField();
   unsigned int old_door_state;
   int max_request_line_len = MAX_REQUEST_LINE_FONT1_LEN;
   int font_nr = FONT_TEXT_2;
@@ -4694,7 +4856,7 @@ static boolean RequestDoor(char *text, unsigned int req_state)
   SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1);
 
   // ---------- handle request buttons ----------
-  result = RequestHandleEvents(req_state);
+  result = RequestHandleEvents(req_state, draw_buffer_last);
 
   UnmapToolButtons();
 
@@ -4735,6 +4897,7 @@ static boolean RequestDoor(char *text, unsigned int req_state)
 
 static boolean RequestEnvelope(char *text, unsigned int req_state)
 {
+  int draw_buffer_last = GetDrawtoField();
   int result;
 
   if (game_status == GAME_MODE_PLAYING)
@@ -4786,7 +4949,7 @@ static boolean RequestEnvelope(char *text, unsigned int req_state)
   SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1);
 
   // ---------- handle request buttons ----------
-  result = RequestHandleEvents(req_state);
+  result = RequestHandleEvents(req_state, draw_buffer_last);
 
   UnmapToolButtons();
 
@@ -4823,6 +4986,8 @@ boolean Request(char *text, unsigned int req_state)
   boolean overlay_enabled = GetOverlayEnabled();
   boolean result;
 
+  game.request_active_or_moving = TRUE;
+
   SetOverlayEnabled(FALSE);
 
   if (global.use_envelope_request)
@@ -4832,6 +4997,8 @@ boolean Request(char *text, unsigned int req_state)
 
   SetOverlayEnabled(overlay_enabled);
 
+  game.request_active_or_moving = FALSE;
+
   return result;
 }
 
@@ -5339,7 +5506,7 @@ unsigned int MoveDoor(unsigned int door_state)
          if (width > door_rect->width)
            width = door_rect->width;
 
-         // printf("::: k == %d [%d] \n", k, start_step);
+         // Debug("tools:MoveDoor", "k == %d [%d]", k, start_step);
        }
 
        if (pos->step_yoffset < 0)      // door part on bottom side
@@ -5671,7 +5838,7 @@ void CreateToolButtons(void)
                      GDI_END);
 
     if (gi == NULL)
-      Error(ERR_EXIT, "cannot create gadget");
+      Fail("cannot create gadget");
 
     tool_gadget[id] = gi;
   }
@@ -5854,6 +6021,39 @@ em_object_mapping_list[GAME_TILE_MAX + 1] =
     EL_EMC_FAKE_ACID,                  -1, -1
   },
 
+  {
+    Xfake_acid_1_player,               FALSE,  FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
+  },
+  {
+    Xfake_acid_2_player,               FALSE,  FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
+  },
+  {
+    Xfake_acid_3_player,               FALSE,  FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
+  },
+  {
+    Xfake_acid_4_player,               FALSE,  FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
+  },
+  {
+    Xfake_acid_5_player,               FALSE,  FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
+  },
+  {
+    Xfake_acid_6_player,               FALSE,  FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
+  },
+  {
+    Xfake_acid_7_player,               FALSE,  FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
+  },
+  {
+    Xfake_acid_8_player,               FALSE,  FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
+  },
+
   {
     Xgrass,                            TRUE,   FALSE,
     EL_EMC_GRASS,                      -1, -1
@@ -6852,11 +7052,11 @@ em_object_mapping_list[GAME_TILE_MAX + 1] =
   },
 
   {
-    Xdrip,                             FALSE,  FALSE,
+    Xdrip,                             TRUE,   FALSE,
     EL_AMOEBA_DROP,                    ACTION_GROWING, -1
   },
   {
-    Xdrip_fall,                                TRUE,   FALSE,
+    Xdrip_fall,                                FALSE,  FALSE,
     EL_AMOEBA_DROP,                    -1, -1
   },
   {
@@ -7704,7 +7904,7 @@ int map_element_RND_to_EM_cave(int element_rnd)
 
   if (element_rnd < 0 || element_rnd >= NUM_FILE_ELEMENTS)
   {
-    Error(ERR_WARN, "invalid RND level element %d", element_rnd);
+    Warn("invalid RND level element %d", element_rnd);
 
     return EL_UNKNOWN;
   }
@@ -7734,7 +7934,7 @@ int map_element_EM_to_RND_cave(int element_em_cave)
 
   if (element_em_cave < 0 || element_em_cave >= CAVE_TILE_MAX)
   {
-    Error(ERR_WARN, "invalid EM cave element %d", element_em_cave);
+    Warn("invalid EM cave element %d", element_em_cave);
 
     return EL_UNKNOWN;
   }
@@ -7764,7 +7964,7 @@ int map_element_EM_to_RND_game(int element_em_game)
 
   if (element_em_game < 0 || element_em_game >= GAME_TILE_MAX)
   {
-    Error(ERR_WARN, "invalid EM game element %d", element_em_game);
+    Warn("invalid EM game element %d", element_em_game);
 
     return EL_UNKNOWN;
   }
@@ -8746,6 +8946,14 @@ void InitGraphicInfo_EM(void)
                        i == Xfake_acid_6 ? 50 :
                        i == Xfake_acid_7 ? 60 :
                        i == Xfake_acid_8 ? 70 :
+                       i == Xfake_acid_1_player ? 0 :
+                       i == Xfake_acid_2_player ? 10 :
+                       i == Xfake_acid_3_player ? 20 :
+                       i == Xfake_acid_4_player ? 30 :
+                       i == Xfake_acid_5_player ? 40 :
+                       i == Xfake_acid_6_player ? 50 :
+                       i == Xfake_acid_7_player ? 60 :
+                       i == Xfake_acid_8_player ? 70 :
                        i == Xball_2 ? 7 :
                        i == Yball_2 ? j + 8 :
                        i == Yball_blank ? j + 1 :
@@ -9069,17 +9277,19 @@ static void CheckSaveEngineSnapshot_MM(boolean element_clicked,
   }
 }
 
-void CheckSingleStepMode_EM(byte action[MAX_PLAYERS], int frame,
-                           boolean any_player_moving,
-                           boolean any_player_snapping,
-                           boolean any_player_dropping)
+boolean CheckSingleStepMode_EM(byte action[MAX_PLAYERS], int frame,
+                              boolean any_player_moving,
+                              boolean any_player_snapping,
+                              boolean any_player_dropping)
 {
   if (tape.single_step && tape.recording && !tape.pausing)
-    if (frame == 7 && !any_player_dropping)
+    if (frame == 7 && !any_player_dropping && FrameCounter > 6)
       TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
 
   CheckSaveEngineSnapshot_EM(action, frame, any_player_moving,
                             any_player_snapping, any_player_dropping);
+
+  return tape.pausing;
 }
 
 void CheckSingleStepMode_SP(boolean murphy_is_waiting,
@@ -9243,51 +9453,59 @@ void PlaySoundSelecting(void)
 #endif
 }
 
-void ToggleFullscreenOrChangeWindowScalingIfNeeded(void)
+void ToggleFullscreenIfNeeded(void)
 {
-  boolean change_fullscreen = (setup.fullscreen !=
-                              video.fullscreen_enabled);
-  boolean change_window_scaling_percent = (!video.fullscreen_enabled &&
-                                          setup.window_scaling_percent !=
-                                          video.window_scaling_percent);
-
-  if (change_window_scaling_percent && video.fullscreen_enabled)
+  // if setup and video fullscreen state are already matching, nothing do do
+  if (setup.fullscreen == video.fullscreen_enabled ||
+      !video.fullscreen_available)
     return;
 
-  if (!change_window_scaling_percent && !video.fullscreen_available)
-    return;
+  SDLSetWindowFullscreen(setup.fullscreen);
 
-  if (change_window_scaling_percent)
-  {
-    SDLSetWindowScaling(setup.window_scaling_percent);
+  // set setup value according to successfully changed fullscreen mode
+  setup.fullscreen = video.fullscreen_enabled;
+}
 
+void ChangeWindowScalingIfNeeded(void)
+{
+  // if setup and video window scaling are already matching, nothing do do
+  if (setup.window_scaling_percent == video.window_scaling_percent ||
+      video.fullscreen_enabled)
     return;
-  }
-  else if (change_fullscreen)
-  {
-    SDLSetWindowFullscreen(setup.fullscreen);
 
-    // set setup value according to successfully changed fullscreen mode
-    setup.fullscreen = video.fullscreen_enabled;
+  SDLSetWindowScaling(setup.window_scaling_percent);
+
+  // set setup value according to successfully changed window scaling
+  setup.window_scaling_percent = video.window_scaling_percent;
+}
+
+void ChangeVsyncModeIfNeeded(void)
+{
+  int setup_vsync_mode = VSYNC_MODE_STR_TO_INT(setup.vsync_mode);
+  int video_vsync_mode = video.vsync_mode;
 
+  // if setup and video vsync mode are already matching, nothing do do
+  if (setup_vsync_mode == video_vsync_mode)
     return;
-  }
 
-  if (change_fullscreen ||
-      change_window_scaling_percent)
+  // if renderer is using OpenGL, vsync mode can directly be changed
+  SDLSetScreenVsyncMode(setup.vsync_mode);
+
+  // if vsync mode unchanged, try re-creating renderer to set vsync mode
+  if (video.vsync_mode == video_vsync_mode)
   {
     Bitmap *tmp_backbuffer = CreateBitmap(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH);
 
-    // save backbuffer content which gets lost when toggling fullscreen mode
+    // save backbuffer content which gets lost when re-creating screen
     BlitBitmap(backbuffer, tmp_backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
 
-    if (change_window_scaling_percent)
-    {
-      // keep window mode, but change window scaling
-      video.fullscreen_enabled = TRUE;         // force new window scaling
-    }
+    // force re-creating screen and renderer to set new vsync mode
+    video.fullscreen_enabled = !setup.fullscreen;
 
-    // toggle fullscreen
+    // when creating new renderer, destroy textures linked to old renderer
+    FreeAllImageTextures();    // needs old renderer to free the textures
+
+    // re-create screen and renderer (including change of vsync mode)
     ChangeVideoModeIfNeeded(setup.fullscreen);
 
     // set setup value according to successfully changed fullscreen mode
@@ -9295,12 +9513,17 @@ void ToggleFullscreenOrChangeWindowScalingIfNeeded(void)
 
     // restore backbuffer content from temporary backbuffer backup bitmap
     BlitBitmap(tmp_backbuffer, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
-
     FreeBitmap(tmp_backbuffer);
 
     // update visible window/screen
     BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+
+    // when changing vsync mode, re-create textures for new renderer
+    InitImageTextures();
   }
+
+  // set setup value according to successfully changed vsync mode
+  setup.vsync_mode = VSYNC_MODE_INT_TO_STR(video.vsync_mode);
 }
 
 static void JoinRectangles(int *x, int *y, int *width, int *height,
@@ -9320,6 +9543,8 @@ void SetAnimStatus(int anim_status_new)
 {
   if (anim_status_new == GAME_MODE_MAIN)
     anim_status_new = GAME_MODE_PSEUDO_MAINONLY;
+  else if (anim_status_new == GAME_MODE_NAMES)
+    anim_status_new = GAME_MODE_PSEUDO_NAMESONLY;
   else if (anim_status_new == GAME_MODE_SCORES)
     anim_status_new = GAME_MODE_PSEUDO_SCORESOLD;
 
@@ -9329,7 +9554,11 @@ void SetAnimStatus(int anim_status_new)
   if ((global.anim_status      == GAME_MODE_PSEUDO_MAINONLY &&
        global.anim_status_next == GAME_MODE_PSEUDO_TYPENAME) ||
       (global.anim_status      == GAME_MODE_PSEUDO_TYPENAME &&
-       global.anim_status_next == GAME_MODE_PSEUDO_MAINONLY))
+       global.anim_status_next == GAME_MODE_PSEUDO_MAINONLY) ||
+      (global.anim_status      == GAME_MODE_PSEUDO_NAMESONLY &&
+       global.anim_status_next == GAME_MODE_PSEUDO_TYPENAMES) ||
+      (global.anim_status      == GAME_MODE_PSEUDO_TYPENAMES &&
+       global.anim_status_next == GAME_MODE_PSEUDO_NAMESONLY))
     global.anim_status = global.anim_status_next;
 }
 
@@ -9486,7 +9715,7 @@ void ChangeViewportPropertiesIfNeeded(void)
     init_gfx_buffers = TRUE;
     init_gadgets_and_anims = TRUE;
 
-    // printf("::: video: init_video_buffer, init_gfx_buffers\n");
+    // Debug("tools:viewport", "video: init_video_buffer, init_gfx_buffers");
   }
 
   if (new_scr_fieldx != SCR_FIELDX ||
@@ -9497,7 +9726,7 @@ void ChangeViewportPropertiesIfNeeded(void)
     SCR_FIELDX = new_scr_fieldx;
     SCR_FIELDY = new_scr_fieldy;
 
-    // printf("::: new_scr_fieldx != SCR_FIELDX ...\n");
+    // Debug("tools:viewport", "new_scr_fieldx != SCR_FIELDX ...");
   }
 
   if (new_sx != SX ||
@@ -9567,7 +9796,7 @@ void ChangeViewportPropertiesIfNeeded(void)
 
     if (new_tilesize_var != TILESIZE_VAR)
     {
-      // printf("::: new_tilesize_var != TILESIZE_VAR\n");
+      // Debug("tools:viewport", "new_tilesize_var != TILESIZE_VAR");
 
       // changing tile size invalidates scroll values of engine snapshots
       FreeEngineSnapshotSingle();
@@ -9601,13 +9830,13 @@ void ChangeViewportPropertiesIfNeeded(void)
     init_gfx_buffers = TRUE;
     init_gadgets_and_anims = TRUE;
 
-    // printf("::: viewports: init_gfx_buffers\n");
-    // printf("::: viewports: init_gadgets_and_anims\n");
+    // Debug("tools:viewport", "viewports: init_gfx_buffers");
+    // Debug("tools:viewport", "viewports: init_gadgets_and_anims");
   }
 
   if (init_gfx_buffers)
   {
-    // printf("::: init_gfx_buffers\n");
+    // Debug("tools:viewport", "init_gfx_buffers");
 
     SCR_FIELDX = new_scr_fieldx_buffers;
     SCR_FIELDY = new_scr_fieldy_buffers;
@@ -9623,7 +9852,7 @@ void ChangeViewportPropertiesIfNeeded(void)
 
   if (init_video_buffer)
   {
-    // printf("::: init_video_buffer\n");
+    // Debug("tools:viewport", "init_video_buffer");
 
     FreeAllImageTextures();    // needs old renderer to free the textures
 
@@ -9633,7 +9862,7 @@ void ChangeViewportPropertiesIfNeeded(void)
 
   if (init_gadgets_and_anims)
   {
-    // printf("::: init_gadgets_and_anims\n");
+    // Debug("tools:viewport", "init_gadgets_and_anims");
 
     InitGadgets();
     InitGlobalAnimations();
@@ -9641,6 +9870,6 @@ void ChangeViewportPropertiesIfNeeded(void)
 
   if (init_em_graphics)
   {
-      InitGraphicInfo_EM();
+    InitGraphicInfo_EM();
   }
 }