SOB (Sprite OBject) File format


Refreshers:

Note: What's described here was mostly figured out from the game's code and toying around in dolphin, it might be incomplete. Things like frame timings are hardcoded into the game.

Source code for this page if you need some reference implementation from the renderer at the bottom of this page.

The SOB file format is used to describe how to layout character data (from .sch -> Sprite CHaracter) to render a sprite. .SCH files don't contain sprites strictly speaking, but chunks of sprites.

Multi-bytes values are in little endian (contrary to the Gamecube being a big endian system).

The header is just a short word of two bytes, indicating how many sprites are described in a given .sob file. Let's say there are N sprites. Then the header is followed by N pairs of short integers, that are offset relative to the beginning of the file. These offsets are the beginning and end of attribute data for a single sprite. Each attribute is made of 6 bytes, so the difference between the beginning and end offset is always a multiple of 6. The game renders them starting from the last.

This file format does not describe which palette it uses, and which pages (continue reading to know what I'm referring to as a page) are mapped to which number, it is assumed to be the responsibility of the game engine.

Here's a description of what each of the 6 bytes does:

Blocks


Attribute data defines where to start pulling character data, and uses 4 bits to determine the dimensions in pixels to pull.

The Block Shape and Block Size, 2 bits each; They describe regions of 8x8 blocks.

There are three types of block shapes: Square (BlockShape = 0), Wide (BlockShape = 1), Tall (BlockShape = 2). Using a BlockShape = 3 makes the game read out of bounds and interpret incorrectly bytes describing the sizes. There are 4 different sizes for each type of Shape.

For the Square Shape:
    0: 1x1 blocks
    1: 2x2 blocks
    2: 4x4 blocks
    3: 8x8 blocks
    
Wide shapes:
    0: 2x1 blocks
    1: 4x1 blocks
    2: 4x2 blocks
    3: 8x4 blocks
    
Tall shapes:
    0: 1x2 blocks
    1: 1x4 blocks
    2: 2x4 blocks
    3: 4x8 blocks

Rendering


Rendering a given sprite ID at coordinates [x;y] consists of the following steps:



Note: the character data rendered here is only the last used character data, some other might be used mid-render

Note 2: Link being a special actor, the renderer here might use the wrong palette for certain things compared to the game


SPL File format


Based on the only SPL file in the game I could find

SPL is a rather simplistic file format. Is it a sequence of 4-short integers tile attributes. Each of these integers describe where to pull a 8x8 block of tile data from the associated SCH and how to flip it. Combining these 4 shorts describes a 16x16 tile. The shorts describe the tile in top-down/left-right order. Here's the layout of one 16-bit integer:

MAP files

Map files are just a 2x2 block of 32x32 blocks of tile indices in short little-endian format.

Renderer

This renderer uses WebGL2, make sure you have a GPU that is from this millenia.

It handles map/character data/palette/layout data entirely within shaders

You can load your own files


Only 1 is implemented for A, feel free to contribute the proper animation data for the 3 others

You can load your own files, make sure they have been decompressed