Skip to content

Liberation Disassembly

Daniel Nylander edited this page Aug 13, 2026 · 5 revisions

Liberation: Captive 2 (CD32) Disassembly Reference

Documentation baseline: v1.1.126.

Complete reverse-engineered data from the Amiga CD32 binary.

  • Version string: $VER: Liberation : Ratt V2.02 : Wyvern V2.00c
  • Binary size: 245,628 bytes
  • Platform: Amiga CD32
  • Multi-disc: CaptiveII_Disk1 through CaptiveII_Disk4
  • Save directory: Lib-Saves

PRNG Algorithm

All procedural systems (city generation, NPCs, shops, combat) share the same 16-bit PRNG, identical to Captive's MapGen PRNG:

uint16_t prng(uint16_t state) {
    state = state * 0x5E5 + 0x29;
    return state;
}

City Generation

Two-layer procedural system: high-level building placement and low-level 64×64 grid.

High-Level City Structure

  • 9 building types: Shop, Bar, Business, Industrial, Residence, Library, Police, Records, Special
  • Type assignment: PRNG % 9
  • Maximum 100 buildings, 36-byte records each
  • Connection markers: CONN_FORWARD = 0xAAAA, CONN_BACKWARD = 0xBBBB
  • Parameters derived from seed + level: density, columns, roads, cross-roads, buildings per segment

Low-Level Grid

  • 64×64 cells across 3 planes
  • Cell constants: EMPTY = 0x0D, WALL = 0x00
  • 256 max buildings, 51-entry connection table
  • Dual seed system: seed_combined = (seed_hi << 4) + seed_lo
  • 8×8 meta-grid overlay

City Name Generation

32 German-themed syllables from the CD32 binary at offset 0x033BEB:

gold  grun  braun  wein  eisen  ein  bieder  jaeger
tell  fern  hahn   stein mann   berg er      mensch
tod   fisch rhein  kurz  laben  weg  wehr    kropf
esel  erz   fach   fuchs schild ort  paar    platz

Additional English syllable tables for compound names:

kan  se   sas  bin  tel  fog  ram  top  chi  ban  mac  tin
tac  mo   more fu   ore  gon  ria  tor  roto para set  fan  pet

Suffixes: bridge, ton, ford, field, town, wick, ham

Pattern: {syllable}{syllable}{suffix} City

Street Name Types (20)

Street    Avenue     Road       Boulevard  Lane
Park      Gardens    Gate       Crescent   Mews
Terrace   Drive      Alley      Approach   Arcade
Buildings Corner     Quadrant   Passage    Promenade

NPC Generation

First Names (35)

Max  Joe  Jack  Jim  Ed  Ann  June  Fred  Kiku  Art  John
Barbara  Steve  Rick  Mark  Barry  Deb  Malc  Tone  Pete
Alison  Maggi  Claire  Kim  Cass  Lynne  Mel  Gill  Cath
Ivor  Huw  Gwynn  Geraint  Narish  Rajiv

Last Names (32)

featherstonehaugh  patel   smythe    singh     meridew
sagan              murray  cherryh   chambers  gaiman
cleese             simon   burkinshaw forward  rector
alexy              jacobs  crowther  macleod   leary
crowley            gibson  floyd     whittle   pitt
heath              goodley chapman   palin     gilliam
hake               turbot

Additional surname elements:

Prefixes: brew, dev, scann, cann, dann, has, ves, mann, van, han, hawk, evan, john, richard, smith, iron, young, ham, pether

Suffixes: -Hammond, -Evans, -Smythe, stone, wick, er, ers, ing, ton, ston, ster, son, s, ly, let, lin

NPC Titles (8)

Governor            Councillor
Investment Counsellor  Engineer
Entrepreneur        Pilot
Trader              Merchant

NPC States (7)

Normal, Dead, Absent, Attack, Follow, Dead_Attack, Dead_Follow

NPC state used as case_value in dialogue text expansion.

Building Types

Shop Types (9)

Emporium      Hardware      Pawnshop
Gunsmith      Jewellers     Store
Market        Newsagent     TriDee Rental

Bar Types (12)

Bar           Boozerama     Diner
PopShop       Pub           Vinyard
Beer Hall     Pool Rooms    Speakeasy
Gin Palace    cha no mise   biru no mise

Business Types (11)

Software         Insurance         Assurance
Bank             Accountants       Actuarial Services
Credit Control   Mercantile        Import/Export
Productions      Expediters

Industrial Types (12)

Engineering        Ceramics          Steel
Aluminium Corp.    Laser Systems     TeleCommunications
Plastics           Mouldings         Metals a.g.
Optik g.m.b.h      ParaGravitics     Noble Gasses

Company Name Prefixes

Info  Star  Mind  Para  Grav  Drive  Scan
Ion   Electro  Terra  Selen  Mar  Bio  Gene

Company Name Suffixes

Tec  Light  Scape  nics  tics  sum
Technology  Logix  Land  Lon  Tron  Games

Pub Name Elements

*Dog  Bush  *Parrot  Firkin  *Bull  Star
Frog  *Queen  *Aardvark  Peristalsis
&Black  &Green  King  Elephant  C...

(* = "The {Name}", & = "The {Color} {Animal}")

Shop and Bar Mechanics

Shop Inventory

  • Item count: 4 + (PRNG & 7) (range: 4-11 items)
  • Prices: 50-499
  • Sell price: buy_price / 2

16 Shop Item Types

Laser Pistol     Plasma Rifle      Ion Cannon
Shield Generator Power Cell        Neural Interface
Servo Motor      Armour Plate      Sensor Array
Navigation Chip  Communicator      Medikit
Charge Pack      Targeting System  Gravity Boots
Data Crystal

Bar Menu

  • Item count: 3 + (PRNG & 3) (range: 3-6)
  • Prices: 5-24

8 Bar Drinks

Synthi-Ale    Neuro-Fizz    Grav-Tonic    Plasma Punch
Ion Brew      Dark Matter   Quasar Shot   Nebula Wine

Combat System

Enemy Generation

  • Max 8 enemies per encounter
  • Count: 1 + PRNG%3 (+1 if difficulty > 3)
  • HP: 20 + difficulty*10 + PRNG%20
  • Damage: 5 + difficulty*3 + PRNG%8
  • Defense: 2 + difficulty*2
  • Speed: 3 + PRNG%4

8 Enemy Types

Guard  Soldier  Enforcer  Drone
Sentinel  Trooper  Agent  Warden

Combat Formulas

  • Droid attack cost: 3 energy
  • Weapon damage: lo_byte * hi_byte of weapon_damage word (from CAPPO.EXE at 0x9BF4)
  • Effective damage: base - target.defense/2 (minimum 1)
  • XP per kill: 50

File Formats

X3G — 3D Vector Format (FORM O3DG)

IFF container structure:

FORM O3DG
  OFFS    — offset index to VCDO objects
  FORM VCDO (per object)
    EXVL  — extended vertex list
    PLST  — polygon list

Vertices: 16 bytes each

int16 x, y, z, group    (8 bytes)
4 reserved words         (8 bytes)

Polygons: variable-size records (minimum 38 bytes)

type, normal_x (int16), normal_y (int16), color,
UV rect (left, top, right, bottom), flags,
vertex_index_list

Vertex indices encoded as byte_offset / 16.

Limits: max 64 objects, 256 vertices, 256 polygons, 8 vertices per polygon.

Data Files Using X3G

File Content Variants
{N}CityVectors.x3g City 3D geometry 4 (N=0-3)
{N}RoomVectors.x3g Room/interior geometry 4
{N}BankVectors.x3g Bank interior 4
{N}BarVectors.x3g Bar interior 4
{N}ShopVectors.x3g Shop interior 4
PoliceVectors.x3g Police/guard models 1
{N}Droids.x3g Droid 3D models 4
{N}CityMonsters.x3g City monsters 4
Monsters{2,3,4}.x3g Additional monster sets 3
People.x3g NPC models 1
Objects.x3g Item/object models 1

VGM — Wall Texture Banks

Container of concatenated AmSp (AMOS Sprite) banks:

  • Up to 4 banks, 256 total sprites
  • Per-sprite header: 10 bytes (width_words, height, depth, flags)
  • Flag bit 15 = mask plane present
  • Bytes-per-row: (w_raw & 0x7FFF) * 2 - (w_raw >> 15)
  • 71 verified wall texture hashes (SHA-256)

IMG — Sprite Format

Container magic: ImgA + BE16 sprite count + BE32 offset table.

  • Amiga planar format: up to 7 bitplanes
  • Mask plane is always the last bitplane
  • Multi-frame sprites: first word = frame count, followed by per-frame offsets
  • Single-frame header: 22 bytes; multi-frame sub-header: 20 bytes
File Content
MainSP.Img Main sprite sheet
MainSP16.Img 16-color sprite sheet
3dView.Img 3D viewport frame/border
Taxi.Img Taxi graphics
backpack.img Inventory/backpack UI
GameMenu.spr Game menu sprites

FNT — Font Format

Magic: CHAR + BE16 glyph_count + BE16 max_width + BE16 num_planes (must be 2).

  • Glyphs: 7 pixels tall, max 8 wide
  • 2 bitplanes, 16 bytes per glyph: 1 width byte + 7 plane0 + 7 plane1 + 1 pad
  • ASCII range starting at character 32
  • 4 font variants: {N}Liberation.FNT (N=0-3)

FORM ANIM — Presentation/Cutscene Format

IFF FORM ANIM with three chunk types:

PALL — Palette:

  • 32 × BE16 Amiga 12-bit RGB colors (4 bits per channel)
  • Expansion: component * 17 (0x0→0, 0xF→255)

PACK — Compressed bitmap data:

  • First longword = work buffer size
  • Segments: BE32 length + 14-byte descriptor + RLE payload
  • Descriptor: BE16 width_bytes, BE16 height, byte depth, BE32 raw_size
  • RLE: bit 7 set = fill run (count = control - 0x7E + 1, minimum 3); bit 7 clear = literal copy (count = control + 1)

SCPT — Script bytecode:

  • Records linked via next = current + be16(current), terminated by zero word
  • Opcodes not yet fully decoded

RNC Compression

Supports RNC1 (forward and backward) and RNC2 (Amiga layout). Used to decompress presentation bundles from CD32 ISO.

ArcD Compression

Magic: 0x41726344 ("ArcD"). Used for DTE (dialogue text encoding) compressed text tables.

3D Viewport Renderer

Rendering Parameters

Parameter Value
Native resolution 256×160
Near clip 4 units
FOV scale 200.0
Camera Yaw-only (no pitch/roll)

Projection

screen_x = (view_x * fov_scale / view_z) + width/2;
screen_y = (view_y * fov_scale / view_z) + height/2;

Lighting

Directional shading:

shade = 0.4 + 0.6 * |nx*0.5 + ny*0.866|

Polygon normals are fixed-point int16, divided by 32768.0.

Rendering Pipeline

  1. Perspective-correct texture mapping using 1/z interpolation
  2. Painter's algorithm (back-to-front sort by average Z)
  3. True 3D polygon renderer (not raycasting like Captive 1)

City Navigation Constants

Constant Value
Cell size 256.0 units
Wall height 128.0 units
Eye height 64.0 units
Movement 4-direction grid (N/E/S/W)

Text Expansion System

Section-addressed dialogue text using control codes.

Format

Text sections: |<id>[<content>]

Control Codes

Code Function
^; Comment to end of line
^^ Newline
^O<n>[opt1|opt2|...] PRNG-selected random option
^N<lo>-<hi> Random number in range
^XCA[case0|case1|...] Case selection (NPC state dispatch)
^XO Extended random option
^S Skip line
^J Insert "trader"
^P Insert person name
^W, ^Z, ^A Placeholder markers
^F, ^I, ^L, ^E, ^G Skip-to-delimiter commands

Limits: 64 sections, 32 variables, 4096-byte output buffer.

Building type ID maps directly to text table section ID. NPC state used as case_value in ^XCA expansion.

Plot Generation

  • 9 building types (mirrors citygen)
  • 128 max buildings, 36-byte records
  • Up to 4 rooms per building with forward/backward room links
  • Generates: city name, victim name, victim title, news source, victim gender
  • Same PRNG and density/column/road formulas as city generation

Save Format

Magic: "LSAV", version 1.

Per-Droid Fields

  • 16-character name
  • HP, energy, level
  • 8 skills
  • 8 equipment slots

Global Fields

  • Dual seed (hi/lo)
  • Difficulty, mission number
  • Gold, tick count
  • City position (x, y), facing direction
  • Generators destroyed / total
  • 256 missions tracked as 32-byte bitfield

Audio

CD Audio (Red Book)

10 music tracks (tracks 2-11) by Mark Knight on the CD32 disc.

Music Track Identification

8 MIDI music tracks identified by SHA-256:

  • Title, Base exploration, Battle, Shop, Holomap, Escape, Final, Trapped

Sound Effects

IFF 8SVX sample format. Effects currently unimplemented pending format verification.

Resource Identification

All game resources identified exclusively by SHA-256 content hash, never by filename.

CD32 Track Hashes

Resource SHA-256 Prefix
CD32 ISO track f807b138...
Presentation bundle 1d3a335d...

Game Data Hashes

7 verified hashes for: game binary, city generator, plot generator, plot text, city text, dialogue text, mission menu.

Amiga ADF parallel hash table maintained separately — CityGen and PlotGen are byte-identical across CD32 and ADF platforms.

Intro and city ANIM content hashes verified after RNC2 decompression.

Disc Structure

CaptiveII_Disk1/
CaptiveII_Disk2/
CaptiveII_Disk3/
CaptiveII_Disk4/
Lib-Saves/          — save directory

4 city variants (0-3) with matching:

  • Vectors: {0-3}CityVectors.x3g, {0-3}RoomVectors.x3g, etc.
  • Monsters: {0-3}CityMonsters.x3g, {0-3}Droids.x3g
  • Fonts: {0-3}Liberation.FNT

Version Strings

$VER: Liberation : Ratt V2.02 : Wyvern V2.00c
NuRAM:Game.DAT
CaptiveII

Game Messages

" ++ Damaged ++ "
"Buildings - "
"$EndText"

Clone this wiki locally