2024-01-19 16:33:54 -05:00
|
|
|
#include <stdlib.h>
|
2024-01-19 19:03:14 -05:00
|
|
|
#include <string.h>
|
2024-01-19 16:33:54 -05:00
|
|
|
|
|
|
|
#include <hexagram/anim.h>
|
|
|
|
|
|
|
|
void hexagram_anim_init(hexagram_anim *anim) {
|
|
|
|
gettimeofday(&anim->start, NULL);
|
|
|
|
}
|
|
|
|
|
2024-01-19 19:03:14 -05:00
|
|
|
static inline double tv_seconds(struct timeval *tv) {
|
|
|
|
return (double)tv->tv_sec + (double)tv->tv_usec / 1000000.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline double stop_offset(hexagram_anim *anim, size_t index) {
|
|
|
|
double offset = 0.0;
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
for (i=0; i<index; i++) {
|
|
|
|
offset += anim->stops[i].duration;
|
|
|
|
}
|
|
|
|
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
2024-01-20 00:39:07 -05:00
|
|
|
int hexagram_anim_step(hexagram_anim *anim, hexagram_anim_progress_fn *fn) {
|
2024-01-19 19:03:14 -05:00
|
|
|
struct timeval tv;
|
2024-01-19 20:47:07 -05:00
|
|
|
double offset = 0.0, interval, progress;
|
2024-01-19 21:31:12 -05:00
|
|
|
size_t i, a;
|
2024-01-19 19:03:14 -05:00
|
|
|
|
|
|
|
gettimeofday(&anim->now, NULL);
|
|
|
|
|
|
|
|
timersub(&anim->now, &anim->start, &tv);
|
|
|
|
|
2024-01-19 20:47:07 -05:00
|
|
|
/* Determine the interval between initialisation and now */
|
2024-01-19 19:03:14 -05:00
|
|
|
interval = tv_seconds(&tv);
|
|
|
|
|
2024-01-19 20:47:07 -05:00
|
|
|
/* Determine current animation stop index and time offset */
|
|
|
|
for (i=0; i<anim->count; i++) {
|
|
|
|
double duration = anim->stops[i].duration;
|
|
|
|
|
|
|
|
if (duration <= 0) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2024-01-21 00:05:34 -05:00
|
|
|
if (offset + duration >= interval) {
|
2024-01-19 20:47:07 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
offset += duration;
|
|
|
|
}
|
|
|
|
|
2024-01-21 00:05:34 -05:00
|
|
|
/* Determine progress through current stop */
|
2024-01-19 20:47:07 -05:00
|
|
|
if (i == anim->count) {
|
2024-01-21 00:05:34 -05:00
|
|
|
i--;
|
|
|
|
progress = 1.0;
|
|
|
|
} else if (fn) {
|
2024-01-20 00:39:07 -05:00
|
|
|
progress = fn(&anim->stops[i],
|
|
|
|
(interval - offset) / anim->stops[i].duration);
|
|
|
|
} else {
|
|
|
|
progress = (interval - offset) / anim->stops[i].duration;
|
|
|
|
}
|
2024-01-19 16:33:54 -05:00
|
|
|
|
2024-01-20 00:43:43 -05:00
|
|
|
for (a=0; a<anim->stops[i].count; a++) {
|
2024-01-19 21:31:12 -05:00
|
|
|
hexagram_anim_action *action = &anim->stops[i].actions[a];
|
|
|
|
|
|
|
|
if (action->flags & HEXAGRAM_ANIM_MOVE) {
|
|
|
|
double x = progress * (action->to.x - action->from.x) + action->from.x,
|
|
|
|
y = progress * (action->to.y - action->from.y) + action->from.y;
|
|
|
|
|
|
|
|
hexagram_gauge_move(action->gauge, x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (action->flags & HEXAGRAM_ANIM_ALPHA) {
|
|
|
|
double alpha = progress * (action->to.alpha - action->from.alpha) + action->from.alpha;
|
|
|
|
|
|
|
|
hexagram_gauge_set_alpha(action->gauge, alpha);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (action->flags & HEXAGRAM_ANIM_RADIUS) {
|
|
|
|
double radius = progress * (action->to.radius - action->from.radius) + action->from.radius;
|
|
|
|
|
|
|
|
hexagram_dial_resize(action->dial, radius);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-19 19:03:14 -05:00
|
|
|
return 1;
|
2024-01-19 16:33:54 -05:00
|
|
|
}
|
2024-01-20 12:26:34 -05:00
|
|
|
|
|
|
|
double hexagram_anim_duration(hexagram_anim *anim) {
|
|
|
|
double ret = 0.0;
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
for (i=0; i<anim->count; i++) {
|
|
|
|
ret += anim->stops[i].duration;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|