# 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.
