====== Sprite Data ====== This page documents the binary sprite format derived from Banjo-Kazooieโ€™s N64 rom. It supports both single-chunk and multi-frame layouts, with support for various pixel formats and chunk-based rendering. All integers are **big-endian** unless stated otherwise. ---- ===== ๐Ÿขฉ Overview ===== This format is used for static or animated sprite graphics in the ROM. Depending on frame count, it can store a simple image or a complex animation. ---- ===== ๐Ÿ“˜ Reference Table ===== ==== ๐Ÿฅ‡ File Header (offsets 0x00โ€“0x03) ==== ^ Field ^ Offset ^ Type ^ Description ^ | Frame Count | 0x00 | `uint16_t` | Number of frames | | Format ID | 0x02 | `uint16_t` | Format identifier | ==== ๐ŸŽจ Format ID Mappings ==== ^ Format ID ^ Enum ^ Description ^ Bits per Pixel ^ | 0x0001 | CI4 | 4-bit color indexed | 4 | | 0x0004 | CI8 | 8-bit color indexed | 8 | | 0x0020 | I4 | 4-bit intensity | 4 | | 0x0040 | I8 | 8-bit intensity | 8 | | 0x0400 | RGBA16 | 16-bit RGBA (5-5-5-1 format) | 16 | | 0x0800 | RGBA32 | 32-bit RGBA | 32 | ---- ===== ๐Ÿ–ผ Single Chunk Sprite Layout ===== Used if `frameCount > 256` (`0x0100`). ==== Structure ==== ^ Field ^ Offset ^ Type ^ Description ^ | X | 0x08 | `int16_t` | X position | | Y | 0x0A | `int16_t` | Y position | | Width | 0x0C | `uint16_t` | Width in pixels | | Height | 0x0E | `uint16_t` | Height in pixels | | Data Offset | ~0x10+ | โ€” | 8-byte aligned after header | | Data Size | โ€” | computed | Width ร— Height ร— bpp รท 8 | ==== Notes ==== * No frame table or chunk headers are present. * Pixel data begins after a 16-byte header, aligned to the next 8-byte boundary. ---- ===== ๐ŸŽž Multi-Frame Sprite Layout ===== Used if `frameCount โ‰ค 256` (`0x0100`). ==== ๐Ÿ“‚ Frame Table ==== * Offset: `0x10` * Entry size: 4 bytes per frame * Each entry contains a **relative** 32-bit offset from the start of the frame data block. ==== ๐Ÿงฑ Frame Data Block ==== Starts at: `0x10 + (frameCount ร— 4)` === Frame Header === ^ Field ^ Offset ^ Type ^ Description ^ | X | 0x00 | `int16_t` | Frame X offset | | Y | 0x02 | `int16_t` | Frame Y offset | | Width | 0x04 | `uint16_t` | Frame width | | Height | 0x06 | `uint16_t` | Frame height | | Chunk Count | 0x08 | `uint16_t` | Number of chunks | === Palette Data (for CI4 / CI8 only) === ^ Field ^ Offset ^ Size ^ Description ^ | Palette Data | aligned after 0x14 | 32 or 512B | 16ร—2 or 256ร—2 bytes, depending on format | === Chunk Table === Each chunk entry is 8 bytes: ^ Field ^ Offset ^ Type ^ Description ^ | Chunk X | 0x00 | `int16_t` | Chunk X position | | Chunk Y | 0x02 | `int16_t` | Chunk Y position | | Chunk Width | 0x04 | `uint16_t` | Width of chunk | | Chunk Height | 0x06 | `uint16_t` | Height of chunk | * Pixel data for each chunk follows the chunk table. * All data is aligned to the next 8-byte boundary. ---- ===== ๐Ÿง  Design Rationale ===== === Format ID and Versatility === * 16-bit format ID allows for clean extensibility. * Decoding behavior is format-specific (e.g. CI formats require palettes). === Single vs Multi-frame Decision === * A `frameCount > 0x0100` indicates the file is a simple image without a frame table. * Keeps parsing logic simpler for single-use graphics. === Frame Table Abstraction === * Offsets are relative to the frame data block, not absolute. * Allows reorganization and stream-friendly parsing. === 8-byte Alignment === * Ensures data structures are aligned in memory. * Improves DMA or cache line performance on N64. === Chunk-Based Rendering === * Chunks allow tile reuse or sub-rectangles. * Efficient layout, supports tilemaps or partial redraws. === Optional Palette === * CI4 and CI8 include palettes automatically. * Size and format are inferred based on format ID. ---- ===== โœ… Validation Checklist ===== Use the following to verify whether a file matches this format: - [ ] File size โ‰ฅ 4 bytes - [ ] Read and parse frame count and format ID - [ ] If frameCount > 0x0100 โ†’ parse as single-chunk - [ ] If โ‰ค 0x0100 โ†’ validate frame table offsets - [ ] Parse each frame header and chunk table - [ ] Validate alignment and total chunk data sizes ---- ===== ๐Ÿ“Œ Notes ===== * All integers are stored in **big-endian** format. * Offsets in the frame table are **relative** to the frame data section. * Data structures and pixel data must be aligned to 8-byte boundaries. * CI4/CI8 formats require an internal palette directly after the frame header. ---- ''This documentation is a work in progress based on reverse engineering efforts. Contributions welcome!''