vehicleSubSystems Phase 2: authentic aux-screen assignment -> panels build
The engineering-screen cluster panels now build for each subsystem on its real aux-screen position. Two pieces: 1. Aux-screen bridge (powersub.cpp BTGetSubsystemAuxScreen): the assignment lives on PoweredSubsystem (auxScreenNumber/Placement/Label, resource +0x104/108/10C) which our ctor already populates -- but the reconstructed heat-leaf branch is NOT byte-exact, so the Make's raw sub[0x1dc]/[0x1e0]/[0x1e4] reads were garbage (0xCDCDCDCD). The bridge casts through the real PoweredSubsystem type + returns the NAMED fields (and is the FUN_0041a1a4/0x50f4bc type filter). Make + Subsystem Cluster now read via the bridge. 2. Reconstruct the 4 child gauges the clusters build that were declared-but-undefined (only VertTwoPartBar/OneOfSeveral/PixInt existed): HorizTwoPartBar (full, mirrors Vert), OneOfSeveralInt (ctor), OneOfSeveralStates (ctor + BecameActive + State Connection @004c3324), BitMapInverseWipe/LeakGauge (full) + SeekVoltageGraph's Execute/BecameActive/dtor -- their /FORCE-stubbed ctors were segfaulting when a cluster built them. VERIFIED (BT_DEV_GAUGES + BT_VSS_LOG): 7 authentic panels build -- Sensor(scr5, qsensors) HeatSinkCluster, Myomers(scr6,qmyomers) MyomerCluster, PPC(scr1,10) + Emitter(scr4,8,7) Energy/Ballistic clusters -- with real labels + placements, 0 crashes, combat un-regressed. 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
a02339112a
commit
6fceb58439
@@ -132,6 +132,16 @@ static void *AttributePointerOf(void *subsystem, const char *name)
|
||||
//
|
||||
static void *ResolveLink(void *plug) { (void)plug; return 0; }
|
||||
|
||||
//
|
||||
// Bridge (defined in powersub.cpp) that reads the engineering-screen assignment
|
||||
// off the real PoweredSubsystem type (auxScreenNumber/Placement/Label) -- the
|
||||
// reconstructed heat-leaf branch is not byte-exact, so the raw sub+0x1dc/0x1e0/
|
||||
// 0x1e4 offsets read garbage; the named fields (populated by the PoweredSubsystem
|
||||
// ctor from the resource) are correct. Returns False for non-PoweredSubsystem-
|
||||
// derived subsystems (== the vehicleSubSystems type filter).
|
||||
//
|
||||
extern bool BTGetSubsystemAuxScreen(Subsystem *sub, int *screen, int *placement, char *label64);
|
||||
|
||||
//
|
||||
// FUN_0041bf44 -- fetch the subsystem linked at slot N (used by the cooling-loop
|
||||
// lamp to find its cooling master). Stubbed to match ResolveLink above.
|
||||
@@ -277,10 +287,44 @@ SeekVoltageGraph::SeekVoltageGraph(
|
||||
|
||||
//
|
||||
// @004c68ac -- dtor. Release the destroyed bitmap, GraphicGauge::~GraphicGauge.
|
||||
//
|
||||
SeekVoltageGraph::~SeekVoltageGraph()
|
||||
{
|
||||
L4Warehouse *warehouse = (L4Warehouse *)renderer->warehousePointer;
|
||||
warehouse->bitMapBin.Release(destroyedImage);
|
||||
}
|
||||
|
||||
Logical SeekVoltageGraph::TestInstance() const
|
||||
{
|
||||
return GraphicGauge::TestInstance();
|
||||
}
|
||||
|
||||
//
|
||||
// @004c6920 -- BecameActive: previousVoltage = 9999.0f (force first redraw).
|
||||
//
|
||||
// @004c6934 -- Execute. If the subsystem is destroyed (subsys+0x40 == 1) draw
|
||||
void SeekVoltageGraph::BecameActive()
|
||||
{
|
||||
previousVoltage = RedrawSentinel; // @0xAC force first redraw
|
||||
destroyedShown = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// @004c6934 -- Execute (the seek-voltage curve plot). BRING-UP: the full plot
|
||||
// (SetupClip/DrawTicks/DrawCursor over a 0..1 voltage polyline) needs the live
|
||||
// seek-voltage sampler (subsys vtbl+0x3c) + the four attribute indices; the
|
||||
// attribute resolve is summarised (FindAttributeIndex returns -1), so the plot is
|
||||
// deferred and Execute is inert until the sampler + attribute reads land. Kept as
|
||||
// a defined no-op so the gauge's vtable is complete (no /FORCE crash when the
|
||||
// Myomer/Energy cluster ticks its SeekVoltageGraph child).
|
||||
//
|
||||
void SeekVoltageGraph::Execute()
|
||||
{
|
||||
// (seek-voltage plot deferred -- see note above.)
|
||||
}
|
||||
|
||||
//
|
||||
// @004c6934 (original notes preserved) -- Execute. If the subsystem is destroyed
|
||||
// (subsys+0x40 == 1) draw
|
||||
// the centred "destroyed" bitmap once. Otherwise, when the live seek voltage
|
||||
// (subsys vtbl+0x3c sampler) changes: clear (SetupClip @004c6be4), re-plot the
|
||||
// 0..1 voltage curve as a polyline (step _DAT_004c6bdc up to _DAT_004c6be0,
|
||||
@@ -751,8 +795,10 @@ SubsystemCluster::SubsystemCluster(
|
||||
mfd_port, x + 0x10e, y + 0xe, "btpbus.pcc", 5, 1,
|
||||
inputVoltage, "PowerSource");
|
||||
|
||||
// Background: image_names[ subsystem damageZoneIndex@0x1e0 ] if present.
|
||||
int dzIndex = *(int *)((char *)subsystem_in + 0x1e0); // BEST-EFFORT raw offset
|
||||
// Background: image_names[ auxScreenPlacement ] if present. (Placement@0x1e0 is
|
||||
// read via the PoweredSubsystem bridge, not the non-byte-exact raw offset.)
|
||||
int dzIndex = -1;
|
||||
BTGetSubsystemAuxScreen(subsystem_in, NULL, &dzIndex, NULL); // auxScreenPlacement
|
||||
background = NULL;
|
||||
if (dzIndex >= 0 && image_names[dzIndex] != NULL)
|
||||
background = new BackgroundBitmap(mfd_mode, renderer_in, owner_ID, // @00471d00
|
||||
@@ -814,8 +860,9 @@ SubsystemCluster::SubsystemCluster(
|
||||
(Scalar *)linkTemp, (Scalar *)linkDegrade, (Scalar *)failTemp, "VertTwoPartBar");
|
||||
|
||||
leakGauge = new BitMapInverseWipe(ChildRate(), eng_mode, renderer_in, // @004c5b7c
|
||||
engPort, 0x255, 0xe0, "eleak.pcc", 0, 0xff, 3,
|
||||
*(int *)((char *)subsystem_in + 0x150), (Scalar *)coolantLeak, "LeakGauge"); // BEST-EFFORT raw
|
||||
engPort, 0x255, 0xe0, "eleak.pcc", 0, 0xff,
|
||||
*(int *)((char *)subsystem_in + 0x150) /*third*/, 3 /*frames*/,
|
||||
(Scalar *)coolantLeak, "LeakGauge"); // BEST-EFFORT raw (subsys+0x150)
|
||||
|
||||
operating = False; // @0xC4 this[0x31]
|
||||
subsystem = subsystem_in; // @0xC0 this[0x30]
|
||||
@@ -1380,13 +1427,19 @@ Logical
|
||||
Subsystem *sub = entity->GetSubsystem(i); // entity+0x128[i]
|
||||
if (sub == NULL)
|
||||
continue;
|
||||
if (!SubsystemDisplayFilter(sub)) // FUN_0041a1a4
|
||||
|
||||
// Read the engineering-screen assignment via the PoweredSubsystem bridge
|
||||
// (also the type filter -- False == not PoweredSubsystem-derived).
|
||||
int auxScreen = 0, placement = -1;
|
||||
char labelBuf[64];
|
||||
if (!BTGetSubsystemAuxScreen(sub, &auxScreen, &placement, labelBuf)) // FUN_0041a1a4 + sub[0x1dc]/[0x1e4]
|
||||
continue;
|
||||
|
||||
int group = *(int *)((char *)sub + 0x1dc) - 1; // aux-screen position 1..12
|
||||
int group = auxScreen - 1; // aux-screen position 1..12
|
||||
if (getenv("BT_VSS_LOG"))
|
||||
DEBUG_STREAM << "[vss] i=" << i << " classID=" << (int)sub->GetClassID()
|
||||
<< " auxScreen[0x1dc]=" << (group + 1) << "\n" << std::flush;
|
||||
<< " auxScreen=" << auxScreen << " placement=" << placement
|
||||
<< " label='" << labelBuf << "'\n" << std::flush;
|
||||
if (group < 0)
|
||||
{
|
||||
DebugStream << "Auxiliary screen position = zero\n";
|
||||
@@ -1400,7 +1453,7 @@ Logical
|
||||
|
||||
const AuxScreenGeometry &g = kAuxGeom[group];
|
||||
int mfdPort = renderer->FindGraphicsPort((char *)g.mfdPortName); // FUN_00447f1c
|
||||
char *label = (char *)((char *)sub + 0x1e4); // the subsystem label
|
||||
char *label = labelBuf; // the subsystem label (bridge)
|
||||
char *tile = (char *)"btwarn.pcc";
|
||||
|
||||
switch (sub->GetClassID()) // sub+4
|
||||
|
||||
Reference in New Issue
Block a user