Searchlight reconstruction -- the pod's night kit, both halves
The subsystem (sim/toggle/attribute/replication) was already complete; this lands the missing VISUALS, decoded from MakeMechRenderables @004cef28 case 0xbd8 (raw pseudocode part_014): - COCKPIT: the 1995 searchlight is a FOG SWAP -- the @00456778/@00456814 watcher switches DPLRenderer::SetFogStyle between the authored fog= (lit) and nosearchlightfog= (dark) sets per map/time page in BTDPL.INI. The engine kept the whole system under its real names; completed the stubbed plane application (currentFogNear/Far) and transcribed the watcher (with its inverted-cache seed) into TickSearchlight. CONSEQUENCE: night now STARTS on the authentic dark set (near-plane 5u on arena pages) -- our builds had rendered the searchlight-ON fog permanently. - EXTERNAL: spot.bgf beam cone hung on the searchlight SITE joint, shown/ hidden from the replicated LightOn attribute (@0045612c watcher). Site segments now build geometry-less DCS children (posed + parentable, as the 1995 graph did) -- previously they were skipped entirely. - searchlight.hpp: commandedOn @0x1DC identified as mountSegment (resource segmentIndex; the cone's mount joint). Benches: searchfog.sh (solo cockpit: first-tick dark sync, F5/0x14 press -> SetFogStyle(2), red-fog probe end-to-end), spotcone.sh (2-node: B's button -> lightState replication -> A logs "[spot] cone SHOWN (seg 20)"). Cone look (size/aim on the mount) pending an eyeball pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
b31c6c4527
commit
412053d5af
@@ -82,7 +82,7 @@ Searchlight::SharedData
|
||||
//
|
||||
// Chains to the PowerWatcher ctor (FUN_004b18a4) with &DAT_00511198, installs
|
||||
// the Searchlight vtable (PTR_FUN_005114d4), builds the 2-level state
|
||||
// AlarmIndicator (@0x1E4) and seeds commandedOn from the segment field
|
||||
// AlarmIndicator (@0x1E4) and seeds mountSegment from the segment field
|
||||
// (+0x28). When this is a live (non-copy) segment with the has-performance
|
||||
// flag set it registers SearchlightSimulation (this[7..9] <- PTR_FUN_00511200);
|
||||
// otherwise it marks the instance "no per-frame performance" (flag bit 2).
|
||||
@@ -103,7 +103,7 @@ Searchlight::Searchlight(
|
||||
lightState = 0; // @0x1D8
|
||||
requestedOn = 0; // @0x1E0
|
||||
stateAlarm.Initialize(2); // FUN_0041b9ec(this+0x1E4, 2)
|
||||
commandedOn = subsystem_resource->segmentIndex; // @0x1DC <- inherited resource +0x28
|
||||
mountSegment = subsystem_resource->segmentIndex; // @0x1DC <- inherited resource +0x28 (the spot-cone mount joint)
|
||||
|
||||
// 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
|
||||
@@ -311,8 +311,8 @@ void
|
||||
if (!announced)
|
||||
{
|
||||
announced = 1;
|
||||
DEBUG_STREAM << "[light] SearchlightSimulation RUNNING (commandedOn "
|
||||
<< commandedOn << ", requestedOn " << requestedOn
|
||||
DEBUG_STREAM << "[light] SearchlightSimulation RUNNING (mountSegment "
|
||||
<< mountSegment << ", requestedOn " << requestedOn
|
||||
<< ", lightState " << lightState << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
@@ -323,7 +323,7 @@ void
|
||||
|
||||
if (getenv("BT_FIRE_LOG") || getenv("BT_HEAT_LOG"))
|
||||
DEBUG_STREAM << "[light] reported lightState " << previous << " -> " << lightState
|
||||
<< " (commandedOn " << commandedOn << ", requestedOn " << requestedOn << ")"
|
||||
<< " (mountSegment " << mountSegment << ", requestedOn " << requestedOn << ")"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
@@ -405,7 +405,7 @@ int
|
||||
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, mountSegment) == 0x1DC, "Searchlight mountSegment @0x1DC (res+0x28 segmentIndex)");
|
||||
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)");
|
||||
@@ -423,3 +423,39 @@ Subsystem *CreateSearchlightSubsystem(Mech *owner, int id, void *seg)
|
||||
return (Subsystem *) new (Memory::Allocate(0x238))
|
||||
Searchlight(owner, id, (Searchlight::SubsystemResource *)seg, Searchlight::DefaultData);
|
||||
}
|
||||
|
||||
//===========================================================================//
|
||||
// Video-layer probe (2026-08-05, the spot-cone/fog reconstruction). The 1995
|
||||
// MakeMechRenderables walk (@004cef28) hits `case 0xbd8` per roster subsystem
|
||||
// and pulls the "LightOn" attribute + the mount joint; our port's tree builder
|
||||
// does not walk the roster, so btl4vid calls this bridge instead (complete-
|
||||
// Searchlight TU, per the databinding rule). Returns the number of
|
||||
// searchlights found (0..2 reported -- the binary's cockpit branch keeps TWO
|
||||
// attr slots, @004cef28 local_118/local_11c; more than 2 exist on no chassis).
|
||||
//===========================================================================//
|
||||
int BTMechSearchlightProbe(
|
||||
void *mech_v,
|
||||
int **light_on_out, // [2] "LightOn" attribute pointers (int*)
|
||||
int *mount_seg_out) // [2] mount segment slots (resource segmentIndex)
|
||||
{
|
||||
Mech *mech = (Mech *)mech_v;
|
||||
if (mech == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int found = 0;
|
||||
for (int i = 0; i < mech->GetSubsystemCount() && found < 2; ++i)
|
||||
{
|
||||
Subsystem *sub = mech->GetSubsystem(i);
|
||||
if (sub == 0
|
||||
|| (int)sub->GetClassID() != (int)RegisteredClass::SearchlightClassID) // 0xBD8
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Searchlight *light = (Searchlight *)sub;
|
||||
light_on_out[found] = light->LightOnPointer(); // == GetAttributePointer("LightOn")
|
||||
mount_seg_out[found] = light->MountSegmentIndex(); // @0x1DC (res+0x28 segmentIndex)
|
||||
++found;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user