X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fanim.c;h=fa124cb6ab692e957125a060b0d8ffe0a013ef96;hp=4a6d2db01199b4a21d20590740185ed84b69ffb7;hb=8b3a64c55ed158de2659a0479a232ee4d335ce48;hpb=a00af4d54f7f23fe9ed4ae7e3244895c4acc0158 diff --git a/src/anim.c b/src/anim.c index 4a6d2db0..fa124cb6 100644 --- a/src/anim.c +++ b/src/anim.c @@ -29,20 +29,25 @@ #define ANIM_CLASS_BIT_TITLE_INITIAL 0 #define ANIM_CLASS_BIT_TITLE 1 #define ANIM_CLASS_BIT_MAIN 2 -#define ANIM_CLASS_BIT_SUBMENU 3 -#define ANIM_CLASS_BIT_MENU 4 -#define ANIM_CLASS_BIT_TOONS 5 +#define ANIM_CLASS_BIT_SCORES 3 +#define ANIM_CLASS_BIT_SUBMENU 4 +#define ANIM_CLASS_BIT_MENU 5 +#define ANIM_CLASS_BIT_TOONS 6 -#define NUM_ANIM_CLASSES 6 +#define NUM_ANIM_CLASSES 7 #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_MAIN (1 << ANIM_CLASS_BIT_MAIN) +#define ANIM_CLASS_SCORES (1 << ANIM_CLASS_BIT_SCORES) #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_SCORES (ANIM_CLASS_TOONS | \ + ANIM_CLASS_SCORES) + #define ANIM_CLASS_TOONS_MENU_MAIN (ANIM_CLASS_TOONS | \ ANIM_CLASS_MENU | \ ANIM_CLASS_MAIN) @@ -126,6 +131,8 @@ struct GlobalAnimMainControlInfo boolean has_base; // animation has base/main/default animation part + int last_x, last_y; + int init_delay_counter; int state; @@ -163,7 +170,8 @@ struct GameModeAnimClass { GAME_MODE_SETUP, ANIM_CLASS_TOONS_MENU_SUBMENU }, { GAME_MODE_PSEUDO_MAINONLY, ANIM_CLASS_TOONS_MENU_MAIN }, { GAME_MODE_PSEUDO_TYPENAME, ANIM_CLASS_TOONS_MENU_MAIN }, - { GAME_MODE_SCORES, ANIM_CLASS_TOONS }, + { GAME_MODE_PSEUDO_SCORESOLD, ANIM_CLASS_TOONS_SCORES }, + { GAME_MODE_PSEUDO_SCORESNEW, ANIM_CLASS_TOONS_SCORES }, { -1, -1 } }; @@ -177,6 +185,7 @@ struct AnimClassGameMode { ANIM_CLASS_BIT_TITLE_INITIAL, GAME_MODE_TITLE_INITIAL }, { ANIM_CLASS_BIT_TITLE, GAME_MODE_TITLE }, { ANIM_CLASS_BIT_MAIN, GAME_MODE_MAIN }, + { ANIM_CLASS_BIT_SCORES, GAME_MODE_SCORES }, { ANIM_CLASS_BIT_SUBMENU, GAME_MODE_PSEUDO_SUBMENU }, { ANIM_CLASS_BIT_MENU, GAME_MODE_PSEUDO_MENU }, { ANIM_CLASS_BIT_TOONS, GAME_MODE_PSEUDO_TOONS }, @@ -197,6 +206,7 @@ static unsigned int anim_sync_frame = 0; static int game_mode_anim_classes[NUM_GAME_MODES]; static int anim_class_game_modes[NUM_ANIM_CLASSES]; +static int anim_status_last_before_fading = GAME_MODE_DEFAULT; static int anim_status_last = GAME_MODE_DEFAULT; static int anim_classes_last = ANIM_CLASS_NONE; @@ -340,6 +350,9 @@ static void InitToonControls() anim->has_base = FALSE; + anim->last_x = POS_OFFSCREEN; + anim->last_y = POS_OFFSCREEN; + anim->init_delay_counter = 0; anim->state = ANIM_STATE_INACTIVE; @@ -433,6 +446,9 @@ void InitGlobalAnimControls() anim->has_base = FALSE; + anim->last_x = POS_OFFSCREEN; + anim->last_y = POS_OFFSCREEN; + anim->init_delay_counter = 0; anim->state = ANIM_STATE_INACTIVE; @@ -545,6 +561,7 @@ void InitGlobalAnimControls() anim_class_game_modes[anim_class_game_modes_list[i].class_bit] = anim_class_game_modes_list[i].game_mode; + anim_status_last_before_fading = GAME_MODE_LOADING; anim_status_last = GAME_MODE_LOADING; anim_classes_last = ANIM_CLASS_NONE; } @@ -583,15 +600,23 @@ void DrawGlobalAnimationsExt(int drawing_target, int drawing_stage) if (drawing_target == DRAW_TO_FADE_TARGET) after_fading = TRUE; + // special case: changing from/to this screen is done without fading + if (global.anim_status == GAME_MODE_PSEUDO_TYPENAME || + anim_status_last == GAME_MODE_PSEUDO_TYPENAME) + after_fading = TRUE; + // ---------- 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 - game_mode_anim_action[anim_status_last] = ANIM_STOP; + if (global.anim_status_next != anim_status_last_before_fading) + { + // stop animations for last screen before fading to new screen + game_mode_anim_action[anim_status_last] = ANIM_STOP; - // start animations for current screen - game_mode_anim_action[global.anim_status] = ANIM_START; + // start animations for current screen after fading to new screen + game_mode_anim_action[global.anim_status] = ANIM_START; + } // start animations for all screens after loading new artwork set if (anim_status_last == GAME_MODE_LOADING) @@ -620,7 +645,10 @@ void DrawGlobalAnimationsExt(int drawing_target, int drawing_stage) if (drawing_target == DRAW_TO_SCREEN) { if (after_fading) + { anim_classes_last = anim_classes_next; + anim_status_last_before_fading = global.anim_status; + } anim_status_last = global.anim_status; @@ -926,32 +954,23 @@ static void StopGlobalAnimSoundAndMusic(struct GlobalAnimPartControlInfo *part) StopGlobalAnimMusic(part); } -static boolean matchesAnimEventMask(int bits, int mask) -{ - return (bits & (mask & ANIM_EVENT_CLICK_ANIM_ALL) && - bits & (mask & ANIM_EVENT_CLICK_PART_ALL)); -} - static boolean isClickablePart(struct GlobalAnimPartControlInfo *part, int mask) { struct GraphicInfo *c = &part->control_info; - - boolean clickable_any = FALSE; - boolean clickable_self = FALSE; - boolean clickable_triggered = FALSE; - - if (mask & ANIM_EVENT_CLICK_ANY) - clickable_any = (c->init_event & ANIM_EVENT_CLICK_ANY || - c->anim_event & ANIM_EVENT_CLICK_ANY); - - if (mask & ANIM_EVENT_CLICK_SELF) - clickable_self = (c->init_event & ANIM_EVENT_CLICK_SELF || - c->anim_event & ANIM_EVENT_CLICK_SELF); - - clickable_triggered = (matchesAnimEventMask(c->init_event, mask) || - matchesAnimEventMask(c->anim_event, mask)); - - return (clickable_any || clickable_self || clickable_triggered); + int trigger_mask = ANIM_EVENT_ANIM_MASK | ANIM_EVENT_PART_MASK; + int mask_anim_only = mask & ANIM_EVENT_ANIM_MASK; + + if (mask & ANIM_EVENT_ANY) + return (c->init_event & ANIM_EVENT_ANY || + c->anim_event & ANIM_EVENT_ANY); + else if (mask & ANIM_EVENT_SELF) + return (c->init_event & ANIM_EVENT_SELF || + c->anim_event & ANIM_EVENT_SELF); + else + return ((c->init_event & trigger_mask) == mask || + (c->anim_event & trigger_mask) == mask || + (c->init_event & trigger_mask) == mask_anim_only || + (c->anim_event & trigger_mask) == mask_anim_only); } static boolean isClickedPart(struct GlobalAnimPartControlInfo *part, @@ -986,6 +1005,8 @@ static boolean isClickedPart(struct GlobalAnimPartControlInfo *part, int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part, int state) { + struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[part->mode_nr]; + struct GlobalAnimMainControlInfo *anim = &ctrl->anim[part->anim_nr]; struct GraphicInfo *g = &part->graphic_info; struct GraphicInfo *c = &part->control_info; boolean viewport_changed = SetGlobalAnimPart_Viewport(part); @@ -1082,6 +1103,14 @@ int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part, int state) if (c->y != ARG_UNDEFINED_VALUE) part->y = c->y; + if (c->position == POS_LAST && + anim->last_x > -g->width && anim->last_x < part->viewport_width && + anim->last_y > -g->height && anim->last_y < part->viewport_height) + { + part->x = anim->last_x; + part->y = anim->last_y; + } + if (c->step_xoffset != ARG_UNDEFINED_VALUE) part->step_xoffset = c->step_xoffset; if (c->step_yoffset != ARG_UNDEFINED_VALUE) @@ -1209,6 +1238,9 @@ int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part, int state) part->x += part->step_xoffset; part->y += part->step_yoffset; + anim->last_x = part->x; + anim->last_y = part->y; + return ANIM_STATE_RUNNING; } @@ -1216,7 +1248,9 @@ void HandleGlobalAnim_Main(struct GlobalAnimMainControlInfo *anim, int action) { struct GlobalAnimPartControlInfo *part; struct GraphicInfo *c = &anim->control_info; + int num_parts = anim->num_parts + (anim->has_base ? 1 : 0); int state, active_part_nr; + int i; #if 0 printf("::: HandleGlobalAnim_Main: %d, %d => %d\n", @@ -1257,13 +1291,8 @@ void HandleGlobalAnim_Main(struct GlobalAnimMainControlInfo *anim, int action) case ANIM_STOP: anim->state = ANIM_STATE_INACTIVE; - { - int num_parts = anim->num_parts + (anim->has_base ? 1 : 0); - int i; - - for (i = 0; i < num_parts; i++) - StopGlobalAnimSoundAndMusic(&anim->part[i]); - } + for (i = 0; i < num_parts; i++) + StopGlobalAnimSoundAndMusic(&anim->part[i]); return; @@ -1273,9 +1302,6 @@ void HandleGlobalAnim_Main(struct GlobalAnimMainControlInfo *anim, int action) if (c->anim_mode & ANIM_ALL || anim->num_parts == 0) { - int num_parts = anim->num_parts + (anim->has_base ? 1 : 0); - int i; - #if 0 printf("::: HandleGlobalAnim_Main: %d, %d => %d\n", anim->mode_nr, anim->nr, num_parts); @@ -1433,20 +1459,24 @@ static void InitGlobalAnim_Clickable() static boolean InitGlobalAnim_Clicked(int mx, int my, boolean clicked) { + boolean anything_clicked = FALSE; boolean any_part_clicked = FALSE; int mode_nr; - for (mode_nr = 0; mode_nr < NUM_GAME_MODES; mode_nr++) + // check game modes in reverse draw order (to stop when clicked) + for (mode_nr = NUM_GAME_MODES - 1; mode_nr >= 0; mode_nr--) { struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[mode_nr]; int anim_nr; - for (anim_nr = 0; anim_nr < ctrl->num_anims; anim_nr++) + // check animations in reverse draw order (to stop when clicked) + for (anim_nr = ctrl->num_anims - 1; anim_nr >= 0; anim_nr--) { struct GlobalAnimMainControlInfo *anim = &ctrl->anim[anim_nr]; int part_nr; - for (part_nr = 0; part_nr < anim->num_parts_all; part_nr++) + // check animation parts in reverse draw order (to stop when clicked) + for (part_nr = anim->num_parts_all - 1; part_nr >= 0; part_nr--) { struct GlobalAnimPartControlInfo *part = &anim->part[part_nr]; @@ -1460,8 +1490,13 @@ static boolean InitGlobalAnim_Clicked(int mx, int my, boolean clicked) if (!part->clickable) continue; - if (isClickablePart(part, ANIM_EVENT_CLICK_ANY)) - any_part_clicked = part->clicked = TRUE; + // always handle "any" click events (clicking anywhere on screen) ... + if (isClickablePart(part, ANIM_EVENT_ANY)) + anything_clicked = part->clicked = TRUE; + + // ... but only handle the first (topmost) clickable animation + if (any_part_clicked) + continue; if (isClickedPart(part, mx, my, clicked)) { @@ -1469,18 +1504,18 @@ static boolean InitGlobalAnim_Clicked(int mx, int my, boolean clicked) printf("::: %d.%d CLICKED\n", anim_nr, part_nr); #endif - if (isClickablePart(part, ANIM_EVENT_CLICK_SELF)) - any_part_clicked = part->clicked = TRUE; + any_part_clicked = TRUE; + + if (isClickablePart(part, ANIM_EVENT_SELF)) + anything_clicked = part->clicked = TRUE; // check if this click is defined to trigger other animations - int old_anim_nr = part->old_anim_nr; - int old_part_nr = part->old_nr; - int mask = ANIM_EVENT_CLICK_ANIM_1 << old_anim_nr; + int gic_anim_nr = part->old_anim_nr + 1; // X as in "anim_X" + int gic_part_nr = part->old_nr + 1; // Y as in "part_Y" + int mask = gic_anim_nr << ANIM_EVENT_ANIM_BIT; - if (part->is_base) - mask |= ANIM_EVENT_CLICK_PART_ALL; - else - mask |= ANIM_EVENT_CLICK_PART_1 << old_part_nr; + if (!part->is_base) + mask |= gic_part_nr << ANIM_EVENT_PART_BIT; int anim2_nr; @@ -1494,7 +1529,7 @@ static boolean InitGlobalAnim_Clicked(int mx, int my, boolean clicked) struct GlobalAnimPartControlInfo *part2 = &anim2->part[part2_nr]; if (isClickablePart(part2, mask)) - any_part_clicked = part2->clicked = TRUE; + anything_clicked = part2->clicked = TRUE; #if 0 struct GraphicInfo *c = &part2->control_info; @@ -1515,7 +1550,7 @@ static boolean InitGlobalAnim_Clicked(int mx, int my, boolean clicked) } } - return any_part_clicked; + return anything_clicked; } static void ResetGlobalAnim_Clickable()