subsystems: un-stub Wave 4 readouts + Wave 6 Myomers (10->15 factory cases)
WAVE 4 (standalone readouts) -- Sensor(0xBC3)/Searchlight(0xBD8)/ ThermalSight(0xBDE)/AmmoBin(0xBCB) un-stubbed via Create<Class>Subsystem bridges + Torso-style de-shim (drop cross-family shadow fields, redirect accessors to the real inherited base, static_assert layout locks). - FIX: Searchlight/ThermalSight ctors gated their Performance on the shadow segmentFlags(=0) so it NEVER installed; switched to owner->simulationFlags. - AmmoBin: retype ammoAlarm HeatAlarm->WatcherGaugeAlarm(0x54) + drop the statusState@0x40 shadow -> exact 0x22C layout. - Guard HeatWatcher::WatchSimulation against the unresolved watchedLink (null-deref exposed once these sims run; faithful fix = resolve the link). - Heat-leaf branch (Sensor) is not byte-exact -> overflow-lock only. WAVE 6 (Myomers 0xBC6, mover-coupled) -- structural un-stub, gated BT_MYOMERS (default on; =0 -> Actuator stub). Wired INERT: MyomersSimulation early-returns (advanced-damage gate stubbed) + no-op mover feed, so the live JointedMover is untouched and the gait cannot regress. De-shim drops the owner*/segmentFlags shims to fit the exact-0x358 alloc. Authentic mover/heat coupling deferred (needs messmgr 0xBD3 + reconciling the mover feed with the gait cutover). Verified: BLH tick 20->27, Mad Cat 24, combat DESTROYED un-regressed, locomotion un-regressed, 0 crashes, 0 heap detections under BT_HEAPCHECK. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
5aa791b245
commit
8b36440d05
@@ -82,21 +82,20 @@ Searchlight::Searchlight(
|
||||
Check(owner);
|
||||
Check_Pointer(subsystem_resource);
|
||||
|
||||
segmentFlags = 0;
|
||||
hostShutDown = False;
|
||||
watchedVoltageLevel = 4; // Ready
|
||||
heatStateLevel = 0; // NormalHeat
|
||||
controlsAllowLights = True;
|
||||
graphicsDirty = False;
|
||||
instanceFlags = 0;
|
||||
|
||||
// (WAVE 4 de-shim) the 7 cross-family shim fields are gone; the accessors
|
||||
// read the inherited base state directly. Only the own fields init here.
|
||||
lightState = 0; // @0x1D8
|
||||
requestedOn = 0; // @0x1E0
|
||||
stateAlarm.Initialize(2); // FUN_0041b9ec(this+0x1E4, 2)
|
||||
commandedOn = subsystem_resource->segmentIndex; // @0x1DC <- inherited resource +0x28
|
||||
|
||||
if (((GetSegmentFlags() & 0xC) == 0) &&
|
||||
((GetSegmentFlags() & 0x100) != 0))
|
||||
// GATE FIX (the functional bug the de-shim unblocks): the binary reads OWNER
|
||||
// simulationFlags (param_2+0x28, raw part_013.c:6012), NOT the old shadow
|
||||
// `segmentFlags` -- which was seeded 0, so the gate was ALWAYS FALSE and
|
||||
// SearchlightSimulation NEVER installed. A live master segment arms it; a
|
||||
// copy/replicant gets DontExecute (flag 2). Mirrors torso.cpp:181-182.
|
||||
if (((owner->simulationFlags & 0xC) == 0) &&
|
||||
((owner->simulationFlags & 0x100) != 0))
|
||||
{
|
||||
SetPerformance(&Searchlight::SearchlightSimulation); // this[7..9] <- PTR_FUN_00511200
|
||||
}
|
||||
@@ -256,3 +255,34 @@ int
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================//
|
||||
// WAVE 4 -- compile-time layout locks. PowerWatcher is Torso-proven at 0x1D8,
|
||||
// so the own fields land at their EXACT binary offsets; sizeof is bounded to
|
||||
// the factory alloc. (BtAlarm is a 4-byte stand-in for the binary's 0x54
|
||||
// GaugeAlarm -- immaterial: nothing reads Searchlight at a raw offset past its
|
||||
// own fields, and the shared BT_LOCAL_ALARM_SHIM stays 4 bytes because
|
||||
// thermalsight.hpp shares that guard.)
|
||||
//===========================================================================//
|
||||
struct SearchlightLayoutCheck
|
||||
{
|
||||
static_assert(offsetof(Searchlight, lightState) == 0x1D8, "Searchlight lightState @0x1D8 (PowerWatcher ends 0x1D8)");
|
||||
static_assert(offsetof(Searchlight, commandedOn) == 0x1DC, "Searchlight commandedOn @0x1DC (res+0x28)");
|
||||
static_assert(offsetof(Searchlight, requestedOn) == 0x1E0, "Searchlight requestedOn @0x1E0");
|
||||
static_assert(offsetof(Searchlight, stateAlarm) == 0x1E4, "Searchlight stateAlarm @0x1E4 (proves base ends 0x1D8)");
|
||||
static_assert(sizeof(Searchlight) <= 0x238, "sizeof(Searchlight) must fit the factory Memory::Allocate(0x238)");
|
||||
};
|
||||
|
||||
|
||||
//===========================================================================//
|
||||
// WAVE 4 factory bridge -- Searchlight (factory case 0xBD8, "LegSubsystem" label).
|
||||
// The real class at 0xBD8 (ctor @004b84dc) is Searchlight; the factory built a
|
||||
// LegSubsystem RECON_SUBSYS stub. No cache write; not a weapon (raw
|
||||
// part_012.c:10166-10175 stores roster-only).
|
||||
//===========================================================================//
|
||||
Subsystem *CreateSearchlightSubsystem(Mech *owner, int id, void *seg)
|
||||
{
|
||||
return (Subsystem *) new (Memory::Allocate(0x238))
|
||||
Searchlight(owner, id, (Searchlight::SubsystemResource *)seg, Searchlight::DefaultData);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user