Gauges: convert generator-voltage bar to named-member bridge

The eng-page generator-voltage bar (evolt.pcc, ScalarBarGauge @004c721c) and
the MyomerCluster seek-voltage graph were fed by GeneratorVoltageConnection,
which walked the same dead path as the generator-letter lamp:
ResolveLink(AttributePointerOf(subsystem,"InputVoltage")) -> read resolved
+0x1DC == Generator::outputVoltage. The BT_DEV_GAUGES audio attribute rows
shifted the chained attribute ids so AttributePointerOf no longer lands on
voltageSource@0x1D0 -> the bar always read 0.

New BTGeneratorVoltage(subsystem) bridge (powersub.cpp) reads the NAMED member
via PoweredSubsystem::ResolveVoltageSource()->Generator::MeasuredVoltage()
(outputVoltage@0x1DC), bypassing the attribute table -- same pattern as
BTPowerSourceFrame/BTCoolingLoopFrame. Both GeneratorVoltageConnection callers
(the ScalarBarGauge param + the MyomerCluster seekValue) now pass subsystem_in.

[voltfeed]-verified: Myomers -> 10000V from GeneratorD (was 0 on the dead
path). Both pod + glass builds clean. Eng-page render awaiting live playtest.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-21 00:21:41 -05:00
co-authored by Claude Opus 4.8
parent 8c7ff639de
commit f2eaf3d0ac
3 changed files with 63 additions and 12 deletions
+17 -9
View File
@@ -233,9 +233,18 @@ protected:
//
// GeneratorVoltageConnection -- @004c3288 ctor / @004c32f4 sampler (vt 0x518e90).
// Resolves the voltage source and copies its output voltage (+0x1dc); 0 if
// unresolved. Drives ScalarBarGauge / SeekVoltageGraph value slots.
// The binary resolves the subsystem's InputVoltage link and copies its output
// voltage (resolved+0x1DC == Generator::outputVoltage); 0 if unresolved. Drives
// the eng-page generator-voltage bar (ScalarBarGauge) + the MyomerCluster
// seek-voltage graph.
// DATABINDING FIX 2026-07-21 (gotcha 8, sibling of the PowerSource/CoolingLoop
// fixes): the ResolveLink(AttributePointerOf(subsystem,"InputVoltage")) path is
// dead after the BT_DEV_GAUGES audio attribute rows shifted the chained ids, so
// the bar always read 0. 'source' now carries the SUBSYSTEM and
// BTGeneratorVoltage (powersub.cpp) reads the NAMED member via
// ResolveVoltageSource()->MeasuredVoltage(), bypassing the attribute table.
//
extern Scalar BTGeneratorVoltage(void *subsystem);
class GeneratorVoltageConnection : public GaugeConnection
{
public:
@@ -243,9 +252,7 @@ public:
: GaugeConnection(0), source(source), destination(destination) {}
void Update() // @004c32f4
{
void *resolved = ResolveLink(source);
*destination = (resolved == 0) ? 0.0f
: *(Scalar *)((char *)resolved + 0x1dc);
*destination = BTGeneratorVoltage(source);
}
protected:
void *source; // @0x10
@@ -1466,8 +1473,8 @@ SubsystemCluster::SubsystemCluster(
generatorVoltageBar = new ScalarBarGauge(ChildRate(), eng_mode, renderer_in, // @004c721c
engPort, 0x89, 0x82, 0x93, 0x13b, "evolt.pcc", 0xff, 0,
WipeGaugeScalar::wipeUp, 0.0f, GeneratorMaxVoltage, inputVoltage,
"GeneratorVoltage(slotOf)");
WipeGaugeScalar::wipeUp, 0.0f, GeneratorMaxVoltage, subsystem_in, // pass the SUBSYSTEM
"GeneratorVoltage(slotOf)"); // -> BTGeneratorVoltage reads voltage by name (attr-shift fix)
// stateLamp only when the subsystem is a Generator (IsDerivedFrom 0x50f4bc).
if (IsGeneratorDerived(subsystem_in))
@@ -1738,8 +1745,9 @@ MyomerCluster::MyomerCluster(
// INFERRED (the MyomerCluster ctor @004c8df4 isn't in the assert-anchored export).
(int *)((char *)subsystem_in + 0x320), "OneOfSeveralInt");
void *inputVoltage = AttributePointerOf(subsystem_in, "InputVoltage");
AddConnection(new GeneratorVoltageConnection(&seekValue, inputVoltage)); // @004c3288
// Pass the SUBSYSTEM -- BTGeneratorVoltage resolves voltageSource by name
// (the attribute-table shift makes AttributePointerOf("InputVoltage") dead).
AddConnection(new GeneratorVoltageConnection(&seekValue, subsystem_in)); // @004c3288
}
MyomerCluster::~MyomerCluster()