2017-10-03 17:25:38 +02:00
|
|
|
|
/*
|
|
|
|
|
* This software is licensed under the terms of the MIT-License
|
|
|
|
|
* See COPYING for further information.
|
|
|
|
|
* ---
|
|
|
|
|
* Copyright (c) 2011-2017, Lukas Weber <laochailan@web.de>.
|
|
|
|
|
* Copyright (c) 2012-2017, Andrei Alexeyev <akari@alienslab.net>.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "aniplayer.h"
|
|
|
|
|
#include "list.h"
|
|
|
|
|
#include "global.h"
|
|
|
|
|
|
|
|
|
|
void aniplayer_create(AniPlayer *plr, Animation *ani) {
|
|
|
|
|
memset(plr,0,sizeof(AniPlayer));
|
|
|
|
|
plr->ani = ani;
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-16 23:49:23 +02:00
|
|
|
|
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?
|
|
|
|
|
|
|
|
|
|
AniPlayer *plr = malloc(sizeof(AniPlayer));
|
|
|
|
|
aniplayer_copy(plr, src);
|
|
|
|
|
return plr;
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-03 17:25:38 +02:00
|
|
|
|
void aniplayer_free(AniPlayer *plr) {
|
2017-10-08 22:39:33 +02:00
|
|
|
|
plr->queuesize = 0; // prevent aniplayer_reset from messing with the queue, since we're going to wipe all of it anyway
|
2017-11-21 15:45:01 +01:00
|
|
|
|
list_free_all((List**)&plr->queue);
|
2017-10-03 17:25:38 +02:00
|
|
|
|
aniplayer_reset(plr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void aniplayer_reset(AniPlayer *plr) { // resets to a neutral state with empty queue.
|
|
|
|
|
plr->stdrow = 0;
|
|
|
|
|
if(plr->queuesize > 0) { // abort the animation in the fastest fluent way.
|
2017-11-21 15:45:01 +01:00
|
|
|
|
list_free_all((List**)&plr->queue->next);
|
2017-10-03 17:25:38 +02:00
|
|
|
|
plr->queuesize = 1;
|
|
|
|
|
plr->queue->delay = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-08 22:48:12 +02:00
|
|
|
|
void aniplayer_copy(AniPlayer *dst, AniPlayer *src) {
|
|
|
|
|
memcpy(dst, src, sizeof(AniPlayer));
|
|
|
|
|
dst->queue = NULL;
|
|
|
|
|
dst->queuesize = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-03 17:25:38 +02:00
|
|
|
|
AniSequence *aniplayer_queue(AniPlayer *plr, int row, int loops, int delay) {
|
2017-11-21 15:45:01 +01:00
|
|
|
|
AniSequence *s = (AniSequence*)list_append((List**)&plr->queue, calloc(1, sizeof(AniSequence)));
|
2017-10-03 17:25:38 +02:00
|
|
|
|
plr->queuesize++;
|
|
|
|
|
s->row = row;
|
|
|
|
|
|
|
|
|
|
if(loops < 0)
|
|
|
|
|
log_fatal("Negative number of loops passed: %d",loops);
|
|
|
|
|
|
2017-10-03 20:09:34 +02:00
|
|
|
|
s->duration = (loops+1)*plr->ani->cols*plr->ani->speed;
|
2017-10-03 17:25:38 +02:00
|
|
|
|
s->delay = delay;
|
2017-10-29 11:06:15 +01:00
|
|
|
|
s->mirrored = plr->mirrored;
|
2017-10-03 17:25:38 +02:00
|
|
|
|
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-04 19:31:22 +02:00
|
|
|
|
AniSequence *aniplayer_queue_pro(AniPlayer *plr, int row, int start, int end, int delay, int speed) {
|
|
|
|
|
AniSequence *s = aniplayer_queue(plr,row,0,delay);
|
|
|
|
|
// i bet you didn’t expect the _pro function calling the plain one
|
|
|
|
|
s->speed = speed;
|
|
|
|
|
|
|
|
|
|
if(speed <= 0)
|
|
|
|
|
speed = plr->ani->speed;
|
|
|
|
|
s->duration = end*speed;
|
|
|
|
|
s->clock = start*speed;
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-03 17:25:38 +02:00
|
|
|
|
void aniplayer_update(AniPlayer *plr) {
|
|
|
|
|
plr->clock++;
|
|
|
|
|
if(plr->queue) {
|
|
|
|
|
AniSequence *s = plr->queue;
|
2017-10-03 20:09:34 +02:00
|
|
|
|
if(s->clock < s->duration) {
|
|
|
|
|
s->clock++;
|
2017-10-03 17:25:38 +02:00
|
|
|
|
} else if(s->delay > 0) {
|
|
|
|
|
s->delay--;
|
|
|
|
|
} else {
|
2017-11-21 15:45:01 +01:00
|
|
|
|
free(list_pop((List**)&plr->queue));
|
2017-10-03 17:25:38 +02:00
|
|
|
|
plr->queuesize--;
|
|
|
|
|
plr->clock = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void aniplayer_play(AniPlayer *plr, float x, float y) {
|
|
|
|
|
int col = (plr->clock/plr->ani->speed) % plr->ani->cols;
|
|
|
|
|
int row = plr->stdrow;
|
2017-10-04 19:31:22 +02:00
|
|
|
|
int speed = plr->ani->speed;
|
2017-10-03 17:25:38 +02:00
|
|
|
|
bool mirror = plr->mirrored;
|
|
|
|
|
if(plr->queue) {
|
|
|
|
|
AniSequence *s = plr->queue;
|
2017-10-04 19:31:22 +02:00
|
|
|
|
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;
|
2017-10-03 17:25:38 +02:00
|
|
|
|
row = s->row;
|
|
|
|
|
|
|
|
|
|
mirror = s->mirrored;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(mirror) {
|
|
|
|
|
glPushMatrix();
|
|
|
|
|
glCullFace(GL_FRONT);
|
|
|
|
|
glTranslatef(x,y,0);
|
|
|
|
|
x = y = 0;
|
|
|
|
|
glScalef(-1,1,1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
draw_animation_p(x,y,col,row,plr->ani);
|
|
|
|
|
|
|
|
|
|
if(mirror) {
|
|
|
|
|
glCullFace(GL_BACK);
|
|
|
|
|
glPopMatrix();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|