// Shared sprite-codegen staging: emits every included (shift, op) blit
// routine once, back to back, into a caller-provided image buffer and
// records the slot-relative routineOffsets on the sprite. This is the SINGLE
// source of the emitted-image layout, used by BOTH the runtime JIT
// (jlSpriteCompile, src/codegen/spriteCompile.c) and the offline bake tool
// (tools/spritebake) so a pre-baked .spc image is byte-identical to what the
// JIT would have produced -- no second implementation to drift.

#ifndef JOEYLIB_SPRITE_STAGE_H
#define JOEYLIB_SPRITE_STAGE_H

#include "joey/sprite.h"
#include "joey/types.h"

// Per-routine emit cap: no single (shift, op) routine may exceed this. A
// long literal so it never wraps the 16-bit int the IIgs uses for plain int
// arithmetic. See spriteStage.c for why the buffer comes from jlpBigAlloc.
#define SPRITE_EMIT_SCRATCH_BYTES (16384ul)

// Whole-sprite staging image cap: every included routine is emitted back to
// back into a SPRITE_STAGING_BYTES buffer, then copied into the arena slot in
// one memcpy. Bounded by the uint16 routine-offset budget (no routine may
// start at >= SPRITE_NOT_COMPILED and each is capped at
// SPRITE_EMIT_SCRATCH_BYTES), so the image never runs past 64 KB.
#define SPRITE_STAGING_BYTES      (0x10000ul)

// Emit every included variant once into `staging` (>= SPRITE_STAGING_BYTES),
// recording each routine's slot-relative offset in sp->routineOffsets
// (0xFFFF == SPRITE_NOT_COMPILED for absent variants). Tier 1 = DRAW shifts
// ascending; tier 2 = SAVE+RESTORE atomic pairs ascending. alignedOnly keeps
// only the byte-aligned degrade phases (arena-full fallback). Returns the
// total image size in bytes (0 == nothing compiled). Depends only on the
// per-CPU emitters -- no arena or heap -- so it links cleanly into a host
// bake tool.
uint32_t spriteStageAndPlan(uint8_t *staging, jlSpriteT *sp, bool alignedOnly);

#endif
