remove the aniplayer object pool
This commit is contained in:
parent
61ed98dfba
commit
e2b5e0a006
5 changed files with 41 additions and 58 deletions
|
@ -19,28 +19,24 @@ void aniplayer_create(AniPlayer *plr, Animation *ani) {
|
|||
plr->ani = ani;
|
||||
}
|
||||
|
||||
AniPlayer* aniplayer_create_copy(AniPlayer *src) {
|
||||
// XXX: maybe it needs another name since it allocates memory?
|
||||
// or maybe aniplayer_create needs another name since it doesn't?
|
||||
int aniplayer_get_frame(AniPlayer *plr) {
|
||||
int col = (plr->clock/plr->ani->speed) % plr->ani->cols;
|
||||
int row = plr->stdrow;
|
||||
int speed = plr->ani->speed;
|
||||
bool mirror = plr->mirrored;
|
||||
if(plr->queue) {
|
||||
AniSequence *s = plr->queue;
|
||||
if(s->speed > 0)
|
||||
speed = s->speed;
|
||||
col = (s->clock/speed) % plr->ani->cols;
|
||||
if(s->backwards)
|
||||
col = ((s->duration-s->clock)/speed) % plr->ani->cols;
|
||||
row = s->row;
|
||||
|
||||
AniPlayer *plr = (AniPlayer*)objpool_acquire(stage_object_pools.aniplayers);
|
||||
|
||||
size_t data_size;
|
||||
void *src_data = objpool_object_contents(NULL, &src->object_interface, NULL);
|
||||
void *dst_data = objpool_object_contents(stage_object_pools.aniplayers, &plr->object_interface, &data_size);
|
||||
memcpy(dst_data, src_data, data_size);
|
||||
|
||||
plr->queue = NULL;
|
||||
plr->queuesize = 0;
|
||||
|
||||
return plr;
|
||||
}
|
||||
|
||||
void aniplayer_free_copy(AniPlayer *ani) {
|
||||
if(ani) {
|
||||
aniplayer_free(ani);
|
||||
objpool_release(stage_object_pools.aniplayers, (ObjectInterface*)ani);
|
||||
mirror = s->mirrored;
|
||||
}
|
||||
|
||||
return (row*plr->ani->cols+col)*(1-2*mirror);
|
||||
}
|
||||
|
||||
void aniplayer_free(AniPlayer *plr) {
|
||||
|
@ -102,23 +98,9 @@ void aniplayer_update(AniPlayer *plr) {
|
|||
}
|
||||
}
|
||||
|
||||
void aniplayer_play(AniPlayer *plr, float x, float y) {
|
||||
int col = (plr->clock/plr->ani->speed) % plr->ani->cols;
|
||||
int row = plr->stdrow;
|
||||
int speed = plr->ani->speed;
|
||||
bool mirror = plr->mirrored;
|
||||
if(plr->queue) {
|
||||
AniSequence *s = plr->queue;
|
||||
if(s->speed > 0)
|
||||
speed = s->speed;
|
||||
col = (s->clock/speed) % plr->ani->cols;
|
||||
if(s->backwards)
|
||||
col = ((s->duration-s->clock)/speed) % plr->ani->cols;
|
||||
row = s->row;
|
||||
|
||||
mirror = s->mirrored;
|
||||
}
|
||||
|
||||
void play_animation_frame(Animation *ani, float x, float y, int frame) {
|
||||
int mirror = frame < 0;
|
||||
frame = abs(frame);
|
||||
if(mirror) {
|
||||
glPushMatrix();
|
||||
glCullFace(GL_FRONT);
|
||||
|
@ -127,7 +109,7 @@ void aniplayer_play(AniPlayer *plr, float x, float y) {
|
|||
glScalef(-1,1,1);
|
||||
}
|
||||
|
||||
draw_animation_p(x,y,col,row,plr->ani);
|
||||
draw_animation_p(x,y,frame%ani->cols,frame/ani->cols,ani);
|
||||
|
||||
if(mirror) {
|
||||
glCullFace(GL_BACK);
|
||||
|
@ -135,6 +117,11 @@ void aniplayer_play(AniPlayer *plr, float x, float y) {
|
|||
}
|
||||
}
|
||||
|
||||
void aniplayer_play(AniPlayer *plr, float x, float y) {
|
||||
int frame = aniplayer_get_frame(plr);
|
||||
play_animation_frame(plr->ani,x,y,frame); // or as my grandpa always said: rather write 100 lines of new code than one old line twice.
|
||||
}
|
||||
|
||||
void play_animation(Animation *ani, float x, float y, int row) { // the old way to draw animations without AniPlayer
|
||||
draw_animation_p(x,y,(global.frames/ani->speed)%ani->cols,row,ani);
|
||||
}
|
||||
|
|
|
@ -50,8 +50,13 @@ void aniplayer_create(AniPlayer *plr, Animation *ani);
|
|||
void aniplayer_free(AniPlayer *plr);
|
||||
void aniplayer_reset(AniPlayer *plr); // resets to a neutral state with empty queue.
|
||||
|
||||
AniPlayer* aniplayer_create_copy(AniPlayer *src);
|
||||
void aniplayer_free_copy(AniPlayer *ani);
|
||||
// this returns a representation of the frame that is currently drawn by the aniplayer.
|
||||
// in multirow animations it is computed as follows:
|
||||
//
|
||||
// idx = (row*ani->cols+col)*(1-2*mirrored)
|
||||
//
|
||||
int aniplayer_get_frame(AniPlayer *plr);
|
||||
void play_animation_frame(Animation *ani, float x, float y, int frame); // context free version that can be used with aniplayer_get_frame to draw a specific state
|
||||
|
||||
AniSequence *aniplayer_queue(AniPlayer *plr, int row, int loops, int delay); // 0 loops: played one time
|
||||
AniSequence *aniplayer_queue_pro(AniPlayer *plr, int row, int start, int duration, int delay, int speed); // self-documenting pro version
|
||||
|
|
24
src/boss.c
24
src/boss.c
|
@ -142,8 +142,9 @@ static bool attack_is_over(Attack *a) {
|
|||
}
|
||||
|
||||
static void BossGlow(Projectile *p, int t) {
|
||||
AniPlayer *aplr = (AniPlayer*)REF(p->args[2]);
|
||||
assert(aplr != NULL);
|
||||
Animation *ani = (Animation *)REF(p->args[3]);
|
||||
assert(ani != 0);
|
||||
int animationFrame = rint(creal(p->args[2]));
|
||||
|
||||
Shader *shader = get_shader("silhouette");
|
||||
glUseProgram(shader->prog);
|
||||
|
@ -163,35 +164,28 @@ static void BossGlow(Projectile *p, int t) {
|
|||
glUniform4fv(uniloc(shader, "color"), 1, clr);
|
||||
glUniform1f(uniloc(shader, "deform"), deform);
|
||||
|
||||
aniplayer_play(aplr,0,0);
|
||||
play_animation_frame(ani,0,0,animationFrame);
|
||||
|
||||
glPopMatrix();
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glUseProgram(recolor_get_shader()->prog);
|
||||
}
|
||||
|
||||
static int boss_glow_rule(Projectile *p, int t) {
|
||||
static int boss_glow(Projectile *p, int t) {
|
||||
if(t == EVENT_DEATH) {
|
||||
AniPlayer *aplr = REF(p->args[2]);
|
||||
aniplayer_free_copy(aplr);
|
||||
free_ref(p->args[2]);
|
||||
return 1;
|
||||
free_ref(p->args[3]);
|
||||
}
|
||||
|
||||
return enemy_flare(p, t);
|
||||
return timeout_linear(p,t);
|
||||
}
|
||||
|
||||
static Projectile* spawn_boss_glow(Boss *boss, Color clr, int timeout) {
|
||||
// copy animation state to render the same frame even after the boss has changed its own
|
||||
AniPlayer *aplr = aniplayer_create_copy(&boss->ani);
|
||||
|
||||
return PARTICLE(
|
||||
// this is in sync with the boss position oscillation
|
||||
.pos = boss->pos + 6 * sin(global.frames/25.0) * I,
|
||||
.color = clr,
|
||||
.rule = boss_glow_rule,
|
||||
.rule = boss_glow,
|
||||
.draw_rule = BossGlow,
|
||||
.args = { timeout, 0, add_ref(aplr), },
|
||||
.args = { timeout, 0, aniplayer_get_frame(&boss->ani), add_ref(global.boss->ani.ani)}, // the ref is needed just to pass a pointer :/
|
||||
.angle = M_PI * 2 * frand(),
|
||||
.size = (1+I)*9000, // ensure it's drawn under everything else
|
||||
);
|
||||
|
|
|
@ -19,14 +19,12 @@
|
|||
#define MAX_items MAX_projectiles
|
||||
#define MAX_enemies 64
|
||||
#define MAX_lasers 64
|
||||
#define MAX_aniplayers 32
|
||||
|
||||
#define OBJECT_POOLS \
|
||||
OBJECT_POOL(Projectile, projectiles) \
|
||||
OBJECT_POOL(Item, items) \
|
||||
OBJECT_POOL(Enemy, enemies) \
|
||||
OBJECT_POOL(Laser, lasers) \
|
||||
OBJECT_POOL(AniPlayer, aniplayers) \
|
||||
|
||||
StageObjectPools stage_object_pools;
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ typedef struct StageObjectPools {
|
|||
ObjectPool *items;
|
||||
ObjectPool *enemies;
|
||||
ObjectPool *lasers;
|
||||
ObjectPool *aniplayers; // hack for the boss glow effect
|
||||
};
|
||||
|
||||
ObjectPool *first;
|
||||
|
|
Loading…
Reference in a new issue