replaced toon animations by global animations (also handling toons)
[rocksndiamonds.git] / src / cartoons.c
1 // ============================================================================
2 // Rocks'n'Diamonds - McDuffin Strikes Back!
3 // ----------------------------------------------------------------------------
4 // (c) 1995-2014 by Artsoft Entertainment
5 //                  Holger Schemel
6 //                  info@artsoft.org
7 //                  http://www.artsoft.org/
8 // ----------------------------------------------------------------------------
9 // cartoons.c
10 // ============================================================================
11
12 #include "cartoons.h"
13 #include "main.h"
14 #include "tools.h"
15
16
17 /* values for global animation definition */
18 #define NUM_GLOBAL_ANIMS_AND_TOONS      (NUM_GLOBAL_ANIMS + 1)
19 #define NUM_GLOBAL_ANIM_PARTS_AND_TOONS MAX(NUM_GLOBAL_ANIM_PARTS_ALL,  \
20                                             MAX_NUM_TOONS)
21
22 struct GlobalAnimPartControlInfo
23 {
24   int nr;
25   int anim_nr;
26   int mode_nr;
27
28   int graphic;
29   struct GraphicInfo graphic_info;
30   struct GraphicInfo control_info;
31
32   int x, y;
33   int step_xoffset, step_yoffset;
34
35   boolean restart;
36   boolean waiting;
37   boolean running;
38
39   unsigned int initial_anim_sync_frame;
40   unsigned int step_frames, step_frames_value;
41   unsigned int step_delay, step_delay_value;
42
43   unsigned int init_delay, init_delay_value;
44   unsigned int anim_delay, anim_delay_value;
45   unsigned int post_delay, post_delay_value;
46 };
47
48 struct GlobalAnimMainControlInfo
49 {
50   struct GlobalAnimPartControlInfo base;
51   struct GlobalAnimPartControlInfo part[NUM_GLOBAL_ANIM_PARTS_AND_TOONS];
52
53   int nr;
54   int mode_nr;
55
56   struct GraphicInfo control_info;
57
58   int num_parts;
59   int part_counter;
60   int active_part_nr;
61
62   boolean has_base;
63
64   boolean restart;
65   boolean waiting;
66   boolean running;
67
68   unsigned int init_delay, init_delay_value;
69 };
70
71 struct GlobalAnimControlInfo
72 {
73   struct GlobalAnimMainControlInfo anim[NUM_GLOBAL_ANIMS_AND_TOONS];
74
75   int nr;
76   int num_anims;
77 };
78
79
80 /* forward declaration for internal use */
81 static void DoAnimationExt(void);
82
83 static struct GlobalAnimControlInfo global_anim_ctrl[NUM_SPECIAL_GFX_ARGS];
84 static struct ToonInfo toons[MAX_NUM_TOONS];
85
86 static unsigned int anim_sync_frame = 0;
87 static unsigned int anim_sync_frame_delay = 0;
88 static unsigned int anim_sync_frame_delay_value = GAME_FRAME_DELAY;
89
90 static boolean do_animations = FALSE;
91
92
93 static int getGlobalAnimationPart(struct GlobalAnimMainControlInfo *anim)
94 {
95   struct GraphicInfo *c = &anim->control_info;
96   int last_anim_random_frame = gfx.anim_random_frame;
97   int part_nr;
98
99   gfx.anim_random_frame = -1;   // (use simple, ad-hoc random numbers)
100
101   part_nr = getAnimationFrame(anim->num_parts, 1,
102                               c->anim_mode, c->anim_start_frame,
103                               anim->part_counter);
104
105   gfx.anim_random_frame = last_anim_random_frame;
106
107   return part_nr;
108 }
109
110 static void PrepareBackbuffer()
111 {
112   if (game_status != GAME_MODE_PLAYING)
113     return;
114
115   BlitScreenToBitmap(backbuffer);
116 }
117
118 boolean ToonNeedsRedraw()
119 {
120   return TRUE;
121 }
122
123 void InitToons()
124 {
125   int num_toons = MAX_NUM_TOONS;
126   int i;
127
128   if (global.num_toons >= 0 && global.num_toons < MAX_NUM_TOONS)
129     num_toons = global.num_toons;
130
131   for (i = 0; i < num_toons; i++)
132   {
133     int graphic = IMG_TOON_1 + i;
134     struct FileInfo *image = getImageListEntryFromImageID(graphic);
135
136     toons[i].bitmap = graphic_info[graphic].bitmap;
137
138     toons[i].src_x = graphic_info[graphic].src_x;
139     toons[i].src_y = graphic_info[graphic].src_y;
140
141     toons[i].width  = graphic_info[graphic].width;
142     toons[i].height = graphic_info[graphic].height;
143
144     toons[i].anim_frames      = graphic_info[graphic].anim_frames;
145     toons[i].anim_delay       = graphic_info[graphic].anim_delay;
146     toons[i].anim_mode        = graphic_info[graphic].anim_mode;
147     toons[i].anim_start_frame = graphic_info[graphic].anim_start_frame;
148
149     toons[i].step_offset = graphic_info[graphic].step_offset;
150     toons[i].step_delay  = graphic_info[graphic].step_delay;
151
152     toons[i].direction = image->parameter[GFX_ARG_DIRECTION];
153     toons[i].position = image->parameter[GFX_ARG_POSITION];
154   }
155
156   InitToonScreen(bitmap_db_toons,
157                  BackToFront, PrepareBackbuffer, ToonNeedsRedraw,
158                  toons, num_toons,
159                  REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE,
160                  GAME_FRAME_DELAY);
161 }
162
163 static void InitToonControls()
164 {
165   struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[GAME_MODE_DEFAULT];
166   struct GlobalAnimMainControlInfo *anim = &ctrl->anim[ctrl->num_anims];
167   int mode_nr, anim_nr, part_nr;
168   int control = IMG_INTERNAL_GLOBAL_TOON_DEFAULT;
169   int num_toons = MAX_NUM_TOONS;
170   int i;
171
172   if (global.num_toons >= 0 && global.num_toons < MAX_NUM_TOONS)
173     num_toons = global.num_toons;
174
175   mode_nr = GAME_MODE_DEFAULT;
176   anim_nr = ctrl->num_anims;
177
178   anim->nr = anim_nr;
179   anim->mode_nr = mode_nr;
180   anim->control_info = graphic_info[control];
181
182   anim->num_parts = 0;
183   anim->part_counter = 0;
184   anim->active_part_nr = 0;
185
186   anim->has_base = FALSE;
187
188   anim->restart = FALSE;
189   anim->waiting = FALSE;
190   anim->running = FALSE;
191
192   anim->init_delay = 0;
193   anim->init_delay_value = 0;
194
195   part_nr = 0;
196
197   for (i = 0; i < num_toons; i++)
198   {
199     struct GlobalAnimPartControlInfo *part = &anim->part[part_nr];
200     int graphic = IMG_TOON_1 + i;
201     int control = graphic;
202
203     part->nr = part_nr;
204     part->anim_nr = anim_nr;
205     part->mode_nr = mode_nr;
206     part->graphic = graphic;
207     part->graphic_info = graphic_info[graphic];
208     part->control_info = graphic_info[control];
209
210     part->graphic_info.anim_delay *= part->graphic_info.step_delay;
211
212     part->control_info.init_delay_fixed = 0;
213     part->control_info.init_delay_random = 150;
214
215     part->control_info.x = ARG_UNDEFINED_VALUE;
216     part->control_info.y = ARG_UNDEFINED_VALUE;
217
218     part->restart = FALSE;
219     part->waiting = FALSE;
220     part->running = FALSE;
221
222     part->step_frames = 0;
223     part->step_frames_value = graphic_info[control].step_frames;
224
225     part->step_delay = 0;
226     part->step_delay_value = graphic_info[control].step_delay;
227
228     anim->num_parts++;
229     part_nr++;
230   }
231
232   ctrl->num_anims++;
233 }
234
235 void InitGlobalAnimControls()
236 {
237   int m, a, p;
238   int mode_nr, anim_nr, part_nr;
239   int graphic, control;
240
241   anim_sync_frame = 0;
242
243   ResetDelayCounter(&anim_sync_frame_delay);
244
245   for (m = 0; m < NUM_SPECIAL_GFX_ARGS; m++)
246   {
247     mode_nr = m;
248
249     struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[mode_nr];
250
251     ctrl->nr = mode_nr;
252     ctrl->num_anims = 0;
253
254     anim_nr = 0;
255
256     for (a = 0; a < NUM_GLOBAL_ANIMS; a++)
257     {
258       struct GlobalAnimMainControlInfo *anim = &ctrl->anim[anim_nr];
259       int ctrl_id = GLOBAL_ANIM_ID_CONTROL_FIRST + a;
260
261       control = global_anim_info[ctrl_id].graphic[GLOBAL_ANIM_ID_PART_BASE][m];
262
263       // if no base animation parameters defined, use default values
264       if (control == IMG_UNDEFINED)
265         control = IMG_INTERNAL_GLOBAL_ANIM_DEFAULT;
266
267       anim->nr = anim_nr;
268       anim->mode_nr = mode_nr;
269       anim->control_info = graphic_info[control];
270
271       anim->num_parts = 0;
272       anim->part_counter = 0;
273       anim->active_part_nr = 0;
274
275       anim->has_base = FALSE;
276
277       anim->restart = FALSE;
278       anim->waiting = FALSE;
279       anim->running = FALSE;
280
281       anim->init_delay = 0;
282       anim->init_delay_value = 0;
283
284       part_nr = 0;
285
286       for (p = 0; p < NUM_GLOBAL_ANIM_PARTS_ALL; p++)
287       {
288         struct GlobalAnimPartControlInfo *part = &anim->part[part_nr];
289
290         graphic = global_anim_info[a].graphic[p][m];
291         control = global_anim_info[ctrl_id].graphic[p][m];
292
293         if (graphic == IMG_UNDEFINED || graphic_info[graphic].bitmap == NULL ||
294             control == IMG_UNDEFINED)
295           continue;
296
297 #if 0
298         printf("::: mode == %d, anim = %d, part = %d [%d, %d, %d] [%d]\n",
299                m, a, p, mode_nr, anim_nr, part_nr, control);
300 #endif
301
302         part->nr = part_nr;
303         part->anim_nr = anim_nr;
304         part->mode_nr = mode_nr;
305         part->graphic = graphic;
306         part->graphic_info = graphic_info[graphic];
307         part->control_info = graphic_info[control];
308
309         part->restart = FALSE;
310         part->waiting = FALSE;
311         part->running = FALSE;
312
313         part->step_frames = 0;
314         part->step_frames_value = graphic_info[control].step_frames;
315
316         part->step_delay = 0;
317         part->step_delay_value = graphic_info[control].step_delay;
318
319         if (p < GLOBAL_ANIM_ID_PART_BASE)
320         {
321           anim->num_parts++;
322           part_nr++;
323         }
324         else
325         {
326           anim->base = *part;
327           anim->has_base = TRUE;
328         }
329       }
330
331       if (anim->num_parts > 0 || anim->has_base)
332       {
333         ctrl->num_anims++;
334         anim_nr++;
335       }
336     }
337   }
338
339   InitToonControls();
340 }
341
342 void DrawGlobalAnim()
343 {
344   int mode_nr;
345
346   if (game_status == GAME_MODE_LOADING)
347     do_animations = FALSE;
348
349   if (!do_animations || !setup.toons)
350     return;
351
352   DoAnimationExt();
353
354   for (mode_nr = 0; mode_nr < NUM_SPECIAL_GFX_ARGS; mode_nr++)
355   {
356     struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[mode_nr];
357     int anim_nr;
358
359     if (mode_nr != GFX_SPECIAL_ARG_DEFAULT &&
360         mode_nr != game_status)
361       continue;
362
363     for (anim_nr = 0; anim_nr < ctrl->num_anims; anim_nr++)
364     {
365       struct GlobalAnimMainControlInfo *anim = &ctrl->anim[anim_nr];
366       struct GraphicInfo *c = &anim->control_info;
367       int part_first, part_last;
368       int part_nr;
369
370       if (!anim->running)
371         continue;
372
373       part_first = part_last = anim->active_part_nr;
374
375       if (c->anim_mode & ANIM_ALL || anim->num_parts == 0)
376       {
377         int num_parts = anim->num_parts + (anim->has_base ? 1 : 0);
378
379         part_first = 0;
380         part_last = num_parts - 1;
381       }
382
383       for (part_nr = part_first; part_nr <= part_last; part_nr++)
384       {
385         struct GlobalAnimPartControlInfo *part = &anim->part[part_nr];
386         struct GraphicInfo *g = &part->graphic_info;
387         Bitmap *src_bitmap;
388         int src_x, src_y;
389         int width  = g->width;
390         int height = g->height;
391         int dst_x = part->x;
392         int dst_y = part->y;
393         int cut_x = 0;
394         int cut_y = 0;
395         int sync_frame;
396         int frame;
397
398         if (!part->running)
399           continue;
400
401         if (part->x < 0)
402         {
403           dst_x = 0;
404           width += part->x;
405           cut_x = -part->x;
406         }
407         else if (part->x > FULL_SXSIZE - g->width)
408           width -= (part->x - (FULL_SXSIZE - g->width));
409
410         if (part->y < 0)
411         {
412           dst_y = 0;
413           height += part->y;
414           cut_y = -part->y;
415         }
416         else if (part->y > FULL_SYSIZE - g->height)
417           height -= (part->y - (FULL_SYSIZE - g->height));
418
419         dst_x += REAL_SX;
420         dst_y += REAL_SY;
421
422         sync_frame = anim_sync_frame - part->initial_anim_sync_frame;
423         frame = getAnimationFrame(g->anim_frames, g->anim_delay,
424                                   g->anim_mode, g->anim_start_frame,
425                                   sync_frame);
426
427         getFixedGraphicSource(part->graphic, frame, &src_bitmap,
428                               &src_x, &src_y);
429
430         src_x += cut_x;
431         src_y += cut_y;
432
433         BlitToScreenMasked(src_bitmap, src_x, src_y, width, height,
434                            dst_x, dst_y);
435       }
436     }
437   }
438 }
439
440 boolean HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part,
441                               boolean restart)
442 {
443   struct GraphicInfo *g = &part->graphic_info;
444   struct GraphicInfo *c = &part->control_info;
445
446   if (restart)
447   {
448     ResetDelayCounterExt(&part->step_delay, anim_sync_frame);
449
450     part->initial_anim_sync_frame = (g->anim_global_sync ? 0 : anim_sync_frame);
451     part->step_frames = 0;
452
453     if (c->direction & MV_HORIZONTAL)
454     {
455       int pos_bottom = FULL_SYSIZE - g->height;
456
457       if (c->position == POS_TOP)
458         part->y = 0;
459       else if (c->position == POS_UPPER)
460         part->y = GetSimpleRandom(pos_bottom / 2);
461       else if (c->position == POS_MIDDLE)
462         part->y = pos_bottom / 2;
463       else if (c->position == POS_LOWER)
464         part->y = pos_bottom / 2 + GetSimpleRandom(pos_bottom / 2);
465       else if (c->position == POS_BOTTOM)
466         part->y = pos_bottom;
467       else
468         part->y = GetSimpleRandom(pos_bottom);
469
470       if (c->direction == MV_RIGHT)
471       {
472         part->step_xoffset = c->step_offset;
473         part->x = -g->width + part->step_xoffset;
474       }
475       else
476       {
477         part->step_xoffset = -c->step_offset;
478         part->x = FULL_SXSIZE + part->step_xoffset;
479       }
480
481       part->step_yoffset = 0;
482     }
483     else if (c->direction & MV_VERTICAL)
484     {
485       int pos_right = FULL_SXSIZE - g->width;
486
487       if (c->position == POS_LEFT)
488         part->x = 0;
489       else if (c->position == POS_RIGHT)
490         part->x = pos_right;
491       else
492         part->x = GetSimpleRandom(pos_right);
493
494       if (c->direction == MV_DOWN)
495       {
496         part->step_yoffset = c->step_offset;
497         part->y = -g->height + part->step_yoffset;
498       }
499       else
500       {
501         part->step_yoffset = -c->step_offset;
502         part->y = FULL_SYSIZE + part->step_yoffset;
503       }
504
505       part->step_xoffset = 0;
506     }
507     else
508     {
509       part->x = 0;
510       part->y = 0;
511
512       part->step_xoffset = 0;
513       part->step_yoffset = 0;
514     }
515
516     if (c->x != ARG_UNDEFINED_VALUE)
517       part->x = c->x;
518     if (c->y != ARG_UNDEFINED_VALUE)
519       part->y = c->y;
520
521     if (c->step_xoffset != ARG_UNDEFINED_VALUE)
522       part->step_xoffset = c->step_xoffset;
523     if (c->step_yoffset != ARG_UNDEFINED_VALUE)
524       part->step_yoffset = c->step_yoffset;
525   }
526
527   if ((part->x <= -g->width    && part->step_xoffset <= 0) ||
528       (part->x >=  FULL_SXSIZE && part->step_xoffset >= 0) ||
529       (part->y <= -g->height   && part->step_yoffset <= 0) ||
530       (part->y >=  FULL_SYSIZE && part->step_yoffset >= 0))
531     return TRUE;
532
533   if (part->step_frames_value != ARG_UNDEFINED_VALUE &&
534       part->step_frames >= part->step_frames_value)
535     return TRUE;
536
537   if (!DelayReachedExt(&part->step_delay, part->step_delay_value,
538                        anim_sync_frame))
539     return FALSE;
540
541 #if 0
542   {
543     static unsigned int last_counter = -1;
544     unsigned int counter = Counter();
545
546     printf("::: NEXT ANIM PART [%d, %d]\n",
547            anim_sync_frame, counter - last_counter);
548
549     last_counter = counter;
550   }
551 #endif
552
553   part->x += part->step_xoffset;
554   part->y += part->step_yoffset;
555
556   part->step_frames++;
557
558   return FALSE;
559 }
560
561 void HandleGlobalAnim_Main(struct GlobalAnimMainControlInfo *anim, int action)
562 {
563   struct GlobalAnimPartControlInfo *part;
564   struct GraphicInfo *c = &anim->control_info;
565   struct GraphicInfo *cp;
566   boolean skip = FALSE;
567
568 #if 0
569   printf("::: HandleGlobalAnim_Main: %d, %d => %d\n",
570          anim->mode_nr, anim->nr, anim->num_parts);
571   printf("::: %d, %d, %d\n", global.num_toons, setup.toons, num_toons);
572 #endif
573
574 #if 0
575   printf("::: %s(%d): %d, %d, %d [%d]\n",
576          (action == ANIM_START ? "ANIM_START" :
577           action == ANIM_CONTINUE ? "ANIM_CONTINUE" :
578           action == ANIM_STOP ? "ANIM_STOP" : "(should not happen)"),
579          anim->nr,
580          anim->restart, anim->waiting, anim->running,
581          anim->num_parts);
582 #endif
583
584   switch (action)
585   {
586     case ANIM_START:
587       anim->restart = TRUE;
588       anim->waiting = FALSE;
589       anim->running = FALSE;
590       anim->part_counter = 0;
591       anim->active_part_nr = 0;
592       skip = TRUE;
593
594       break;
595
596     case ANIM_CONTINUE:
597       if (!anim->restart &&
598           !anim->waiting &&
599           !anim->running)
600         skip = TRUE;
601
602       break;
603
604     case ANIM_STOP:
605       anim->restart = FALSE;
606       anim->waiting = FALSE;
607       anim->running = FALSE;
608       skip = TRUE;
609
610       break;
611
612     default:
613       break;
614   }
615
616   if (c->anim_mode & ANIM_ALL || anim->num_parts == 0)
617   {
618     int num_parts = anim->num_parts + (anim->has_base ? 1 : 0);
619     int i;
620
621 #if 0
622     printf("::: HandleGlobalAnim_Main: %d, %d => %d\n",
623            anim->mode_nr, anim->nr, num_parts);
624 #endif
625
626     for (i = 0; i < num_parts; i++)
627     {
628       part = &anim->part[i];
629       cp = &part->control_info;
630
631       switch (action)
632       {
633         case ANIM_START:
634           anim->running = TRUE;
635
636           part->restart = TRUE;
637           part->waiting = FALSE;
638           part->running = FALSE;
639           skip = TRUE;
640
641           break;
642
643         case ANIM_CONTINUE:
644           if (!part->restart &&
645               !part->waiting &&
646               !part->running)
647             skip = TRUE;
648
649           break;
650
651         case ANIM_STOP:
652           part->restart = FALSE;
653           part->waiting = FALSE;
654           part->running = FALSE;
655           skip = TRUE;
656
657           break;
658
659         default:
660           break;
661       }
662
663       if (skip)
664         continue;
665
666       if (part->restart)
667       {
668 #if 0
669         printf("::: RESTART %d.%d\n", part->anim_nr, part->nr);
670 #endif
671
672         if (!part->waiting)
673         {
674 #if 0
675           printf("::: WAITING %d.%d\n", part->anim_nr, part->nr);
676 #endif
677
678           ResetDelayCounterExt(&part->init_delay, anim_sync_frame);
679
680           part->init_delay_value =
681             (cp->init_delay_fixed + GetSimpleRandom(cp->init_delay_random));
682
683           part->waiting = TRUE;
684         }
685
686         if (!DelayReachedExt(&part->init_delay, part->init_delay_value,
687                              anim_sync_frame))
688           return;
689
690 #if 0
691         printf("::: RUNNING %d.%d\n", part->anim_nr, part->nr);
692 #endif
693
694         part->waiting = FALSE;
695         part->running = TRUE;
696       }
697
698 #if 0
699       printf("::: DO PART %d.%d [%d, %d, %d] [%d]\n", part->anim_nr, part->nr,
700              part->restart, part->waiting, part->running,
701              anim->running);
702 #endif
703
704       part->restart = HandleGlobalAnim_Part(part, part->restart);
705
706       if (part->restart)
707         part->running = FALSE;
708     }
709
710     return;
711   }
712
713   if (skip)
714     return;
715
716   if (anim->restart && !anim->waiting)          // directly after restart
717     anim->active_part_nr = getGlobalAnimationPart(anim);
718
719   part = &anim->part[anim->active_part_nr];
720
721   if (anim->restart)
722   {
723     if (!anim->waiting)
724     {
725       cp = &part->control_info;
726
727       ResetDelayCounterExt(&part->init_delay, anim_sync_frame);
728
729       part->init_delay_value =
730         (cp->init_delay_fixed + GetSimpleRandom(cp->init_delay_random));
731
732       anim->waiting = TRUE;
733     }
734
735     if (!DelayReachedExt(&part->init_delay, part->init_delay_value,
736                          anim_sync_frame))
737       return;
738
739     anim->waiting = FALSE;
740     anim->running = TRUE;
741   }
742
743   part->running = TRUE;
744
745   anim->restart = HandleGlobalAnim_Part(part, anim->restart);
746
747   if (anim->restart)
748   {
749     anim->running = FALSE;
750
751     anim->part_counter++;
752   }
753 }
754
755 void HandleGlobalAnim_Mode(struct GlobalAnimControlInfo *ctrl, int action)
756 {
757   int i;
758
759 #if 0
760   printf("::: HandleGlobalAnim_Mode: %d => %d\n",
761          ctrl->nr, ctrl->num_anims);
762 #endif
763
764   for (i = 0; i < ctrl->num_anims; i++)
765     HandleGlobalAnim_Main(&ctrl->anim[i], action);
766 }
767
768 void HandleGlobalAnim(int action)
769 {
770 #if 0
771   printf("::: HandleGlobalAnim [mode == %d]\n", game_status);
772 #endif
773
774   HandleGlobalAnim_Mode(&global_anim_ctrl[GAME_MODE_DEFAULT], action);
775   HandleGlobalAnim_Mode(&global_anim_ctrl[game_status], action);
776 }
777
778 void InitAnimation()
779 {
780   // HandleAnimation(ANIM_START);
781
782 #if 0
783   printf("::: InitAnimation\n");
784 #endif
785
786   // InitCounter();
787
788   InitGlobalAnimControls();
789
790   HandleGlobalAnim(ANIM_START);
791
792   do_animations = TRUE;
793 }
794
795 void StopAnimation()
796 {
797   // HandleAnimation(ANIM_STOP);
798
799 #if 0
800   printf("::: StopAnimation\n");
801 #endif
802
803   HandleGlobalAnim(ANIM_STOP);
804
805   do_animations = FALSE;
806 }
807
808 static void DoAnimationExt()
809 {
810 #if 0
811   printf("::: DoAnimation [%d, %d]\n", anim_sync_frame, Counter());
812 #endif
813
814 #if 1
815   WaitUntilDelayReached(&anim_sync_frame_delay, anim_sync_frame_delay_value);
816   anim_sync_frame++;
817 #else
818   if (DelayReached(&anim_sync_frame_delay, anim_sync_frame_delay_value))
819     anim_sync_frame++;
820 #endif
821
822   HandleGlobalAnim(ANIM_CONTINUE);
823
824 #if 1
825   // force screen redraw in next frame to continue drawing global animations
826   redraw_mask = REDRAW_ALL;
827 #endif
828 }
829
830 void DoAnimation()
831 {
832   // HandleAnimation(ANIM_CONTINUE);
833
834 #if 1
835   // force screen redraw in next frame to continue drawing global animations
836   redraw_mask = REDRAW_ALL;
837 #endif
838 }