#define NUM_GLOBAL_ANIM_PARTS_AND_TOONS MAX(NUM_GLOBAL_ANIM_PARTS_ALL, \
NUM_GLOBAL_TOON_PARTS)
-#define ANIM_CLASS_BIT_SUBMENU 0
-#define ANIM_CLASS_BIT_MENU 1
-#define ANIM_CLASS_BIT_TOONS 2
+#define ANIM_CLASS_BIT_TITLE_INITIAL 0
+#define ANIM_CLASS_BIT_TITLE 1
+#define ANIM_CLASS_BIT_SUBMENU 2
+#define ANIM_CLASS_BIT_MENU 3
+#define ANIM_CLASS_BIT_TOONS 4
-#define NUM_ANIM_CLASSES 3
+#define NUM_ANIM_CLASSES 5
#define ANIM_CLASS_NONE 0
+#define ANIM_CLASS_TITLE_INITIAL (1 << ANIM_CLASS_BIT_TITLE_INITIAL)
+#define ANIM_CLASS_TITLE (1 << ANIM_CLASS_BIT_TITLE)
#define ANIM_CLASS_SUBMENU (1 << ANIM_CLASS_BIT_SUBMENU)
#define ANIM_CLASS_MENU (1 << ANIM_CLASS_BIT_MENU)
#define ANIM_CLASS_TOONS (1 << ANIM_CLASS_BIT_TOONS)
+#define ANIM_CLASS_TOONS_MENU (ANIM_CLASS_TOONS | \
+ ANIM_CLASS_MENU)
+
+#define ANIM_CLASS_TOONS_MENU_SUBMENU (ANIM_CLASS_TOONS | \
+ ANIM_CLASS_MENU | \
+ ANIM_CLASS_SUBMENU)
struct GlobalAnimPartControlInfo
{
int init_delay_counter;
int state;
+
+ int last_state, last_active_part_nr;
};
struct GlobalAnimControlInfo
int class;
} game_mode_anim_classes_list[] =
{
- { GAME_MODE_LEVELS, ANIM_CLASS_TOONS | ANIM_CLASS_MENU | ANIM_CLASS_SUBMENU },
- { GAME_MODE_LEVELNR,ANIM_CLASS_TOONS | ANIM_CLASS_MENU | ANIM_CLASS_SUBMENU },
- { GAME_MODE_INFO, ANIM_CLASS_TOONS | ANIM_CLASS_MENU | ANIM_CLASS_SUBMENU },
- { GAME_MODE_SETUP, ANIM_CLASS_TOONS | ANIM_CLASS_MENU | ANIM_CLASS_SUBMENU },
- { GAME_MODE_MAIN, ANIM_CLASS_TOONS | ANIM_CLASS_MENU },
- { GAME_MODE_SCORES, ANIM_CLASS_TOONS },
-
- { -1, -1 }
+ { GAME_MODE_TITLE_INITIAL_1, ANIM_CLASS_TITLE_INITIAL },
+ { GAME_MODE_TITLE_INITIAL_2, ANIM_CLASS_TITLE_INITIAL },
+ { GAME_MODE_TITLE_INITIAL_3, ANIM_CLASS_TITLE_INITIAL },
+ { GAME_MODE_TITLE_INITIAL_4, ANIM_CLASS_TITLE_INITIAL },
+ { GAME_MODE_TITLE_INITIAL_5, ANIM_CLASS_TITLE_INITIAL },
+ { GAME_MODE_TITLE_1, ANIM_CLASS_TITLE },
+ { GAME_MODE_TITLE_2, ANIM_CLASS_TITLE },
+ { GAME_MODE_TITLE_3, ANIM_CLASS_TITLE },
+ { GAME_MODE_TITLE_4, ANIM_CLASS_TITLE },
+ { GAME_MODE_TITLE_5, ANIM_CLASS_TITLE },
+ { GAME_MODE_LEVELS, ANIM_CLASS_TOONS_MENU_SUBMENU },
+ { GAME_MODE_LEVELNR, ANIM_CLASS_TOONS_MENU_SUBMENU },
+ { GAME_MODE_INFO, ANIM_CLASS_TOONS_MENU_SUBMENU },
+ { GAME_MODE_SETUP, ANIM_CLASS_TOONS_MENU_SUBMENU },
+ { GAME_MODE_MAIN, ANIM_CLASS_TOONS_MENU },
+ { GAME_MODE_SCORES, ANIM_CLASS_TOONS },
+
+ { -1, -1 }
};
struct AnimClassGameMode
int game_mode;
} anim_class_game_modes_list[] =
{
- { ANIM_CLASS_BIT_SUBMENU, GAME_MODE_PSEUDO_SUBMENU },
- { ANIM_CLASS_BIT_MENU, GAME_MODE_PSEUDO_MENU },
- { ANIM_CLASS_BIT_TOONS, GAME_MODE_PSEUDO_TOONS },
+ { ANIM_CLASS_BIT_TITLE_INITIAL, GAME_MODE_TITLE_INITIAL },
+ { ANIM_CLASS_BIT_TITLE, GAME_MODE_TITLE },
+ { ANIM_CLASS_BIT_SUBMENU, GAME_MODE_PSEUDO_SUBMENU },
+ { ANIM_CLASS_BIT_MENU, GAME_MODE_PSEUDO_MENU },
+ { ANIM_CLASS_BIT_TOONS, GAME_MODE_PSEUDO_TOONS },
- { -1, -1 }
+ { -1, -1 }
};
/* forward declaration for internal use */
else if (part->y > part->viewport_height - g->height)
height -= (part->y - (part->viewport_height - g->height));
+ if (width <= 0 || height <= 0)
+ continue;
+
dst_x += part->viewport_x;
dst_y += part->viewport_y;
return ANIM_STATE_WAITING;
}
+ // check if moving animation has left the visible screen area
if ((part->x <= -g->width && part->step_xoffset <= 0) ||
(part->x >= part->viewport_width && part->step_xoffset >= 0) ||
(part->y <= -g->height && part->step_yoffset <= 0) ||
(part->y >= part->viewport_height && part->step_yoffset >= 0))
- return ANIM_STATE_RESTART;
+ {
+ // do not stop animation before "anim" or "post" counter are finished
+ if (part->anim_delay_counter == 0 &&
+ part->post_delay_counter == 0)
+ {
+ part->post_delay_counter =
+ (c->post_delay_fixed + GetSimpleRandom(c->post_delay_random));
+
+ if (part->post_delay_counter > 0)
+ return ANIM_STATE_RUNNING;
+
+ return ANIM_STATE_RESTART;
+ }
+ }
if (part->anim_delay_counter > 0)
{
if (part->post_delay_counter > 0)
return ANIM_STATE_RUNNING;
+ // additional state "RUNNING" required to not skip drawing last frame
return ANIM_STATE_RESTART | ANIM_STATE_RUNNING;
}
}
{
struct GlobalAnimPartControlInfo *part;
struct GraphicInfo *c = &anim->control_info;
+ int state, active_part_nr;
#if 0
printf("::: HandleGlobalAnim_Main: %d, %d => %d\n",
switch (action)
{
case ANIM_START:
- anim->state = ANIM_STATE_RESTART;
+ anim->state = anim->last_state = ANIM_STATE_RESTART;
+ anim->active_part_nr = anim->last_active_part_nr = 0;
anim->part_counter = 0;
- anim->active_part_nr = 0;
break;
if (anim->state == ANIM_STATE_INACTIVE)
return;
+ anim->state = anim->last_state;
+ anim->active_part_nr = anim->last_active_part_nr;
+
break;
case ANIM_STOP:
part->state = ANIM_STATE_INACTIVE;
}
+ anim->last_state = anim->state;
+ anim->last_active_part_nr = anim->active_part_nr;
+
return;
}
if (c->anim_mode & ANIM_ONCE &&
anim->part_counter == anim->num_parts)
anim->state = ANIM_STATE_INACTIVE;
+
+ state = anim->state;
+ active_part_nr = anim->active_part_nr;
+
+ // while the animation parts are pausing (waiting or inactive), play the base
+ // (main) animation; this corresponds to the "boring player animation" logic
+ // (!!! KLUDGE WARNING: I THINK THIS IS A MESS THAT SHOULD BE CLEANED UP !!!)
+ if (anim->has_base)
+ {
+ if (anim->state == ANIM_STATE_WAITING ||
+ anim->state == ANIM_STATE_INACTIVE)
+ {
+ anim->active_part_nr = anim->num_parts; // part nr of base animation
+ part = &anim->part[anim->active_part_nr];
+
+ if (anim->state != anim->last_state)
+ part->state = ANIM_STATE_RESTART;
+
+ anim->state = ANIM_STATE_RUNNING;
+ part->state = HandleGlobalAnim_Part(part, part->state);
+ }
+ }
+
+ anim->last_state = state;
+ anim->last_active_part_nr = active_part_nr;
}
void HandleGlobalAnim_Mode(struct GlobalAnimControlInfo *ctrl, int action)