+
+/* ========================================================================= */
+/* generic animation frame calculation */
+/* ========================================================================= */
+
+int getAnimationFrame(int num_frames, int delay, int mode, int start_frame,
+ int sync_frame)
+{
+ int frame = 0;
+
+ sync_frame += start_frame * delay;
+
+ if (mode & ANIM_LOOP) /* looping animation */
+ {
+ frame = (sync_frame % (delay * num_frames)) / delay;
+ }
+ else if (mode & ANIM_LINEAR) /* linear (non-looping) animation */
+ {
+ frame = sync_frame / delay;
+
+ if (frame > num_frames - 1)
+ frame = num_frames - 1;
+ }
+ else if (mode & ANIM_PINGPONG) /* oscillate (border frames once) */
+ {
+#if 1
+ int max_anim_frames = (num_frames > 1 ? 2 * num_frames - 2 : 1);
+#else
+ int max_anim_frames = 2 * num_frames - 2;
+#endif
+
+ frame = (sync_frame % (delay * max_anim_frames)) / delay;
+ frame = (frame < num_frames ? frame : max_anim_frames - frame);
+ }
+ else if (mode & ANIM_PINGPONG2) /* oscillate (border frames twice) */
+ {
+ int max_anim_frames = 2 * num_frames;
+
+ frame = (sync_frame % (delay * max_anim_frames)) / delay;
+ frame = (frame < num_frames ? frame : max_anim_frames - frame - 1);
+ }
+ else if (mode & ANIM_RANDOM) /* play frames in random order */
+ {
+ /* note: expect different frames for the same delay cycle! */
+
+ if (gfx.anim_random_frame < 0)
+ frame = SimpleRND(num_frames);
+ else
+ frame = gfx.anim_random_frame % num_frames;
+ }
+
+ if (mode & ANIM_REVERSE) /* use reverse animation direction */
+ frame = num_frames - frame - 1;
+
+ return frame;
+}
+
+
+/* ========================================================================= */
+/* toon animation functions */
+/* ========================================================================= */
+
+static int get_toon_direction(char *direction_string_raw)
+{
+ char *direction_string = getStringToLower(direction_string_raw);
+ int direction = (strcmp(direction_string, "left") == 0 ? MV_LEFT :
+ strcmp(direction_string, "right") == 0 ? MV_RIGHT :
+ strcmp(direction_string, "up") == 0 ? MV_UP :
+ strcmp(direction_string, "down") == 0 ? MV_DOWN :
+ MV_NO_MOVING);
+
+ free(direction_string);
+
+ return direction;
+}
+
+void InitToonScreen(Bitmap *save_buffer,