Demonstrates loading LZ77-compressed tile data directly into VRAM using the LzssDecodeVram() function. The compressed tile file is 8.5 KB in ROM but decompresses to 12.5 KB of 4bpp tile data – a 31% size reduction. On a real cartridge with limited ROM space, compression like this is essential for fitting large tilesets, and the SNES hardware can decompress data fast enough to load during force blank.
LzssDecodeVram()LZ77 is a dictionary-based compression algorithm that replaces repeated byte sequences with back-references (offset + length pairs). The LZSS variant used here stores a header with the uncompressed size, followed by flag bytes that indicate whether the next chunk is a literal byte or a back-reference. The gfx4snes tool generates LZ77-compressed tile data when invoked with the -z flag. The OpenSNES library provides LzssDecodeVram() which decompresses directly into VRAM via the PPU data port ($2118/$2119), avoiding the need for a large RAM buffer.
Tile graphics (character data) are the largest asset in most SNES games – a single 4bpp 8x8 tile is 32 bytes, and a full tileset can easily reach 16-32 KB. Tilemaps are smaller (2 bytes per tile entry, typically 2 KB for a 32x32 screen) and palette data is tiny (32 bytes for 16 colors). Compressing the large tile data gives the best ROM savings with minimal added complexity. In this example, only the .pic file is compressed; the .map and .pal files are stored raw.
The SNES PPU ignores writes to VRAM during active display (scanlines 0-224). Decompression takes longer than one VBlank period, so the screen must be kept in force blank (REG_INIDISP = $80, which sets bit 7 of register $2100) during the entire decompression. The consoleInit() function leaves the screen in force blank by default, so the decompression can proceed immediately.
This example has no interactive controls. It displays a static image.
consoleInit() initializes the NMI handler and leaves the display disabled. Force blank is explicitly set to ensure VRAM writes succeed during decompression:
LzssDecodeVram() reads the compressed data from ROM and writes the decompressed 4bpp tile data directly to VRAM at word address $4000. No intermediate RAM buffer is needed:
The 16-color palette is DMA'd to CGRAM starting at color 0. The tilemap is DMA'd to VRAM at $0000:
BG1 is configured with its tilemap at VRAM $0000 and tile data at $4000, then Mode 1 is activated with only BG1 enabled:
The program enters an infinite WaitForVBlank() loop. The image is static – no scrolling, no animation:
Then open mode1_lz77.sfc in your emulator (Mesen2 recommended). You should see a static full-screen image. The key takeaway is not what is displayed, but that the tile data was loaded from a compressed source, saving approximately 4 KB of ROM space.
console lzss background sprite