diff --git a/game/reconstructed/btl4gaug.cpp b/game/reconstructed/btl4gaug.cpp index 993a781..18384eb 100644 --- a/game/reconstructed/btl4gaug.cpp +++ b/game/reconstructed/btl4gaug.cpp @@ -1552,13 +1552,149 @@ void // segmentSpan = (int)( (float)(|n|/(|n|-1)) * 0.75f ) // _DAT_004c62d4 // Deleting-dtor thunk @004c66b3 -> FUN_00474094 (arc base dtor). // -// @004c62fc Make / @004c6394 ctor (vtable PTR_FUN_0051898c) -- SegmentArcRatio: -// derives from the second MUNGA L4 arc primitive (FUN_00473f44) and adds TWO -// GaugeConnectionDirectOf feeds (numerator @0x30, denominator @0x31, -// FUN_00474855 x2); precomputes segmentSpan with _DAT_004c6484 (0.75f). -// Make @004c62fc allocates 0xcc and supplies the arc geometry resources -// (DAT_00517eb0..00518158) and the name "SegmentArcRatio". -// Deleting-dtor thunk @004c668d -> FUN_00474094. +//########################################################################### +// SegmentArcRatio @004c62fc Make / @004c6394 ctor / @004c6488 Execute +// (vtable PTR_FUN_0051898c; base = engine SegmentArc) // +// A segmented arc dial (config keyword "segmentArcRatio"). Two Scalar +// connections drive it -- numerator (value) and denominator (max) -- and Execute +// lights numerator/denominator of the arc. Used for the cockpit SPEED arc +// (config binds numerator=LinearSpeed, denominator=MaxRunSpeed), so the arc +// sweeps as the mech accelerates. Unlike VertTwoPartBar, the drawing is +// inherited from the engine SegmentArc base -- this class only computes the +// [0,1] fill fraction into the base's currentValue, then delegates the render. +//########################################################################### + +MethodDescription + SegmentArcRatio::methodDescription = + { + "segmentArcRatio", + SegmentArcRatio::Make, + { + // + // CFG shape (L4GAUGE.CFG:4964): + // segmentArcRatio( rate, mode, inner,outer, deg0,deg1, segs, + // bg,fg, valueAttr, maxAttr ) + // e.g. segmentArcRatio(C,ModeAlwaysActive,32,39,0,360,36,0,2, + // LinearSpeed, MaxRunSpeed); + // + { ParameterDescription::typeRate, NULL }, // rate ID + { ParameterDescription::typeModeMask, NULL }, // mode mask + { ParameterDescription::typeScalar, NULL }, // inner radius + { ParameterDescription::typeScalar, NULL }, // outer radius + { ParameterDescription::typeScalar, NULL }, // start angle (deg) + { ParameterDescription::typeScalar, NULL }, // end angle (deg) + { ParameterDescription::typeInteger, NULL }, // segment count (+dir) + { ParameterDescription::typeColor, NULL }, // background colour + { ParameterDescription::typeColor, NULL }, // foreground colour + { ParameterDescription::typeAttribute, NULL }, // numerator (value) + { ParameterDescription::typeAttribute, NULL }, // denominator (max) + PARAMETER_DESCRIPTION_END + } + }; + +// +// @004c62fc -- Make. Allocate + construct; no resource to verify (returns True). +// +Logical + SegmentArcRatio::Make( + int display_port_index, + Vector2DOf position, + Entity * /*entity -- unused*/, + GaugeRenderer *gauge_renderer + ) +{ + ParameterDescription *p = methodDescription.parameterList; + + SegmentArcRatio *gauge = (SegmentArcRatio *)operator new(0xcc); // FUN_00402298(0xcc) + if (gauge != NULL) + { + new (gauge) SegmentArcRatio( // FUN_004c6394 + p[0].data.rate, p[1].data.modeMask, + (L4GaugeRenderer *)gauge_renderer, + display_port_index, // graphics_port_number + position.x, position.y, // centre + p[2].data.scalar, p[3].data.scalar, // inner, outer radius + p[4].data.scalar, p[5].data.scalar, // start, end angle + p[6].data.integer, // segment count (+dir) + p[7].data.color, p[8].data.color, // bg, fg + (Scalar *)p[9].data.attributePointer, // numerator source + (Scalar *)p[10].data.attributePointer, // denominator source + "SegmentArcRatio"); + } + return True; // binary returns 1 unconditionally +} + +// +// @004c6394 -- ctor. Engine SegmentArc base (inner0==inner1, outer0==outer1 -- +// the Make duplicates them, so the arc has a constant radius); precompute the +// span factor and wire the two Scalar connections. +// +SegmentArcRatio::SegmentArcRatio( + GaugeRate rate, + ModeMask mode_mask, + L4GaugeRenderer *renderer_in, + int graphics_port_number, + int center_x, + int center_y, + Scalar inner, + Scalar outer, + Scalar deg0, + Scalar deg1, + int number_of_segs, + int background_color, + int foreground_color, + Scalar *numerator_pointer, + Scalar *denominator_pointer, + const char *identification_string +): + SegmentArc(rate, mode_mask, renderer_in, 0, // FUN_00473f44 (owner_ID 0) + graphics_port_number, center_x, center_y, + inner, outer, inner, outer, // inner0/outer0 == inner1/outer1 + deg0, deg1, number_of_segs, + background_color, foreground_color, + True, // use_thick_lines (binary param_20 = 1) + identification_string) +{ + // segmentSpan = (Scalar)(|n| / (|n|-1)) * 0.75f -- |n|/(|n|-1) is INTEGER + // division (== 1 for n>=2), so this is 0.75 for the 36-segment speed arc. + int n = (number_of_segs < 0) ? -number_of_segs : number_of_segs; // @0xC8 + segmentSpan = (Scalar)(n / (n - 1)) * 0.75f; // _DAT_004c6484 = 0.75f + + AddConnection(new GaugeConnectionDirectOf(0, &numerator, numerator_pointer)); // @0xC0 + AddConnection(new GaugeConnectionDirectOf(0, &denominator, denominator_pointer)); // @0xC4 +} + +// +// @004c668d -- deleting-dtor thunk. Connections + arc base are released by the +// implicit base-dtor chain (FUN_00474094); no own teardown. +// +SegmentArcRatio::~SegmentArcRatio() +{ +} + +// +// @004c6488 -- Execute. currentValue = clamp(|numerator/denominator * span|,0,1); +// then delegate to the engine SegmentArc::Execute (0x474300) which lights that +// fraction of the segments. (x87 recovered by disassembly: FUN_004dcd00 = fabs.) +// +void + SegmentArcRatio::Execute() +{ + if (denominator < 1.0f) // guard div-by-tiny / unpowered + { + currentValue = 0.0f; + } + else + { + currentValue = numerator / denominator * segmentSpan; + if (currentValue < 0.0f) currentValue = -currentValue; // FUN_004dcd00 = fabs + if (currentValue < 0.0f) + currentValue = 0.0f; + else if (currentValue > 1.0f) + currentValue = 1.0f; + } + SegmentArc::Execute(); // 0x474300 -- the base draw +} // === btl4gau2.cpp begins at @004c6798 (SeekVoltage gauge) -- not part of this TU. diff --git a/game/reconstructed/btl4gaug.hpp b/game/reconstructed/btl4gaug.hpp index 0b8ece0..b9a6809 100644 --- a/game/reconstructed/btl4gaug.hpp +++ b/game/reconstructed/btl4gaug.hpp @@ -518,16 +518,28 @@ }; class SegmentArcRatio : - public SegmentArc // MUNGA L4 base (FUN_00473f44; engine class SegmentArc) + public SegmentArc // MUNGA L4 base (engine SegmentArc, L4GAUGE.cpp:4827) { public: + // Registered in BTL4MethodDescription[] (btl4grnd.cpp) as "segmentArcRatio". + static MethodDescription methodDescription; + static Logical Make(int, Vector2DOf, Entity *, GaugeRenderer *); // @004c62fc - SegmentArcRatio(/* ...arc geometry... */); // @004c6394 + SegmentArcRatio( // @004c6394 + GaugeRate, ModeMask, L4GaugeRenderer *, int graphics_port_number, + int center_x, int center_y, + Scalar inner, Scalar outer, Scalar deg0, Scalar deg1, + int number_of_segs, int background_color, int foreground_color, + Scalar *numerator_pointer, Scalar *denominator_pointer, + const char *identification_string); ~SegmentArcRatio(); // dtor thunk @004c668d + + void Execute(); // @004c6488 (ratio -> currentValue -> SegmentArc::Execute) + protected: Scalar numerator; // @0xC0 this[0x30] (connection) Scalar denominator; // @0xC4 this[0x31] (connection) - int segmentSpan; // @0xC8 this[0x32] + Scalar segmentSpan; // @0xC8 this[0x32] (float, read by Execute) }; #endif diff --git a/game/reconstructed/btl4grnd.cpp b/game/reconstructed/btl4grnd.cpp index a0b3117..19cb447 100644 --- a/game/reconstructed/btl4grnd.cpp +++ b/game/reconstructed/btl4grnd.cpp @@ -135,6 +135,7 @@ MethodDescription &ColorMapperMultiArmor::methodDescription, // "colorMapperMultiArmor" -- worst-of-8-zones tint &ColorMapperCritical::methodDescription, // "cmCrit" -- subsystem-critical-state tint &VertTwoPartBar::methodDescription, // "vertBar" -- vertical fill bar (coolant/heat) + &SegmentArcRatio::methodDescription, // "segmentArcRatio" -- segmented arc dial (speed) &BTL4ChainToPrevious };