User Tools

Site Tools


banjo_kazooie:sprites

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
banjo_kazooie:sprites [2025/04/12 12:23]
snowboundmage2
banjo_kazooie:sprites [2025/04/12 13:01] (current)
snowboundmage2 [Sprite Asset]
Line 1: Line 1:
 ====== Sprite Data ====== ====== Sprite Data ======
  
-This page documents the binary ​layout of sprite ​files found in the Banjo-Kazooie ​ROM (Nintendo 64)These files contain image data composed of one or more frameseach composed of a series of image chunks.+This page documents the binary sprite ​format derived from Banjo-Kazooie’s N64 romIt supports both single-chunk and multi-frame layoutswith support for various pixel formats and chunk-based rendering.
  
-All multi-byte values ​are stored in **big endian**.   +All integers ​are **big-endian** ​unless ​stated ​otherwise.
-Unless otherwise ​stated, all examples use sprite ID `06EB`.+
  
-===== File Structure =====+----
  
-A sprite file is divided into the following sections:+===== 🢩 Overview =====
  
-  * [[#​header|Header (0x00–0x10)]] +This format is used for static or animated sprite graphics in the ROMDepending on frame count, it can store a simple image or a complex animation.
-  * [[#​frame_offset_table|Frame Offset Table (0x10–...)]] +
-  * [[#​frame_data|Frame Data]] +
-  * [[#​chunk_data|Chunk Data (WIP)]]+
  
-===== Header ===== +----
-The header occupies the first 0x10 bytes of the file and contains basic metadata about the sprite.+
  
-^ Offset ^ Size ^ Description ^ +===== 📘 Reference Table =====
-| 0x00 | 2 bytes | Frame count (`frameCnt`) | +
-| 0x02 | 2 bytes | Format ID / type (`type`) — usually `0x0100` | +
-| 0x04 | 2 bytes | Unknown (`unk4`) | +
-| 0x06 | 2 bytes | Unknown (`unk6`) | +
-| 0x08 | 2 bytes | Possibly default width (`unk8`) | +
-| 0x0A | 2 bytes | Possibly default height (`unkA`) | +
-| 0x0C | 4 bytes | Bitfield flags (`unkC`) — see below | +
-| 0x10 | ...     | Frame offset table (`offsets[]`) |+
  
-The bitfield at `0x0C` may contain rendering options or format hints.+==== 🥇 File Header (offsets 0x00–0x03) ====
  
-==== Bitfield at 0x0C ====+^ Field       ^ Offset ^ Type       ^ Description ​                   ^ 
 +| Frame Count | 0x00   | `uint16_t` | Number of frames ​              | 
 +| Format ID   | 0x02   | `uint16_t` | Format identifier ​             |
  
-The 32-bit word at offset `0x0C` includes the following layout:+==== 🎨 Format ID Mappings ====
  
-Bits Field ^ Description ^ +Format ID Enum     ^ Description ​                 ^ Bits per Pixel 
-31–28 ​`bit31` ​Possibly render mode +0x0001 ​   ​CI4      ​4-bit color indexed ​         | 4              ​
-27–25 ​`bit27` ​Possibly format ID +0x0004 ​   ​CI8      ​8-bit color indexed ​         | 8              ​
-24–23 ​`bit24` ​Possibly compression ​+0x0020 ​   ​I4       4-bit intensity ​             | 4              ​
-22–21 ​`bit22` ​Possibly blending or layer mode +0x0040 ​   ​I8       8-bit intensity ​             | 8              ​
-20–0  ​`pad`   | Unused or reserved ​|+0x0400 ​   ​RGBA16 ​  | 16-bit RGBA (5-5-5-1 format) | 16             | 
 +| 0x0800 ​   | RGBA32 ​  | 32-bit RGBA                  | 32             |
  
-===== Frame Offset Table ===== +----
-Immediately following the header is the frame offset table. This table contains 32-bit pointers to each frame'​s data section, relative to the start of the offset table.+
  
-^ Offset ^ Size ^ Description ^ +===== 🖼 Single Chunk Sprite Layout =====
-| 0x10 | 4 bytes | Frame 0 offset: `0x00000004` (points to 0x18 from file start) |+
  
-Total size of this section = `4 × frameCnt`+Used if `frameCount > 256(`0x0100`).
  
-===== Frame Data =====+==== Structure ​====
  
-Each frame starts with a 20-byte 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        |
  
-==== Frame Header ​====+==== Notes ==== 
 +  * No frame table or chunk headers are present. 
 +  * Pixel data begins after a 16-byte header, aligned to the next 8-byte boundary.
  
-^ Offset ^ Size ^ Field ^ Description ^ +----
-| +0x00 | 2 bytes | `unk0` | Possibly X offset | +
-| +0x02 | 2 bytes | `unk2` | Possibly Y offset | +
-| +0x04 | 2 bytes | `w`    | Width in pixels | +
-| +0x06 | 2 bytes | `h`    | Height in pixels | +
-| +0x08 | 2 bytes | `chunkCnt` | Number of image chunks | +
-| +0x0A | 2 bytes | `unkA` | Unknown | +
-| +0x0C | 2 bytes | `unkC` | Unknown | +
-| +0x0E | 2 bytes | `unkE` | Unknown | +
-| +0x10 | 2 bytes | `unk10` | Unknown | +
-| +0x12 | 2 bytes | `unk12` | Unknown |+
  
-After the frame header, a sequence of **chunk definitions** begins.+===== 🎞 Multi-Frame Sprite Layout =====
  
-===== Chunk Data =====+Used if `frameCount ≤ 256` (`0x0100`).
  
-Each chunk describes a rectangular image section used to draw part of the frame.+==== 📂 Frame Table ====
  
-==== Chunk Structure ====+  * Offset: `0x10` 
 +  * Entry size: 4 bytes per frame 
 +  * Each entry contains a **relative** 32-bit offset from the start of the frame data block.
  
-^ Offset ^ Size ^ Field ^ Description ^ +==== 🧱 Frame Data Block ====
-| +0x00 | 2 bytes | `x` | X position | +
-| +0x02 | 2 bytes | `y` | Y position | +
-| +0x04 | 2 bytes | `w` | Width | +
-| +0x06 | 2 bytes | `h` | Height |+
  
-There are `chunkCntchunk structures per frame, immediately following the frame header.+Starts at: `0x10 + (frameCount × 4)`
  
-===== Image Format Enum =====+=== Frame Header ​===
  
-The sprite rendering system likely interprets pixel data using the following enum:+^ 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 ​    |
  
-^ Value ^ Name ^ Description ^ +=== Palette Data (for CI4 / CI8 only) ===
-| 0 | `CI4`     | Color Indexed 4-bit | +
-| 1 | `CI8`     | Color Indexed 8-bit | +
-| 2 | `I4`      | Intensity 4-bit | +
-| 3 | `I8`      | Intensity 8-bit | +
-| 4 | `RGBA16` ​ | 16-bit RGBA | +
-| 5 | `RGBA32` ​ | 32-bit RGBA | +
-| 6 | `IA4`     | Intensity + Alpha 4-bit | +
-| 7 | `IA8`     | Intensity + Alpha 8-bit | +
-| 8 | `UNKNOWN` | Fallback ​unknown |+
  
-Format may be deduced from the header `type` field or the bitfield at `0x0C`.+^ Field        ^ Offset ​            ^ Size       ^ Description ​                      ^ 
 +| Palette Data | aligned after 0x14 | 32 or 512B | 16×2 or 256×2 bytes, depending on format |
  
-===== C Definitions =====+=== Chunk Table ===
  
-The following C-like structures represent the sprite format as reverse-engineered:+Each chunk entry is 8 bytes:
  
-<code c+^ Field        ^ Offset ^ Type       ^ Description ​        ^ 
-typedef struct { +| Chunk X      | 0x00   | `int16_t` ​ | Chunk X position ​   | 
-  ​u16 frameCnt; +| Chunk Y      | 0x02   | `int16_t` ​ | Chunk Y position ​   | 
-  ​u16 type; +| Chunk Width  | 0x04   | `uint16_t` | Width of chunk      | 
-  ​u16 unk4; +| Chunk Height | 0x06   | `uint16_t` | Height of chunk     | 
-  ​u16 unk6; + 
-  ​u16 unk8; +  * Pixel data for each chunk follows the chunk table. 
-  ​u16 unkA; +  * All data is aligned to the next 8-byte boundary. 
-  ​struct { + 
-    u32 bit31 : 4; +---- 
-    u32 bit27 : 3; + 
-    u32 bit24 : 2; +===== 🧠 Design Rationale ===== 
-    u32 bit22 : 2; + 
-    u32 pad_bit20 ​21; +=== Format ID and Versatility === 
-  ​} unkC; +  * 16-bit format ID allows for clean extensibility. 
-  ​u32 offsets[]; +  * Decoding behavior is format-specific (e.g. CI formats require palettes). 
-} BKSprite;+ 
 +=== 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 
 + 
 +----
  
-typedef struct { +===== 📌 Notes =====
-  s16 unk0; +
-  s16 unk2; +
-  s16 w; +
-  s16 h; +
-  s16 chunkCnt; +
-  s16 unkA; +
-  s16 unkC; +
-  s16 unkE; +
-  s16 unk10; +
-  s16 unk12; +
-} BKSpriteFrame;​+
  
-typedef struct { +  * All integers are stored in **big-endian** format. 
-  ​s16 x; +  ​* Offsets in the frame table are **relative** to the frame data section. 
-  ​s16 y; +  ​* Data structures and pixel data must be aligned to 8-byte boundaries. 
-  ​s16 w; +  ​* CI4/CI8 formats require an internal palette directly after the frame header.
-  s16 h; +
-} BKSpriteTextureBlock;​ +
-</code>+
  
 ---- ----
  
-''​This ​format ​is still under investigation. Contributions ​and corrections ​welcome.''​+''​This ​documentation ​is a work in progress based on reverse engineering efforts. Contributions welcome!''​
  
banjo_kazooie/sprites.1744460614.txt.gz · Last modified: 2025/04/12 12:23 by snowboundmage2