Skip to main content

Phase 1: Extraction & Analysis

:::info Status In Progress — ROM structure fully analyzed. Custom compression format identified. Next step: RAM dump via emulator to access decompressed model data. :::

Goals

  1. Determine if model data is compressed YES - ERZ format (Huffman+LZ)
  2. Locate model data offsets in the ROM binary Character cluster at 0x621E2
  3. Rip Tony Hawk's existing 3D model from the ROM
  4. Extract and catalog all character textures
  5. Document the skeleton hierarchy and segment count

Step 0: RAM Dump (Primary Approach)

Since the ROM uses custom compression, the fastest path is to dump decompressed data directly from N64 RAM while the game is running.

Quick Start

# Install emulator
brew install mupen64plus

# Run the game (select Tony Hawk, enter a level)
mupen64plus "Tony Hawk's Pro Skater (USA) (Rev 1).z64"

# Save state: press F5 in-game
# State saved to: ~/.local/share/mupen64plus/save/

# Extract and analyze
cd n64-mods
python3 scripts/extract_savestate.py ~/.local/share/mupen64plus/save/THPS*.st
python3 scripts/dump_ram.py *_rdram.bin

What This Gets Us

The RAM dump contains the fully decompressed character model currently in use:

  • F3DEX2 display lists (ready to parse)
  • Vertex data (positions, UVs, normals)
  • Loaded textures (in N64 format, ready to view with Texture64)
  • Bone/animation state

The dump_ram.py script scans for display list patterns and exports OBJ models that can be imported into Blender.

Alternative: RetroArch

If mupen64plus doesn't work, RetroArch with the mupen64plus-next core also produces save states we can extract RDRAM from.


Step 1: Rip Model via Emulator (Alternative)

Use Project64 with the LemD3D9 graphics plugin to capture the rendered geometry.

Setup

  1. Install Project64
  2. Download LemD3D9 r22 plugin
  3. Copy LemD3D9.dll to Project64's Plugin/GFX/ folder
  4. In Project64 Settings → Plugins → Video, select LemD3D9

Ripping Process

  1. Load THPS ROM in Project64
  2. Navigate to character select screen (select Tony Hawk)
  3. In LemD3D9 graphics settings, enable geometry export
  4. The plugin captures F3DEX2 display lists as they render → exports OBJ files
  5. Import the OBJ into Blender to study proportions and triangle count

What to Document

  • Total triangle count
  • Number of mesh segments (body parts)
  • Approximate vertex positions (will be used to locate data in ROM)

Step 2: Locate Model Data in ROM

Hex Editor Analysis

Open the .z64 in HxD or ImHex.

Strategy: Use known vertex positions from the ripped model to search the ROM binary.

Example: If a vertex is at position (120, -45, 30)
In big-endian 16-bit: 0x0078 0xFFD3 0x001E
Search for this byte sequence in the ROM

What to Look For

  • File table: Usually near the start of ROM, contains offset/size pairs pointing to assets
  • Vertex data clusters: Groups of 16-byte entries with signed-16-bit coordinate patterns
  • Display list commands: 8-byte entries starting with known F3DEX2 opcodes:
    • 0x01 — G_VTX (load vertices)
    • 0x05 or 0x06 — G_TRI1/G_TRI2 (draw triangles)
    • 0xFD — G_SETTIMG (set texture image)
    • 0xF5 — G_SETTILE (configure texture tile)

Known F3DEX2 Command Bytes (First byte of 8-byte command)

ByteCommandPurpose
01G_VTXLoad vertex buffer
05G_TRI1Draw 1 triangle
06G_TRI2Draw 2 triangles
D7G_TEXTURESet texture parameters
D9G_SETOTHERMODE_HSet render modes
E7G_RDPPIPESYNCPipeline sync
F5G_SETTILEConfigure texture tile descriptor
FDG_SETTIMGSet texture image address
F8G_RDPFULLSYNCFull sync

Step 3: Extract Textures

Use Texture64 to scan the ROM for textures.

Process

  1. Open ROM in Texture64
  2. Scan for CI4/CI8/RGBA16 textures in the character data region
  3. Identify face, body, clothing textures
  4. Export as PNG for reference
  5. Document: format, dimensions, palette, ROM offset for each texture

Expected Texture Formats

  • CI4 (4-bit color-indexed): 16 colors per texture, most memory-efficient
  • CI8 (8-bit color-indexed): 256 colors, used for more detailed textures like faces
  • RGBA16 (5551): 16-bit per pixel, used sparingly due to TMEM constraints

Compression: CONFIRMED - Edge of Reality "ERZ" Format

:::danger Critical Finding The ROM uses a custom Huffman + LZ hybrid compression. No standard tools can decompress it. The emulator-based RAM dump approach bypasses this entirely. :::

ERZ Block Format (discovered via ROM analysis)

Offset Size Description
0x00 3 Magic: "ERZ" (45 52 5A)
0x03 1 Type: 01 (standard) or 02 (alternate)
0x04 4 Buffer size (big-endian u32): 0x4000 for models, 0x10000 for levels
0x08 4 Decompressed data size (big-endian u32)
0x0C ... Compressed bitstream (Huffman + LZ)

ROM Block Statistics

Buffer SizeBlock CountAvg Decomp SizeLikely Content
16 KB (0x4000)10748.7 KBModels, textures, game data
64 KB (0x10000)1324.4 KBLevel geometry
8 KB (0x2000)225.7 KBAudio/small assets

Character Data Location

Cluster 1 at ROM 0x621E2 - 0xA87CE:

  • 51 consecutive ERZ blocks
  • Average decompressed size: 5.7 KB each
  • Total region: ~285 KB compressed
  • This is the strongest candidate for character model + texture data
  • 10 characters × ~5 blocks each ≈ 50 blocks (matches!)

Decompressor Function

  • ROM offset: 0x1F30
  • RAM address: 0x80001330
  • Signature: Allocates 384-byte stack buffer for 3 Huffman lookup tables (128 bytes each)
  • Algorithm: Reads bitstream byte-by-byte, uses tables to decode Huffman symbols, outputs literal bytes or LZ back-references

Compression NOT Used

FormatPresent?
ZlibNo (false positive byte patterns only)
MIO0/YAY0/YAZ0No
Standard LZ77No (custom variant)

Step 5: Document the Skeleton

From the ripped model and ROM analysis, determine:

  • Total bone count
  • Bone hierarchy (parent-child tree)
  • Rest pose bone positions
  • Which mesh segments attach to which bones
  • Animation data location in ROM (separate from model data)

Expected Skeleton Structure (typical N64 skater)

Root (pelvis)
├── Spine
│ ├── Head
│ ├── Left Upper Arm
│ │ └── Left Forearm
│ │ └── Left Hand
│ └── Right Upper Arm
│ └── Right Forearm
│ └── Right Hand
├── Left Upper Leg
│ └── Left Lower Leg
│ └── Left Foot
└── Right Upper Leg
└── Right Lower Leg
└── Right Foot

Tools Needed

Deliverables

After completing this phase, we should have:

  1. Tony Hawk's model as OBJ files (per-segment)
  2. All character textures as PNGs with documented ROM offsets
  3. Complete skeleton hierarchy map
  4. ROM offset ranges for model data, texture data, and animation data
  5. Compression status confirmed