added support for x/y/width/height parameters for border/background images
[rocksndiamonds.git] / src / tools.c
index 627c77c61f842840eefe6ca162e4482776df9728..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)
@@ -1492,6 +1506,8 @@ int getGraphicAnimationFrame(int graphic, int sync_frame)
   // animation synchronized with global frame counter, not move position
   if (graphic_info[graphic].anim_global_sync || sync_frame < 0)
     sync_frame = FrameCounter;
+  else if (graphic_info[graphic].anim_global_anim_sync)
+    sync_frame = getGlobalAnimSyncFrame();
 
   return getAnimationFrame(graphic_info[graphic].anim_frames,
                           graphic_info[graphic].anim_delay,
@@ -2987,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)
 {
@@ -4189,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)
   {
@@ -4249,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
@@ -4270,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;
@@ -5894,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;
 
@@ -8203,10 +8228,6 @@ int map_element_RND_to_MM(int element_rnd)
          element_rnd <= EL_MM_RUNTIME_END ?
          EL_MM_RUNTIME_START_NATIVE + element_rnd - EL_MM_RUNTIME_START :
 
-         element_rnd >= EL_MM_DUMMY_START &&
-         element_rnd <= EL_MM_DUMMY_END ?
-         EL_MM_DUMMY_START_NATIVE + element_rnd - EL_MM_DUMMY_START :
-
          EL_MM_EMPTY_NATIVE);
 }
 
@@ -8232,10 +8253,6 @@ int map_element_MM_to_RND(int element_mm)
          element_mm <= EL_MM_RUNTIME_END_NATIVE ?
          EL_MM_RUNTIME_START + element_mm - EL_MM_RUNTIME_START_NATIVE :
 
-         element_mm >= EL_MM_DUMMY_START_NATIVE &&
-         element_mm <= EL_MM_DUMMY_END_NATIVE ?
-         EL_MM_DUMMY_START + element_mm - EL_MM_DUMMY_START_NATIVE :
-
          EL_EMPTY);
 }
 
@@ -8329,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);
@@ -8786,6 +8808,8 @@ void SetGfxAnimation_EM(struct GraphicInfo_EM *g_em,
 
   if (graphic_info[graphic].anim_global_sync)
     sync_frame = FrameCounter;
+  else if (graphic_info[graphic].anim_global_anim_sync)
+    sync_frame = getGlobalAnimSyncFrame();
   else if (IN_FIELD(x, y, MAX_LEV_FIELDX, MAX_LEV_FIELDY))
     sync_frame = GfxFrame[x][y];
   else
@@ -8845,6 +8869,8 @@ void getGraphicSourceObjectExt_EM(struct GraphicInfo_EM *g_em,
 
   if (graphic_info[graphic].anim_global_sync)
     sync_frame = FrameCounter;
+  else if (graphic_info[graphic].anim_global_anim_sync)
+    sync_frame = getGlobalAnimSyncFrame();
   else if (IN_FIELD(x, y, MAX_LEV_FIELDX, MAX_LEV_FIELDY))
     sync_frame = GfxFrame[x][y];
   else
@@ -9308,7 +9334,7 @@ void InitGraphicInfo_EM(void)
   }
 }
 
-static void CheckSaveEngineSnapshot_EM(byte action[MAX_PLAYERS], int frame,
+static void CheckSaveEngineSnapshot_EM(int frame,
                                       boolean any_player_moving,
                                       boolean any_player_snapping,
                                       boolean any_player_dropping)
@@ -9365,7 +9391,7 @@ static void CheckSaveEngineSnapshot_MM(boolean element_clicked,
   }
 }
 
-boolean CheckSingleStepMode_EM(byte action[MAX_PLAYERS], int frame,
+boolean CheckSingleStepMode_EM(int frame,
                               boolean any_player_moving,
                               boolean any_player_snapping,
                               boolean any_player_dropping)
@@ -9374,7 +9400,7 @@ boolean CheckSingleStepMode_EM(byte action[MAX_PLAYERS], int frame,
     if (frame == 7 && !any_player_dropping && FrameCounter > 6)
       TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
 
-  CheckSaveEngineSnapshot_EM(action, frame, any_player_moving,
+  CheckSaveEngineSnapshot_EM(frame, any_player_moving,
                             any_player_snapping, any_player_dropping);
 
   return tape.pausing;
@@ -9408,7 +9434,7 @@ void CheckSingleStepMode_MM(boolean element_clicked,
 }
 
 void getGraphicSource_SP(struct GraphicInfo_SP *g_sp,
-                        int graphic, int sync_frame, int x, int y)
+                        int graphic, int sync_frame)
 {
   int frame = getGraphicAnimationFrame(graphic, sync_frame);
 
@@ -9425,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)