Declarative animation player — data-driven frame sequencing. More...
#include <snes/types.h>Go to the source code of this file.
Classes | |
| struct | AnimClip |
| An animation clip — ROM-resident, 12 bytes. More... | |
| struct | AnimPlayer |
| A playback head — RAM, 8 bytes, array-friendly. More... | |
Macros | |
| #define | ANIM_F_FINISHED 0x01 |
| AnimPlayer.flags bit: an ANIM_ONCE clip reached its last frame. | |
| #define | ANIM_LOOP 0 |
| Loop mode: wrap to frame 0 after the last frame. | |
| #define | ANIM_NONE 0xFFFF |
| animTick()/animFrame() result when the player has no clip. | |
| #define | ANIM_ONCE 1 |
| Loop mode: hold the last frame and raise ANIM_F_FINISHED. | |
| #define | ANIM_PLAYER_INIT {0, 0, 0, 0, 0} |
| Static initializer: AnimPlayer p = ANIM_PLAYER_INIT;. | |
| #define | animDone(_p) |
| Nonzero once an ANIM_ONCE clip holds its last frame. | |
| #define | animFrame(_p) |
| Current frame value WITHOUT advancing (ANIM_NONE if stopped). | |
| #define | animStop(_p) |
| Stop: detach the clip, clear flags. Next animPlay starts fresh. | |
| #define | animTickMeta(_p, _tbl) |
| Tick + resolve against a gfx4snes metasprite pointer table. | |
| #define | animTickOam(_p, _id) |
| Tick + apply to the dynamic sprite engine (the 90% one-liner). | |
| #define | DECLARE_ANIM_CLIP(name, mode_, speed_, ...) |
| Declare a static const AnimClip with uniform frame duration. | |
Functions | |
| void | animPlay (AnimPlayer *p, const AnimClip *clip) |
| Start (or keep) a clip — continue-if-same semantics. | |
| void | animRestart (AnimPlayer *p) |
| Force-restart the current clip from frame 0, even mid-flight. | |
| u16 | animTick (AnimPlayer *p) |
| Advance one tick; return the current frame value. | |
Declarative animation player — data-driven frame sequencing.
Replaces the hand-rolled tempo counters every game rewrites (a tick variable, a modulo gate, manual oamframeid/oamrefresh pokes) with two small structs and one explicit per-frame call.
A frame value is an opaque u16 — the player sequences it without interpreting it. Choose what it means per clip:
Zero global state, zero init call, zero link dependencies: all state lives in caller-owned AnimPlayer structs, and nothing runs unless you tick. Pausing an animation = not ticking it (costs nothing).
Requires 'anim' in LIB_MODULES.
License: CC0 (Public Domain)
| #define ANIM_F_FINISHED 0x01 |
AnimPlayer.flags bit: an ANIM_ONCE clip reached its last frame.
| #define ANIM_LOOP 0 |
Loop mode: wrap to frame 0 after the last frame.
| #define ANIM_NONE 0xFFFF |
animTick()/animFrame() result when the player has no clip.
| #define ANIM_ONCE 1 |
Loop mode: hold the last frame and raise ANIM_F_FINISHED.
| #define ANIM_PLAYER_INIT {0, 0, 0, 0, 0} |
Static initializer: AnimPlayer p = ANIM_PLAYER_INIT;.
| #define animDone | ( | _p | ) |
Nonzero once an ANIM_ONCE clip holds its last frame.
| #define animFrame | ( | _p | ) |
| #define animStop | ( | _p | ) |
Stop: detach the clip, clear flags. Next animPlay starts fresh.
| #define animTickMeta | ( | _p, | |
| _tbl ) |
Tick + resolve against a gfx4snes metasprite pointer table.
Feeds oamDrawMeta()/oamMetaDrawDyn() directly:
| #define animTickOam | ( | _p, | |
| _id ) |
Tick + apply to the dynamic sprite engine (the 90% one-liner).
Writes oambuffer[_id].oamframeid and sets oamrefresh = 1 ONLY when the frame actually changed — the VRAM re-upload is the expensive part, so a 1-frame clip (stand pose) costs nothing after the first apply.
Macro (not a function) so the anim module carries no link dependency on the dynamic engine: the oambuffer reference lands in YOUR translation unit, which already links sprite/sprite_dynamic.
| #define DECLARE_ANIM_CLIP | ( | name, | |
| mode_, | |||
| speed_, | |||
| ... ) |
Declare a static const AnimClip with uniform frame duration.
Per-frame durations can't be expressed variadically — declare those clips as raw structs (see the AnimClip example above).
| void animPlay | ( | AnimPlayer * | p, |
| const AnimClip * | clip ) |
Start (or keep) a clip — continue-if-same semantics.
Safe to call unconditionally every frame from a state machine:
| p | Player (caller-owned) |
| clip | ROM clip to play |
| void animRestart | ( | AnimPlayer * | p | ) |
Force-restart the current clip from frame 0, even mid-flight.
| u16 animTick | ( | AnimPlayer * | p | ) |
Advance one tick; return the current frame value.
Call once per game-loop iteration per active player (after WaitForVBlank(), like the rest of the frame logic).