moved waiting for initial delay to central animation function
[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 int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part, int state)
429 {
430   struct GraphicInfo *g = &part->graphic_info;
431   struct GraphicInfo *c = &part->control_info;
432
433   if (state & ANIM_STATE_RESTART)
434   {
435     ResetDelayCounterExt(&part->step_delay, anim_sync_frame);
436
437     part->init_delay_value =
438       (c->init_delay_fixed + GetSimpleRandom(c->init_delay_random));
439
440     part->initial_anim_sync_frame =
441       (g->anim_global_sync ? 0 : anim_sync_frame + part->init_delay_value);
442
443     part->step_frames = 0;
444
445     if (c->direction & MV_HORIZONTAL)
446     {
447       int pos_bottom = FULL_SYSIZE - g->height;
448
449       if (c->position == POS_TOP)
450         part->y = 0;
451       else if (c->position == POS_UPPER)
452         part->y = GetSimpleRandom(pos_bottom / 2);
453       else if (c->position == POS_MIDDLE)
454         part->y = pos_bottom / 2;
455       else if (c->position == POS_LOWER)
456         part->y = pos_bottom / 2 + GetSimpleRandom(pos_bottom / 2);
457       else if (c->position == POS_BOTTOM)
458         part->y = pos_bottom;
459       else
460         part->y = GetSimpleRandom(pos_bottom);
461
462       if (c->direction == MV_RIGHT)
463       {
464         part->step_xoffset = c->step_offset;
465         part->x = -g->width + part->step_xoffset;
466       }
467       else
468       {
469         part->step_xoffset = -c->step_offset;
470         part->x = FULL_SXSIZE + part->step_xoffset;
471       }
472
473       part->step_yoffset = 0;
474     }
475     else if (c->direction & MV_VERTICAL)
476     {
477       int pos_right = FULL_SXSIZE - g->width;
478
479       if (c->position == POS_LEFT)
480         part->x = 0;
481       else if (c->position == POS_RIGHT)
482         part->x = pos_right;
483       else
484         part->x = GetSimpleRandom(pos_right);
485
486       if (c->direction == MV_DOWN)
487       {
488         part->step_yoffset = c->step_offset;
489         part->y = -g->height + part->step_yoffset;
490       }
491       else
492       {
493         part->step_yoffset = -c->step_offset;
494         part->y = FULL_SYSIZE + part->step_yoffset;
495       }
496
497       part->step_xoffset = 0;
498     }
499     else
500     {
501       part->x = 0;
502       part->y = 0;
503
504       part->step_xoffset = 0;
505       part->step_yoffset = 0;
506     }
507
508     if (c->x != ARG_UNDEFINED_VALUE)
509       part->x = c->x;
510     if (c->y != ARG_UNDEFINED_VALUE)
511       part->y = c->y;
512
513     if (c->step_xoffset != ARG_UNDEFINED_VALUE)
514       part->step_xoffset = c->step_xoffset;
515     if (c->step_yoffset != ARG_UNDEFINED_VALUE)
516       part->step_yoffset = c->step_yoffset;
517   }
518
519   if (part->init_delay_value > 0)
520   {
521     part->init_delay_value--;
522
523     return ANIM_STATE_WAITING;
524   }
525
526   if ((part->x <= -g->width    && part->step_xoffset <= 0) ||
527       (part->x >=  FULL_SXSIZE && part->step_xoffset >= 0) ||
528       (part->y <= -g->height   && part->step_yoffset <= 0) ||
529       (part->y >=  FULL_SYSIZE && part->step_yoffset >= 0))
530     return ANIM_STATE_RESTART;
531
532   if (part->step_frames_value != ARG_UNDEFINED_VALUE &&
533       part->step_frames >= part->step_frames_value)
534     return ANIM_STATE_RESTART;
535
536   if (!DelayReachedExt(&part->step_delay, part->step_delay_value,
537                        anim_sync_frame))
538     return ANIM_STATE_RUNNING;
539
540 #if 0
541   {
542     static unsigned int last_counter = -1;
543     unsigned int counter = Counter();
544
545     printf("::: NEXT ANIM PART [%d, %d]\n",
546            anim_sync_frame, counter - last_counter);
547
548     last_counter = counter;
549   }
550 #endif
551
552   part->x += part->step_xoffset;
553   part->y += part->step_yoffset;
554
555   part->step_frames++;
556
557   return ANIM_STATE_RUNNING;
558 }
559
560 void HandleGlobalAnim_Main(struct GlobalAnimMainControlInfo *anim, int action)
561 {
562   struct GlobalAnimPartControlInfo *part;
563   struct GraphicInfo *c = &anim->control_info;
564   boolean skip = FALSE;
565
566 #if 0
567   printf("::: HandleGlobalAnim_Main: %d, %d => %d\n",
568          anim->mode_nr, anim->nr, anim->num_parts);
569   printf("::: %d, %d, %d\n", global.num_toons, setup.toons, num_toons);
570 #endif
571
572 #if 0
573   printf("::: %s(%d): %d, %d, %d [%d]\n",
574          (action == ANIM_START ? "ANIM_START" :
575           action == ANIM_CONTINUE ? "ANIM_CONTINUE" :
576           action == ANIM_STOP ? "ANIM_STOP" : "(should not happen)"),
577          anim->nr,
578          anim->state & ANIM_STATE_RESTART,
579          anim->state & ANIM_STATE_WAITING,
580          anim->state & ANIM_STATE_RUNNING,
581          anim->num_parts);
582 #endif
583
584   switch (action)
585   {
586     case ANIM_START:
587       anim->state = ANIM_STATE_RESTART;
588       anim->part_counter = 0;
589       anim->active_part_nr = 0;
590       skip = TRUE;
591
592       break;
593
594     case ANIM_CONTINUE:
595       if (anim->state == ANIM_STATE_INACTIVE)
596         skip = TRUE;
597
598       break;
599
600     case ANIM_STOP:
601       anim->state = ANIM_STATE_INACTIVE;
602       skip = TRUE;
603
604       break;
605
606     default:
607       break;
608   }
609
610   if (c->anim_mode & ANIM_ALL || anim->num_parts == 0)
611   {
612     int num_parts = anim->num_parts + (anim->has_base ? 1 : 0);
613     int i;
614
615 #if 0
616     printf("::: HandleGlobalAnim_Main: %d, %d => %d\n",
617            anim->mode_nr, anim->nr, num_parts);
618 #endif
619
620     for (i = 0; i < num_parts; i++)
621     {
622       part = &anim->part[i];
623
624       switch (action)
625       {
626         case ANIM_START:
627           anim->state = ANIM_STATE_RUNNING;
628           part->state = ANIM_STATE_RESTART;
629           skip = TRUE;
630
631           break;
632
633         case ANIM_CONTINUE:
634           if (part->state == ANIM_STATE_INACTIVE)
635             skip = TRUE;
636
637           break;
638
639         case ANIM_STOP:
640           part->state = ANIM_STATE_INACTIVE;
641           skip = TRUE;
642
643           break;
644
645         default:
646           break;
647       }
648
649 #if 0
650       printf("::: LOOPING ...\n");
651 #endif
652
653       if (skip)
654         continue;
655
656 #if 0
657       printf("::: DO PART (1) %d.%d [%d, %d, %d] [%d] [%d / %d]\n",
658              part->anim_nr, part->nr,
659              part->state & ANIM_STATE_RESTART,
660              part->state & ANIM_STATE_WAITING,
661              part->state & ANIM_STATE_RUNNING,
662              anim->state & ANIM_STATE_RUNNING,
663              part->step_frames, part->step_frames_value);
664 #endif
665
666       part->state = HandleGlobalAnim_Part(part, part->state);
667
668 #if 0
669       printf("::: DO PART (2) %d.%d [%d, %d, %d] [%d] [%d / %d]\n",
670              part->anim_nr, part->nr,
671              part->state & ANIM_STATE_RESTART,
672              part->state & ANIM_STATE_WAITING,
673              part->state & ANIM_STATE_RUNNING,
674              anim->state & ANIM_STATE_RUNNING,
675              part->step_frames, part->step_frames_value);
676 #endif
677     }
678
679     return;
680   }
681
682   if (skip)
683     return;
684
685   if (anim->state == ANIM_STATE_RESTART)        // directly after restart
686     anim->active_part_nr = getGlobalAnimationPart(anim);
687
688   part = &anim->part[anim->active_part_nr];
689
690   part->state = ANIM_STATE_RUNNING;
691
692   anim->state = HandleGlobalAnim_Part(part, anim->state);
693
694   if (anim->state == ANIM_STATE_RESTART)
695     anim->part_counter++;
696 }
697
698 void HandleGlobalAnim_Mode(struct GlobalAnimControlInfo *ctrl, int action)
699 {
700   int i;
701
702 #if 0
703   printf("::: HandleGlobalAnim_Mode: %d => %d\n",
704          ctrl->nr, ctrl->num_anims);
705 #endif
706
707   for (i = 0; i < ctrl->num_anims; i++)
708     HandleGlobalAnim_Main(&ctrl->anim[i], action);
709 }
710
711 void HandleGlobalAnim(int action)
712 {
713 #if 0
714   printf("::: HandleGlobalAnim [mode == %d]\n", game_status);
715 #endif
716
717   HandleGlobalAnim_Mode(&global_anim_ctrl[GAME_MODE_DEFAULT], action);
718   HandleGlobalAnim_Mode(&global_anim_ctrl[game_status], action);
719 }
720
721 void InitAnimation()
722 {
723   // HandleAnimation(ANIM_START);
724
725 #if 0
726   printf("::: InitAnimation\n");
727 #endif
728
729   // InitCounter();
730
731   InitGlobalAnimControls();
732
733   HandleGlobalAnim(ANIM_START);
734
735   do_animations = TRUE;
736 }
737
738 void StopAnimation()
739 {
740   // HandleAnimation(ANIM_STOP);
741
742 #if 0
743   printf("::: StopAnimation\n");
744 #endif
745
746   HandleGlobalAnim(ANIM_STOP);
747
748   do_animations = FALSE;
749 }
750
751 static void DoAnimationExt()
752 {
753 #if 0
754   printf("::: DoAnimation [%d, %d]\n", anim_sync_frame, Counter());
755 #endif
756
757 #if 1
758   WaitUntilDelayReached(&anim_sync_frame_delay, anim_sync_frame_delay_value);
759   anim_sync_frame++;
760 #else
761   if (DelayReached(&anim_sync_frame_delay, anim_sync_frame_delay_value))
762     anim_sync_frame++;
763 #endif
764
765   HandleGlobalAnim(ANIM_CONTINUE);
766
767 #if 1
768   // force screen redraw in next frame to continue drawing global animations
769   redraw_mask = REDRAW_ALL;
770 #endif
771 }
772
773 void DoAnimation()
774 {
775   // HandleAnimation(ANIM_CONTINUE);
776
777 #if 1
778   // force screen redraw in next frame to continue drawing global animations
779   redraw_mask = REDRAW_ALL;
780 #endif
781 }