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_SUBMENU 0
28 #define ANIM_CLASS_BIT_MENU 1
29 #define ANIM_CLASS_BIT_TOONS 2
31 #define NUM_ANIM_CLASSES 3
33 #define ANIM_CLASS_NONE 0
34 #define ANIM_CLASS_SUBMENU (1 << ANIM_CLASS_BIT_SUBMENU)
35 #define ANIM_CLASS_MENU (1 << ANIM_CLASS_BIT_MENU)
36 #define ANIM_CLASS_TOONS (1 << ANIM_CLASS_BIT_TOONS)
39 struct GlobalAnimPartControlInfo
46 struct GraphicInfo graphic_info;
47 struct GraphicInfo control_info;
55 int step_xoffset, step_yoffset;
57 unsigned int initial_anim_sync_frame;
58 unsigned int step_delay, step_delay_value;
60 int init_delay_counter;
61 int anim_delay_counter;
62 int post_delay_counter;
70 struct GlobalAnimMainControlInfo
72 struct GlobalAnimPartControlInfo base;
73 struct GlobalAnimPartControlInfo part[NUM_GLOBAL_ANIM_PARTS_AND_TOONS];
78 struct GraphicInfo control_info;
86 int init_delay_counter;
91 struct GlobalAnimControlInfo
93 struct GlobalAnimMainControlInfo anim[NUM_GLOBAL_ANIMS_AND_TOONS];
99 struct GameModeAnimClass
103 } game_mode_anim_classes_list[] =
105 { GAME_MODE_LEVELS, ANIM_CLASS_TOONS | ANIM_CLASS_MENU | ANIM_CLASS_SUBMENU },
106 { GAME_MODE_LEVELNR,ANIM_CLASS_TOONS | ANIM_CLASS_MENU | ANIM_CLASS_SUBMENU },
107 { GAME_MODE_INFO, ANIM_CLASS_TOONS | ANIM_CLASS_MENU | ANIM_CLASS_SUBMENU },
108 { GAME_MODE_SETUP, ANIM_CLASS_TOONS | ANIM_CLASS_MENU | ANIM_CLASS_SUBMENU },
109 { GAME_MODE_MAIN, ANIM_CLASS_TOONS | ANIM_CLASS_MENU },
110 { GAME_MODE_SCORES, ANIM_CLASS_TOONS },
115 struct AnimClassGameMode
119 } anim_class_game_modes_list[] =
121 { ANIM_CLASS_BIT_SUBMENU, GAME_MODE_PSEUDO_SUBMENU },
122 { ANIM_CLASS_BIT_MENU, GAME_MODE_PSEUDO_MENU },
123 { ANIM_CLASS_BIT_TOONS, GAME_MODE_PSEUDO_TOONS },
128 /* forward declaration for internal use */
129 static void HandleGlobalAnim(int, int);
130 static void DoAnimationExt(void);
132 static struct GlobalAnimControlInfo global_anim_ctrl[NUM_GAME_MODES];
133 static struct ToonInfo toons[MAX_NUM_TOONS];
135 static unsigned int anim_sync_frame = 0;
136 static unsigned int anim_sync_frame_delay = 0;
137 static unsigned int anim_sync_frame_delay_value = GAME_FRAME_DELAY;
139 static int game_mode_anim_classes[NUM_GAME_MODES];
140 static int anim_class_game_modes[NUM_ANIM_CLASSES];
142 static int anim_status_last = GAME_MODE_DEFAULT;
143 static int anim_classes_last = ANIM_CLASS_NONE;
146 static int getGlobalAnimationPart(struct GlobalAnimMainControlInfo *anim)
148 struct GraphicInfo *c = &anim->control_info;
149 int last_anim_random_frame = gfx.anim_random_frame;
152 gfx.anim_random_frame = -1; // (use simple, ad-hoc random numbers)
154 part_nr = getAnimationFrame(anim->num_parts, 1,
155 c->anim_mode, c->anim_start_frame,
158 gfx.anim_random_frame = last_anim_random_frame;
163 static int compareGlobalAnimPartControlInfo(const void *obj1, const void *obj2)
165 const struct GlobalAnimPartControlInfo *o1 =
166 (struct GlobalAnimPartControlInfo *)obj1;
167 const struct GlobalAnimPartControlInfo *o2 =
168 (struct GlobalAnimPartControlInfo *)obj2;
171 if (o1->control_info.draw_order != o2->control_info.draw_order)
172 compare_result = o1->control_info.draw_order - o2->control_info.draw_order;
174 compare_result = o1->nr - o2->nr;
176 return compare_result;
179 static int compareGlobalAnimMainControlInfo(const void *obj1, const void *obj2)
181 const struct GlobalAnimMainControlInfo *o1 =
182 (struct GlobalAnimMainControlInfo *)obj1;
183 const struct GlobalAnimMainControlInfo *o2 =
184 (struct GlobalAnimMainControlInfo *)obj2;
187 if (o1->control_info.draw_order != o2->control_info.draw_order)
188 compare_result = o1->control_info.draw_order - o2->control_info.draw_order;
190 compare_result = o1->nr - o2->nr;
192 return compare_result;
195 static void PrepareBackbuffer()
197 if (game_status != GAME_MODE_PLAYING)
200 BlitScreenToBitmap(backbuffer);
203 boolean ToonNeedsRedraw()
210 int num_toons = MAX_NUM_TOONS;
213 if (global.num_toons >= 0 && global.num_toons < MAX_NUM_TOONS)
214 num_toons = global.num_toons;
216 for (i = 0; i < num_toons; i++)
218 int graphic = IMG_TOON_1 + i;
219 struct FileInfo *image = getImageListEntryFromImageID(graphic);
221 toons[i].bitmap = graphic_info[graphic].bitmap;
223 toons[i].src_x = graphic_info[graphic].src_x;
224 toons[i].src_y = graphic_info[graphic].src_y;
226 toons[i].width = graphic_info[graphic].width;
227 toons[i].height = graphic_info[graphic].height;
229 toons[i].anim_frames = graphic_info[graphic].anim_frames;
230 toons[i].anim_delay = graphic_info[graphic].anim_delay;
231 toons[i].anim_mode = graphic_info[graphic].anim_mode;
232 toons[i].anim_start_frame = graphic_info[graphic].anim_start_frame;
234 toons[i].step_offset = graphic_info[graphic].step_offset;
235 toons[i].step_delay = graphic_info[graphic].step_delay;
237 toons[i].direction = image->parameter[GFX_ARG_DIRECTION];
238 toons[i].position = image->parameter[GFX_ARG_POSITION];
241 InitToonScreen(bitmap_db_toons,
242 BackToFront, PrepareBackbuffer, ToonNeedsRedraw,
244 REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE,
248 static void InitToonControls()
250 int mode_nr_toons = GAME_MODE_PSEUDO_TOONS;
251 struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[mode_nr_toons];
252 struct GlobalAnimMainControlInfo *anim = &ctrl->anim[ctrl->num_anims];
253 int mode_nr, anim_nr, part_nr;
254 int control = IMG_INTERNAL_GLOBAL_TOON_DEFAULT;
255 int num_toons = MAX_NUM_TOONS;
258 if (global.num_toons >= 0 && global.num_toons < MAX_NUM_TOONS)
259 num_toons = global.num_toons;
261 mode_nr = mode_nr_toons;
262 anim_nr = ctrl->num_anims;
265 anim->mode_nr = mode_nr;
266 anim->control_info = graphic_info[control];
269 anim->part_counter = 0;
270 anim->active_part_nr = 0;
272 anim->has_base = FALSE;
274 anim->init_delay_counter = 0;
276 anim->state = ANIM_STATE_INACTIVE;
280 for (i = 0; i < num_toons; i++)
282 struct GlobalAnimPartControlInfo *part = &anim->part[part_nr];
283 int graphic = IMG_TOON_1 + i;
284 int control = graphic;
287 part->anim_nr = anim_nr;
288 part->mode_nr = mode_nr;
289 part->graphic = graphic;
290 part->graphic_info = graphic_info[graphic];
291 part->control_info = graphic_info[control];
293 part->graphic_info.anim_delay *= part->graphic_info.step_delay;
295 part->control_info.init_delay_fixed = 0;
296 part->control_info.init_delay_random = 150;
298 part->control_info.x = ARG_UNDEFINED_VALUE;
299 part->control_info.y = ARG_UNDEFINED_VALUE;
301 part->initial_anim_sync_frame = 0;
303 part->step_delay = 0;
304 part->step_delay_value = graphic_info[control].step_delay;
306 part->state = ANIM_STATE_INACTIVE;
307 part->last_anim_status = -1;
316 void InitGlobalAnimControls()
319 int mode_nr, anim_nr, part_nr;
320 int graphic, control;
324 ResetDelayCounter(&anim_sync_frame_delay);
326 for (m = 0; m < NUM_GAME_MODES; m++)
330 struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[mode_nr];
337 for (a = 0; a < NUM_GLOBAL_ANIMS; a++)
339 struct GlobalAnimMainControlInfo *anim = &ctrl->anim[anim_nr];
340 int ctrl_id = GLOBAL_ANIM_ID_CONTROL_FIRST + a;
342 control = global_anim_info[ctrl_id].graphic[GLOBAL_ANIM_ID_PART_BASE][m];
344 // if no base animation parameters defined, use default values
345 if (control == IMG_UNDEFINED)
346 control = IMG_INTERNAL_GLOBAL_ANIM_DEFAULT;
349 anim->mode_nr = mode_nr;
350 anim->control_info = graphic_info[control];
353 anim->part_counter = 0;
354 anim->active_part_nr = 0;
356 anim->has_base = FALSE;
358 anim->init_delay_counter = 0;
360 anim->state = ANIM_STATE_INACTIVE;
364 for (p = 0; p < NUM_GLOBAL_ANIM_PARTS_ALL; p++)
366 struct GlobalAnimPartControlInfo *part = &anim->part[part_nr];
368 graphic = global_anim_info[a].graphic[p][m];
369 control = global_anim_info[ctrl_id].graphic[p][m];
371 if (graphic == IMG_UNDEFINED || graphic_info[graphic].bitmap == NULL ||
372 control == IMG_UNDEFINED)
376 printf("::: mode == %d, anim = %d, part = %d [%d, %d, %d] [%d]\n",
377 m, a, p, mode_nr, anim_nr, part_nr, control);
381 part->anim_nr = anim_nr;
382 part->mode_nr = mode_nr;
383 part->graphic = graphic;
384 part->graphic_info = graphic_info[graphic];
385 part->control_info = graphic_info[control];
387 part->initial_anim_sync_frame = 0;
389 part->step_delay = 0;
390 part->step_delay_value = graphic_info[control].step_delay;
392 part->state = ANIM_STATE_INACTIVE;
393 part->last_anim_status = -1;
395 if (p < GLOBAL_ANIM_ID_PART_BASE)
403 anim->has_base = TRUE;
407 if (anim->num_parts > 0 || anim->has_base)
417 /* sort all animations according to draw_order and animation number */
418 for (m = 0; m < NUM_GAME_MODES; m++)
420 struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[m];
422 /* sort all main animations for this game mode */
423 qsort(ctrl->anim, ctrl->num_anims,
424 sizeof(struct GlobalAnimMainControlInfo),
425 compareGlobalAnimMainControlInfo);
427 for (a = 0; a < ctrl->num_anims; a++)
429 struct GlobalAnimMainControlInfo *anim = &ctrl->anim[a];
431 /* sort all animation parts for this main animation */
432 qsort(anim->part, anim->num_parts,
433 sizeof(struct GlobalAnimPartControlInfo),
434 compareGlobalAnimPartControlInfo);
438 for (i = 0; i < NUM_GAME_MODES; i++)
439 game_mode_anim_classes[i] = ANIM_CLASS_NONE;
440 for (i = 0; game_mode_anim_classes_list[i].game_mode != -1; i++)
441 game_mode_anim_classes[game_mode_anim_classes_list[i].game_mode] =
442 game_mode_anim_classes_list[i].class;
444 for (i = 0; i < NUM_ANIM_CLASSES; i++)
445 anim_class_game_modes[i] = GAME_MODE_DEFAULT;
446 for (i = 0; anim_class_game_modes_list[i].game_mode != -1; i++)
447 anim_class_game_modes[anim_class_game_modes_list[i].class_bit] =
448 anim_class_game_modes_list[i].game_mode;
450 anim_status_last = GAME_MODE_LOADING;
451 anim_classes_last = ANIM_CLASS_NONE;
454 void InitGlobalAnimations()
456 InitGlobalAnimControls();
459 void DrawGlobalAnimExt(int drawing_stage)
463 if (global.anim_status != anim_status_last)
465 boolean before_fading = (global.anim_status == GAME_MODE_PSEUDO_FADING);
466 boolean after_fading = (anim_status_last == GAME_MODE_PSEUDO_FADING);
467 int anim_classes_next = game_mode_anim_classes[global.anim_status_next];
470 // ---------- part 1 ------------------------------------------------------
471 // start or stop global animations by change of game mode
472 // (special handling of animations for "current screen" and "all screens")
474 // stop animations for last screen
475 HandleGlobalAnim(ANIM_STOP, anim_status_last);
477 // start animations for current screen
478 HandleGlobalAnim(ANIM_START, global.anim_status);
480 // start animations for all screens after loading new artwork set
481 if (anim_status_last == GAME_MODE_LOADING)
482 HandleGlobalAnim(ANIM_START, GAME_MODE_DEFAULT);
484 // ---------- part 2 ------------------------------------------------------
485 // start or stop global animations by change of animation class
486 // (generic handling of animations for "class of screens")
488 for (i = 0; i < NUM_ANIM_CLASSES; i++)
490 int anim_class_check = (1 << i);
491 int anim_class_game_mode = anim_class_game_modes[i];
492 int anim_class_last = anim_classes_last & anim_class_check;
493 int anim_class_next = anim_classes_next & anim_class_check;
495 // stop animations for changed screen class before fading to new screen
496 if (before_fading && anim_class_last && !anim_class_next)
497 HandleGlobalAnim(ANIM_STOP, anim_class_game_mode);
499 // start animations for changed screen class after fading to new screen
500 if (after_fading && !anim_class_last && anim_class_next)
501 HandleGlobalAnim(ANIM_START, anim_class_game_mode);
505 anim_classes_last = anim_classes_next;
507 anim_status_last = global.anim_status;
510 if (!setup.toons || global.anim_status == GAME_MODE_LOADING)
513 if (drawing_stage == DRAW_GLOBAL_ANIM_STAGE_1)
516 for (mode_nr = 0; mode_nr < NUM_GAME_MODES; mode_nr++)
518 struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[mode_nr];
522 if (mode_nr != GFX_SPECIAL_ARG_DEFAULT &&
523 mode_nr != game_status)
527 for (anim_nr = 0; anim_nr < ctrl->num_anims; anim_nr++)
529 struct GlobalAnimMainControlInfo *anim = &ctrl->anim[anim_nr];
530 struct GraphicInfo *c = &anim->control_info;
531 int part_first, part_last;
534 if (!(anim->state & ANIM_STATE_RUNNING))
537 part_first = part_last = anim->active_part_nr;
539 if (c->anim_mode & ANIM_ALL || anim->num_parts == 0)
541 int num_parts = anim->num_parts + (anim->has_base ? 1 : 0);
544 part_last = num_parts - 1;
547 for (part_nr = part_first; part_nr <= part_last; part_nr++)
549 struct GlobalAnimPartControlInfo *part = &anim->part[part_nr];
550 struct GraphicInfo *g = &part->graphic_info;
553 int width = g->width;
554 int height = g->height;
562 if (!(part->state & ANIM_STATE_RUNNING))
565 if (part->drawing_stage != drawing_stage)
574 else if (part->x > part->viewport_width - g->width)
575 width -= (part->x - (part->viewport_width - g->width));
583 else if (part->y > part->viewport_height - g->height)
584 height -= (part->y - (part->viewport_height - g->height));
586 if (width <= 0 || height <= 0)
589 dst_x += part->viewport_x;
590 dst_y += part->viewport_y;
592 sync_frame = anim_sync_frame - part->initial_anim_sync_frame;
593 frame = getAnimationFrame(g->anim_frames, g->anim_delay,
594 g->anim_mode, g->anim_start_frame,
597 getFixedGraphicSource(part->graphic, frame, &src_bitmap,
603 BlitToScreenMasked(src_bitmap, src_x, src_y, width, height,
610 void DrawGlobalAnim(int drawing_stage)
612 DrawGlobalAnimExt(drawing_stage);
615 boolean SetGlobalAnimPart_Viewport(struct GlobalAnimPartControlInfo *part)
621 boolean changed = FALSE;
623 if (part->last_anim_status == global.anim_status)
626 part->last_anim_status = global.anim_status;
628 part->drawing_stage = DRAW_GLOBAL_ANIM_STAGE_1;
630 if (part->control_info.class == get_hash_from_key("window") ||
631 part->control_info.class == get_hash_from_key("border"))
635 viewport_width = WIN_XSIZE;
636 viewport_height = WIN_YSIZE;
638 part->drawing_stage = DRAW_GLOBAL_ANIM_STAGE_2;
640 else if (part->control_info.class == get_hash_from_key("door_1"))
644 viewport_width = DXSIZE;
645 viewport_height = DYSIZE;
647 else if (part->control_info.class == get_hash_from_key("door_2"))
651 viewport_width = VXSIZE;
652 viewport_height = VYSIZE;
654 else // default: "playfield"
656 viewport_x = REAL_SX;
657 viewport_y = REAL_SY;
658 viewport_width = FULL_SXSIZE;
659 viewport_height = FULL_SYSIZE;
662 if (viewport_x != part->viewport_x ||
663 viewport_y != part->viewport_y ||
664 viewport_width != part->viewport_width ||
665 viewport_height != part->viewport_height)
667 part->viewport_x = viewport_x;
668 part->viewport_y = viewport_y;
669 part->viewport_width = viewport_width;
670 part->viewport_height = viewport_height;
678 int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part, int state)
680 struct GraphicInfo *g = &part->graphic_info;
681 struct GraphicInfo *c = &part->control_info;
682 boolean viewport_changed = SetGlobalAnimPart_Viewport(part);
684 if (viewport_changed)
685 state |= ANIM_STATE_RESTART;
687 if (state & ANIM_STATE_RESTART)
689 ResetDelayCounterExt(&part->step_delay, anim_sync_frame);
691 part->init_delay_counter =
692 (c->init_delay_fixed + GetSimpleRandom(c->init_delay_random));
694 part->anim_delay_counter =
695 (c->anim_delay_fixed + GetSimpleRandom(c->anim_delay_random));
697 part->initial_anim_sync_frame =
698 (g->anim_global_sync ? 0 : anim_sync_frame + part->init_delay_counter);
700 if (c->direction & MV_HORIZONTAL)
702 int pos_bottom = part->viewport_height - g->height;
704 if (c->position == POS_TOP)
706 else if (c->position == POS_UPPER)
707 part->y = GetSimpleRandom(pos_bottom / 2);
708 else if (c->position == POS_MIDDLE)
709 part->y = pos_bottom / 2;
710 else if (c->position == POS_LOWER)
711 part->y = pos_bottom / 2 + GetSimpleRandom(pos_bottom / 2);
712 else if (c->position == POS_BOTTOM)
713 part->y = pos_bottom;
715 part->y = GetSimpleRandom(pos_bottom);
717 if (c->direction == MV_RIGHT)
719 part->step_xoffset = c->step_offset;
720 part->x = -g->width + part->step_xoffset;
724 part->step_xoffset = -c->step_offset;
725 part->x = part->viewport_width + part->step_xoffset;
728 part->step_yoffset = 0;
730 else if (c->direction & MV_VERTICAL)
732 int pos_right = part->viewport_width - g->width;
734 if (c->position == POS_LEFT)
736 else if (c->position == POS_RIGHT)
739 part->x = GetSimpleRandom(pos_right);
741 if (c->direction == MV_DOWN)
743 part->step_yoffset = c->step_offset;
744 part->y = -g->height + part->step_yoffset;
748 part->step_yoffset = -c->step_offset;
749 part->y = part->viewport_height + part->step_yoffset;
752 part->step_xoffset = 0;
759 part->step_xoffset = 0;
760 part->step_yoffset = 0;
763 if (c->x != ARG_UNDEFINED_VALUE)
765 if (c->y != ARG_UNDEFINED_VALUE)
768 if (c->step_xoffset != ARG_UNDEFINED_VALUE)
769 part->step_xoffset = c->step_xoffset;
770 if (c->step_yoffset != ARG_UNDEFINED_VALUE)
771 part->step_yoffset = c->step_yoffset;
774 if (part->init_delay_counter > 0)
776 part->init_delay_counter--;
778 return ANIM_STATE_WAITING;
781 if ((part->x <= -g->width && part->step_xoffset <= 0) ||
782 (part->x >= part->viewport_width && part->step_xoffset >= 0) ||
783 (part->y <= -g->height && part->step_yoffset <= 0) ||
784 (part->y >= part->viewport_height && part->step_yoffset >= 0))
785 return ANIM_STATE_RESTART;
787 if (part->anim_delay_counter > 0)
789 part->anim_delay_counter--;
791 if (part->anim_delay_counter == 0)
793 part->post_delay_counter =
794 (c->post_delay_fixed + GetSimpleRandom(c->post_delay_random));
796 if (part->post_delay_counter > 0)
797 return ANIM_STATE_RUNNING;
799 return ANIM_STATE_RESTART | ANIM_STATE_RUNNING;
803 if (part->post_delay_counter > 0)
805 part->post_delay_counter--;
807 if (part->post_delay_counter == 0)
808 return ANIM_STATE_RESTART;
810 return ANIM_STATE_WAITING;
813 if (!DelayReachedExt(&part->step_delay, part->step_delay_value,
815 return ANIM_STATE_RUNNING;
819 static unsigned int last_counter = -1;
820 unsigned int counter = Counter();
822 printf("::: NEXT ANIM PART [%d, %d]\n",
823 anim_sync_frame, counter - last_counter);
825 last_counter = counter;
829 part->x += part->step_xoffset;
830 part->y += part->step_yoffset;
832 return ANIM_STATE_RUNNING;
835 void HandleGlobalAnim_Main(struct GlobalAnimMainControlInfo *anim, int action)
837 struct GlobalAnimPartControlInfo *part;
838 struct GraphicInfo *c = &anim->control_info;
841 printf("::: HandleGlobalAnim_Main: %d, %d => %d\n",
842 anim->mode_nr, anim->nr, anim->num_parts);
843 printf("::: %d, %d, %d\n", global.num_toons, setup.toons, num_toons);
847 printf("::: %s(%d): %d, %d, %d [%d]\n",
848 (action == ANIM_START ? "ANIM_START" :
849 action == ANIM_CONTINUE ? "ANIM_CONTINUE" :
850 action == ANIM_STOP ? "ANIM_STOP" : "(should not happen)"),
852 anim->state & ANIM_STATE_RESTART,
853 anim->state & ANIM_STATE_WAITING,
854 anim->state & ANIM_STATE_RUNNING,
861 anim->state = ANIM_STATE_RESTART;
862 anim->part_counter = 0;
863 anim->active_part_nr = 0;
868 if (anim->state == ANIM_STATE_INACTIVE)
874 anim->state = ANIM_STATE_INACTIVE;
882 if (c->anim_mode & ANIM_ALL || anim->num_parts == 0)
884 int num_parts = anim->num_parts + (anim->has_base ? 1 : 0);
888 printf("::: HandleGlobalAnim_Main: %d, %d => %d\n",
889 anim->mode_nr, anim->nr, num_parts);
892 for (i = 0; i < num_parts; i++)
894 part = &anim->part[i];
899 anim->state = ANIM_STATE_RUNNING;
900 part->state = ANIM_STATE_RESTART;
905 if (part->state == ANIM_STATE_INACTIVE)
911 part->state = ANIM_STATE_INACTIVE;
919 part->state = HandleGlobalAnim_Part(part, part->state);
921 // when animation mode is "once", stop after animation was played once
922 if (c->anim_mode & ANIM_ONCE &&
923 part->state & ANIM_STATE_RESTART)
924 part->state = ANIM_STATE_INACTIVE;
930 if (anim->state & ANIM_STATE_RESTART) // directly after restart
931 anim->active_part_nr = getGlobalAnimationPart(anim);
933 part = &anim->part[anim->active_part_nr];
935 part->state = ANIM_STATE_RUNNING;
937 anim->state = HandleGlobalAnim_Part(part, anim->state);
939 if (anim->state & ANIM_STATE_RESTART)
940 anim->part_counter++;
942 // when animation mode is "once", stop after all animations were played once
943 if (c->anim_mode & ANIM_ONCE &&
944 anim->part_counter == anim->num_parts)
945 anim->state = ANIM_STATE_INACTIVE;
948 void HandleGlobalAnim_Mode(struct GlobalAnimControlInfo *ctrl, int action)
953 printf("::: HandleGlobalAnim_Mode: %d => %d\n",
954 ctrl->nr, ctrl->num_anims);
957 for (i = 0; i < ctrl->num_anims; i++)
958 HandleGlobalAnim_Main(&ctrl->anim[i], action);
961 static void HandleGlobalAnim(int action, int game_mode)
964 printf("::: HandleGlobalAnim [mode == %d]\n", game_status);
967 HandleGlobalAnim_Mode(&global_anim_ctrl[game_mode], action);
978 static void DoAnimationExt()
983 printf("::: DoAnimation [%d, %d]\n", anim_sync_frame, Counter());
987 WaitUntilDelayReached(&anim_sync_frame_delay, anim_sync_frame_delay_value);
990 if (DelayReached(&anim_sync_frame_delay, anim_sync_frame_delay_value))
994 for (i = 0; i < NUM_GAME_MODES; i++)
995 HandleGlobalAnim(ANIM_CONTINUE, i);
998 // force screen redraw in next frame to continue drawing global animations
999 redraw_mask = REDRAW_ALL;
1005 // HandleAnimation(ANIM_CONTINUE);
1008 // force screen redraw in next frame to continue drawing global animations
1009 redraw_mask = REDRAW_ALL;