X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fcartoons.c;h=6768c505f062829e2cd6aa2493bc5a3391f80f91;hb=6f25a5c9cc138edfbfe689fdfed1488bc6e60b23;hp=0352e4f85ab17ed5fa8babc68a3c8798d8dce6ab;hpb=9f88e49643566b03fbd6e92509bb66fd42bc1daa;p=rocksndiamonds.git diff --git a/src/cartoons.c b/src/cartoons.c index 0352e4f8..6768c505 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 @@ -160,6 +162,38 @@ static int getGlobalAnimationPart(struct GlobalAnimMainControlInfo *anim) return part_nr; } +static int compareGlobalAnimPartControlInfo(const void *obj1, const void *obj2) +{ + const struct GlobalAnimPartControlInfo *o1 = + (struct GlobalAnimPartControlInfo *)obj1; + const struct GlobalAnimPartControlInfo *o2 = + (struct GlobalAnimPartControlInfo *)obj2; + int compare_result; + + if (o1->control_info.draw_order != o2->control_info.draw_order) + compare_result = o1->control_info.draw_order - o2->control_info.draw_order; + else + compare_result = o1->nr - o2->nr; + + return compare_result; +} + +static int compareGlobalAnimMainControlInfo(const void *obj1, const void *obj2) +{ + const struct GlobalAnimMainControlInfo *o1 = + (struct GlobalAnimMainControlInfo *)obj1; + const struct GlobalAnimMainControlInfo *o2 = + (struct GlobalAnimMainControlInfo *)obj2; + int compare_result; + + if (o1->control_info.draw_order != o2->control_info.draw_order) + compare_result = o1->control_info.draw_order - o2->control_info.draw_order; + else + compare_result = o1->nr - o2->nr; + + return compare_result; +} + static void PrepareBackbuffer() { if (game_status != GAME_MODE_PLAYING) @@ -382,6 +416,27 @@ void InitGlobalAnimControls() InitToonControls(); + /* sort all animations according to draw_order and animation number */ + for (m = 0; m < NUM_GAME_MODES; m++) + { + struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[m]; + + /* sort all main animations for this game mode */ + qsort(ctrl->anim, ctrl->num_anims, + sizeof(struct GlobalAnimMainControlInfo), + compareGlobalAnimMainControlInfo); + + for (a = 0; a < ctrl->num_anims; a++) + { + struct GlobalAnimMainControlInfo *anim = &ctrl->anim[a]; + + /* sort all animation parts for this main animation */ + qsort(anim->part, anim->num_parts, + sizeof(struct GlobalAnimPartControlInfo), + compareGlobalAnimPartControlInfo); + } + } + for (i = 0; i < NUM_GAME_MODES; i++) game_mode_anim_classes[i] = ANIM_CLASS_NONE; for (i = 0; game_mode_anim_classes_list[i].game_mode != -1; i++) @@ -405,14 +460,19 @@ void InitGlobalAnimations() void DrawGlobalAnimExt(int drawing_stage) { - int anim_classes = game_mode_anim_classes[global.anim_status_next]; int mode_nr; - int i; - // start or stop global animations by change of game mode - // (special handling of animations for "current screen" and "all screens") if (global.anim_status != anim_status_last) { + boolean before_fading = (global.anim_status == GAME_MODE_PSEUDO_FADING); + boolean after_fading = (anim_status_last == GAME_MODE_PSEUDO_FADING); + int anim_classes_next = game_mode_anim_classes[global.anim_status_next]; + int i; + + // ---------- part 1 ------------------------------------------------------ + // start or stop global animations by change of game mode + // (special handling of animations for "current screen" and "all screens") + // stop animations for last screen HandleGlobalAnim(ANIM_STOP, anim_status_last); @@ -423,27 +483,30 @@ void DrawGlobalAnimExt(int drawing_stage) if (anim_status_last == GAME_MODE_LOADING) HandleGlobalAnim(ANIM_START, GAME_MODE_DEFAULT); - anim_status_last = global.anim_status; - } + // ---------- part 2 ------------------------------------------------------ + // start or stop global animations by change of animation class + // (generic handling of animations for "class of screens") - // start or stop global animations by change of animation class - // (generic handling of animations for "class of screens") - if (anim_classes != anim_classes_last) - { for (i = 0; i < NUM_ANIM_CLASSES; i++) { int anim_class_check = (1 << i); int anim_class_game_mode = anim_class_game_modes[i]; int anim_class_last = anim_classes_last & anim_class_check; - int anim_class = anim_classes & anim_class_check; + int anim_class_next = anim_classes_next & anim_class_check; - if (anim_class_last && !anim_class) + // stop animations for changed screen class before fading to new screen + if (before_fading && anim_class_last && !anim_class_next) HandleGlobalAnim(ANIM_STOP, anim_class_game_mode); - else if (!anim_class_last && anim_class) + + // start animations for changed screen class after fading to new screen + if (after_fading && !anim_class_last && anim_class_next) HandleGlobalAnim(ANIM_START, anim_class_game_mode); } - anim_classes_last = anim_classes; + if (after_fading) + anim_classes_last = anim_classes_next; + + anim_status_last = global.anim_status; } if (!setup.toons || global.anim_status == GAME_MODE_LOADING) @@ -522,6 +585,9 @@ void DrawGlobalAnimExt(int drawing_stage) 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; @@ -772,7 +838,7 @@ void HandleGlobalAnim_Main(struct GlobalAnimMainControlInfo *anim, int action) { struct GlobalAnimPartControlInfo *part; struct GraphicInfo *c = &anim->control_info; - boolean skip = FALSE; + int state, active_part_nr; #if 0 printf("::: HandleGlobalAnim_Main: %d, %d => %d\n", @@ -795,24 +861,25 @@ 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; - skip = TRUE; break; case ANIM_CONTINUE: if (anim->state == ANIM_STATE_INACTIVE) - skip = TRUE; + return; + + anim->state = anim->last_state; + anim->active_part_nr = anim->last_active_part_nr; break; case ANIM_STOP: anim->state = ANIM_STATE_INACTIVE; - skip = TRUE; - break; + return; default: break; @@ -837,37 +904,37 @@ void HandleGlobalAnim_Main(struct GlobalAnimMainControlInfo *anim, int action) case ANIM_START: anim->state = ANIM_STATE_RUNNING; part->state = ANIM_STATE_RESTART; - skip = TRUE; break; case ANIM_CONTINUE: if (part->state == ANIM_STATE_INACTIVE) - skip = TRUE; + continue; break; case ANIM_STOP: part->state = ANIM_STATE_INACTIVE; - skip = TRUE; - break; + continue; default: break; } - if (skip) - continue; - part->state = HandleGlobalAnim_Part(part, part->state); + + // when animation mode is "once", stop after animation was played once + if (c->anim_mode & ANIM_ONCE && + part->state & ANIM_STATE_RESTART) + part->state = ANIM_STATE_INACTIVE; } - return; - } + anim->last_state = anim->state; + anim->last_active_part_nr = anim->active_part_nr; - if (skip) return; + } if (anim->state & ANIM_STATE_RESTART) // directly after restart anim->active_part_nr = getGlobalAnimationPart(anim); @@ -880,6 +947,36 @@ void HandleGlobalAnim_Main(struct GlobalAnimMainControlInfo *anim, int action) if (anim->state & ANIM_STATE_RESTART) anim->part_counter++; + + // when animation mode is "once", stop after all animations were played once + 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)