CORNCOB Research archive

Airfield survey and remaining campaign interface reconstruction

Reference: normal 3.42 installs/deluxe_dnk/MOAG.EXE, SHA-256 6d8c922d59a873073796b367a2a40993fcaa5e763ed2ca907a945981f0c5bc32. Its MZ header is 0x3200 bytes; module DS is 0x1886, giving a file DS base of 0x1ba60. Addresses below are file offsets unless stated otherwise.

INT survey

The survey belongs to MOAG's INT code, independently of TOWER.EXE's briefing reader. It builds TOWERS.INF from live world records. One-airfield worlds include all 64 tiles; a nine-airfield expansion instead uses the per-airfield tile table at DS:52d0. The four base worlds all use the central RDU airfield.

Temporary entries are 17 bytes: three signed dword positions, word type, word flags and a grouping byte. The low five bits identify the group; bit 0x40 marks an objective anchor. The 61 three-byte descriptors at 0x20dac contain a name pointer and inclusion/enemy attribute bits.

The first tower groups friendly objects within a strict 400,000 cm square. Orbs, objective saucers and qualifying portals claim ungrouped neighbors in the same square. Remaining objects share a final group. Sorting compares group, enemy attribute, objective marker, completion flag for objective pairs, type and quality. Destroyed or completed objects retain their original description rules.

Range calculation truncates each axis into tenths of a mile (16,090 cm) before an integer Newton square root. Zero displays as .0. Positive X is north and positive Y west. Bearings use integer dominance ratios with boundaries 150 and 503. Altitude uses signed wrapping z * 10 / 305, rather than an exact modern feet conversion. Typed labels and mission text retain original backslash markup.

tools/moag_survey_native.py executes the unchanged routines in Unicorn. Only fprintf output and near allocation are supplied. The C++ generator records 1,952 descriptions (61 types × eight qualities × four flag combinations) and 96 complete randomized grouping/sort runs. The committed Morning text also matches a real DOSBox-produced TOWERS.INF byte for byte. The scrolling document has 15 visible lines; its headings scroll with the body.

Airfield census and storage

INT counts unwrecked aircraft whose X/Y displacement from the airfield start, and Z displacement from 720 cm, are each below 524,288 cm. This is an integer start box, not a modern Euclidean range. A one-tower world's incomplete objective counts are merged into the central airfield. Objective types match the career scan, including spies and qualifying portals.

MOAG's empty-field warning (0x12819 onward) offers P only when reserve stock is positive. Enter continues on foot, Escape aborts, and another key returns to selection. A completed theater first warns that no objectives remain. Deleting a completed theater requires Y because removing its record can prevent Combat Master credit; Enter is not confirmation.

Storage selection sets DS:b1bd and appends h to the flight command. CMDLINE.ASM's hopt enables chainflag. READUNIV then starts the pilot aboard an aircraft at the stored start, disables normal arrival boarding and sets flag 0x1000. This is the lower-powered Dumpy, not the standard Corsair. The existing flight model already interprets that variant (3.ASM around 8790).

MOAG decrements reserve stock on a credited return (0x12ff5 / 0x1323d), not at selection. Aborted and invulnerable branches bypass consumption. The native cache's reserve word +0x1c corresponds to saved THT word 38. The C++ handoff keeps the pending choice with the sortie; returning updates that word. Trainee worlds and reserves remain transient. Checks cover exhaustion, on-foot continuation, uncounted returns, restart persistence and the Dumpy spawn position/variant.

Records and conditional dialogs

Killed/captured activation can resurrect and activate in one operation. Manual resurrection separately asks whether to activate the pilot. Stockade confinement has a scheduled release and cannot be removed with resurrection. Reports distinguish K.I.A., captivity, confinement, active duty and waiting. An unavailable named pilot reverts to the trainee after the return/report sequence.

ISCORE's preliminary report temporarily marks home/landed, accumulates speculative statistics, and displays its own flight-report scoring factors without saving. Training uses the global record, even with a combat world open. MOAG's final mission report uses campaign scoring and the pre-promotion rank. Promotion and medal notices follow, then the post-mission career overview. Decorations are abbreviated and drawn as repeated MEDAL.FNC glyph pairs, fourteen per line. Populated high-score rows retain fixed native columns, highlighted retirement stars, separate kill totals and signed integer points per mission.

analysis/native-campaign/ preserves original 640×400 DOSBox screenshots. Eleven are hashed by corncob-cpp/tools/generate_campaign_menu_reference.py and compared against complete C++ frames. They cover preliminary/start/survey/reserve, three populated score tables, final mission report, promotion, decoration and post-mission medals. Conditional dialogs also have state-transition tests; their entire pixel/state combination space has not been established.

Capture preparation:

All drawing in these captures comes from unmodified DOS binaries. Unicorn fixture execution and DOSBox pixel capture are separate checks. Longer campaign play, all record combinations and whole-session painter/PRNG fidelity remain broader verification work, rather than additional missing menu features.