remove the aniplayer object pool

This commit is contained in:
laochailan 2017-12-30 10:44:40 +01:00
parent 61ed98dfba
commit e2b5e0a006
No known key found for this signature in database
GPG key ID: 49BE98017AFBC943
5 changed files with 41 additions and 58 deletions

View file

@ -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);
}

View file

@ -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

View file

@ -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
);

View file

@ -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;

View file

@ -18,7 +18,6 @@ typedef struct StageObjectPools {
ObjectPool *items;
ObjectPool *enemies;
ObjectPool *lasers;
ObjectPool *aniplayers; // hack for the boss glow effect
};
ObjectPool *first;