RogueLife/src/anim.c

70 lines
2.0 KiB
C

#include "anim.h"
#include <gint/display.h>
/* List of animations (and directional animations). */
#define NORMAL_ANIM(name) \
extern anim_frame_t name[];
#define DIRECTIONAL_ANIM(name) \
extern anim_frame_t name ## _up[]; \
extern anim_frame_t name ## _right[]; \
extern anim_frame_t name ## _down[]; \
extern anim_frame_t name ## _left[]; \
anim_frame_t *name[4] = { \
name ## _up, name ## _right, name ## _down, name ## _left };
#define ANIM_4DIRECTIONAL(prefix, suffix) \
extern anim_frame_t prefix ## _up_ ## suffix[]; \
extern anim_frame_t prefix ## _right_ ## suffix[]; \
extern anim_frame_t prefix ## _down_ ## suffix[]; \
extern anim_frame_t prefix ## _left_ ## suffix[]; \
anim_frame_t *prefix ## _ ## suffix[4] = { \
prefix ## _up_ ## suffix, \
prefix ## _right_ ## suffix, \
prefix ## _down_ ## suffix, \
prefix ## _left_ ## suffix, \
};
DIRECTIONAL_ANIM(anim_swing);
DIRECTIONAL_ANIM(anim_impale);
ANIM_4DIRECTIONAL(anims_player, Idle);
ANIM_4DIRECTIONAL(anims_player, Walking);
ANIM_4DIRECTIONAL(anims_player, Attack);
ANIM_4DIRECTIONAL(anims_player, Hit);
/* Animation functions. */
fixed_t (anim_duration)(anim_frame_t const *first_frame)
{
anim_frame_t const *frame = first_frame;
int ms = 0;
int i = 0;
while(frame == first_frame + i) {
ms += frame->duration;
frame = frame->next;
i++;
}
return fix(ms) / 1000;
}
void anim_frame_render(int x, int y, anim_frame_t const *frame)
{
if(!frame) return;
dsubimage(x - frame->cx, y - frame->cy, frame->sheet,
frame->x, frame->y, frame->w, frame->h, DIMAGE_NONE);
}
void anim_state_update(anim_state_t *state, fixed_t dt)
{
if(!state->frame) return;
state->elapsed += fround(dt * 1000);
if(state->elapsed < state->frame->duration) return;
/* Switch to next frame */
state->elapsed -= state->frame->duration;
state->frame = state->frame->next;
}