X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fcartoons.c;h=9b80de87e3ed2685a6da1247c970b6cb37f3c856;hb=cea1ea492e56f8816aa76b3d59ae44c4f3b73339;hp=e6b622dc94d51197069b3437e868abcca1ddf046;hpb=69ec0335692c5e18ca09c091df5a75f022f503f7;p=rocksndiamonds.git diff --git a/src/cartoons.c b/src/cartoons.c index e6b622dc..9b80de87 100644 --- a/src/cartoons.c +++ b/src/cartoons.c @@ -86,6 +86,8 @@ struct GlobalAnimMainControlInfo int init_delay_counter; int state; + + int last_state, last_active_part_nr; }; struct GlobalAnimControlInfo @@ -778,11 +780,25 @@ int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part, int state) 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) { @@ -796,6 +812,7 @@ int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part, int state) 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; } } @@ -836,6 +853,7 @@ void HandleGlobalAnim_Main(struct GlobalAnimMainControlInfo *anim, int action) { struct GlobalAnimPartControlInfo *part; struct GraphicInfo *c = &anim->control_info; + int state, active_part_nr; #if 0 printf("::: HandleGlobalAnim_Main: %d, %d => %d\n", @@ -858,9 +876,9 @@ void HandleGlobalAnim_Main(struct GlobalAnimMainControlInfo *anim, int action) 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; @@ -868,6 +886,9 @@ void HandleGlobalAnim_Main(struct GlobalAnimMainControlInfo *anim, int action) 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: @@ -924,6 +945,9 @@ void HandleGlobalAnim_Main(struct GlobalAnimMainControlInfo *anim, int action) part->state = ANIM_STATE_INACTIVE; } + anim->last_state = anim->state; + anim->last_active_part_nr = anim->active_part_nr; + return; } @@ -943,6 +967,31 @@ void HandleGlobalAnim_Main(struct GlobalAnimMainControlInfo *anim, int action) 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)