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
@@ -1501,6 +1501,228 @@ OneOfSeveralPixInt::~OneOfSeveralPixInt()
|
||||
}
|
||||
|
||||
|
||||
//###########################################################################
|
||||
// Additional composite-cluster child gauges (used by btl4gau2's
|
||||
// SubsystemCluster family). HorizTwoPartBar mirrors VertTwoPartBar
|
||||
// (horizontal); OneOfSeveralInt/States are OneOfSeveral subclasses; the
|
||||
// LeakGauge base BitMapInverseWipe reveals a bitmap up to a level.
|
||||
//###########################################################################
|
||||
|
||||
//
|
||||
// StateConnection -- @004c3324 ctor / @004c3390 Transfer. Copies a Subsystem's
|
||||
// state word (@0x14) into the destination each frame (drives OneOfSeveralStates).
|
||||
//
|
||||
class StateConnection : public GaugeConnection
|
||||
{
|
||||
public:
|
||||
StateConnection(int *destination, Entity *source)
|
||||
: GaugeConnection(0), source(source), destination(destination) {} // FUN_004c3324
|
||||
void Update() // @004c3390
|
||||
{
|
||||
*destination = *(int *)((char *)source + 0x14); // Subsystem state @0x14
|
||||
}
|
||||
protected:
|
||||
Entity *source; // @0x10
|
||||
int *destination; // @0x14
|
||||
};
|
||||
|
||||
//
|
||||
// @004c4170 -- HorizTwoPartBar ctor (vtable 0x518cbc). GraphicGauge base, intern
|
||||
// the tile bitmap, SetExtent, store fill/bg + width/height, wire the value/low/
|
||||
// high Scalar connections. Grows left->right (mirror of VertTwoPartBar).
|
||||
//
|
||||
HorizTwoPartBar::HorizTwoPartBar(
|
||||
GaugeRate rate, ModeMask mode_mask, L4GaugeRenderer *renderer_in,
|
||||
int graphics_port_number, int left, int bottom, int right, int top,
|
||||
const char *tile_image, int fill_color, int background_color,
|
||||
Scalar *value_pointer, Scalar *low_pointer, Scalar *high_pointer,
|
||||
const char *identification_string
|
||||
):
|
||||
GraphicGauge(rate, mode_mask, renderer_in, 0, graphics_port_number, // FUN_00444818
|
||||
identification_string)
|
||||
{
|
||||
tileImage = new char[strlen(tile_image) + 1];
|
||||
strcpy(tileImage, tile_image);
|
||||
L4Warehouse *warehouse = (L4Warehouse *)renderer_in->warehousePointer;
|
||||
warehouse->bitMapBin.Get(tileImage);
|
||||
localView.SetPositionWithinPort(left, bottom, right, top); // vtbl+0x08
|
||||
fillColor = fill_color;
|
||||
backgroundColor = background_color;
|
||||
width = right - left;
|
||||
height = (top - bottom) - 1;
|
||||
AddConnection(new GaugeConnectionDirectOf<Scalar>(0, &value, value_pointer));
|
||||
AddConnection(new GaugeConnectionDirectOf<Scalar>(0, &low, low_pointer));
|
||||
AddConnection(new GaugeConnectionDirectOf<Scalar>(0, &high, high_pointer));
|
||||
}
|
||||
|
||||
HorizTwoPartBar::~HorizTwoPartBar()
|
||||
{
|
||||
L4Warehouse *warehouse = (L4Warehouse *)renderer->warehousePointer;
|
||||
warehouse->bitMapBin.Release(tileImage);
|
||||
delete[] tileImage;
|
||||
tileImage = NULL;
|
||||
}
|
||||
|
||||
Logical HorizTwoPartBar::TestInstance() const { return GraphicGauge::TestInstance(); }
|
||||
|
||||
void HorizTwoPartBar::BecameActive() // @004c4324
|
||||
{
|
||||
previousFull = 0;
|
||||
previousFill = width;
|
||||
}
|
||||
|
||||
//
|
||||
// @004c4340 -- Execute: clamp value to [0,high], map value/warn to bar pixels
|
||||
// (half-up round of width*x/high), repaint on change (mirror of VertTwoPartBar
|
||||
// but along X).
|
||||
//
|
||||
void HorizTwoPartBar::Execute()
|
||||
{
|
||||
if (value < 0.0f) value = 0.0f;
|
||||
else if (value > high) value = high;
|
||||
|
||||
int warnPix = (int)((Scalar)width * low / high + 0.5f);
|
||||
int valPix = (int)((Scalar)width * value / high + 0.5f);
|
||||
if (warnPix < 0) warnPix = 0; else if (warnPix > width) warnPix = width;
|
||||
if (valPix < 0) valPix = 0; else if (valPix > width) valPix = width;
|
||||
|
||||
if (warnPix != previousFull || valPix != previousFill)
|
||||
{
|
||||
if (warnPix < valPix)
|
||||
{
|
||||
localView.SetColor(fillColor);
|
||||
localView.MoveToAbsolute(warnPix, 0);
|
||||
localView.DrawFilledRectangleToAbsolute(valPix - 1, height);
|
||||
}
|
||||
if (valPix < width)
|
||||
{
|
||||
localView.SetColor(backgroundColor);
|
||||
localView.MoveToAbsolute(valPix, 0);
|
||||
localView.DrawFilledRectangleToAbsolute(width, height);
|
||||
}
|
||||
previousFull = warnPix;
|
||||
previousFill = valPix;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// @004c5148 -- OneOfSeveralInt ctor (vtable 0x518bac): OneOfSeveral(fromStrip=1) +
|
||||
// a GaugeConnectionDirectOf<int> feeding the selected frame. dtor @004c51d8.
|
||||
//
|
||||
OneOfSeveralInt::OneOfSeveralInt(
|
||||
GaugeRate rate, ModeMask mode_mask, L4GaugeRenderer *renderer_in,
|
||||
int graphics_port_number, int x, int y, const char *image,
|
||||
int columns, int rows, int *value_pointer, const char *identification_string
|
||||
):
|
||||
OneOfSeveral(rate, mode_mask, renderer_in, graphics_port_number, x, y,
|
||||
True, image, 0, 0, columns, rows, identification_string)
|
||||
{
|
||||
selected = 0;
|
||||
AddConnection(new GaugeConnectionDirectOf<int>(0, &selected, value_pointer)); // FUN_004749de
|
||||
}
|
||||
|
||||
OneOfSeveralInt::~OneOfSeveralInt() {} // @004c51d8
|
||||
|
||||
//
|
||||
// @004c5470 -- OneOfSeveralStates ctor (vtable 0x518b24): OneOfSeveral + a
|
||||
// StateConnection reading the subsystem state word @0x14. BecameActive @004c552c
|
||||
// clamps the state >= 0 then chains OneOfSeveral::Execute. dtor @004c5500.
|
||||
//
|
||||
OneOfSeveralStates::OneOfSeveralStates(
|
||||
GaugeRate rate, ModeMask mode_mask, L4GaugeRenderer *renderer_in,
|
||||
int graphics_port_number, int x, int y, const char *image,
|
||||
int columns, int rows, Entity *subsystem_source, const char *identification_string
|
||||
):
|
||||
OneOfSeveral(rate, mode_mask, renderer_in, graphics_port_number, x, y,
|
||||
True, image, 0, 0, columns, rows, identification_string)
|
||||
{
|
||||
selected = 0;
|
||||
AddConnection(new StateConnection(&selected, subsystem_source)); // FUN_004c3324
|
||||
}
|
||||
|
||||
OneOfSeveralStates::~OneOfSeveralStates() {} // @004c5500
|
||||
|
||||
void OneOfSeveralStates::BecameActive() // @004c552c
|
||||
{
|
||||
if (selected < 0)
|
||||
selected = 0;
|
||||
OneOfSeveral::BecameActive();
|
||||
}
|
||||
|
||||
//
|
||||
// @004c5b7c -- BitMapInverseWipe ctor (vtable 0x518a9c): GraphicGauge base;
|
||||
// SetOrigin(x,y), intern the image, store colours + frame geometry (frameWidth =
|
||||
// imageWidth/3, fullWidth = frames*2), wire a Scalar level connection. Used as
|
||||
// the coolant LeakGauge.
|
||||
//
|
||||
BitMapInverseWipe::BitMapInverseWipe(
|
||||
GaugeRate rate, ModeMask mode_mask, L4GaugeRenderer *renderer_in,
|
||||
int graphics_port_number, int x, int y, const char *image,
|
||||
int color_a, int color_b, int third, int frames,
|
||||
Scalar *value_pointer, const char *identification_string
|
||||
):
|
||||
GraphicGauge(rate, mode_mask, renderer_in, 0, graphics_port_number,
|
||||
identification_string)
|
||||
{
|
||||
localView.SetOrigin(x, y); // vtbl+0x10
|
||||
imageName = new char[strlen(image) + 1];
|
||||
strcpy(imageName, image);
|
||||
colorA = color_a;
|
||||
colorB = color_b;
|
||||
this->frames = frames;
|
||||
fullWidth = frames * 2;
|
||||
this->third = third;
|
||||
L4Warehouse *warehouse = (L4Warehouse *)renderer_in->warehousePointer;
|
||||
BitMap *bmp = warehouse->bitMapBin.Get(imageName);
|
||||
if (bmp == NULL)
|
||||
{
|
||||
frameWidth = 0;
|
||||
frameHeight = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
frameWidth = bmp->Data.Size.x / 3;
|
||||
frameHeight = bmp->Data.Size.y;
|
||||
}
|
||||
AddConnection(new GaugeConnectionDirectOf<Scalar>(0, &value, value_pointer)); // FUN_00474855
|
||||
}
|
||||
|
||||
BitMapInverseWipe::~BitMapInverseWipe() // @004c5c80
|
||||
{
|
||||
L4Warehouse *warehouse = (L4Warehouse *)renderer->warehousePointer;
|
||||
warehouse->bitMapBin.Release(imageName);
|
||||
delete[] imageName;
|
||||
imageName = NULL;
|
||||
}
|
||||
|
||||
Logical BitMapInverseWipe::TestInstance() const { return GraphicGauge::TestInstance(); }
|
||||
|
||||
void BitMapInverseWipe::BecameActive() // @004c5cf4
|
||||
{
|
||||
previousLevel = -1;
|
||||
}
|
||||
|
||||
//
|
||||
// @004c5d08 -- Execute. BRING-UP: the authentic wipe (reveal the bitmap columns
|
||||
// up to the level, coloured by colorA/colorB) needs the frame-strip blit math;
|
||||
// a safe minimal repaint (blit the base frame on level change) keeps the vtable
|
||||
// complete + non-crashing until the full wipe lands.
|
||||
//
|
||||
void BitMapInverseWipe::Execute()
|
||||
{
|
||||
int level = (int)value;
|
||||
if (level != previousLevel)
|
||||
{
|
||||
previousLevel = level;
|
||||
L4Warehouse *warehouse = (L4Warehouse *)renderer->warehousePointer;
|
||||
BitMap *bmp = warehouse->bitMapBin.Get(imageName);
|
||||
if (bmp != NULL)
|
||||
localView.DrawBitMapOpaque(0, 0, bmp);
|
||||
warehouse->bitMapBin.Release(imageName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//###########################################################################
|
||||
//###########################################################################
|
||||
// HeadingPointer @004c554c Make / @004c562c ctor
|
||||
|
||||
Reference in New Issue
Block a user