rnd-20030111-2-src
[rocksndiamonds.git] / src / tools.c
index cfaa4ca2d93130fa1102e2a4fe16f2a357353f3c..354f196c48797f47612d8157fa2650029fa848c5 100644 (file)
@@ -32,7 +32,6 @@
 #define NUM_TOOL_BUTTONS       7
 
 /* forward declaration for internal use */
-static int getGraphicAnimationPhase(int, int, int);
 static void UnmapToolButtons();
 static void HandleToolButtons(struct GadgetInfo *);
 
@@ -280,7 +279,7 @@ void BackToFront()
       info1[0] = '\0';
 
     sprintf(text, "%.1f fps%s", global.frames_per_second, info1);
-    DrawTextExt(window, SX, SY, text, FS_SMALL, FC_YELLOW);
+    DrawTextExt(window, SX, SY, text, FS_SMALL, FC_YELLOW, FONT_OPAQUE);
   }
 
   FlushDisplay();
@@ -363,9 +362,32 @@ void FadeToFront()
   BackToFront();
 }
 
+void SetMainBackgroundImage(int graphic)
+{
+  SetMainBackgroundBitmap(graphic == IMG_UNDEFINED ? NULL :
+                         new_graphic_info[graphic].bitmap ?
+                         new_graphic_info[graphic].bitmap :
+                         new_graphic_info[IMG_BACKGROUND_DEFAULT].bitmap);
+}
+
+void SetDoorBackgroundImage(int graphic)
+{
+  SetDoorBackgroundBitmap(graphic == IMG_UNDEFINED ? NULL :
+                         new_graphic_info[graphic].bitmap ?
+                         new_graphic_info[graphic].bitmap :
+                         new_graphic_info[IMG_BACKGROUND_DEFAULT].bitmap);
+}
+
+void DrawBackground(int dest_x, int dest_y, int width, int height)
+{
+  ClearRectangleOnBackground(backbuffer, dest_x, dest_y, width, height);
+
+  redraw_mask |= REDRAW_FIELD;
+}
+
 void ClearWindow()
 {
-  ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
+  DrawBackground(REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
 
   if (setup.soft_scrolling && game_status == PLAYING)
   {
@@ -380,8 +402,6 @@ void ClearWindow()
     ClearRectangle(window, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
     SetDrawtoField(DRAW_DIRECT);
   }
-
-  redraw_mask |= REDRAW_FIELD;
 }
 
 void MarkTileDirty(int x, int y)
@@ -415,6 +435,75 @@ void SetBorderElement()
   }
 }
 
+static int getGraphicAnimationPhase(int frames, int delay, int mode)
+{
+  int phase;
+
+  if (mode & ANIM_PINGPONG)
+  {
+    int max_anim_frames = 2 * frames - 2;
+
+    phase = (FrameCounter % (delay * max_anim_frames)) / delay;
+    phase = (phase < frames ? phase : max_anim_frames - phase);
+  }
+  else
+    phase = (FrameCounter % (delay * frames)) / delay;
+
+  if (mode & ANIM_REVERSE)
+    phase = -phase;
+
+  return phase;
+}
+
+inline int getGraphicAnimationFrame(int graphic, int sync_frame)
+{
+  /* animation synchronized with global frame counter, not move position */
+  if (new_graphic_info[graphic].anim_global_sync || sync_frame < 0)
+    sync_frame = FrameCounter;
+
+  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);
+}
+
+inline void DrawGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y,
+                                   int graphic, int sync_frame, int mask_mode)
+{
+  int frame = getGraphicAnimationFrame(graphic, sync_frame);
+
+  if (mask_mode == USE_MASKING)
+    DrawGraphicThruMaskExt(dst_bitmap, x, y, graphic, frame);
+  else
+    DrawGraphicExt(dst_bitmap, x, y, graphic, frame);
+}
+
+inline boolean DrawGraphicAnimation(int x, int y, int graphic)
+{
+  int lx = LEVELX(x), ly = LEVELY(y);
+
+  if (!IN_SCR_FIELD(x, y) ||
+      (GfxFrame[lx][ly] % new_graphic_info[graphic].anim_delay) != 0)
+    return FALSE;
+
+  DrawGraphicAnimationExt(drawto_field, FX + x * TILEX, FY + y * TILEY,
+                         graphic, GfxFrame[lx][ly], NO_MASKING);
+  MarkTileDirty(x, y);
+
+  return TRUE;
+}
+
+boolean DrawLevelGraphicAnimation(int x, int y, int graphic)
+{
+  return DrawGraphicAnimation(SCREENX(x), SCREENY(y), graphic);
+}
+
+boolean DrawLevelElementAnimation(int x, int y, int element)
+{
+  return DrawGraphicAnimation(SCREENX(x), SCREENY(y), el2img(element));
+}
+
 void DrawAllPlayers()
 {
   int i;
@@ -625,9 +714,10 @@ void DrawPlayer(struct PlayerInfo *player)
   {
     int px = SCREENX(next_jx), py = SCREENY(next_jy);
 
-    if (element == EL_SOKOBAN_FIELD_EMPTY ||
-       Feld[next_jx][next_jy] == EL_SOKOBAN_FIELD_FULL)
-      DrawGraphicShiftedThruMask(px, py, sxx, syy, GFX_SOKOBAN_OBJEKT, 0,
+    if ((sxx || syy) &&
+       (element == EL_SOKOBAN_FIELD_EMPTY ||
+        Feld[next_jx][next_jy] == EL_SOKOBAN_FIELD_FULL))
+      DrawGraphicShiftedThruMask(px, py, sxx, syy, IMG_SOKOBAN_OBJECT, 0,
                                 NO_CUTTING);
     else
     {
@@ -637,9 +727,7 @@ void DrawPlayer(struct PlayerInfo *player)
       int frame = 0;
 #endif
 
-      if ((element == EL_ROCK ||
-          element == EL_BD_ROCK ||
-          element == EL_SP_ZONK) && sxx)
+      if ((sxx || syy) && IS_PUSHABLE(element))
       {
        graphic = el_dir_act2img(element, player->MovDir, GFX_ACTION_MOVING);
 #if 1
@@ -693,7 +781,7 @@ void DrawPlayer(struct PlayerInfo *player)
 #endif
 
     if (game.emulation == EMU_SUPAPLEX)
-      DrawGraphic(sx, sy, GFX_SP_DISK_RED, 0);
+      DrawGraphic(sx, sy, IMG_SP_DISK_RED, 0);
     else
       DrawGraphicThruMask(sx, sy, graphic, frame);
   }
@@ -705,7 +793,7 @@ void DrawPlayer(struct PlayerInfo *player)
                   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 phase = ExplodePhase[last_jx][last_jy] - 1;
     int frame = getGraphicAnimationFrame(graphic, phase - delay);
 
     if (phase >= delay)
@@ -736,104 +824,7 @@ void DrawPlayer(struct PlayerInfo *player)
   MarkTileDirty(sx,sy);
 }
 
-static int getGraphicAnimationPhase(int frames, int delay, int mode)
-{
-  int phase;
-
-  if (mode & ANIM_PINGPONG)
-  {
-    int max_anim_frames = 2 * frames - 2;
-
-    phase = (FrameCounter % (delay * max_anim_frames)) / delay;
-    phase = (phase < frames ? phase : max_anim_frames - phase);
-  }
-  else
-    phase = (FrameCounter % (delay * frames)) / delay;
-
-  if (mode & ANIM_REVERSE)
-    phase = -phase;
-
-  return phase;
-}
-
-int getGraphicAnimationFrame(int graphic, int sync_frame)
-{
-  int num_frames = new_graphic_info[graphic].anim_frames;
-  int delay = new_graphic_info[graphic].anim_delay;
-  int mode = new_graphic_info[graphic].anim_mode;
-  int frame = 0;
-
-  /* animation synchronized with global frame counter, not move position */
-  if (new_graphic_info[graphic].anim_global_sync || sync_frame < 0)
-    sync_frame = FrameCounter;
-
-  sync_frame += new_graphic_info[graphic].anim_start_frame * delay;
-
-  if (mode & ANIM_LOOP)                        /* normal, looping animation */
-  {
-    frame = (sync_frame % (delay * num_frames)) / delay;
-  }
-  else if (mode & ANIM_LINEAR)         /* normal, non-looping animation */
-  {
-    frame = sync_frame / delay;
-
-    if (frame > num_frames - 1)
-      frame = num_frames - 1;
-  }
-  else if (mode & ANIM_PINGPONG)       /* use border frames once */
-  {
-    int max_anim_frames = 2 * num_frames - 2;
-
-    frame = (sync_frame % (delay * max_anim_frames)) / delay;
-    frame = (frame < num_frames ? frame : max_anim_frames - frame);
-  }
-  else if (mode & ANIM_PINGPONG2)      /* use border frames twice */
-  {
-    int max_anim_frames = 2 * num_frames;
-
-    frame = (sync_frame % (delay * max_anim_frames)) / delay;
-    frame = (frame < num_frames ? frame : max_anim_frames - frame - 1);
-  }
-
-  if (mode & ANIM_REVERSE)             /* use reverse animation direction */
-    frame = num_frames - frame - 1;
-
-  return frame;
-}
-
-void DrawGraphicAnimationExt(int x, int y, int graphic, int mask_mode)
-{
-#if 0
-  int delay = new_graphic_info[graphic].anim_delay;
-
-  if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
-#else
-  if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
-#endif
-  {
-    int frame = getGraphicAnimationFrame(graphic, -1);
-
-    if (mask_mode == USE_MASKING)
-      DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic, frame);
-    else
-      DrawGraphic(SCREENX(x), SCREENY(y), graphic, frame);
-  }
-}
-
 #if 0
-void DrawOldGraphicAnimation(int x, int y, int graphic,
-                            int frames, int delay, int mode)
-{
-  DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, NO_MASKING);
-}
-#endif
-
-void DrawGraphicAnimation(int x, int y, int graphic)
-{
-  DrawGraphicAnimationExt(x, y, graphic, NO_MASKING);
-}
-
-#if 1
 void getOldGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
 {
   if (graphic >= 0 && graphic_info[graphic].bitmap != NULL)
@@ -922,7 +913,7 @@ void DrawGraphic(int x, int y, int graphic, int frame)
   MarkTileDirty(x, y);
 }
 
-#if 1
+#if 0
 void DrawOldGraphicExt(DrawBuffer *dst_bitmap, int x, int y, int graphic)
 {
   Bitmap *src_bitmap;
@@ -1012,6 +1003,17 @@ void getMiniGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
   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)
+  {
+    /* 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;
@@ -1319,7 +1321,11 @@ inline static int getFramePosition(int x, int y)
   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);
+
+  frame_pos = GfxFrame[x][y];
+
 #endif
 
   return frame_pos;
@@ -1338,6 +1344,12 @@ inline static int getGfxAction(int x, int y)
   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;
 }
 
@@ -1345,11 +1357,23 @@ 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 move_dir = MovDir[ux][uy];
-  int move_pos = getFramePosition(ux, uy);
-  int gfx_action = getGfxAction(ux, uy);
-  int graphic = el_dir_act2img(element, move_dir, gfx_action);
-  int frame = getGraphicAnimationFrame(graphic, move_pos);
+  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)
   {
@@ -1729,6 +1753,17 @@ void getMicroGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
   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;
@@ -1738,12 +1773,7 @@ void DrawMicroElement(int xpos, int ypos, int element)
 {
   Bitmap *src_bitmap;
   int src_x, src_y;
-  int graphic;
-
-  if (element == EL_EMPTY)
-    return;
-
-  graphic = el2img(element);
+  int graphic = el2img(element);
 
   getMicroGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
   BlitBitmap(src_bitmap, drawto, src_x, src_y, MICRO_TILEX, MICRO_TILEY,
@@ -1754,6 +1784,7 @@ void DrawLevel()
 {
   int x,y;
 
+  SetDrawBackgroundMask(REDRAW_NONE);
   ClearWindow();
 
   for(x=BX1; x<=BX2; x++)
@@ -1778,7 +1809,7 @@ static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
 {
   int x, y;
 
-  ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
+  DrawBackground(xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
 
   if (lev_fieldx < STD_LEV_FIELDX)
     xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
@@ -1797,7 +1828,8 @@ static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
       if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
        DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
                         Ur[lx][ly]);
-      else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
+      else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1
+              && BorderElement != EL_EMPTY)
        DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
                         BorderElement);
     }
@@ -1819,7 +1851,7 @@ static void DrawMicroLevelLabelExt(int mode)
 {
   char label_text[MAX_MICROLABEL_SIZE + 1];
 
-  ClearRectangle(drawto, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
+  DrawBackground(SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
 
   strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
                       mode == MICROLABEL_CREATED_BY ? "created by" :
@@ -1967,12 +1999,14 @@ boolean Request(char *text, unsigned int req_state)
   CloseDoor(DOOR_CLOSE_1);
 
   /* save old door content */
-  BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
+  BlitBitmap(bitmap_db_door, bitmap_db_door,
             DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
             DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
 
+  SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1);
+
   /* clear door drawing field */
-  ClearRectangle(drawto, DX, DY, DXSIZE, DYSIZE);
+  DrawBackground(DX, DY, DXSIZE, DYSIZE);
 
   /* write text for request */
   for(ty=0; ty < MAX_REQUEST_LINES; ty++)
@@ -2000,8 +2034,8 @@ boolean Request(char *text, unsigned int req_state)
     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);
+    DrawText(DX + 50 - (tl * 14)/2, DY + 8 + ty * 16,
+            text_line, FS_SMALL, FC_YELLOW);
 
     text += tl + (tc == ' ' ? 1 : 0);
   }
@@ -2024,7 +2058,7 @@ boolean Request(char *text, unsigned int req_state)
   }
 
   /* copy request gadgets to door backbuffer */
-  BlitBitmap(drawto, pix[PIX_DB_DOOR],
+  BlitBitmap(drawto, bitmap_db_door,
             DX, DY, DXSIZE, DYSIZE,
             DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
 
@@ -2035,7 +2069,11 @@ boolean Request(char *text, unsigned int req_state)
 #endif
 
   if (!(req_state & REQUEST_WAIT_FOR))
-    return(FALSE);
+  {
+    SetDrawBackgroundMask(REDRAW_FIELD);
+
+    return FALSE;
+  }
 
   if (game_status != MAINMENU)
     InitAnimation();
@@ -2044,6 +2082,8 @@ boolean Request(char *text, unsigned int req_state)
 
   request_gadget_id = -1;
 
+  SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1);
+
   while(result < 0)
   {
     if (PendingEvent())
@@ -2170,7 +2210,7 @@ boolean Request(char *text, unsigned int req_state)
 
     if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
     {
-      BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
+      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);
@@ -2179,6 +2219,8 @@ boolean Request(char *text, unsigned int req_state)
 
   RemapAllGadgets();
 
+  SetDrawBackgroundMask(REDRAW_FIELD);
+
 #if defined(PLATFORM_UNIX)
   /* continue network game after request */
   if (options.network &&
@@ -2187,7 +2229,7 @@ boolean Request(char *text, unsigned int req_state)
     SendToServer_ContinuePlaying();
 #endif
 
-  return(result);
+  return result;
 }
 
 unsigned int OpenDoor(unsigned int door_state)
@@ -2196,7 +2238,7 @@ unsigned int OpenDoor(unsigned int door_state)
 
   if (door_state & DOOR_COPY_BACK)
   {
-    BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
+    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;
@@ -2211,9 +2253,9 @@ unsigned int CloseDoor(unsigned int door_state)
 {
   unsigned int new_door_state;
 
-  BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
+  BlitBitmap(backbuffer, bitmap_db_door,
             DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
-  BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
+  BlitBitmap(backbuffer, bitmap_db_door,
             VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
 
   new_door_state = MoveDoor(door_state);
@@ -2265,10 +2307,17 @@ unsigned int MoveDoor(unsigned int door_state)
   {
     stepsize = 20;
     door_delay_value = 0;
+
     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))
@@ -2284,17 +2333,18 @@ unsigned int MoveDoor(unsigned int door_state)
 
     for(x=start; x<=DXSIZE; x+=stepsize)
     {
-      Bitmap *bitmap = pix[PIX_DOOR];
+      Bitmap *bitmap = new_graphic_info[IMG_GLOBAL_DOOR].bitmap;
       GC gc = bitmap->stored_clip_gc;
 
-      WaitUntilDelayReached(&door_delay, door_delay_value);
+      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;
 
-       BlitBitmap(pix[PIX_DB_DOOR], drawto,
+       BlitBitmap(bitmap_db_door, drawto,
                   DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
                   DXSIZE,DYSIZE - i/2, DX, DY);
 
@@ -2337,7 +2387,7 @@ unsigned int MoveDoor(unsigned int door_state)
        int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
        int j = (VXSIZE - i) / 3;
 
-       BlitBitmap(pix[PIX_DB_DOOR], drawto,
+       BlitBitmap(bitmap_db_door, drawto,
                   DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
                   VXSIZE, VYSIZE - i/2, VX, VY);
 
@@ -2389,8 +2439,12 @@ unsigned int MoveDoor(unsigned int door_state)
 void DrawSpecialEditorDoor()
 {
   /* draw bigger toolbox window */
-  BlitBitmap(pix[PIX_DOOR], drawto,
-            DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
+  BlitBitmap(new_graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
+            DOOR_GFX_PAGEX7, 0, EXSIZE + 8, 8,
+            EX - 4, EY - 12);
+  BlitBitmap(new_graphic_info[IMG_GLOBAL_BORDER].bitmap, drawto,
+            EX - 4, VY - 4, EXSIZE + 8, EYSIZE - VYSIZE + 4,
+            EX - 4, EY - 4);
 
   redraw_mask |= REDRAW_ALL;
 }
@@ -2398,8 +2452,9 @@ void DrawSpecialEditorDoor()
 void UndrawSpecialEditorDoor()
 {
   /* draw normal tape recorder window */
-  BlitBitmap(pix[PIX_BACK], drawto,
-            562, 344, 108, 56, EX - 4, EY - 12);
+  BlitBitmap(new_graphic_info[IMG_GLOBAL_BORDER].bitmap, drawto,
+            EX - 4, EY - 12, EXSIZE + 8, EYSIZE - VYSIZE + 12,
+            EX - 4, EY - 12);
 
   redraw_mask |= REDRAW_ALL;
 }
@@ -2527,7 +2582,7 @@ void CreateToolButtons()
 
   for (i=0; i<NUM_TOOL_BUTTONS; i++)
   {
-    Bitmap *gd_bitmap = pix[PIX_DOOR];
+    Bitmap *gd_bitmap = new_graphic_info[IMG_GLOBAL_DOOR].bitmap;
     Bitmap *deco_bitmap = None;
     int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
     struct GadgetInfo *gi;
@@ -2579,6 +2634,14 @@ void CreateToolButtons()
   }
 }
 
+void FreeToolButtons()
+{
+  int i;
+
+  for (i=0; i<NUM_TOOL_BUTTONS; i++)
+    FreeGadget(tool_gadget[i]);
+}
+
 static void UnmapToolButtons()
 {
   int i;
@@ -2916,9 +2979,9 @@ int el2gfx(int element)
 #if DEBUG
   int graphic_OLD = el2gfx_OLD(element);
 
-  if (element >= MAX_ELEMENTS)
+  if (element >= MAX_NUM_ELEMENTS)
   {
-    Error(ERR_WARN, "el2gfx: element == %d >= MAX_ELEMENTS", element);
+    Error(ERR_WARN, "el2gfx: element == %d >= MAX_NUM_ELEMENTS", element);
   }
 
   if (graphic_NEW != graphic_OLD)
@@ -2952,6 +3015,24 @@ int el_dir2img(int element, int direction)
 
 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);