//--- // anim: Renderer's animations // // Animations in this engine are simply linked variants of sprites. Animated // images change over time, moving from frame to frame, and that's it. //--- #pragma once #include #include "fixed.h" #include typedef struct anim_frame { /* Sheet */ bopti_image_t const *sheet; /* Box for the frame within the sheet */ uint8_t x, y, w, h; /* Position of center for this frame */ int8_t cx, cy; /* Duration of the frame (ms) */ uint16_t duration; /* Next frame */ struct anim_frame *next; } anim_frame_t; typedef struct { /* Number of directions 1: Basic sprite 2: LEFT and RIGHT (enemies) 4: UP, RIGHT, DOWN and LEFT (player, some attacks) */ int directions; /* First frame for each direction */ anim_frame_t *start[]; } anim_t; typedef struct { /* Current frame */ anim_frame_t const *frame; /* Time elapsed */ uint16_t elapsed; } anim_state_t; /* Duration of an animation, in seconds; assumed unique for all directions */ fixed_t anim_duration(anim_t const *anim); /* Check if a frame is in an animation. */ bool anim_in(anim_frame_t const *frame, anim_t const *anim, int index); /* Render a frame at the center position (x,y), similar to dimage(). */ void anim_frame_render(int x, int y, anim_frame_t const *frame); /* Render a subimage of a frame, similar to dsubimage(). */ void anim_frame_subrender(int x, int y, anim_frame_t const *frame, int left, int top, int width, int height); /* Update an animation to next frame. */ void anim_state_update(anim_state_t *state, fixed_t dt); /* List of animations. */ /* Basic skills */ extern anim_t anims_skill_hit; extern anim_t anims_skill_projectile; extern anim_t anims_skill_teleport; extern anim_t anims_skill_shock; extern anim_t anims_skill_judgement; /* Directional skills */ extern anim_t anims_skill_swing; extern anim_t anims_skill_impale; extern anim_t anims_skill_bullet; /* Enemies */ #define ANIM_ENEMIES(MACRO) \ ANIM_E1(MACRO, slime, Idle, Walking, Attack, Fire, Hit, Death) \ ANIM_E1(MACRO, fire_slime, Idle, Walking, Attack, Fire, Hit, Death) \ ANIM_E1(MACRO, water_slime, Idle, Walking, Attack, Fire, Hit, Death) \ ANIM_E1(MACRO, chemical_slime, Idle, Walking, Attack, Fire, Hit, Death) \ ANIM_E1(MACRO, bat, Idle, Hit, Death) \ ANIM_E1(MACRO, albinos_bat, Idle, Hit, Death) \ ANIM_E1(MACRO, crimson_bat, Idle, Hit, Death) \ ANIM_E1(MACRO, gunslinger, Idle, Walking, Reloading, Fire, Hit, Death) \ ANIM_E1(MACRO, gb_gunslinger, Idle, Walking, Reloading, Fire, Hit, Death) \ ANIM_E1(MACRO, master_gunslinger, Idle, Walking,Reloading,Fire,Hit,Death) \ ANIM_E1(MACRO, tifucile, Idle, Walking, Hit, Death) \ ANIM_E1(MACRO, washing_machine, Idle, Walking, Attack, Hit, Death) /* Player */ extern anim_t anims_player_Idle; extern anim_t anims_player_Walking; extern anim_t anims_player_Attack; extern anim_t anims_player_Hit; /* HUD */ extern anim_t anims_hud_xp_Idle; extern anim_t anims_hud_xp_Shine; extern anim_t anims_hud_xp_Explode; /* Items */ extern anim_t anims_item_life; extern anim_t anims_item_chest; extern anim_t anims_item_potion_atk; extern anim_t anims_item_potion_cooldown; extern anim_t anims_item_potion_def; extern anim_t anims_item_potion_frz; extern anim_t anims_item_potion_hp; extern anim_t anims_item_potion_spd; extern anim_t anims_item_stick1; extern anim_t anims_item_stick2; extern anim_t anims_item_sword1; extern anim_t anims_item_sword2; extern anim_t anims_item_armor1; /* Expand definitions for enemies */ #define ANIM_E1(MACRO, ENEMY, SEQ, ...) \ MACRO(ENEMY, SEQ) __VA_OPT__(ANIM_E2(MACRO, ENEMY, __VA_ARGS__)) #define ANIM_E2(MACRO, ENEMY, SEQ, ...) \ MACRO(ENEMY, SEQ) __VA_OPT__(ANIM_E3(MACRO, ENEMY, __VA_ARGS__)) #define ANIM_E3(MACRO, ENEMY, SEQ, ...) \ MACRO(ENEMY, SEQ) __VA_OPT__(ANIM_E4(MACRO, ENEMY, __VA_ARGS__)) #define ANIM_E4(MACRO, ENEMY, SEQ, ...) \ MACRO(ENEMY, SEQ) __VA_OPT__(ANIM_E5(MACRO, ENEMY, __VA_ARGS__)) #define ANIM_E5(MACRO, ENEMY, SEQ, ...) \ MACRO(ENEMY, SEQ) __VA_OPT__(ANIM_E6(MACRO, ENEMY, __VA_ARGS__)) #define ANIM_E6(MACRO, ENEMY, SEQ, ...) \ MACRO(ENEMY, SEQ) __VA_OPT__(ANIM_ETOO_MANY_ARGS) #define ANIM_ENEMIES_PROTO(ENEMY, SEQ) \ extern anim_t anims_ ## ENEMY ## _ ## SEQ; ANIM_ENEMIES(ANIM_ENEMIES_PROTO)