Reverse-engineering notes on SLPS-25172, the Japan/Asia PlayStation 2 release of Namco Tales Studio's Tales of Destiny 2, mastered 10 November 2002.
This repository is documentation and analysis only. It contains no disc
image, no extracted asset, no patch and no translation. The tools operate on
an image you supply yourself; every number quoted in the documents was
produced by running them, and their output is committed under
reports/ so the claims can be checked without owning the disc.
There is no porting, BYOA or modding intent. The goal is a written record of how this build is put together — and of what seven years of Tales did and did not change.
| Disc | one single-layer DVD, 1,579,104 sectors of 2,048 bytes, 3.23 GB |
| File system | ISO 9660 and UDF — a bridge disc — volume TOD2, publisher NAMCO LTD. |
| Files | 16, in two directories |
| Executable | SLPS_251.72, 1,275,360 bytes, loaded at 0x00100000 |
| Codec | the same in-house LZSS as 1995, 1997 and 2000 — decoded here by the shared reference decoder with no PlayStation 2 branch |
| Blocks | 9,469, 329 MB → 1,413 MB (4.29×), 9,469 exact, 0 short, 0 over |
| Archive | FILE.FPB, 1.52 GB, 9,206 members, no header — its directory is compiled into the executable |
| The index trick | member offsets are 64-byte aligned, so the low six bits carry the padding — one u32 gives extent and exact length |
| Bundles | 461 SCPK scenes, 8,603 members, of which only 1,525 are distinct — 47.2% is copies |
| Overlays | the linker left 77 empty marker sections naming every overlay, including a sound test and a model viewer |
| Textures | 7,424 TM2@ pictures, header arithmetic closing on all of them — and every one is a palette, never an image |
| Video | 1.54 GB of MPEG-2, 640×448, and three different versions of TMPGEnc |
| Slack | 278 of 1,579,104 sectors — 0.0176%, all of it UDF structures |
| Passengers | 173 MB of a completely different, unreleased game |
Four structural facts carry most of the weight.
The 1995 compressor crossed a console generation.
tales-blockcodec-doc
section 8 named Tales of Destiny 2 as the title that would settle whether
the format survived the PlayStation. It did, and it did not change: same
header, same method bytes, same nibble order, same 4,096-byte ring preloaded
with 3,840 synthetic bytes, same RING − 18 / RING − 17 cursors. 9,469 of
9,469 blocks decode to the length their headers declare, using the shared
decoder unmodified. The decoder itself could not be the same object code —
the EE is an R5900 — and measurement bears that out precisely: 0 identical
words against the 2000 build, but ~50% of the same opcode sequence, the same
constants, the same unroll factor of eight, the same argument register for the
ring. Same source, new compiler. See
04 and 10.
The archive directory packs two fields into one word. FILE.FPB has no
header. Its 9,206 members are described by 9,207 u32 at virtual address
0x001DC314 inside SLPS_251.72. Because members are laid out at 64-byte
alignment the low six bits of a start offset are always zero, so the format
spends them on the number of padding bytes after that member. One word,
extent and exact length. The array's last entry is 0x5A62D740 — the
archive's size to the byte, which is what pins it down. See
05.
The linker left a table of contents for a game that has none.
SLPS_251.72 carries 77 zero-length sections — .mnu_shop_end,
.battle_b013_end, .fld_event_sp07_end, .minigame1_end — and each one's
address is its overlay's load base plus that overlay's exact byte count. That
names 65 of the 70 anonymous members of MIPS code in the archive and pins
three load addresses. Two of the names are not shipping features: a sound
test (the largest menu overlay on the disc, 63,736 bytes) and a model
viewer (member #9004, 3,168 bytes). See 06.
A whole unreleased game rode along, with its contents deleted. 173 MB of this disc is a promo build of Venus & Braves (SLPS-25196, released July 2003): the complete game executable, pointed at a virtual CD image in which 2,923 of 2,939 files had been replaced by a one-byte space. The index survived intact, so the entire asset manifest of an unreleased game — 2,939 build paths across 613 directories, seven of them named after members of the team — is readable on a retail disc from eight months earlier. One file, 56 KB of animation data, escaped the stubbing. See 08.
Start at docs/01-overview.md.
| Document | Contents |
|---|---|
| 01 — Overview | The disc, the hashes, where the 3.2 GB goes |
| 02 — The disc | ISO 9660 and UDF, the layout as a seek plan, the slack |
| 03 — The executables | Two EE programs, 23 IOP modules, and one module shipped in two versions |
| 04 — The block codec | 9,469 blocks, and the decoder in two places on two CPUs |
| 05 — The archives and the index | The packed directory, SCPK, and the 47.2% that is copies |
| 06 — The overlay map | 77 empty sections, and the game they name |
| 07 — Graphics, audio and video | TM2@, the SCEI sound chunks, and three TMPGEnc builds |
| 08 — The other game on the disc | Venus & Braves, stubbed to one byte per file |
| 09 — Leftovers | Ten things that were not meant to ship |
| 10 — The Tales lineage | 1995 → 1997 → 2000 → 2002, measured |
| 99 — Open questions | What is still unknown, and how to attack it |
Dependency-free Python 3 under tools/. Nothing bundles game data.
See tools/README.md for the full list.
export ISO="Tales of Destiny 2 (Japan, Asia).iso"
# the disc
python tools/iso9660.py "$ISO" --pvd
python tools/iso9660.py "$ISO" --extract iso/
python tools/sector_map.py "$ISO"
# the executables
python tools/ps2elf.py iso/SLPS_251.72 --sections
python tools/dismips.py iso/SLPS_251.72 --va 0x0010A1B0 40 # the EE decoder
python tools/dismips.py iso/FILESYS.IRX 0x4904 40 # the IOP decoder
python tools/overlays.py iso/SLPS_251.72 --match iso/FILE.FPB --at 0x001DC314
# the archive
python tools/fpb.py iso/FILE.FPB --index iso/SLPS_251.72 --at 0x001DC314 --census
python tools/verify.py iso/FILE.FPB --index iso/SLPS_251.72 --at 0x001DC314
python tools/scpk.py iso/FILE.FPB --index iso/SLPS_251.72 --at 0x001DC314 --dupes
python tools/tm2.py iso/FILE.FPB --index iso/SLPS_251.72 --at 0x001DC314 --census
python tools/audio.py iso/FILE.FPB --index iso/SLPS_251.72 --at 0x001DC314
# the passengers, and the archaeology
python tools/vimage.py iso/VIMAGE/CDIMAGE.BIN --stubs
python tools/vimage.py iso/VIMAGE/CDIMAGE.BIN --extract out/
python tools/movies.py iso/MOVIE.FPB
python tools/leftovers.py iso/
# the lineage, against the PlayStation discs
python tools/decoder_lineage.py SLPS_011.00 0x80150BB0 SLPS_030.50 0x80023504 140
python tools/decoder_lineage.py SLPS_030.50 0x80023504 iso/SLPS_251.72 0x0010A1B0 140Claims in these documents are labelled:
- Verified — a reimplementation reproduces the format over the whole relevant corpus, and the disagreements are enumerated.
- Consistent — the model explains every sample checked, but has not been exhaustively proven.
- Open — observed but not explained. Everything of this kind is collected in 99 rather than softened in place.
| Subject | Status | Coverage |
|---|---|---|
| ISO 9660 volume and file table | Verified | all 16 entries parsed and re-read |
| UDF bridge structures | Verified | recognition sequence and descriptors identified by LBA |
| Free-space census | Verified | 278 sectors, every run identified |
| PS2 ELF headers, segments, sections | Verified | both EE executables and all IOP modules |
| Block codec, methods 0 / 1 / 3 | Verified | 9,469 / 9,469 blocks, zero disagreements |
| Codec identity with 1997 and 2000 | Verified | 140 words compared instruction by instruction, control reproduced |
The FILE.FPB index |
Verified | ends on the archive's exact size; 9,206 / 9,206 members 64-aligned |
| The padding-in-low-bits encoding | Verified | member lengths check against the block headers they contain |
SCPK container |
Verified | header plus member sizes account for all 461 bundles exactly |
| Duplicate census | Verified | every bundle member hashed; 47.2% |
TM2@ picture header |
Verified | 0x10 + w·h·4 == total on 7,424 / 7,424 |
The TM2@ kind byte |
Open | 19 distinct values, no correlation found |
SCEI audio chunks |
Verified | 18 / 18 members walked, 9 bank/sequence pairs |
| IOP module inventory | Verified | 23 modules, .iopmod parsed on each |
The two sio2man builds |
Verified | two differing bytes, both named |
| Overlay names and load bases | Verified | 65 of 70 code members matched, constant offset per family |
| The other five code members | Open | no load base fits |
VIMAGE format and the stubbing |
Verified | 2,938 / 2,938 contiguous extents; every placeholder read |
| Venus & Braves identification | Consistent | save folder, RTTI names and build paths agree |
Codec absent from VENUS.ELF |
Consistent | constants analysis; exhaustive decode-test not run |
MOVIE.FPB parameters |
Consistent | start-code survey, not a demux |
MCD / MFH / MDL@ / SFM_ / SMO_ schemas |
Open | outermost level only |
| The script and the font | Open | no Shift-JIS anywhere; indexed text suspected |
| Streamed music | Open | nine sequenced banks is too few; the rest not located |
This is one of a set. Findings that are not specific to a single title live in the shared repository rather than being copied into each pipeline:
- tales-blockcodec-doc — the block codec, specified once, for all four titles
- snes-talesofphantasia-doc — Super Famicom, 1995
- ps1-talesofdestiny-doc — PlayStation, 1997
- ps1-talesofeternia-doc — PlayStation, 2000
- pc-talesofberseria-doc — PC, 2017
Documentation: CC BY 4.0. Tools: MIT.
Tales of Destiny 2 and Venus & Braves are trademarks of BANDAI NAMCO Entertainment. This project is unaffiliated with and unendorsed by Bandai Namco, Namco Tales Studio, Wolf Team or Sony Interactive Entertainment.