Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cd32-liberation-doc

Reverse-engineering notes on Liberation: Captive II (Byte Engineers / Mindscape, 1994) for the Amiga CD32 — a first-person polygon RPG whose 3D engine ships as three separate shared libraries, whose city is built at run time by three separate programs, and whose 169 MB data track is 91 % digitised speech.

This repository documents the Mindscape release: one MODE1/2048 track of 82,502 sectors and ten Red Book audio tracks, 187 files, one codec, and the largest data track on any CD32 disc in this series by a factor of 1.4.

Documentation only. No game assets, no extracted art, no audio, no executable code is committed here. The tools in tools/ reproduce every figure, table and image in these pages from your own legally obtained copy.

What is documented

Doc Contents
00-overview.md The release, the two version numbers, and the nine days in which the game changed its name
01-disc-image.md The cue sheet, ten audio tracks, the sector map, and 71 % of a CD
02-trademark-block.md The .TM block, and the fifth disc to carry the same 2,048 bytes
03-filesystem.md ISO 9660 field by field, and an executable that disproves its own datestamp
04-boot-chain.md A boot script that mounts a reset-surviving RAM disk, and two programs for one library
05-compression.md The census, and an RNC\2 container that is not RNC ProPack
06-executables.md Nine libraries, 181 calls, a backup-copy fallback, and Akiko measured to zero
07-3d-engine.md Three Wyvern libraries, a 512-entry sine table, a perspective divide that retries on overflow
08-graphics.md ImgA, AmSp, CHAR, and 10,792 pre-rendered wall sprites
09-text-system.md The text bytecode, the generators, and a note to translators that shipped
10-audio.md 34 minutes of Red Book, 195 minutes of speech, and 63 lines nobody recorded
11-leftovers.md The archaeology
12-open-questions.md Thirteen things unresolved, with the measurement beside each
notes/file-inventory.md All 197 directory records with LBA, size, timestamp, magic and SHA-1
notes/speech-index.md Every .LOG table, every rate, and the 63 unrecorded line numbers
notes/sprite-banks.md Every AmSp bank, every ImgA container, every .x3g object
notes/text-records.md Record statistics for the six compiled text files, and the speech cross-check
notes/string-inventory.md Every legible string in every executable, by file and offset
cd32-platformnotes-doc Platform checklist — what to look for on any CD32 or CDTV disc. Shared by every Amiga CD pipeline; this repo does not keep a copy

Highlights

The two version numbers in the dump's filename are two people. The first string in the game executable is $VER: Liberation : Ratt V2.02 : Wyvern V2.00c :, followed by (c) 1993 ( The Byte Engineers. The rights of Antony Crowther and Ross Goodley to be identified as the authors of this program are hereby asserted. : Friday 08-Apr-94 09:35:08 ). Ratt is Crowther's handle; Wyvern signs all three of the 3D libraries in libs/ (MATH 1.2, TRIDEE 1.3, VECTOR 1.5, all (C) Wyvern 1992). Two authors, two version numbers, and a third set on the engine.

The executable disproves its own datestamp. Twelve of the 197 directory records read 1992-02-05, two years before the master — the platform notes' classic "check before you call this a dead clock". Here it can be checked without leaving the disc: /captiveII is one of the twelve, and the binary itself says it was linked Friday 08-Apr-94 09:35:08. Same 245,628 bytes, no earlier release to inherit from. It is a wrong clock, on the machine that assembled the last twelve files, and the file's own version string is what proves it.

Akiko is not used, and this was the best candidate left. Zero lea $B80000,aN, zero movea.l #$B80000,aN, zero references to the C2P port at $B80038, zero $C0DE0000, across every code and data hunk on the disc. The seven byte-pattern hits are all identifiable coincidences. The reasons are in the same binary: nonvolatile.library and lowlevel.library — the only two CD32-specific modules — are both opened behind one runtime flag at $3299(a5), and neither open is fatal if it fails; the root holds a Workbench icon; and four floppy volume names of the A1200 release are compiled in. The same executable had to run on an A1200.

The 3D engine is a blitter program, and its surfaces are pre-rendered. vector.library's 47 absolute custom-chip references are 45 Blitter registers and nothing else — no bitplane pointer, no colour register, no copper. tridee.library touches no hardware at all. And the 71 WallNN.VGM files, 11.9 MB, are not textures: each is four AmSp banks of 42, 45, 24 and 41 sprites — 10,792 pre-computed perspective projections of wall faces, every one four planes plus a one-bit mask, blitted by view. There is no texture mapper, no span filler and no chunky buffer, which is the other reason Akiko had nothing to do.

A 512-entry sine table and a divide that retries on overflow. math.library's table is the last 1,024 bytes of the file, amplitude 16,384, one turn, cosine taken as sine + 128 entries; 498 of the 512 entries are exactly round(16384·sin(2πn/512)) and 14 are one bit out. The perspective divide catches divs.w's overflow flag and halves the numerator's scale and retries the same divide, giving up a bit of precision rather than clipping — four instructions where a near-plane clip would have been.

The game runs three other programs to write itself. /CityGen 1.12, /PlotGen and /BuildingGen 1.3 are separate AmigaDOS executables that captiveII launches by name to lay out the city, lay out a building, and generate the plot, the news reports, the police dossier and every conversation in the game. BuildingGen makes no library calls at all in 23 KB of code. PlotGen opens each of its three inputs twice — CaptiveII:PGE.TXT and then CaptiveII_Disk3:PGE.TXT, the third floppy of the A1200 release, fallback and all.

The disc ships a manual for its own scripting language, addressed to translators. PGE.txt opens with 384 words explaining the text-generation controls one at a time — ^On[a|b|c] for a random alternative, ^Nx-y for a random number, ^P for a personal name, ^J for a profession — signed Ross Goodley and ending "if you cannot make anything of it you phone me direct on (0742) …". 0742 was Sheffield until PhONEday retired it in April 1995. No translation shipped, but three things on the disc were built for one: that note, twenty-three accented Latin capitals in both fonts that nothing prints, and generator vocabulary in German, French and romanised Japanese (Beobachter, Fernsehnachrichten, actualites, cha no mise, Terebi no Shimbun).

Both authors are in the random-surname table. crowther and goodley sit in the list of names the game gives to procedurally generated citizens, between cherryh, gaiman, gibson, leary and crowley on one side and cleese, chapman, palin and gilliam on the other. The first-name list has Tone in it.

Three hours and fifteen minutes of speech, recorded twice, with 63 gaps. 1,248 lines in two voices — Voice 1 mostly 7–12 kHz, Voice 2 mostly 15–16 kHz, different performances of different lengths, with the rate chosen per clip (fifteen distinct rates across shop1/Voice1) — stored as bare runs of IFF 8SVX with a .LOG of file offsets beside them. An entry of 0xFFFFFFFF means the line was never recorded, and there are 63 of them, 58 in Voice 1 and 5 in Voice 2. The dialogue bytecode's 0xB1 speech markers index the same table, and the counts agree exactly: 566 distinct markers in char1.txt against 566 lines in Char1/Voice1.LOG.

A boot script that mounts a reset-surviving RAM disk. Twenty-two non-blank lines, and the middle of it mounts ramdrive.device as RRD: from a Devs/Mountlist on the disc, makes it bootable with a one-line startup sequence (rrd:WARNING), copies c/WARNING onto it, and relabels it Ram_Reset. A recoverable RAM disk outranks the CD at boot, so a reset boots the warning instead of the game. No other disc in this series does anything like it.

The loader carries second copies of its own executables. c/Liberation names CaptiveII:CaptiveII and CaptiveII:BackUp/CaptiveII in consecutive strings, and captiveII names :CityGen :PlotGen :BuildingGen followed by :backup/CityGen :backup/PlotGen :backup/BuildingGen. All four backup copies are byte-identical, and the timestamps show each was made four to six seconds after its original was built. 292 KB of insurance against a 1994 double-speed drive missing a sector.

And a demo build's refusal, still in the retail binary. At hunk 0x546A: [Sorry, this is only a 1 disk demo.] — bracketed, so it is a dialogue record in the text system, not a printf.

Reproducing

Every number above comes out of tools/ run against the eleven files of a standard rip. Python 3, pillow for the renderers, capstone for the disassembly helpers.

cd tools
python pvd.py        "../<Track 01>.iso"          # volume descriptors
python isofs.py      "../<Track 01>.iso"          # the directory
python timestamps.py "../<Track 01>.iso"          # the build log
python sectormap.py  "../<Track 01>.iso"          # what no file claims
python tmblock.py    "../<Track 01>.iso"          # the trademark block
python tracks.py     ..                           # the audio tracks
python extract.py    "../<Track 01>.iso" ../_work/iso
python census.py     ../_work/iso                 # before any magic scan
python scan.py --magic ../_work/iso/captiveII
python scan.py --akiko ../_work/iso/captiveII
python scan.py --regs  ../_work/iso/libs/vector.library
python hunk.py       ../_work/iso/captiveII
python libcalls.py   ../_work/iso/captiveII dos=0x150 exec=0x154 \
                     intuition=0x158 graphics=0x15C vector=0x160 \
                     tridee=0x164 nonvolatile=0x168 lowlevel=0x3350 math=0x34A0
python libinfo.py    ../_work/iso/libs/math.library --sine 0x9E4
python img.py        ../_work/iso/backpack.img
python amsp.py       ../_work/iso/Wall01.VGM
python fnt.py        ../_work/iso/0Liberation.FNT 0 40
python x3g.py        ../_work/iso/0CityVectors.x3g
python sty.py        ../_work/iso/intro.sty
python speech.py     ../_work/iso/Char1 ../_work/iso/shop1
python samples.py    ../_work/iso/Samples.BIN
python text.py       ../_work/iso/Char1/char1.txt
python orphans.py    ../_work/iso --named
python orphans.py    ../_work/iso --unnamed

tools/rnc2.py is the one tool here that does not work: it is a faithful transcription of the disc's own decruncher that desynchronises after two tokens, and 12-open-questions.md says exactly where and what was ruled out.

The other discs

cd32-platformnotes-doc the shared checklist
cd32-dragonstone-doc Dragonstone, Core Design, 1995
cd32-marvinsmarvellousadventure-doc Marvin's Marvellous Adventure, 21st Century, 1995
cd32-prey-doc Prey: An Alien Encounter, Almathera, 1993 — and its 1992 CDTV master
cd32-thesperislegacy-doc The Speris Legacy, Team 17, 1996
cd32-legends-doc Legends, Krisalis / Guildhall, 1996

About

Liberation: Captive II (Byte Engineers/Mindscape, 1994, Amiga CD32) — the largest CD32 data track in the series, 91 % of it speech: three Wyvern shared libraries that are the 3D engine, 10,792 pre-rendered wall sprites instead of a texture mapper, three generators run at boot, and a text system that shipped with its author's note to translators

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages