rnd-20030105-1-src
[rocksndiamonds.git] / src / tools.c
index e241c79adb289bdb3fe69614687019ebf79a8aed..ecc1e12780d289c39c2c1b98333561249a889c6c 100644 (file)
@@ -279,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();
@@ -362,9 +362,39 @@ void FadeToFront()
   BackToFront();
 }
 
+void DrawBackground(int x, int y, int width, int height)
+{
+  /* some sanity checks */
+  if (x < REAL_SX)
+  {
+    width -= (REAL_SX - x);
+    x = REAL_SX;
+  }
+
+  if (y < REAL_SY)
+  {
+    height -= (REAL_SY - y);
+    y = REAL_SY;
+  }
+
+  if (width > FULL_SXSIZE)
+    width = FULL_SXSIZE;
+
+  if (height > FULL_SYSIZE)
+    height = FULL_SYSIZE;
+
+  if (DrawingOnBackground(x, y) && game_status != PLAYING)
+    BlitBitmap(gfx.background_bitmap, backbuffer, x - REAL_SX, y - REAL_SY,
+              width, height, x, y);
+  else
+    ClearRectangle(backbuffer, x, 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)
   {
@@ -379,8 +409,6 @@ void ClearWindow()
     ClearRectangle(window, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
     SetDrawtoField(DRAW_DIRECT);
   }
-
-  redraw_mask |= REDRAW_FIELD;
 }
 
 static int getGraphicAnimationPhase(int frames, int delay, int mode)
@@ -669,9 +697,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 && IS_PUSHABLE(element))
       {
        graphic = el_dir_act2img(element, player->MovDir, GFX_ACTION_MOVING);
 #if 1
@@ -790,7 +816,7 @@ void DrawGraphicAnimation(int x, int y, int graphic)
   MarkTileDirty(x, y);
 }
 
-#if 1
+#if 0
 void getOldGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
 {
   if (graphic >= 0 && graphic_info[graphic].bitmap != NULL)
@@ -1306,6 +1332,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;
 }
 
@@ -1313,11 +1345,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)
   {
@@ -1717,12 +1761,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,
@@ -1757,7 +1796,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;
@@ -1776,7 +1815,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);
     }
@@ -1798,7 +1838,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" :
@@ -1980,7 +2020,7 @@ boolean Request(char *text, unsigned int req_state)
     text_line[tl] = 0;
 
     DrawTextExt(drawto, DX + 50 - (tl * 14)/2, DY + 8 + ty * 16,
-               text_line, FS_SMALL, FC_YELLOW);
+               text_line, FS_SMALL, FC_YELLOW, FONT_OPAQUE);
 
     text += tl + (tc == ' ' ? 1 : 0);
   }
@@ -2244,10 +2284,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))
@@ -2266,7 +2313,8 @@ unsigned int MoveDoor(unsigned int door_state)
       Bitmap *bitmap = new_graphic_info[IMG_MENU_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)
       {
@@ -2369,7 +2417,11 @@ void DrawSpecialEditorDoor()
 {
   /* draw bigger toolbox window */
   BlitBitmap(new_graphic_info[IMG_MENU_DOOR].bitmap, drawto,
-            DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
+            DOOR_GFX_PAGEX7, 0, EXSIZE + 8, 8,
+            EX - 4, EY - 12);
+  BlitBitmap(new_graphic_info[IMG_MENU_FRAME].bitmap, drawto,
+            EX - 4, VY - 4, EXSIZE + 8, EYSIZE - VYSIZE + 4,
+            EX - 4, EY - 4);
 
   redraw_mask |= REDRAW_ALL;
 }
@@ -2377,8 +2429,9 @@ void DrawSpecialEditorDoor()
 void UndrawSpecialEditorDoor()
 {
   /* draw normal tape recorder window */
-  BlitBitmap(new_graphic_info[IMG_MENU_BACK].bitmap, drawto,
-            562, 344, 108, 56, EX - 4, EY - 12);
+  BlitBitmap(new_graphic_info[IMG_MENU_FRAME].bitmap, drawto,
+            EX - 4, EY - 12, EXSIZE + 8, EYSIZE - VYSIZE + 12,
+            EX - 4, EY - 12);
 
   redraw_mask |= REDRAW_ALL;
 }
@@ -2558,6 +2611,14 @@ void CreateToolButtons()
   }
 }
 
+void FreeToolButtons()
+{
+  int i;
+
+  for (i=0; i<NUM_TOOL_BUTTONS; i++)
+    FreeGadget(tool_gadget[i]);
+}
+
 static void UnmapToolButtons()
 {
   int i;
@@ -2931,6 +2992,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);