Files
TeslaRel410/restoration/source410/BT_L4/BTL4GAU2.HPP
T
CydandClaude Fable 5 42ff5c3856 BT410 Phase 5.3.29: the panel titles -- 94.8% identical to the shipped cockpit
Reading the art settled where the titles live: qsensors/qmyomers/qermlas/
qppc/qstrk6.pcc are 299x26 TITLE BANNERS, while the qblh0..7.pcc strings
the cfg hands vehicleSubSystems are 77x120 MECH ICONS (already lit by the
5.3.28 placement fix).  So the authored auxScreenLabel IS the panel title
-- it just belongs on the MFD panel, not only the ENG page.

SubsystemCluster now builds a titleBanner child from the cached label.
Placement was MEASURED against the shipped framebuffer through the A/B rig
(BackgroundBitmap places by left/BOTTOM): a bring-up BT_TITLE_DY knob, then
a green-pixel correlation over the title band, then baked at x+0x09,
y+0xb3 from the panel origin.  "SENSOR CLUSTER", "MYOMERS", "TYPE II 65
TONS" and both "ERMED LASER RANGE 500M" banners now render where the
shipped binary puts them.

Score progression vs the shipped cockpit on identical GAUGE content:
  5.3.26 birth            90.1% identical / 82% coverage
  5.3.28 authored screens 93.2% / 85%
  5.3.29 titles tuned     94.8% / 91%

Also: grab.ps1 now focuses the target window before capturing -- the
screen-copy grabbed whatever was in front, which cost two junk captures
(a white frame and an unrelated 3-D app window).

Gauge fight 11/11 rounds and smoke both clean, zero faults.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 23:09:15 -05:00

574 lines
28 KiB
C++

//===========================================================================//
// File: btl4gau2.hpp //
// Project: BattleTech Brick: Gauge Renderer Manager //
// Contents: Cockpit instrument library, part 2 -- the COMPOSITE "panel" //
// gauges that the BattleTech engineering / weapon-status HUD is //
// assembled from. Where btl4gaug.cpp holds the primitive widgets //
// (bars, dials, lamps, colour-mappers), btl4gau2.cpp holds the //
// higher-level gauges that AGGREGATE those primitives into a single //
// subsystem read-out: //
// * SeekVoltageGraph -- energy-weapon seek-voltage curve //
// * ConfigMapGauge -- joystick / config-manager state lamp //
// * GeneratorCluster -- generator voltage + coolant + leak panel //
// * PrepEngrScreen -- per-weapon engineering screen builder //
// * SubsystemCluster +-> HeatSinkCluster //
// +-> MyomerCluster //
// +-> WeaponCluster +-> EnergyWeaponCluster //
// +-> BallisticWeaponClu.//
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 02/22/96 CPB Initial coding. //
//---------------------------------------------------------------------------//
// Copyright (C) 1996, Virtual World Entertainment, Inc. All rights reserved //
// PROPRIETARY AND CONFIDENTIAL //
//===========================================================================//
//
// STAGED RECONSTRUCTION. No BTL4GAU2.HPP survived; recovered from the shipped
// binary (BTL4OPT.EXE) and re-hosted onto the authentic 1995 engine headers
// (MUNGA GAUGE/GAUGREND + MUNGA_L4 L4GAUGE) for the BC++4.52 build.
//
// Translation-unit extent (BTL4.MAK link order:
// btl4mode -> btl4rdr -> btl4gaug -> btl4gau2 -> btl4gau3 -> btl4grnd -> ...):
// first gau2 code @004c6798 (SeekVoltageGraph::SeekVoltageGraph)
// last gau2 code @004c9b50 (BallisticWeaponCluster helpers)
// plus VehicleSubSystems::Make @004cbaf0
//
// Class names recovered from the CODE name-string pool around 0x519760
// (the gauge name list) and the per-instance identification strings:
// "GeneratorCluster" 0x519a8c "PrepEngr" 0x519a9d
// "ConfigMap" 0x519a38 "CoolingLoop" 0x519a42 "PowerSource" 0x519a4e
// "GeneratorVoltage(scalar)" 0x519a73 "GeneratorVoltage(slotOf)" 0x519a5a
// "EngrGraph" 0x519a2e "WeaponCluster ... " 0x519dcb
// Field offsets in comments are the BINARY's byte offsets (e.g. "@0x90" ==
// this[0x24]); the recompiled objects are NOT byte-locked to them.
//
// Names flagged "(best-effort)" exist in the binary but their identification
// string could not be tied to them unambiguously.
//
#if !defined(BTL4GAU2_HPP)
# define BTL4GAU2_HPP
# if !defined(SLOT_HPP)
# include <slot.hpp>
# endif
# if !defined(L4GREND_HPP)
# include <l4grend.hpp>
# endif
# if !defined(L4GAUGE_HPP)
# include <l4gauge.hpp>
# endif
# if !defined(BTL4GAUG_HPP)
# include <btl4gaug.hpp>
# endif
# if !defined(HEAT_HPP)
# include <heat.hpp>
# endif
// (see btl4gaug.hpp -- <powersub.hpp> intentionally not pulled in; the
// composite gauges reference subsystems by pointer/attribute, not by type.)
//
// Reconstruction type: the original referenced an "AttributeAccessor" handle
// (a small object that samples one named subsystem attribute). Only its
// address is used here (it is immediately reinterpreted as a Scalar*), so an
// opaque forward declaration is sufficient for this translation unit.
//
class AttributeAccessor;
//#######################################################################
// SeekVoltageGraph -- the energy-weapon / myomer "seek voltage" response
// graph on the engineering detail pages (the "POWER" box).
// @004c6798 ctor / @004c68ac dtor / @004c6920 BecameActive / @004c6934 Execute.
// vtable PTR_FUN_0051a1fc. Resolves the four SeekVoltage attribute
// POINTERS off the weapon subsystem by NAME ("CurrentSeekVoltageIndex" /
// "MinSeekVoltageIndex" / "MaxSeekVoltageIndex" / "SeekVoltage") and plots
// the subsystem's voltage-response curve (binary vtbl slot 15 sampler:
// Emitter @004bb42c / Myomers @004b8f94) over the top data box
// (0x97,0x80)-(0x17d,0x13b): x = response(v)*230 (0..1 normalised sqrt
// response), y = v/12000*187 (voltage axis), with per-gear tick marks (the
// current gear drawn as a full L) and, when draw_cursor, a live 8x8 XOR
// cursor at the subsystem's live voltage. When the subsystem is destroyed
// (simulationState == 1) it shows a centred "destroyed" bitmap instead.
// Its Execute's full-box CLEAR (@004c6be4) is what erases the sibling eng
// pages' stale pixels on the shared Eng bit-plane -- the widget IS the
// top-box eraser (Gitea #10 finding A).
//#######################################################################
class SeekVoltageGraph :
public GraphicGauge
{
public:
SeekVoltageGraph( // @004c6798
GaugeRate rate, ModeMask mode_mask, L4GaugeRenderer *renderer,
int graphics_port_number, Entity *subsystem,
AttributeAccessor *seek_voltage_pointer,
const char *destroyed_image, Logical draw_cursor,
const char *identification_string);
~SeekVoltageGraph(); // @004c68ac
Logical TestInstance() const;
void BecameActive(); // @004c6920
void Execute(); // @004c6934
protected:
void ClearGraph(); // @004c6be4 (full-box erase)
void DrawTicks(); // @004c6c6c (per-gear ticks, XOR)
void DrawCursorBox(); // @004c6c30 (8x8 cursor, XOR)
char *destroyedImage; // @0x90 this[0x24]
int *currentSeekIndexPtr; // @0x94 this[0x25] attr ptr (or NULL)
int *minSeekIndexPtr; // @0x98 this[0x26] attr ptr (or NULL)
int *maxSeekIndexPtr; // @0x9C this[0x27] attr ptr (or NULL)
Scalar *seekVoltageTablePtr; // @0xA0 this[0x28] attr ptr (array base)
Scalar *liveVoltage; // @0xA4 this[0x29] the ctor's
// seek_voltage_pointer ("OutputVoltage"
// attr ptr / cluster seekValue cache) --
// Execute derefs it for the live cursor
// (never NULL: ctor normalises a miss to
// the file-scope unbound cell)
Subsystem *subsystem; // @0xA8 this[0x2A]
Scalar previousVoltage; // @0xAC this[0x2B] cached response at
// 12000 V (9999 sentinel = force replot)
Scalar xScale; // @0xB0 this[0x2C] =230.0f
Scalar yScale; // @0xB4 this[0x2D] =187.0f
int destroyedShown; // @0xB8 this[0x2E]
Logical drawCursor; // @0xBC this[0x2F]
int cursorX; // @0xC0 this[0x30] (-1 = no cursor drawn)
int cursorY; // @0xC4 this[0x31]
int tickIndexShown; // @0xC8 this[0x32] gear index the tick
// highlight was last drawn at
};
//#######################################################################
// ConfigMapGauge -- the joystick / config-manager (control-mapper) state
// lamp. @004c6d80 ctor / @004c6e54 dtor / @004c6ee0 LinkToEntity /
// @004c6ef4 BecameActive / @004c6f1c Execute. vtable PTR_FUN_0051a1b8.
// Owns a base joystick bitmap ("btjoy.pcc") plus four config-state pixmaps
// (cm_off/cm_other/cm_only/cm_both .pcc) selected from a 4-entry table
// (DAT_00518eb8) driven by the control-mapper state. Named "ConfigMap".
//#######################################################################
class ConfigMapGauge :
public GraphicGauge
{
public:
ConfigMapGauge( // @004c6d80
GaugeRate, ModeMask, L4GaugeRenderer *, int graphics_port_number,
int x, int y, Entity *subsystem, const char *identification_string);
~ConfigMapGauge(); // @004c6e54
Logical TestInstance() const;
// @004c6ee0 -- the GaugeBase::LinkToEntity OVERRIDE (vtbl slot 9, +0x24),
// NOT a "SetColor": it stores the viewpoint entity into @0x94 and Execute
// gates on it. GaugeRenderer::LinkToEntity (GAUGREND.CPP:3011) broadcasts
// it to every gauge when the viewpoint binds -- THAT is what lights the
// trigger-config joystick in the shipped game. (The old "SetColor, no
// callers -> authentically dormant" claim was a mislabel.)
void LinkToEntity(Entity *entity); // @004c6ee0 writes this[0x25]
void BecameActive(); // @004c6ef4
void Execute(); // @004c6f1c
protected:
Entity *subsystem; // @0x90 this[0x24] (a Subsystem, stored
// as the ctor's Entity* -- cast back
// through Subsystem* before use)
Entity *linkedEntity; // @0x94 this[0x25] (Execute gate)
char *joystickImage; // @0x98 this[0x26] "btjoy.pcc"
char *stateImage[4]; // @0x9C this[0x27..0x2A]
int previousState[4]; // @0xAC this[0x2B..0x2E]
Logical dirty; // @0xBC this[0x2F]
};
//#######################################################################
// Two small OneOfSeveral subclasses that drive the selected frame from a
// subsystem value through a file-private GaugeConnection.
// AnimatedSubsystemLamp @004c70a4 (vtable 0051a174) -- connection @004c3134
// AnimatedSourceLamp @004c7160 (vtable 0051a130) -- connection @004c31ec
// Both chain OneOfSeveral::OneOfSeveral (@004c4d88, fromImageStrip=1) and
// share dtor FUN_004c4e7c. Used for the cooling-loop / power-source lamps.
// (Class names best-effort; the gauge is generic and reused with the
// instance strings "CoolingLoop" and "PowerSource".)
//
// SHADOW-FIELD FIX (kept on re-host): 'selected' is INHERITED from
// OneOfSeveral (@0xAC). A redeclared 'int selected;' here shadowed the
// base at a higher offset -- the connection wrote the shadow while
// OneOfSeveral::Execute read the base (always 0), freezing the lamp at
// frame 0. Neither class declares its own copy.
//#######################################################################
class AnimatedSubsystemLamp : // (best-effort)
public OneOfSeveral
{
public:
AnimatedSubsystemLamp( // @004c70a4
GaugeRate, ModeMask, L4GaugeRenderer *, int,
int x, int y, const char *image, int columns, int rows,
void *subsystem, const char *identification_string);
~AnimatedSubsystemLamp(); // @004c7134
};
class AnimatedSourceLamp : // (best-effort)
public OneOfSeveral
{
public:
AnimatedSourceLamp( // @004c7160
GaugeRate, ModeMask, L4GaugeRenderer *, int,
int x, int y, const char *image, int columns, int rows,
void *source, const char *identification_string);
~AnimatedSourceLamp(); // @004c71f0
};
//#######################################################################
// ScalarBarGauge -- a generator-voltage bar (derives from the engine
// BarGraphBitMapScalar, L4GAUGE.HPP -- WipeGaugeScalar : GraphicGauge).
// Two ctors, one vtable (0051a0e4), shared dtor @004c733c:
// @004c721c "slotOf" variant -- AddConnection(GeneratorVoltageConnection
// @004c3288) feeding the inherited currentValue from the
// subsystem's resolved voltage source.
// @004c72ac plain-Scalar variant -- a GaugeConnectionDirectOf<Scalar>
// (engine template) from a DIRECT Scalar*.
// Used with "GeneratorVoltage(slotOf)" / "GeneratorVoltage(scalar)".
//
// Its value slot @0xB4 (this[0x2D]) IS the inherited
// WipeGaugeScalar::currentValue -- the connection writes it, so NO own
// field is declared (declaring one would shadow / mis-align).
//
// BC++4.52 NOTE: the void* / Scalar* 15th-argument overload pair is
// ambiguous for a literal 0/NULL argument -- every call site must pass a
// TYPED pointer.
//#######################################################################
class ScalarBarGauge :
public BarGraphBitMapScalar
{
public:
ScalarBarGauge( // @004c721c (slotOf variant)
GaugeRate, ModeMask, L4GaugeRenderer *, int graphics_port_number,
int left, int bottom, int right, int top,
const char *tile_image, int foreground_color, int background_color,
WipeGaugeScalar::Direction direction, Scalar min, Scalar max,
void *voltage_source, const char *identification_string);
ScalarBarGauge( // @004c72ac (plain-Scalar variant)
GaugeRate, ModeMask, L4GaugeRenderer *, int graphics_port_number,
int left, int bottom, int right, int top,
const char *tile_image, int foreground_color, int background_color,
WipeGaugeScalar::Direction direction, Scalar min, Scalar max,
Scalar *value_source, const char *identification_string);
~ScalarBarGauge(); // @004c733c
};
//#######################################################################
// GeneratorCluster -- the generator read-out panel (config keyword
// "GeneratorCluster": engineering buttons 9-12, GeneratorA..D).
// @004c7368 Make / @004c746c ctor / @004c7778 dtor. vtable PTR_FUN_0051a0a0.
// A GraphicGauge that owns five child gauges, parented to its own port:
// VertTwoPartBar (temperature) this[0x26]
// ScalarBarGauge (voltage 0..12kV) this[0x27]
// BitMapInverseWipe/Leak (coolant leak) this[0x28]
// TwoState x2 (status lamps) this[0x29],this[0x2A]
// Make resolves the named generator via FindSubsystem; warns
// "Subsystem <name> not found".
//#######################################################################
class GeneratorCluster :
public GraphicGauge
{
public:
// Registered config primitive "GeneratorCluster" (15 params; NO leading
// rate token -- the panel rate is hard-wired 0xFFFF).
static MethodDescription methodDescription;
static Logical Make(int, Vector2DOf<int>, Entity *, GaugeRenderer *); // @004c7368
GeneratorCluster( // @004c746c (BINARY param order)
ModeMask, L4GaugeRenderer *, int owner_ID, int graphics_port_number,
int x, int y, Subsystem *subsystem,
const char *background_image, int extra_color,
const char *temp_tile, int temp_bg_color, int temp_fill_color,
const char *voltage_tile, int voltage_fg_color,
const char *leak_image, int leak_color_b,
const char *lampA_image, const char *lampB_image,
int lamp_on_color, int lamp_off_color,
const char *identification_string);
~GeneratorCluster(); // @004c7778
// A container panel MUST override BecameActive + Execute: the engine
// base Gauge::Execute is Fail("not overridden") (GAUGE.CPP:598), and
// the default BecameActive self-inactivates. The panel draws its
// static background pixmap; the 5 self-registered child gauges draw
// the dynamic content.
void BecameActive();
void Execute();
protected:
char *backgroundImage; // @0x90 this[0x24] interned .pcc (AddRef'd)
int secondaryColor; // @0x94 this[0x25] = leak colorB (stored, unread)
GraphicGauge
*temperatureBar, // @0x98 this[0x26] VertTwoPartBar
*voltageBar, // @0x9C this[0x27] ScalarBarGauge (@004c72ac variant)
*leakGauge, // @0xA0 this[0x28] BitMapInverseWipe
*lampA, // @0xA4 this[0x29] TwoState
*lampB; // @0xA8 this[0x2A] TwoState
Subsystem *subsystem; // @0xAC this[0x2B]
int _reserved0xB0; // @0xB0 this[0x2C] (trailing pad -> binary sizeof 0xB4)
};
//#######################################################################
// PrepEngrScreen (config keyword "prepEngr") -- the per-engineering-screen
// STATIC LABEL overlay. @004c7b30 Make / @004c7bf0 ctor / @004c7d14 dtor /
// @004c7e48 BecameActive. vtable PTR_FUN_0051a06c.
//
// A GraphicGaugeBackground (paint-on-activation, NOT an Execute gauge --
// the same base/vtable shape as the engine's BackgroundBitmap: only the
// dtor + BecameActive slots are overridden). Interns 7 status .pcc's
// (font + 6 labels) and, when its MFD-Eng screen (1..12) activates, paints
// the labels for the ONE subsystem whose aux screen == this screen,
// dispatched by the subsystem's ClassID.
// (FIX kept from the decode: mech/screenNumber were SWAPPED in the first
// reconstruction, and the missing methodDescription parse-skipped all 12
// CFG lines.)
//#######################################################################
class PrepEngrScreen :
public GraphicGaugeBackground
{
public:
static MethodDescription methodDescription; // "prepEngr"
static Logical Make(int, Vector2DOf<int>, Entity *, GaugeRenderer *); // @004c7b30
PrepEngrScreen( // @004c7bf0
ModeMask, L4GaugeRenderer *, unsigned int owner_ID,
int graphics_port_number, Entity *mech, int screen_number,
const char *img0/*font*/, const char *img1, const char *img2,
const char *img3, const char *img4, const char *img5,
const char *img6, const char *identification_string = "PrepEngr");
~PrepEngrScreen(); // @004c7d14
void BecameActive(); // @004c7e48 (the paint slot -- NOT Execute)
protected:
int screenNumber; // @0x6C this[0x1B]
Entity *mech; // @0x70 this[0x1C]
char *statusImage[7]; // @0x74 this[0x1D..0x23] (interned .pcc names)
// binary sizeof == 0x90 (Make alloc); no offset locks (every read is
// via named members).
};
//#######################################################################
// SubsystemCluster family -- the big composite panels. Each is a
// GraphicGauge that builds a dozen child gauges into one cockpit instrument.
//
// SubsystemCluster @004c8140 (vtable 0051a020) -- base "engineering"
// panel: HorizTwoPartBar + cooling/power loops + generator voltage +
// OneOfSeveralInt + OneOfSeveralStates + 2x VertTwoPartBar + LeakGauge
// + BackgroundBitmap. Uses the btXXloop / btXbus / evolt / btecmode /
// eleak art.
//
// HeatSinkCluster @004c8a6c (vtable 00519fd4) : SubsystemCluster
// adds 4 failure-annunciator TwoStates (btehfail/btepfail/btesfail)
// and a NumericDisplayScalar. Execute @004c8db0 scales heatLoad by
// 100 (_DAT_004c8df0) into the numeric read-out.
//
// MyomerCluster @004c8df4 (vtable 00519f88) : SubsystemCluster
// adds a SeekVoltageGraph ("EngrGraph") + seek-step OneOfSeveralInt.
//
// WeaponCluster @004c8fc4 (vtable 00519f38) : SubsystemCluster
// adds a SegmentArc270 (recharge dial, 0..360) + a ConfigMapGauge.
// Reads "PercentDone". Execute @004c9290 toggles the warning lamp
// past _DAT_004c92e0 (0.99).
//
// EnergyWeaponCluster @004c93b0 (vtable 00519ee8) : WeaponCluster
// adds a SeekVoltageGraph ("EngrGraph", edestryd.pcc) and a
// seek-step OneOfSeveralInt (bteseek.pcc).
// BallisticWeaponCluster @004c9558 (vtable 00519e98) : WeaponCluster
// adds 2x NumericDisplayInteger (ammo), jam/fire TwoStates
// (btejam/btefire), NumericDisplayScalarTwoState, an eject
// BitMapInverseWipeScalar (bteejtm), plus a GraphicsViewRecord
// erase tracker (this[0x3F]).
//#######################################################################
class SubsystemCluster :
public GraphicGauge
{
public:
// @004c8140. Binary param order (rate/mode are hardcoded 0xFFFF /
// ModeAlwaysActive in the base GraphicGauge ctor; the panel's two
// bit-plane MODE masks are mfd_mode (MFD-port children) and eng_mode
// (engineering-port children)).
SubsystemCluster( // @004c8140
ModeMask mfd_mode, L4GaugeRenderer *renderer, int owner_ID,
int mfd_port, int x, int y, Subsystem *subsystem, ModeMask eng_mode,
const char *eng_port_name, const char *tile_image,
const char *label, char **image_names,
const char *identification_string);
~SubsystemCluster(); // @004c87dc
Logical TestInstance() const;
void BecameActive(); // (re-host addition: forces the first repaint)
void Execute(); // @004c88e4
protected:
BackgroundBitmap
*background;
BackgroundBitmap *titleBanner; // the authored 299x26 panel title // @0x90 this[0x24] BackgroundBitmap
GraphicGauge
*generatorVoltageBar, // @0x94 this[0x25] ScalarBarGauge (evolt)
*temperatureBar, // @0x98 this[0x26] HorizTwoPartBar
*coolingLoopA, // @0x9C this[0x27] AnimatedSubsystemLamp
*coolingLoopB, // @0xA0 this[0x28]
*powerSourceA, // @0xA4 this[0x29] AnimatedSourceLamp
*powerSourceB, // @0xA8 this[0x2A]
*vertBarA, // @0xAC this[0x2B] VertTwoPartBar
*vertBarB, // @0xB0 this[0x2C]
*modeLamp, // @0xB4 this[0x2D] OneOfSeveralInt
*stateLamp, // @0xB8 this[0x2E] OneOfSeveralStates
*leakGauge; // @0xBC this[0x2F] LeakGauge
Subsystem *subsystem; // @0xC0 this[0x30]
// POLARITY CORRECTED (PPC-dial fix, kept on re-host): the binary's
// *(subsystem+0x40)==1 means the subsystem FAILED -- it lights the
// destroyed-X TwoStates (the engine TwoState draws bright on NONZERO)
// and selects the dead-panel look (GetDrawState 1 = black fill). The
// old name `operating` had it backwards, inverting every consumer.
Logical failedState; // @0xC4 this[0x31] 1 = subsystem destroyed
int previousDrawState; // @0xC8 this[0x32] (Execute repaint key)
// internal helpers (non-virtual)
void DrawPanelFrame(int color); // @004c89c4
void ReleaseChildren(); // @004c8820
void SetChildrenEnable(int enable); // @004c8a28
public:
int GetDrawState(); // @004c8990 (operational-state virtual, vtbl+0x48)
};
class HeatSinkCluster : // @004c8a6c
public SubsystemCluster
{
public:
HeatSinkCluster( // @004c8a6c
ModeMask mfd_mode, L4GaugeRenderer *, int owner_ID, int mfd_port,
int x, int y, Subsystem *subsystem, Subsystem *hud, ModeMask eng_mode,
const char *eng_port_name, const char *tile_image, const char *label,
const char *fail_lamp_image, char **image_names,
const char *identification_string);
~HeatSinkCluster(); // @004c8d18
void Execute(); // @004c8db0
protected:
Subsystem *failSubsystem; // @0xCC this[0x33]
Logical failFlag; // @0xD0 this[0x34]
Scalar heatLoad; // @0xD4 this[0x35] (connection dst)
Scalar heatLoadScaled; // @0xD8 this[0x36]
GraphicGauge
*heatFailLamp, // @0xDC this[0x37] TwoState
*hsFailLamp, // @0xE0 this[0x38] TwoState (btehfail)
*powerFailLamp, // @0xE4 this[0x39] TwoState (btepfail)
*structFailLamp, // @0xE8 this[0x3A] TwoState (btesfail)
*heatNumeric; // @0xEC this[0x3B] NumericDisplayScalar
};
//
// MyomerCluster @004c8df4 (vtable 00519f88) : SubsystemCluster -- the myomer
// (muscle) panel. Adds a SeekVoltageGraph ("EngrGraph", edestryd.pcc) fed
// by a GeneratorVoltageConnection (writes seekValue) + a seek-step
// OneOfSeveralInt (bteseek.pcc). Execute = base.
//
class MyomerCluster : // @004c8df4
public SubsystemCluster
{
public:
MyomerCluster( // @004c8df4
ModeMask mfd_mode, L4GaugeRenderer *, int owner_ID, int mfd_port,
int x, int y, Subsystem *subsystem, ModeMask eng_mode,
const char *eng_port_name, const char *tile_image, const char *label,
char **image_names, const char *identification_string);
~MyomerCluster(); // @004c8f54
protected:
Scalar seekValue; // @0xCC this[0x33] (connection dst)
GraphicGauge
*seekGraph, // @0xD0 this[0x34] SeekVoltageGraph
*seekStepLamp; // @0xD4 this[0x35] OneOfSeveralInt
};
class WeaponCluster : // @004c8fc4
public SubsystemCluster
{
public:
WeaponCluster( // @004c8fc4
ModeMask mfd_mode, L4GaugeRenderer *, int owner_ID, int mfd_port,
int x, int y, Subsystem *subsystem, ModeMask eng_mode,
const char *eng_port_name, const char *tile_image, const char *label,
const char *cluster_image, char **image_names,
const char *identification_string);
~WeaponCluster(); // @004c91d4
void BecameActive(); // @004c9258
void Execute(); // @004c9290
virtual void DrawWarningLamp(int on); // @004c932c (virtual: BallisticWeaponCluster overrides)
protected:
char *clusterImage; // @0xCC this[0x33] (interned)
GraphicGauge *rechargeArc; // @0xD0 this[0x34] SegmentArc270
ConfigMapGauge *configMap; // @0xD4 this[0x35]
Scalar percentDone; // @0xD8 this[0x36] (connection dst)
int warningCenterX; // @0xDC this[0x37]
int warningCenterY; // @0xE0 this[0x38]
int warningState; // @0xE4 this[0x39]
};
class EnergyWeaponCluster : // @004c93b0
public WeaponCluster
{
public:
EnergyWeaponCluster( // @004c93b0
ModeMask mfd_mode, L4GaugeRenderer *, int owner_ID, int mfd_port,
int x, int y, Subsystem *subsystem, ModeMask eng_mode,
const char *eng_port_name, const char *tile_image, const char *label,
const char *cluster_image, char **image_names,
const char *identification_string);
~EnergyWeaponCluster(); // @004c94dc
protected:
SeekVoltageGraph *seekGraph; // @0xE8 this[0x3A]
GraphicGauge *seekStepLamp; // @0xEC this[0x3B] OneOfSeveralInt
};
class BallisticWeaponCluster : // @004c9558
public WeaponCluster
{
public:
BallisticWeaponCluster( // @004c9558
ModeMask mfd_mode, L4GaugeRenderer *, int owner_ID, int mfd_port,
int x, int y, Subsystem *subsystem, ModeMask eng_mode,
const char *eng_port_name, const char *tile_image, const char *label,
const char *cluster_image, char **image_names,
const char *font_a, const char *font_b,
const char *identification_string);
~BallisticWeaponCluster(); // @004c9940
void BecameActive(); // @004c99cc
void Execute(); // @004c9a38
void DrawWarningLamp(int on); // @004c9b50 (override: dot + ammo colour swap)
Logical TestInstance() const; // @004c9adc
protected:
Logical jammed; // @0xE8 this[0x3A]
Logical firing; // @0xEC this[0x3B]
Logical reloading; // @0xF0 this[0x3C]
int reloadStartTime; // @0xF4 this[0x3D]
Scalar reloadSeconds; // @0xF8 this[0x3E]
GraphicsViewRecord
*ammoErase; // @0xFC this[0x3F] (bring-up NULL)
GraphicGauge
*ammoNumeric, // @0x100 this[0x40] NumericDisplayScalarTwoState
*destroyedLamp, // @0x104 this[0x41] TwoState
*jamLamp, // @0x108 this[0x42] TwoState (btejam)
*fireLamp, // @0x10C this[0x43] TwoState (btefire)
*ejectWipe, // @0x110 this[0x44] BitMapInverseWipeScalar (NULL)
*ammoCountA, // @0x114 this[0x45] NumericDisplayInteger
*ammoCountB; // @0x118 this[0x46] NumericDisplayInteger
};
//#######################################################################
// vehicleSubSystems -- the config primitive that builds the engineering-
// screen (MFD) subsystem cluster panels. Make @004cbaf0 (methodDescription
// @0x51c080, 8 typeString params = the 8 status strip bitmaps) is a per-
// subsystem factory: it walks the mech roster (skipping slot 0), and for
// each displayable subsystem builds the right cluster (HeatSink/Myomer/
// Energy/Ballistic) onto one of 12 auxiliary MFD positions. This holder
// just carries the registered MethodDescription + the static Make
// dispatcher (there is no instance).
//#######################################################################
class VehicleSubSystems
{
public:
static MethodDescription methodDescription;
static Logical Make( // @004cbaf0
int display_port_index, Vector2DOf<int> position,
Entity *entity, GaugeRenderer *gauge_renderer);
};
#endif