added option to rotate newly created gray ball content for MM engine
[rocksndiamonds.git] / src / anim.c
index 7f6691f0fac1f6c82a4fc7909fa457c97b3b9175..b3c7dce23bff7c646ec67c12fb4e2d4b8b72cf0a 100644 (file)
@@ -124,7 +124,8 @@ struct GlobalAnimPartControlInfo
 
   unsigned int initial_anim_sync_frame;
   unsigned int anim_random_frame;
-  unsigned int step_delay, step_delay_value;
+
+  DelayCounter step_delay;
 
   int init_delay_counter;
   int anim_delay_counter;
@@ -410,7 +411,8 @@ static void InitToonControls(void)
     int sound = SND_UNDEFINED;
     int music = MUS_UNDEFINED;
     int graphic = IMG_TOON_1 + i;
-    int control = graphic;
+
+    control = graphic;
 
     part->nr = part_nr;
     part->anim_nr = anim_nr;
@@ -436,8 +438,8 @@ static void InitToonControls(void)
     part->initial_anim_sync_frame = 0;
     part->anim_random_frame = -1;
 
-    part->step_delay = 0;
-    part->step_delay_value = graphic_info[control].step_delay;
+    part->step_delay.count = 0;
+    part->step_delay.value = graphic_info[control].step_delay;
 
     part->state = ANIM_STATE_INACTIVE;
     part->last_anim_status = -1;
@@ -543,8 +545,8 @@ static void InitGlobalAnimControls(void)
        part->initial_anim_sync_frame = 0;
        part->anim_random_frame = -1;
 
-       part->step_delay = 0;
-       part->step_delay_value = graphic_info[control].step_delay;
+       part->step_delay.count = 0;
+       part->step_delay.value = graphic_info[control].step_delay;
 
        part->state = ANIM_STATE_INACTIVE;
        part->last_anim_status = -1;
@@ -634,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;
 
@@ -783,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))
@@ -803,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
@@ -846,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);
       }
     }
   }
@@ -1175,12 +1201,12 @@ static boolean isClickedPart(struct GlobalAnimPartControlInfo *part,
 
 static boolean clickBlocked(struct GlobalAnimPartControlInfo *part)
 {
-  return (part->control_info.style & STYLE_BLOCK ? TRUE : FALSE);
+  return ((part->control_info.style & STYLE_BLOCK) ? TRUE : FALSE);
 }
 
 static boolean clickConsumed(struct GlobalAnimPartControlInfo *part)
 {
-  return (part->control_info.style & STYLE_PASSTHROUGH ? FALSE : TRUE);
+  return ((part->control_info.style & STYLE_PASSTHROUGH) ? FALSE : TRUE);
 }
 
 static void InitGlobalAnim_Triggered(struct GlobalAnimPartControlInfo *part,
@@ -1313,7 +1339,8 @@ static int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part,
     part->anim_event_state = (c->anim_event != ANIM_EVENT_UNDEFINED);
 
     part->initial_anim_sync_frame =
-      (g->anim_global_sync ? 0 : anim_sync_frame + part->init_delay_counter);
+      (g->anim_global_sync || g->anim_global_anim_sync ? 0 :
+       anim_sync_frame + part->init_delay_counter);
 
     // do not re-initialize random animation frame after fade-in
     if (part->anim_random_frame == -1)
@@ -1531,8 +1558,7 @@ static int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part,
   // special case to prevent expiring loop sounds when playing
   PlayGlobalAnimSoundIfLoop(part);
 
-  if (!DelayReachedExt(&part->step_delay, part->step_delay_value,
-                      anim_sync_frame))
+  if (!DelayReachedExt(&part->step_delay, anim_sync_frame))
     return ANIM_STATE_RUNNING;
 
 #if 0
@@ -1981,3 +2007,8 @@ boolean HandleGlobalAnimClicks(int mx, int my, int button, boolean force_click)
 
   return click_consumed_current;
 }
+
+int getGlobalAnimSyncFrame(void)
+{
+  return anim_sync_frame;
+}