From e2b5e0a00654a71375f080f109a86e6eb065716d Mon Sep 17 00:00:00 2001 From: laochailan Date: Sat, 30 Dec 2017 10:44:40 +0100 Subject: [PATCH] remove the aniplayer object pool --- src/aniplayer.c | 63 ++++++++++++++++++---------------------------- src/aniplayer.h | 9 +++++-- src/boss.c | 24 +++++++----------- src/stageobjects.c | 2 -- src/stageobjects.h | 1 - 5 files changed, 41 insertions(+), 58 deletions(-) diff --git a/src/aniplayer.c b/src/aniplayer.c index 76b82611..3e3633c5 100644 --- a/src/aniplayer.c +++ b/src/aniplayer.c @@ -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); } diff --git a/src/aniplayer.h b/src/aniplayer.h index 63ca5788..ae3f5da1 100644 --- a/src/aniplayer.h +++ b/src/aniplayer.h @@ -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 diff --git a/src/boss.c b/src/boss.c index 94151b7e..1fdb1712 100644 --- a/src/boss.c +++ b/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 ); diff --git a/src/stageobjects.c b/src/stageobjects.c index 01161e78..d7e16087 100644 --- a/src/stageobjects.c +++ b/src/stageobjects.c @@ -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; diff --git a/src/stageobjects.h b/src/stageobjects.h index 5abc439d..3e777542 100644 --- a/src/stageobjects.h +++ b/src/stageobjects.h @@ -18,7 +18,6 @@ typedef struct StageObjectPools { ObjectPool *items; ObjectPool *enemies; ObjectPool *lasers; - ObjectPool *aniplayers; // hack for the boss glow effect }; ObjectPool *first;