Resource extraction and binary formats
Open the offline resource browser to inspect the results. It works directly from the filesystem: no server, downloads or build are needed. The source installations are never modified by the extraction tools.
Current extraction
Ten retained game filesystems are scanned, including the original installation and played 2.00 floppy, with identical source files sharing one decoded asset. The browser records every contributing source path and SHA-256. Embedded models are extracted from all seven distinct flight binaries. The two reference editions have traced runtime animation; byte-identical installations reuse those profiles.
| Resource | Decoded result |
|---|---|
| Artwork | 40 distinct VGA images decoded to indexed PNG; 14 original distribution JPEGs displayed in place |
| Cockpit and help screens | Two cockpit-mask variants and 25 distinct help images; each reference install has one cockpit and ten help pages |
| Worlds | 25 distributed definitions, 22 saved campaigns, three native-generated training examples and the source-only slalom layout |
| Embedded models | All seven flight binaries; 61 templates each, plus sun geometry, early sun-face variants and radar wrecks; animated effects in the reference editions |
| Palettes | Six distinct 256-colour palettes across editions |
| Medals | Sixteen custom 8×16 glyphs |
| Music | Six ROL sequences, three banks, one decoded driver; seven full sequence/bank FLAC renders |
| Effects | Three ADL files, 35 patch auditions and two examples executing native sound routines |
| Presentations | 55 distinct image/layout combinations; 17 panels in the normal reference, plus original animated title playback |
| Runtime state | Three recorded demos; four distinct pilot files; four distinct high-score files with three top-ten tables each |
| Programs | DOS executable headers and printable strings for 33 distinct executable contents |
| Text | 93 distinct manuals, help files, briefings, scripts and distribution documents |
| Promotional screens | Three executable text-mode screens, rendered with searchable transcriptions |
| Sky and instruments | Generated native star positions and plots, plus existing original cockpit/HUD and SRATS captures |
| Configuration | Four distinct configuration/PIF files, with original bytes, words and strings retained |
These are counts of distinct resources, not counts of missions, songs per edition or independently flyable craft. Source JPEGs and converted VGA images remain separate representations; they are not claimed to be byte-identical.
Reproducing the extraction
With Pillow, Unicorn and DOSBox installed (DOSBox supplies the external BIOS text font for presentation composites):
python3 tools/extract_resources.py
The source tools are extract_resources.py, corncob_models.py, corncob_colours.py, corncob_music.py, resource_viewer.html and model_viewer.js.
Additional verification uses Pillow and Unicorn:
python3 tools/validate_resources.py
The verification report records byte-for-byte
agreement with the original RIMG.EXE decompression loop for all 27 masks, and
agreement with the original 3.EXE record-expansion routine for all 898 objects
in the four normal-game reference theatres and two saved campaigns. Fourteen illustrated VGA images also
match the dimensions and closely match the colours of their original JPEGs.
The latter is an image comparison, not an assertion that different JPEG decoder
and quantiser implementations produce identical pixels.
disassemble_engine.py uses Capstone to regenerate selected, identified original routines. Its addresses are executable file offsets, and the fixed ranges refer to retail 3.42 only.
VGA images
The first four bytes are two little-endian words: maximum X and maximum Y. Dimensions are those values plus one. A file contains:
- Four-byte dimensions.
width × heightconsecutive, row-major palette indices.- Padding bringing the pixel allocation up to
align_up(width, 8) × height. - Two extra bytes.
- Optionally, a 768-byte palette.
The padding is all at the end, not at the end of each row. Treating the allocation stride as the row stride produces conspicuous diagonal shearing. The JPEG converter's output routines establish the ordering directly; the two extra bytes are zero in its output but need not be zero in hand-authored images.
Embedded and separate palettes contain 256 RGB triples with six-bit components.
PNG export preserves the original indices and expands each component with
(value << 2) | (value >> 4).
Images without an embedded palette inherit palette state during title playback.
Their static previews use HC6.PAL and explicitly identify that choice; it is not
a claim that every frame of the title uses that palette unchanged. Original
colour cycling, fades and sprite transparency still need their playback traced.
Evidence: JVCC.EXE file ranges 0x491–0x59b, 0x59b–0x63a and
0x6f5–0x7e2 in the selected disassembly.
IMG cockpit and help graphics
These are compressed one-bit graphics, not disk images. RIMG.EXE skips the
first four bytes and alternates:
- A little-endian repeat count, masked with
0x3fff, followed by one repeated byte. - A little-endian literal count, masked with
0x3fff, followed by those bytes.
The expanded screen is 640×350, eight pixels per byte, most-significant bit first. Runs are clipped to the destination capacity. The final repeat can fill the remaining screen without another literal payload; blindly reading complete repeat/literal pairs until end-of-file is incorrect.
The browser shows raw monochrome masks. The helper normally applies them to two EGA video pages and depends on existing video state. A nonzero view argument changes its draw capacity from 28,000 to 15,920 bytes, i.e. 199 scanlines. The numbered files are help screens, rather than different craft/view masks. Checked transcriptions preserve all 25 distinct help images, including earlier wording and the 1.20 welcome page. The browser labels their subjects and searches their text. The diagonal line in both cockpit variants is part of the original data; its purpose is unresolved.
Evidence: RIMG.EXE file range 0x292–0x2de, independently executed in Unicorn;
also the native DOSBox helper capture.
World files: CCT and DEF
All decoded editions use 64 tiles in row-major order, eight columns by eight rows. Each tile starts with a 16-byte header:
| Offset | Size | Meaning |
|---|---|---|
+0 |
4 | Pie followed by NUL |
+4 |
2 | Tile X, 0–7 |
+6 |
2 | Tile Y, 0–7 |
+8 |
2 | Object count |
+10 |
1 | Tile storage/state flags |
+11 |
5 | Packed six-bit sky/ground RGB values |
The header is followed by count 23-byte object records:
| Offset | Size | Meaning |
|---|---|---|
+0 |
2 | Packed high coordinate bits: X in bits 0–4, Y in 5–9, Z in 10–14 |
+2 |
2 | X low word |
+4 |
2 | Y low word |
+6 |
2 | Z low word |
+8 |
3 | Heading, pitch, roll high bytes, in that order; expanded to 16-bit angles with low byte zero |
+11 |
2 | Object flags |
+13 |
8 | Four object-specific words; raw values retained pending per-type interpretation |
+21 |
2 | Object type, encoded in CCT and plain in DEF |
For CCT, the type is stored_type XOR x_low XOR y_low. This is a small
obfuscation, not compression. DEF files in the expansion retain the plain type.
The decoder checks every type against the 61-entry definition table.
Coordinates are centimetres. With tile_size = 32 × 65536 and
origin = -128 × 65536, the position is:
X = origin + tile_X × tile_size + packed_X × 65536 + X_low
Y = origin + tile_Y × tile_size + packed_Y × 65536 + Y_low
Z = packed_Z × 65536 + Z_low
Each tile covers approximately 20.97 km; the complete coordinate grid spans approximately 167.77 km on each horizontal axis. This is the storage grid, not an assertion that scenery fills every tile or that the player has unrestricted travel across all of it.
After all 64 tiles are twelve bytes: the player start position as three signed 32-bit centimetre coordinates. This is confirmed by READUNIV in the preserved original source, which copies them directly into the player position.
READCOLORS interprets header bytes 11–15 as a big-endian 40-bit value. Its six-bit
channels are sky R/G/B at shifts 32/26/20 and ground R/G/B at shifts 14/8/2; the
lowest two bits are unused. For example White Sands stores sky (15, 8, 61) and
ground (59, 62, 52). These replace EGA palette slots 11 and 2. The native C++
reconstruction and the 3D research world viewer use these values.
Evidence: 3.EXE loader 0x1b84–0x1c1c, compact-record expansion
0x7f85–0x8056, and inverse packing 0x8056–0x80f8. The expansion table lookup
is found by its instruction sequence and checked against template self-IDs.
The angles_u8 and angles_u16 arrays retain the original heading, pitch, roll
order. MAT.ASM documents the same order for GETANG; NCALCMAT transforms
model coordinates with Rz(heading) × Ry(pitch) × Rx(roll). Atkinsville’s
second parked aircraft stores [224, 250, 0]: a −45° heading and −8.4375°
pitch, not a 45° pitch. Early extraction variable names reversed heading and
pitch, although the exported arrays always retained the correct byte order.
The resource browser opens worlds in 3D, including all edition variants and saved campaigns. It shares the showcase's scenery renderer, recovered world colours and per-instance colour cycling. Object selection exposes the complete record and links to that edition's model; mission starts, landmarks, type filters and airfield/world framing are available. The 2D atlas remains an alternative and a fallback when WebGL is unavailable. It shows +X to the right and +Y upward without assuming those axes mean East/North. Both views support shareable world/object links. See viewer maintenance for the feature list, source provenance and browser checks.
Briefing and environment files
Mission headings occur as both Mission Code Name: and Mission:. Each stored
Sxyth start is paired with its own title, direction, distance, difficulty and
briefing text. A fresh Direction: without a mission heading begins an untitled
briefing; Ice World's second Dulles start must not inherit Hornet's Nest from
the preceding mission. Missions without Sxyth still appear in the complete raw
text, but have no stored starting position to offer in the viewer.
Selecting a start shows a reading copy with hard-wrapped lines joined and divider
lines removed. Original wording is retained, and the full verbatim section remains
under Briefings and environment. A start URL parameter links directly to the
chosen briefing. In 3D, the stored heading helps frame nearby objective scenery
from the approach direction. The orbit centre stays on the ground beneath it;
the camera pulls back to include elevated structures. This is an inspection
heuristic, not a stored mission-to-object link. The 2D objectives & starts
switch controls atlas markers and
is disabled in the 3D scenery view.
TWR files are CP437 text with form-feed-separated sections. Each Sxyth line
provides a mission start: X, Y, Z and yaw. A section can contain several missions;
one form-feed block is not necessarily one mission.
The optional leading X line describes sun angle, sun size, sun colour, gravity,
air density, star visibility and atmosphere height. These meanings come directly
from the expansion's mission-builder manual.
Its documented ranges should not be assumed to match every engine's actual clamps.
The same manual reproduces original assembly symbol names and object tables. Those supply the browser's names, including generator orbs, KLA sites, vehicles, forcefields, portals and the rescue van. Record parameters can have different meanings for different types; the JSON deliberately preserves them as raw words.
Embedded model data
Models are stored inside the flight executable, not in the cockpit IMG files.
Both reference engines have a 61-entry template-pointer table. Each template is
74 bytes and ends with its own type ID, which the extractor validates.
Three data pointers at template offsets +40, +42 and +44 select model detail
variants. They are not executable callbacks.
A model starts with three position/cache words, then a command count. Eight command lists follow, one per viewing octant. Every command is two words: primitive opcode and data-segment address. The original renderer selects the list by signs of the camera-relative position in model coordinates.
| Opcode | Payload |
|---|---|
| 0 | No drawing |
| 2 | Counted list of polyline pointers; each polyline has segment count, colour and count + 1 connected XYZ vertices |
| 4 | Counted XYZ points with individual colour words |
| 6 | Counted XYZ centres, diameters and colour words; projected as circular discs |
| 8 | Polygon vertex count, colour word and XYZ vertices |
The size word in opcode 6 is a diameter, not a radius. The original projection
routine scales it by focal length / depth, then the rasterizer halves that result
to position the left and right edges (3.EXE file offsets 0x6be4–0x6bfc).
For example, the ground crew's head has diameter 40, and the ground vehicle's
wheels have diameter 428 with centres at Z=214, placing their bottoms at ground
level. The extractor records diameter; browser framing uses half that value
and both the main view and thumbnails use the full width for point size.
The verification report includes execution of the
original projection and rasterizer setup for head and wheel sizes.
The experimental stealth aircraft at White Sands is not a separate object
number. The parked instance is type 2 (Aircraft), with flags 0x20f9: flag
0x2000 makes the game replace its near and middle model pointers at runtime.
The original extractor followed only template pointers and therefore missed it.
It is now extracted as a separate browser entry, Experimental stealth aircraft
(White Sands), while retaining type 2 and recording the selection condition.
Its model contains five polygons, at data-segment address 0x6838 in retail
3.42 (0x6a6a in Other Worlds). The far-detail pointer is left unchanged by the
original code, so selecting Far shows the ordinary aircraft's distant silhouette.
Retail selection blocks are at file offsets 0x8fc1–0x8fd1 (internal/player
object) and 0x97ac–0x97bc (parked aircraft). Both blocks in both reference
engines are checked by executing the original instructions with the flag clear
and set. The White Sands briefing explicitly describes the parked craft as an
experimental aircraft for a high-altitude test.
Model states and the ground crew's gesture
The browser's Pose / state selector now exposes the following original arrangements. Thumbnails follow the selected state too, and the framing stays fixed across a model's states so changes of pose do not look like zooming.
| Object | States exposed |
|---|---|
| Runway piece | Standard and alternate quality-flag geometry |
| Ground crew (7) | Standing; raised middle finger; shot and lying flat |
| Radar (3) and wreck type 33 | Active/inactive dish; distinct burning radar wreck |
| Aircraft (2 and internal 28) | Intact; damaged/bent geometry with the fire-particle primitive |
| Explosion (19) | White flash; yellow flash; red flash |
| Generator orb (0) | Intact; destroyed (becomes type 43) |
| Fuel dump (27) | Intact; destroyed (becomes type 33) |
The crew gesture is one discrete pose change, not a cycling animation. In
retail 3.42, 0x8d2b–0x8dbb resets the uniform colours, checks damage, and tests
proximity. With the player on foot, a standing crew member within 2,000 cm
(20 metres) switches all three model pointers from the standing model to
0x6f71. That pose persists when the player moves away. The model adds a bent
arm, hand and extended finger; there are no intermediate frames to interpolate.
Flag 0x1000 instead selects the bloodied 0x7099 model and sets pitch to
0x4000 (a quarter turn), laying it flat. Flag 0x0800 makes the uniform black;
this colour variant is not a separate pose. Equivalent models in Other Worlds
are 0x71a3 and 0x72cb.
The aircraft damage flag 0x0100 selects model 0x47a1 for near/middle detail
(0x4879 in Other Worlds). Its bent parts are authored geometry. The model
gallery previews its fire discs using captured native particle updates, as
described under continuous effects;
it does not run the complete aircraft-damage simulation. The experimental-aircraft flag overrides that ordinary damage-model
selection, so the stealth preview does not inherit this state selector.
Explosion updates (0xae0b–0xae28) select the white model while the lifetime
word is above 3, yellow at 3 and red at 0–2. The stored diameters are 2,500,
4,000 and 6,000 respectively. The viewer defaults to an Animated stages
inspection loop for this object, showing white → yellow → red at four stages
per second. This deliberately readable preview cadence is not a claim about
the original lifetime countdown timing. Animate geometry pauses the loop;
each stage remains individually selectable. The main view and thumbnails share
the same stage and fixed framing, preserving the visible expansion.
The verification tool runs the original crew routine for near/far, on-foot/in- aircraft, shot and already-raised cases in both reference engines. It also executes the aircraft-damage and explosion-stage selection instructions. The results are in verification.json.
Stored model swaps are distinct from continuous effects. The reference viewers now include traced dish/propeller rotation, forcefield geometry and captured particle updates; their timing and preview limits are described below. This does not simulate whole-object flight or gameplay-driven damage progression.
A colour word with a nonzero high byte points to a runtime colour variable; otherwise its low byte supplies the stored value. Some values also involve renderer conventions that are not yet reproduced. Animation and object quality can alter colours, geometry and model selection during play. The state selector applies the explicitly traced model swaps and crew pitch change described above.
All original command lists and addresses are retained. The model gallery follows the original painter order, selecting one of the eight lists for the viewing direction. It preserves interleaved polygons, polylines and discs, repeated commands, and surfaces omitted from particular directions. Depth testing is disabled: coplanar details rely on later drawing replacing earlier pixels, including the crew's eyes and mouth, runway markings and rescue-van windows. Some van lists draw the windscreen twice around other surfaces; deduplicating commands or sorting by primitive type loses that authored layering.
The list index packs signs of the model-relative object-minus-viewer vector: negative X contributes 4, negative Y 2 and negative Z 1. Preview camera and pose rotations are inverted before selecting the list, including the shot crew's quarter-turn pose. Exact-axis views choose the nonnegative side. Verification executes the original selector and observes the van's command traversal for all 26 nonzero combinations of negative/zero/positive axis components, in both reference engines. Thus the checks include omitted and repeated commands as well as all eight octants.
The model gallery uses an orthographic inspection projection and optional neutral shading so that uninitialised runtime colours do not hide the geometry. It is not a pixel-faithful reproduction of the DOS rasterizer or a full simulation of live object behaviour. Game-colour rendering remains approximate where special stipple/rasterizer conventions have not yet been reproduced. A clickable thumbnail gallery follows the main preview’s rotation, detail level and colour selection. Paging defaults to thirty models at a time and can be disabled to show all models. Line strokes scale against a 320-pixel reference viewport, with a one-CSS-pixel minimum for thumbnails; their thickness stays constant while zooming. They are drawn as screen-space quads to avoid WebGL drivers that limit native line width to one pixel. Thumbnail badges identify available colour variants and multiple poses/states; the corresponding dropdown is greyed out when the current preview has only one meaningful choice.
Evidence: distance/detail selection 0x7270–0x73a8, octant/command dispatch
0x5e44–0x5fc2, polygon transform 0x5b83–0x5c89 and disc transform
0x5d45–0x5e0d in the retail reference. Connected polylines advance one vertex
per segment; treating them as independent pairs reads into neighbouring data.
Runtime model colours
Game colours is now the default in the model browser. Animate colours can freeze the current frame for inspection; Neutral geometry remains available. The main model and its thumbnails share the same colour phase. Colour variant selects the original three-bit quality's paint-table row (0–7) where applicable; it changes the preview's paint rather than simulating that quality's wider gameplay rules. Radar dishes have active/inactive homing- beacon states so their conditional flashing can be inspected explicitly.
These colours are pointers into mutable data, not black materials. The traced rules include:
| Appearance | Original rule reproduced |
|---|---|
| Generator-orb core, Mindbender and other users of the shared random colour | One random colour from indices 0–14 per game frame |
| Active radar homing dish | Black/white flashing from timer bit 0x0400; black when inactive |
| Projectile/debris colour pairs | Swap their original two colours each game frame |
| Generator-orb base, forcefields, balloons and vehicles | Original eight-row quality/paint tables |
| Orb ring and ground-vehicle antenna | Timer-bit 0x0200 flashing when object flag 0x0800 enables it |
| Saucer paint and mission-objective saucer panels | Two quality-dependent paint colours; objective panels use the shared random colour |
The random generator is the original 32-bit multiplicative recurrence,
state = state * 0x278dde6d mod 2^32, with the high word reduced modulo 15
for the shared colour. The viewer uses a fixed seed and advances it independently
of which thumbnails happen to be visible. The game consumes random numbers for
many other effects, so this is not a claim to reproduce a particular play
session's exact random sequence.
Random and alternating colours advance once per DOS game frame, so their speed originally depended on frame rate. The inspection preview uses 30 colour updates per second. Timer-driven flashing uses the original PIT input 1,193,182 Hz divided by 1,024, approximately 1,165.2 ticks/second; it is not arbitrarily tied to the browser's refresh rate. Pausing freezes both clocks.
The extraction records rule sources and tables for both reference engines.
Verification executes the original routines for 64 consecutive random colours,
all eight rows of seven table selections, active/inactive flashes at timer
boundaries, the three alternating pairs and every possible shared colour in
the objective-saucer override. Original routine excerpts are retained in
engine-disassembly.txt; results are under
model_colours in verification.json.
The 3D world viewer applies the traced placement flags, paint choices and world-defined sky/ground colours. It cycles colours on static geometry; the model gallery separately offers the recovered pose and particle previews. Neither viewer reproduces every special EGA drawing mode or live gameplay transition. Untraced colour pointers retain their stored values instead of being assigned an invented animation.
Music and effects
ROL streams have been decoded completely: tempo changes and eleven logical voices, each with notes/rests, instrument changes, volume changes and pitch changes. Durations below integrate the stored tempo values. They are nominal sequence durations, not verified recordings or loop boundaries.
| Edition | File | Nominal duration |
|---|---|---|
| Normal game | DESTINY3.ROL |
84.46 s |
| Normal game | RIDINGT.ROL |
203.99 s |
| Normal game | DREAMSO2.ROL |
178.33 s |
| Other Worlds | VOYAGE3.ROL |
232.24 s |
| Other Worlds | DAYBREAK.ROL |
152.16 s |
| Other Worlds | HEAVENS.ROL |
229.65 s |
The normal-game manual credits Jim Collymore / James L. Collymore for its music.
It refers to an older DREAMS0.ROL filename; the inspected file is DREAMSO2.ROL.
Title playback references DESTINY3; ROLFILES.TXT lists the two menu pieces.
The normal-game audio exports now use the original driver; its native timings
and register sequence are documented in audio-rendering.md.
BNK extraction retains instrument names, active-slot information and the 30-byte patch records. ROL instrument names are terminated at NUL; bytes after that can contain editor leftovers and are not part of the name.
MOAGDATA, common to the later packages, decodes with XOR 0xA5. The block
contains the AdLib sound-driver V1.51 signature. The decoded block is exported
without truncation. Object/linker-style filenames near its end, such as
iscore.OBJ and readfont.obj, are recorded with offsets; their reason for being
in the block has not been established.
ADL effect files contain comma-separated hexadecimal register/value pairs,
separated into blocks by ff. The normal reference has twelve blocks. They are
patch definitions rather than recordings. All three banks now have playable
auditions, and selected native routines supply engine and death-sound examples.
Audio exports and reproduction document all seven complete music renders, their matching banks, release tails and the distinction between AdPlug sequence timing, native register-writing routines and chosen audition settings. Audio exports use maximum FLAC compression and no normalisation.
Original author's retrospective
Kevin Stokes's 2010 engine article, archived in 2020 is a useful primary source alongside the binaries. It describes signed fixed-point rotation matrices, saturating arithmetic, aerodynamic lift and damage effects, AdLib synthesis, and the separate C front end written by George Welch. The main engine source was assembly. It also explains the artwork: photographs of plastic aircraft models and the author in surplus flying clothing, retouched digitally. These are author recollections; exact release-specific behaviour is still checked against the retained programs.
Continuous model effects
The reference model viewers now animate native forcefield shapes, saucer pulse vertices, radar rotation, the propeller and a repeatable particle preview. The geometry and colour controls pause independently. Static geometry remains cached; only models using changing words are rebuilt, and visible thumbnails follow them.
The forcefield routine at 0x8ada–0x8bd6 increments a 16-bit phase each game frame.
It uses three cosine phases with multipliers 4096, 3111 and 5333. The original
quarter-wave table and integer interpolation are retained, including the sign
of each destination coordinate and the engine's clamps. Forty-two words affect
stored geometry. Thirteen phases, including wrap and quadrant boundaries, are
checked against native execution in each reference engine; browser checks compare
the resulting coordinate words too. This does not substitute a modern sine curve.
The particle update at 0x3ffa–0x4105 jitters position and diameter words in shared
fire/smoke/effect buffers. A 120-frame clip of original routine output supplies
76 words used by extracted models. The clip repeats for inspection; the original
PRNG does not have a 120-frame period. Preview cadence is 30 frames per second,
whereas these effects originally advanced with the game loop.
Radar heading is four angle units per PIT tick: approximately one revolution in
14.1 seconds. The player propeller's native roll is
-timer * 2 * (speed_input - 10), modulo 65536. Its preview holds the input at 20;
this is a controlled display input, not a running flight model. Both rotations
retain view-dependent painter-list selection.
Run python3 tools/extract_runtime.py after the initial extraction, then regenerate
with python3 tools/extract_resources.py. Runtime extraction requires Unicorn.
The JSON files models/*-runtime.json retain recipes, native particle frames,
bindings, code ranges and comparison values.
Earlier models
All seven engines use the same basic template/model structure. Earlier builds' additional model-pointer assignments are followed separately; newer code offsets and state triggers are not copied onto them. Their colour animation controls are disabled where no older-build profile has been traced.
The geometry comparison ignores relocated addresses and compares every detail level's eight ordered drawing lists. Relative to normal 3.42, 1.20 changes the saucer's far model and the portal's near/middle models; 2.00 changes the portal's near/middle models. Later template geometry is identical under that comparison. Each normal-game engine now has 111 extracted models, including stored sun-face and otherwise untraced geometry; Other Worlds has 112. These are model records, not independently placeable object types. The runway switch is verified natively with six flag combinations in both reference engines. Shape matches identify earlier extra appearances without assigning unverified gameplay triggers. The early sun-face assignment is traced explicitly. The comparison does not claim identical gameplay or colours.
Presentations
The browser composes the PICT/TPICT artwork with the stored text, colours and
positions, and provides previous/next panel controls. PICT entries store text
count, pixel X/Y, image filename, text colour, then row/column/text triples.
TPICT instead starts with pixel X/Y and filename, followed by text count/colour
and column/row/text triples; -1 terminates it. These fields are layout data,
not per-caption timing values.
Normal retail has fifteen outcome panels and two story panels. Different scripts
and image variants across editions produce 55 distinct compositions. The flight
engine's outcome compositor at 0xdc8e–0xdd25 confirms the image and BIOS text
placement. Both reconstructed normal story panels match original CCTITLE output
pixel for pixel, including palette index zero's tinted background. See the
composition comparison.
The animated title is also available as a lossless RGB VP9 recording of the original CCTITLE executable in an isolated DOSBox/Xvfb session. Its drawing, palette changes and fades are original program output; page holds follow the recorded key schedule. The silent video avoids storing another copy of the separately exported music. Capture metadata records the executable hash, DOSBox configuration and key timings.
tools/capture_title.py reproduces that capture with DOSBox, Xvfb, xdotool, ffmpeg
and Pillow. Presentation BIOS text uses DOSBox 0.74-3's built-in IBM-compatible
8×8 font, external to Corncob's assets and licensed GPL-2.0-or-later. The extractor
locates and checks that font; it does not claim the font was stored in Corncob.
Saved state, demonstrations and training
State-format notes describe the saved theatre header, its embedded pilot record and world, the seeded pilot-file mask, full/delta demo records and the native training generator. These now have usable browser views rather than being omitted opaque files. The original demo reader matches all 4,580 decoded position/angle states; pilot masking matches every supplied byte.
Coverage and fidelity limits
The identified resource backlog now has extraction and inspection output: audio,
continuous effects, presentations, earlier models, saved campaigns/pilots, demos
and generated training scenery. Extraction checks all 793 source files for changes and currently reports no
decoding warnings. The coverage inventory accounts for
791 inspected/decoded source files and two retained duplicate distribution ZIPs;
no source file is unaccounted for. Executable coverage means identified embedded
resources and program metadata, not that every instruction or field is understood.
Final extraction pass records the added material and limits. Reproduce the additional checks with
tools/validate_extended.py and, optionally with Playwright/Chromium,
tools/validate_browser.py.
This remains resource analysis rather than a reimplementation of the game. Unlabelled campaign/statistics fields, some per-instance colour flags and special EGA drawing modes are preserved honestly; generated-world examples and particle clips do not enumerate every possible runtime state. Normal-game music now uses unchanged bundled-driver captures; other-edition exports still use AdPlug. Effect auditions explicitly state their selected pitch/hold inputs. Exact gameplay-driven sound scheduling, complete flight dynamics, collision rules and AI require the subsequent game-logic work.
Sun, promotional screens and final coverage
The final-pass notes describe the renderer-owned sun and
earlier face variant, the distinct radar wreck, executable promotional screens,
older saved games, high-score layouts, native stars and configuration exports.
The original star generator can be rerun with tools/extract_renderer.py before
regenerating resources. tools/validate_remaining.py checks native score sums,
sun settings and geometry switches, and scans all seven flight binaries for
additional complete models referenced by immediate AX/SI loads.
Models omitted by source build switches
The preserved assembly also contains source-only geometry in conditional data branches. Source variants expose the farm from FARM.INC, full/line-trunk/foliage-only tree helpers, the long-stem Tet, and the slalom crater (160 metres across, fixed blue). The farm and tree replace saucer and shell geometry in the slalom configuration. The foliage-only tree is complete but not referenced by its selected object template. Other changed slalom templates reuse existing aircraft and forcefield models.
tools/extract_source_models.py decodes only the original DW/DB/EQU/DUP data,
resolves its pointers into a reserved normalized address range and exports the
same primitive/model schema as the executable extractor. These 935 bytes are
bundled in corncob-cpp as generated resources; the original source is unchanged.
Each preview is marked source-only so it is not mistaken for an asset present
in a retained released executable. The usual extraction command also incorporates
these previews; --cpp ../corncob-cpp on the source extractor refreshes the
bundled generated header and its provenance.
The farm preview now includes Intact and Destroyed states. Slalom's
bmrtim calls gmdest: destruction replaces the farm with the shared fuel-dump
wreck (gmobj2/gmobj3, type 33), rather than a separate damaged-farm mesh. Each
edition preview uses its own wreck addresses; the standalone source catalogue
borrows the equivalent Deluxe geometry and records that provenance. The three
source traffic aircraft likewise reuse the normal aircraft middle/far models.
The Worlds & missions selector includes Slalom — recovered source experiment, with 109 placements, six checkpoint boundaries and passing sides, the runway start, and links to its source-specific models. It initially fits the course and airfield; Fit world includes the distant survey pads. The five survey objects occupy four corners of a 20.97152 km square, including two coincident markers at the origin. They are not established world boundaries.
Slalom JSON and
SVG overview are generated by
extract_source_world.py, called by the source
model publisher and the normal resource extraction. The shared airfield is
emulated from Deluxe's original training generator with all defence counts zero;
the alternate layout is reconstructed from DEFOBJS.ASM, with a matching random
stream. The JSON distinguishes source placements from native live records and
records the preserved-source/released-build forcefield flag difference. This is
a recovered source experiment, not evidence of a shipped slalom edition.