Skip to content
View in the app

A better way to browse. Learn more.

ResHax

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.
Help us keep the site running.
Zero Tolerance for Disrespect

[PS2/Xbox/PC] Test Drive / TD Overdrive: The Brotherhood of Speed - Steve Snake compression (SNK0)

Featured Replies

  • Localization

SNK0 is a cut-down deflate: LZ77 with a 32 KB window and one Huffman code per block. The literal/length alphabet and the length and distance tables are the same as deflate, but the block header is much simpler and distances aren't Huffman coded.

not sure what the u32 at 0x04 is, but it doesn't seem needed for decompression

Attached a script to decompress the file into .bin format

Usage

python snk_decompress.py speaker.snk                writes speaker.snk.bin
python snk_decompress.py speaker.snk speaker.bin    writes speaker.bin

File layout

Everything is little endian. Nothing inside the bitstream is aligned: each block starts at the bit right after the previous block ends.

header       0x10 bytes
bitstream    blocks, until the output reaches the decompressed size
padding      zero bits to the end of the byte, then zero bytes

Header

0x00  char[4]  magic "SNK0"
0x04  u32      unknown (see Notes)
0x08  u32      CRC32 of the decompressed data (standard zlib / PKZIP CRC32)
0x0C  u32      decompressed size
0x10           bitstream starts here

Differences from deflate

  • No zlib/gzip wrapper and no 3-bit block header. Every block works like a dynamic block.

  • The code lengths are stored raw as nibbles, instead of HLIT/HDIST/HCLEN and the run-length coded code length alphabet.

  • There's no distance tree. The distance code is always getbits(5).

  • No final-block flag. The decompressed size in the header says when to stop.

Notes

  • The sample has 10 blocks of about 14.5 KB compressed each (115k to 125k bits), apart from a short last one. The decoder doesn't care where blocks are split.

  • Code lengths in the sample go up to 14 bits. The 4-bit field allows up to 15.

  • the sample (speaker.snk) itself is a PS2 texture: a 0x80 byte header, a 256 colour RGBA palette at 0x80 (CSM1 order, alpha 0 to 0x7F) and 512x512 swizzled 8-bit pixels at 0x480. In the header, 0x00 = 0x80 (palette offset), 0x04 = 0x480 (pixel offset), 0x2C = 0x13 (PSMT8) and 0x2E / 0x30 = 512 / 512.

snk_decompress.py

Create an account or sign in to comment

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.