joeylib2/src/core/spriteInternal.h

67 lines
3.1 KiB
C

// Internal sprite definitions shared between sprite.c and the
// per-platform codegen emitters. Public API users include
// joey/sprite.h instead.
#ifndef JOEYLIB_SPRITE_INTERNAL_H
#define JOEYLIB_SPRITE_INTERNAL_H
#include "codegenArenaInternal.h"
#include "joey/sprite.h"
#define SPRITE_OP_DRAW 0
#define SPRITE_OP_SAVE 1
#define SPRITE_OP_RESTORE 2
#define SPRITE_OP_COUNT 3
// Sentinel stored in routineOffsets[shift][op] when that op's emitter
// returned 0 bytes (i.e., the platform doesn't implement compiled
// codegen for that op yet). Distinct from a real offset of 0, which
// is valid for the first emitted op (typically DRAW shift 0).
#define SPRITE_NOT_COMPILED 0xFFFFu
struct SpriteT {
const uint8_t *tileData; // wTiles * hTiles * 32 bytes; NULL for loaded sprites
uint8_t widthTiles;
uint8_t heightTiles;
bool ownsTileData; // true if spriteDestroy must free tileData
// Compiled-path state. slot==NULL means not yet compiled (or
// compile failed); spriteDraw falls back to the interpreter.
// The fn-call address for (shift, op) is computed at draw time:
// (codegenArenaBase() + slot->offset + routineOffsets[shift][op])
// so a codegenArenaCompact that moves the slot's bytes is
// transparent to the caller.
ArenaSlotT *slot;
uint16_t routineOffsets[JOEY_SPRITE_SHIFT_COUNT][SPRITE_OP_COUNT];
SpriteFlagsE flags;
// Per-shift, per-op MVN bank-patch cache for IIgs save/restore.
// patchMvnBanks rewrites 16+ MVN bank operands every call, but the
// banks themselves rarely change frame-to-frame (screen surface
// is fixed; backup buffer is allocated once). After the first
// patch, subsequent calls compare requested banks to the cache
// and skip the re-stamp loop. 0xFF means "never patched yet".
// 12 bytes per sprite. Unused on non-IIgs.
uint8_t cachedDstBank[JOEY_SPRITE_SHIFT_COUNT][SPRITE_OP_COUNT];
uint8_t cachedSrcBank[JOEY_SPRITE_SHIFT_COUNT][SPRITE_OP_COUNT];
// Cached `copyBytes * heightPx` per shift for spriteCompiledSaveUnder's
// `backup->sizeBytes` field. uint16_t * uint16_t goes through ORCA-C
// 2.2.1's ~CUMUL2 helper (~30-50 cyc); cache hit dodges it. Filled
// lazily on first call (0 sentinel = uncached).
uint16_t cachedSizeBytes[JOEY_SPRITE_SHIFT_COUNT];
};
// Compiled entry points. Implemented alongside spriteCompile in
// src/codegen/spriteCompile.c. Each handles the per-platform calling
// convention the emitted bytes use (cdecl on x86, stack args on 68k,
// inline asm + self-modifying stub on IIgs). The dispatchers in
// src/core/sprite.c call these when sp->slot is non-NULL, the
// matching routineOffsets entry is not SPRITE_NOT_COMPILED, and the
// draw/save/restore is fully on-surface.
void spriteCompiledDraw (SurfaceT *dst, const SpriteT *sp, int16_t x, int16_t y);
void spriteCompiledSaveUnder (const SurfaceT *src, SpriteT *sp, int16_t x, int16_t y, SpriteBackupT *backup);
void spriteCompiledRestoreUnder (SurfaceT *dst, const SpriteBackupT *backup);
#endif