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 dst_x += part->viewport_x;
587 dst_y += part->viewport_y;
589 sync_frame = anim_sync_frame - part->initial_anim_sync_frame;
590 frame = getAnimationFrame(g->anim_frames, g->anim_delay,
591 g->anim_mode, g->anim_start_frame,
594 getFixedGraphicSource(part->graphic, frame, &src_bitmap,
600 BlitToScreenMasked(src_bitmap, src_x, src_y, width, height,
607 void DrawGlobalAnim(int drawing_stage)
609 DrawGlobalAnimExt(drawing_stage);
612 boolean SetGlobalAnimPart_Viewport(struct GlobalAnimPartControlInfo *part)
618 boolean changed = FALSE;
620 if (part->last_anim_status == global.anim_status)
623 part->last_anim_status = global.anim_status;
625 part->drawing_stage = DRAW_GLOBAL_ANIM_STAGE_1;
627 if (part->control_info.class == get_hash_from_key("window") ||
628 part->control_info.class == get_hash_from_key("border"))
632 viewport_width = WIN_XSIZE;
633 viewport_height = WIN_YSIZE;
635 part->drawing_stage = DRAW_GLOBAL_ANIM_STAGE_2;
637 else if (part->control_info.class == get_hash_from_key("door_1"))
641 viewport_width = DXSIZE;
642 viewport_height = DYSIZE;
644 else if (part->control_info.class == get_hash_from_key("door_2"))
648 viewport_width = VXSIZE;
649 viewport_height = VYSIZE;
651 else // default: "playfield"
653 viewport_x = REAL_SX;
654 viewport_y = REAL_SY;
655 viewport_width = FULL_SXSIZE;
656 viewport_height = FULL_SYSIZE;
659 if (viewport_x != part->viewport_x ||
660 viewport_y != part->viewport_y ||
661 viewport_width != part->viewport_width ||
662 viewport_height != part->viewport_height)
664 part->viewport_x = viewport_x;
665 part->viewport_y = viewport_y;
666 part->viewport_width = viewport_width;
667 part->viewport_height = viewport_height;
675 int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part, int state)
677 struct GraphicInfo *g = &part->graphic_info;
678 struct GraphicInfo *c = &part->control_info;
679 boolean viewport_changed = SetGlobalAnimPart_Viewport(part);
681 if (viewport_changed)
682 state |= ANIM_STATE_RESTART;
684 if (state & ANIM_STATE_RESTART)
686 ResetDelayCounterExt(&part->step_delay, anim_sync_frame);
688 part->init_delay_counter =
689 (c->init_delay_fixed + GetSimpleRandom(c->init_delay_random));
691 part->anim_delay_counter =
692 (c->anim_delay_fixed + GetSimpleRandom(c->anim_delay_random));
694 part->initial_anim_sync_frame =
695 (g->anim_global_sync ? 0 : anim_sync_frame + part->init_delay_counter);
697 if (c->direction & MV_HORIZONTAL)
699 int pos_bottom = part->viewport_height - g->height;
701 if (c->position == POS_TOP)
703 else if (c->position == POS_UPPER)
704 part->y = GetSimpleRandom(pos_bottom / 2);
705 else if (c->position == POS_MIDDLE)
706 part->y = pos_bottom / 2;
707 else if (c->position == POS_LOWER)
708 part->y = pos_bottom / 2 + GetSimpleRandom(pos_bottom / 2);
709 else if (c->position == POS_BOTTOM)
710 part->y = pos_bottom;
712 part->y = GetSimpleRandom(pos_bottom);
714 if (c->direction == MV_RIGHT)
716 part->step_xoffset = c->step_offset;
717 part->x = -g->width + part->step_xoffset;
721 part->step_xoffset = -c->step_offset;
722 part->x = part->viewport_width + part->step_xoffset;
725 part->step_yoffset = 0;
727 else if (c->direction & MV_VERTICAL)
729 int pos_right = part->viewport_width - g->width;
731 if (c->position == POS_LEFT)
733 else if (c->position == POS_RIGHT)
736 part->x = GetSimpleRandom(pos_right);
738 if (c->direction == MV_DOWN)
740 part->step_yoffset = c->step_offset;
741 part->y = -g->height + part->step_yoffset;
745 part->step_yoffset = -c->step_offset;
746 part->y = part->viewport_height + part->step_yoffset;
749 part->step_xoffset = 0;
756 part->step_xoffset = 0;
757 part->step_yoffset = 0;
760 if (c->x != ARG_UNDEFINED_VALUE)
762 if (c->y != ARG_UNDEFINED_VALUE)
765 if (c->step_xoffset != ARG_UNDEFINED_VALUE)
766 part->step_xoffset = c->step_xoffset;
767 if (c->step_yoffset != ARG_UNDEFINED_VALUE)
768 part->step_yoffset = c->step_yoffset;
771 if (part->init_delay_counter > 0)
773 part->init_delay_counter--;
775 return ANIM_STATE_WAITING;
778 if ((part->x <= -g->width && part->step_xoffset <= 0) ||
779 (part->x >= part->viewport_width && part->step_xoffset >= 0) ||
780 (part->y <= -g->height && part->step_yoffset <= 0) ||
781 (part->y >= part->viewport_height && part->step_yoffset >= 0))
782 return ANIM_STATE_RESTART;
784 if (part->anim_delay_counter > 0)
786 part->anim_delay_counter--;
788 if (part->anim_delay_counter == 0)
790 part->post_delay_counter =
791 (c->post_delay_fixed + GetSimpleRandom(c->post_delay_random));
793 if (part->post_delay_counter > 0)
794 return ANIM_STATE_RUNNING;
796 return ANIM_STATE_RESTART | ANIM_STATE_RUNNING;
800 if (part->post_delay_counter > 0)
802 part->post_delay_counter--;
804 if (part->post_delay_counter == 0)
805 return ANIM_STATE_RESTART;
807 return ANIM_STATE_WAITING;
810 if (!DelayReachedExt(&part->step_delay, part->step_delay_value,
812 return ANIM_STATE_RUNNING;
816 static unsigned int last_counter = -1;
817 unsigned int counter = Counter();
819 printf("::: NEXT ANIM PART [%d, %d]\n",
820 anim_sync_frame, counter - last_counter);
822 last_counter = counter;
826 part->x += part->step_xoffset;
827 part->y += part->step_yoffset;
829 return ANIM_STATE_RUNNING;
832 void HandleGlobalAnim_Main(struct GlobalAnimMainControlInfo *anim, int action)
834 struct GlobalAnimPartControlInfo *part;
835 struct GraphicInfo *c = &anim->control_info;
838 printf("::: HandleGlobalAnim_Main: %d, %d => %d\n",
839 anim->mode_nr, anim->nr, anim->num_parts);
840 printf("::: %d, %d, %d\n", global.num_toons, setup.toons, num_toons);
844 printf("::: %s(%d): %d, %d, %d [%d]\n",
845 (action == ANIM_START ? "ANIM_START" :
846 action == ANIM_CONTINUE ? "ANIM_CONTINUE" :
847 action == ANIM_STOP ? "ANIM_STOP" : "(should not happen)"),
849 anim->state & ANIM_STATE_RESTART,
850 anim->state & ANIM_STATE_WAITING,
851 anim->state & ANIM_STATE_RUNNING,
858 anim->state = ANIM_STATE_RESTART;
859 anim->part_counter = 0;
860 anim->active_part_nr = 0;
865 if (anim->state == ANIM_STATE_INACTIVE)
871 anim->state = ANIM_STATE_INACTIVE;
879 if (c->anim_mode & ANIM_ALL || anim->num_parts == 0)
881 int num_parts = anim->num_parts + (anim->has_base ? 1 : 0);
885 printf("::: HandleGlobalAnim_Main: %d, %d => %d\n",
886 anim->mode_nr, anim->nr, num_parts);
889 for (i = 0; i < num_parts; i++)
891 part = &anim->part[i];
896 anim->state = ANIM_STATE_RUNNING;
897 part->state = ANIM_STATE_RESTART;
902 if (part->state == ANIM_STATE_INACTIVE)
908 part->state = ANIM_STATE_INACTIVE;
916 part->state = HandleGlobalAnim_Part(part, part->state);
918 // when animation mode is "once", stop after animation was played once
919 if (c->anim_mode & ANIM_ONCE &&
920 part->state & ANIM_STATE_RESTART)
921 part->state = ANIM_STATE_INACTIVE;
927 if (anim->state & ANIM_STATE_RESTART) // directly after restart
928 anim->active_part_nr = getGlobalAnimationPart(anim);
930 part = &anim->part[anim->active_part_nr];
932 part->state = ANIM_STATE_RUNNING;
934 anim->state = HandleGlobalAnim_Part(part, anim->state);
936 if (anim->state & ANIM_STATE_RESTART)
937 anim->part_counter++;
939 // when animation mode is "once", stop after all animations were played once
940 if (c->anim_mode & ANIM_ONCE &&
941 anim->part_counter == anim->num_parts)
942 anim->state = ANIM_STATE_INACTIVE;
945 void HandleGlobalAnim_Mode(struct GlobalAnimControlInfo *ctrl, int action)
950 printf("::: HandleGlobalAnim_Mode: %d => %d\n",
951 ctrl->nr, ctrl->num_anims);
954 for (i = 0; i < ctrl->num_anims; i++)
955 HandleGlobalAnim_Main(&ctrl->anim[i], action);
958 static void HandleGlobalAnim(int action, int game_mode)
961 printf("::: HandleGlobalAnim [mode == %d]\n", game_status);
964 HandleGlobalAnim_Mode(&global_anim_ctrl[game_mode], action);
975 static void DoAnimationExt()
980 printf("::: DoAnimation [%d, %d]\n", anim_sync_frame, Counter());
984 WaitUntilDelayReached(&anim_sync_frame_delay, anim_sync_frame_delay_value);
987 if (DelayReached(&anim_sync_frame_delay, anim_sync_frame_delay_value))
991 for (i = 0; i < NUM_GAME_MODES; i++)
992 HandleGlobalAnim(ANIM_CONTINUE, i);
995 // force screen redraw in next frame to continue drawing global animations
996 redraw_mask = REDRAW_ALL;
1002 // HandleAnimation(ANIM_CONTINUE);
1005 // force screen redraw in next frame to continue drawing global animations
1006 redraw_mask = REDRAW_ALL;