added support for x/y/width/height parameters for border/background images
[rocksndiamonds.git] / src / tools.c
index 7f448fdfc25df57f38c753c924afafc00d0e2c90..4ebf19bb15cc49e9e0a5f6a37937202d4ddc58dc 100644 (file)
@@ -1110,26 +1110,25 @@ static int getGlobalGameStatus(int status)
          status);
 }
 
-Bitmap *getBitmapFromGraphicOrDefault(int graphic, int default_graphic)
+int getImageFromGraphicOrDefault(int graphic, int default_graphic)
 {
   if (graphic == IMG_UNDEFINED)
-    return NULL;
+    return IMG_UNDEFINED;
 
   boolean redefined = getImageListEntryFromImageID(graphic)->redefined;
 
   return (graphic_info[graphic].bitmap != NULL || redefined ?
-         graphic_info[graphic].bitmap :
-         graphic_info[default_graphic].bitmap);
+         graphic : default_graphic);
 }
 
-static Bitmap *getBackgroundBitmap(int graphic)
+static int getBackgroundImage(int graphic)
 {
-  return getBitmapFromGraphicOrDefault(graphic, IMG_BACKGROUND);
+  return getImageFromGraphicOrDefault(graphic, IMG_BACKGROUND);
 }
 
-static Bitmap *getGlobalBorderBitmap(int graphic)
+static int getGlobalBorderImage(int graphic)
 {
-  return getBitmapFromGraphicOrDefault(graphic, IMG_GLOBAL_BORDER);
+  return getImageFromGraphicOrDefault(graphic, IMG_GLOBAL_BORDER);
 }
 
 Bitmap *getGlobalBorderBitmapFromStatus(int status_raw)
@@ -1141,51 +1140,66 @@ Bitmap *getGlobalBorderBitmapFromStatus(int status_raw)
      status == GAME_MODE_EDITOR  ? IMG_GLOBAL_BORDER_EDITOR :
      status == GAME_MODE_PLAYING ? IMG_GLOBAL_BORDER_PLAYING :
      IMG_GLOBAL_BORDER);
+  int graphic_final = getGlobalBorderImage(graphic);
 
-  return getGlobalBorderBitmap(graphic);
+  return graphic_info[graphic_final].bitmap;
+}
+
+void SetBackgroundImage(int graphic, int redraw_mask)
+{
+  struct GraphicInfo *g = &graphic_info[graphic];
+  struct GraphicInfo g_undefined = { 0 };
+
+  if (graphic == IMG_UNDEFINED)
+    g = &g_undefined;
+
+  // remove every mask before setting mask for window, and
+  // remove window area mask before setting mask for main or door area
+  int remove_mask = (redraw_mask == REDRAW_ALL ? 0xffff : REDRAW_ALL);
+
+  // (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!)
+  SetBackgroundBitmap(NULL, remove_mask, 0, 0, 0, 0);  // !!! FIX THIS !!!
+  SetBackgroundBitmap(g->bitmap, redraw_mask,
+                     g->src_x, g->src_y,
+                     g->width, g->height);
 }
 
 void SetWindowBackgroundImageIfDefined(int graphic)
 {
   if (graphic_info[graphic].bitmap)
-    SetWindowBackgroundBitmap(graphic_info[graphic].bitmap);
+    SetBackgroundImage(graphic, REDRAW_ALL);
 }
 
 void SetMainBackgroundImageIfDefined(int graphic)
 {
   if (graphic_info[graphic].bitmap)
-    SetMainBackgroundBitmap(graphic_info[graphic].bitmap);
+    SetBackgroundImage(graphic, REDRAW_FIELD);
 }
 
 void SetDoorBackgroundImageIfDefined(int graphic)
 {
   if (graphic_info[graphic].bitmap)
-    SetDoorBackgroundBitmap(graphic_info[graphic].bitmap);
+    SetBackgroundImage(graphic, REDRAW_DOOR_1);
 }
 
 void SetWindowBackgroundImage(int graphic)
 {
-  SetWindowBackgroundBitmap(getBackgroundBitmap(graphic));
+  SetBackgroundImage(getBackgroundImage(graphic), REDRAW_ALL);
 }
 
 void SetMainBackgroundImage(int graphic)
 {
-  SetMainBackgroundBitmap(getBackgroundBitmap(graphic));
+  SetBackgroundImage(getBackgroundImage(graphic), REDRAW_FIELD);
 }
 
 void SetDoorBackgroundImage(int graphic)
 {
-  SetDoorBackgroundBitmap(getBackgroundBitmap(graphic));
+  SetBackgroundImage(getBackgroundImage(graphic), REDRAW_DOOR_1);
 }
 
 void SetPanelBackground(void)
 {
-  struct GraphicInfo *gfx = &graphic_info[IMG_BACKGROUND_PANEL];
-
-  BlitBitmapTiled(gfx->bitmap, bitmap_db_panel, gfx->src_x, gfx->src_y,
-                 gfx->width, gfx->height, 0, 0, DXSIZE, DYSIZE);
-
-  SetDoorBackgroundBitmap(bitmap_db_panel);
+  SetDoorBackgroundImage(IMG_BACKGROUND_PANEL);
 }
 
 void DrawBackground(int x, int y, int width, int height)
@@ -2989,6 +3003,16 @@ void ShowEnvelope(int envelope_nr)
   BackToFront();
 }
 
+void ShowEnvelope_MM(int envelope_nr)
+{
+  BlitBitmap(backbuffer, bitmap_db_field, REAL_SX, REAL_SY,
+            FULL_SXSIZE, FULL_SYSIZE, REAL_SX, REAL_SY);
+
+  ShowEnvelope(envelope_nr);
+
+  SetDrawtoField(DRAW_TO_BACKBUFFER);
+}
+
 static void PrepareEnvelopeRequestToScreen(Bitmap *bitmap, int sx, int sy,
                                           int xsize, int ysize)
 {
@@ -4191,9 +4215,6 @@ static void DrawPlayerExt(struct PlayerInfo *player, int drawing_stage)
       DrawDynamite(last_jx, last_jy);
     else
       DrawLevelField(last_jx, last_jy);
-
-    if (player->is_pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
-      DrawLevelElement(next_jx, next_jy, EL_EMPTY);
   }
   else if (drawing_stage == DRAW_PLAYER_STAGE_FIELD_UNDER_PLAYER)
   {
@@ -4251,6 +4272,9 @@ static void DrawPlayerExt(struct PlayerInfo *player, int drawing_stage)
     if (!player->is_pushing || !player->is_moving)
       return;
 
+    if (Tile[next_jx][next_jy] == EL_EXPLOSION)
+      return;
+
     int gfx_frame = GfxFrame[jx][jy];
 
     if (!IS_MOVING(jx, jy))            // push movement already finished
@@ -4272,14 +4296,12 @@ static void DrawPlayerExt(struct PlayerInfo *player, int drawing_stage)
        DrawLevelElement(jx, jy, Back[jx][jy]);
       else
        DrawLevelElement(jx, jy, EL_EMPTY);
-
-      if (Back[next_jx][next_jy])
-       DrawLevelElement(next_jx, next_jy, Back[next_jx][next_jy]);
-      else
-       DrawLevelElement(next_jx, next_jy, EL_EMPTY);
     }
-    else if (Back[next_jx][next_jy])
+
+    if (Back[next_jx][next_jy])
       DrawLevelElement(next_jx, next_jy, Back[next_jx][next_jy]);
+    else
+      DrawLevelElement(next_jx, next_jy, EL_EMPTY);
 
     int px = SCREENX(jx), py = SCREENY(jy);
     int pxx = (TILEX - ABS(sxx)) * dx;
@@ -5896,7 +5918,8 @@ void CreateToolButtons(void)
       }
     }
 
-    if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
+    if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4 &&
+       pos->draw_player)
     {
       int player_nr = id - TOOL_CTRL_ID_PLAYER_1;
 
@@ -8323,6 +8346,11 @@ int el2img_mm(int element_mm)
   return el2img(map_element_MM_to_RND(element_mm));
 }
 
+int el_act2img_mm(int element_mm, int action)
+{
+  return el_act2img(map_element_MM_to_RND(element_mm), action);
+}
+
 int el_act_dir2img(int element, int action, int direction)
 {
   element = GFX_ELEMENT(element);
@@ -9423,6 +9451,17 @@ int getGraphicInfo_Delay(int graphic)
   return graphic_info[graphic].anim_delay;
 }
 
+boolean getGraphicInfo_NewFrame(int x, int y, int graphic)
+{
+  if (!IS_NEW_FRAME(GfxFrame[x][y], graphic))
+    return FALSE;
+
+  if (ANIM_MODE(graphic) & (ANIM_TILED | ANIM_RANDOM_STATIC))
+    return FALSE;
+
+  return TRUE;
+}
+
 void PlayMenuSoundExt(int sound)
 {
   if (sound == SND_UNDEFINED)