Files
TeslaRel410/restoration/source410/BT_L4/BTL4.NOTES.md
T
CydandClaude Fable 5 d2be54a3b9 BT410 5.3.106: MISSION REVIEW LINKS -- the playback app, the winners circle, and the last Fail() in main
BTL4PB.CPP reconstructed against its AUTHENTIC surviving header (BTL4PB.HPP)
from the binary's 0x4d3b74-0x4d40d8 cluster, cross-checked against the
surviving RP411 twin -- and the review/camera launch in BTL4.CPP's main() is
real code now.  btl4.lib 11 -> 12 members, link clean, zero unresolved: the
linker pulled the entire playback chain for the first time.

The launch decode closed on two identifications:

  The `if (spool_file)` guard in the decomp means the manager getter is
  GetStoredSpoolFile -- the empty-spool getter cannot fail, so a review pod
  with no recorded battle simply starts nothing, which is the right field
  behaviour.

  The camera app's ctor (FUN_0047c3fc) sits in the ENGINE range with the
  (ResourceFile*, ApplicationID) shape: the camera pod's recorder IS the
  engine's own L4SpoolingApplication -- restored one commit ago -- started
  with ApplicationID 1 == BTL4.  BT shipped no camera app of its own.

What the playback app does, all binary-anchored: BTSpoolerTask pumps
recorded packets through DispatchPacket -> the client's own
ReceiveNetworkPacket; RunMission synchronises the clock (timeBias = Now -
the recorded run packet's stamp); the frame loop runs controls ONLY in
interactive review (mode 2), then update/interest/renderer/intercom; and
StopMission plays the WINNERS CIRCLE -- release the spool, park each
player's mech on the dropzone named "win1".."winN" by finishing rank,
freeze it (DoNothing performance), and tilt the camera up 45 degrees over
the tableau.

DOS-authentic ctor shape throughout: the binary's base call is (resource,
0x3eb, DefaultData) -- no windowing parameters ever existed in 4.10; the
RP411 twin's HINSTANCE/HWND threading is port drift, dropped.

Also fixed from 5.3.105's debt: L4PlaybackNetworkManager chains
NetworkManager::DefaultData -- the 1995 header declares no statics of its
own; the RP411 self-reference was drift too.

One [T3] in source: the idle frame's renderer service (the descendant's
ExecuteIdle) has no 1995 entry point; pre-egg the idle frame spins.

RUNTIME TEST PENDING, stated plainly: exercising review needs a
camera/review egg and a recorded spool on the rig (CAMERA-REVIEW-NOTES.md
has the roles).  The normal pod path regressed clean (mode gate untouched).

The Fail() census moves: BTL4.CPP and SEQCTL.CPP are now stub-free; 22
stubs remain across 15 files.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 15:54:31 -05:00

4.2 KiB

BTL4.CPP — reconstruction notes

Status: FULLY RECONSTRUCTED (2026-08-03) — both launch paths. The review/camera branch links against the real BTL4PB + L4SPLR bricks; no Fail() remains in this TU.

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

  1. Ghidra decomp of the 4.11 binaryC:\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.
  2. 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.
  3. Surviving 1995 launcher-style TU CODE/RP/RP_L4/RPL4TOOL.CPP — house style for main(int, char*[]) and the ProgName global pattern.
  4. BT411's win32 launcher game/btl4main.cpp (adapted from RP's RPL4.CPP) independently reconstructs the same skeleton and pins version[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));

RECONSTRUCTED 2026-08-03: the branch is real. BTL4PB.CPP reconstructs the playback app against its authentic surviving header; L4SPLR.CPP back-dates the RP411 descendant onto the authentic 1995 engine header (see each sidecar). Two identifications closed it: the if (spool_file) guard means the getter is GetStoredSpoolFile (the empty-spool getter cannot fail), and the camera app's ctor FUN_0047c3fc sits in the engine range with the (ResourceFile*, ApplicationID) shape — the camera app IS the engine's L4SpoolingApplication, started with ApplicationID 1 == BTL4. RUNTIME TEST PENDING: needs a camera/review egg and a recorded spool on the rig (CAMERA-REVIEW-NOTES.md).

Deliberate differences from the binary

  • HEAPSIZE string 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_Registering debug bookkeeping is absent from the optimized binary (DEBUG_LEVEL=0 compiles it out), so it is not written here.