class AnimationContext2D { U64 signature; I64 duration; // in jiffies I64 index; // current frame I64 length; // length in frames I64 timer; // timer + cnts.jiffies = current ticks Context2D** frame; // Context2D*, ... }; AnimationContext2D* @animation2d_new_from_frames(Context2D** frames, I64 length, I64 duration = 250) { if (!frames || !length) return NULL; AnimationContext2D* actx = CAlloc(sizeof(AnimationContext2D)); actx->signature = 'animated'; actx->frame = frames; actx->length = length; actx->duration = duration; return actx; } Context2D* @animation2d_frame(AnimationContext2D* actx) { I64 ticks = cnts.jiffies; if (!actx) return NULL; if (!actx->length) return NULL; if (actx->index > actx->length - 1) actx->index = 0; if (!actx->index && !actx->timer) actx->timer = ticks; while (ticks >= actx->timer + actx->duration) { actx->timer += actx->duration; actx->index++; if (actx->index > actx->length - 1) actx->index = 0; } return actx->frame[actx->index]; } Bool @animation2d_is_animation(AnimationContext2D* actx) { return T(actx->signature == 'animated', TRUE, FALSE); } U0 @animation2d_reset(AnimationContext2D* actx) { actx->index = 0; } class @animation2d { Context2D* (*Frame)(AnimationContext2D* actx); U0 (*Reset)(AnimationContext2D* actx); Bool (*IsAnimation)(AnimationContext2D* actx); AnimationContext2D* (*NewFromFrames)(Context2D** frames, I64 length, I64 duration = 250); }; @animation2d Animation2D; Animation2D.IsAnimation = &@animation2d_is_animation; Animation2D.NewFromFrames = &@animation2d_new_from_frames; Animation2D.Frame = &@animation2d_frame; Animation2D.Reset = &@animation2d_reset; "animation2d ";