#include #include #include void hexagram_anim_init(hexagram_anim *anim) { gettimeofday(&anim->start, NULL); } 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; istops[i].duration; } return offset; } int hexagram_anim_step(hexagram_anim *anim, hexagram_anim_progress_fn *fn) { struct timeval tv; double offset = 0.0, interval, progress; size_t i, a; gettimeofday(&anim->now, NULL); timersub(&anim->now, &anim->start, &tv); /* Determine the interval between initialisation and now */ interval = tv_seconds(&tv); /* Determine current animation stop index and time offset */ for (i=0; icount; i++) { double duration = anim->stops[i].duration; if (duration <= 0) { continue; } if (interval <= offset + duration) { break; } offset += duration; } if (i == anim->count) { /* We are apparently at the end. */ return 0; } /* Determine current progress through current stop */ if (fn) { progress = fn(&anim->stops[i], (interval - offset) / anim->stops[i].duration); } else { progress = (interval - offset) / anim->stops[i].duration; } for (a=0; astops[i].count; a++) { 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); } } return 1; }