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 graphic = IMG_TOON_1 + i;
310 int control = graphic;
313 part->anim_nr = anim_nr;
314 part->mode_nr = mode_nr;
315 part->graphic = graphic;
316 part->graphic_info = graphic_info[graphic];
317 part->control_info = graphic_info[control];
319 part->graphic_info.anim_delay *= part->graphic_info.step_delay;
321 part->control_info.init_delay_fixed = 0;
322 part->control_info.init_delay_random = 150;
324 part->control_info.x = ARG_UNDEFINED_VALUE;
325 part->control_info.y = ARG_UNDEFINED_VALUE;
327 part->initial_anim_sync_frame = 0;
329 part->step_delay = 0;
330 part->step_delay_value = graphic_info[control].step_delay;
332 part->state = ANIM_STATE_INACTIVE;
333 part->last_anim_status = -1;
342 void InitGlobalAnimControls()
345 int mode_nr, anim_nr, part_nr;
346 int sound, graphic, control;
350 ResetDelayCounter(&anim_sync_frame_delay);
352 for (m = 0; m < NUM_GAME_MODES; m++)
356 struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[mode_nr];
363 for (a = 0; a < NUM_GLOBAL_ANIMS; a++)
365 struct GlobalAnimMainControlInfo *anim = &ctrl->anim[anim_nr];
366 int ctrl_id = GLOBAL_ANIM_ID_CONTROL_FIRST + a;
368 control = global_anim_info[ctrl_id].graphic[GLOBAL_ANIM_ID_PART_BASE][m];
370 // if no base animation parameters defined, use default values
371 if (control == IMG_UNDEFINED)
372 control = IMG_INTERNAL_GLOBAL_ANIM_DEFAULT;
375 anim->mode_nr = mode_nr;
376 anim->control_info = graphic_info[control];
379 anim->part_counter = 0;
380 anim->active_part_nr = 0;
382 anim->has_base = FALSE;
384 anim->init_delay_counter = 0;
386 anim->state = ANIM_STATE_INACTIVE;
390 for (p = 0; p < NUM_GLOBAL_ANIM_PARTS_ALL; p++)
392 struct GlobalAnimPartControlInfo *part = &anim->part[part_nr];
394 sound = global_anim_info[a].sound[p][m];
395 graphic = global_anim_info[a].graphic[p][m];
396 control = global_anim_info[ctrl_id].graphic[p][m];
398 if (graphic == IMG_UNDEFINED || graphic_info[graphic].bitmap == NULL ||
399 control == IMG_UNDEFINED)
403 printf("::: mode == %d, anim = %d, part = %d [%d, %d, %d] [%d]\n",
404 m, a, p, mode_nr, anim_nr, part_nr, control);
408 printf("::: mode == %d, anim = %d, part = %d [%d, %d, %d] [%d]\n",
409 m, a, p, mode_nr, anim_nr, part_nr, sound);
413 part->anim_nr = anim_nr;
414 part->mode_nr = mode_nr;
416 part->graphic = graphic;
417 part->graphic_info = graphic_info[graphic];
418 part->control_info = graphic_info[control];
420 part->initial_anim_sync_frame = 0;
422 part->step_delay = 0;
423 part->step_delay_value = graphic_info[control].step_delay;
425 part->state = ANIM_STATE_INACTIVE;
426 part->last_anim_status = -1;
428 if (p < GLOBAL_ANIM_ID_PART_BASE)
436 anim->has_base = TRUE;
440 if (anim->num_parts > 0 || anim->has_base)
450 /* sort all animations according to draw_order and animation number */
451 for (m = 0; m < NUM_GAME_MODES; m++)
453 struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[m];
455 /* sort all main animations for this game mode */
456 qsort(ctrl->anim, ctrl->num_anims,
457 sizeof(struct GlobalAnimMainControlInfo),
458 compareGlobalAnimMainControlInfo);
460 for (a = 0; a < ctrl->num_anims; a++)
462 struct GlobalAnimMainControlInfo *anim = &ctrl->anim[a];
464 /* sort all animation parts for this main animation */
465 qsort(anim->part, anim->num_parts,
466 sizeof(struct GlobalAnimPartControlInfo),
467 compareGlobalAnimPartControlInfo);
471 for (i = 0; i < NUM_GAME_MODES; i++)
472 game_mode_anim_classes[i] = ANIM_CLASS_NONE;
473 for (i = 0; game_mode_anim_classes_list[i].game_mode != -1; i++)
474 game_mode_anim_classes[game_mode_anim_classes_list[i].game_mode] =
475 game_mode_anim_classes_list[i].class;
477 for (i = 0; i < NUM_ANIM_CLASSES; i++)
478 anim_class_game_modes[i] = GAME_MODE_DEFAULT;
479 for (i = 0; anim_class_game_modes_list[i].game_mode != -1; i++)
480 anim_class_game_modes[anim_class_game_modes_list[i].class_bit] =
481 anim_class_game_modes_list[i].game_mode;
483 anim_status_last = GAME_MODE_LOADING;
484 anim_classes_last = ANIM_CLASS_NONE;
487 void InitGlobalAnimations()
489 InitGlobalAnimControls();
492 void DrawGlobalAnimExt(int drawing_stage)
496 if (global.anim_status != anim_status_last)
498 boolean before_fading = (global.anim_status == GAME_MODE_PSEUDO_FADING);
499 boolean after_fading = (anim_status_last == GAME_MODE_PSEUDO_FADING);
500 int anim_classes_next = game_mode_anim_classes[global.anim_status_next];
503 // ---------- part 1 ------------------------------------------------------
504 // start or stop global animations by change of game mode
505 // (special handling of animations for "current screen" and "all screens")
507 // stop animations for last screen
508 HandleGlobalAnim(ANIM_STOP, anim_status_last);
510 // start animations for current screen
511 HandleGlobalAnim(ANIM_START, global.anim_status);
513 // start animations for all screens after loading new artwork set
514 if (anim_status_last == GAME_MODE_LOADING)
515 HandleGlobalAnim(ANIM_START, GAME_MODE_DEFAULT);
517 // ---------- part 2 ------------------------------------------------------
518 // start or stop global animations by change of animation class
519 // (generic handling of animations for "class of screens")
521 for (i = 0; i < NUM_ANIM_CLASSES; i++)
523 int anim_class_check = (1 << i);
524 int anim_class_game_mode = anim_class_game_modes[i];
525 int anim_class_last = anim_classes_last & anim_class_check;
526 int anim_class_next = anim_classes_next & anim_class_check;
528 // stop animations for changed screen class before fading to new screen
529 if (before_fading && anim_class_last && !anim_class_next)
530 HandleGlobalAnim(ANIM_STOP, anim_class_game_mode);
532 // start animations for changed screen class after fading to new screen
533 if (after_fading && !anim_class_last && anim_class_next)
534 HandleGlobalAnim(ANIM_START, anim_class_game_mode);
538 anim_classes_last = anim_classes_next;
540 anim_status_last = global.anim_status;
543 if (!setup.toons || global.anim_status == GAME_MODE_LOADING)
546 if (drawing_stage == DRAW_GLOBAL_ANIM_STAGE_1)
549 for (mode_nr = 0; mode_nr < NUM_GAME_MODES; mode_nr++)
551 struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[mode_nr];
555 if (mode_nr != GFX_SPECIAL_ARG_DEFAULT &&
556 mode_nr != game_status)
560 for (anim_nr = 0; anim_nr < ctrl->num_anims; anim_nr++)
562 struct GlobalAnimMainControlInfo *anim = &ctrl->anim[anim_nr];
563 struct GraphicInfo *c = &anim->control_info;
564 int part_first, part_last;
567 if (!(anim->state & ANIM_STATE_RUNNING))
570 part_first = part_last = anim->active_part_nr;
572 if (c->anim_mode & ANIM_ALL || anim->num_parts == 0)
574 int num_parts = anim->num_parts + (anim->has_base ? 1 : 0);
577 part_last = num_parts - 1;
580 for (part_nr = part_first; part_nr <= part_last; part_nr++)
582 struct GlobalAnimPartControlInfo *part = &anim->part[part_nr];
583 struct GraphicInfo *g = &part->graphic_info;
586 int width = g->width;
587 int height = g->height;
595 if (!(part->state & ANIM_STATE_RUNNING))
598 if (part->drawing_stage != drawing_stage)
607 else if (part->x > part->viewport_width - g->width)
608 width -= (part->x - (part->viewport_width - g->width));
616 else if (part->y > part->viewport_height - g->height)
617 height -= (part->y - (part->viewport_height - g->height));
619 if (width <= 0 || height <= 0)
622 dst_x += part->viewport_x;
623 dst_y += part->viewport_y;
625 sync_frame = anim_sync_frame - part->initial_anim_sync_frame;
626 frame = getAnimationFrame(g->anim_frames, g->anim_delay,
627 g->anim_mode, g->anim_start_frame,
630 getFixedGraphicSource(part->graphic, frame, &src_bitmap,
636 BlitToScreenMasked(src_bitmap, src_x, src_y, width, height,
643 void DrawGlobalAnim(int drawing_stage)
645 DrawGlobalAnimExt(drawing_stage);
648 boolean SetGlobalAnimPart_Viewport(struct GlobalAnimPartControlInfo *part)
654 boolean changed = FALSE;
656 if (part->last_anim_status == global.anim_status)
659 part->last_anim_status = global.anim_status;
661 part->drawing_stage = DRAW_GLOBAL_ANIM_STAGE_1;
663 if (part->control_info.class == get_hash_from_key("window") ||
664 part->control_info.class == get_hash_from_key("border"))
668 viewport_width = WIN_XSIZE;
669 viewport_height = WIN_YSIZE;
671 part->drawing_stage = DRAW_GLOBAL_ANIM_STAGE_2;
673 else if (part->control_info.class == get_hash_from_key("door_1"))
677 viewport_width = DXSIZE;
678 viewport_height = DYSIZE;
680 else if (part->control_info.class == get_hash_from_key("door_2"))
684 viewport_width = VXSIZE;
685 viewport_height = VYSIZE;
687 else // default: "playfield"
689 viewport_x = REAL_SX;
690 viewport_y = REAL_SY;
691 viewport_width = FULL_SXSIZE;
692 viewport_height = FULL_SYSIZE;
695 if (viewport_x != part->viewport_x ||
696 viewport_y != part->viewport_y ||
697 viewport_width != part->viewport_width ||
698 viewport_height != part->viewport_height)
700 part->viewport_x = viewport_x;
701 part->viewport_y = viewport_y;
702 part->viewport_width = viewport_width;
703 part->viewport_height = viewport_height;
711 void PlayGlobalAnimSound(struct GlobalAnimPartControlInfo *part)
713 int sound = part->sound;
715 if (sound == SND_UNDEFINED)
718 if ((!setup.sound_simple && !IS_LOOP_SOUND(sound)) ||
719 (!setup.sound_loops && IS_LOOP_SOUND(sound)))
722 // !!! TODO: ADD STEREO POSITION FOR MOVING ANIMATIONS !!!
723 if (IS_LOOP_SOUND(sound))
724 PlaySoundLoop(sound);
729 printf("::: PLAY %d.%d.%d: %d\n",
730 part->anim_nr, part->nr, part->mode_nr, sound);
734 void StopGlobalAnimSound(struct GlobalAnimPartControlInfo *part)
736 int sound = part->sound;
738 if (sound == SND_UNDEFINED)
744 printf("::: STOP %d.%d.%d: %d\n",
745 part->anim_nr, part->nr, part->mode_nr, sound);
749 int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part, int state)
751 struct GraphicInfo *g = &part->graphic_info;
752 struct GraphicInfo *c = &part->control_info;
753 boolean viewport_changed = SetGlobalAnimPart_Viewport(part);
755 if (viewport_changed)
756 state |= ANIM_STATE_RESTART;
758 if (state & ANIM_STATE_RESTART)
760 ResetDelayCounterExt(&part->step_delay, anim_sync_frame);
762 part->init_delay_counter =
763 (c->init_delay_fixed + GetSimpleRandom(c->init_delay_random));
765 part->anim_delay_counter =
766 (c->anim_delay_fixed + GetSimpleRandom(c->anim_delay_random));
768 part->initial_anim_sync_frame =
769 (g->anim_global_sync ? 0 : anim_sync_frame + part->init_delay_counter);
771 if (c->direction & MV_HORIZONTAL)
773 int pos_bottom = part->viewport_height - g->height;
775 if (c->position == POS_TOP)
777 else if (c->position == POS_UPPER)
778 part->y = GetSimpleRandom(pos_bottom / 2);
779 else if (c->position == POS_MIDDLE)
780 part->y = pos_bottom / 2;
781 else if (c->position == POS_LOWER)
782 part->y = pos_bottom / 2 + GetSimpleRandom(pos_bottom / 2);
783 else if (c->position == POS_BOTTOM)
784 part->y = pos_bottom;
786 part->y = GetSimpleRandom(pos_bottom);
788 if (c->direction == MV_RIGHT)
790 part->step_xoffset = c->step_offset;
791 part->x = -g->width + part->step_xoffset;
795 part->step_xoffset = -c->step_offset;
796 part->x = part->viewport_width + part->step_xoffset;
799 part->step_yoffset = 0;
801 else if (c->direction & MV_VERTICAL)
803 int pos_right = part->viewport_width - g->width;
805 if (c->position == POS_LEFT)
807 else if (c->position == POS_RIGHT)
810 part->x = GetSimpleRandom(pos_right);
812 if (c->direction == MV_DOWN)
814 part->step_yoffset = c->step_offset;
815 part->y = -g->height + part->step_yoffset;
819 part->step_yoffset = -c->step_offset;
820 part->y = part->viewport_height + part->step_yoffset;
823 part->step_xoffset = 0;
830 part->step_xoffset = 0;
831 part->step_yoffset = 0;
834 if (c->x != ARG_UNDEFINED_VALUE)
836 if (c->y != ARG_UNDEFINED_VALUE)
839 if (c->step_xoffset != ARG_UNDEFINED_VALUE)
840 part->step_xoffset = c->step_xoffset;
841 if (c->step_yoffset != ARG_UNDEFINED_VALUE)
842 part->step_yoffset = c->step_yoffset;
844 if (part->init_delay_counter == 0)
845 PlayGlobalAnimSound(part);
848 if (part->init_delay_counter > 0)
850 part->init_delay_counter--;
852 if (part->init_delay_counter == 0)
853 PlayGlobalAnimSound(part);
855 return ANIM_STATE_WAITING;
858 // check if moving animation has left the visible screen area
859 if ((part->x <= -g->width && part->step_xoffset <= 0) ||
860 (part->x >= part->viewport_width && part->step_xoffset >= 0) ||
861 (part->y <= -g->height && part->step_yoffset <= 0) ||
862 (part->y >= part->viewport_height && part->step_yoffset >= 0))
864 // do not stop animation before "anim" or "post" counter are finished
865 if (part->anim_delay_counter == 0 &&
866 part->post_delay_counter == 0)
868 part->post_delay_counter =
869 (c->post_delay_fixed + GetSimpleRandom(c->post_delay_random));
871 if (part->post_delay_counter > 0)
872 return ANIM_STATE_RUNNING;
874 StopGlobalAnimSound(part);
876 return ANIM_STATE_RESTART;
880 if (part->anim_delay_counter > 0)
882 part->anim_delay_counter--;
884 if (part->anim_delay_counter == 0)
886 part->post_delay_counter =
887 (c->post_delay_fixed + GetSimpleRandom(c->post_delay_random));
889 if (part->post_delay_counter > 0)
890 return ANIM_STATE_RUNNING;
892 StopGlobalAnimSound(part);
894 // additional state "RUNNING" required to not skip drawing last frame
895 return ANIM_STATE_RESTART | ANIM_STATE_RUNNING;
899 if (part->post_delay_counter > 0)
901 part->post_delay_counter--;
903 if (part->post_delay_counter == 0)
904 StopGlobalAnimSound(part);
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;