TOWER.EXE: normal Corncob 3D 3.42
Reference: installs/deluxe_dnk/TOWER.EXE, 18,528 bytes,
SHA-256 9bfcf33fb27f6e35e17383c8cc19a6f125e287cd75fb9c7f0e282f639f110233.
This is a separate Borland C/C++ real-mode program. Its C source is absent from
the preserved assembly release. The application code and the text/keyboard
helpers have now been traced directly in this executable and reproduced in
corncob-cpp/src/game/tower_briefing.cpp.
Contract and ownership
The normal invocation is tower -_- n [filename]. The guard string is required;
n is a zero-based airfield index from 0 to 8. The default input is towers.dat;
the optional filename replaces that name. n = -1 takes the separate boss-screen
path. Invalid/missing arguments produce the embedded diagnostics. The module
saves/restores the caller's text-screen state and returns success after normal
interaction.
The flight engine's RUNTOWER constructs this command. DOTOWER suspends its
timer and commits elapsed flight time before invoking the helper. The helper
itself does not repair aircraft, move the player, advance simulation, allocate
reserve aircraft, or calculate the live object survey. Those responsibilities
belong to the engine or MOAG. In particular, TOWERS.INF is a different document;
TOWER does not read it. The preserved engine source also mentions a separate
TU.EXE detailed-info helper, which is not included in this installation.
The reader skips n + 1 form-feed-delimited sections before displaying text.
Section zero is the theatre description; sections one through nine are the
nine airfield briefings. The four bundled base theatres and generated training
use airfield four (section five). A separator must start a physical fgets line;
an embedded form feed elsewhere in a line is not a separator.
Text and display
The window occupies the complete 80 by 25 colour text screen: grey-on-blue single-line frame, body at column 1/row 1 (zero-based), 77 text columns, 22 body rows, scrollbar in column 78, and an inverse white-on-black footer on row 23. It uses the normal BIOS 8 by 16 font, without MOAG's medal replacements.
Input uses fgets(..., 128, ...), not arbitrary-length logical lines. Long lines
therefore break into chunks of at most 127 bytes. Up to two trailing CR/LF bytes
are stripped; blank lines remain. Rendering truncates each body line after 77
visible characters. \\ prints a literal backslash, \( / \) enable/disable
bright text, and \X temporarily colours X yellow. Emphasis persists across
consecutive lines in a redraw; it starts afresh when the page is redrawn.
For N > 22 lines, top scroll position S is clamped to [0, N - 22]. The scrollbar
starts at floor(S * 22 / N) and ends inclusively after another
floor(22 * 22 / N) rows. The track uses CP437 177, the thumb 219. The long
footer is Type [up], [down], PGUP, PGDN, <CR> to select, <esc> to cancel.
At 22 lines or fewer the scrollbar is blank and the footer becomes
Type <CR> to return to the game....
An empty section shows There is no information to print here, number=n and
Type almost any key to continue...; any key acknowledges it.
Navigation and mission selection
All four arrows move one row. PgUp/PgDn move 20 rows; Space also moves 20 rows forward. Lowercase U/D move 11 rows backward/forward. Home/lowercase G go to the beginning, End/uppercase G to the end. Lowercase J/K move down/up. Numeric 2/6 move down, 4/8 move up. Control-B/P move up, Control-F/N down, Control-O back 20, Control-Y forward 20, Control-T to the beginning and Control-R to the end. The unusual bindings come from the executable's two keyboard-dispatch tables; they are not deductions from the documentation.
At each redraw the program clears its selected-start string, then highlights
and copies the first visible line beginning exactly Sxyth . Later Sxyth lines
on the same page remain ordinary text. It leaves the directive and its numeric
coordinates visible. Selecting a mission consequently means scrolling until
that mission's directive is the first one visible. There is no separate list of
mission names or independent selected-row cursor.
Enter writes the selected directive's suffix, followed by a newline, to
STARTLOC.DAT. If the visible page contains no directive, Enter deletes that
file. Escape, Backspace and lowercase Q also delete it and return. An earlier
invocation's selection is never reused. On return, 3.EXE reads this file only
while the pilot is in an aircraft. Its existing damage gate and DONEWMISS
continuation then apply; selecting a start while on foot has no flight effect.
F1 inside the reader temporarily displays the BOSS.TXT disguise. Any key
restores the same page and recalculates its selected start. Standalone -1 uses
the same disguise and then exits. Boss text treats $$ as a literal dollar and
an unpaired dollar as a cursor-position marker, replacing that marker with a
space. The bundled file places a DOS prompt near the bottom of the screen.
Executable map
Offsets below are executable file offsets, including the 0x400-byte MZ header. Far-call segment addresses in the disassembly are module-relative.
| File offset | Role |
|---|---|
| 0x2b94–0x2dd2 | Main: guard/argument parsing, boss dispatch, full-screen frame, section reader, write/delete STARTLOC.DAT |
| 0x2dd2–0x2e0c | Fatal argument diagnostic and normal screen restoration |
| 0x31d3–0x3275 | Rich-text escape decoder and visible-width limit |
| 0x36db–0x39a7 | Section skipping, line counting, allocation and loading |
| 0x39a7–0x3a0b | Strip up to two trailing CR/LF bytes |
| 0x3a0b–0x3bda | Footer, scrolling and completion-key dispatch |
| 0x3c36–0x3c71 | Recognise Sxyth and copy its suffix |
| 0x3c71–0x3d9e | Render visible rows, highlight first directive and draw scrollbar |
| 0x3deb–0x3e6d | Centre/pad footer text |
| 0x3e6d–0x3f07 | Decode ASCII and DOS extended key inputs |
| 0x3f3f–0x3fb9 | Save display, show boss disguise, wait, restore display |
| 0x3fb9–0x40e2 | Load BOSS.TXT, dollar escaping and cursor marker |
| 0x40e2–0x4130 | DOS input and pending-key draining |
| 0x4130 | Data segment base; strings and runtime state follow |
The common reader contains return cases for other menu modes, but main always invokes its mode 1. Unreachable branches do not imply extra tower menus. DOS memory-allocation failures and missing files have diagnostic branches; the native reconstruction embeds its documents and does not reproduce DOS heap or process-management machinery. DOS error beeps and a blinking hardware text cursor are not part of the pixel-reference contract.
Verification
tools/capture_native_tower.py runs the unmodified executable in a temporary
copy of the installation on a private X display. It preserves 49 complete
640 by 400 RGB captures and the exact STARTLOC.DAT contents or absence in
analysis/native-tower/captures.json. The set covers all four actual theatres,
all nine section indices, generated training, boundaries and navigation aliases,
Enter/cancellation, multiple directives, long lines, literal backslashes,
multiline emphasis, empty input and the hidden boss round trip.
The synthetic inputs test the original program directly; they do not use the C++ implementation to generate expectations. The native fixture generator in corncob-cpp imports these captured RGB hashes and return-file results. All 49 screens and their handoffs match. The original game installations are untouched.