Compression

From ProjectPokemon Wiki
Revision as of 22:36, 26 October 2016 by Nich (talk | contribs) (LZ is also available on the GBA; fixed up formatting and grammar)
Jump to navigation Jump to search
This article is incomplete.
Please feel free to add missing information and complete the article.

Compression is used in many of the games to decrease the amount of space taken up by files when not loaded into RAM or just not actively being used.

Lempel–Ziv (LZ)

The main set of compression algorithms in GBA-era and later games is Lempel–Ziv compression, commonly shortened to LZ. Algorithms classified under this name use relative references to bytes that have already been processed.

The header for LZ compression is 4 bytes wide:

struct lz_header {
    u32 type : 8;  /* First byte */
    u32 decompressed_size : 24;  /* Other 3 bytes */
}

LZ77

The main variant, LZ77, allows references up to 0xFFF bytes back for up to 0x12 bytes. LZ77's type identifier is 0x10.

LZSS Compression

Another common variant used is LZSS which allows for more controlled decompression. LZSS allows for up to 0xFFF bytes back for up to 0x1110 bytes depending on the mode switch. LZSS has a type of 0x11.

BLZ Compression

BLZ compression is used mainly for data that cannot be copied into an output buffer; usually it must be done in place usually because the block is too large. This was implemented in Diamond and Pearl but was not extensively used until Heart Gold and Soul Silver, where it was used to compress the ARM binaries as well as the overlays.

The magic number 0xDEC0???? indicates the 0x1Cth byte of the compressed region. The end of the compressed region is stored at the 0x14th byte (a u32); note that the end is an absolute location in RAM. If the end RAM address is 0, the file is considered decompressed. Compression starts at the end of the compressed region and fills in from the end of the decompressed region until it reaches the start of the decompressed region.

struct blz_control {
    u32 compressed_size : 24;
    u32 header_size : 8;
    u32 decompressed_increase;
}