Commit Graph
5 Commits
Author SHA1 Message Date
arcattackandClaude Opus 4.8 c0d2eb0aae gauge-complete P4f: PrepEngrScreen reconstructed + registered -> 12 engineering-screen label overlays build
The "prepEngr" cockpit primitive (the per-engineering-screen static label overlay,
12 CFG calls at L4GAUGE.CFG:4595-4759) was a MISLABELED stub (base Gauge, an Execute
override, mech/screenNumber SWAPPED) with no methodDescription -> parse-SKIPPED, none built.

Reconstructed byte-verified (ctor @4c7bf0, BecameActive @4c7e48, Make @4c7b30; vtable
0051a06c). THREE corrections vs the stub (decode workflow + vtables.tsv proof):
(1) base = GraphicGaugeBackground, not Gauge -- vtable-identical shape to the engine's
BackgroundBitmap (only dtor + BecameActive overridden); (2) the overridden slot is
BecameActive (a paint-on-activation), NOT Execute -- GraphicGaugeBackground has no Execute
virtual, so the Gauge::Execute->Fail->abort hazard doesn't apply; (3) screenNumber@0x6C /
mech@0x70 were swapped. sizeof 0x90.

BecameActive walks the mech roster (databinding-safe GetSubsystemCount/GetSubsystem +
BTGetSubsystemAuxScreen bridge, like VehicleSubSystems::Make), finds the subsystem whose
auxScreenNumber == this screen (1..12), and paints the screen-number numeric + subsystem
label + type-specific label cells dispatched on GetClassID (Sensor/Myomers/Emitter/PPC/
Projectile/Missile/GaussRifle). methodDescription = 9 params (mode, screen, 7 .pcc names).
Registered in BTL4MethodDescription[]. Two raw subsystem reads (heat-sink #, +0x224 label)
are guarded fail-soft best-efforts (marked; the aux-screen bridge label64 substitutes).

VERIFIED: the skip list drops from {prepEngr x12, messageBoard} to just {messageBoard} --
all 12 prepEngr gauges build; no screen-range/crash; boot+sim+combat run; gauge composite
renders identically (COOLANT 300/77, clusters, radar all un-regressed). The prepEngr labels
paint on the Eng (ModeMFD*Eng*) screens, not the default composite view.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 21:32:12 -05:00
arcattackandClaude Opus 4.8 88cd68aaa1 gauge wave P2d: GeneratorCluster un-gated -- the 4 generator panels render
Root-caused the P2c abort with a cdb attach to the frozen abort dialog: the stack
was Gauge::Execute (GAUGE.cpp:598) -> abort, via GuardedExecute <- Update <-
ProcessOneActiveGauge.  The engine base Gauge::Execute is Fail("not overridden")
-> abort, so an ACTIVE container that doesn't override Execute aborts by design;
GuardedExecute's SEH can't catch an abort().  The decode's "GeneratorCluster
overrides ONLY the dtor / renders via its children" was wrong -- the 1995 base
Gauge::Execute was a no-op, the 2007 WinTesla engine's aborts, so the container
MUST override Execute (the sibling SubsystemCluster does).

FIX: give GeneratorCluster the two container overrides (mirroring SubsystemCluster):
- BecameActive() -- blit the panel's static background pixmap (DrawPixelMap8) and,
  by overriding the default, DON'T self-inactivate so the panel stays active.
- Execute() -- no-op (the 5 self-registered child gauges draw the dynamic content;
  the override exists only to avoid the base Fail->abort).

Re-registered in BTL4MethodDescription[].  Verified DBASE+dev gauges: all 4
generator panels (A/B/C/D) render -- blue OutputVoltage bars (the @004c72ac
ScalarBarGauge Scalar* variant), labels, status lamps -- 0 "BecameActive not
defined" warnings, NO abort, combat un-regressed (TARGET DESTROYED).  Phase 2 is
now COMPLETE (4/4 widgets: LeakGauge, VertNormalSlider, PilotList, GeneratorCluster).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 17:57:20 -05:00
arcattackandClaude Opus 4.8 b44e908101 gauge wave P2c: GeneratorCluster reconstructed + infra (gated -- parent aborts)
Reconstructed the 4th unbuilt widget (the 4 generator engineering panels, buttons
9-12) + its companions, but left it UNREGISTERED pending a runtime-abort fix:

- Generator OutputVoltage attribute table (powersub) -> outputVoltage@0x1DC, chained
  to HeatSink's dense index (temps already reach it).  Correct + reusable.
- ScalarBarGauge @004c72ac plain-Scalar variant (btl4gau2) -- the DIRECT-Scalar* bar
  the GeneratorCluster voltage bar needs (the existing @004c721c takes a resolved
  source object).  Correct + harmless.
- GeneratorCluster Make/ctor/dtor + 15-param methodDescription reconstructed from
  part_014.c:891-1013 (replacing the prose + placeholder Make + the bogus DAT pool);
  builds the 5 children (temp bar / voltage bar / leak wipe / 2 lamps).  Header fixed
  to the binary ctor param order (secondaryColor@0x94, +_reserved0xB0 -> sizeof 0xB4).
  ChildRate forward-declared.

⚠ REGISTRATION GATED (commented out in BTL4MethodDescription[]): registering it
aborts at runtime -- the 4 panels build (the 4 "BecameActive not defined" warnings
fire) then abort().  ISOLATED to the PARENT lifecycle: the abort PERSISTS with all 5
children nulled; there are no pure virtuals; Execute is SEH-guarded under BT_DEV_GAUGES
so the fault is in the unguarded ctor/lifecycle path.  The sibling SubsystemCluster
overrides BecameActive/Execute/TestInstance whereas the decode has GeneratorCluster
overriding ONLY the dtor -- that "inherits only the dtor" claim is the prime suspect.
Deferred; the 3 other P2 widgets (LeakGauge/VertNormalSlider/PilotList) ship clean.

Verified: unregistered -> parse-skips -> no abort; combat un-regressed (DESTROYED),
0 crashes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 17:43:47 -05:00
arcattackandClaude Opus 4.8 674c172cf8 vehicleSubSystems Phase 1: reconstruct + register the cluster-panel family
Reconstruct the whole engineering-screen (MFD) subsystem cluster-panel system in
btl4gau2 (from the Ghidra decomp of BTL4OPT.EXE) and register the vehicleSubSystems
config primitive:

- Sub-gauges: AnimatedSubsystemLamp/AnimatedSourceLamp (OneOfSeveral + cooling/
  power connections), ScalarBarGauge (BarGraphBitMapScalar + generator-voltage
  connection), ConfigMapGauge, plus the 3 file-private GaugeConnection classes
  (@004c3134/31ec/3288 samplers).
- SubsystemCluster base (ctor builds ~11 child gauges across the MFD + engineering
  ports; Execute/dtor/frame-draw/enable helpers) + the 5 subclasses HeatSink/
  Myomer/Weapon/Energy/Ballistic (ctors + Executes).
- VehicleSubSystems::Make dispatcher (@004cbaf0): per-subsystem factory keyed on
  classID (HeatSink 0xBC3 / Myomer 0xBC6 / Energy 0xBC8,0xBD4 / Ballistic
  0xBCD,0xBD0), placed via the 12-row aux-screen geometry table, + registered in
  BTL4MethodDescription[].

SAFE + gated: gauges only build under BT_DEV_GAUGES/pod, and until Phase 2
populates the subsystem aux-screen field (subsystem[0x1dc]) the Make hits its
"aux screen = zero" skip -> combat untouched.  Two minor children deferred as
marked NULLs (SegmentArc270 recharge dial + BitMapInverseWipeScalar eject wipe --
their ctors are btl4gaug placeholders).  Raw-offset subsystem reads (0x1dc/0x1e0/
0x1e4/0x31c/0x334/0x364/0x43c...) marked BEST-EFFORT pending Phase 2.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 06:43:32 -05:00
arcattackandClaude Opus 4.8 7b7d465e5e Initial commit: bt411 -- standalone Windows BattleTech (Tesla 4.10 port)
Clean, self-contained extraction of the BattleTech-specific work from the
reverse-engineering workspace -- engine + game + content + build, with nothing
from Red Planet or the raw archive dumps. Builds green (Win32) and runs the
single-player drive->animate->target->fire->damage->destroy loop out of the box.

Layout:
  engine/   MUNGA + MUNGA_L4 shared 2007 engine, carrying our BT render/loader
            work (bgfload/L4D3D/L4VIDEO: BSL bit-slice decode, LOD/ground/shadow
            models) + image codec; the minimal rp/ headers the audio HAL needs
  game/     reconstructed BT logic + surviving-original BT source + fwd shims
            + WinMain launcher
  content/  full runtime tree (BTL4.RES, VIDEO/, GAUGE/, AUDIO/, eggs, BTDPL.INI)
  docs/     format specs + reconstruction ledgers
  reference/ raw Ghidra pseudocode (recon source-of-truth) + decomp exporter
  tools/    MP console emulator + map/resource scanners

One top-level CMake builds munga_engine lib + bt410_l4 game lib + btl4.exe.
All paths relativized (186 fwd shims + ~437 CMake abs paths -> repo-relative);
DXSDK is the one external, overridable via -DDXSDK. Verified: builds to a
byte-identical 2.27MB exe and runs combat (TARGET DESTROYED, 0 crashes) against
the bundled content.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 21:03:40 -05:00