The reconstructed tree now produces a runnable binary with the authentic 1995 toolchain (BC4.52 / tlink32 / DPMI32): - BTL4.CPP main TU reconstructed from the 4.11 Ghidra decomp (FUN_0040109c) + the 4.10 binary's own string pool + surviving RPL4TOOL.CPP house style; probe_main.cpp scaffold retired (BTL4.NOTES.md documents every decoded call) - L4NET.CPP staged: L4NetworkManager ctor/dtor + 10 vtable-pulled virtuals (standalone-benign ones no-op, network ones Fail loudly) + NetNub client globals (Net_Common_Ptr=NULL routes L4File to its plain-DOS path) - build410.sh: libs now built in the AUTHENTIC makefile member order (MUNGA.MAK / mungal4.mak / BT.MAK / BTL4.MAK). Order is load-bearing: tlink emits static-init records in module pull order, and alphabetical order booted into a null-vptr crash (IcomManager::ClassDerivations constructing before parent NetworkClient::ClassDerivations). Also fixed stage_link to the proven 32-bit lib set (SOSDBXC+SOSMBXC, no WATTCPLG) - BOXTREE.HPP MemoryBlock unify, BTL4GRND notify stubs, remaining engine backfills (audio/gauge/resource/stream TUs) that closed the deep ledger Smoke test (DOSBox-X + 32RTM, copy of the pod BT tree, our exe swapped in): BattleTech v4.10 BTL4Application::BTL4Application l4net.cpp(22): L4NetworkManager -- l4net.cpp not yet reconstructed Static init, main, -egg parse, BTL4.RES load (version 1.0.6 check passes), ApplicationManager and the BTL4Application ctor chain all execute real reconstructed code; boot halts at the first staged Fail() as designed. Next brick: the real l4net.cpp body. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3.7 KiB
3.7 KiB
BTL4.CPP — reconstruction notes
Status: RECONSTRUCTED (normal launch path); review/camera branch staged with Fail().
The 4.10 main TU. No original survives anywhere in the archive (OPT.MAK links
btl4.obj as a bare object next to the libs — it was never a lib member).
Evidence base
- Ghidra decomp of the 4.11 binary —
C:\VWE\BT411\reference\decomp\all\part_000.c,FUN_0040109c(the 524-byte function the Borland startup calls =main). The 4.10 and 4.11 binaries share the same string pool layout for this TU. - String pool of the original 4.10
BTL4OPT.EXE(ALPHA_1/REL410/BT), file offset ~917884:"btl4" "HEAPSIZE" "BattleTech v4.10" "btl4.res" "SPOOLSIZE" "Spool size = "— banner text and resource name byte-exact. - Surviving 1995 launcher-style TU
CODE/RP/RP_L4/RPL4TOOL.CPP— house style formain(int, char*[])and theProgNameglobal pattern. - BT411's win32 launcher
game/btl4main.cpp(adapted from RP's RPL4.CPP) independently reconstructs the same skeleton and pinsversion[3] = {1,0,6}against the RESOURCE.cpp version check.
Decoded decomp → source mapping
| decomp | source |
|---|---|
FUN_004dbb24(&cout, "BattleTech v4.10", 0); FUN_004d9c38(&cout) |
DEBUG_STREAM << "BattleTech v4.10" << endl |
FUN_0047b2ec(argc, argv, &LAB_0047af8c) |
L4Application::ParseCommandLine(argc, argv, L4Application::ParseToken) |
FUN_00407218(stack84, "btl4.res", &DAT_004e0070, 3) |
StreamableResourceFile resources("btl4.res", version) (match_level=3 is the declared default) |
DAT_004e0070 = 3 bytes |
version[3] = {MAJOR_DATA_VERSION, RELEASE_VERSION, MINOR_DATA_VERSION} = {1,0,6} from BTL4VER.HPP |
DAT_004fd550 < 1 |
L4Application::GetMissionReviewMode() < 1 (inline static accessor) |
new(0x28) FUN_0044f29c(this, DAT_0052140c) |
new ApplicationManager(GetTicksPerSecond()) (inline friend accessor, TIME.HPP:49) — DAT_0052140c is set to 28.0f by SystemClock::SystemClock() (L4TIME.CPP:93) when L4TIMER=FAST |
new(0xd4) FUN_004d34c4(this, &resources, 0x3EB, &DAT_0051e8d8) |
new BTL4Application(&resources) — 0x3EB/DefaultData are the declared default args (BTL4APP.HPP:34) |
FUN_0044f318(mgr, app) |
application_manager->StartApplication(application) |
FUN_0044f344(mgr) |
application_manager->RunMissions() |
| vcall slot 0 (mgr, 3) | delete application_manager |
return DAT_004efc98 |
return Exit_Code (APP.HPP:542) |
Review/camera branch (NOT yet reconstructed — staged Fail)
Decomp structure for missionReviewMode >= 1 (mode 1 = camera, 2 = review per
emulator/CAMERA-REVIEW-NOTES.md):
spool_size = getenv("SPOOLSIZE") ? atoi(...) : 0x800000; // "Spool size = " printed
mgr = new(0x38) MissionReviewApplicationManager(ticksPerSecond,
(mode != 2) ? 2 : 1, spool_size);
spool_file = <mgr getter, FUN_0044fa14>;
if (spool_file)
mgr->StartApplication(new(0xd8) BTL4PlaybackApplication(&resources, spool_file));
if (mode == 1)
mgr->StartApplication(new(0xd8) <camera app, FUN_0047c3fc>(&resources, 1));
Class declarations survive: BTL4PlaybackApplication (CODE/BT/BT_L4/BTL4PB.HPP),
spooler bricks in CODE/RP/MUNGA_L4/L4SPLR.HPP (MissionReviewApplicationManager
referenced there). Their .CPP bodies are not staged, so the branch Fails loudly
instead of linking half a subsystem.
Deliberate differences from the binary
HEAPSIZEstring sits in the pool between ProgName and the banner but is not referenced from the decompiled main — it likely belongs to the runtime heap init, not this TU. Not reproduced.Register_Object/Start_Registeringdebug bookkeeping is absent from the optimized binary (DEBUG_LEVEL=0 compiles it out), so it is not written here.