rnd-20021227-2-src
[rocksndiamonds.git] / src / tools.c
index 0c9cd1766e69264bcacc83ed69a7f278ac7d9e96..9b972e7df955a0557e9876d2c413142ab35859eb 100644 (file)
@@ -1,35 +1,24 @@
 /***********************************************************
-*  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
+* Rocks'n'Diamonds -- McDuffin Strikes Back!               *
 *----------------------------------------------------------*
-*  (c) 1995-98 Artsoft Entertainment                       *
-*              Holger Schemel                              *
-*              Oststrasse 11a                              *
-*              33604 Bielefeld                             *
-*              phone: ++49 +521 290471                     *
-*              email: aeglos@valinor.owl.de                *
+* (c) 1995-2002 Artsoft Entertainment                      *
+*               Holger Schemel                             *
+*               Detmolder Strasse 189                      *
+*               33604 Bielefeld                            *
+*               Germany                                    *
+*               e-mail: info@artsoft.org                   *
 *----------------------------------------------------------*
-*  tools.c                                                 *
+* tools.c                                                  *
 ***********************************************************/
 
-#include <stdarg.h>
-
-#ifdef __FreeBSD__
-#include <machine/joystick.h>
-#endif
+#include "libgame/libgame.h"
 
 #include "tools.h"
 #include "game.h"
 #include "events.h"
-#include "sound.h"
-#include "misc.h"
-#include "buttons.h"
-#include "joystick.h"
 #include "cartoons.h"
 #include "network.h"
-
-#ifdef MSDOS
-extern boolean wait_for_vsync;
-#endif
+#include "tape.h"
 
 /* tool button identifiers */
 #define TOOL_CTRL_ID_YES       0
@@ -43,9 +32,6 @@ extern boolean wait_for_vsync;
 #define NUM_TOOL_BUTTONS       7
 
 /* forward declaration for internal use */
-static int getGraphicAnimationPhase(int, int, int);
-static void DrawGraphicAnimationShiftedThruMask(int, int, int, int, int,
-                                               int, int, int);
 static void UnmapToolButtons();
 static void HandleToolButtons(struct GadgetInfo *);
 
@@ -82,10 +68,55 @@ void SetDrawtoField(int mode)
   }
 }
 
+void RedrawPlayfield(boolean force_redraw, int x, int y, int width, int height)
+{
+  if (game_status == PLAYING)
+  {
+    if (force_redraw)
+    {
+      x = gfx.sx - TILEX;
+      y = gfx.sy - TILEY;
+      width = gfx.sxsize + 2 * TILEX;
+      height = gfx.sysize + 2 * TILEY;
+    }
+
+    if (force_redraw || setup.direct_draw)
+    {
+      int xx, yy;
+      int x1 = (x - SX) / TILEX, y1 = (y - SY) / TILEY;
+      int x2 = (x - SX + width) / TILEX, y2 = (y - SY + height) / TILEY;
+
+      if (setup.direct_draw)
+       SetDrawtoField(DRAW_BACKBUFFER);
+
+      for(xx=BX1; xx<=BX2; xx++)
+       for(yy=BY1; yy<=BY2; yy++)
+         if (xx >= x1 && xx <= x2 && yy >= y1 && yy <= y2)
+           DrawScreenField(xx, yy);
+      DrawAllPlayers();
+
+      if (setup.direct_draw)
+       SetDrawtoField(DRAW_DIRECT);
+    }
+
+    if (setup.soft_scrolling)
+    {
+      int fx = FX, fy = FY;
+
+      fx += (ScreenMovDir & (MV_LEFT|MV_RIGHT) ? ScreenGfxPos : 0);
+      fy += (ScreenMovDir & (MV_UP|MV_DOWN)    ? ScreenGfxPos : 0);
+
+      BlitBitmap(fieldbuffer, backbuffer, fx,fy, SXSIZE,SYSIZE, SX,SY);
+    }
+  }
+
+  BlitBitmap(drawto, window, x, y, width, height, x, y);
+}
+
 void BackToFront()
 {
   int x,y;
-  Drawable buffer = (drawto_field == window ? backbuffer : drawto_field);
+  DrawBuffer *buffer = (drawto_field == window ? backbuffer : drawto_field);
 
   if (setup.direct_draw && game_status == PLAYING)
     redraw_mask &= ~REDRAW_MAIN;
@@ -96,21 +127,49 @@ void BackToFront()
   if (redraw_mask & REDRAW_FIELD)
     redraw_mask &= ~REDRAW_TILES;
 
-  if (!redraw_mask)
+  if (redraw_mask == REDRAW_NONE)
     return;
 
+  if (global.fps_slowdown && game_status == PLAYING)
+  {
+    static boolean last_frame_skipped = FALSE;
+    boolean skip_even_when_not_scrolling = TRUE;
+    boolean just_scrolling = (ScreenMovDir != 0);
+    boolean verbose = FALSE;
+
+    if (global.fps_slowdown_factor > 1 &&
+       (FrameCounter % global.fps_slowdown_factor) &&
+       (just_scrolling || skip_even_when_not_scrolling))
+    {
+      redraw_mask &= ~REDRAW_MAIN;
+
+      last_frame_skipped = TRUE;
+
+      if (verbose)
+       printf("FRAME SKIPPED\n");
+    }
+    else
+    {
+      if (last_frame_skipped)
+       redraw_mask |= REDRAW_FIELD;
+
+      last_frame_skipped = FALSE;
+
+      if (verbose)
+       printf("frame not skipped\n");
+    }
+  }
+
   /* synchronize X11 graphics at this point; if we would synchronize the
      display immediately after the buffer switching (after the XFlush),
      this could mean that we have to wait for the graphics to complete,
      although we could go on doing calculations for the next frame */
 
-  XSync(display, FALSE);
+  SyncDisplay();
 
   if (redraw_mask & REDRAW_ALL)
   {
-    XCopyArea(display, backbuffer, window, gc,
-             0, 0, WIN_XSIZE, WIN_YSIZE,
-             0, 0);
+    BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
     redraw_mask = 0;
   }
 
@@ -118,9 +177,8 @@ void BackToFront()
   {
     if (game_status != PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER)
     {
-      XCopyArea(display, backbuffer, window, gc,
-               REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE,
-               REAL_SX, REAL_SY);
+      BlitBitmap(backbuffer, window,
+                REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, REAL_SX, REAL_SY);
     }
     else
     {
@@ -137,7 +195,7 @@ void BackToFront()
          ABS(ScreenMovPos) == ScrollStepSize ||
          redraw_tiles > REDRAWTILES_THRESHOLD)
       {
-       XCopyArea(display, buffer, window, gc, fx, fy, SXSIZE, SYSIZE, SX, SY);
+       BlitBitmap(buffer, window, fx, fy, SXSIZE, SYSIZE, SX, SY);
 
 #ifdef DEBUG
 #if 0
@@ -154,55 +212,50 @@ void BackToFront()
 #endif
       }
     }
+
     redraw_mask &= ~REDRAW_MAIN;
   }
 
   if (redraw_mask & REDRAW_DOORS)
   {
     if (redraw_mask & REDRAW_DOOR_1)
-      XCopyArea(display, backbuffer, window, gc,
-               DX, DY, DXSIZE, DYSIZE,
-               DX, DY);
+      BlitBitmap(backbuffer, window, DX, DY, DXSIZE, DYSIZE, DX, DY);
     if (redraw_mask & REDRAW_DOOR_2)
     {
       if ((redraw_mask & REDRAW_DOOR_2) == REDRAW_DOOR_2)
-       XCopyArea(display,backbuffer,window,gc,
-                 VX,VY, VXSIZE,VYSIZE,
-                 VX,VY);
+       BlitBitmap(backbuffer, window, VX,VY, VXSIZE,VYSIZE, VX,VY);
       else
       {
        if (redraw_mask & REDRAW_VIDEO_1)
-         XCopyArea(display,backbuffer,window,gc,
-                   VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS,
-                   VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
-                   VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS);
+         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)
-         XCopyArea(display,backbuffer,window,gc,
-                   VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS,
-                   VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
-                   VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS);
+         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)
-         XCopyArea(display,backbuffer,window,gc,
-                   VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS,
-                   VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
-                   VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
+         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);
       }
     }
     if (redraw_mask & REDRAW_DOOR_3)
-      XCopyArea(display, backbuffer, window, gc,
-               EX, EY, EXSIZE, EYSIZE,
-               EX, EY);
+      BlitBitmap(backbuffer, window, EX, EY, EXSIZE, EYSIZE, EX, EY);
     redraw_mask &= ~REDRAW_DOORS;
   }
 
   if (redraw_mask & REDRAW_MICROLEVEL)
   {
-    XCopyArea(display,backbuffer,window,gc,
-             MICROLEV_XPOS, MICROLEV_YPOS, MICROLEV_XSIZE, MICROLEV_YSIZE,
-             MICROLEV_XPOS, MICROLEV_YPOS);
-    XCopyArea(display,backbuffer,window,gc,
-             SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE,
-             SX, MICROLABEL_YPOS);
+    BlitBitmap(backbuffer, window,
+              MICROLEV_XPOS, MICROLEV_YPOS, MICROLEV_XSIZE, MICROLEV_YSIZE,
+              MICROLEV_XPOS, MICROLEV_YPOS);
+    BlitBitmap(backbuffer, window,
+              SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE,
+              SX, MICROLABEL_YPOS);
     redraw_mask &= ~REDRAW_MICROLEVEL;
   }
 
@@ -211,96 +264,111 @@ void BackToFront()
     for(x=0; x<SCR_FIELDX; x++)
       for(y=0; y<SCR_FIELDY; y++)
        if (redraw[redraw_x1 + x][redraw_y1 + y])
-         XCopyArea(display, buffer, window, gc,
-                   FX + x * TILEX, FX + y * TILEY, TILEX, TILEY,
-                   SX + x * TILEX, SY + y * TILEY);
+         BlitBitmap(buffer, window,
+                    FX + x * TILEX, FX + y * TILEY, TILEX, TILEY,
+                    SX + x * TILEX, SY + y * TILEY);
+  }
+
+  if (redraw_mask & REDRAW_FPS)                /* display frames per second */
+  {
+    char text[100];
+    char info1[100];
+
+    sprintf(info1, " (only every %d. frame)", global.fps_slowdown_factor);
+    if (!global.fps_slowdown)
+      info1[0] = '\0';
+
+    sprintf(text, "%.1f fps%s", global.frames_per_second, info1);
+    DrawTextExt(window, SX, SY, text, FS_SMALL, FC_YELLOW);
   }
 
-  XFlush(display);
+  FlushDisplay();
 
   for(x=0; x<MAX_BUF_XSIZE; x++)
     for(y=0; y<MAX_BUF_YSIZE; y++)
       redraw[x][y] = 0;
   redraw_tiles = 0;
-  redraw_mask = 0;
+  redraw_mask = REDRAW_NONE;
 }
 
 void FadeToFront()
 {
-/*
+#if 0
   long fading_delay = 300;
 
   if (setup.fading && (redraw_mask & REDRAW_FIELD))
   {
-*/
+#endif
 
-/*
+#if 0
     int x,y;
 
-    XFillRectangle(display,window,gc,
-                  REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
-    XFlush(display);
+    ClearRectangle(window, REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
+    FlushDisplay();
 
     for(i=0;i<2*FULL_SYSIZE;i++)
     {
       for(y=0;y<FULL_SYSIZE;y++)
       {
-       XCopyArea(display,backbuffer,window,gc,
-                 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
+       BlitBitmap(backbuffer, window,
+                  REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
       }
-      XFlush(display);
+      FlushDisplay();
       Delay(10);
     }
-*/
+#endif
 
-/*
+#if 0
     for(i=1;i<FULL_SYSIZE;i+=2)
-      XCopyArea(display,backbuffer,window,gc,
-               REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
-    XFlush(display);
+      BlitBitmap(backbuffer, window,
+                REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
+    FlushDisplay();
     Delay(fading_delay);
-*/
+#endif
 
-/*
-    XSetClipOrigin(display,clip_gc[PIX_FADEMASK],0,0);
-    XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
-             REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
-    XFlush(display);
+#if 0
+    SetClipOrigin(clip_gc[PIX_FADEMASK], 0, 0);
+    BlitBitmapMasked(backbuffer, window,
+                    REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
+                    REAL_SX,REAL_SY);
+    FlushDisplay();
     Delay(fading_delay);
 
-    XSetClipOrigin(display,clip_gc[PIX_FADEMASK],-1,-1);
-    XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
-             REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
-    XFlush(display);
+    SetClipOrigin(clip_gc[PIX_FADEMASK], -1, -1);
+    BlitBitmapMasked(backbuffer, window,
+                    REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
+                    REAL_SX,REAL_SY);
+    FlushDisplay();
     Delay(fading_delay);
 
-    XSetClipOrigin(display,clip_gc[PIX_FADEMASK],0,-1);
-    XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
-             REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
-    XFlush(display);
+    SetClipOrigin(clip_gc[PIX_FADEMASK], 0, -1);
+    BlitBitmapMasked(backbuffer, window,
+                    REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
+                    REAL_SX,REAL_SY);
+    FlushDisplay();
     Delay(fading_delay);
 
-    XSetClipOrigin(display,clip_gc[PIX_FADEMASK],-1,0);
-    XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
-             REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
-    XFlush(display);
+    SetClipOrigin(clip_gc[PIX_FADEMASK], -1, 0);
+    BlitBitmapMasked(backbuffer, window,
+                    REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
+                    REAL_SX,REAL_SY);
+    FlushDisplay();
     Delay(fading_delay);
 
     redraw_mask &= ~REDRAW_MAIN;
   }
-*/
+#endif
 
   BackToFront();
 }
 
 void ClearWindow()
 {
-  XFillRectangle(display, backbuffer, gc,
-                REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
+  ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
 
   if (setup.soft_scrolling && game_status == PLAYING)
   {
-    XFillRectangle(display, fieldbuffer, gc, 0, 0, FXSIZE, FYSIZE);
+    ClearRectangle(fieldbuffer, 0, 0, FXSIZE, FYSIZE);
     SetDrawtoField(DRAW_BUFFERED);
   }
   else
@@ -308,167 +376,74 @@ void ClearWindow()
 
   if (setup.direct_draw && game_status == PLAYING)
   {
-    XFillRectangle(display, window, gc,
-                  REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
+    ClearRectangle(window, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
     SetDrawtoField(DRAW_DIRECT);
   }
 
   redraw_mask |= REDRAW_FIELD;
 }
 
-int getFontWidth(int font_size, int font_type)
-{
-  return (font_size == FS_BIG ? FONT1_XSIZE :
-         font_size == FS_MEDIUM ? FONT6_XSIZE :
-         font_type == FC_SPECIAL1 ? FONT3_XSIZE :
-         font_type == FC_SPECIAL2 ? FONT4_XSIZE :
-         font_type == FC_SPECIAL3 ? FONT5_XSIZE :
-         FONT2_XSIZE);
-}
-
-int getFontHeight(int font_size, int font_type)
+static int getGraphicAnimationPhase(int frames, int delay, int mode)
 {
-  return (font_size == FS_BIG ? FONT1_YSIZE :
-         font_size == FS_MEDIUM ? FONT6_YSIZE :
-         font_type == FC_SPECIAL1 ? FONT3_YSIZE :
-         font_type == FC_SPECIAL2 ? FONT4_YSIZE :
-         font_type == FC_SPECIAL3 ? FONT5_YSIZE :
-         FONT2_YSIZE);
-}
+  int phase;
 
-void DrawInitText(char *text, int ypos, int color)
-{
-#ifdef USE_SDL_LIBRARY
-  if (sdl_window && sdl_pix[PIX_SMALLFONT])
-  {
-    SDLFillRectangle(sdl_window, 0, ypos, WIN_XSIZE, FONT2_YSIZE, 0x000000);
-    DrawTextExt(window, gc, (WIN_XSIZE - strlen(text) * FONT2_XSIZE)/2,
-               ypos,text,FS_SMALL,color);
-    SDL_Flip(sdl_window);
-  }
-#else
-  if (display && window && pix[PIX_SMALLFONT])
+  if (mode & ANIM_PINGPONG)
   {
-    XFillRectangle(display, window, gc, 0, ypos, WIN_XSIZE, FONT2_YSIZE);
-    DrawTextExt(window, gc, (WIN_XSIZE - strlen(text) * FONT2_XSIZE)/2,
-               ypos,text,FS_SMALL,color);
-    XFlush(display);
-  }
-#endif
-}
+    int max_anim_frames = 2 * frames - 2;
 
-void DrawTextFCentered(int y, int font_type, char *format, ...)
-{
-  char buffer[FULL_SXSIZE / FONT5_XSIZE + 10];
-  int font_width = getFontWidth(FS_SMALL, font_type);
-  va_list ap;
+    phase = (FrameCounter % (delay * max_anim_frames)) / delay;
+    phase = (phase < frames ? phase : max_anim_frames - phase);
+  }
+  else
+    phase = (FrameCounter % (delay * frames)) / delay;
 
-  va_start(ap, format);
-  vsprintf(buffer, format, ap);
-  va_end(ap);
+  if (mode & ANIM_REVERSE)
+    phase = -phase;
 
-  DrawText(SX + (SXSIZE - strlen(buffer) * font_width) / 2, SY + y,
-          buffer, FS_SMALL, font_type);
+  return phase;
 }
 
-void DrawTextF(int x, int y, int font_type, char *format, ...)
+inline int getGraphicAnimationFrame(int graphic, int sync_frame)
 {
-  char buffer[FULL_SXSIZE / FONT5_XSIZE + 10];
-  va_list ap;
-
-  va_start(ap, format);
-  vsprintf(buffer, format, ap);
-  va_end(ap);
+  /* animation synchronized with global frame counter, not move position */
+  if (new_graphic_info[graphic].anim_global_sync || sync_frame < 0)
+    sync_frame = FrameCounter;
 
-  DrawText(SX + x, SY + y, buffer, FS_SMALL, font_type);
+  return getAnimationFrame(new_graphic_info[graphic].anim_frames,
+                          new_graphic_info[graphic].anim_delay,
+                          new_graphic_info[graphic].anim_mode,
+                          new_graphic_info[graphic].anim_start_frame,
+                          sync_frame);
 }
 
-void DrawText(int x, int y, char *text, int font_size, int font_type)
+void MarkTileDirty(int x, int y)
 {
-  DrawTextExt(drawto, gc, x, y, text, font_size, font_type);
+  int xx = redraw_x1 + x;
+  int yy = redraw_y1 + y;
 
-  if (x < DX)
-    redraw_mask |= REDRAW_FIELD;
-  else if (y < VY)
-    redraw_mask |= REDRAW_DOOR_1;
+  if (!redraw[xx][yy])
+    redraw_tiles++;
+
+  redraw[xx][yy] = TRUE;
+  redraw_mask |= REDRAW_TILES;
 }
 
-void DrawTextExt(Drawable d, GC gc, int x, int y,
-                char *text, int font_size, int font_type)
+void SetBorderElement()
 {
-  int font_width, font_height, font_start;
-  int font_pixmap;
-  boolean print_inverse = FALSE;
-
-  if (font_size != FS_SMALL && font_size != FS_BIG && font_size != FS_MEDIUM)
-    font_size = FS_SMALL;
-  if (font_type < FC_RED || font_type > FC_SPECIAL3)
-    font_type = FC_RED;
-
-  font_width = getFontWidth(font_size, font_type);
-  font_height = getFontHeight(font_size, font_type);
-
-  font_pixmap = (font_size == FS_BIG ? PIX_BIGFONT :
-                font_size == FS_MEDIUM ? PIX_MEDIUMFONT :
-                PIX_SMALLFONT);
-  font_start = (font_type * (font_size == FS_BIG ? FONT1_YSIZE :
-                            font_size == FS_MEDIUM ? FONT6_YSIZE :
-                            FONT2_YSIZE) *
-               FONT_LINES_PER_FONT);
+  int x, y;
 
-  if (font_type == FC_SPECIAL3)
-    font_start += (FONT4_YSIZE - FONT2_YSIZE) * FONT_LINES_PER_FONT;
+  BorderElement = EL_EMPTY;
 
-  while (*text)
+  for(y=0; y<lev_fieldy && BorderElement == EL_EMPTY; y++)
   {
-    char c = *text++;
-
-    if (c == '~' && font_size == FS_SMALL)
+    for(x=0; x<lev_fieldx; x++)
     {
-      print_inverse = TRUE;
-      continue;
-    }
-
-    if (c >= 'a' && c <= 'z')
-      c = 'A' + (c - 'a');
-    else if (c == 'ä' || c == 'Ä')
-      c = 91;
-    else if (c == 'ö' || c == 'Ö')
-      c = 92;
-    else if (c == 'ü' || c == 'Ãœ')
-      c = 93;
-
-    if (c >= 32 && c <= 95)
-    {
-      int src_x = ((c - 32) % FONT_CHARS_PER_LINE) * font_width;
-      int src_y = ((c - 32) / FONT_CHARS_PER_LINE) * font_height + font_start;
-      int dest_x = x, dest_y = y;
+      if (!IS_MASSIVE(Feld[x][y]))
+       BorderElement = EL_STEELWALL;
 
-      if (print_inverse)
-      {
-       XCopyArea(display, pix[font_pixmap], d, gc,
-                 FONT_CHARS_PER_LINE * font_width,
-                 3 * font_height + font_start,
-                 font_width, font_height, x, y);
-
-       XSetClipOrigin(display, clip_gc[font_pixmap],
-                      dest_x - src_x, dest_y - src_y);
-       XCopyArea(display, pix[font_pixmap], d, clip_gc[font_pixmap],
-                 0, 0, font_width, font_height, dest_x, dest_y);
-      }
-      else
-      {
-#ifdef USE_SDL_LIBRARY
-       SDLCopyArea(sdl_pix[font_pixmap], sdl_window,
-                   src_x, src_y, font_width, font_height, dest_x, dest_y);
-#else
-       XCopyArea(display, pix[font_pixmap], d, gc,
-                 src_x, src_y, font_width, font_height, dest_x, dest_y);
-#endif
-      }
+      if (y != 0 && y != lev_fieldy - 1 && x != lev_fieldx - 1)
+       x = lev_fieldx - 2;
     }
-
-    x += font_width;
   }
 }
 
@@ -497,7 +472,8 @@ void DrawPlayer(struct PlayerInfo *player)
   int sx = SCREENX(jx), sy = SCREENY(jy);
   int sxx = 0, syy = 0;
   int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy];
-  int graphic, phase;
+  int graphic;
+  int frame = 0;
   boolean player_is_moving = (last_jx != jx || last_jy != jy ? TRUE : FALSE);
 
   if (!player->active || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy)))
@@ -513,7 +489,7 @@ void DrawPlayer(struct PlayerInfo *player)
   }
 #endif
 
-  if (element == EL_EXPLODING)
+  if (element == EL_EXPLOSION)
     return;
 
   /* draw things in the field the player is leaving, if needed */
@@ -523,7 +499,11 @@ void DrawPlayer(struct PlayerInfo *player)
     if (Store[last_jx][last_jy] && IS_DRAWABLE(last_element))
     {
       DrawLevelElement(last_jx, last_jy, Store[last_jx][last_jy]);
-      DrawLevelFieldThruMask(last_jx, last_jy);
+
+      if (last_element == EL_DYNAMITE_ACTIVE)
+       DrawDynamite(last_jx, last_jy);
+      else
+       DrawLevelFieldThruMask(last_jx, last_jy);
     }
     else if (last_element == EL_DYNAMITE_ACTIVE)
       DrawDynamite(last_jx, last_jy);
@@ -534,10 +514,10 @@ void DrawPlayer(struct PlayerInfo *player)
     {
       if (player->GfxPos)
       {
-       if (Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
-         DrawLevelElement(next_jx, next_jy, EL_SOKOBAN_FELD_LEER);
+       if (Feld[next_jx][next_jy] == EL_SOKOBAN_FIELD_FULL)
+         DrawLevelElement(next_jx, next_jy, EL_SOKOBAN_FIELD_EMPTY);
        else
-         DrawLevelElement(next_jx, next_jy, EL_LEERRAUM);
+         DrawLevelElement(next_jx, next_jy, EL_EMPTY);
       }
       else
        DrawLevelField(next_jx, next_jy);
@@ -556,6 +536,8 @@ void DrawPlayer(struct PlayerInfo *player)
     DrawLevelElement(jx, jy, Store[jx][jy]);
   else if (!IS_ACTIVE_BOMB(element))
     DrawLevelField(jx, jy);
+  else
+    DrawLevelElement(jx, jy, EL_EMPTY);
 
   /* draw player himself */
 
@@ -569,44 +551,44 @@ void DrawPlayer(struct PlayerInfo *player)
        ((action & (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)) &&
        !(action & ~(MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN))));
 
-    graphic = GFX_SP_MURPHY;
+    graphic = IMG_SP_MURPHY;
 
     if (player->Pushing)
     {
       if (player->MovDir == MV_LEFT)
-       graphic = GFX_MURPHY_PUSH_LEFT;
+       graphic = IMG_SP_MURPHY_LEFT_PUSHING;
       else if (player->MovDir == MV_RIGHT)
-       graphic = GFX_MURPHY_PUSH_RIGHT;
+       graphic = IMG_SP_MURPHY_RIGHT_PUSHING;
       else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
-       graphic = GFX_MURPHY_PUSH_LEFT;
+       graphic = IMG_SP_MURPHY_LEFT_PUSHING;
       else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
-       graphic = GFX_MURPHY_PUSH_RIGHT;
+       graphic = IMG_SP_MURPHY_RIGHT_PUSHING;
     }
     else if (player->snapped)
     {
       if (player->MovDir == MV_LEFT)
-       graphic = GFX_MURPHY_SNAP_LEFT;
+       graphic = IMG_SP_MURPHY_LEFT_SNAPPING;
       else if (player->MovDir == MV_RIGHT)
-       graphic = GFX_MURPHY_SNAP_RIGHT;
+       graphic = IMG_SP_MURPHY_RIGHT_SNAPPING;
       else if (player->MovDir == MV_UP)
-       graphic = GFX_MURPHY_SNAP_UP;
+       graphic = IMG_SP_MURPHY_UP_SNAPPING;
       else if (player->MovDir == MV_DOWN)
-       graphic = GFX_MURPHY_SNAP_DOWN;
+       graphic = IMG_SP_MURPHY_DOWN_SNAPPING;
     }
     else if (action_moving)
     {
       if (player->MovDir == MV_LEFT)
-       graphic = GFX_MURPHY_GO_LEFT;
+       graphic = IMG_SP_MURPHY_LEFT_MOVING;
       else if (player->MovDir == MV_RIGHT)
-       graphic = GFX_MURPHY_GO_RIGHT;
+       graphic = IMG_SP_MURPHY_RIGHT_MOVING;
       else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
-       graphic = GFX_MURPHY_GO_LEFT;
+       graphic = IMG_SP_MURPHY_LEFT_MOVING;
       else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
-       graphic = GFX_MURPHY_GO_RIGHT;
+       graphic = IMG_SP_MURPHY_RIGHT_MOVING;
       else
-       graphic = GFX_MURPHY_GO_LEFT;
+       graphic = IMG_SP_MURPHY_LEFT_MOVING;
 
-      graphic += getGraphicAnimationPhase(3, 2, ANIM_OSCILLATE);
+      frame = getGraphicAnimationFrame(graphic, -1);
     }
 
     if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
@@ -615,18 +597,29 @@ void DrawPlayer(struct PlayerInfo *player)
   else
   {
     if (player->MovDir == MV_LEFT)
-      graphic =
-       (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT);
+      graphic = (player->Pushing ? IMG_PLAYER1_LEFT_PUSHING :
+                player->is_moving ? IMG_PLAYER1_LEFT_MOVING :
+                IMG_PLAYER1_LEFT);
     else if (player->MovDir == MV_RIGHT)
-      graphic =
-       (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT);
+      graphic = (player->Pushing ? IMG_PLAYER1_RIGHT_PUSHING :
+                player->is_moving ? IMG_PLAYER1_RIGHT_MOVING :
+                IMG_PLAYER1_RIGHT);
     else if (player->MovDir == MV_UP)
-      graphic = GFX_SPIELER1_UP;
+      graphic = (player->Pushing ? IMG_PLAYER1_UP_PUSHING :
+                player->is_moving ? IMG_PLAYER1_UP_MOVING :
+                IMG_PLAYER1_UP);
     else       /* MV_DOWN || MV_NO_MOVING */
-      graphic = GFX_SPIELER1_DOWN;
+      graphic = (player->Pushing ? IMG_PLAYER1_DOWN_PUSHING :
+                player->is_moving ? IMG_PLAYER1_DOWN_MOVING :
+                IMG_PLAYER1_DOWN);
+
+    graphic = PLAYER_NR_GFX(graphic, player->index_nr);
 
-    graphic += player->index_nr * 3 * HEROES_PER_LINE;
-    graphic += player->Frame;
+#if 0
+    frame = player->Frame;
+#else
+    frame = getGraphicAnimationFrame(graphic, player->Frame);
+#endif
   }
 
   if (player->GfxPos)
@@ -640,43 +633,73 @@ void DrawPlayer(struct PlayerInfo *player)
   if (!setup.soft_scrolling && ScreenMovPos)
     sxx = syy = 0;
 
-  DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, NO_CUTTING);
+#if 0
+  if (player->Frame)
+    printf("-> %d\n", player->Frame);
+#endif
+
+  DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING);
 
   if (SHIELD_ON(player))
   {
-    int graphic = (player->shield_active_time_left ? GFX2_SHIELD_ACTIVE :
-                  GFX2_SHIELD_PASSIVE);
+    int graphic = (player->shield_deadly_time_left ? IMG_SHIELD_DEADLY_ACTIVE :
+                  IMG_SHIELD_NORMAL_ACTIVE);
+    int frame = getGraphicAnimationFrame(graphic, -1);
 
-    DrawGraphicAnimationShiftedThruMask(sx, sy, sxx, syy, graphic,
-                                       3, 8, ANIM_OSCILLATE);
+    DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING);
   }
 
+#if 0
   if (player->Pushing && player->GfxPos)
+#else
+  if (player->Pushing && player_is_moving)
+#endif
   {
     int px = SCREENX(next_jx), py = SCREENY(next_jy);
 
-    if (element == EL_SOKOBAN_FELD_LEER ||
-       Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
-      DrawGraphicShiftedThruMask(px, py, sxx, syy, GFX_SOKOBAN_OBJEKT,
+    if (element == EL_SOKOBAN_FIELD_EMPTY ||
+       Feld[next_jx][next_jy] == EL_SOKOBAN_FIELD_FULL)
+      DrawGraphicShiftedThruMask(px, py, sxx, syy, GFX_SOKOBAN_OBJEKT, 0,
                                 NO_CUTTING);
     else
     {
       int element = Feld[next_jx][next_jy];
-      int graphic = el2gfx(element);
+      int graphic = el2img(element);
+#if 1
+      int frame = 0;
+#endif
 
-      if ((element == EL_FELSBROCKEN ||
-          element == EL_SP_ZONK ||
-          element == EL_BD_ROCK) && sxx)
+      if ((element == EL_ROCK ||
+          element == EL_BD_ROCK ||
+          element == EL_SP_ZONK) && sxx)
       {
-       int phase = (player->GfxPos / (TILEX / 4));
+       graphic = el_dir_act2img(element, player->MovDir, GFX_ACTION_MOVING);
+#if 1
+       frame = getGraphicAnimationFrame(graphic, player->GfxPos);
+
+       frame = getGraphicAnimationFrame(graphic, player->Frame);
+#endif
 
+#if 0
+       printf("-> %d [%d]\n", player->Frame, player->GfxPos);
+#endif
+
+#if 0
+       /* !!! FIX !!! */
        if (player->MovDir == MV_LEFT)
-         graphic += phase;
-       else
-         graphic += (phase + 4) % 4;
+         frame = 3 - frame;
+#endif
+
+#if 0
+       frame = (player->GfxPos / (TILEX / 4));
+
+       if (player->MovDir == MV_RIGHT)
+         frame = (frame + 4) % 4;
+#endif
       }
 
-      DrawGraphicShifted(px, py, sxx, syy, graphic, NO_CUTTING, NO_MASKING);
+      DrawGraphicShifted(px, py, sxx, syy, graphic, frame,
+                        NO_CUTTING, NO_MASKING);
     }
   }
 
@@ -684,39 +707,48 @@ void DrawPlayer(struct PlayerInfo *player)
 
   if (IS_ACTIVE_BOMB(element))
   {
-    graphic = el2gfx(element);
+    graphic = el2img(element);
 
+#if 0
     if (element == EL_DYNAMITE_ACTIVE)
     {
-      if ((phase = (96 - MovDelay[jx][jy]) / 12) > 6)
-       phase = 6;
+      if ((frame = (96 - MovDelay[jx][jy]) / 12) > 6)
+       frame = 6;
     }
     else
     {
-      if ((phase = ((96 - MovDelay[jx][jy]) / 6) % 8) > 3)
-       phase = 7 - phase;
+      if ((frame = ((96 - MovDelay[jx][jy]) / 6) % 8) > 3)
+       frame = 7 - frame;
     }
+#else
+    frame = getGraphicAnimationFrame(graphic, 96 - MovDelay[jx][jy]);
+#endif
 
     if (game.emulation == EMU_SUPAPLEX)
-      DrawGraphic(sx, sy, GFX_SP_DISK_RED);
+      DrawGraphic(sx, sy, GFX_SP_DISK_RED, 0);
     else
-      DrawGraphicThruMask(sx, sy, graphic + phase);
+      DrawGraphicThruMask(sx, sy, graphic, frame);
   }
 
-  if (player_is_moving && last_element == EL_EXPLODING)
+  if (player_is_moving && last_element == EL_EXPLOSION)
   {
-    int phase = Frame[last_jx][last_jy];
-    int delay = 2;
+    int stored = Store[last_jx][last_jy];
+    int graphic = (game.emulation != EMU_SUPAPLEX ? IMG_EXPLOSION :
+                  stored == EL_SP_INFOTRON ? IMG_SP_EXPLOSION_INFOTRON :
+                  IMG_SP_EXPLOSION);
+    int delay = (game.emulation == EMU_SUPAPLEX ? 3 : 2);
+    int phase = Frame[last_jx][last_jy] - 1;
+    int frame = getGraphicAnimationFrame(graphic, phase - delay);
 
-    if (phase > 2)
-      DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy),
-                         GFX_EXPLOSION + ((phase - 1) / delay - 1));
+    if (phase >= delay)
+      DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy), graphic, frame);
   }
 
   /* draw elements that stay over the player */
   /* handle the field the player is leaving ... */
   if (player_is_moving && IS_OVER_PLAYER(last_element))
     DrawLevelField(last_jx, last_jy);
+
   /* ... and the field the player is entering */
   if (IS_OVER_PLAYER(element))
     DrawLevelField(jx, jy);
@@ -728,152 +760,162 @@ void DrawPlayer(struct PlayerInfo *player)
     int x_size = TILEX * (1 + ABS(jx - last_jx));
     int y_size = TILEY * (1 + ABS(jy - last_jy));
 
-    XCopyArea(display, drawto_field, window, gc,
-             dest_x, dest_y, x_size, y_size, dest_x, dest_y);
+    BlitBitmap(drawto_field, window,
+              dest_x, dest_y, x_size, y_size, dest_x, dest_y);
     SetDrawtoField(DRAW_DIRECT);
   }
 
   MarkTileDirty(sx,sy);
 }
 
-static int getGraphicAnimationPhase(int frames, int delay, int mode)
+void DrawGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y,
+                            int graphic, int mask_mode)
 {
-  int phase;
+  int frame = getGraphicAnimationFrame(graphic, -1);
 
-  if (mode == ANIM_OSCILLATE)
-  {
-    int max_anim_frames = 2 * frames - 2;
-    phase = (FrameCounter % (delay * max_anim_frames)) / delay;
-    phase = (phase < frames ? phase : max_anim_frames - phase);
-  }
+  if (mask_mode == USE_MASKING)
+    DrawGraphicThruMaskExt(dst_bitmap, x, y, graphic, frame);
   else
-    phase = (FrameCounter % (delay * frames)) / delay;
-
-  if (mode == ANIM_REVERSE)
-    phase = -phase;
-
-  return(phase);
+    DrawGraphicExt(dst_bitmap, x, y, graphic, frame);
 }
 
-void DrawGraphicAnimationExt(int x, int y, int graphic,
-                            int frames, int delay, int mode, int mask_mode)
+void DrawGraphicAnimation(int x, int y, int graphic)
 {
-  int phase = getGraphicAnimationPhase(frames, delay, mode);
-
-  if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
-  {
-    if (mask_mode == USE_MASKING)
-      DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic + phase);
-    else
-      DrawGraphic(SCREENX(x), SCREENY(y), graphic + phase);
-  }
-}
-
-void DrawGraphicAnimation(int x, int y, int graphic,
-                         int frames, int delay, int mode)
-{
-  DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, NO_MASKING);
-}
-
-void DrawGraphicAnimationThruMask(int x, int y, int graphic,
-                                 int frames, int delay, int mode)
-{
-  DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
-}
-
-static void DrawGraphicAnimationShiftedThruMask(int sx, int sy,
-                                               int sxx, int syy,
-                                               int graphic,
-                                               int frames, int delay,
-                                               int mode)
-{
-  int phase = getGraphicAnimationPhase(frames, delay, mode);
+  if (!IN_SCR_FIELD(x, y) ||
+      (FrameCounter % new_graphic_info[graphic].anim_delay) != 0)
+    return;
 
-  DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic + phase, NO_CUTTING);
+  DrawGraphicAnimationExt(drawto_field, FX + x * TILEX, FY + y * TILEY,
+                         graphic, NO_MASKING);
+  MarkTileDirty(x, y);
 }
 
-void getGraphicSource(int graphic, int *pixmap_nr, int *x, int *y)
+#if 0
+void getOldGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
 {
-  if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
+  if (graphic >= 0 && graphic_info[graphic].bitmap != NULL)
   {
-    graphic -= GFX_START_ROCKSSCREEN;
-    *pixmap_nr = PIX_BACK;
-    *x = SX + (graphic % GFX_PER_LINE) * TILEX;
-    *y = SY + (graphic / GFX_PER_LINE) * TILEY;
+    *bitmap = graphic_info[graphic].bitmap;
+    *x = graphic_info[graphic].src_x;
+    *y = graphic_info[graphic].src_y;
+  }
+  else if (graphic >= GFX_START_ROCKSELEMENTS &&
+          graphic <= GFX_END_ROCKSELEMENTS)
+  {
+    graphic -= GFX_START_ROCKSELEMENTS;
+    *bitmap = new_graphic_info[IMG_OLD_PIX_ELEMENTS].bitmap;
+    *x = (graphic % GFX_PER_LINE) * TILEX;
+    *y = (graphic / GFX_PER_LINE) * TILEY;
   }
   else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
   {
     graphic -= GFX_START_ROCKSHEROES;
-    *pixmap_nr = PIX_HEROES;
+    *bitmap = new_graphic_info[IMG_OLD_PIX_HEROES].bitmap;
     *x = (graphic % HEROES_PER_LINE) * TILEX;
     *y = (graphic / HEROES_PER_LINE) * TILEY;
   }
   else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
   {
     graphic -= GFX_START_ROCKSSP;
-    *pixmap_nr = PIX_SP;
+    *bitmap = new_graphic_info[IMG_OLD_PIX_SP].bitmap;
     *x = (graphic % SP_PER_LINE) * TILEX;
     *y = (graphic / SP_PER_LINE) * TILEY;
   }
   else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
   {
     graphic -= GFX_START_ROCKSDC;
-    *pixmap_nr = PIX_DC;
+    *bitmap = new_graphic_info[IMG_OLD_PIX_DC].bitmap;
     *x = (graphic % DC_PER_LINE) * TILEX;
     *y = (graphic / DC_PER_LINE) * TILEY;
   }
   else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
   {
     graphic -= GFX_START_ROCKSMORE;
-    *pixmap_nr = PIX_MORE;
+    *bitmap = new_graphic_info[IMG_OLD_PIX_MORE].bitmap;
     *x = (graphic % MORE_PER_LINE) * TILEX;
     *y = (graphic / MORE_PER_LINE) * TILEY;
   }
   else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
   {
     graphic -= GFX_START_ROCKSFONT;
-    *pixmap_nr = PIX_BIGFONT;
+    *bitmap = new_graphic_info[IMG_OLD_PIX_FONT_EM].bitmap;
     *x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
-    *y = ((graphic / FONT_CHARS_PER_LINE) * TILEY +
-         FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY);
+    *y = (graphic / FONT_CHARS_PER_LINE) * TILEY;
   }
   else
   {
-    *pixmap_nr = PIX_SP;
+    *bitmap = new_graphic_info[IMG_OLD_PIX_SP].bitmap;
     *x = 0;
     *y = 0;
   }
 }
+#endif
+
+void getGraphicSource(int graphic, int frame, Bitmap **bitmap, int *x, int *y)
+{
+  Bitmap *src_bitmap = new_graphic_info[graphic].bitmap;
+  int offset_x = new_graphic_info[graphic].offset_x;
+  int offset_y = new_graphic_info[graphic].offset_y;
+  int src_x = new_graphic_info[graphic].src_x + frame * offset_x;
+  int src_y = new_graphic_info[graphic].src_y + frame * offset_y;
+
+  *bitmap = src_bitmap;
+  *x = src_x;
+  *y = src_y;
+}
 
-void DrawGraphic(int x, int y, int graphic)
+void DrawGraphic(int x, int y, int graphic, int frame)
 {
 #if DEBUG
-  if (!IN_SCR_FIELD(x,y))
+  if (!IN_SCR_FIELD(x, y))
   {
-    printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
+    printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n", x, y, graphic);
     printf("DrawGraphic(): This should never happen!\n");
     return;
   }
 #endif
 
-  DrawGraphicExt(drawto_field, gc, FX + x*TILEX, FY + y*TILEY, graphic);
-  MarkTileDirty(x,y);
+  DrawGraphicExt(drawto_field, FX + x * TILEX, FY + y * TILEY, graphic, frame);
+  MarkTileDirty(x, y);
 }
 
-void DrawGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
+#if 0
+void DrawOldGraphicExt(DrawBuffer *dst_bitmap, int x, int y, int graphic)
+{
+  Bitmap *src_bitmap;
+  int src_x, src_y;
+
+  getOldGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
+  BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y, TILEX, TILEY, x, y);
+}
+#endif
+
+void DrawGraphicExt(DrawBuffer *dst_bitmap, int x, int y, int graphic,
+                   int frame)
 {
-  int pixmap_nr;
+#if 1
+  Bitmap *src_bitmap;
   int src_x, src_y;
 
-  getGraphicSource(graphic, &pixmap_nr, &src_x, &src_y);
-  XCopyArea(display, pix[pixmap_nr], d, gc,
-           src_x, src_y, TILEX, TILEY, x, y);
+  getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
+#else
+  Bitmap *src_bitmap = new_graphic_info[graphic].bitmap;
+  int src_x = new_graphic_info[graphic].src_x;
+  int src_y = new_graphic_info[graphic].src_y;
+  int offset_x = new_graphic_info[graphic].offset_x;
+  int offset_y = new_graphic_info[graphic].offset_y;
+
+  src_x += frame * offset_x;
+  src_y += frame * offset_y;
+#endif
+
+  BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y, TILEX, TILEY, x, y);
 }
 
-void DrawGraphicThruMask(int x, int y, int graphic)
+void DrawGraphicThruMask(int x, int y, int graphic, int frame)
 {
 #if DEBUG
-  if (!IN_SCR_FIELD(x,y))
+  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");
@@ -881,153 +923,126 @@ void DrawGraphicThruMask(int x, int y, int graphic)
   }
 #endif
 
-  DrawGraphicThruMaskExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
-  MarkTileDirty(x,y);
+  DrawGraphicThruMaskExt(drawto_field, FX + x * TILEX, FY + y *TILEY, graphic,
+                        frame);
+  MarkTileDirty(x, y);
 }
 
-void DrawGraphicThruMaskExt(Drawable d, int dest_x, int dest_y, int graphic)
+void DrawGraphicThruMaskExt(DrawBuffer *d, int dest_x, int dest_y, int graphic,
+                           int frame)
 {
-  int tile = graphic;
-  int pixmap_nr;
+#if 1
+  Bitmap *src_bitmap;
   int src_x, src_y;
-  Pixmap src_pixmap;
   GC drawing_gc;
 
-  if (graphic == GFX_LEERRAUM)
-    return;
+  getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
+  drawing_gc = src_bitmap->stored_clip_gc;
+#else
+  GC drawing_gc = src_bitmap->stored_clip_gc;
+  Bitmap *src_bitmap = new_graphic_info[graphic].bitmap;
+  int src_x = new_graphic_info[graphic].src_x;
+  int src_y = new_graphic_info[graphic].src_y;
+  int offset_x = new_graphic_info[graphic].offset_x;
+  int offset_y = new_graphic_info[graphic].offset_y;
 
-  getGraphicSource(graphic, &pixmap_nr, &src_x, &src_y);
-  src_pixmap = pix[pixmap_nr];
-  drawing_gc = clip_gc[pixmap_nr];
+  src_x += frame * offset_x;
+  src_y += frame * offset_y;
 
-  if (tile_clipmask[tile] != None)
-  {
-    XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
-    XSetClipOrigin(display, tile_clip_gc, dest_x, dest_y);
-    XCopyArea(display, src_pixmap, d, tile_clip_gc,
-             src_x, src_y, TILEX, TILEY, dest_x, dest_y);
-  }
-  else
-  {
-#if DEBUG
-    printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
 #endif
 
-    XSetClipOrigin(display, drawing_gc, dest_x-src_x, dest_y-src_y);
-    XCopyArea(display, src_pixmap, d, drawing_gc,
-             src_x, src_y, TILEX, TILEY, dest_x, dest_y);
-  }
+  SetClipOrigin(src_bitmap, drawing_gc, dest_x - src_x, dest_y - src_y);
+  BlitBitmapMasked(src_bitmap, d, src_x, src_y, TILEX, TILEY, dest_x, dest_y);
 }
 
 void DrawMiniGraphic(int x, int y, int graphic)
 {
-  DrawMiniGraphicExt(drawto,gc, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
-  MarkTileDirty(x/2, y/2);
+  DrawMiniGraphicExt(drawto, SX + x * MINI_TILEX,SY + y * MINI_TILEY, graphic);
+  MarkTileDirty(x / 2, y / 2);
 }
 
-void getMiniGraphicSource(int graphic, Pixmap *pixmap, int *x, int *y)
+void getMiniGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
 {
-  if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
-  {
-    graphic -= GFX_START_ROCKSSCREEN;
-    *pixmap = pix[PIX_BACK];
-    *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
-    *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
-  }
-  else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
-  {
-    graphic -= GFX_START_ROCKSSP;
-    graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
-    *pixmap = pix[PIX_SP];
-    *x = MINI_SP_STARTX + (graphic % MINI_SP_PER_LINE) * MINI_TILEX;
-    *y = MINI_SP_STARTY + (graphic / MINI_SP_PER_LINE) * MINI_TILEY;
-  }
-  else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
-  {
-    graphic -= GFX_START_ROCKSDC;
-    *pixmap = pix[PIX_DC];
-    *x = MINI_DC_STARTX + (graphic % MINI_DC_PER_LINE) * MINI_TILEX;
-    *y = MINI_DC_STARTY + (graphic / MINI_DC_PER_LINE) * MINI_TILEY;
-  }
-  else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
-  {
-    graphic -= GFX_START_ROCKSMORE;
-    *pixmap = pix[PIX_MORE];
-    *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
-    *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
-  }
-  else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
-  {
-    graphic -= GFX_START_ROCKSFONT;
-    *pixmap = pix[PIX_SMALLFONT];
-    *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
-    *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
-             FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
-  }
-  else
+  Bitmap *src_bitmap = new_graphic_info[graphic].bitmap;
+  int mini_startx = 0;
+  int mini_starty = src_bitmap->height * 2 / 3;
+  int src_x = mini_startx + new_graphic_info[graphic].src_x / 2;
+  int src_y = mini_starty + new_graphic_info[graphic].src_y / 2;
+
+  if (src_x + MINI_TILEX > src_bitmap->width ||
+      src_y + MINI_TILEY > src_bitmap->height)
   {
-    *pixmap = pix[PIX_SP];
-    *x = MINI_SP_STARTX;
-    *y = MINI_SP_STARTY;
+    /* graphic of desired size seems not to be contained in this image;
+       dirty workaround: get it from the middle of the normal sized image */
+
+    getGraphicSource(graphic, 0, &src_bitmap, &src_x, &src_y);
+    src_x += (TILEX / 2 - MINI_TILEX / 2);
+    src_y += (TILEY / 2 - MINI_TILEY / 2);
   }
+
+  *bitmap = src_bitmap;
+  *x = src_x;
+  *y = src_y;
 }
 
-void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
+void DrawMiniGraphicExt(DrawBuffer *d, int x, int y, int graphic)
 {
-  Pixmap pixmap;
+  Bitmap *src_bitmap;
   int src_x, src_y;
 
-  getMiniGraphicSource(graphic, &pixmap, &src_x, &src_y);
-  XCopyArea(display, pixmap, d, gc,
-           src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
+  getMiniGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
+  BlitBitmap(src_bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
 }
 
-void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
+void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic, int frame,
                        int cut_mode, int mask_mode)
 {
+  Bitmap *src_bitmap;
+  GC drawing_gc;
+  int src_x;
+  int src_y;
+  int offset_x;
+  int offset_y;
+
   int width = TILEX, height = TILEY;
   int cx = 0, cy = 0;
-  int src_x, src_y, dest_x, dest_y;
-  int tile = graphic;
-  int pixmap_nr;
-  Pixmap src_pixmap;
-  GC drawing_gc;
+  int dest_x, dest_y;
 
   if (graphic < 0)
   {
-    DrawGraphic(x, y, graphic);
+    DrawGraphic(x, y, graphic, frame);
     return;
   }
 
-  if (dx || dy)                        /* Verschiebung der Grafik? */
+  if (dx || dy)                        /* shifted graphic */
   {
-    if (x < BX1)               /* Element kommt von links ins Bild */
+    if (x < BX1)               /* object enters playfield from the left */
     {
       x = BX1;
       width = dx;
       cx = TILEX - dx;
       dx = 0;
     }
-    else if (x > BX2)          /* Element kommt von rechts ins Bild */
+    else if (x > BX2)          /* object enters playfield from the right */
     {
       x = BX2;
       width = -dx;
       dx = TILEX + dx;
     }
-    else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
+    else if (x==BX1 && dx < 0) /* object leaves playfield to the left */
     {
       width += dx;
       cx = -dx;
       dx = 0;
     }
-    else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
+    else if (x==BX2 && dx > 0) /* object leaves playfield to the right */
       width -= dx;
-    else if (dx)               /* allg. Bewegung in x-Richtung */
+    else if (dx)               /* general horizontal movement */
       MarkTileDirty(x + SIGN(dx), y);
 
-    if (y < BY1)               /* Element kommt von oben ins Bild */
+    if (y < BY1)               /* object enters playfield from the top */
     {
-      if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
+      if (cut_mode==CUT_BELOW) /* object completely above top border */
        return;
 
       y = BY1;
@@ -1035,13 +1050,13 @@ void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
       cy = TILEY - dy;
       dy = 0;
     }
-    else if (y > BY2)          /* Element kommt von unten ins Bild */
+    else if (y > BY2)          /* object enters playfield from the bottom */
     {
       y = BY2;
       height = -dy;
       dy = TILEY + dy;
     }
-    else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
+    else if (y==BY1 && dy < 0) /* object leaves playfield to the top */
     {
       height += dy;
       cy = -dy;
@@ -1049,23 +1064,30 @@ void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
     }
     else if (dy > 0 && cut_mode == CUT_ABOVE)
     {
-      if (y == BY2)            /* Element unterhalb des Bildes */
+      if (y == BY2)            /* object completely above bottom border */
        return;
 
       height = dy;
       cy = TILEY - dy;
       dy = TILEY;
       MarkTileDirty(x, y + 1);
-    }                          /* Element verläßt unten das Bild */
+    }                          /* object leaves playfield to the bottom */
     else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
       height -= dy;
-    else if (dy)               /* allg. Bewegung in y-Richtung */
+    else if (dy)               /* general vertical movement */
       MarkTileDirty(x, y + SIGN(dy));
   }
 
-  getGraphicSource(graphic, &pixmap_nr, &src_x, &src_y);
-  src_pixmap = pix[pixmap_nr];
-  drawing_gc = clip_gc[pixmap_nr];
+  src_bitmap = new_graphic_info[graphic].bitmap;
+  src_x = new_graphic_info[graphic].src_x;
+  src_y = new_graphic_info[graphic].src_y;
+  offset_x = new_graphic_info[graphic].offset_x;
+  offset_y = new_graphic_info[graphic].offset_y;
+
+  drawing_gc = src_bitmap->stored_clip_gc;
+
+  src_x += frame * offset_x;
+  src_y += frame * offset_y;
 
   src_x += cx;
   src_y += cy;
@@ -1084,37 +1106,24 @@ void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
 
   if (mask_mode == USE_MASKING)
   {
-    if (tile_clipmask[tile] != None)
-    {
-      XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
-      XSetClipOrigin(display, tile_clip_gc, dest_x, dest_y);
-      XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc,
-               src_x, src_y, TILEX, TILEY, dest_x, dest_y);
-    }
-    else
-    {
-#if DEBUG
-      printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
-#endif
-
-      XSetClipOrigin(display, drawing_gc, dest_x - src_x, dest_y - src_y);
-      XCopyArea(display, src_pixmap, drawto_field, drawing_gc,
-               src_x, src_y, width, height, dest_x, dest_y);
-    }
+    SetClipOrigin(src_bitmap, drawing_gc, dest_x - src_x, dest_y - src_y);
+    BlitBitmapMasked(src_bitmap, drawto_field, src_x, src_y, width, height,
+                    dest_x, dest_y);
   }
   else
-    XCopyArea(display, src_pixmap, drawto_field, gc,
-             src_x, src_y, width, height, dest_x, dest_y);
+    BlitBitmap(src_bitmap, drawto_field, src_x, src_y, width, height,
+              dest_x, dest_y);
 
   MarkTileDirty(x,y);
 }
 
 void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
-                               int cut_mode)
+                               int frame, int cut_mode)
 {
-  DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
+  DrawGraphicShifted(x,y, dx,dy, graphic, frame, cut_mode, USE_MASKING);
 }
 
+#if 0
 void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
                          int cut_mode, int mask_mode)
 {
@@ -1125,16 +1134,16 @@ void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
   int phase2  = phase8 / 4;
   int dir = MovDir[ux][uy];
 
-  if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
+  if (element == EL_PACMAN || element == EL_BUG || element == EL_SPACESHIP)
   {
-    graphic += 4 * !phase2;
+    graphic += 1 * !phase2;
 
     if (dir == MV_UP)
-      graphic += 1;
+      graphic += 1 * 2;
     else if (dir == MV_LEFT)
-      graphic += 2;
+      graphic += 2 * 2;
     else if (dir == MV_DOWN)
-      graphic += 3;
+      graphic += 3 * 2;
   }
   else if (element == EL_SP_SNIKSNAK)
   {
@@ -1151,39 +1160,39 @@ void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
   }
   else if (element == EL_SP_ELECTRON)
   {
-    graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
+    graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_LOOP);
   }
-  else if (element == EL_MOLE || element == EL_PINGUIN ||
-          element == EL_SCHWEIN || element == EL_DRACHE)
+  else if (element == EL_MOLE || element == EL_PENGUIN ||
+          element == EL_PIG || element == EL_DRAGON)
   {
     if (dir == MV_LEFT)
       graphic = (element == EL_MOLE ? GFX_MOLE_LEFT :
-                element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
-                element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
+                element == EL_PENGUIN ? GFX_PINGUIN_LEFT :
+                element == EL_PIG ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
     else if (dir == MV_RIGHT)
       graphic = (element == EL_MOLE ? GFX_MOLE_RIGHT :
-                element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
-                element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
+                element == EL_PENGUIN ? GFX_PINGUIN_RIGHT :
+                element == EL_PIG ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
     else if (dir == MV_UP)
       graphic = (element == EL_MOLE ? GFX_MOLE_UP :
-                element == EL_PINGUIN ? GFX_PINGUIN_UP :
-                element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
+                element == EL_PENGUIN ? GFX_PINGUIN_UP :
+                element == EL_PIG ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
     else
       graphic = (element == EL_MOLE ? GFX_MOLE_DOWN :
-                element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
-                element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
+                element == EL_PENGUIN ? GFX_PINGUIN_DOWN :
+                element == EL_PIG ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
 
     graphic += phase4;
   }
-  else if (element == EL_SONDE)
+  else if (element == EL_SATELLITE)
   {
-    graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
+    graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_LOOP);
   }
-  else if (element == EL_SALZSAEURE)
+  else if (element == EL_ACID)
   {
-    graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
+    graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_LOOP);
   }
-  else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
+  else if (element == EL_BD_BUTTERFLY || element == EL_BD_FIREFLY)
   {
     graphic += !phase2;
   }
@@ -1191,14 +1200,16 @@ void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
   {
     graphic += phase4;
   }
-  else if ((element == EL_FELSBROCKEN ||
+  else if ((element == EL_ROCK ||
            element == EL_SP_ZONK ||
            element == EL_BD_ROCK ||
-           IS_GEM(element)) && !cut_mode)
+           element == EL_SP_INFOTRON ||
+           IS_GEM(element))
+          && !cut_mode)
   {
     if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
     {
-      if (element == EL_FELSBROCKEN ||
+      if (element == EL_ROCK ||
          element == EL_SP_ZONK ||
          element == EL_BD_ROCK)
       {
@@ -1213,19 +1224,21 @@ void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
        graphic += phase2;
     }
   }
-  else if (element == EL_MAGIC_WALL_EMPTY ||
-          element == EL_MAGIC_WALL_BD_EMPTY ||
+  else if (element == EL_MAGIC_WALL_ACTIVE ||
+          element == EL_MAGIC_WALL_EMPTYING ||
+          element == EL_BD_MAGIC_WALL_ACTIVE ||
+          element == EL_BD_MAGIC_WALL_EMPTYING ||
           element == EL_MAGIC_WALL_FULL ||
-          element == EL_MAGIC_WALL_BD_FULL)
+          element == EL_BD_MAGIC_WALL_FULL)
   {
     graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
   }
-  else if (IS_AMOEBOID(element))
+  else if (IS_AMOEBOID(element) || element == EL_AMOEBA_DRIPPING)
   {
-    graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
+    graphic = (element == EL_AMOEBA_DEAD ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
     graphic += (x + 2 * y + 4) % 4;
   }
-  else if (element == EL_MAUER_LEBT)
+  else if (element == EL_WALL_GROWING)
   {
     boolean links_massiv = FALSE, rechts_massiv = FALSE;
 
@@ -1241,14 +1254,16 @@ void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
     else if (rechts_massiv)
       graphic = GFX_MAUER_L;
   }
-  else if ((element == EL_INVISIBLE_STEEL ||
-           element == EL_UNSICHTBAR ||
-           element == EL_SAND_INVISIBLE) && game.light_time_left)
+#if 0
+  else if ((element == EL_INVISIBLE_STEELWALL ||
+           element == EL_INVISIBLE_WALL ||
+           element == EL_INVISIBLE_SAND) && game.light_time_left)
   {
-    graphic = (element == EL_INVISIBLE_STEEL ? GFX_INVISIBLE_STEEL_ON :
-              element == EL_UNSICHTBAR ? GFX_UNSICHTBAR_ON :
+    graphic = (element == EL_INVISIBLE_STEELWALL ? GFX_INVISIBLE_STEEL_ON :
+              element == EL_INVISIBLE_WALL ? GFX_UNSICHTBAR_ON :
               GFX_SAND_INVISIBLE_ON);
   }
+#endif
 
   if (dx || dy)
     DrawGraphicShifted(x, y, dx, dy, graphic, cut_mode, mask_mode);
@@ -1257,6 +1272,111 @@ void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
   else
     DrawGraphic(x, y, graphic);
 }
+#endif
+
+inline static int getFramePosition(int x, int y)
+{
+  int frame_pos = -1;          /* default: global synchronization */
+#if 0
+  int element = Feld[x][y];
+
+  if (element == EL_QUICKSAND_FULL ||
+      element == EL_MAGIC_WALL_FULL ||
+      element == EL_BD_MAGIC_WALL_FULL)
+    frame_pos = -1;
+  else if (IS_MOVING(x, y) || CAN_MOVE(element) || CAN_FALL(element))
+    frame_pos = ABS(MovPos[x][y]) / (TILEX / 8);
+#else
+  frame_pos = ABS(MovPos[x][y]) / (TILEX / 8);
+#endif
+
+  return frame_pos;
+}
+
+inline static int getGfxAction(int x, int y)
+{
+  int gfx_action = GFX_ACTION_DEFAULT;
+
+#if 0
+  if (GfxAction[x][y] != GFX_ACTION_DEFAULT)
+    gfx_action = GfxAction[x][y];
+  else if (IS_MOVING(x, y))
+    gfx_action = GFX_ACTION_MOVING;
+#else
+  gfx_action = GfxAction[x][y];
+#endif
+
+#if DEBUG
+  if (gfx_action < 0)
+    printf("getGfxAction: THIS SHOULD NEVER HAPPEN: GfxAction[%d][%d] == %d\n",
+          x, y, gfx_action);
+#endif
+
+  return gfx_action;
+}
+
+void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
+                         int cut_mode, int mask_mode)
+{
+  int ux = LEVELX(x), uy = LEVELY(y);
+  int graphic;
+  int frame;
+
+  if (IN_LEV_FIELD(ux, uy))
+  {
+    int move_dir = MovDir[ux][uy];
+    int move_pos = getFramePosition(ux, uy);
+    int gfx_action = getGfxAction(ux, uy);
+
+    graphic = el_dir_act2img(element, move_dir, gfx_action);
+    frame = getGraphicAnimationFrame(graphic, move_pos);
+  }
+  else
+  {
+    graphic = el2img(element);
+    frame = getGraphicAnimationFrame(graphic, 0);
+  }
+
+  if (element == EL_WALL_GROWING)
+  {
+    boolean left_stopped = FALSE, right_stopped = FALSE;
+
+    if (!IN_LEV_FIELD(ux - 1, uy) || IS_MAUER(Feld[ux - 1][uy]))
+      left_stopped = TRUE;
+    if (!IN_LEV_FIELD(ux + 1, uy) || IS_MAUER(Feld[ux + 1][uy]))
+      right_stopped = TRUE;
+
+    if (left_stopped && right_stopped)
+      graphic = IMG_WALL;
+    else if (left_stopped)
+    {
+      graphic = IMG_WALL_GROWING_ACTIVE_RIGHT;
+      frame = new_graphic_info[graphic].anim_frames - 1;
+    }
+    else if (right_stopped)
+    {
+      graphic = IMG_WALL_GROWING_ACTIVE_LEFT;
+      frame = new_graphic_info[graphic].anim_frames - 1;
+    }
+  }
+  else if (IS_AMOEBOID(element) || element == EL_AMOEBA_DRIPPING)
+  {
+    graphic = (element == EL_BD_AMOEBA ? IMG_BD_AMOEBA_PART1 :
+              element == EL_AMOEBA_WET ? IMG_AMOEBA_WET_PART1 :
+              element == EL_AMOEBA_DRY ? IMG_AMOEBA_DRY_PART1 :
+              element == EL_AMOEBA_FULL ? IMG_AMOEBA_FULL_PART1 :
+              IMG_AMOEBA_DEAD_PART1);
+
+    graphic += (x + 2 * y + 4) % 4;
+  }
+
+  if (dx || dy)
+    DrawGraphicShifted(x, y, dx, dy, graphic, frame, cut_mode, mask_mode);
+  else if (mask_mode == USE_MASKING)
+    DrawGraphicThruMask(x, y, graphic, frame);
+  else
+    DrawGraphic(x, y, graphic, frame);
+}
 
 void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
                         int cut_mode, int mask_mode)
@@ -1278,10 +1398,17 @@ void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
   DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
 }
 
+#if 0
+void DrawOldScreenElementThruMask(int x, int y, int element)
+{
+  DrawOldScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
+}
+
 void DrawScreenElementThruMask(int x, int y, int element)
 {
   DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
 }
+#endif
 
 void DrawLevelElementThruMask(int x, int y, int element)
 {
@@ -1293,8 +1420,10 @@ void DrawLevelFieldThruMask(int x, int y)
   DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
 }
 
-void ErdreichAnbroeckeln(int x, int y)
+void DrawCrumbledSand(int x, int y)
 {
+  Bitmap *src_bitmap;
+  int src_x, src_y;
   int i, width, height, cx,cy;
   int ux = LEVELX(x), uy = LEVELY(y);
   int element, graphic;
@@ -1312,15 +1441,19 @@ void ErdreichAnbroeckeln(int x, int y)
 
   element = Feld[ux][uy];
 
-  if (element == EL_ERDREICH ||
+  if (element == EL_SAND ||
       element == EL_LANDMINE ||
-      element == EL_TRAP_INACTIVE ||
+      element == EL_TRAP ||
       element == EL_TRAP_ACTIVE)
   {
     if (!IN_SCR_FIELD(x, y))
       return;
 
-    graphic = GFX_ERDENRAND;
+    graphic = IMG_SAND_CRUMBLED;
+
+    src_bitmap = new_graphic_info[graphic].bitmap;
+    src_x = new_graphic_info[graphic].src_x;
+    src_y = new_graphic_info[graphic].src_y;
 
     for(i=0; i<4; i++)
     {
@@ -1329,13 +1462,13 @@ void ErdreichAnbroeckeln(int x, int y)
       uxx = ux + xy[i][0];
       uyy = uy + xy[i][1];
       if (!IN_LEV_FIELD(uxx, uyy))
-       element = EL_BETON;
+       element = EL_STEELWALL;
       else
        element = Feld[uxx][uyy];
 
-      if (element == EL_ERDREICH ||
+      if (element == EL_SAND ||
          element == EL_LANDMINE ||
-         element == EL_TRAP_INACTIVE ||
+         element == EL_TRAP ||
          element == EL_TRAP_ACTIVE)
        continue;
 
@@ -1354,17 +1487,19 @@ void ErdreichAnbroeckeln(int x, int y)
        cy = (i == 3 ? TILEY - snip : 0);
       }
 
-      XCopyArea(display, pix[PIX_BACK], drawto_field, gc,
-               SX + (graphic % GFX_PER_LINE) * TILEX + cx,
-               SY + (graphic / GFX_PER_LINE) * TILEY + cy,
-               width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
+      BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy,
+                width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
     }
 
     MarkTileDirty(x, y);
   }
   else
   {
-    graphic = GFX_ERDENRAND;
+    graphic = IMG_SAND_CRUMBLED;
+
+    src_bitmap = new_graphic_info[graphic].bitmap;
+    src_x = new_graphic_info[graphic].src_x;
+    src_y = new_graphic_info[graphic].src_y;
 
     for(i=0; i<4; i++)
     {
@@ -1376,9 +1511,9 @@ void ErdreichAnbroeckeln(int x, int y)
       uyy = uy + xy[i][1];
 
       if (!IN_LEV_FIELD(uxx, uyy) ||
-         (Feld[uxx][uyy] != EL_ERDREICH &&
+         (Feld[uxx][uyy] != EL_SAND &&
           Feld[uxx][uyy] != EL_LANDMINE &&
-          Feld[uxx][uyy] != EL_TRAP_INACTIVE &&
+          Feld[uxx][uyy] != EL_TRAP &&
           Feld[uxx][uyy] != EL_TRAP_ACTIVE) ||
          !IN_SCR_FIELD(xx, yy))
        continue;
@@ -1398,10 +1533,8 @@ void ErdreichAnbroeckeln(int x, int y)
        cy = (i==0 ? TILEY-snip : 0);
       }
 
-      XCopyArea(display, pix[PIX_BACK], drawto_field, gc,
-               SX + (graphic % GFX_PER_LINE) * TILEX + cx,
-               SY + (graphic / GFX_PER_LINE) * TILEY + cy,
-               width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
+      BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy,
+                width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
 
       MarkTileDirty(xx, yy);
     }
@@ -1411,7 +1544,7 @@ void ErdreichAnbroeckeln(int x, int y)
 void DrawScreenElement(int x, int y, int element)
 {
   DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
-  ErdreichAnbroeckeln(x, y);
+  DrawCrumbledSand(x, y);
 }
 
 void DrawLevelElement(int x, int y, int element)
@@ -1423,12 +1556,12 @@ void DrawLevelElement(int x, int y, int element)
 void DrawScreenField(int x, int y)
 {
   int ux = LEVELX(x), uy = LEVELY(y);
-  int element;
+  int element, content;
 
   if (!IN_LEV_FIELD(ux, uy))
   {
     if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
-      element = EL_LEERRAUM;
+      element = EL_EMPTY;
     else
       element = BorderElement;
 
@@ -1437,34 +1570,37 @@ void DrawScreenField(int x, int y)
   }
 
   element = Feld[ux][uy];
+  content = Store[ux][uy];
 
   if (IS_MOVING(ux, uy))
   {
     int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
     boolean cut_mode = NO_CUTTING;
 
-    if (Store[ux][uy] == EL_MORAST_LEER ||
-       Store[ux][uy] == EL_MAGIC_WALL_EMPTY ||
-       Store[ux][uy] == EL_MAGIC_WALL_BD_EMPTY ||
-       Store[ux][uy] == EL_AMOEBE_NASS)
+    if (element == EL_QUICKSAND_EMPTYING ||
+       element == EL_MAGIC_WALL_EMPTYING ||
+       element == EL_BD_MAGIC_WALL_EMPTYING ||
+       element == EL_AMOEBA_DRIPPING)
       cut_mode = CUT_ABOVE;
-    else if (Store[ux][uy] == EL_MORAST_VOLL ||
-            Store[ux][uy] == EL_MAGIC_WALL_FULL ||
-            Store[ux][uy] == EL_MAGIC_WALL_BD_FULL)
+    else if (element == EL_QUICKSAND_FILLING ||
+            element == EL_MAGIC_WALL_FILLING ||
+            element == EL_BD_MAGIC_WALL_FILLING)
       cut_mode = CUT_BELOW;
 
     if (cut_mode == CUT_ABOVE)
-      DrawScreenElementShifted(x, y, 0, 0, Store[ux][uy], NO_CUTTING);
+      DrawScreenElementShifted(x, y, 0, 0, element, NO_CUTTING);
     else
-      DrawScreenElement(x, y, EL_LEERRAUM);
+      DrawScreenElement(x, y, EL_EMPTY);
 
     if (horiz_move)
       DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
-    else
+    else if (cut_mode == NO_CUTTING)
       DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
+    else
+      DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], content, cut_mode);
 
-    if (Store[ux][uy] == EL_SALZSAEURE)
-      DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
+    if (content == EL_ACID)
+      DrawLevelElementThruMask(ux, uy + 1, EL_ACID);
   }
   else if (IS_BLOCKED(ux, uy))
   {
@@ -1472,6 +1608,7 @@ void DrawScreenField(int x, int y)
     int sx, sy;
     int horiz_move;
     boolean cut_mode = NO_CUTTING;
+    int element_old, content_old;
 
     Blocked2Moving(ux, uy, &oldx, &oldy);
     sx = SCREENX(oldx);
@@ -1479,24 +1616,31 @@ void DrawScreenField(int x, int y)
     horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
                  MovDir[oldx][oldy] == MV_RIGHT);
 
-    if (Store[oldx][oldy] == EL_MORAST_LEER ||
-       Store[oldx][oldy] == EL_MAGIC_WALL_EMPTY ||
-       Store[oldx][oldy] == EL_MAGIC_WALL_BD_EMPTY ||
-       Store[oldx][oldy] == EL_AMOEBE_NASS)
+    element_old = Feld[oldx][oldy];
+    content_old = Store[oldx][oldy];
+
+    if (element_old == EL_QUICKSAND_EMPTYING ||
+       element_old == EL_MAGIC_WALL_EMPTYING ||
+       element_old == EL_BD_MAGIC_WALL_EMPTYING ||
+       element_old == EL_AMOEBA_DRIPPING)
       cut_mode = CUT_ABOVE;
 
-    DrawScreenElement(x, y, EL_LEERRAUM);
-    element = Feld[oldx][oldy];
+    DrawScreenElement(x, y, EL_EMPTY);
 
     if (horiz_move)
-      DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
+      DrawScreenElementShifted(sx, sy, MovPos[oldx][oldy], 0, element_old,
+                              NO_CUTTING);
+    else if (cut_mode == NO_CUTTING)
+      DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], element_old,
+                              cut_mode);
     else
-      DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
+      DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], content_old,
+                              cut_mode);
   }
   else if (IS_DRAWABLE(element))
     DrawScreenElement(x, y, element);
   else
-    DrawScreenElement(x, y, EL_LEERRAUM);
+    DrawScreenElement(x, y, EL_EMPTY);
 }
 
 void DrawLevelField(int x, int y)
@@ -1525,13 +1669,7 @@ void DrawMiniElement(int x, int y, int element)
 {
   int graphic;
 
-  if (!element)
-  {
-    DrawMiniGraphic(x, y, -1);
-    return;
-  }
-
-  graphic = el2gfx(element);
+  graphic = el2img(element);
   DrawMiniGraphic(x, y, graphic);
 }
 
@@ -1540,7 +1678,7 @@ void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
   int x = sx + scroll_x, y = sy + scroll_y;
 
   if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
-    DrawMiniElement(sx, sy, EL_LEERRAUM);
+    DrawMiniElement(sx, sy, EL_EMPTY);
   else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
     DrawMiniElement(sx, sy, Feld[x][y]);
   else
@@ -1548,15 +1686,15 @@ void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
     int steel_type, steel_position;
     int border[6][2] =
     {
-      { GFX_VSTEEL_UPPER_LEFT, GFX_ISTEEL_UPPER_LEFT  },
-      { GFX_VSTEEL_UPPER_RIGHT,        GFX_ISTEEL_UPPER_RIGHT },
-      { GFX_VSTEEL_LOWER_LEFT, GFX_ISTEEL_LOWER_LEFT  },
-      { GFX_VSTEEL_LOWER_RIGHT,        GFX_ISTEEL_LOWER_RIGHT },
-      { GFX_VSTEEL_VERTICAL,   GFX_ISTEEL_VERTICAL    },
-      { GFX_VSTEEL_HORIZONTAL, GFX_ISTEEL_HORIZONTAL  }
+      { IMG_STEELWALL_TOPLEFT,         IMG_INVISIBLE_STEELWALL_TOPLEFT     },
+      { IMG_STEELWALL_TOPRIGHT,                IMG_INVISIBLE_STEELWALL_TOPRIGHT    },
+      { IMG_STEELWALL_BOTTOMLEFT,      IMG_INVISIBLE_STEELWALL_BOTTOMLEFT  },
+      { IMG_STEELWALL_BOTTOMRIGHT,     IMG_INVISIBLE_STEELWALL_BOTTOMRIGHT },
+      { IMG_STEELWALL_VERTICAL,                IMG_INVISIBLE_STEELWALL_VERTICAL    },
+      { IMG_STEELWALL_HORIZONTAL,      IMG_INVISIBLE_STEELWALL_HORIZONTAL  }
     };
 
-    steel_type = (BorderElement == EL_BETON ? 0 : 1);
+    steel_type = (BorderElement == EL_STEELWALL ? 0 : 1);
     steel_position = (x == -1 && y == -1                       ? 0 :
                      x == lev_fieldx && y == -1                ? 1 :
                      x == -1 && y == lev_fieldy                ? 2 :
@@ -1569,45 +1707,44 @@ void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
   }
 }
 
+void getMicroGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
+{
+  Bitmap *src_bitmap = new_graphic_info[graphic].bitmap;
+  int mini_startx = src_bitmap->width * 3 / 4;
+  int mini_starty = src_bitmap->height * 2 / 3;
+  int src_x = mini_startx + new_graphic_info[graphic].src_x / 8;
+  int src_y = mini_starty + new_graphic_info[graphic].src_y / 8;
+
+  if (src_x + MICRO_TILEX > src_bitmap->width ||
+      src_y + MICRO_TILEY > src_bitmap->height)
+  {
+    /* graphic of desired size seems not to be contained in this image;
+       dirty workaround: get it from the middle of the normal sized image */
+
+    getGraphicSource(graphic, 0, &src_bitmap, &src_x, &src_y);
+    src_x += (TILEX / 2 - MICRO_TILEX / 2);
+    src_y += (TILEY / 2 - MICRO_TILEY / 2);
+  }
+
+  *bitmap = src_bitmap;
+  *x = src_x;
+  *y = src_y;
+}
+
 void DrawMicroElement(int xpos, int ypos, int element)
 {
+  Bitmap *src_bitmap;
+  int src_x, src_y;
   int graphic;
 
-  if (element == EL_LEERRAUM)
+  if (element == EL_EMPTY)
     return;
 
-  graphic = el2gfx(element);
+  graphic = el2img(element);
 
-  if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
-  {
-    graphic -= GFX_START_ROCKSSP;
-    graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
-    XCopyArea(display, pix[PIX_SP], drawto, gc,
-             MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
-             MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
-             MICRO_TILEX, MICRO_TILEY, xpos, ypos);
-  }
-  else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
-  {
-    graphic -= GFX_START_ROCKSDC;
-    XCopyArea(display, pix[PIX_DC], drawto, gc,
-             MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
-             MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
-             MICRO_TILEX, MICRO_TILEY, xpos, ypos);
-  }
-  else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
-  {
-    graphic -= GFX_START_ROCKSMORE;
-    XCopyArea(display, pix[PIX_MORE], drawto, gc,
-             MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE) *MICRO_TILEX,
-             MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE) *MICRO_TILEY,
-             MICRO_TILEX, MICRO_TILEY, xpos, ypos);
-  }
-  else
-    XCopyArea(display, pix[PIX_BACK], drawto, gc,
-             MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
-             MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
-             MICRO_TILEX, MICRO_TILEY, xpos, ypos);
+  getMicroGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
+  BlitBitmap(src_bitmap, drawto, src_x, src_y, MICRO_TILEX, MICRO_TILEY,
+            xpos, ypos);
 }
 
 void DrawLevel()
@@ -1638,8 +1775,7 @@ static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
 {
   int x, y;
 
-  XFillRectangle(display, drawto, gc,
-                xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
+  ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
 
   if (lev_fieldx < STD_LEV_FIELDX)
     xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
@@ -1680,8 +1816,7 @@ static void DrawMicroLevelLabelExt(int mode)
 {
   char label_text[MAX_MICROLABEL_SIZE + 1];
 
-  XFillRectangle(display, drawto,gc,
-                SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
+  ClearRectangle(drawto, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
 
   strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
                       mode == MICROLABEL_CREATED_BY ? "created by" :
@@ -1806,12 +1941,15 @@ int REQ_in_range(int x, int y)
   return 0;
 }
 
+#define MAX_REQUEST_LINES              13
+#define MAX_REQUEST_LINE_LEN           7
+
 boolean Request(char *text, unsigned int req_state)
 {
   int mx, my, ty, result = -1;
   unsigned int old_door_state;
 
-#ifndef MSDOS
+#if defined(PLATFORM_UNIX)
   /* pause network game while waiting for request to answer */
   if (options.network &&
       game_status == PLAYING &&
@@ -1826,40 +1964,43 @@ boolean Request(char *text, unsigned int req_state)
   CloseDoor(DOOR_CLOSE_1);
 
   /* save old door content */
-  XCopyArea(display, pix[PIX_DB_DOOR], pix[PIX_DB_DOOR], gc,
-           DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
-           DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
+  BlitBitmap(bitmap_db_door, bitmap_db_door,
+            DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
+            DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
 
   /* clear door drawing field */
-  XFillRectangle(display, drawto, gc, DX, DY, DXSIZE, DYSIZE);
+  ClearRectangle(drawto, DX, DY, DXSIZE, DYSIZE);
 
   /* write text for request */
-  for(ty=0; ty<13; ty++)
+  for(ty=0; ty < MAX_REQUEST_LINES; ty++)
   {
+    char text_line[MAX_REQUEST_LINE_LEN + 1];
     int tx, tl, tc;
-    char txt[256];
 
     if (!*text)
       break;
 
-    for(tl=0,tx=0; tx<7; tl++,tx++)
+    for(tl=0,tx=0; tx < MAX_REQUEST_LINE_LEN; tl++,tx++)
     {
       tc = *(text + tx);
-      if (!tc || tc == 32)
+      if (!tc || tc == ' ')
        break;
     }
+
     if (!tl)
     { 
       text++; 
       ty--; 
       continue; 
     }
-    sprintf(txt, text); 
-    txt[tl] = 0;
-    DrawTextExt(drawto, gc,
-               DX + 51 - (tl * 14)/2, DY + 8 + ty * 16,
-               txt, FS_SMALL, FC_YELLOW);
-    text += tl + (tc == 32 ? 1 : 0);
+
+    strncpy(text_line, text, tl);
+    text_line[tl] = 0;
+
+    DrawTextExt(drawto, DX + 50 - (tl * 14)/2, DY + 8 + ty * 16,
+               text_line, FS_SMALL, FC_YELLOW);
+
+    text += tl + (tc == ' ' ? 1 : 0);
   }
 
   if (req_state & REQ_ASK)
@@ -1880,9 +2021,9 @@ boolean Request(char *text, unsigned int req_state)
   }
 
   /* copy request gadgets to door backbuffer */
-  XCopyArea(display, drawto, pix[PIX_DB_DOOR], gc,
-           DX, DY, DXSIZE, DYSIZE,
-           DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+  BlitBitmap(drawto, bitmap_db_door,
+            DX, DY, DXSIZE, DYSIZE,
+            DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
 
   OpenDoor(DOOR_OPEN_1);
 
@@ -1902,43 +2043,37 @@ boolean Request(char *text, unsigned int req_state)
 
   while(result < 0)
   {
-    if (XPending(display))
+    if (PendingEvent())
     {
-      XEvent event;
+      Event event;
 
-      XNextEvent(display, &event);
+      NextEvent(&event);
 
       switch(event.type)
       {
-       case ButtonPress:
-       case ButtonRelease:
-       case MotionNotify:
+       case EVENT_BUTTONPRESS:
+       case EVENT_BUTTONRELEASE:
+       case EVENT_MOTIONNOTIFY:
        {
-         if (event.type == MotionNotify)
+         if (event.type == EVENT_MOTIONNOTIFY)
          {
-           Window root, child;
-           int root_x, root_y;
-           int win_x, win_y;
-           unsigned int mask;
-
-           if (!XQueryPointer(display, window, &root, &child,
-                              &root_x, &root_y, &win_x, &win_y, &mask))
-             continue;
+           if (!PointerInWindow(window))
+             continue; /* window and pointer are on different screens */
 
            if (!button_status)
              continue;
 
            motion_status = TRUE;
-           mx = ((XMotionEvent *) &event)->x;
-           my = ((XMotionEvent *) &event)->y;
+           mx = ((MotionEvent *) &event)->x;
+           my = ((MotionEvent *) &event)->y;
          }
          else
          {
            motion_status = FALSE;
-           mx = ((XButtonEvent *) &event)->x;
-           my = ((XButtonEvent *) &event)->y;
-           if (event.type==ButtonPress)
-             button_status = ((XButtonEvent *) &event)->button;
+           mx = ((ButtonEvent *) &event)->x;
+           my = ((ButtonEvent *) &event)->y;
+           if (event.type == EVENT_BUTTONPRESS)
+             button_status = ((ButtonEvent *) &event)->button;
            else
              button_status = MB_RELEASED;
          }
@@ -1978,15 +2113,14 @@ boolean Request(char *text, unsigned int req_state)
          break;
        }
 
-       case KeyPress:
-         switch(XLookupKeysym((XKeyEvent *)&event,
-                              ((XKeyEvent *)&event)->state))
+       case EVENT_KEYPRESS:
+         switch(GetEventKey((KeyEvent *)&event, TRUE))
          {
-           case XK_Return:
+           case KSYM_Return:
              result = 1;
              break;
 
-           case XK_Escape:
+           case KSYM_Escape:
              result = 0;
              break;
 
@@ -1997,8 +2131,8 @@ boolean Request(char *text, unsigned int req_state)
            result = 0;
          break;
 
-       case KeyRelease:
-         key_joystick_mapping = 0;
+       case EVENT_KEYRELEASE:
+         ClearPlayerAction();
          break;
 
        default:
@@ -2033,16 +2167,16 @@ boolean Request(char *text, unsigned int req_state)
 
     if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
     {
-      XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
-               DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
-               DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
+      BlitBitmap(bitmap_db_door, bitmap_db_door,
+                DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
+                DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
       OpenDoor(DOOR_OPEN_1);
     }
   }
 
   RemapAllGadgets();
 
-#ifndef MSDOS
+#if defined(PLATFORM_UNIX)
   /* continue network game after request */
   if (options.network &&
       game_status == PLAYING &&
@@ -2059,9 +2193,9 @@ unsigned int OpenDoor(unsigned int door_state)
 
   if (door_state & DOOR_COPY_BACK)
   {
-    XCopyArea(display, pix[PIX_DB_DOOR], pix[PIX_DB_DOOR], gc,
-             DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
-             DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+    BlitBitmap(bitmap_db_door, bitmap_db_door,
+              DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
+              DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
     door_state &= ~DOOR_COPY_BACK;
   }
 
@@ -2074,10 +2208,10 @@ unsigned int CloseDoor(unsigned int door_state)
 {
   unsigned int new_door_state;
 
-  XCopyArea(display, backbuffer, pix[PIX_DB_DOOR], gc,
-           DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
-  XCopyArea(display, backbuffer, pix[PIX_DB_DOOR], gc,
-           VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
+  BlitBitmap(backbuffer, bitmap_db_door,
+            DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+  BlitBitmap(backbuffer, bitmap_db_door,
+            VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
 
   new_door_state = MoveDoor(door_state);
 
@@ -2086,7 +2220,12 @@ unsigned int CloseDoor(unsigned int door_state)
 
 unsigned int GetDoorState()
 {
-  return(MoveDoor(DOOR_GET_STATE));
+  return MoveDoor(DOOR_GET_STATE);
+}
+
+unsigned int SetDoorState(unsigned int door_state)
+{
+  return MoveDoor(door_state | DOOR_SET_STATE);
 }
 
 unsigned int MoveDoor(unsigned int door_state)
@@ -2100,6 +2239,16 @@ unsigned int MoveDoor(unsigned int door_state)
   if (door_state == DOOR_GET_STATE)
     return(door1 | door2);
 
+  if (door_state & DOOR_SET_STATE)
+  {
+    if (door_state & DOOR_ACTION_1)
+      door1 = door_state & DOOR_ACTION_1;
+    if (door_state & DOOR_ACTION_2)
+      door2 = door_state & DOOR_ACTION_2;
+
+    return(door1 | door2);
+  }
+
   if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
     door_state &= ~DOOR_OPEN_1;
   else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
@@ -2113,59 +2262,77 @@ unsigned int MoveDoor(unsigned int door_state)
   {
     stepsize = 20;
     door_delay_value = 0;
-    StopSound(SND_OEFFNEN);
+
+    StopSound(SND_MENU_DOOR_OPENING);
+    StopSound(SND_MENU_DOOR_CLOSING);
+  }
+
+  if (global.autoplay_leveldir)
+  {
+    door_state |= DOOR_NO_DELAY;
+    door_state &= ~DOOR_CLOSE_ALL;
   }
 
   if (door_state & DOOR_ACTION)
   {
     if (!(door_state & DOOR_NO_DELAY))
-      PlaySoundStereo(SND_OEFFNEN, PSND_MAX_RIGHT);
+    {
+      /* opening door sound has priority over simultaneously closing door */
+      if (door_state & (DOOR_OPEN_1 | DOOR_OPEN_2))
+       PlaySoundStereo(SND_MENU_DOOR_OPENING, SOUND_MAX_RIGHT);
+      else if (door_state & (DOOR_CLOSE_1 | DOOR_CLOSE_2))
+       PlaySoundStereo(SND_MENU_DOOR_CLOSING, SOUND_MAX_RIGHT);
+    }
 
     start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
 
     for(x=start; x<=DXSIZE; x+=stepsize)
     {
-      WaitUntilDelayReached(&door_delay, door_delay_value);
+      Bitmap *bitmap = new_graphic_info[IMG_MENU_DOOR].bitmap;
+      GC gc = bitmap->stored_clip_gc;
+
+      if (!(door_state & DOOR_NO_DELAY))
+       WaitUntilDelayReached(&door_delay, door_delay_value);
 
       if (door_state & DOOR_ACTION_1)
       {
        int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
        int j = (DXSIZE - i) / 3;
 
-       XCopyArea(display, pix[PIX_DB_DOOR], drawto, gc,
-                 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
-                 DXSIZE,DYSIZE - i/2, DX, DY);
-
-       XFillRectangle(display, drawto, gc, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
-
-       XSetClipOrigin(display, clip_gc[PIX_DOOR],
-                      DX - i, (DY + j) - DOOR_GFX_PAGEY1);
-       XCopyArea(display, pix[PIX_DOOR], drawto,clip_gc[PIX_DOOR],
-                 DXSIZE, DOOR_GFX_PAGEY1, i, 77, DX + DXSIZE - i, DY + j);
-       XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
-                 DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63, DX + DXSIZE - i,
-                 DY + 140 + j);
-       XSetClipOrigin(display, clip_gc[PIX_DOOR],
-                      DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
-       XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
-                 DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j, DX, DY);
-       XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
-                 DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63, DX, DY + 140 - j);
-
-       XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
-                 DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
-                 DX, DY + 77 - j);
-       XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
-                 DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
-                 DX, DY + 203 - j);
-       XSetClipOrigin(display, clip_gc[PIX_DOOR],
-                      DX - i, (DY + j) - DOOR_GFX_PAGEY1);
-       XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
-                 DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
-                 DX + DXSIZE - i, DY + 77 + j);
-       XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
-                 DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
-                 DX + DXSIZE - i, DY + 203 + j);
+       BlitBitmap(bitmap_db_door, drawto,
+                  DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
+                  DXSIZE,DYSIZE - i/2, DX, DY);
+
+       ClearRectangle(drawto, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
+
+       SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
+       BlitBitmapMasked(bitmap, drawto,
+                        DXSIZE, DOOR_GFX_PAGEY1, i, 77,
+                        DX + DXSIZE - i, DY + j);
+       BlitBitmapMasked(bitmap, drawto,
+                        DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63,
+                        DX + DXSIZE - i, DY + 140 + j);
+       SetClipOrigin(bitmap, gc, DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
+       BlitBitmapMasked(bitmap, drawto,
+                        DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j,
+                        DX, DY);
+       BlitBitmapMasked(bitmap, drawto,
+                        DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63,
+                        DX, DY + 140 - j);
+
+       BlitBitmapMasked(bitmap, drawto,
+                        DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
+                        DX, DY + 77 - j);
+       BlitBitmapMasked(bitmap, drawto,
+                        DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
+                        DX, DY + 203 - j);
+       SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
+       BlitBitmapMasked(bitmap, drawto,
+                        DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
+                        DX + DXSIZE - i, DY + 77 + j);
+       BlitBitmapMasked(bitmap, drawto,
+                        DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
+                        DX + DXSIZE - i, DY + 203 + j);
 
        redraw_mask |= REDRAW_DOOR_1;
       }
@@ -2175,29 +2342,30 @@ unsigned int MoveDoor(unsigned int door_state)
        int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
        int j = (VXSIZE - i) / 3;
 
-       XCopyArea(display, pix[PIX_DB_DOOR], drawto, gc,
-                 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
-                 VXSIZE, VYSIZE - i/2, VX, VY);
-
-       XFillRectangle(display, drawto, gc, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
-
-       XSetClipOrigin(display, clip_gc[PIX_DOOR],
-                      VX - i, (VY + j) - DOOR_GFX_PAGEY2);
-       XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
-                 VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2, VX + VXSIZE-i, VY+j);
-       XSetClipOrigin(display, clip_gc[PIX_DOOR],
-                      VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
-       XCopyArea(display, pix[PIX_DOOR], drawto,clip_gc[PIX_DOOR],
-                 VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j, VX, VY);
-
-       XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
-                 VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2, i, VYSIZE / 2,
-                 VX, VY + VYSIZE / 2 - j);
-       XSetClipOrigin(display, clip_gc[PIX_DOOR],
-                      VX - i, (VY + j) - DOOR_GFX_PAGEY2);
-       XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
-                 VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2, i, VYSIZE / 2 - j,
-                 VX + VXSIZE - i, VY + VYSIZE / 2 + j);
+       BlitBitmap(bitmap_db_door, drawto,
+                  DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
+                  VXSIZE, VYSIZE - i/2, VX, VY);
+
+       ClearRectangle(drawto, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
+
+       SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
+       BlitBitmapMasked(bitmap, drawto,
+                        VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2,
+                        VX + VXSIZE-i, VY+j);
+       SetClipOrigin(bitmap, gc,
+                     VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
+       BlitBitmapMasked(bitmap, drawto,
+                        VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j,
+                        VX, VY);
+
+       BlitBitmapMasked(bitmap, drawto,
+                        VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2,
+                        i, VYSIZE / 2, VX, VY + VYSIZE / 2 - j);
+       SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
+       BlitBitmapMasked(bitmap, drawto,
+                        VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2,
+                        i, VYSIZE / 2 - j,
+                        VX + VXSIZE - i, VY + VYSIZE / 2 + j);
 
        redraw_mask |= REDRAW_DOOR_2;
       }
@@ -2210,7 +2378,10 @@ unsigned int MoveDoor(unsigned int door_state)
   }
 
   if (setup.quick_doors)
-    StopSound(SND_OEFFNEN);
+  {
+    StopSound(SND_MENU_DOOR_OPENING);
+    StopSound(SND_MENU_DOOR_CLOSING);
+  }
 
   if (door_state & DOOR_ACTION_1)
     door1 = door_state & DOOR_ACTION_1;
@@ -2223,8 +2394,8 @@ unsigned int MoveDoor(unsigned int door_state)
 void DrawSpecialEditorDoor()
 {
   /* draw bigger toolbox window */
-  XCopyArea(display, pix[PIX_DOOR], drawto, gc,
-           DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
+  BlitBitmap(new_graphic_info[IMG_MENU_DOOR].bitmap, drawto,
+            DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
 
   redraw_mask |= REDRAW_ALL;
 }
@@ -2232,24 +2403,27 @@ void DrawSpecialEditorDoor()
 void UndrawSpecialEditorDoor()
 {
   /* draw normal tape recorder window */
-  XCopyArea(display, pix[PIX_BACK], drawto, gc,
-           562, 344, 108, 56, EX - 4, EY - 12);
+  BlitBitmap(new_graphic_info[IMG_MENU_BACK].bitmap, drawto,
+            562, 344, 108, 56, EX - 4, EY - 12);
 
   redraw_mask |= REDRAW_ALL;
 }
 
-int ReadPixel(Drawable d, int x, int y)
+#ifndef        TARGET_SDL
+int ReadPixel(DrawBuffer *bitmap, int x, int y)
 {
   XImage *pixel_image;
   unsigned long pixel_value;
 
-  pixel_image = XGetImage(display, d, x, y, 1, 1, AllPlanes, ZPixmap);
+  pixel_image = XGetImage(display, bitmap->drawable,
+                         x, y, 1, 1, AllPlanes, ZPixmap);
   pixel_value = XGetPixel(pixel_image, 0, 0);
 
   XDestroyImage(pixel_image);
 
   return pixel_value;
 }
+#endif
 
 /* ---------- new tool button stuff ---------------------------------------- */
 
@@ -2352,19 +2526,14 @@ static struct
   }
 };
 
-static void DoNotDisplayInfoText(void *ptr)
-{
-  return;
-}
-
 void CreateToolButtons()
 {
   int i;
 
   for (i=0; i<NUM_TOOL_BUTTONS; i++)
   {
-    Pixmap gd_pixmap = pix[PIX_DOOR];
-    Pixmap deco_pixmap = None;
+    Bitmap *gd_bitmap = new_graphic_info[IMG_MENU_DOOR].bitmap;
+    Bitmap *deco_bitmap = None;
     int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
     struct GadgetInfo *gi;
     unsigned long event_mask;
@@ -2382,8 +2551,10 @@ void CreateToolButtons()
 
     if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
     {
-      getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
-                          &deco_pixmap, &deco_x, &deco_y);
+      int player_nr = id - TOOL_CTRL_ID_PLAYER_1;
+
+      getMiniGraphicSource(PLAYER_NR_GFX(IMG_PLAYER1, player_nr),
+                          &deco_bitmap, &deco_x, &deco_y);
       deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
       deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
     }
@@ -2396,15 +2567,14 @@ void CreateToolButtons()
                      GDI_HEIGHT, toolbutton_info[i].height,
                      GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
                      GDI_STATE, GD_BUTTON_UNPRESSED,
-                     GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y,
-                     GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y,
-                     GDI_DECORATION_DESIGN, deco_pixmap, deco_x, deco_y,
+                     GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
+                     GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
+                     GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
                      GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
                      GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
                      GDI_DECORATION_SHIFTING, 1, 1,
                      GDI_EVENT_MASK, event_mask,
                      GDI_CALLBACK_ACTION, HandleToolButtons,
-                     GDI_CALLBACK_INFO, DoNotDisplayInfoText,
                      GDI_END);
 
     if (gi == NULL)
@@ -2414,6 +2584,14 @@ void CreateToolButtons()
   }
 }
 
+void FreeToolButtons()
+{
+  int i;
+
+  for (i=0; i<NUM_TOOL_BUTTONS; i++)
+    FreeGadget(tool_gadget[i]);
+}
+
 static void UnmapToolButtons()
 {
   int i;
@@ -2427,263 +2605,296 @@ static void HandleToolButtons(struct GadgetInfo *gi)
   request_gadget_id = gi->custom_id;
 }
 
-int el2gfx(int element)
+int get_next_element(int element)
 {
   switch(element)
   {
-    case EL_LEERRAUM:          return -1;
-    case EL_ERDREICH:          return GFX_ERDREICH;
-    case EL_MAUERWERK:         return GFX_MAUERWERK;
-    case EL_FELSBODEN:         return GFX_FELSBODEN;
-    case EL_FELSBROCKEN:       return GFX_FELSBROCKEN;
-    case EL_SCHLUESSEL:                return GFX_SCHLUESSEL;
-    case EL_EDELSTEIN:         return GFX_EDELSTEIN;
-    case EL_AUSGANG_ZU:                return GFX_AUSGANG_ZU;
-    case EL_AUSGANG_ACT:       return GFX_AUSGANG_ACT;
-    case EL_AUSGANG_AUF:       return GFX_AUSGANG_AUF;
-    case EL_SPIELFIGUR:                return GFX_SPIELFIGUR;
-    case EL_SPIELER1:          return GFX_SPIELER1;
-    case EL_SPIELER2:          return GFX_SPIELER2;
-    case EL_SPIELER3:          return GFX_SPIELER3;
-    case EL_SPIELER4:          return GFX_SPIELER4;
-    case EL_KAEFER:            return GFX_KAEFER;
-    case EL_KAEFER_RIGHT:      return GFX_KAEFER_RIGHT;
-    case EL_KAEFER_UP:         return GFX_KAEFER_UP;
-    case EL_KAEFER_LEFT:       return GFX_KAEFER_LEFT;
-    case EL_KAEFER_DOWN:       return GFX_KAEFER_DOWN;
-    case EL_FLIEGER:           return GFX_FLIEGER;
-    case EL_FLIEGER_RIGHT:     return GFX_FLIEGER_RIGHT;
-    case EL_FLIEGER_UP:                return GFX_FLIEGER_UP;
-    case EL_FLIEGER_LEFT:      return GFX_FLIEGER_LEFT;
-    case EL_FLIEGER_DOWN:      return GFX_FLIEGER_DOWN;
-    case EL_BUTTERFLY:         return GFX_BUTTERFLY;
-    case EL_BUTTERFLY_RIGHT:   return GFX_BUTTERFLY_RIGHT;
-    case EL_BUTTERFLY_UP:      return GFX_BUTTERFLY_UP;
-    case EL_BUTTERFLY_LEFT:    return GFX_BUTTERFLY_LEFT;
-    case EL_BUTTERFLY_DOWN:    return GFX_BUTTERFLY_DOWN;
-    case EL_FIREFLY:           return GFX_FIREFLY;
-    case EL_FIREFLY_RIGHT:     return GFX_FIREFLY_RIGHT;
-    case EL_FIREFLY_UP:                return GFX_FIREFLY_UP;
-    case EL_FIREFLY_LEFT:      return GFX_FIREFLY_LEFT;
-    case EL_FIREFLY_DOWN:      return GFX_FIREFLY_DOWN;
-    case EL_MAMPFER:           return GFX_MAMPFER;
-    case EL_ROBOT:             return GFX_ROBOT;
-    case EL_BETON:             return GFX_BETON;
-    case EL_DIAMANT:           return GFX_DIAMANT;
-    case EL_MORAST_LEER:       return GFX_MORAST_LEER;
-    case EL_MORAST_VOLL:       return GFX_MORAST_VOLL;
-    case EL_TROPFEN:           return GFX_TROPFEN;
-    case EL_BOMBE:             return GFX_BOMBE;
-    case EL_MAGIC_WALL_OFF:    return GFX_MAGIC_WALL_OFF;
-    case EL_MAGIC_WALL_EMPTY:  return GFX_MAGIC_WALL_EMPTY;
-    case EL_MAGIC_WALL_FULL:   return GFX_MAGIC_WALL_FULL;
-    case EL_MAGIC_WALL_DEAD:   return GFX_MAGIC_WALL_DEAD;
-    case EL_SALZSAEURE:                return GFX_SALZSAEURE;
-    case EL_AMOEBE_TOT:                return GFX_AMOEBE_TOT;
-    case EL_AMOEBE_NASS:       return GFX_AMOEBE_NASS;
-    case EL_AMOEBE_NORM:       return GFX_AMOEBE_NORM;
-    case EL_AMOEBE_VOLL:       return GFX_AMOEBE_VOLL;
-    case EL_AMOEBE_BD:         return GFX_AMOEBE_BD;
-    case EL_AMOEBA2DIAM:       return GFX_AMOEBA2DIAM;
-    case EL_KOKOSNUSS:         return GFX_KOKOSNUSS;
-    case EL_LIFE:              return GFX_LIFE;
-    case EL_LIFE_ASYNC:                return GFX_LIFE_ASYNC;
-    case EL_DYNAMITE_ACTIVE:   return GFX_DYNAMIT;
-    case EL_BADEWANNE:         return GFX_BADEWANNE;
-    case EL_BADEWANNE1:                return GFX_BADEWANNE1;
-    case EL_BADEWANNE2:                return GFX_BADEWANNE2;
-    case EL_BADEWANNE3:                return GFX_BADEWANNE3;
-    case EL_BADEWANNE4:                return GFX_BADEWANNE4;
-    case EL_BADEWANNE5:                return GFX_BADEWANNE5;
-    case EL_ABLENK_AUS:                return GFX_ABLENK_AUS;
-    case EL_ABLENK_EIN:                return GFX_ABLENK_EIN;
-    case EL_SCHLUESSEL1:       return GFX_SCHLUESSEL1;
-    case EL_SCHLUESSEL2:       return GFX_SCHLUESSEL2;
-    case EL_SCHLUESSEL3:       return GFX_SCHLUESSEL3;
-    case EL_SCHLUESSEL4:       return GFX_SCHLUESSEL4;
-    case EL_PFORTE1:           return GFX_PFORTE1;
-    case EL_PFORTE2:           return GFX_PFORTE2;
-    case EL_PFORTE3:           return GFX_PFORTE3;
-    case EL_PFORTE4:           return GFX_PFORTE4;
-    case EL_PFORTE1X:          return GFX_PFORTE1X;
-    case EL_PFORTE2X:          return GFX_PFORTE2X;
-    case EL_PFORTE3X:          return GFX_PFORTE3X;
-    case EL_PFORTE4X:          return GFX_PFORTE4X;
-    case EL_DYNAMITE_INACTIVE: return GFX_DYNAMIT_AUS;
-    case EL_PACMAN:            return GFX_PACMAN;
-    case EL_PACMAN_RIGHT:      return GFX_PACMAN_RIGHT;
-    case EL_PACMAN_UP:         return GFX_PACMAN_UP;
-    case EL_PACMAN_LEFT:       return GFX_PACMAN_LEFT;
-    case EL_PACMAN_DOWN:       return GFX_PACMAN_DOWN;
-    case EL_UNSICHTBAR:                return GFX_UNSICHTBAR;
-    case EL_ERZ_EDEL:          return GFX_ERZ_EDEL;
-    case EL_ERZ_DIAM:          return GFX_ERZ_DIAM;
-    case EL_BIRNE_AUS:         return GFX_BIRNE_AUS;
-    case EL_BIRNE_EIN:         return GFX_BIRNE_EIN;
-    case EL_ZEIT_VOLL:         return GFX_ZEIT_VOLL;
-    case EL_ZEIT_LEER:         return GFX_ZEIT_LEER;
-    case EL_MAUER_LEBT:                return GFX_MAUER_LEBT;
-    case EL_MAUER_X:           return GFX_MAUER_X;
-    case EL_MAUER_Y:           return GFX_MAUER_Y;
-    case EL_MAUER_XY:          return GFX_MAUER_XY;
-    case EL_EDELSTEIN_BD:      return GFX_EDELSTEIN_BD;
-    case EL_EDELSTEIN_GELB:    return GFX_EDELSTEIN_GELB;
-    case EL_EDELSTEIN_ROT:     return GFX_EDELSTEIN_ROT;
-    case EL_EDELSTEIN_LILA:    return GFX_EDELSTEIN_LILA;
-    case EL_ERZ_EDEL_BD:       return GFX_ERZ_EDEL_BD;
-    case EL_ERZ_EDEL_GELB:     return GFX_ERZ_EDEL_GELB;
-    case EL_ERZ_EDEL_ROT:      return GFX_ERZ_EDEL_ROT;
-    case EL_ERZ_EDEL_LILA:     return GFX_ERZ_EDEL_LILA;
-    case EL_MAMPFER2:          return GFX_MAMPFER2;
-    case EL_MAGIC_WALL_BD_OFF: return GFX_MAGIC_WALL_BD_OFF;
-    case EL_MAGIC_WALL_BD_EMPTY:return GFX_MAGIC_WALL_BD_EMPTY;
-    case EL_MAGIC_WALL_BD_FULL:        return GFX_MAGIC_WALL_BD_FULL;
-    case EL_MAGIC_WALL_BD_DEAD:        return GFX_MAGIC_WALL_BD_DEAD;
-    case EL_DYNABOMB_ACTIVE_1: return GFX_DYNABOMB;
-    case EL_DYNABOMB_ACTIVE_2: return GFX_DYNABOMB;
-    case EL_DYNABOMB_ACTIVE_3: return GFX_DYNABOMB;
-    case EL_DYNABOMB_ACTIVE_4: return GFX_DYNABOMB;
-    case EL_DYNABOMB_NR:       return GFX_DYNABOMB_NR;
-    case EL_DYNABOMB_SZ:       return GFX_DYNABOMB_SZ;
-    case EL_DYNABOMB_XL:       return GFX_DYNABOMB_XL;
-    case EL_SOKOBAN_OBJEKT:    return GFX_SOKOBAN_OBJEKT;
-    case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
-    case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
-    case EL_MOLE:              return GFX_MOLE;
-    case EL_PINGUIN:           return GFX_PINGUIN;
-    case EL_SCHWEIN:           return GFX_SCHWEIN;
-    case EL_DRACHE:            return GFX_DRACHE;
-    case EL_SONDE:             return GFX_SONDE;
-    case EL_PFEIL_LEFT:                return GFX_PFEIL_LEFT;
-    case EL_PFEIL_RIGHT:       return GFX_PFEIL_RIGHT;
-    case EL_PFEIL_UP:          return GFX_PFEIL_UP;
-    case EL_PFEIL_DOWN:                return GFX_PFEIL_DOWN;
-    case EL_SPEED_PILL:                return GFX_SPEED_PILL;
-    case EL_SP_TERMINAL_ACTIVE:        return GFX_SP_TERMINAL;
-    case EL_SP_BUG_ACTIVE:     return GFX_SP_BUG_ACTIVE;
-    case EL_SP_ZONK:           return GFX_SP_ZONK;
+    case EL_QUICKSAND_FILLING:         return EL_QUICKSAND_FULL;
+    case EL_QUICKSAND_EMPTYING:                return EL_QUICKSAND_EMPTY;
+    case EL_MAGIC_WALL_FILLING:                return EL_MAGIC_WALL_FULL;
+    case EL_MAGIC_WALL_EMPTYING:       return EL_MAGIC_WALL_ACTIVE;
+    case EL_BD_MAGIC_WALL_FILLING:     return EL_BD_MAGIC_WALL_FULL;
+    case EL_BD_MAGIC_WALL_EMPTYING:    return EL_BD_MAGIC_WALL_ACTIVE;
+    case EL_AMOEBA_DRIPPING:           return EL_AMOEBA_WET;
+
+    default:                           return element;
+  }
+}
+
+int el2gfx_OLD(int element)
+{
+  switch(element)
+  {
+    case EL_EMPTY:                     return -1;
+    case EL_SAND:                      return GFX_ERDREICH;
+    case EL_WALL:                      return GFX_MAUERWERK;
+    case EL_WALL_CRUMBLED:             return GFX_FELSBODEN;
+    case EL_ROCK:                      return GFX_FELSBROCKEN;
+    case EL_EMERALD:                   return GFX_EDELSTEIN;
+    case EL_EXIT_CLOSED:               return GFX_AUSGANG_ZU;
+    case EL_EXIT_OPENING:              return GFX_AUSGANG_ACT;
+    case EL_EXIT_OPEN:                 return GFX_AUSGANG_AUF;
+    case EL_SP_EXIT_OPEN:              return GFX_SP_EXIT;
+    case EL_PLAYER1:                   return GFX_SPIELER1;
+    case EL_PLAYER2:                   return GFX_SPIELER2;
+    case EL_PLAYER3:                   return GFX_SPIELER3;
+    case EL_PLAYER4:                   return GFX_SPIELER4;
+    case EL_BUG:                       return GFX_KAEFER;
+    case EL_BUG_RIGHT:                 return GFX_KAEFER_RIGHT;
+    case EL_BUG_UP:                    return GFX_KAEFER_UP;
+    case EL_BUG_LEFT:                  return GFX_KAEFER_LEFT;
+    case EL_BUG_DOWN:                  return GFX_KAEFER_DOWN;
+    case EL_SPACESHIP:                 return GFX_FLIEGER;
+    case EL_SPACESHIP_RIGHT:           return GFX_FLIEGER_RIGHT;
+    case EL_SPACESHIP_UP:              return GFX_FLIEGER_UP;
+    case EL_SPACESHIP_LEFT:            return GFX_FLIEGER_LEFT;
+    case EL_SPACESHIP_DOWN:            return GFX_FLIEGER_DOWN;
+    case EL_BD_BUTTERFLY:              return GFX_BUTTERFLY;
+    case EL_BD_BUTTERFLY_RIGHT:                return GFX_BUTTERFLY_RIGHT;
+    case EL_BD_BUTTERFLY_UP:           return GFX_BUTTERFLY_UP;
+    case EL_BD_BUTTERFLY_LEFT:         return GFX_BUTTERFLY_LEFT;
+    case EL_BD_BUTTERFLY_DOWN:         return GFX_BUTTERFLY_DOWN;
+    case EL_BD_FIREFLY:                        return GFX_FIREFLY;
+    case EL_BD_FIREFLY_RIGHT:          return GFX_FIREFLY_RIGHT;
+    case EL_BD_FIREFLY_UP:             return GFX_FIREFLY_UP;
+    case EL_BD_FIREFLY_LEFT:           return GFX_FIREFLY_LEFT;
+    case EL_BD_FIREFLY_DOWN:           return GFX_FIREFLY_DOWN;
+    case EL_YAMYAM:                    return GFX_MAMPFER;
+    case EL_ROBOT:                     return GFX_ROBOT;
+    case EL_STEELWALL:                 return GFX_BETON;
+    case EL_DIAMOND:                   return GFX_DIAMANT;
+    case EL_QUICKSAND_EMPTY:           return GFX_MORAST_LEER;
+    case EL_QUICKSAND_FULL:            return GFX_MORAST_VOLL;
+    case EL_QUICKSAND_EMPTYING:                return GFX_MORAST_LEER;
+    case EL_AMOEBA_DROP:               return GFX_TROPFEN;
+    case EL_BOMB:                      return GFX_BOMBE;
+    case EL_MAGIC_WALL:                        return GFX_MAGIC_WALL_OFF;
+    case EL_MAGIC_WALL_ACTIVE:         return GFX_MAGIC_WALL_EMPTY;
+    case EL_MAGIC_WALL_EMPTYING:       return GFX_MAGIC_WALL_EMPTY;
+    case EL_MAGIC_WALL_FULL:           return GFX_MAGIC_WALL_FULL;
+    case EL_MAGIC_WALL_DEAD:           return GFX_MAGIC_WALL_DEAD;
+    case EL_ACID:                      return GFX_SALZSAEURE;
+    case EL_AMOEBA_DEAD:               return GFX_AMOEBE_TOT;
+    case EL_AMOEBA_WET:                        return GFX_AMOEBE_NASS;
+    case EL_AMOEBA_DRY:                        return GFX_AMOEBE_NORM;
+    case EL_AMOEBA_FULL:               return GFX_AMOEBE_VOLL;
+    case EL_BD_AMOEBA:                 return GFX_AMOEBE_BD;
+    case EL_AMOEBA_TO_DIAMOND:         return GFX_AMOEBA2DIAM;
+    case EL_AMOEBA_DRIPPING:           return GFX_AMOEBE_NASS;
+    case EL_NUT:                       return GFX_KOKOSNUSS;
+    case EL_GAMEOFLIFE:                        return GFX_LIFE;
+    case EL_BIOMAZE:                   return GFX_LIFE_ASYNC;
+    case EL_DYNAMITE_ACTIVE:           return GFX_DYNAMIT;
+    case EL_STONEBLOCK:                        return GFX_BADEWANNE;
+    case EL_ACIDPOOL_TOPLEFT:          return GFX_BADEWANNE1;
+    case EL_ACIDPOOL_TOPRIGHT:         return GFX_BADEWANNE2;
+    case EL_ACIDPOOL_BOTTOMLEFT:       return GFX_BADEWANNE3;
+    case EL_ACIDPOOL_BOTTOM:           return GFX_BADEWANNE4;
+    case EL_ACIDPOOL_BOTTOMRIGHT:      return GFX_BADEWANNE5;
+    case EL_ROBOT_WHEEL:               return GFX_ABLENK_AUS;
+    case EL_ROBOT_WHEEL_ACTIVE:                return GFX_ABLENK_EIN;
+    case EL_KEY1:                      return GFX_SCHLUESSEL1;
+    case EL_KEY2:                      return GFX_SCHLUESSEL2;
+    case EL_KEY3:                      return GFX_SCHLUESSEL3;
+    case EL_KEY4:                      return GFX_SCHLUESSEL4;
+    case EL_GATE1:                     return GFX_PFORTE1;
+    case EL_GATE2:                     return GFX_PFORTE2;
+    case EL_GATE3:                     return GFX_PFORTE3;
+    case EL_GATE4:                     return GFX_PFORTE4;
+    case EL_GATE1_GRAY:                        return GFX_PFORTE1X;
+    case EL_GATE2_GRAY:                        return GFX_PFORTE2X;
+    case EL_GATE3_GRAY:                        return GFX_PFORTE3X;
+    case EL_GATE4_GRAY:                        return GFX_PFORTE4X;
+    case EL_DYNAMITE:                  return GFX_DYNAMIT_AUS;
+    case EL_PACMAN:                    return GFX_PACMAN;
+    case EL_PACMAN_RIGHT:              return GFX_PACMAN_RIGHT;
+    case EL_PACMAN_UP:                 return GFX_PACMAN_UP;
+    case EL_PACMAN_LEFT:               return GFX_PACMAN_LEFT;
+    case EL_PACMAN_DOWN:               return GFX_PACMAN_DOWN;
+    case EL_INVISIBLE_WALL:            return GFX_UNSICHTBAR;
+    case EL_INVISIBLE_WALL_ACTIVE:     return GFX_UNSICHTBAR_ON;
+    case EL_WALL_EMERALD:              return GFX_ERZ_EDEL;
+    case EL_WALL_DIAMOND:              return GFX_ERZ_DIAM;
+    case EL_LAMP:                      return GFX_BIRNE_AUS;
+    case EL_LAMP_ACTIVE:               return GFX_BIRNE_EIN;
+    case EL_TIME_ORB_FULL:             return GFX_ZEIT_VOLL;
+    case EL_TIME_ORB_EMPTY:            return GFX_ZEIT_LEER;
+    case EL_WALL_GROWING:              return GFX_MAUER_LEBT;
+    case EL_WALL_GROWING_X:            return GFX_MAUER_X;
+    case EL_WALL_GROWING_Y:            return GFX_MAUER_Y;
+    case EL_WALL_GROWING_XY:           return GFX_MAUER_XY;
+    case EL_BD_DIAMOND:                        return GFX_EDELSTEIN_BD;
+    case EL_EMERALD_YELLOW:            return GFX_EDELSTEIN_GELB;
+    case EL_EMERALD_RED:               return GFX_EDELSTEIN_ROT;
+    case EL_EMERALD_PURPLE:            return GFX_EDELSTEIN_LILA;
+    case EL_WALL_BD_DIAMOND:           return GFX_ERZ_EDEL_BD;
+    case EL_WALL_EMERALD_YELLOW:       return GFX_ERZ_EDEL_GELB;
+    case EL_WALL_EMERALD_RED:          return GFX_ERZ_EDEL_ROT;
+    case EL_WALL_EMERALD_PURPLE:       return GFX_ERZ_EDEL_LILA;
+    case EL_DARK_YAMYAM:               return GFX_MAMPFER2;
+    case EL_BD_MAGIC_WALL:             return GFX_MAGIC_WALL_BD_OFF;
+    case EL_BD_MAGIC_WALL_ACTIVE:      return GFX_MAGIC_WALL_BD_EMPTY;
+    case EL_BD_MAGIC_WALL_EMPTYING:    return GFX_MAGIC_WALL_BD_EMPTY;
+    case EL_BD_MAGIC_WALL_FULL:                return GFX_MAGIC_WALL_BD_FULL;
+    case EL_BD_MAGIC_WALL_DEAD:                return GFX_MAGIC_WALL_BD_DEAD;
+    case EL_DYNABOMB_PLAYER1_ACTIVE:   return GFX_DYNABOMB;
+    case EL_DYNABOMB_PLAYER2_ACTIVE:   return GFX_DYNABOMB;
+    case EL_DYNABOMB_PLAYER3_ACTIVE:   return GFX_DYNABOMB;
+    case EL_DYNABOMB_PLAYER4_ACTIVE:   return GFX_DYNABOMB;
+    case EL_DYNABOMB_NR:               return GFX_DYNABOMB_NR;
+    case EL_DYNABOMB_SZ:               return GFX_DYNABOMB_SZ;
+    case EL_DYNABOMB_XL:               return GFX_DYNABOMB_XL;
+    case EL_SOKOBAN_OBJECT:            return GFX_SOKOBAN_OBJEKT;
+    case EL_SOKOBAN_FIELD_EMPTY:       return GFX_SOKOBAN_FELD_LEER;
+    case EL_SOKOBAN_FIELD_FULL:                return GFX_SOKOBAN_FELD_VOLL;
+    case EL_MOLE:                      return GFX_MOLE;
+    case EL_PENGUIN:                   return GFX_PINGUIN;
+    case EL_PIG:                       return GFX_SCHWEIN;
+    case EL_DRAGON:                    return GFX_DRACHE;
+    case EL_SATELLITE:                 return GFX_SONDE;
+    case EL_ARROW_BLUE_LEFT:           return GFX_PFEIL_LEFT;
+    case EL_ARROW_BLUE_RIGHT:          return GFX_PFEIL_RIGHT;
+    case EL_ARROW_BLUE_UP:             return GFX_PFEIL_UP;
+    case EL_ARROW_BLUE_DOWN:           return GFX_PFEIL_DOWN;
+    case EL_SPEED_PILL:                        return GFX_SPEED_PILL;
+    case EL_SP_TERMINAL_ACTIVE:                return GFX_SP_TERMINAL;
+    case EL_SP_BUGGY_BASE_ACTIVE:      return GFX_SP_BUG_ACTIVE;
+    case EL_SP_ZONK:                   return GFX_SP_ZONK;
       /* ^^^^^^^^^^ non-standard position in supaplex graphic set! */
-    case EL_INVISIBLE_STEEL:   return GFX_INVISIBLE_STEEL;
-    case EL_BLACK_ORB:         return GFX_BLACK_ORB;
-    case EL_EM_GATE_1:         return GFX_EM_GATE_1;
-    case EL_EM_GATE_2:         return GFX_EM_GATE_2;
-    case EL_EM_GATE_3:         return GFX_EM_GATE_3;
-    case EL_EM_GATE_4:         return GFX_EM_GATE_4;
-    case EL_EM_GATE_1X:                return GFX_EM_GATE_1X;
-    case EL_EM_GATE_2X:                return GFX_EM_GATE_2X;
-    case EL_EM_GATE_3X:                return GFX_EM_GATE_3X;
-    case EL_EM_GATE_4X:                return GFX_EM_GATE_4X;
-    case EL_EM_KEY_1_FILE:     return GFX_EM_KEY_1;
-    case EL_EM_KEY_2_FILE:     return GFX_EM_KEY_2;
-    case EL_EM_KEY_3_FILE:     return GFX_EM_KEY_3;
-    case EL_EM_KEY_4_FILE:     return GFX_EM_KEY_4;
-    case EL_EM_KEY_1:          return GFX_EM_KEY_1;
-    case EL_EM_KEY_2:          return GFX_EM_KEY_2;
-    case EL_EM_KEY_3:          return GFX_EM_KEY_3;
-    case EL_EM_KEY_4:          return GFX_EM_KEY_4;
-    case EL_PEARL:             return GFX_PEARL;
-    case EL_CRYSTAL:           return GFX_CRYSTAL;
-    case EL_WALL_PEARL:                return GFX_WALL_PEARL;
-    case EL_WALL_CRYSTAL:      return GFX_WALL_CRYSTAL;
-    case EL_DOOR_WHITE:                return GFX_DOOR_WHITE;
-    case EL_DOOR_WHITE_GRAY:   return GFX_DOOR_WHITE_GRAY;
-    case EL_KEY_WHITE:         return GFX_KEY_WHITE;
-    case EL_SHIELD_PASSIVE:    return GFX_SHIELD_PASSIVE;
-    case EL_SHIELD_ACTIVE:     return GFX_SHIELD_ACTIVE;
-    case EL_EXTRA_TIME:                return GFX_EXTRA_TIME;
-    case EL_SWITCHGATE_OPEN:   return GFX_SWITCHGATE_OPEN;
-    case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED;
-    case EL_SWITCHGATE_SWITCH_1:return GFX_SWITCHGATE_SWITCH_1;
-    case EL_SWITCHGATE_SWITCH_2:return GFX_SWITCHGATE_SWITCH_2;
-    case EL_BELT1_LEFT:                return GFX_BELT1_LEFT;
-    case EL_BELT1_MIDDLE:      return GFX_BELT1_MIDDLE;
-    case EL_BELT1_RIGHT:       return GFX_BELT1_RIGHT;
-    case EL_BELT1_SWITCH_LEFT: return GFX_BELT1_SWITCH_LEFT;
-    case EL_BELT1_SWITCH_MIDDLE:return GFX_BELT1_SWITCH_MIDDLE;
-    case EL_BELT1_SWITCH_RIGHT:        return GFX_BELT1_SWITCH_RIGHT;
-    case EL_BELT2_LEFT:                return GFX_BELT2_LEFT;
-    case EL_BELT2_MIDDLE:      return GFX_BELT2_MIDDLE;
-    case EL_BELT2_RIGHT:       return GFX_BELT2_RIGHT;
-    case EL_BELT2_SWITCH_LEFT: return GFX_BELT2_SWITCH_LEFT;
-    case EL_BELT2_SWITCH_MIDDLE:return GFX_BELT2_SWITCH_MIDDLE;
-    case EL_BELT2_SWITCH_RIGHT:        return GFX_BELT2_SWITCH_RIGHT;
-    case EL_BELT3_LEFT:                return GFX_BELT3_LEFT;
-    case EL_BELT3_MIDDLE:      return GFX_BELT3_MIDDLE;
-    case EL_BELT3_RIGHT:       return GFX_BELT3_RIGHT;
-    case EL_BELT3_SWITCH_LEFT: return GFX_BELT3_SWITCH_LEFT;
-    case EL_BELT3_SWITCH_MIDDLE:return GFX_BELT3_SWITCH_MIDDLE;
-    case EL_BELT3_SWITCH_RIGHT:        return GFX_BELT3_SWITCH_RIGHT;
-    case EL_BELT4_LEFT:                return GFX_BELT4_LEFT;
-    case EL_BELT4_MIDDLE:      return GFX_BELT4_MIDDLE;
-    case EL_BELT4_RIGHT:       return GFX_BELT4_RIGHT;
-    case EL_BELT4_SWITCH_LEFT: return GFX_BELT4_SWITCH_LEFT;
-    case EL_BELT4_SWITCH_MIDDLE:return GFX_BELT4_SWITCH_MIDDLE;
-    case EL_BELT4_SWITCH_RIGHT:        return GFX_BELT4_SWITCH_RIGHT;
-    case EL_LANDMINE:          return GFX_LANDMINE;
-    case EL_ENVELOPE:          return GFX_ENVELOPE;
-    case EL_LIGHT_SWITCH_OFF:  return GFX_LIGHT_SWITCH_OFF;
-    case EL_LIGHT_SWITCH_ON:   return GFX_LIGHT_SWITCH_ON;
-    case EL_SIGN_EXCLAMATION:  return GFX_SIGN_EXCLAMATION;
-    case EL_SIGN_RADIOACTIVITY:        return GFX_SIGN_RADIOACTIVITY;
-    case EL_SIGN_STOP:         return GFX_SIGN_STOP;
-    case EL_SIGN_WHEELCHAIR:   return GFX_SIGN_WHEELCHAIR;
-    case EL_SIGN_PARKING:      return GFX_SIGN_PARKING;
-    case EL_SIGN_ONEWAY:       return GFX_SIGN_ONEWAY;
-    case EL_SIGN_HEART:                return GFX_SIGN_HEART;
-    case EL_SIGN_TRIANGLE:     return GFX_SIGN_TRIANGLE;
-    case EL_SIGN_ROUND:                return GFX_SIGN_ROUND;
-    case EL_SIGN_EXIT:         return GFX_SIGN_EXIT;
-    case EL_SIGN_YINYANG:      return GFX_SIGN_YINYANG;
-    case EL_SIGN_OTHER:                return GFX_SIGN_OTHER;
-    case EL_MOLE_LEFT:         return GFX_MOLE_LEFT;
-    case EL_MOLE_RIGHT:                return GFX_MOLE_RIGHT;
-    case EL_MOLE_UP:           return GFX_MOLE_UP;
-    case EL_MOLE_DOWN:         return GFX_MOLE_DOWN;
-    case EL_STEEL_SLANTED:     return GFX_STEEL_SLANTED;
-    case EL_SAND_INVISIBLE:    return GFX_SAND_INVISIBLE;
-    case EL_DX_UNKNOWN_15:     return GFX_DX_UNKNOWN_15;
-    case EL_DX_UNKNOWN_42:     return GFX_DX_UNKNOWN_42;
-    case EL_TIMEGATE_OPEN:     return GFX_TIMEGATE_OPEN;
-    case EL_TIMEGATE_CLOSED:   return GFX_TIMEGATE_CLOSED;
-    case EL_TIMEGATE_SWITCH_ON:        return GFX_TIMEGATE_SWITCH;
-    case EL_TIMEGATE_SWITCH_OFF:return GFX_TIMEGATE_SWITCH;
-    case EL_BALLOON:           return GFX_BALLOON;
-    case EL_BALLOON_SEND_LEFT: return GFX_BALLOON_SEND_LEFT;
-    case EL_BALLOON_SEND_RIGHT:        return GFX_BALLOON_SEND_RIGHT;
-    case EL_BALLOON_SEND_UP:   return GFX_BALLOON_SEND_UP;
-    case EL_BALLOON_SEND_DOWN: return GFX_BALLOON_SEND_DOWN;
-    case EL_BALLOON_SEND_ANY:  return GFX_BALLOON_SEND_ANY;
-    case EL_EMC_STEEL_WALL_1:  return GFX_EMC_STEEL_WALL_1;
-    case EL_EMC_STEEL_WALL_2:  return GFX_EMC_STEEL_WALL_2;
-    case EL_EMC_STEEL_WALL_3:  return GFX_EMC_STEEL_WALL_3;
-    case EL_EMC_STEEL_WALL_4:  return GFX_EMC_STEEL_WALL_4;
-    case EL_EMC_WALL_1:                return GFX_EMC_WALL_1;
-    case EL_EMC_WALL_2:                return GFX_EMC_WALL_2;
-    case EL_EMC_WALL_3:                return GFX_EMC_WALL_3;
-    case EL_EMC_WALL_4:                return GFX_EMC_WALL_4;
-    case EL_EMC_WALL_5:                return GFX_EMC_WALL_5;
-    case EL_EMC_WALL_6:                return GFX_EMC_WALL_6;
-    case EL_EMC_WALL_7:                return GFX_EMC_WALL_7;
-    case EL_EMC_WALL_8:                return GFX_EMC_WALL_8;
-    case EL_TUBE_CROSS:                return GFX_TUBE_CROSS;
-    case EL_TUBE_VERTICAL:     return GFX_TUBE_VERTICAL;
-    case EL_TUBE_HORIZONTAL:   return GFX_TUBE_HORIZONTAL;
-    case EL_TUBE_VERT_LEFT:    return GFX_TUBE_VERT_LEFT;
-    case EL_TUBE_VERT_RIGHT:   return GFX_TUBE_VERT_RIGHT;
-    case EL_TUBE_HORIZ_UP:     return GFX_TUBE_HORIZ_UP;
-    case EL_TUBE_HORIZ_DOWN:   return GFX_TUBE_HORIZ_DOWN;
-    case EL_TUBE_LEFT_UP:      return GFX_TUBE_LEFT_UP;
-    case EL_TUBE_LEFT_DOWN:    return GFX_TUBE_LEFT_DOWN;
-    case EL_TUBE_RIGHT_UP:     return GFX_TUBE_RIGHT_UP;
-    case EL_TUBE_RIGHT_DOWN:   return GFX_TUBE_RIGHT_DOWN;
-    case EL_SPRING:            return GFX_SPRING;
-    case EL_SPRING_MOVING:     return GFX_SPRING;
-    case EL_TRAP_INACTIVE:     return GFX_TRAP_INACTIVE;
-    case EL_TRAP_ACTIVE:       return GFX_TRAP_ACTIVE;
-    case EL_BD_WALL:           return GFX_BD_WALL;
-    case EL_BD_ROCK:           return GFX_BD_ROCK;
-    case EL_DX_SUPABOMB:       return GFX_DX_SUPABOMB;
-    case EL_SP_MURPHY_CLONE:   return GFX_SP_MURPHY_CLONE;
+    case EL_INVISIBLE_STEELWALL:       return GFX_INVISIBLE_STEEL;
+    case EL_INVISIBLE_STEELWALL_ACTIVE:        return GFX_INVISIBLE_STEEL_ON;
+    case EL_BLACK_ORB:                 return GFX_BLACK_ORB;
+    case EL_EM_GATE1:                  return GFX_EM_GATE_1;
+    case EL_EM_GATE2:                  return GFX_EM_GATE_2;
+    case EL_EM_GATE3:                  return GFX_EM_GATE_3;
+    case EL_EM_GATE4:                  return GFX_EM_GATE_4;
+    case EL_EM_GATE1_GRAY:             return GFX_EM_GATE_1X;
+    case EL_EM_GATE2_GRAY:             return GFX_EM_GATE_2X;
+    case EL_EM_GATE3_GRAY:             return GFX_EM_GATE_3X;
+    case EL_EM_GATE4_GRAY:             return GFX_EM_GATE_4X;
+    case EL_EM_KEY1_FILE:              return GFX_EM_KEY_1;
+    case EL_EM_KEY2_FILE:              return GFX_EM_KEY_2;
+    case EL_EM_KEY3_FILE:              return GFX_EM_KEY_3;
+    case EL_EM_KEY4_FILE:              return GFX_EM_KEY_4;
+    case EL_EM_KEY1:                   return GFX_EM_KEY_1;
+    case EL_EM_KEY2:                   return GFX_EM_KEY_2;
+    case EL_EM_KEY3:                   return GFX_EM_KEY_3;
+    case EL_EM_KEY4:                   return GFX_EM_KEY_4;
+    case EL_PEARL:                     return GFX_PEARL;
+    case EL_CRYSTAL:                   return GFX_CRYSTAL;
+    case EL_WALL_PEARL:                        return GFX_WALL_PEARL;
+    case EL_WALL_CRYSTAL:              return GFX_WALL_CRYSTAL;
+    case EL_DOOR_WHITE:                        return GFX_DOOR_WHITE;
+    case EL_DOOR_WHITE_GRAY:           return GFX_DOOR_WHITE_GRAY;
+    case EL_KEY_WHITE:                 return GFX_KEY_WHITE;
+    case EL_SHIELD_NORMAL:             return GFX_SHIELD_PASSIVE;
+    case EL_SHIELD_DEADLY:             return GFX_SHIELD_ACTIVE;
+    case EL_EXTRA_TIME:                        return GFX_EXTRA_TIME;
+    case EL_SWITCHGATE_OPEN:           return GFX_SWITCHGATE_OPEN;
+    case EL_SWITCHGATE_CLOSED:         return GFX_SWITCHGATE_CLOSED;
+    case EL_SWITCHGATE_SWITCH_UP:      return GFX_SWITCHGATE_SWITCH_1;
+    case EL_SWITCHGATE_SWITCH_DOWN:    return GFX_SWITCHGATE_SWITCH_2;
+    case EL_CONVEYOR_BELT1_LEFT:       return GFX_BELT1_LEFT;
+    case EL_CONVEYOR_BELT1_MIDDLE:     return GFX_BELT1_MIDDLE;
+    case EL_CONVEYOR_BELT1_RIGHT:      return GFX_BELT1_RIGHT;
+    case EL_CONVEYOR_BELT1_LEFT_ACTIVE:        return GFX_BELT1_LEFT;
+    case EL_CONVEYOR_BELT1_MIDDLE_ACTIVE:return GFX_BELT1_MIDDLE;
+    case EL_CONVEYOR_BELT1_RIGHT_ACTIVE:return GFX_BELT1_RIGHT;
+    case EL_CONVEYOR_BELT1_SWITCH_LEFT:        return GFX_BELT1_SWITCH_LEFT;
+    case EL_CONVEYOR_BELT1_SWITCH_MIDDLE:return GFX_BELT1_SWITCH_MIDDLE;
+    case EL_CONVEYOR_BELT1_SWITCH_RIGHT:return GFX_BELT1_SWITCH_RIGHT;
+    case EL_CONVEYOR_BELT2_LEFT:       return GFX_BELT2_LEFT;
+    case EL_CONVEYOR_BELT2_MIDDLE:     return GFX_BELT2_MIDDLE;
+    case EL_CONVEYOR_BELT2_RIGHT:      return GFX_BELT2_RIGHT;
+    case EL_CONVEYOR_BELT2_LEFT_ACTIVE:        return GFX_BELT2_LEFT;
+    case EL_CONVEYOR_BELT2_MIDDLE_ACTIVE:return GFX_BELT2_MIDDLE;
+    case EL_CONVEYOR_BELT2_RIGHT_ACTIVE:return GFX_BELT2_RIGHT;
+    case EL_CONVEYOR_BELT2_SWITCH_LEFT:        return GFX_BELT2_SWITCH_LEFT;
+    case EL_CONVEYOR_BELT2_SWITCH_MIDDLE:return GFX_BELT2_SWITCH_MIDDLE;
+    case EL_CONVEYOR_BELT2_SWITCH_RIGHT:return GFX_BELT2_SWITCH_RIGHT;
+    case EL_CONVEYOR_BELT3_LEFT:       return GFX_BELT3_LEFT;
+    case EL_CONVEYOR_BELT3_MIDDLE:     return GFX_BELT3_MIDDLE;
+    case EL_CONVEYOR_BELT3_RIGHT:      return GFX_BELT3_RIGHT;
+    case EL_CONVEYOR_BELT3_LEFT_ACTIVE:        return GFX_BELT3_LEFT;
+    case EL_CONVEYOR_BELT3_MIDDLE_ACTIVE:return GFX_BELT3_MIDDLE;
+    case EL_CONVEYOR_BELT3_RIGHT_ACTIVE:return GFX_BELT3_RIGHT;
+    case EL_CONVEYOR_BELT3_SWITCH_LEFT:        return GFX_BELT3_SWITCH_LEFT;
+    case EL_CONVEYOR_BELT3_SWITCH_MIDDLE:return GFX_BELT3_SWITCH_MIDDLE;
+    case EL_CONVEYOR_BELT3_SWITCH_RIGHT:return GFX_BELT3_SWITCH_RIGHT;
+    case EL_CONVEYOR_BELT4_LEFT:       return GFX_BELT4_LEFT;
+    case EL_CONVEYOR_BELT4_MIDDLE:     return GFX_BELT4_MIDDLE;
+    case EL_CONVEYOR_BELT4_RIGHT:      return GFX_BELT4_RIGHT;
+    case EL_CONVEYOR_BELT4_LEFT_ACTIVE:        return GFX_BELT4_LEFT;
+    case EL_CONVEYOR_BELT4_MIDDLE_ACTIVE:return GFX_BELT4_MIDDLE;
+    case EL_CONVEYOR_BELT4_RIGHT_ACTIVE:return GFX_BELT4_RIGHT;
+    case EL_CONVEYOR_BELT4_SWITCH_LEFT:        return GFX_BELT4_SWITCH_LEFT;
+    case EL_CONVEYOR_BELT4_SWITCH_MIDDLE:return GFX_BELT4_SWITCH_MIDDLE;
+    case EL_CONVEYOR_BELT4_SWITCH_RIGHT:return GFX_BELT4_SWITCH_RIGHT;
+    case EL_LANDMINE:                  return GFX_LANDMINE;
+    case EL_ENVELOPE:                  return GFX_ENVELOPE;
+    case EL_LIGHT_SWITCH:              return GFX_LIGHT_SWITCH_OFF;
+    case EL_LIGHT_SWITCH_ACTIVE:       return GFX_LIGHT_SWITCH_ON;
+    case EL_SIGN_EXCLAMATION:          return GFX_SIGN_EXCLAMATION;
+    case EL_SIGN_RADIOACTIVITY:                return GFX_SIGN_RADIOACTIVITY;
+    case EL_SIGN_STOP:                 return GFX_SIGN_STOP;
+    case EL_SIGN_WHEELCHAIR:           return GFX_SIGN_WHEELCHAIR;
+    case EL_SIGN_PARKING:              return GFX_SIGN_PARKING;
+    case EL_SIGN_ONEWAY:               return GFX_SIGN_ONEWAY;
+    case EL_SIGN_HEART:                        return GFX_SIGN_HEART;
+    case EL_SIGN_TRIANGLE:             return GFX_SIGN_TRIANGLE;
+    case EL_SIGN_ROUND:                        return GFX_SIGN_ROUND;
+    case EL_SIGN_EXIT:                 return GFX_SIGN_EXIT;
+    case EL_SIGN_YINYANG:              return GFX_SIGN_YINYANG;
+    case EL_SIGN_OTHER:                        return GFX_SIGN_OTHER;
+    case EL_MOLE_LEFT:                 return GFX_MOLE_LEFT;
+    case EL_MOLE_RIGHT:                        return GFX_MOLE_RIGHT;
+    case EL_MOLE_UP:                   return GFX_MOLE_UP;
+    case EL_MOLE_DOWN:                 return GFX_MOLE_DOWN;
+    case EL_STEELWALL_SLANTED:         return GFX_STEEL_SLANTED;
+    case EL_INVISIBLE_SAND:            return GFX_SAND_INVISIBLE;
+    case EL_INVISIBLE_SAND_ACTIVE:     return GFX_SAND_INVISIBLE_ON;
+    case EL_DX_UNKNOWN_15:             return GFX_DX_UNKNOWN_15;
+    case EL_DX_UNKNOWN_42:             return GFX_DX_UNKNOWN_42;
+    case EL_TIMEGATE_OPEN:             return GFX_TIMEGATE_OPEN;
+    case EL_TIMEGATE_CLOSED:           return GFX_TIMEGATE_CLOSED;
+    case EL_TIMEGATE_SWITCH_ACTIVE:    return GFX_TIMEGATE_SWITCH;
+    case EL_TIMEGATE_SWITCH:           return GFX_TIMEGATE_SWITCH;
+    case EL_BALLOON:                   return GFX_BALLOON;
+    case EL_BALLOON_SEND_LEFT:         return GFX_BALLOON_SEND_LEFT;
+    case EL_BALLOON_SEND_RIGHT:                return GFX_BALLOON_SEND_RIGHT;
+    case EL_BALLOON_SEND_UP:           return GFX_BALLOON_SEND_UP;
+    case EL_BALLOON_SEND_DOWN:         return GFX_BALLOON_SEND_DOWN;
+    case EL_BALLOON_SEND_ANY_DIRECTION:        return GFX_BALLOON_SEND_ANY;
+    case EL_EMC_STEELWALL1:            return GFX_EMC_STEEL_WALL_1;
+    case EL_EMC_STEELWALL2:            return GFX_EMC_STEEL_WALL_2;
+    case EL_EMC_STEELWALL3:            return GFX_EMC_STEEL_WALL_3;
+    case EL_EMC_STEELWALL4:            return GFX_EMC_STEEL_WALL_4;
+    case EL_EMC_WALL_PILLAR_UPPER:     return GFX_EMC_WALL_1;
+    case EL_EMC_WALL_PILLAR_MIDDLE:    return GFX_EMC_WALL_2;
+    case EL_EMC_WALL_PILLAR_LOWER:     return GFX_EMC_WALL_3;
+    case EL_EMC_WALL4:                 return GFX_EMC_WALL_4;
+    case EL_EMC_WALL5:                 return GFX_EMC_WALL_5;
+    case EL_EMC_WALL6:                 return GFX_EMC_WALL_6;
+    case EL_EMC_WALL7:                 return GFX_EMC_WALL_7;
+    case EL_EMC_WALL8:                 return GFX_EMC_WALL_8;
+    case EL_TUBE_ALL:                  return GFX_TUBE_CROSS;
+    case EL_TUBE_VERTICAL:             return GFX_TUBE_VERTICAL;
+    case EL_TUBE_HORIZONTAL:           return GFX_TUBE_HORIZONTAL;
+    case EL_TUBE_VERTICAL_LEFT:                return GFX_TUBE_VERT_LEFT;
+    case EL_TUBE_VERTICAL_RIGHT:       return GFX_TUBE_VERT_RIGHT;
+    case EL_TUBE_HORIZONTAL_UP:                return GFX_TUBE_HORIZ_UP;
+    case EL_TUBE_HORIZONTAL_DOWN:      return GFX_TUBE_HORIZ_DOWN;
+    case EL_TUBE_LEFT_UP:              return GFX_TUBE_LEFT_UP;
+    case EL_TUBE_LEFT_DOWN:            return GFX_TUBE_LEFT_DOWN;
+    case EL_TUBE_RIGHT_UP:             return GFX_TUBE_RIGHT_UP;
+    case EL_TUBE_RIGHT_DOWN:           return GFX_TUBE_RIGHT_DOWN;
+    case EL_SPRING:                    return GFX_SPRING;
+    case EL_TRAP:                      return GFX_TRAP_INACTIVE;
+    case EL_TRAP_ACTIVE:               return GFX_TRAP_ACTIVE;
+    case EL_BD_WALL:                   return GFX_BD_WALL;
+    case EL_BD_ROCK:                   return GFX_BD_ROCK;
+    case EL_DX_SUPABOMB:               return GFX_DX_SUPABOMB;
+    case EL_SP_MURPHY_CLONE:           return GFX_SP_MURPHY_CLONE;
 
     default:
     {
@@ -2704,3 +2915,76 @@ int el2gfx(int element)
     }
   }
 }
+
+int el2gfx(int element)
+{
+#if 1
+  int graphic_OLD = el2gfx_OLD(element);
+
+  return graphic_OLD;
+#else
+
+  int graphic_NEW = element_info[element].graphic[GFX_ACTION_DEFAULT];
+
+#if DEBUG
+  int graphic_OLD = el2gfx_OLD(element);
+
+  if (element >= MAX_ELEMENTS)
+  {
+    Error(ERR_WARN, "el2gfx: element == %d >= MAX_ELEMENTS", element);
+  }
+
+  if (graphic_NEW != graphic_OLD)
+  {
+    Error(ERR_WARN, "el2gfx: graphic_NEW (%d) != graphic_OLD (%d)",
+         graphic_NEW, graphic_OLD);
+  }
+#endif
+
+  return graphic_NEW;
+#endif
+}
+
+int el2img(int element)
+{
+  int graphic = element_info[element].graphic[GFX_ACTION_DEFAULT];
+
+#if DEBUG
+  if (graphic < 0)
+    Error(ERR_WARN, "element %d -> graphic %d -- probably crashing now...",
+         element, graphic);
+#endif
+
+  return graphic;
+}
+
+int el_dir2img(int element, int direction)
+{
+  return el_dir_act2img(element, direction, GFX_ACTION_DEFAULT);
+}
+
+int el_dir_act2img(int element, int direction, int action)
+{
+#if DEBUG
+  if (element < 0)
+  {    
+    printf("el_dir_act2img: THIS SHOULD NEVER HAPPEN: element == %d\n",
+          element);
+
+    return IMG_EMPTY;
+  }
+
+  if (action < 0)
+  {    
+    printf("el_dir_act2img: THIS SHOULD NEVER HAPPEN: action == %d\n",
+          action);
+
+    return IMG_EMPTY;
+  }
+#endif
+
+  action = graphics_action_mapping[action];
+  direction = MV_DIR_BIT(direction);
+
+  return element_info[element].direction_graphic[action][direction];
+}