1 // ============================================================================
2 // Rocks'n'Diamonds - McDuffin Strikes Back!
3 // ----------------------------------------------------------------------------
4 // (c) 1995-2014 by Artsoft Entertainment
7 // http://www.artsoft.org/
8 // ----------------------------------------------------------------------------
10 // ============================================================================
17 /* values for global toon animation definition */
18 #define NUM_GLOBAL_TOON_ANIMS 1
19 #define NUM_GLOBAL_TOON_PARTS MAX_NUM_TOONS
21 /* values for global animation definition (including toons) */
22 #define NUM_GLOBAL_ANIMS_AND_TOONS (NUM_GLOBAL_ANIMS + \
23 NUM_GLOBAL_TOON_ANIMS)
24 #define NUM_GLOBAL_ANIM_PARTS_AND_TOONS MAX(NUM_GLOBAL_ANIM_PARTS_ALL, \
25 NUM_GLOBAL_TOON_PARTS)
27 #define ANIM_CLASS_BIT_TITLE_INITIAL 0
28 #define ANIM_CLASS_BIT_TITLE 1
29 #define ANIM_CLASS_BIT_SUBMENU 2
30 #define ANIM_CLASS_BIT_MENU 3
31 #define ANIM_CLASS_BIT_TOONS 4
33 #define NUM_ANIM_CLASSES 5
35 #define ANIM_CLASS_NONE 0
36 #define ANIM_CLASS_TITLE_INITIAL (1 << ANIM_CLASS_BIT_TITLE_INITIAL)
37 #define ANIM_CLASS_TITLE (1 << ANIM_CLASS_BIT_TITLE)
38 #define ANIM_CLASS_SUBMENU (1 << ANIM_CLASS_BIT_SUBMENU)
39 #define ANIM_CLASS_MENU (1 << ANIM_CLASS_BIT_MENU)
40 #define ANIM_CLASS_TOONS (1 << ANIM_CLASS_BIT_TOONS)
42 #define ANIM_CLASS_TOONS_MENU (ANIM_CLASS_TOONS | \
45 #define ANIM_CLASS_TOONS_MENU_SUBMENU (ANIM_CLASS_TOONS | \
49 struct GlobalAnimPartControlInfo
56 struct GraphicInfo graphic_info;
57 struct GraphicInfo control_info;
65 int step_xoffset, step_yoffset;
67 unsigned int initial_anim_sync_frame;
68 unsigned int step_delay, step_delay_value;
70 int init_delay_counter;
71 int anim_delay_counter;
72 int post_delay_counter;
80 struct GlobalAnimMainControlInfo
82 struct GlobalAnimPartControlInfo base;
83 struct GlobalAnimPartControlInfo part[NUM_GLOBAL_ANIM_PARTS_AND_TOONS];
88 struct GraphicInfo control_info;
96 int init_delay_counter;
100 int last_state, last_active_part_nr;
103 struct GlobalAnimControlInfo
105 struct GlobalAnimMainControlInfo anim[NUM_GLOBAL_ANIMS_AND_TOONS];
111 struct GameModeAnimClass
115 } game_mode_anim_classes_list[] =
117 { GAME_MODE_TITLE_INITIAL_1, ANIM_CLASS_TITLE_INITIAL },
118 { GAME_MODE_TITLE_INITIAL_2, ANIM_CLASS_TITLE_INITIAL },
119 { GAME_MODE_TITLE_INITIAL_3, ANIM_CLASS_TITLE_INITIAL },
120 { GAME_MODE_TITLE_INITIAL_4, ANIM_CLASS_TITLE_INITIAL },
121 { GAME_MODE_TITLE_INITIAL_5, ANIM_CLASS_TITLE_INITIAL },
122 { GAME_MODE_TITLE_1, ANIM_CLASS_TITLE },
123 { GAME_MODE_TITLE_2, ANIM_CLASS_TITLE },
124 { GAME_MODE_TITLE_3, ANIM_CLASS_TITLE },
125 { GAME_MODE_TITLE_4, ANIM_CLASS_TITLE },
126 { GAME_MODE_TITLE_5, ANIM_CLASS_TITLE },
127 { GAME_MODE_LEVELS, ANIM_CLASS_TOONS_MENU_SUBMENU },
128 { GAME_MODE_LEVELNR, ANIM_CLASS_TOONS_MENU_SUBMENU },
129 { GAME_MODE_INFO, ANIM_CLASS_TOONS_MENU_SUBMENU },
130 { GAME_MODE_SETUP, ANIM_CLASS_TOONS_MENU_SUBMENU },
131 { GAME_MODE_MAIN, ANIM_CLASS_TOONS_MENU },
132 { GAME_MODE_SCORES, ANIM_CLASS_TOONS },
137 struct AnimClassGameMode
141 } anim_class_game_modes_list[] =
143 { ANIM_CLASS_BIT_TITLE_INITIAL, GAME_MODE_TITLE_INITIAL },
144 { ANIM_CLASS_BIT_TITLE, GAME_MODE_TITLE },
145 { ANIM_CLASS_BIT_SUBMENU, GAME_MODE_PSEUDO_SUBMENU },
146 { ANIM_CLASS_BIT_MENU, GAME_MODE_PSEUDO_MENU },
147 { ANIM_CLASS_BIT_TOONS, GAME_MODE_PSEUDO_TOONS },
152 /* forward declaration for internal use */
153 static void HandleGlobalAnim(int, int);
154 static void DoAnimationExt(void);
156 static struct GlobalAnimControlInfo global_anim_ctrl[NUM_GAME_MODES];
157 static struct ToonInfo toons[MAX_NUM_TOONS];
159 static unsigned int anim_sync_frame = 0;
160 static unsigned int anim_sync_frame_delay = 0;
161 static unsigned int anim_sync_frame_delay_value = GAME_FRAME_DELAY;
163 static int game_mode_anim_classes[NUM_GAME_MODES];
164 static int anim_class_game_modes[NUM_ANIM_CLASSES];
166 static int anim_status_last = GAME_MODE_DEFAULT;
167 static int anim_classes_last = ANIM_CLASS_NONE;
170 static int getGlobalAnimationPart(struct GlobalAnimMainControlInfo *anim)
172 struct GraphicInfo *c = &anim->control_info;
173 int last_anim_random_frame = gfx.anim_random_frame;
176 gfx.anim_random_frame = -1; // (use simple, ad-hoc random numbers)
178 part_nr = getAnimationFrame(anim->num_parts, 1,
179 c->anim_mode, c->anim_start_frame,
182 gfx.anim_random_frame = last_anim_random_frame;
187 static int compareGlobalAnimPartControlInfo(const void *obj1, const void *obj2)
189 const struct GlobalAnimPartControlInfo *o1 =
190 (struct GlobalAnimPartControlInfo *)obj1;
191 const struct GlobalAnimPartControlInfo *o2 =
192 (struct GlobalAnimPartControlInfo *)obj2;
195 if (o1->control_info.draw_order != o2->control_info.draw_order)
196 compare_result = o1->control_info.draw_order - o2->control_info.draw_order;
198 compare_result = o1->nr - o2->nr;
200 return compare_result;
203 static int compareGlobalAnimMainControlInfo(const void *obj1, const void *obj2)
205 const struct GlobalAnimMainControlInfo *o1 =
206 (struct GlobalAnimMainControlInfo *)obj1;
207 const struct GlobalAnimMainControlInfo *o2 =
208 (struct GlobalAnimMainControlInfo *)obj2;
211 if (o1->control_info.draw_order != o2->control_info.draw_order)
212 compare_result = o1->control_info.draw_order - o2->control_info.draw_order;
214 compare_result = o1->nr - o2->nr;
216 return compare_result;
219 static void PrepareBackbuffer()
221 if (game_status != GAME_MODE_PLAYING)
224 BlitScreenToBitmap(backbuffer);
227 boolean ToonNeedsRedraw()
234 int num_toons = MAX_NUM_TOONS;
237 if (global.num_toons >= 0 && global.num_toons < MAX_NUM_TOONS)
238 num_toons = global.num_toons;
240 for (i = 0; i < num_toons; i++)
242 int graphic = IMG_TOON_1 + i;
243 struct FileInfo *image = getImageListEntryFromImageID(graphic);
245 toons[i].bitmap = graphic_info[graphic].bitmap;
247 toons[i].src_x = graphic_info[graphic].src_x;
248 toons[i].src_y = graphic_info[graphic].src_y;
250 toons[i].width = graphic_info[graphic].width;
251 toons[i].height = graphic_info[graphic].height;
253 toons[i].anim_frames = graphic_info[graphic].anim_frames;
254 toons[i].anim_delay = graphic_info[graphic].anim_delay;
255 toons[i].anim_mode = graphic_info[graphic].anim_mode;
256 toons[i].anim_start_frame = graphic_info[graphic].anim_start_frame;
258 toons[i].step_offset = graphic_info[graphic].step_offset;
259 toons[i].step_delay = graphic_info[graphic].step_delay;
261 toons[i].direction = image->parameter[GFX_ARG_DIRECTION];
262 toons[i].position = image->parameter[GFX_ARG_POSITION];
265 InitToonScreen(bitmap_db_toons,
266 BackToFront, PrepareBackbuffer, ToonNeedsRedraw,
268 REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE,
272 static void InitToonControls()
274 int mode_nr_toons = GAME_MODE_PSEUDO_TOONS;
275 struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[mode_nr_toons];
276 struct GlobalAnimMainControlInfo *anim = &ctrl->anim[ctrl->num_anims];
277 int mode_nr, anim_nr, part_nr;
278 int control = IMG_INTERNAL_GLOBAL_TOON_DEFAULT;
279 int num_toons = MAX_NUM_TOONS;
282 if (global.num_toons >= 0 && global.num_toons < MAX_NUM_TOONS)
283 num_toons = global.num_toons;
285 mode_nr = mode_nr_toons;
286 anim_nr = ctrl->num_anims;
289 anim->mode_nr = mode_nr;
290 anim->control_info = graphic_info[control];
293 anim->part_counter = 0;
294 anim->active_part_nr = 0;
296 anim->has_base = FALSE;
298 anim->init_delay_counter = 0;
300 anim->state = ANIM_STATE_INACTIVE;
304 for (i = 0; i < num_toons; i++)
306 struct GlobalAnimPartControlInfo *part = &anim->part[part_nr];
307 int graphic = IMG_TOON_1 + i;
308 int control = graphic;
311 part->anim_nr = anim_nr;
312 part->mode_nr = mode_nr;
313 part->graphic = graphic;
314 part->graphic_info = graphic_info[graphic];
315 part->control_info = graphic_info[control];
317 part->graphic_info.anim_delay *= part->graphic_info.step_delay;
319 part->control_info.init_delay_fixed = 0;
320 part->control_info.init_delay_random = 150;
322 part->control_info.x = ARG_UNDEFINED_VALUE;
323 part->control_info.y = ARG_UNDEFINED_VALUE;
325 part->initial_anim_sync_frame = 0;
327 part->step_delay = 0;
328 part->step_delay_value = graphic_info[control].step_delay;
330 part->state = ANIM_STATE_INACTIVE;
331 part->last_anim_status = -1;
340 void InitGlobalAnimControls()
343 int mode_nr, anim_nr, part_nr;
344 int graphic, control;
348 ResetDelayCounter(&anim_sync_frame_delay);
350 for (m = 0; m < NUM_GAME_MODES; m++)
354 struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[mode_nr];
361 for (a = 0; a < NUM_GLOBAL_ANIMS; a++)
363 struct GlobalAnimMainControlInfo *anim = &ctrl->anim[anim_nr];
364 int ctrl_id = GLOBAL_ANIM_ID_CONTROL_FIRST + a;
366 control = global_anim_info[ctrl_id].graphic[GLOBAL_ANIM_ID_PART_BASE][m];
368 // if no base animation parameters defined, use default values
369 if (control == IMG_UNDEFINED)
370 control = IMG_INTERNAL_GLOBAL_ANIM_DEFAULT;
373 anim->mode_nr = mode_nr;
374 anim->control_info = graphic_info[control];
377 anim->part_counter = 0;
378 anim->active_part_nr = 0;
380 anim->has_base = FALSE;
382 anim->init_delay_counter = 0;
384 anim->state = ANIM_STATE_INACTIVE;
388 for (p = 0; p < NUM_GLOBAL_ANIM_PARTS_ALL; p++)
390 struct GlobalAnimPartControlInfo *part = &anim->part[part_nr];
392 graphic = global_anim_info[a].graphic[p][m];
393 control = global_anim_info[ctrl_id].graphic[p][m];
395 if (graphic == IMG_UNDEFINED || graphic_info[graphic].bitmap == NULL ||
396 control == IMG_UNDEFINED)
400 printf("::: mode == %d, anim = %d, part = %d [%d, %d, %d] [%d]\n",
401 m, a, p, mode_nr, anim_nr, part_nr, control);
405 part->anim_nr = anim_nr;
406 part->mode_nr = mode_nr;
407 part->graphic = graphic;
408 part->graphic_info = graphic_info[graphic];
409 part->control_info = graphic_info[control];
411 part->initial_anim_sync_frame = 0;
413 part->step_delay = 0;
414 part->step_delay_value = graphic_info[control].step_delay;
416 part->state = ANIM_STATE_INACTIVE;
417 part->last_anim_status = -1;
419 if (p < GLOBAL_ANIM_ID_PART_BASE)
427 anim->has_base = TRUE;
431 if (anim->num_parts > 0 || anim->has_base)
441 /* sort all animations according to draw_order and animation number */
442 for (m = 0; m < NUM_GAME_MODES; m++)
444 struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[m];
446 /* sort all main animations for this game mode */
447 qsort(ctrl->anim, ctrl->num_anims,
448 sizeof(struct GlobalAnimMainControlInfo),
449 compareGlobalAnimMainControlInfo);
451 for (a = 0; a < ctrl->num_anims; a++)
453 struct GlobalAnimMainControlInfo *anim = &ctrl->anim[a];
455 /* sort all animation parts for this main animation */
456 qsort(anim->part, anim->num_parts,
457 sizeof(struct GlobalAnimPartControlInfo),
458 compareGlobalAnimPartControlInfo);
462 for (i = 0; i < NUM_GAME_MODES; i++)
463 game_mode_anim_classes[i] = ANIM_CLASS_NONE;
464 for (i = 0; game_mode_anim_classes_list[i].game_mode != -1; i++)
465 game_mode_anim_classes[game_mode_anim_classes_list[i].game_mode] =
466 game_mode_anim_classes_list[i].class;
468 for (i = 0; i < NUM_ANIM_CLASSES; i++)
469 anim_class_game_modes[i] = GAME_MODE_DEFAULT;
470 for (i = 0; anim_class_game_modes_list[i].game_mode != -1; i++)
471 anim_class_game_modes[anim_class_game_modes_list[i].class_bit] =
472 anim_class_game_modes_list[i].game_mode;
474 anim_status_last = GAME_MODE_LOADING;
475 anim_classes_last = ANIM_CLASS_NONE;
478 void InitGlobalAnimations()
480 InitGlobalAnimControls();
483 void DrawGlobalAnimExt(int drawing_stage)
487 if (global.anim_status != anim_status_last)
489 boolean before_fading = (global.anim_status == GAME_MODE_PSEUDO_FADING);
490 boolean after_fading = (anim_status_last == GAME_MODE_PSEUDO_FADING);
491 int anim_classes_next = game_mode_anim_classes[global.anim_status_next];
494 // ---------- part 1 ------------------------------------------------------
495 // start or stop global animations by change of game mode
496 // (special handling of animations for "current screen" and "all screens")
498 // stop animations for last screen
499 HandleGlobalAnim(ANIM_STOP, anim_status_last);
501 // start animations for current screen
502 HandleGlobalAnim(ANIM_START, global.anim_status);
504 // start animations for all screens after loading new artwork set
505 if (anim_status_last == GAME_MODE_LOADING)
506 HandleGlobalAnim(ANIM_START, GAME_MODE_DEFAULT);
508 // ---------- part 2 ------------------------------------------------------
509 // start or stop global animations by change of animation class
510 // (generic handling of animations for "class of screens")
512 for (i = 0; i < NUM_ANIM_CLASSES; i++)
514 int anim_class_check = (1 << i);
515 int anim_class_game_mode = anim_class_game_modes[i];
516 int anim_class_last = anim_classes_last & anim_class_check;
517 int anim_class_next = anim_classes_next & anim_class_check;
519 // stop animations for changed screen class before fading to new screen
520 if (before_fading && anim_class_last && !anim_class_next)
521 HandleGlobalAnim(ANIM_STOP, anim_class_game_mode);
523 // start animations for changed screen class after fading to new screen
524 if (after_fading && !anim_class_last && anim_class_next)
525 HandleGlobalAnim(ANIM_START, anim_class_game_mode);
529 anim_classes_last = anim_classes_next;
531 anim_status_last = global.anim_status;
534 if (!setup.toons || global.anim_status == GAME_MODE_LOADING)
537 if (drawing_stage == DRAW_GLOBAL_ANIM_STAGE_1)
540 for (mode_nr = 0; mode_nr < NUM_GAME_MODES; mode_nr++)
542 struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[mode_nr];
546 if (mode_nr != GFX_SPECIAL_ARG_DEFAULT &&
547 mode_nr != game_status)
551 for (anim_nr = 0; anim_nr < ctrl->num_anims; anim_nr++)
553 struct GlobalAnimMainControlInfo *anim = &ctrl->anim[anim_nr];
554 struct GraphicInfo *c = &anim->control_info;
555 int part_first, part_last;
558 if (!(anim->state & ANIM_STATE_RUNNING))
561 part_first = part_last = anim->active_part_nr;
563 if (c->anim_mode & ANIM_ALL || anim->num_parts == 0)
565 int num_parts = anim->num_parts + (anim->has_base ? 1 : 0);
568 part_last = num_parts - 1;
571 for (part_nr = part_first; part_nr <= part_last; part_nr++)
573 struct GlobalAnimPartControlInfo *part = &anim->part[part_nr];
574 struct GraphicInfo *g = &part->graphic_info;
577 int width = g->width;
578 int height = g->height;
586 if (!(part->state & ANIM_STATE_RUNNING))
589 if (part->drawing_stage != drawing_stage)
598 else if (part->x > part->viewport_width - g->width)
599 width -= (part->x - (part->viewport_width - g->width));
607 else if (part->y > part->viewport_height - g->height)
608 height -= (part->y - (part->viewport_height - g->height));
610 if (width <= 0 || height <= 0)
613 dst_x += part->viewport_x;
614 dst_y += part->viewport_y;
616 sync_frame = anim_sync_frame - part->initial_anim_sync_frame;
617 frame = getAnimationFrame(g->anim_frames, g->anim_delay,
618 g->anim_mode, g->anim_start_frame,
621 getFixedGraphicSource(part->graphic, frame, &src_bitmap,
627 BlitToScreenMasked(src_bitmap, src_x, src_y, width, height,
634 void DrawGlobalAnim(int drawing_stage)
636 DrawGlobalAnimExt(drawing_stage);
639 boolean SetGlobalAnimPart_Viewport(struct GlobalAnimPartControlInfo *part)
645 boolean changed = FALSE;
647 if (part->last_anim_status == global.anim_status)
650 part->last_anim_status = global.anim_status;
652 part->drawing_stage = DRAW_GLOBAL_ANIM_STAGE_1;
654 if (part->control_info.class == get_hash_from_key("window") ||
655 part->control_info.class == get_hash_from_key("border"))
659 viewport_width = WIN_XSIZE;
660 viewport_height = WIN_YSIZE;
662 part->drawing_stage = DRAW_GLOBAL_ANIM_STAGE_2;
664 else if (part->control_info.class == get_hash_from_key("door_1"))
668 viewport_width = DXSIZE;
669 viewport_height = DYSIZE;
671 else if (part->control_info.class == get_hash_from_key("door_2"))
675 viewport_width = VXSIZE;
676 viewport_height = VYSIZE;
678 else // default: "playfield"
680 viewport_x = REAL_SX;
681 viewport_y = REAL_SY;
682 viewport_width = FULL_SXSIZE;
683 viewport_height = FULL_SYSIZE;
686 if (viewport_x != part->viewport_x ||
687 viewport_y != part->viewport_y ||
688 viewport_width != part->viewport_width ||
689 viewport_height != part->viewport_height)
691 part->viewport_x = viewport_x;
692 part->viewport_y = viewport_y;
693 part->viewport_width = viewport_width;
694 part->viewport_height = viewport_height;
702 int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part, int state)
704 struct GraphicInfo *g = &part->graphic_info;
705 struct GraphicInfo *c = &part->control_info;
706 boolean viewport_changed = SetGlobalAnimPart_Viewport(part);
708 if (viewport_changed)
709 state |= ANIM_STATE_RESTART;
711 if (state & ANIM_STATE_RESTART)
713 ResetDelayCounterExt(&part->step_delay, anim_sync_frame);
715 part->init_delay_counter =
716 (c->init_delay_fixed + GetSimpleRandom(c->init_delay_random));
718 part->anim_delay_counter =
719 (c->anim_delay_fixed + GetSimpleRandom(c->anim_delay_random));
721 part->initial_anim_sync_frame =
722 (g->anim_global_sync ? 0 : anim_sync_frame + part->init_delay_counter);
724 if (c->direction & MV_HORIZONTAL)
726 int pos_bottom = part->viewport_height - g->height;
728 if (c->position == POS_TOP)
730 else if (c->position == POS_UPPER)
731 part->y = GetSimpleRandom(pos_bottom / 2);
732 else if (c->position == POS_MIDDLE)
733 part->y = pos_bottom / 2;
734 else if (c->position == POS_LOWER)
735 part->y = pos_bottom / 2 + GetSimpleRandom(pos_bottom / 2);
736 else if (c->position == POS_BOTTOM)
737 part->y = pos_bottom;
739 part->y = GetSimpleRandom(pos_bottom);
741 if (c->direction == MV_RIGHT)
743 part->step_xoffset = c->step_offset;
744 part->x = -g->width + part->step_xoffset;
748 part->step_xoffset = -c->step_offset;
749 part->x = part->viewport_width + part->step_xoffset;
752 part->step_yoffset = 0;
754 else if (c->direction & MV_VERTICAL)
756 int pos_right = part->viewport_width - g->width;
758 if (c->position == POS_LEFT)
760 else if (c->position == POS_RIGHT)
763 part->x = GetSimpleRandom(pos_right);
765 if (c->direction == MV_DOWN)
767 part->step_yoffset = c->step_offset;
768 part->y = -g->height + part->step_yoffset;
772 part->step_yoffset = -c->step_offset;
773 part->y = part->viewport_height + part->step_yoffset;
776 part->step_xoffset = 0;
783 part->step_xoffset = 0;
784 part->step_yoffset = 0;
787 if (c->x != ARG_UNDEFINED_VALUE)
789 if (c->y != ARG_UNDEFINED_VALUE)
792 if (c->step_xoffset != ARG_UNDEFINED_VALUE)
793 part->step_xoffset = c->step_xoffset;
794 if (c->step_yoffset != ARG_UNDEFINED_VALUE)
795 part->step_yoffset = c->step_yoffset;
798 if (part->init_delay_counter > 0)
800 part->init_delay_counter--;
802 return ANIM_STATE_WAITING;
805 // check if moving animation has left the visible screen area
806 if ((part->x <= -g->width && part->step_xoffset <= 0) ||
807 (part->x >= part->viewport_width && part->step_xoffset >= 0) ||
808 (part->y <= -g->height && part->step_yoffset <= 0) ||
809 (part->y >= part->viewport_height && part->step_yoffset >= 0))
811 // do not stop animation before "anim" or "post" counter are finished
812 if (part->anim_delay_counter == 0 &&
813 part->post_delay_counter == 0)
815 part->post_delay_counter =
816 (c->post_delay_fixed + GetSimpleRandom(c->post_delay_random));
818 if (part->post_delay_counter > 0)
819 return ANIM_STATE_RUNNING;
821 return ANIM_STATE_RESTART;
825 if (part->anim_delay_counter > 0)
827 part->anim_delay_counter--;
829 if (part->anim_delay_counter == 0)
831 part->post_delay_counter =
832 (c->post_delay_fixed + GetSimpleRandom(c->post_delay_random));
834 if (part->post_delay_counter > 0)
835 return ANIM_STATE_RUNNING;
837 // additional state "RUNNING" required to not skip drawing last frame
838 return ANIM_STATE_RESTART | ANIM_STATE_RUNNING;
842 if (part->post_delay_counter > 0)
844 part->post_delay_counter--;
846 if (part->post_delay_counter == 0)
847 return ANIM_STATE_RESTART;
849 return ANIM_STATE_WAITING;
852 if (!DelayReachedExt(&part->step_delay, part->step_delay_value,
854 return ANIM_STATE_RUNNING;
858 static unsigned int last_counter = -1;
859 unsigned int counter = Counter();
861 printf("::: NEXT ANIM PART [%d, %d]\n",
862 anim_sync_frame, counter - last_counter);
864 last_counter = counter;
868 part->x += part->step_xoffset;
869 part->y += part->step_yoffset;
871 return ANIM_STATE_RUNNING;
874 void HandleGlobalAnim_Main(struct GlobalAnimMainControlInfo *anim, int action)
876 struct GlobalAnimPartControlInfo *part;
877 struct GraphicInfo *c = &anim->control_info;
878 int state, active_part_nr;
881 printf("::: HandleGlobalAnim_Main: %d, %d => %d\n",
882 anim->mode_nr, anim->nr, anim->num_parts);
883 printf("::: %d, %d, %d\n", global.num_toons, setup.toons, num_toons);
887 printf("::: %s(%d): %d, %d, %d [%d]\n",
888 (action == ANIM_START ? "ANIM_START" :
889 action == ANIM_CONTINUE ? "ANIM_CONTINUE" :
890 action == ANIM_STOP ? "ANIM_STOP" : "(should not happen)"),
892 anim->state & ANIM_STATE_RESTART,
893 anim->state & ANIM_STATE_WAITING,
894 anim->state & ANIM_STATE_RUNNING,
901 anim->state = anim->last_state = ANIM_STATE_RESTART;
902 anim->active_part_nr = anim->last_active_part_nr = 0;
903 anim->part_counter = 0;
908 if (anim->state == ANIM_STATE_INACTIVE)
911 anim->state = anim->last_state;
912 anim->active_part_nr = anim->last_active_part_nr;
917 anim->state = ANIM_STATE_INACTIVE;
925 if (c->anim_mode & ANIM_ALL || anim->num_parts == 0)
927 int num_parts = anim->num_parts + (anim->has_base ? 1 : 0);
931 printf("::: HandleGlobalAnim_Main: %d, %d => %d\n",
932 anim->mode_nr, anim->nr, num_parts);
935 for (i = 0; i < num_parts; i++)
937 part = &anim->part[i];
942 anim->state = ANIM_STATE_RUNNING;
943 part->state = ANIM_STATE_RESTART;
948 if (part->state == ANIM_STATE_INACTIVE)
954 part->state = ANIM_STATE_INACTIVE;
962 part->state = HandleGlobalAnim_Part(part, part->state);
964 // when animation mode is "once", stop after animation was played once
965 if (c->anim_mode & ANIM_ONCE &&
966 part->state & ANIM_STATE_RESTART)
967 part->state = ANIM_STATE_INACTIVE;
970 anim->last_state = anim->state;
971 anim->last_active_part_nr = anim->active_part_nr;
976 if (anim->state & ANIM_STATE_RESTART) // directly after restart
977 anim->active_part_nr = getGlobalAnimationPart(anim);
979 part = &anim->part[anim->active_part_nr];
981 part->state = ANIM_STATE_RUNNING;
983 anim->state = HandleGlobalAnim_Part(part, anim->state);
985 if (anim->state & ANIM_STATE_RESTART)
986 anim->part_counter++;
988 // when animation mode is "once", stop after all animations were played once
989 if (c->anim_mode & ANIM_ONCE &&
990 anim->part_counter == anim->num_parts)
991 anim->state = ANIM_STATE_INACTIVE;
994 active_part_nr = anim->active_part_nr;
996 // while the animation parts are pausing (waiting or inactive), play the base
997 // (main) animation; this corresponds to the "boring player animation" logic
998 // (!!! KLUDGE WARNING: I THINK THIS IS A MESS THAT SHOULD BE CLEANED UP !!!)
1001 if (anim->state == ANIM_STATE_WAITING ||
1002 anim->state == ANIM_STATE_INACTIVE)
1004 anim->active_part_nr = anim->num_parts; // part nr of base animation
1005 part = &anim->part[anim->active_part_nr];
1007 if (anim->state != anim->last_state)
1008 part->state = ANIM_STATE_RESTART;
1010 anim->state = ANIM_STATE_RUNNING;
1011 part->state = HandleGlobalAnim_Part(part, part->state);
1015 anim->last_state = state;
1016 anim->last_active_part_nr = active_part_nr;
1019 void HandleGlobalAnim_Mode(struct GlobalAnimControlInfo *ctrl, int action)
1024 printf("::: HandleGlobalAnim_Mode: %d => %d\n",
1025 ctrl->nr, ctrl->num_anims);
1028 for (i = 0; i < ctrl->num_anims; i++)
1029 HandleGlobalAnim_Main(&ctrl->anim[i], action);
1032 static void HandleGlobalAnim(int action, int game_mode)
1035 printf("::: HandleGlobalAnim [mode == %d]\n", game_status);
1038 HandleGlobalAnim_Mode(&global_anim_ctrl[game_mode], action);
1041 void InitAnimation()
1045 void StopAnimation()
1049 static void DoAnimationExt()
1054 printf("::: DoAnimation [%d, %d]\n", anim_sync_frame, Counter());
1058 WaitUntilDelayReached(&anim_sync_frame_delay, anim_sync_frame_delay_value);
1061 if (DelayReached(&anim_sync_frame_delay, anim_sync_frame_delay_value))
1065 for (i = 0; i < NUM_GAME_MODES; i++)
1066 HandleGlobalAnim(ANIM_CONTINUE, i);
1069 // force screen redraw in next frame to continue drawing global animations
1070 redraw_mask = REDRAW_ALL;
1076 // HandleAnimation(ANIM_CONTINUE);
1079 // force screen redraw in next frame to continue drawing global animations
1080 redraw_mask = REDRAW_ALL;