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
58 struct GraphicInfo graphic_info;
59 struct GraphicInfo control_info;
67 int step_xoffset, step_yoffset;
69 unsigned int initial_anim_sync_frame;
70 unsigned int step_delay, step_delay_value;
72 int init_delay_counter;
73 int anim_delay_counter;
74 int post_delay_counter;
82 struct GlobalAnimMainControlInfo
84 struct GlobalAnimPartControlInfo base;
85 struct GlobalAnimPartControlInfo part[NUM_GLOBAL_ANIM_PARTS_AND_TOONS];
90 struct GraphicInfo control_info;
98 int init_delay_counter;
102 int last_state, last_active_part_nr;
105 struct GlobalAnimControlInfo
107 struct GlobalAnimMainControlInfo anim[NUM_GLOBAL_ANIMS_AND_TOONS];
113 struct GameModeAnimClass
117 } game_mode_anim_classes_list[] =
119 { GAME_MODE_TITLE_INITIAL_1, ANIM_CLASS_TITLE_INITIAL },
120 { GAME_MODE_TITLE_INITIAL_2, ANIM_CLASS_TITLE_INITIAL },
121 { GAME_MODE_TITLE_INITIAL_3, ANIM_CLASS_TITLE_INITIAL },
122 { GAME_MODE_TITLE_INITIAL_4, ANIM_CLASS_TITLE_INITIAL },
123 { GAME_MODE_TITLE_INITIAL_5, ANIM_CLASS_TITLE_INITIAL },
124 { GAME_MODE_TITLE_1, ANIM_CLASS_TITLE },
125 { GAME_MODE_TITLE_2, ANIM_CLASS_TITLE },
126 { GAME_MODE_TITLE_3, ANIM_CLASS_TITLE },
127 { GAME_MODE_TITLE_4, ANIM_CLASS_TITLE },
128 { GAME_MODE_TITLE_5, ANIM_CLASS_TITLE },
129 { GAME_MODE_LEVELS, ANIM_CLASS_TOONS_MENU_SUBMENU },
130 { GAME_MODE_LEVELNR, ANIM_CLASS_TOONS_MENU_SUBMENU },
131 { GAME_MODE_INFO, ANIM_CLASS_TOONS_MENU_SUBMENU },
132 { GAME_MODE_SETUP, ANIM_CLASS_TOONS_MENU_SUBMENU },
133 { GAME_MODE_MAIN, ANIM_CLASS_TOONS_MENU },
134 { GAME_MODE_SCORES, ANIM_CLASS_TOONS },
139 struct AnimClassGameMode
143 } anim_class_game_modes_list[] =
145 { ANIM_CLASS_BIT_TITLE_INITIAL, GAME_MODE_TITLE_INITIAL },
146 { ANIM_CLASS_BIT_TITLE, GAME_MODE_TITLE },
147 { ANIM_CLASS_BIT_SUBMENU, GAME_MODE_PSEUDO_SUBMENU },
148 { ANIM_CLASS_BIT_MENU, GAME_MODE_PSEUDO_MENU },
149 { ANIM_CLASS_BIT_TOONS, GAME_MODE_PSEUDO_TOONS },
154 /* forward declaration for internal use */
155 static void HandleGlobalAnim(int, int);
156 static void DoAnimationExt(void);
158 static struct GlobalAnimControlInfo global_anim_ctrl[NUM_GAME_MODES];
159 static struct ToonInfo toons[MAX_NUM_TOONS];
161 static unsigned int anim_sync_frame = 0;
162 static unsigned int anim_sync_frame_delay = 0;
163 static unsigned int anim_sync_frame_delay_value = GAME_FRAME_DELAY;
165 static int game_mode_anim_classes[NUM_GAME_MODES];
166 static int anim_class_game_modes[NUM_ANIM_CLASSES];
168 static int anim_status_last = GAME_MODE_DEFAULT;
169 static int anim_classes_last = ANIM_CLASS_NONE;
172 static int getGlobalAnimationPart(struct GlobalAnimMainControlInfo *anim)
174 struct GraphicInfo *c = &anim->control_info;
175 int last_anim_random_frame = gfx.anim_random_frame;
178 gfx.anim_random_frame = -1; // (use simple, ad-hoc random numbers)
180 part_nr = getAnimationFrame(anim->num_parts, 1,
181 c->anim_mode, c->anim_start_frame,
184 gfx.anim_random_frame = last_anim_random_frame;
189 static int compareGlobalAnimPartControlInfo(const void *obj1, const void *obj2)
191 const struct GlobalAnimPartControlInfo *o1 =
192 (struct GlobalAnimPartControlInfo *)obj1;
193 const struct GlobalAnimPartControlInfo *o2 =
194 (struct GlobalAnimPartControlInfo *)obj2;
197 if (o1->control_info.draw_order != o2->control_info.draw_order)
198 compare_result = o1->control_info.draw_order - o2->control_info.draw_order;
200 compare_result = o1->nr - o2->nr;
202 return compare_result;
205 static int compareGlobalAnimMainControlInfo(const void *obj1, const void *obj2)
207 const struct GlobalAnimMainControlInfo *o1 =
208 (struct GlobalAnimMainControlInfo *)obj1;
209 const struct GlobalAnimMainControlInfo *o2 =
210 (struct GlobalAnimMainControlInfo *)obj2;
213 if (o1->control_info.draw_order != o2->control_info.draw_order)
214 compare_result = o1->control_info.draw_order - o2->control_info.draw_order;
216 compare_result = o1->nr - o2->nr;
218 return compare_result;
221 static void PrepareBackbuffer()
223 if (game_status != GAME_MODE_PLAYING)
226 BlitScreenToBitmap(backbuffer);
229 boolean ToonNeedsRedraw()
236 int num_toons = MAX_NUM_TOONS;
239 if (global.num_toons >= 0 && global.num_toons < MAX_NUM_TOONS)
240 num_toons = global.num_toons;
242 for (i = 0; i < num_toons; i++)
244 int graphic = IMG_TOON_1 + i;
245 struct FileInfo *image = getImageListEntryFromImageID(graphic);
247 toons[i].bitmap = graphic_info[graphic].bitmap;
249 toons[i].src_x = graphic_info[graphic].src_x;
250 toons[i].src_y = graphic_info[graphic].src_y;
252 toons[i].width = graphic_info[graphic].width;
253 toons[i].height = graphic_info[graphic].height;
255 toons[i].anim_frames = graphic_info[graphic].anim_frames;
256 toons[i].anim_delay = graphic_info[graphic].anim_delay;
257 toons[i].anim_mode = graphic_info[graphic].anim_mode;
258 toons[i].anim_start_frame = graphic_info[graphic].anim_start_frame;
260 toons[i].step_offset = graphic_info[graphic].step_offset;
261 toons[i].step_delay = graphic_info[graphic].step_delay;
263 toons[i].direction = image->parameter[GFX_ARG_DIRECTION];
264 toons[i].position = image->parameter[GFX_ARG_POSITION];
267 InitToonScreen(bitmap_db_toons,
268 BackToFront, PrepareBackbuffer, ToonNeedsRedraw,
270 REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE,
274 static void InitToonControls()
276 int mode_nr_toons = GAME_MODE_PSEUDO_TOONS;
277 struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[mode_nr_toons];
278 struct GlobalAnimMainControlInfo *anim = &ctrl->anim[ctrl->num_anims];
279 int mode_nr, anim_nr, part_nr;
280 int control = IMG_INTERNAL_GLOBAL_TOON_DEFAULT;
281 int num_toons = MAX_NUM_TOONS;
284 if (global.num_toons >= 0 && global.num_toons < MAX_NUM_TOONS)
285 num_toons = global.num_toons;
287 mode_nr = mode_nr_toons;
288 anim_nr = ctrl->num_anims;
291 anim->mode_nr = mode_nr;
292 anim->control_info = graphic_info[control];
295 anim->part_counter = 0;
296 anim->active_part_nr = 0;
298 anim->has_base = FALSE;
300 anim->init_delay_counter = 0;
302 anim->state = ANIM_STATE_INACTIVE;
306 for (i = 0; i < num_toons; i++)
308 struct GlobalAnimPartControlInfo *part = &anim->part[part_nr];
309 int sound = SND_UNDEFINED;
310 int graphic = IMG_TOON_1 + i;
311 int control = graphic;
314 part->anim_nr = anim_nr;
315 part->mode_nr = mode_nr;
317 part->graphic = graphic;
318 part->graphic_info = graphic_info[graphic];
319 part->control_info = graphic_info[control];
321 part->graphic_info.anim_delay *= part->graphic_info.step_delay;
323 part->control_info.init_delay_fixed = 0;
324 part->control_info.init_delay_random = 150;
326 part->control_info.x = ARG_UNDEFINED_VALUE;
327 part->control_info.y = ARG_UNDEFINED_VALUE;
329 part->initial_anim_sync_frame = 0;
331 part->step_delay = 0;
332 part->step_delay_value = graphic_info[control].step_delay;
334 part->state = ANIM_STATE_INACTIVE;
335 part->last_anim_status = -1;
344 void InitGlobalAnimControls()
347 int mode_nr, anim_nr, part_nr;
348 int sound, graphic, control;
352 ResetDelayCounter(&anim_sync_frame_delay);
354 for (m = 0; m < NUM_GAME_MODES; m++)
358 struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[mode_nr];
365 for (a = 0; a < NUM_GLOBAL_ANIMS; a++)
367 struct GlobalAnimMainControlInfo *anim = &ctrl->anim[anim_nr];
368 int ctrl_id = GLOBAL_ANIM_ID_CONTROL_FIRST + a;
370 control = global_anim_info[ctrl_id].graphic[GLOBAL_ANIM_ID_PART_BASE][m];
372 // if no base animation parameters defined, use default values
373 if (control == IMG_UNDEFINED)
374 control = IMG_INTERNAL_GLOBAL_ANIM_DEFAULT;
377 anim->mode_nr = mode_nr;
378 anim->control_info = graphic_info[control];
381 anim->part_counter = 0;
382 anim->active_part_nr = 0;
384 anim->has_base = FALSE;
386 anim->init_delay_counter = 0;
388 anim->state = ANIM_STATE_INACTIVE;
392 for (p = 0; p < NUM_GLOBAL_ANIM_PARTS_ALL; p++)
394 struct GlobalAnimPartControlInfo *part = &anim->part[part_nr];
396 sound = global_anim_info[a].sound[p][m];
397 graphic = global_anim_info[a].graphic[p][m];
398 control = global_anim_info[ctrl_id].graphic[p][m];
400 if (graphic == IMG_UNDEFINED || graphic_info[graphic].bitmap == NULL ||
401 control == IMG_UNDEFINED)
405 printf("::: mode == %d, anim = %d, part = %d [%d, %d, %d] [%d]\n",
406 m, a, p, mode_nr, anim_nr, part_nr, control);
410 printf("::: mode == %d, anim = %d, part = %d [%d, %d, %d] [%d]\n",
411 m, a, p, mode_nr, anim_nr, part_nr, sound);
415 part->anim_nr = anim_nr;
416 part->mode_nr = mode_nr;
418 part->graphic = graphic;
419 part->graphic_info = graphic_info[graphic];
420 part->control_info = graphic_info[control];
422 part->initial_anim_sync_frame = 0;
424 part->step_delay = 0;
425 part->step_delay_value = graphic_info[control].step_delay;
427 part->state = ANIM_STATE_INACTIVE;
428 part->last_anim_status = -1;
430 if (p < GLOBAL_ANIM_ID_PART_BASE)
438 anim->has_base = TRUE;
442 if (anim->num_parts > 0 || anim->has_base)
452 /* sort all animations according to draw_order and animation number */
453 for (m = 0; m < NUM_GAME_MODES; m++)
455 struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[m];
457 /* sort all main animations for this game mode */
458 qsort(ctrl->anim, ctrl->num_anims,
459 sizeof(struct GlobalAnimMainControlInfo),
460 compareGlobalAnimMainControlInfo);
462 for (a = 0; a < ctrl->num_anims; a++)
464 struct GlobalAnimMainControlInfo *anim = &ctrl->anim[a];
466 /* sort all animation parts for this main animation */
467 qsort(anim->part, anim->num_parts,
468 sizeof(struct GlobalAnimPartControlInfo),
469 compareGlobalAnimPartControlInfo);
473 for (i = 0; i < NUM_GAME_MODES; i++)
474 game_mode_anim_classes[i] = ANIM_CLASS_NONE;
475 for (i = 0; game_mode_anim_classes_list[i].game_mode != -1; i++)
476 game_mode_anim_classes[game_mode_anim_classes_list[i].game_mode] =
477 game_mode_anim_classes_list[i].class;
479 for (i = 0; i < NUM_ANIM_CLASSES; i++)
480 anim_class_game_modes[i] = GAME_MODE_DEFAULT;
481 for (i = 0; anim_class_game_modes_list[i].game_mode != -1; i++)
482 anim_class_game_modes[anim_class_game_modes_list[i].class_bit] =
483 anim_class_game_modes_list[i].game_mode;
485 anim_status_last = GAME_MODE_LOADING;
486 anim_classes_last = ANIM_CLASS_NONE;
489 void InitGlobalAnimations()
491 InitGlobalAnimControls();
494 void DrawGlobalAnimExt(int drawing_stage)
498 if (global.anim_status != anim_status_last)
500 boolean before_fading = (global.anim_status == GAME_MODE_PSEUDO_FADING);
501 boolean after_fading = (anim_status_last == GAME_MODE_PSEUDO_FADING);
502 int anim_classes_next = game_mode_anim_classes[global.anim_status_next];
505 // ---------- part 1 ------------------------------------------------------
506 // start or stop global animations by change of game mode
507 // (special handling of animations for "current screen" and "all screens")
509 // stop animations for last screen
510 HandleGlobalAnim(ANIM_STOP, anim_status_last);
512 // start animations for current screen
513 HandleGlobalAnim(ANIM_START, global.anim_status);
515 // start animations for all screens after loading new artwork set
516 if (anim_status_last == GAME_MODE_LOADING)
517 HandleGlobalAnim(ANIM_START, GAME_MODE_DEFAULT);
519 // ---------- part 2 ------------------------------------------------------
520 // start or stop global animations by change of animation class
521 // (generic handling of animations for "class of screens")
523 for (i = 0; i < NUM_ANIM_CLASSES; i++)
525 int anim_class_check = (1 << i);
526 int anim_class_game_mode = anim_class_game_modes[i];
527 int anim_class_last = anim_classes_last & anim_class_check;
528 int anim_class_next = anim_classes_next & anim_class_check;
530 // stop animations for changed screen class before fading to new screen
531 if (before_fading && anim_class_last && !anim_class_next)
532 HandleGlobalAnim(ANIM_STOP, anim_class_game_mode);
534 // start animations for changed screen class after fading to new screen
535 if (after_fading && !anim_class_last && anim_class_next)
536 HandleGlobalAnim(ANIM_START, anim_class_game_mode);
540 anim_classes_last = anim_classes_next;
542 anim_status_last = global.anim_status;
545 if (!setup.toons || global.anim_status == GAME_MODE_LOADING)
548 if (drawing_stage == DRAW_GLOBAL_ANIM_STAGE_1)
551 for (mode_nr = 0; mode_nr < NUM_GAME_MODES; mode_nr++)
553 struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[mode_nr];
557 if (mode_nr != GFX_SPECIAL_ARG_DEFAULT &&
558 mode_nr != game_status)
562 for (anim_nr = 0; anim_nr < ctrl->num_anims; anim_nr++)
564 struct GlobalAnimMainControlInfo *anim = &ctrl->anim[anim_nr];
565 struct GraphicInfo *c = &anim->control_info;
566 int part_first, part_last;
569 if (!(anim->state & ANIM_STATE_RUNNING))
572 part_first = part_last = anim->active_part_nr;
574 if (c->anim_mode & ANIM_ALL || anim->num_parts == 0)
576 int num_parts = anim->num_parts + (anim->has_base ? 1 : 0);
579 part_last = num_parts - 1;
582 for (part_nr = part_first; part_nr <= part_last; part_nr++)
584 struct GlobalAnimPartControlInfo *part = &anim->part[part_nr];
585 struct GraphicInfo *g = &part->graphic_info;
588 int width = g->width;
589 int height = g->height;
597 if (!(part->state & ANIM_STATE_RUNNING))
600 if (part->drawing_stage != drawing_stage)
609 else if (part->x > part->viewport_width - g->width)
610 width -= (part->x - (part->viewport_width - g->width));
618 else if (part->y > part->viewport_height - g->height)
619 height -= (part->y - (part->viewport_height - g->height));
621 if (width <= 0 || height <= 0)
624 dst_x += part->viewport_x;
625 dst_y += part->viewport_y;
627 sync_frame = anim_sync_frame - part->initial_anim_sync_frame;
628 frame = getAnimationFrame(g->anim_frames, g->anim_delay,
629 g->anim_mode, g->anim_start_frame,
632 getFixedGraphicSource(part->graphic, frame, &src_bitmap,
638 BlitToScreenMasked(src_bitmap, src_x, src_y, width, height,
645 void DrawGlobalAnim(int drawing_stage)
647 DrawGlobalAnimExt(drawing_stage);
650 boolean SetGlobalAnimPart_Viewport(struct GlobalAnimPartControlInfo *part)
656 boolean changed = FALSE;
658 if (part->last_anim_status == global.anim_status)
661 part->last_anim_status = global.anim_status;
663 part->drawing_stage = DRAW_GLOBAL_ANIM_STAGE_1;
665 if (part->control_info.class == get_hash_from_key("window") ||
666 part->control_info.class == get_hash_from_key("border"))
670 viewport_width = WIN_XSIZE;
671 viewport_height = WIN_YSIZE;
673 part->drawing_stage = DRAW_GLOBAL_ANIM_STAGE_2;
675 else if (part->control_info.class == get_hash_from_key("door_1"))
679 viewport_width = DXSIZE;
680 viewport_height = DYSIZE;
682 else if (part->control_info.class == get_hash_from_key("door_2"))
686 viewport_width = VXSIZE;
687 viewport_height = VYSIZE;
689 else // default: "playfield"
691 viewport_x = REAL_SX;
692 viewport_y = REAL_SY;
693 viewport_width = FULL_SXSIZE;
694 viewport_height = FULL_SYSIZE;
697 if (viewport_x != part->viewport_x ||
698 viewport_y != part->viewport_y ||
699 viewport_width != part->viewport_width ||
700 viewport_height != part->viewport_height)
702 part->viewport_x = viewport_x;
703 part->viewport_y = viewport_y;
704 part->viewport_width = viewport_width;
705 part->viewport_height = viewport_height;
713 void PlayGlobalAnimSound(struct GlobalAnimPartControlInfo *part)
715 int sound = part->sound;
717 if (sound == SND_UNDEFINED)
720 if ((!setup.sound_simple && !IS_LOOP_SOUND(sound)) ||
721 (!setup.sound_loops && IS_LOOP_SOUND(sound)))
724 // !!! TODO: ADD STEREO POSITION FOR MOVING ANIMATIONS !!!
725 if (IS_LOOP_SOUND(sound))
726 PlaySoundLoop(sound);
731 printf("::: PLAY %d.%d.%d: %d\n",
732 part->anim_nr, part->nr, part->mode_nr, sound);
736 void StopGlobalAnimSound(struct GlobalAnimPartControlInfo *part)
738 int sound = part->sound;
740 if (sound == SND_UNDEFINED)
746 printf("::: STOP %d.%d.%d: %d\n",
747 part->anim_nr, part->nr, part->mode_nr, sound);
751 int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part, int state)
753 struct GraphicInfo *g = &part->graphic_info;
754 struct GraphicInfo *c = &part->control_info;
755 boolean viewport_changed = SetGlobalAnimPart_Viewport(part);
757 if (viewport_changed)
758 state |= ANIM_STATE_RESTART;
760 if (state & ANIM_STATE_RESTART)
762 ResetDelayCounterExt(&part->step_delay, anim_sync_frame);
764 part->init_delay_counter =
765 (c->init_delay_fixed + GetSimpleRandom(c->init_delay_random));
767 part->anim_delay_counter =
768 (c->anim_delay_fixed + GetSimpleRandom(c->anim_delay_random));
770 part->initial_anim_sync_frame =
771 (g->anim_global_sync ? 0 : anim_sync_frame + part->init_delay_counter);
773 if (c->direction & MV_HORIZONTAL)
775 int pos_bottom = part->viewport_height - g->height;
777 if (c->position == POS_TOP)
779 else if (c->position == POS_UPPER)
780 part->y = GetSimpleRandom(pos_bottom / 2);
781 else if (c->position == POS_MIDDLE)
782 part->y = pos_bottom / 2;
783 else if (c->position == POS_LOWER)
784 part->y = pos_bottom / 2 + GetSimpleRandom(pos_bottom / 2);
785 else if (c->position == POS_BOTTOM)
786 part->y = pos_bottom;
788 part->y = GetSimpleRandom(pos_bottom);
790 if (c->direction == MV_RIGHT)
792 part->step_xoffset = c->step_offset;
793 part->x = -g->width + part->step_xoffset;
797 part->step_xoffset = -c->step_offset;
798 part->x = part->viewport_width + part->step_xoffset;
801 part->step_yoffset = 0;
803 else if (c->direction & MV_VERTICAL)
805 int pos_right = part->viewport_width - g->width;
807 if (c->position == POS_LEFT)
809 else if (c->position == POS_RIGHT)
812 part->x = GetSimpleRandom(pos_right);
814 if (c->direction == MV_DOWN)
816 part->step_yoffset = c->step_offset;
817 part->y = -g->height + part->step_yoffset;
821 part->step_yoffset = -c->step_offset;
822 part->y = part->viewport_height + part->step_yoffset;
825 part->step_xoffset = 0;
832 part->step_xoffset = 0;
833 part->step_yoffset = 0;
836 if (c->x != ARG_UNDEFINED_VALUE)
838 if (c->y != ARG_UNDEFINED_VALUE)
841 if (c->step_xoffset != ARG_UNDEFINED_VALUE)
842 part->step_xoffset = c->step_xoffset;
843 if (c->step_yoffset != ARG_UNDEFINED_VALUE)
844 part->step_yoffset = c->step_yoffset;
846 if (part->init_delay_counter == 0)
847 PlayGlobalAnimSound(part);
850 if (part->init_delay_counter > 0)
852 part->init_delay_counter--;
854 if (part->init_delay_counter == 0)
855 PlayGlobalAnimSound(part);
857 return ANIM_STATE_WAITING;
860 // check if moving animation has left the visible screen area
861 if ((part->x <= -g->width && part->step_xoffset <= 0) ||
862 (part->x >= part->viewport_width && part->step_xoffset >= 0) ||
863 (part->y <= -g->height && part->step_yoffset <= 0) ||
864 (part->y >= part->viewport_height && part->step_yoffset >= 0))
866 // do not stop animation before "anim" or "post" counter are finished
867 if (part->anim_delay_counter == 0 &&
868 part->post_delay_counter == 0)
870 StopGlobalAnimSound(part);
872 part->post_delay_counter =
873 (c->post_delay_fixed + GetSimpleRandom(c->post_delay_random));
875 if (part->post_delay_counter > 0)
876 return ANIM_STATE_RUNNING;
878 // drawing last frame not needed here -- animation not visible anymore
879 return ANIM_STATE_RESTART;
883 if (part->anim_delay_counter > 0)
885 part->anim_delay_counter--;
887 if (part->anim_delay_counter == 0)
889 StopGlobalAnimSound(part);
891 part->post_delay_counter =
892 (c->post_delay_fixed + GetSimpleRandom(c->post_delay_random));
894 if (part->post_delay_counter > 0)
895 return ANIM_STATE_RUNNING;
897 // additional state "RUNNING" required to not skip drawing last frame
898 return ANIM_STATE_RESTART | ANIM_STATE_RUNNING;
902 if (part->post_delay_counter > 0)
904 part->post_delay_counter--;
906 if (part->post_delay_counter == 0)
907 return ANIM_STATE_RESTART;
909 return ANIM_STATE_WAITING;
912 if (!DelayReachedExt(&part->step_delay, part->step_delay_value,
914 return ANIM_STATE_RUNNING;
918 static unsigned int last_counter = -1;
919 unsigned int counter = Counter();
921 printf("::: NEXT ANIM PART [%d, %d]\n",
922 anim_sync_frame, counter - last_counter);
924 last_counter = counter;
928 part->x += part->step_xoffset;
929 part->y += part->step_yoffset;
931 return ANIM_STATE_RUNNING;
934 void HandleGlobalAnim_Main(struct GlobalAnimMainControlInfo *anim, int action)
936 struct GlobalAnimPartControlInfo *part;
937 struct GraphicInfo *c = &anim->control_info;
938 int state, active_part_nr;
941 printf("::: HandleGlobalAnim_Main: %d, %d => %d\n",
942 anim->mode_nr, anim->nr, anim->num_parts);
943 printf("::: %d, %d, %d\n", global.num_toons, setup.toons, num_toons);
947 printf("::: %s(%d): %d, %d, %d [%d]\n",
948 (action == ANIM_START ? "ANIM_START" :
949 action == ANIM_CONTINUE ? "ANIM_CONTINUE" :
950 action == ANIM_STOP ? "ANIM_STOP" : "(should not happen)"),
952 anim->state & ANIM_STATE_RESTART,
953 anim->state & ANIM_STATE_WAITING,
954 anim->state & ANIM_STATE_RUNNING,
961 anim->state = anim->last_state = ANIM_STATE_RESTART;
962 anim->active_part_nr = anim->last_active_part_nr = 0;
963 anim->part_counter = 0;
968 if (anim->state == ANIM_STATE_INACTIVE)
971 anim->state = anim->last_state;
972 anim->active_part_nr = anim->last_active_part_nr;
977 anim->state = ANIM_STATE_INACTIVE;
980 int num_parts = anim->num_parts + (anim->has_base ? 1 : 0);
983 for (i = 0; i < num_parts; i++)
984 StopGlobalAnimSound(&anim->part[i]);
993 if (c->anim_mode & ANIM_ALL || anim->num_parts == 0)
995 int num_parts = anim->num_parts + (anim->has_base ? 1 : 0);
999 printf("::: HandleGlobalAnim_Main: %d, %d => %d\n",
1000 anim->mode_nr, anim->nr, num_parts);
1003 for (i = 0; i < num_parts; i++)
1005 part = &anim->part[i];
1010 anim->state = ANIM_STATE_RUNNING;
1011 part->state = ANIM_STATE_RESTART;
1016 if (part->state == ANIM_STATE_INACTIVE)
1022 part->state = ANIM_STATE_INACTIVE;
1030 part->state = HandleGlobalAnim_Part(part, part->state);
1032 // when animation mode is "once", stop after animation was played once
1033 if (c->anim_mode & ANIM_ONCE &&
1034 part->state & ANIM_STATE_RESTART)
1035 part->state = ANIM_STATE_INACTIVE;
1038 anim->last_state = anim->state;
1039 anim->last_active_part_nr = anim->active_part_nr;
1044 if (anim->state & ANIM_STATE_RESTART) // directly after restart
1045 anim->active_part_nr = getGlobalAnimationPart(anim);
1047 part = &anim->part[anim->active_part_nr];
1049 part->state = ANIM_STATE_RUNNING;
1051 anim->state = HandleGlobalAnim_Part(part, anim->state);
1053 if (anim->state & ANIM_STATE_RESTART)
1054 anim->part_counter++;
1056 // when animation mode is "once", stop after all animations were played once
1057 if (c->anim_mode & ANIM_ONCE &&
1058 anim->part_counter == anim->num_parts)
1059 anim->state = ANIM_STATE_INACTIVE;
1061 state = anim->state;
1062 active_part_nr = anim->active_part_nr;
1064 // while the animation parts are pausing (waiting or inactive), play the base
1065 // (main) animation; this corresponds to the "boring player animation" logic
1066 // (!!! KLUDGE WARNING: I THINK THIS IS A MESS THAT SHOULD BE CLEANED UP !!!)
1069 if (anim->state == ANIM_STATE_WAITING ||
1070 anim->state == ANIM_STATE_INACTIVE)
1072 anim->active_part_nr = anim->num_parts; // part nr of base animation
1073 part = &anim->part[anim->active_part_nr];
1075 if (anim->state != anim->last_state)
1076 part->state = ANIM_STATE_RESTART;
1078 anim->state = ANIM_STATE_RUNNING;
1079 part->state = HandleGlobalAnim_Part(part, part->state);
1083 anim->last_state = state;
1084 anim->last_active_part_nr = active_part_nr;
1087 void HandleGlobalAnim_Mode(struct GlobalAnimControlInfo *ctrl, int action)
1092 printf("::: HandleGlobalAnim_Mode: %d => %d\n",
1093 ctrl->nr, ctrl->num_anims);
1096 for (i = 0; i < ctrl->num_anims; i++)
1097 HandleGlobalAnim_Main(&ctrl->anim[i], action);
1100 static void HandleGlobalAnim(int action, int game_mode)
1103 printf("::: HandleGlobalAnim [mode == %d]\n", game_status);
1106 HandleGlobalAnim_Mode(&global_anim_ctrl[game_mode], action);
1109 void InitAnimation()
1113 void StopAnimation()
1117 static void DoAnimationExt()
1122 printf("::: DoAnimation [%d, %d]\n", anim_sync_frame, Counter());
1126 WaitUntilDelayReached(&anim_sync_frame_delay, anim_sync_frame_delay_value);
1129 if (DelayReached(&anim_sync_frame_delay, anim_sync_frame_delay_value))
1133 for (i = 0; i < NUM_GAME_MODES; i++)
1134 HandleGlobalAnim(ANIM_CONTINUE, i);
1137 // force screen redraw in next frame to continue drawing global animations
1138 redraw_mask = REDRAW_ALL;
1144 // HandleAnimation(ANIM_CONTINUE);
1147 // force screen redraw in next frame to continue drawing global animations
1148 redraw_mask = REDRAW_ALL;