67 lines
3.1 KiB
C
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
|