- BORLAND/: Borland C++ 4.52 (chosen over 4.5 by byte-match: CODE/RP/CW32.LIB
is identical to 4.52's install lib). BCC32/TLINK32/TLIB/MAKE run natively on
Win11; CODE/BT/OPT.MAK is the shipped BTL4OPT.EXE's exact flag recipe
(extender = Borland PowerPack DPMI32, not Phar Lap TNT).
- restoration/source410/: the literal 1995-form reconstruction of the missing
BT game source (never mixed into CODE/). Round 1-3 state:
* 6 of 10 surviving original TUs COMPILE CLEAN under the period toolchain
(BTMSSN, BTCNSL, BTSCNRL, BTTEAM, BTL4MODE, BTL4ARND) - first builds
since 1996.
* BT_L4/BTL4APP.CPP pilot reconstruction: 12/12 functions, Fail() lands on
its binary-recorded line 400 exactly.
* BT/BTCNSL.HPP: console wire IDs recovered from the binary's ctors
(Killed=9, Damaged=10, ScoreUpdate=13, DeathWithoutHonor=15 [T1];
TeamScore=12 flagged [T4]).
* MUNGA/: 8 engine-header backfills back-dated from the BT412 WinTesla tree
(VDATA numbering decomp-verified; AUDREND's OpenAL-era virtual removed -
the period compiler is the drift detector).
* Tooling: backdate.py (WinTesla->1995 header transform), compile410.sh
(per-TU verification sweep under authentic OPT.MAK flags).
* README: corrected roadmap - MECH.HPP is the capstone grown with the mech
TU reconstructions; BTREG.CPP green = the header-family milestone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
70 lines
4.3 KiB
Markdown
70 lines
4.3 KiB
Markdown
# BTL4APP.CPP — reconstruction notes (2026-07-18)
|
|
|
|
**Status: 12/12 functions reconstructed; the binary's `Fail()` line constraint (BTL4APP.CPP:400)
|
|
is met exactly.** Source basis: decomp `BT411/reference/decomp/all/part_014.c:8052-8425`,
|
|
port semantic map `BT411/game/reconstructed/btl4app.cpp`, surviving headers BTL4APP.HPP /
|
|
L4APP.HPP / BTL4MODE.HPP / BTL4ARND.HPP / BTREG.HPP / L4CTRL.HPP / CONTROLS.HPP / MODE.HPP /
|
|
APPMSG.HPP / RPL4VID.HPP / RENDERER.HPP / LATTICE.HPP, idiom exemplars AUDSRC.CPP /
|
|
BTL4ARND.CPP / L4MPPR.CPP / BTMSSN.CPP.
|
|
|
|
## Address map (source order = binary emission order) [T1]
|
|
| line | function | @addr | size |
|
|
|---|---|---|---|
|
|
| 100 | ctor | 4d34c4 | 72 |
|
|
| 116 | dtor | 4d350c | 44 |
|
|
| 125 | MakeRegistry | 4d3538 | 44 |
|
|
| 138 | MakeVideoRenderer | 4d3564 | 76 |
|
|
| 165 | MakeAudioRenderer | 4d35b0 | 100 |
|
|
| 189 | MakeModeManager | 4d3614 | 48 |
|
|
| 202 | MakeControlsManager | 4d3644 | 72 |
|
|
| 228 | MakeGaugeRenderer | 4d368c | 56 |
|
|
| 249 | MakeMission | 4d36c4 | 48 |
|
|
| 264 | MakeViewpointEntity | 4d36f4 | 824 (anchor; Fail @ line 400 ✅) |
|
|
| 461 | RunMissionMessageHandler | 4d3a2c | 104 |
|
|
| 476 | StopMissionMessageHandler | 4d3a94 | 224 |
|
|
|
|
Note the CPP emission order differs from BTL4APP.HPP's declaration order (ModeManager before
|
|
ControlsManager before GaugeRenderer in the binary) — the binary order wins. [T1]
|
|
|
|
## Decoded constants — all resolve to named 1995 expressions [T1]
|
|
- ctor base arg `1` = `BTL4` (`enum ApplicationID {RPL4, BTL4, BTW4}`, APPMSG.HPP:47 — note
|
|
the unreleased **BTW4** slot).
|
|
- `0x50421` = `BTL4ModeManager::ModeInitial`; `0x400000` = `ModePlasmaDisplay`; the +8/+4
|
|
writes = `ModeManager::AddModeMask/RemoveModeMask` inlines (MODE.HPP:56-70, byte-exact).
|
|
- `2`/`4` = `LBE4ControlsManager::{PrimaryThrustMaster, PrimaryRIO}` (L4CTRL.HPP IOType).
|
|
- `-1` mode mask = `ModeManager::ModeAlwaysActive` (MODE.HPP); keyboard registration =
|
|
`ControlsUpdateManager<ControlsKey>::Add(ModeMask, Receiver*, MessageID, Plug*)`
|
|
(CONTROLS.HPP:319; the vtbl+0x14 call on `keyboardGroup[KeyboardPC]` @manager+0x1a0).
|
|
- Video ctor 5-tuple = `(DefaultRendererRate, MaxRendererComplexity, DefaultRendererPriority,
|
|
VisualInterestType, 1)` — signature from RPL4VID.HPP; the two leading globals are
|
|
DAT_004e8238/DAT_004e823c (extern consts, RENDERER.HPP:38/41). ⚠ the PORT's btl4app.cpp
|
|
maps these to the WRONG positions (globals as args 4-5) — flagged for back-porting.
|
|
- Audio ctor = `(GetFrameRate(), GetMissionReviewMode())` — BTL4ARND.HPP:95 proves arg2 is
|
|
`Logical mission_review_mode`; DAT_004fd550 = `L4Application::missionReviewMode` static.
|
|
`GetFrameRate` naming for FUN_0044e19c is [T3] (port identification, not header-proven).
|
|
- All string literals byte-verified via section_dump (51ebd6…51ed40), including
|
|
`"*****Mech has no controls mapping!*****"` and the camera/mech `"Thrustmaster"`/`"L4"`
|
|
mapping names.
|
|
|
|
## Judgment calls (flagged, not proven)
|
|
- **Banner** copies the stale `rp4lbe4.cc` RP-clone banner because the surviving BTL4APP.HPP
|
|
carries the matching stale `rp4lbe4.hh` banner — the pair was cloned from RP together. [T4]
|
|
- Include list & order mirror the port's reconstruction, trimmed to 1995 headers. [T4]
|
|
- `switch` vs `if/else` for the two class cases compiles identically at -O; switch chosen to
|
|
match VWE style elsewhere. [T4]
|
|
- Camera-case mapper resource = stack `SubsystemResource` (decomp-proven: 32-byte name copy,
|
|
classID 0xf, modelSize 0x30); mech-case mappers take a **CString name** (decomp-proven:
|
|
CString ctor + refcount at the call) with `ClassID`/`SharedData` DEFAULTED (0x7dc,
|
|
&DefaultData passed by the compiler). [T1 shape / T3 default-arg reading]
|
|
- `mech_mapper = NULL;` after `Fail()` reflects the decomp's `puVar3 = 0` (Fail returns in
|
|
OPT?); kept. [T1]
|
|
- `description->resourceAddress` / `ControlMappingsListResourceType` (== 6) member/constant
|
|
names follow the port's ResourceDescription reading; verify against the 1995 RESITEM/RES
|
|
headers when that TU is done. [T3]
|
|
- Two `Check*` lines were omitted in MakeViewpointEntity to meet the line-400 constraint;
|
|
Check macros are invisible in OPT builds so the choice is evidence-neutral, but WHICH
|
|
lines the original spent is unknown — revisit if a Borland build ever line-checks. [T4]
|
|
|
|
## Line-constraint ledger
|
|
`BTL4APP.CPP:400` = the only Fail in the TU ✅ met exactly.
|