BallisticWeaponCluster's two round counters pointed at UnboundIntegerSource because ProjectileWeapon::ammoBinLink is protected -- the documented inert gap in the ctor ledger. ProjectileWeapon now exposes GetAmmoCount() (the resolved bin's rounds, -1 with no bin) and the cluster copies it into a live cell each Execute, the same pattern it already uses for jammed and reloadSeconds. The binary pointed its NumericDisplayInteger straight at the resolved bin's count. The STREAK 6 panel now reads 0024 against the shipped binary's 0024, in the same font, stencilled into the fire-ready disc the same way. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
581 lines
28 KiB
C++
581 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:
|
|
//
|
|
// The live ammo cell the two round counters point at. The binary
|
|
// pointed them at the resolved AmmoBin's count; the link is
|
|
// protected, so Execute copies it here each frame -- the same
|
|
// pattern this cluster already uses for jammed / reloadSeconds.
|
|
//
|
|
int ammoRounds;
|
|
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
|