CORNCOB Research archive

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.

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.