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:15]
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]]+
  
-===== 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 (`0x0001`) | +
-| 0x02 | 2 bytes | Format ID (`0x0100`) | +
-| 0x04 | 4 bytes | Unknown or sentinel (`0xFFFFFFFF`) | +
-| 0x08 | 2 bytes | Default width? (`0x00BE` ​190) | +
-| 0x0A | 2 bytes | Default height? (`0x00BE` ​190) | +
-| 0x0C | 4 bytes | Padding or flags (`0x00000000`) |+
  
-===== Frame Offset Table ===== +==== 🥇 File Header (offsets 0x00–0x03) ​====
-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.+
  
-For a file with 1 frame: +^ Field       ^ Offset ^ Type       ^ Description ​                   
-^ Offset ^ Size ^ Description ^ +Frame Count 0x00   | `uint16_t| Number of frames ​              | 
-0x10 4 bytes Frame 0 offset: ​`0x00000004(points to 0x18 from file start) ​|+| Format ID   | 0x02   | `uint16_t` | Format identifier ​             ​|
  
-Total size of this section ​`4 × frame_count`+==== 🎨 Format ID Mappings ====
  
-===== Frame Data =====+^ 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             |
  
-Each frame starts with a 12-byte header.+----
  
-==== Frame 0 Header (at 0x18) ====+===== 🖼 Single Chunk Sprite Layout =====
  
-^ Offset ^ Size ^ Description ^ +Used if `frameCount > 256` (`0x0100`).
-| 0x00 | 2 bytes | X position (`0x0000`) | +
-| 0x02 | 2 bytes | Y position (`0x0000`) | +
-| 0x04 | 2 bytes | Width in pixels (`0x0391` = 913) | +
-| 0x06 | 2 bytes | Height in pixels (`0x0013` = 19) | +
-| 0x08 | 2 bytes | Chunk count (`0x003E` = 62) | +
-| 0x0A | 2 bytes | Unknown or padding ​(`0x0000`) |+
  
-Following the frame header, chunk data begins at offset `0x24`.+==== Structure ====
  
-===== Notes =====+^ 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        |
  
-  ​The format ID `0x0100` appears to be standard for most (if not all) sprite files+==== Notes ==== 
-  * Chunk data is not yet fully documented, but it follows immediately ​after the frame header+  ​No frame table or chunk headers are present
-  * Width and height fields may override ​the default width/​height stored in the main header.+  * Pixel data begins ​after a 16-byte ​header, aligned to the next 8-byte boundary.
  
 ---- ----
-''​This ​format is still under investigationIf you have additional samples ​or insightsplease contribute.''​+ 
 +===== 🎞 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 layoutsupports 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 effortsContributions welcome!''​
  
banjo_kazooie/sprites.1744460108.txt.gz · Last modified: 2025/04/12 12:15 by snowboundmage2