Formats
Byte-level specs for everything on the disc, each with provenance back to a Ghidra-traced function dump. The full reference for each format is on GitHub; the cards below are quick orientation.
Disc + container layer
What the disc image looks like before any in-game format gets involved.
PSX disc geometry
Mode2/2352 sectors, 24-byte ECC overhead, ISO9660 path resolution. The
iso crate's RawDisc::read_sector hides the sector layer and returns clean 2048-byte user data.PROT.DAT TOC
The project archive. 1234 entries indexed by a 16-byte TOC.
start_lba = toc[p+2], size = toc[p+5] - toc[p+3] + 4. Walked at boot by FUN_8003E4E8.CDNAME.TXT name map
#define name N markers tag block starts; names inherit forward to subsequent entries. Some labels are misleading (vab_01, move_program_no) — verify against the loader-call constant or magic bytes.Compression + dispatch
Legaia LZS
Custom LZSS decoder reverse-engineered from
FUN_8001A55C. 4096-byte ring buffer, zero-init. "Decompresses without error" is not a validity signal — always magic-check the decoded output.Asset type dispatcher
FUN_8001F05C dispatches by 8-bit type byte: 0=TIM, 2=TMD, 4=MES, 6=ANM, 7=VDF, 8=SIN, 9=TMD2, B=MOVE2. LZS-vs-raw decided per asset.Pack format
Used inside DATA_FIELD streaming chunks. Header
u32 count + u32 word_offsets[count].Standalone TIM-pack
Used by some standalone PROT entries. Header
(magic_lo, magic_hi, count<16, marker=0x01) + offsets; byte_offset = word_index*4 + 4.Per-asset formats
PSX TIM
Standard PlayStation texture format. 4 / 8 / 15 bpp; CLUTs scatter across PROT entries.
crates/tim exports to PNG.Legaia TMD
Custom PSX TMD variant — magic
0x80000002. Object pointers are byte offsets relative to header end. Primitives use a custom 8-byte group header + per-mode descriptor table at DAT_8007326C.VAB sound bank
PSX-standard VAB (program/tone/SPU-ADPCM sample).
crates/vab extracts and decodes to WAV. Banks live in battle_data / level_up — vab_01 is misleading.PsyQ SEQ
PsyQ's MIDI-derived sequence format (
pQES magic). 13-byte header (PPQN, tempo, time-sig) + delta-time / MIDI events with running status. Drives SsSeqOpen / SsSeqPlay. crates/seq parses + walks; engine-audio::Sequencer plays one against a VAB.MES dialog
Two variants: Compact (
0x404 magic) and Records (0x44 0x78). Bytecode tokens (Glyph / Op65 / Op4c / Op26 / End). Renderer is overlay-resident.Dialog font
Proportional Latin font (
FUN_80036888). 256-byte width table at 0x80073F1C; 38-entry escape table at 0x80074050; glyph bitmaps in VRAM at (896, 0), 4bpp, 16x16 cells (drawn 14x15).ANM animation
Asset-type 6 container.
(count + byte_offsets + records); marker_1 = 0x080C across all observed records. The per-actor anim tick is FUN_80021DF4 in SCUS_942.54 (4732 bytes) — best modelled as a layered pipeline rather than a per-opcode jump table. The keyframe pose decoder (dispatch byte 0x06) is ported to legaia_anm::AnimPlayer; the per-arm physics (position / velocity / acceleration math, the positional SFX emitter for 0x05, path interpolation for 0x03, render submissions for 0x04 / 0x07) is ported in engine_vm::actor_tick. See actor-vm.html for the full per-arm breakdown.MDT — move tables
Tactical Arts move records. Both layouts parse cleanly; the consumer is
FUN_800204F8. The runtime MOVE base (_DAT_8007B888) is sourced per-scene from descriptor[4] (type 0x05 = Move) of every CDNAME block's slot-1 PROT entry (a scene_asset_table) — not from a single boot-time PROT entry.Art data — Tactical Arts records
Per-character art records (Vahn
0x80160EFC / Noa 0x80176998 / Gala 0x8018BA54; PROT entry 0x05C4). 40-field schema: command sequence, action constant, power bytes (UDF / LDF + alt-range with floater/short misses), hit timing, special / hit effect cues, status effects, repeat-frame replay. Action Constants 0x00–0x32, Learned Art Constant slots (with character-specific holes), Art Anim Data slot table, Miracle / Super Art trigger tables. crates/art.Streaming + scene containers
DATA_FIELD streaming
Chunked container parsed by
crates/asset::parse_streaming. Sister detector data_field_truncated catches the shape where the final chunk's declared size walks past EOF (runtime extends via streaming DMA continuation).Scene bundles
Five sister detectors covering ~50% of PROT entries:
scene_tmd_stream, scene_vab_stream, scene_asset_table (canonical 7-asset table), scene_scripted_asset_table (script prescript + asset table), scene_event_scripts (prescript-only), plus tmd_size_prefix (truncated TMD-prefix).Effect bundles
Magic
0x02018B0C (efect.dat). 2-pack wrapper: 14 sprite-anim entries + 33 effect scripts indexed by effect ID.Field-pack format
Magic
0x01059B84. 4 PROT entries share a byte-identical 97-entry static schema. Consumer is FUN_801D6704 (overlay 0897, 801d6ae8) which calls the scene loader then dispatches through FUN_80020224; slots are read at hard-coded offsets, not iterated.Navmesh / region table
24-byte stride record table loaded into RAM at
0x80108EA4..0x801095xx. Per-record id + sub-id + 6-i16 coordinate fields + 4-byte ASCII tag + two u16 sub-fields. First few records carry shared template tags ((((, 333T, ZZZ); per-scene records follow. Inferred from a mednafen-state diff against the configured navmesh_candidate window; consumer not yet pinned.Runtime overlay carriers
MIPS overlay code
Some PROT entries carry MIPS code that loads into the overlay window at
0x801C0000+. The detector finds them by SP-prologue density.Overlay pointer-table code
Sister format to MIPS overlay. Header is a pointer table; the rest is overlay code referenced by those pointers. 42 PROT entries.
Audio path-strings + placeholders
Sound-driver path strings
3 SCUS consumers: sound init / streaming-asset loader / mode-aware ext dispatcher. 8 extensions: .MAP, .PCH, .spk, .dpk, etc.
Pochi-filler placeholder slots
265 PROT entries are dev-fill placeholders ("pochipochi..." byte pattern). Reserved-but-unused scene asset slots.
DMY.DAT
Memory-bus test pattern + paired random blobs. Dev fixtures, not real game data.
Asset descriptor format
The (type_byte << 24) | size calling convention used by
FUN_8001F05C and the descriptor-pair walker.