Yay0 (Compression)

From Wexos's Wiki
Jump to navigationJump to search

Yay0 is a RLE compression (run-length encoding). It is used in many Nintendo 64 games, and early Nintendo GameCube games as well. One example of a game which uses Yay0 is Luigi's Mansion for the Nintendo GameCube. Note that Yay0-compressed files are not affected by the endianness of the CPU. All fields will always be stored as big endian.

Header

A Yay0-compressed file starts with the following header:

Offset Type Description
0x00 String File magic. Always Yay0 in ASCII.
0x04 UInt32 Size of the decompressed data in bytes.
0x08 UInt32 Link table offset.
0x0C UInt32 Byte chunk offset.

Chunks

The data is stored into different chunks. There are three different data blocks, the command block, which is stored directly after the header, and then two are linked in the header. Each UInt32 in the command block contains 32 commands, one per bit, where MSB is the first command, and LSB corrusponds to the last command. Commands are read until the output data size matches the size of the uncompressed data, which is specified in the header.

Direct Copy

If a command bit is 1, then one byte is copied directly from the input to the output data. The data is copied from the byte chunk block.

Run-length

If a command bit is 0, then the chunk contains run-length encoded data. One UInt16 (A) has to be read from the link table block. The data is copied from the output to the output. The output address, where the data is copied from, can be calculated using this formula:

CopyOffset = CurrentOffset - (A & 0xFFF) - 1

Then the number of bytes to copy needs to be calculated. The run-length command supports two different size mode, and first the following calculation is performed:

B = (A >> 12) & 0b1111

If B is zero, then another byte is read from the byte chunk block. The number of bytes to copy is then calculated by adding 0x12 to the read byte. If B is not zero, then the number of bytes to copy is by adding 2 to B.