changed sound effect "game.losing" to be undefined by default
[rocksndiamonds.git] / src / anim.c
index 50075c832ab8b42b4993c7c8fa7f7871aeac831c..2f0278ef19360c83630208261d9cc28a3b107c30 100644 (file)
@@ -636,11 +636,77 @@ void InitGlobalAnimations(void)
   InitGlobalAnimControls();
 }
 
-static void DrawGlobalAnimationsExt(int drawing_target, int drawing_stage)
+static void BlitGlobalAnimation(struct GlobalAnimPartControlInfo *part,
+                               Bitmap *src_bitmap, int src_x0, int src_y0,
+                               int drawing_target)
 {
+  struct GraphicInfo *g = &part->graphic_info;
+  struct GraphicInfo *c = &part->control_info;
+  void (*blit_bitmap)(Bitmap *, Bitmap *, int, int, int, int, int, int) =
+    (g->draw_masked ? BlitBitmapMasked : BlitBitmap);
+  void (*blit_screen)(Bitmap *, int, int, int, int, int, int) =
+    (g->draw_masked ? BlitToScreenMasked : BlitToScreen);
   Bitmap *fade_bitmap =
     (drawing_target == DRAW_TO_FADE_SOURCE ? gfx.fade_bitmap_source :
      drawing_target == DRAW_TO_FADE_TARGET ? gfx.fade_bitmap_target : NULL);
+  int x, y;
+
+  for (y = 0; y < c->stacked_yfactor; y++)
+  {
+    for (x = 0; x < c->stacked_xfactor; x++)
+    {
+      int src_x = src_x0;
+      int src_y = src_y0;
+      int dst_x = part->x + x * (g->width  + c->stacked_xoffset);
+      int dst_y = part->y + y * (g->height + c->stacked_yoffset);
+      int cut_x = 0;
+      int cut_y = 0;
+      int width  = g->width;
+      int height = g->height;
+
+      if (dst_x < 0)
+      {
+       width += dst_x;
+       cut_x = -dst_x;
+       dst_x = 0;
+      }
+      else if (dst_x > part->viewport_width - g->width)
+      {
+       width -= (dst_x - (part->viewport_width - g->width));
+      }
+
+      if (dst_y < 0)
+      {
+       height += dst_y;
+       cut_y  = -dst_y;
+       dst_y = 0;
+      }
+      else if (dst_y > part->viewport_height - g->height)
+      {
+       height -= (dst_y - (part->viewport_height - g->height));
+      }
+
+      if (width <= 0 || height <= 0)
+       continue;
+
+      src_x += cut_x;
+      src_y += cut_y;
+
+      dst_x += part->viewport_x;
+      dst_y += part->viewport_y;
+
+      if (drawing_target == DRAW_TO_SCREEN)
+       blit_screen(src_bitmap, src_x, src_y, width, height,
+                   dst_x, dst_y);
+      else
+       blit_bitmap(src_bitmap, fade_bitmap, src_x, src_y, width, height,
+                   dst_x, dst_y);
+    }
+  }
+}
+
+static void DrawGlobalAnimationsExt(int drawing_target, int drawing_stage)
+{
   int game_mode_anim_action[NUM_GAME_MODES];
   int mode_nr;
 
@@ -785,18 +851,8 @@ static void DrawGlobalAnimationsExt(int drawing_target, int drawing_stage)
        struct GraphicInfo *g = &part->graphic_info;
        Bitmap *src_bitmap;
        int src_x, src_y;
-       int width  = g->width;
-       int height = g->height;
-       int dst_x = part->x;
-       int dst_y = part->y;
-       int cut_x = 0;
-       int cut_y = 0;
        int sync_frame;
        int frame;
-       void (*blit_bitmap)(Bitmap *, Bitmap *, int, int, int, int, int, int) =
-         (g->draw_masked ? BlitBitmapMasked : BlitBitmap);
-       void (*blit_screen)(Bitmap *, int, int, int, int, int, int) =
-         (g->draw_masked ? BlitToScreenMasked : BlitToScreen);
        int last_anim_random_frame = gfx.anim_random_frame;
 
        if (!(part->state & ANIM_STATE_RUNNING))
@@ -805,30 +861,6 @@ static void DrawGlobalAnimationsExt(int drawing_target, int drawing_stage)
        if (part->drawing_stage != drawing_stage)
          continue;
 
-       if (part->x < 0)
-       {
-         dst_x = 0;
-         width += part->x;
-         cut_x = -part->x;
-       }
-       else if (part->x > part->viewport_width - g->width)
-         width -= (part->x - (part->viewport_width - g->width));
-
-       if (part->y < 0)
-       {
-         dst_y = 0;
-         height += part->y;
-         cut_y = -part->y;
-       }
-       else if (part->y > part->viewport_height - g->height)
-         height -= (part->y - (part->viewport_height - g->height));
-
-       if (width <= 0 || height <= 0)
-         continue;
-
-       dst_x += part->viewport_x;
-       dst_y += part->viewport_y;
-
        sync_frame = anim_sync_frame - part->initial_anim_sync_frame;
 
        // re-initialize random animation frame after animation delay
@@ -848,15 +880,7 @@ static void DrawGlobalAnimationsExt(int drawing_target, int drawing_stage)
        getGlobalAnimGraphicSource(part->graphic, frame, &src_bitmap,
                                   &src_x, &src_y);
 
-       src_x += cut_x;
-       src_y += cut_y;
-
-       if (drawing_target == DRAW_TO_SCREEN)
-         blit_screen(src_bitmap, src_x, src_y, width, height,
-                     dst_x, dst_y);
-       else
-         blit_bitmap(src_bitmap, fade_bitmap, src_x, src_y, width, height,
-                     dst_x, dst_y);
+       BlitGlobalAnimation(part, src_bitmap, src_x, src_y, drawing_target);
       }
     }
   }
@@ -1145,34 +1169,54 @@ static boolean isClickablePart(struct GlobalAnimPartControlInfo *part, int mask)
   return FALSE;
 }
 
-static boolean isClickedPart(struct GlobalAnimPartControlInfo *part,
-                            int mx, int my, boolean clicked)
+static boolean isInsidePartStacked(struct GlobalAnimPartControlInfo *part,
+                                  int mx, int my)
 {
   struct GraphicInfo *g = &part->graphic_info;
+  struct GraphicInfo *c = &part->control_info;
   int part_x = part->viewport_x + part->x;
   int part_y = part->viewport_y + part->y;
   int part_width  = g->width;
   int part_height = g->height;
+  int x, y;
+
+  for (y = 0; y < c->stacked_yfactor; y++)
+  {
+    for (x = 0; x < c->stacked_xfactor; x++)
+    {
+      int part_stacked_x = part_x + x * (part_width  + c->stacked_xoffset);
+      int part_stacked_y = part_y + y * (part_height + c->stacked_yoffset);
+
+      if (mx >= part_stacked_x &&
+         mx <  part_stacked_x + part_width &&
+         my >= part_stacked_y &&
+         my <  part_stacked_y + part_height)
+       return TRUE;
+    }
+  }
 
+  return FALSE;
+}
+
+static boolean isClickedPart(struct GlobalAnimPartControlInfo *part,
+                            int mx, int my, boolean clicked)
+{
   // check if mouse click was detected at all
   if (!clicked)
     return FALSE;
 
-  // check if mouse click is inside the animation part's viewport
+  // check if mouse click is outside the animation part's viewport
   if (mx <  part->viewport_x ||
       mx >= part->viewport_x + part->viewport_width ||
       my <  part->viewport_y ||
       my >= part->viewport_y + part->viewport_height)
     return FALSE;
 
-  // check if mouse click is inside the animation part's graphic
-  if (mx <  part_x ||
-      mx >= part_x + part_width ||
-      my <  part_y ||
-      my >= part_y + part_height)
-    return FALSE;
+  // check if mouse click is inside the animation part's (stacked) graphic
+  if (isInsidePartStacked(part, mx, my))
+    return TRUE;
 
-  return TRUE;
+  return FALSE;
 }
 
 static boolean clickBlocked(struct GlobalAnimPartControlInfo *part)
@@ -1953,6 +1997,18 @@ static void ResetGlobalAnim_Clicked(void)
   InitGlobalAnim_Clicked(-1, -1, ANIM_CLICKED_RESET);
 }
 
+void RestartGlobalAnimsByStatus(int status)
+{
+  int anim_status_last = global.anim_status;
+
+  global.anim_status = status;
+
+  // force restarting global animations by changed global animation status
+  SDLRedrawWindow();
+
+  global.anim_status = anim_status_last;
+}
+
 boolean HandleGlobalAnimClicks(int mx, int my, int button, boolean force_click)
 {
   static boolean click_consumed = FALSE;