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