rnd-20051209-1-src
[rocksndiamonds.git] / src / tools.c
index badbb81eb4dd9ea18be487ac69f086c3cf32d685..aa1767a426c9f4e962b63a08ab06935564906ed2 100644 (file)
@@ -85,6 +85,7 @@ void DumpTile(int x, int y)
   printf("  MovDir:      %d\n", MovDir[x][y]);
   printf("  MovDelay:    %d\n", MovDelay[x][y]);
   printf("  ChangeDelay: %d\n", ChangeDelay[x][y]);
+  printf("  Count:       %d\n", Count[x][y]);
   printf("  GfxElement:  %d\n", GfxElement[x][y]);
   printf("  GfxAction:   %d\n", GfxAction[x][y]);
   printf("  GfxFrame:    %d\n", GfxFrame[x][y]);
@@ -256,8 +257,8 @@ void BackToFront()
       {
        BlitBitmap(buffer, window, fx, fy, SXSIZE, SYSIZE, SX, SY);
 
-#ifdef DEBUG
 #if 0
+#ifdef DEBUG
        printf("redrawing all (ScreenGfxPos == %d) because %s\n",
               ScreenGfxPos,
               (setup.soft_scrolling ?
@@ -281,32 +282,7 @@ void BackToFront()
       BlitBitmap(backbuffer, window, DX, DY, DXSIZE, DYSIZE, DX, DY);
 
     if (redraw_mask & REDRAW_DOOR_2)
-    {
-#if 0
-      if ((redraw_mask & REDRAW_DOOR_2) == REDRAW_DOOR_2)
-#endif
-       BlitBitmap(backbuffer, window, VX, VY, VXSIZE, VYSIZE, VX, VY);
-#if 0
-      else
-      {
-       if (redraw_mask & REDRAW_VIDEO_1)
-         BlitBitmap(backbuffer, window,
-                    VX + VIDEO_DISPLAY1_XPOS, VY + VIDEO_DISPLAY1_YPOS,
-                    VIDEO_DISPLAY_XSIZE, VIDEO_DISPLAY_YSIZE,
-                    VX + VIDEO_DISPLAY1_XPOS, VY + VIDEO_DISPLAY1_YPOS);
-       if (redraw_mask & REDRAW_VIDEO_2)
-         BlitBitmap(backbuffer, window,
-                    VX + VIDEO_DISPLAY2_XPOS, VY + VIDEO_DISPLAY2_YPOS,
-                    VIDEO_DISPLAY_XSIZE, VIDEO_DISPLAY_YSIZE,
-                    VX + VIDEO_DISPLAY2_XPOS, VY + VIDEO_DISPLAY2_YPOS);
-       if (redraw_mask & REDRAW_VIDEO_3)
-         BlitBitmap(backbuffer, window,
-                    VX + VIDEO_CONTROL_XPOS, VY + VIDEO_CONTROL_YPOS,
-                    VIDEO_CONTROL_XSIZE, VIDEO_CONTROL_YSIZE,
-                    VX + VIDEO_CONTROL_XPOS, VY + VIDEO_CONTROL_YPOS);
-      }
-#endif
-    }
+      BlitBitmap(backbuffer, window, VX, VY, VXSIZE, VYSIZE, VX, VY);
 
     if (redraw_mask & REDRAW_DOOR_3)
       BlitBitmap(backbuffer, window, EX, EY, EXSIZE, EYSIZE, EX, EY);
@@ -425,6 +401,12 @@ void FadeToFront()
   BackToFront();
 }
 
+void SetMainBackgroundImageIfDefined(int graphic)
+{
+  if (graphic_info[graphic].bitmap)
+    SetMainBackgroundImage(graphic);
+}
+
 void SetMainBackgroundImage(int graphic)
 {
   SetMainBackgroundBitmap(graphic == IMG_UNDEFINED ? NULL :
@@ -528,28 +510,18 @@ inline void getGraphicSourceExt(int graphic, int frame, Bitmap **bitmap,
   if (g->offset_y == 0)                /* frames are ordered horizontally */
   {
     int max_width = g->anim_frames_per_line * g->width;
-#if 1
     int pos = (src_y / g->height) * max_width + src_x + frame * g->offset_x;
 
     *x = pos % max_width;
     *y = src_y % g->height + pos / max_width * g->height;
-#else
-    *x = (src_x + frame * g->offset_x) % max_width;
-    *y = src_y + (src_x + frame * g->offset_x) / max_width * g->height;
-#endif
   }
   else if (g->offset_x == 0)   /* frames are ordered vertically */
   {
     int max_height = g->anim_frames_per_line * g->height;
-#if 1
     int pos = (src_x / g->width) * max_height + src_y + frame * g->offset_y;
 
     *x = src_x % g->width + pos / max_height * g->width;
     *y = pos % max_height;
-#else
-    *x = src_x + (src_y + frame * g->offset_y) / max_height * g->width;
-    *y = (src_y + frame * g->offset_y) % max_height;
-#endif
   }
   else                         /* frames are ordered diagonally */
   {
@@ -810,12 +782,6 @@ inline static void DrawGraphicShiftedDouble(int x, int y, int dx, int dy,
 
     MarkTileDirty(x2, y2);
   }
-
-#if 0
-  printf("::: DONE DrawGraphicShiftedDouble");
-  BackToFront();
-  Delay(1000);
-#endif
 }
 
 static void DrawGraphicShifted(int x, int y, int dx, int dy,
@@ -940,11 +906,7 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame)
   int sx = SCREENX(x), sy = SCREENY(y);
   int element;
   int width, height, cx, cy, i;
-#if 1
   int crumbled_border_size = graphic_info[graphic].border_size;
-#else
-  int snip = TILEX / 8;        /* number of border pixels from "crumbled graphic" */
-#endif
   static int xy[4][2] =
   {
     { 0, -1 },
@@ -953,12 +915,6 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame)
     { 0, +1 }
   };
 
-#if 0
-  if (x == 0 && y == 7)
-    printf("::: %d, %d [%d]\n", GfxElement[x][y], Feld[x][y],
-          crumbled_border_size);
-#endif
-
   if (!IN_LEV_FIELD(x, y))
     return;
 
@@ -977,24 +933,13 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame)
       int xx = x + xy[i][0];
       int yy = y + xy[i][1];
 
-#if 1
       element = (IN_LEV_FIELD(xx, yy) ? TILE_GFX_ELEMENT(xx, yy) :
                 BorderElement);
-#else
-      element = (IN_LEV_FIELD(xx, yy) ? Feld[xx][yy] : BorderElement);
-#endif
 
       /* check if neighbour field is of same type */
       if (GFX_CRUMBLED(element) && !IS_MOVING(xx, yy))
        continue;
 
-#if 0
-      if (Feld[x][y] == EL_CUSTOM_START + 123)
-       printf("::: crumble [%d] THE CHAOS ENGINE (%d, %d): %d, %d\n",
-              i, Feld[x][y], element,
-              GFX_CRUMBLED(element), IS_MOVING(x, y));
-#endif
-
       if (i == 1 || i == 2)
       {
        width = crumbled_border_size;
@@ -1018,10 +963,6 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame)
   }
   else         /* crumble neighbour fields */
   {
-#if 0
-    getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
-#endif
-
     for (i = 0; i < 4; i++)
     {
       int xx = x + xy[i][0];
@@ -1047,12 +988,10 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame)
        continue;
 #endif
 
-#if 1
       graphic = el_act2crm(Feld[xx][yy], ACTION_DEFAULT);
       crumbled_border_size = graphic_info[graphic].border_size;
 
       getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
-#endif
 
       if (i == 1 || i == 2)
       {
@@ -1079,7 +1018,6 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame)
 
 void DrawLevelFieldCrumbledSand(int x, int y)
 {
-#if 1
   int graphic;
 
   if (!IN_LEV_FIELD(x, y))
@@ -1088,21 +1026,13 @@ void DrawLevelFieldCrumbledSand(int x, int y)
   graphic = el_act2crm(Feld[x][y], ACTION_DEFAULT);
 
   DrawLevelFieldCrumbledSandExt(x, y, graphic, 0);
-#else
-  DrawLevelFieldCrumbledSandExt(x, y, IMG_SAND_CRUMBLED, 0);
-#endif
 }
 
 void DrawLevelFieldCrumbledSandDigging(int x, int y, int direction,
                                       int step_frame)
 {
-#if 1
   int graphic1 = el_act_dir2img(GfxElement[x][y], ACTION_DIGGING, direction);
   int graphic2 = el_act_dir2crm(GfxElement[x][y], ACTION_DIGGING, direction);
-#else
-  int graphic1 = el_act_dir2img(EL_SAND,          ACTION_DIGGING, direction);
-  int graphic2 = el_act_dir2img(EL_SAND_CRUMBLED, ACTION_DIGGING, direction);
-#endif
   int frame1 = getGraphicAnimationFrame(graphic1, step_frame);
   int frame2 = getGraphicAnimationFrame(graphic2, step_frame);
   int sx = SCREENX(x), sy = SCREENY(y);
@@ -1359,13 +1289,8 @@ void DrawEnvelopeBackground(int envelope_nr, int startx, int starty,
 void AnimateEnvelope(int envelope_nr, int anim_mode, int action)
 {
   int graphic = IMG_BACKGROUND_ENVELOPE_1 + envelope_nr;
-#if 1
   Bitmap *src_bitmap = graphic_info[graphic].bitmap;
   int mask_mode = (src_bitmap != NULL ? BLIT_MASKED : BLIT_ON_BACKGROUND);
-#else
-  boolean draw_masked = graphic_info[graphic].draw_masked;
-  int mask_mode = (draw_masked ? BLIT_MASKED : BLIT_ON_BACKGROUND);
-#endif
   boolean ffwd_delay = (tape.playing && tape.fast_forward);
   boolean no_delay = (tape.warp_forward);
   unsigned long anim_delay = 0;
@@ -1509,7 +1434,7 @@ static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
 {
   int x, y;
 
-  DrawBackground(xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
+  DrawBackground(xpos, ypos, MICROLEVEL_XSIZE, MICROLEVEL_YSIZE);
 
   if (lev_fieldx < STD_LEV_FIELDX)
     xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
@@ -1540,37 +1465,54 @@ static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
 
 #define MICROLABEL_EMPTY               0
 #define MICROLABEL_LEVEL_NAME          1
-#define MICROLABEL_CREATED_BY          2
+#define MICROLABEL_LEVEL_AUTHOR_HEAD   2
 #define MICROLABEL_LEVEL_AUTHOR                3
-#define MICROLABEL_IMPORTED_FROM       4
-#define MICROLABEL_LEVEL_IMPORT_INFO   5
+#define MICROLABEL_IMPORTED_FROM_HEAD  4
+#define MICROLABEL_IMPORTED_FROM       5
+#define MICROLABEL_IMPORTED_BY_HEAD    6
+#define MICROLABEL_IMPORTED_BY         7
 
 static void DrawMicroLevelLabelExt(int mode)
 {
   char label_text[MAX_OUTPUT_LINESIZE + 1];
   int max_len_label_text;
   int font_nr = FONT_TEXT_2;
+  int i;
 
-  if (mode == MICROLABEL_CREATED_BY || mode == MICROLABEL_IMPORTED_FROM)
+  if (mode == MICROLABEL_LEVEL_AUTHOR_HEAD ||
+      mode == MICROLABEL_IMPORTED_FROM_HEAD ||
+      mode == MICROLABEL_IMPORTED_BY_HEAD)
     font_nr = FONT_TEXT_3;
 
   max_len_label_text = SXSIZE / getFontWidth(font_nr);
 
-  DrawBackground(SX, MICROLABEL_YPOS, SXSIZE, getFontHeight(font_nr));
+  for (i = 0; i < max_len_label_text; i++)
+    label_text[i] = ' ';
+  label_text[max_len_label_text] = '\0';
 
-  strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
-                      mode == MICROLABEL_CREATED_BY ? "created by" :
-                      mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
-                      mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
-                      mode == MICROLABEL_LEVEL_IMPORT_INFO ?
-                      leveldir_current->imported_from : ""),
+  if (strlen(label_text) > 0)
+  {
+    int lxpos = SX + (SXSIZE - getTextWidth(label_text, font_nr)) / 2;
+    int lypos = MICROLABEL2_YPOS;
+
+    DrawText(lxpos, lypos, label_text, font_nr);
+  }
+
+  strncpy(label_text,
+         (mode == MICROLABEL_LEVEL_NAME ? level.name :
+          mode == MICROLABEL_LEVEL_AUTHOR_HEAD ? "created by" :
+          mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
+          mode == MICROLABEL_IMPORTED_FROM_HEAD ? "imported from" :
+          mode == MICROLABEL_IMPORTED_FROM ? leveldir_current->imported_from :
+          mode == MICROLABEL_IMPORTED_BY_HEAD ? "imported by" :
+          mode == MICROLABEL_IMPORTED_BY ? leveldir_current->imported_by :""),
          max_len_label_text);
   label_text[max_len_label_text] = '\0';
 
   if (strlen(label_text) > 0)
   {
     int lxpos = SX + (SXSIZE - getTextWidth(label_text, font_nr)) / 2;
-    int lypos = MICROLABEL_YPOS;
+    int lypos = MICROLABEL2_YPOS;
 
     DrawText(lxpos, lypos, label_text, font_nr);
   }
@@ -1605,11 +1547,18 @@ void DrawMicroLevel(int xpos, int ypos, boolean restart)
 
     if (leveldir_current->name)
     {
-      int text_width = getTextWidth(leveldir_current->name, FONT_TEXT_1);
-      int lxpos = SX + (SXSIZE - text_width) / 2;
-      int lypos = SY + 352;
+      char label_text[MAX_OUTPUT_LINESIZE + 1];
+      int font_nr = FONT_TEXT_1;
+      int max_len_label_text = SXSIZE / getFontWidth(font_nr);
+      int lxpos, lypos;
+
+      strncpy(label_text, leveldir_current->name, max_len_label_text);
+      label_text[max_len_label_text] = '\0';
+
+      lxpos = SX + (SXSIZE - getTextWidth(label_text, font_nr)) / 2;
+      lypos = SY + MICROLABEL1_YPOS;
 
-      DrawText(lxpos, lypos, leveldir_current->name, FONT_TEXT_1);
+      DrawText(lxpos, lypos, label_text, font_nr);
     }
 
     game_status = last_game_status;    /* restore current game status */
@@ -1658,6 +1607,7 @@ void DrawMicroLevel(int xpos, int ypos, boolean restart)
     DrawMicroLevelExt(xpos, ypos, from_x, from_y);
   }
 
+  /* !!! THIS ALL SUCKS -- SHOULD BE CLEANLY REWRITTEN !!! */
   /* redraw micro level label, if needed */
   if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
       strcmp(level.author, ANONYMOUS_NAME) != 0 &&
@@ -1666,20 +1616,35 @@ void DrawMicroLevel(int xpos, int ypos, boolean restart)
   {
     int max_label_counter = 23;
 
-    if (leveldir_current->imported_from != NULL)
+    if (leveldir_current->imported_from != NULL &&
+       strlen(leveldir_current->imported_from) > 0)
+      max_label_counter += 14;
+    if (leveldir_current->imported_by != NULL &&
+       strlen(leveldir_current->imported_by) > 0)
       max_label_counter += 14;
 
     label_counter = (label_counter + 1) % max_label_counter;
     label_state = (label_counter >= 0 && label_counter <= 7 ?
                   MICROLABEL_LEVEL_NAME :
                   label_counter >= 9 && label_counter <= 12 ?
-                  MICROLABEL_CREATED_BY :
+                  MICROLABEL_LEVEL_AUTHOR_HEAD :
                   label_counter >= 14 && label_counter <= 21 ?
                   MICROLABEL_LEVEL_AUTHOR :
                   label_counter >= 23 && label_counter <= 26 ?
-                  MICROLABEL_IMPORTED_FROM :
+                  MICROLABEL_IMPORTED_FROM_HEAD :
                   label_counter >= 28 && label_counter <= 35 ?
-                  MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
+                  MICROLABEL_IMPORTED_FROM :
+                  label_counter >= 37 && label_counter <= 40 ?
+                  MICROLABEL_IMPORTED_BY_HEAD :
+                  label_counter >= 42 && label_counter <= 49 ?
+                  MICROLABEL_IMPORTED_BY : MICROLABEL_EMPTY);
+
+    if (leveldir_current->imported_from == NULL &&
+       (label_state == MICROLABEL_IMPORTED_FROM_HEAD ||
+        label_state == MICROLABEL_IMPORTED_FROM))
+      label_state = (label_state == MICROLABEL_IMPORTED_FROM_HEAD ?
+                    MICROLABEL_IMPORTED_BY_HEAD : MICROLABEL_IMPORTED_BY);
+
     DrawMicroLevelLabelExt(label_state);
   }
 
@@ -1716,13 +1681,9 @@ void DrawLevelGraphicAnimation(int x, int y, int graphic)
 
 void DrawLevelElementAnimation(int x, int y, int element)
 {
-#if 1
   int graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]);
 
   DrawGraphicAnimation(SCREENX(x), SCREENY(y), graphic);
-#else
-  DrawGraphicAnimation(SCREENX(x), SCREENY(y), el2img(element));
-#endif
 }
 
 inline void DrawLevelGraphicAnimationIfNeeded(int x, int y, int graphic)
@@ -1819,13 +1780,6 @@ void DrawPlayer(struct PlayerInfo *player)
   int jx = player->jx;
   int jy = player->jy;
   int move_dir = player->MovDir;
-#if 0
-  int last_jx = player->last_jx;
-  int last_jy = player->last_jy;
-  int next_jx = jx + (jx - last_jx);
-  int next_jy = jy + (jy - last_jy);
-  boolean player_is_moving = (last_jx != jx || last_jy != jy ? TRUE : FALSE);
-#else
   int dx = (move_dir == MV_LEFT ? -1 : move_dir == MV_RIGHT ? +1 : 0);
   int dy = (move_dir == MV_UP   ? -1 : move_dir == MV_DOWN  ? +1 : 0);
   int last_jx = (player->is_moving ? jx - dx : jx);
@@ -1833,7 +1787,6 @@ void DrawPlayer(struct PlayerInfo *player)
   int next_jx = jx + dx;
   int next_jy = jy + dy;
   boolean player_is_moving = (player->MovPos ? TRUE : FALSE);
-#endif
   int sx = SCREENX(jx), sy = SCREENY(jy);
   int sxx = 0, syy = 0;
   int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy];
@@ -1873,11 +1826,7 @@ void DrawPlayer(struct PlayerInfo *player)
   /* draw things in the field the player is leaving, if needed               */
   /* ----------------------------------------------------------------------- */
 
-#if 1
   if (player->is_moving)
-#else
-  if (player_is_moving)
-#endif
   {
     if (Back[last_jx][last_jy] && IS_DRAWABLE(last_element))
     {
@@ -1932,6 +1881,10 @@ void DrawPlayer(struct PlayerInfo *player)
     {
       GfxElement[jx][jy] = EL_UNDEFINED;
 
+      /* make sure that pushed elements are drawn with correct frame rate */
+      if (player->is_pushing && player->is_moving)
+       GfxFrame[jx][jy] = player->StepFrame;
+
       DrawLevelField(jx, jy);
     }
   }
@@ -1940,8 +1893,6 @@ void DrawPlayer(struct PlayerInfo *player)
   /* draw player himself                                                     */
   /* ----------------------------------------------------------------------- */
 
-#if 1
-
   graphic = getPlayerGraphic(player, move_dir);
 
   /* in the case of changed player action or direction, prevent the current
@@ -1949,29 +1900,6 @@ void DrawPlayer(struct PlayerInfo *player)
   if (player->Frame == 0 && equalGraphics(graphic, last_player_graphic))
     player->Frame = last_player_frame;
 
-#else
-
-  if (player->use_murphy_graphic)
-  {
-    static int last_horizontal_dir = MV_LEFT;
-
-    if (move_dir == MV_LEFT || move_dir == MV_RIGHT)
-      last_horizontal_dir = move_dir;
-
-    graphic = el_act_dir2img(EL_SP_MURPHY, player->GfxAction, move_dir);
-
-    if (graphic == IMG_SP_MURPHY)      /* undefined => use special graphic */
-    {
-      int direction = (player->is_snapping ? move_dir : last_horizontal_dir);
-
-      graphic = el_act_dir2img(EL_SP_MURPHY, player->GfxAction, direction);
-    }
-  }
-  else
-    graphic = el_act_dir2img(player->element_nr, player->GfxAction, move_dir);
-
-#endif
-
   frame = getGraphicAnimationFrame(graphic, player->Frame);
 
   if (player->GfxPos)
@@ -2008,21 +1936,11 @@ void DrawPlayer(struct PlayerInfo *player)
 
 #if 1
   if (player->is_pushing && player->is_moving)
-#else
-  if (player->is_pushing && player_is_moving)
-#endif
   {
-#if 1
     int px = SCREENX(jx), py = SCREENY(jy);
     int pxx = (TILEX - ABS(sxx)) * dx;
     int pyy = (TILEY - ABS(syy)) * dy;
-#else
-    int px = SCREENX(next_jx), py = SCREENY(next_jy);
-    int pxx = sxx;
-    int pyy = syy;
-#endif
 
-#if 1
     int graphic;
     int frame;
 
@@ -2038,35 +1956,8 @@ void DrawPlayer(struct PlayerInfo *player)
 
     /* masked drawing is needed for EMC style (double) movement graphics */
     DrawGraphicShiftedThruMask(px, py, pxx, pyy, graphic, frame, NO_CUTTING);
-
-#else
-    if (Back[next_jx][next_jy])
-      DrawLevelElement(next_jx, next_jy, Back[next_jx][next_jy]);
-
-    if ((pxx || pyy) && element == EL_SOKOBAN_OBJECT)
-      DrawGraphicShiftedThruMask(px, py, pxx, pyy, IMG_SOKOBAN_OBJECT, 0,
-                                NO_CUTTING);
-    else
-    {
-      int element = MovingOrBlocked2Element(next_jx, next_jy);
-      int graphic = el_act_dir2img(element, ACTION_PUSHING, move_dir);
-#if 1
-      int frame = getGraphicAnimationFrame(graphic, player->StepFrame);
-#else
-      int frame = getGraphicAnimationFrame(graphic, player->Frame);
-#endif
-
-#if 1
-      /* masked drawing is needed for EMC style (double) movement graphics */
-      DrawGraphicShiftedThruMask(px, py, pxx, pyy, graphic, frame,
-                                NO_CUTTING);
-#else
-      DrawGraphicShifted(px, py, pxx, pyy, graphic, frame,
-                        NO_CUTTING, NO_MASKING);
-#endif
-    }
-#endif
   }
+#endif
 
   /* ----------------------------------------------------------------------- */
   /* draw things in front of player (active dynamite or dynabombs)           */
@@ -2107,7 +1998,6 @@ void DrawPlayer(struct PlayerInfo *player)
       DrawLevelFieldThruMask(last_jx, last_jy);
   }
 
-#if 1
   /* do not redraw accessible elements if the player is just pushing them */
   if (!player_is_moving || !player->is_pushing)
   {
@@ -2118,22 +2008,6 @@ void DrawPlayer(struct PlayerInfo *player)
       DrawLevelFieldThruMask(jx, jy);
   }
 
-#else
-
-#if 0
-  /* !!! I have forgotton what this should be good for !!! */
-  /* !!! causes player being visible when pushing from within tubes !!! */
-  if (!player->is_pushing)
-#endif
-  {
-    /* ... and the field the player is entering */
-    if (IS_ACCESSIBLE_INSIDE(element))
-      DrawLevelField(jx, jy);
-    else if (IS_ACCESSIBLE_UNDER(element))
-      DrawLevelFieldThruMask(jx, jy);
-  }
-#endif
-
   if (setup.direct_draw)
   {
     int dst_x = SX + SCREENX(MIN(jx, last_jx)) * TILEX;
@@ -2224,21 +2098,15 @@ boolean Request(char *text, unsigned int req_state)
     }
   }
 
-#if 1
   if (game_status == GAME_MODE_PLAYING &&
       level.game_engine_type == GAME_ENGINE_TYPE_EM)
     BlitScreenToBitmap_EM(backbuffer);
-#endif
 
-#if 1
   /* disable deactivated drawing when quick-loading level tape recording */
   if (tape.playing && tape.deactivate_display)
     TapeDeactivateDisplayOff(TRUE);
-#endif
 
-#if 1
   SetMouseCursor(CURSOR_DEFAULT);
-#endif
 
 #if defined(NETWORK_AVALIABLE)
   /* pause network game while waiting for request to answer */
@@ -2333,10 +2201,6 @@ boolean Request(char *text, unsigned int req_state)
 
   OpenDoor(DOOR_OPEN_1);
 
-#if 0
-  ClearEventQueue();
-#endif
-
   if (!(req_state & REQUEST_WAIT_FOR_INPUT))
   {
     SetDrawBackgroundMask(REDRAW_FIELD);
@@ -2353,10 +2217,6 @@ boolean Request(char *text, unsigned int req_state)
 
   SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1);
 
-#if 0
-  SetMouseCursor(CURSOR_DEFAULT);
-#endif
-
   while (result < 0)
   {
     if (PendingEvent())
@@ -2498,11 +2358,9 @@ boolean Request(char *text, unsigned int req_state)
     SendToServer_ContinuePlaying();
 #endif
 
-#if 1
   /* restore deactivated drawing when quick-loading level tape recording */
   if (tape.playing && tape.deactivate_display)
     TapeDeactivateDisplayOn();
-#endif
 
   return result;
 }
@@ -2594,11 +2452,6 @@ unsigned int MoveDoor(unsigned int door_state)
   {
     stepsize = 20;             /* must be choosen to always draw last frame */
     door_delay_value = 0;
-
-#if 0
-    StopSound(SND_DOOR_OPENING);
-    StopSound(SND_DOOR_CLOSING);
-#endif
   }
 
   if (global.autoplay_leveldir)
@@ -2799,14 +2652,6 @@ unsigned int MoveDoor(unsigned int door_state)
     }
   }
 
-#if 0
-  if (setup.quick_doors)
-  {
-    StopSound(SND_DOOR_OPENING);
-    StopSound(SND_DOOR_CLOSING);
-  }
-#endif
-
   if (door_state & DOOR_ACTION_1)
     door1 = door_state & DOOR_ACTION_1;
   if (door_state & DOOR_ACTION_2)
@@ -3019,8 +2864,6 @@ static void HandleToolButtons(struct GadgetInfo *gi)
   request_gadget_id = gi->custom_id;
 }
 
-#if 1
-
 static struct Mapping_EM_to_RND_object
 {
   int element_em;
@@ -3807,7 +3650,7 @@ em_object_mapping_list[] =
   },
   {
     Ybomb_eat,                         FALSE,  FALSE,
-    EL_BOMB,                           ACTION_SMASHED_BY_ROCK, -1
+    EL_BOMB,                           ACTION_ACTIVATING, -1
   },
   {
     Xballoon,                          TRUE,   FALSE,
@@ -3975,19 +3818,19 @@ em_object_mapping_list[] =
   },
   {
     Ykey_5_eat,                                FALSE,  FALSE,
-    EL_EM_KEY_5,                       ACTION_COLLECTING, -1
+    EL_EMC_KEY_5,                      ACTION_COLLECTING, -1
   },
   {
     Ykey_6_eat,                                FALSE,  FALSE,
-    EL_EM_KEY_6,                       ACTION_COLLECTING, -1
+    EL_EMC_KEY_6,                      ACTION_COLLECTING, -1
   },
   {
     Ykey_7_eat,                                FALSE,  FALSE,
-    EL_EM_KEY_7,                       ACTION_COLLECTING, -1
+    EL_EMC_KEY_7,                      ACTION_COLLECTING, -1
   },
   {
     Ykey_8_eat,                                FALSE,  FALSE,
-    EL_EM_KEY_8,                       ACTION_COLLECTING, -1
+    EL_EMC_KEY_8,                      ACTION_COLLECTING, -1
   },
   {
     Ylenses_eat,                       FALSE,  FALSE,
@@ -4046,7 +3889,7 @@ em_object_mapping_list[] =
     EL_AMOEBA_DRY,                     ACTION_OTHER, -1
   },
   {
-    Xamoeba_5,                         FALSE,  FALSE,
+    Xamoeba_5,                         TRUE,   FALSE,
     EL_AMOEBA_WET,                     ACTION_OTHER, -1
   },
   {
@@ -4079,19 +3922,19 @@ em_object_mapping_list[] =
   },
   {
     Xdoor_5,                           TRUE,   FALSE,
-    EL_EM_GATE_5,                      -1, -1
+    EL_EMC_GATE_5,                     -1, -1
   },
   {
     Xdoor_6,                           TRUE,   FALSE,
-    EL_EM_GATE_6,                      -1, -1
+    EL_EMC_GATE_6,                     -1, -1
   },
   {
     Xdoor_7,                           TRUE,   FALSE,
-    EL_EM_GATE_7,                      -1, -1
+    EL_EMC_GATE_7,                     -1, -1
   },
   {
     Xdoor_8,                           TRUE,   FALSE,
-    EL_EM_GATE_8,                      -1, -1
+    EL_EMC_GATE_8,                     -1, -1
   },
   {
     Xkey_1,                            TRUE,   FALSE,
@@ -4111,19 +3954,19 @@ em_object_mapping_list[] =
   },
   {
     Xkey_5,                            TRUE,   FALSE,
-    EL_EM_KEY_5,                       -1, -1
+    EL_EMC_KEY_5,                      -1, -1
   },
   {
     Xkey_6,                            TRUE,   FALSE,
-    EL_EM_KEY_6,                       -1, -1
+    EL_EMC_KEY_6,                      -1, -1
   },
   {
     Xkey_7,                            TRUE,   FALSE,
-    EL_EM_KEY_7,                       -1, -1
+    EL_EMC_KEY_7,                      -1, -1
   },
   {
     Xkey_8,                            TRUE,   FALSE,
-    EL_EM_KEY_8,                       -1, -1
+    EL_EMC_KEY_8,                      -1, -1
   },
   {
     Xwind_n,                           TRUE,   FALSE,
@@ -4335,19 +4178,51 @@ em_object_mapping_list[] =
   },
   {
     Xfake_door_5,                      TRUE,   FALSE,
-    EL_EM_GATE_5_GRAY,                 -1, -1
+    EL_EMC_GATE_5_GRAY,                        -1, -1
   },
   {
     Xfake_door_6,                      TRUE,   FALSE,
-    EL_EM_GATE_6_GRAY,                 -1, -1
+    EL_EMC_GATE_6_GRAY,                        -1, -1
   },
   {
     Xfake_door_7,                      TRUE,   FALSE,
-    EL_EM_GATE_7_GRAY,                 -1, -1
+    EL_EMC_GATE_7_GRAY,                        -1, -1
   },
   {
     Xfake_door_8,                      TRUE,   FALSE,
-    EL_EM_GATE_8_GRAY,                 -1, -1
+    EL_EMC_GATE_8_GRAY,                        -1, -1
+  },
+  {
+    Xfake_acid_1,                      TRUE,   FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
+  },
+  {
+    Xfake_acid_2,                      FALSE,  FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
+  },
+  {
+    Xfake_acid_3,                      FALSE,  FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
+  },
+  {
+    Xfake_acid_4,                      FALSE,  FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
+  },
+  {
+    Xfake_acid_5,                      FALSE,  FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
+  },
+  {
+    Xfake_acid_6,                      FALSE,  FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
+  },
+  {
+    Xfake_acid_7,                      FALSE,  FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
+  },
+  {
+    Xfake_acid_8,                      FALSE,  FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
   },
   {
     Xsteel_1,                          TRUE,   FALSE,
@@ -4856,7 +4731,7 @@ int map_element_EM_to_RND(int element_em)
   return EL_UNKNOWN;
 }
 
-#else
+#if 0
 
 int map_element_RND_to_EM(int element_rnd)
 {
@@ -5599,6 +5474,11 @@ int el2preimg(int element)
   return element_info[element].special_graphic[GFX_SPECIAL_ARG_PREVIEW];
 }
 
+int font2baseimg(int font_nr)
+{
+  return font_info[font_nr].special_graphic[GFX_SPECIAL_ARG_DEFAULT];
+}
+
 int getGameFrameDelay_EM(int native_em_game_frame_delay)
 {
   int game_frame_delay_value;
@@ -5798,6 +5678,14 @@ void InitGraphicInfo_EM(void)
                        i == Xacid_6 ? 50 :
                        i == Xacid_7 ? 60 :
                        i == Xacid_8 ? 70 :
+                       i == Xfake_acid_1 ? 0 :
+                       i == Xfake_acid_2 ? 10 :
+                       i == Xfake_acid_3 ? 20 :
+                       i == Xfake_acid_4 ? 30 :
+                       i == Xfake_acid_5 ? 40 :
+                       i == Xfake_acid_6 ? 50 :
+                       i == Xfake_acid_7 ? 60 :
+                       i == Xfake_acid_8 ? 70 :
                        i == Xball_2 ? 7 :
                        i == Xball_2B ? j + 8 :
                        i == Yball_eat ? j + 1 :
@@ -5896,7 +5784,6 @@ void InitGraphicInfo_EM(void)
       getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x, &src_y,
                          g->double_movement && is_backside);
 
-#if 1
       g_em->bitmap = src_bitmap;
       g_em->src_x = src_x;
       g_em->src_y = src_y;
@@ -5907,18 +5794,13 @@ void InitGraphicInfo_EM(void)
       g_em->width  = TILEX;
       g_em->height = TILEY;
 
-      g_em->has_crumbled_graphics = FALSE;
       g_em->crumbled_bitmap = NULL;
       g_em->crumbled_src_x = 0;
       g_em->crumbled_src_y = 0;
       g_em->crumbled_border_size = 0;
-#endif
 
-#if 0
-      if (effective_element == EL_EMC_GRASS &&
-         effective_action == ACTION_DIGGING)
-       printf("::: %d\n", crumbled);
-#endif
+      g_em->has_crumbled_graphics = FALSE;
+      g_em->preserve_background = FALSE;
 
 #if 0
       if (has_crumbled_graphics && crumbled == IMG_EMPTY_SPACE)
@@ -5941,7 +5823,6 @@ void InitGraphicInfo_EM(void)
        g_em->crumbled_border_size = graphic_info[crumbled].border_size;
       }
 
-#if 1
       if (!g->double_movement && (effective_action == ACTION_FALLING ||
                                  effective_action == ACTION_MOVING ||
                                  effective_action == ACTION_PUSHING))
@@ -5950,43 +5831,46 @@ void InitGraphicInfo_EM(void)
          (effective_action == ACTION_FALLING ? MV_DOWN : direction);
        int dx = (move_dir == MV_LEFT ? -1 : move_dir == MV_RIGHT ? 1 : 0);
        int dy = (move_dir == MV_UP   ? -1 : move_dir == MV_DOWN  ? 1 : 0);
-       int cx = ABS(dx) * TILEX / 8;
-       int cy = ABS(dy) * TILEY / 8;
-
-       if (is_backside)                /* tile where movement starts */
+       int num_steps = (i == Ydrip_s1 ||
+                        i == Ydrip_s1B ||
+                        i == Ydrip_s2 ||
+                        i == Ydrip_s2B ? 16 : 8);
+       int cx = ABS(dx) * (TILEX / num_steps);
+       int cy = ABS(dy) * (TILEY / num_steps);
+       int step_frame = (i == Ydrip_s2 ||
+                         i == Ydrip_s2B ? j + 8 : j) + 1;
+       int step = (is_backside ? step_frame : num_steps - step_frame);
+
+       if (is_backside)        /* tile where movement starts */
        {
          if (dx < 0 || dy < 0)
          {
-           g_em->src_offset_x = cx * (j + 1);
-           g_em->src_offset_y = cy * (j + 1);
+           g_em->src_offset_x = cx * step;
+           g_em->src_offset_y = cy * step;
          }
          else
          {
-           g_em->dst_offset_x = cx * (j + 1);
-           g_em->dst_offset_y = cy * (j + 1);
+           g_em->dst_offset_x = cx * step;
+           g_em->dst_offset_y = cy * step;
          }
-
-         g_em->width  = TILEX - cx * (j + 1);
-         g_em->height = TILEY - cy * (j + 1);
        }
        else                    /* tile where movement ends */
        {
          if (dx < 0 || dy < 0)
          {
-           g_em->dst_offset_x = cx * (7 - j);
-           g_em->dst_offset_y = cy * (7 - j);
+           g_em->dst_offset_x = cx * step;
+           g_em->dst_offset_y = cy * step;
          }
          else
          {
-           g_em->src_offset_x = cx * (7 - j);
-           g_em->src_offset_y = cy * (7 - j);
+           g_em->src_offset_x = cx * step;
+           g_em->src_offset_y = cy * step;
          }
-
-         g_em->width  = TILEX - cx * (7 - j);
-         g_em->height = TILEY - cy * (7 - j);
        }
+
+       g_em->width  = TILEX - cx * step;
+       g_em->height = TILEY - cy * step;
       }
-#endif
 
       /* create unique graphic identifier to decide if tile must be redrawn */
       /* bit 31 - 16 (16 bit): EM style element
@@ -6059,6 +5943,36 @@ void InitGraphicInfo_EM(void)
     }
   }
 
+  for (i = 0; i < TILE_MAX; i++)
+  {
+    for (j = 0; j < 8; j++)
+    {
+      int element = object_mapping[i].element_rnd;
+      int action = object_mapping[i].action;
+
+      if (action == ACTION_SMASHED_BY_ROCK &&
+         element_info[element].graphic[action] ==
+         element_info[element].graphic[ACTION_DEFAULT])
+      {
+       /* no separate animation for "smashed by rock" -- use rock instead */
+       struct GraphicInfo_EM *g_em = &graphic_info_em_object[i][7 - j];
+       struct GraphicInfo_EM *g_xx = &graphic_info_em_object[Ystone_s][7 - j];
+
+       g_em->bitmap            = g_xx->bitmap;
+       g_em->src_x             = g_xx->src_x;
+       g_em->src_y             = g_xx->src_y;
+       g_em->src_offset_x      = g_xx->src_offset_x;
+       g_em->src_offset_y      = g_xx->src_offset_y;
+       g_em->dst_offset_x      = g_xx->dst_offset_x;
+       g_em->dst_offset_y      = g_xx->dst_offset_y;
+       g_em->width             = g_xx->width;
+       g_em->height            = g_xx->height;
+
+       g_em->preserve_background = TRUE;
+      }
+    }
+  }
+
   for (p = 0; p < 2; p++)
   {
     for (i = 0; i < SPR_MAX; i++)
@@ -6095,7 +6009,6 @@ void InitGraphicInfo_EM(void)
 
        getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x,&src_y, FALSE);
 
-#if 1
        g_em->bitmap = src_bitmap;
        g_em->src_x = src_x;
        g_em->src_y = src_y;
@@ -6105,7 +6018,6 @@ void InitGraphicInfo_EM(void)
        g_em->dst_offset_y = 0;
        g_em->width  = TILEX;
        g_em->height = TILEY;
-#endif
 
 #if DEBUG_EM_GFX
        if (g_em->bitmap != debug_bitmap ||