The MadCat torso twists, the view turns with it, and targeting follows. Three reconstruction fronts closed: THE ELECTRICAL WATCHDOG CHAIN (why the torso never powered up): - PowerWatcher::UpdateWatch reconstructed (@004b181c, the REAL registered Performance -- PTR @0050f5fc; Ghidra missed the fn start): the watchdog MIRRORS the watched subsystem's electrical level (+0x278), brownout downgrade when gen output <= minVoltage% x rated. @004b1804 relabeled ResetToInitialState (slot 10) -- the old "Simulation" tag was wrong. - The factory watcher-CONNECT pass reconstructed (vtable slot +0x38, @004aee2c/@004b1a40 byte-identical, recovered from raw exe bytes): watchedLink.Add(roster[watchedSubsystem]) on the master node. Was the SubProxy::Start() no-op -- every watchdog sat at 0 forever. - MinVoltageScale = 0.01 (a 10-byte x87 literal @0x4b1924; was 1.0f = permanent brownout) and PowerWatcher's Derivation chains its REAL base HeatWatcher (the HeatableSubsystem stand-in broke IsDerivedFrom for the whole Torso/Searchlight/ThermalSight family). - KB correction swept: derivation tag 0x50e604 = HEATWATCHER (not "HeatSink"); the btl4gaug heat-widget gate now tests it via the BTIsHeatWatcher bridge. THE CROSSHAIR (task #58 forensics, 6-agent workflow + live probes): - The VIEW is TORSO-MOUNTED: jointtorso -> jointeye -> siteeyepoint in every twist-capable .SKL; the camera + canopy ride the same hinge subtree through HingeRenderable's live matrix-stack compose -- ALREADY WORKING in the port. The crosshair stays screen-centered (center IS the boresight); the twist reads on the tape carets/compass/radar. - The real bug was the port's gBTAimX = tan(twist) slew (the falsified "body-mounted view" model): the camera already carried the twist, so the crosshair counter-slid to hull-forward and the fire ray with it. Deleted; the pick ray inherits the twist from the yawing eye basis. - Two instrumentation traps documented (chase-eye-as-default-camera, BT_FORCE_TORSO clobbering real joints -> the hook now only fills unresolved ones); an over-correcting explicit eye compose was added on those false readings and retired the same day. CONTROLS + REPLICATION: - Q/E spring-center on release (the axis is a twist-RATE demand; the old hold-deflection model drifted forever); X also zeroes the axis and pulses the authentic torso Recenter (@004b6918). M cycles control mode via the real CycleControlMode body. - Torso update-record DIRECTION fixed: engine truth is Write=serialize / Read=apply; @004b6a78 is the READ (was mislabeled Write) and the missing WRITE @004b6a1c recovered from raw disasm (recordLength 0x1C, twist/vel/rate at +0x10/14/18) -- kills the replicant's 0xCDCDCDCD -140-degree ghost twist. - Marching-ghost desync: 4 Standing-case guards zero stale reverse cycleSpeed (negative cadence passed the <= ZeroSpeed stop gate). - Kill credit rerouted to the OBSERVED killer (lastInflictingID -> killer's player link) -- kills count, target K/D populates. KB: subsystems.md (watcher chain), multiplayer.md (record direction), combat-damage.md + gauges-hud.md + cockpit-view.md (torso-mounted view re-correction), decomp-reference.md (new addresses + tag fix), open-questions.md (dead capability-roster loops 2-4, snapshot CD read). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
582 lines
24 KiB
C++
582 lines
24 KiB
C++
//===========================================================================//
|
|
// File: btl4gaug.hpp //
|
|
// Project: BattleTech Brick: Gauge Renderer Manager //
|
|
// Contents: The cockpit instrument gauge library -- the family of small //
|
|
// "widget" gauges that the BattleTech HUD is assembled from: //
|
|
// * ColorMapper* -- palette-animating tint gauges driven by //
|
|
// subsystem state (heat / armour / crit) //
|
|
// * Horiz/VertTwoPartBar, VertNormalSlider //
|
|
// -- two-colour fill bars (throttle / damage) //
|
|
// * OneOfSeveral* -- multi-frame bitmap selectors (state lamp) //
|
|
// * HeadingPointer -- rotating numeric heading readout //
|
|
// * SegmentArc270/Ratio-- arc / dial style gauges //
|
|
// * BitMap wipe gauges -- bitmap "fuel / leak" wipe indicators //
|
|
//---------------------------------------------------------------------------//
|
|
// Date Who Modification //
|
|
// -------- --- ---------------------------------------------------------- //
|
|
// 02/22/96 CPB Initial coding. //
|
|
//---------------------------------------------------------------------------//
|
|
// Copyright (C) 1996, Virtual World Entertainment, Inc. All rights reserved //
|
|
// PROPRIETARY AND CONFIDENTIAL //
|
|
//===========================================================================//
|
|
//
|
|
// RECONSTRUCTED. No BTL4GAUG.HPP survived (the BT_L4 source tree retains only
|
|
// BTL4RDR.HPP and BTL4GALM.HPP). This declaration is recovered from the
|
|
// shipped binary (BTL4OPT.EXE); the Ghidra pseudo-C is in
|
|
// recovered/all/part_013.c (@004c2f94..@004c5e84)
|
|
// recovered/all/part_014.c (@004c5e84..@004c6394)
|
|
// The module is the .obj that links immediately after btl4rdr.obj and before
|
|
// btl4gau2.obj (see BTL4.MAK), so it owns the contiguous code run
|
|
// [ @004c2f94 .. @004c6771 ] (btl4gau2.cpp begins at @004c6798).
|
|
//
|
|
// The sole address with a surviving embedded assert path -- the anchor --
|
|
// is ColorMapperHeat's constructor:
|
|
// @004c3f6c "d:\tesla\bt\bt_l4\BTL4GAUG.CPP", line 0x68a
|
|
//
|
|
// Class names are recovered verbatim from the CODE name-string pool
|
|
// (section_dump.txt @0x518480..0x51859e):
|
|
// ColorMapper ColorMapperArmor ColorMapperMultiArmor ColorMapperCritical
|
|
// ColorMapperHeat HorizTwoPartBar VertTwoPartBar VertNormalSlider
|
|
// OneOfSeveral OneOfSeveralInt OneOfSeveralPixInt OneOfSeveralStates
|
|
// HeadingPointer BitMapInverseWipe BitMapInverseWipeScalar
|
|
// SegmentArc270 SegmentArcRatio
|
|
//
|
|
// Field offsets in comments are the byte offsets observed in the decompiled
|
|
// object (e.g. "@0x90" == this[0x24]). The two base gauges are the MUNGA L4
|
|
// gauge primitives:
|
|
// Gauge ctor FUN_00444308 dtor FUN_00444360 -- non-graphic;
|
|
// used by the ColorMapper family (they tint a palette, they
|
|
// do not own a GraphicsView).
|
|
// GraphicGauge ctor FUN_00444818 dtor FUN_00444870 -- owns a GraphicsView
|
|
// embedded at +0x48 (this[0x12]); used by every drawing gauge.
|
|
// (Same base as MapDisplay in btl4rdr.cpp.)
|
|
//
|
|
// Names flagged "(name unconfirmed)" are best-effort: the class exists in the
|
|
// binary but its identification string could not be tied to it unambiguously.
|
|
//
|
|
|
|
#if !defined(BTL4GAUG_HPP)
|
|
# define BTL4GAUG_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(HEAT_HPP)
|
|
# include <heat.hpp>
|
|
# endif
|
|
|
|
// NOTE (reconstruction): the original BTL4GAUG.HPP also pulled in
|
|
// <powersub.hpp>, but nothing in this gauge-widget family actually depends
|
|
// on a power-subsystem type (the gauges connect to subsystems by name /
|
|
// attribute index, not by class). The include is dropped to keep this TU
|
|
// independent of the (separately-reconstructed) powersub header.
|
|
|
|
//#######################################################################
|
|
//#######################################################################
|
|
// ColorMapper family
|
|
//
|
|
// A ColorMapper is NOT a drawing gauge: every frame it reads a single
|
|
// subsystem-derived value (0..255), looks the corresponding R/G/B
|
|
// triple out of a named palette resource, and -- if it has changed --
|
|
// writes it straight into one hardware palette slot (colorIndex). The
|
|
// cockpit art that uses that slot therefore changes colour live. With
|
|
// two palette names it alternates between them every frame to flash.
|
|
//
|
|
// The driving value arrives through a small file-private GaugeConnection
|
|
// (see btl4gaug.cpp) wired to currentColorIndex. ColorMapperHeat's
|
|
// connection reads HeatableSubsystem::currentTemperature (@0x114).
|
|
//#######################################################################
|
|
//#######################################################################
|
|
|
|
class ColorMapper :
|
|
public Gauge
|
|
{
|
|
public:
|
|
ColorMapper(
|
|
GaugeRate rate,
|
|
ModeMask mode_mask,
|
|
L4GaugeRenderer *renderer,
|
|
int graphics_port_number,
|
|
int color_index,
|
|
const char *palette_name_a,
|
|
const char *palette_name_b,
|
|
const char *identification_string
|
|
);
|
|
~ColorMapper();
|
|
|
|
Logical TestInstance() const; // inherits Gauge
|
|
void BecameActive();
|
|
void Execute(); // @004c3980 -- palette push
|
|
|
|
protected:
|
|
char *paletteName[2]; // @0x48,@0x4C this[0x12],[0x13]
|
|
Logical twoColorMode; // @0x50 this[0x14] (names differ)
|
|
int currentColorIndex; // @0x54 this[0x15] (connection dst)
|
|
int previousColorIndex; // @0x58 this[0x16]
|
|
int colorSlot; // @0x5C this[0x17] hw palette slot
|
|
int paletteToggle; // @0x60 this[0x18] 0/1 flash phase
|
|
unsigned char
|
|
previousRed, // @0x64 this[0x19].b0
|
|
previousGreen, // @0x65
|
|
previousBlue; // @0x66
|
|
GraphicsPort
|
|
*graphicsPort; // @0x68 this[0x1A] (renderer port)
|
|
};
|
|
|
|
//
|
|
// ColorMapperArmor -- tints by the damage ratio of one named damage zone.
|
|
// Connection: @004c33a4 (reads Subsystem damage-zone array @0x120[index]).
|
|
//
|
|
class ColorMapperArmor :
|
|
public ColorMapper
|
|
{
|
|
public:
|
|
// Registered in BTL4MethodDescription[] (btl4grnd.cpp) as "cmArmor".
|
|
static MethodDescription methodDescription;
|
|
|
|
static Logical Make( // @004c3aa4
|
|
int display_port_index, Vector2DOf<int> position,
|
|
Entity *entity, GaugeRenderer *gauge_renderer);
|
|
|
|
ColorMapperArmor( // @004c3b98
|
|
GaugeRate rate, ModeMask mode_mask, L4GaugeRenderer *renderer,
|
|
int graphics_port_number, int color_index,
|
|
Entity *entity, const char *palette_a, const char *palette_b,
|
|
int damage_zone_index, const char *identification_string);
|
|
~ColorMapperArmor();
|
|
|
|
// @004c3c38 -- store the group state into @0x6C (used by PlayerStatusMappingGroup
|
|
// to push the mech's disabled/enabled state onto all 28 zone tints).
|
|
void SetColor(int state) { unused = state; }
|
|
protected:
|
|
int unused; // @0x6C this[0x1B] (state slot; SetColor writes it)
|
|
};
|
|
|
|
//
|
|
// ColorMapperMultiArmor -- worst-of-N damage zones.
|
|
// Connection: @004c346c (copies 8 zone indices, takes the max ratio).
|
|
//
|
|
class ColorMapperMultiArmor :
|
|
public ColorMapper
|
|
{
|
|
public:
|
|
// Registered in BTL4MethodDescription[] (btl4grnd.cpp) as "colorMapperMultiArmor".
|
|
static MethodDescription methodDescription;
|
|
|
|
static Logical Make(int, Vector2DOf<int>, Entity *, GaugeRenderer *); // @004c3c48
|
|
ColorMapperMultiArmor( // @004c3d60
|
|
GaugeRate, ModeMask, L4GaugeRenderer *, int, int,
|
|
Entity *, const char *, const char *,
|
|
const int *zone_indices /*[8]*/, const char *);
|
|
~ColorMapperMultiArmor();
|
|
};
|
|
|
|
//
|
|
// ColorMapperCritical -- tints by a subsystem's operational state.
|
|
// Connection: @004c3598 (subsystem operational flag @0x40 -> 100, else value).
|
|
//
|
|
class ColorMapperCritical :
|
|
public ColorMapper
|
|
{
|
|
public:
|
|
// Registered in BTL4MethodDescription[] (btl4grnd.cpp) as "cmCrit".
|
|
static MethodDescription methodDescription;
|
|
|
|
static Logical Make(int, Vector2DOf<int>, Entity *, GaugeRenderer *); // @004c3ddc
|
|
ColorMapperCritical( // @004c3e40
|
|
GaugeRate, ModeMask, L4GaugeRenderer *, int, int,
|
|
Entity *, const char *, const char *,
|
|
const char *subsystem_name, const char *);
|
|
~ColorMapperCritical();
|
|
};
|
|
|
|
//
|
|
// ColorMapperHeat -- the cockpit heat tint. ANCHOR @004c3f6c.
|
|
// Connection: @004c3664 (reads HeatableSubsystem::currentTemperature@0x114
|
|
// as a 0..100 percentage). The named subsystem must derive from a heat
|
|
// class (IsDerivedFrom 0x50e3ec HeatableSubsystem or 0x50e604 HEATWATCHER
|
|
// -- task #57 relabel) or the ctor asserts (line 0x68a).
|
|
//
|
|
class ColorMapperHeat :
|
|
public ColorMapper
|
|
{
|
|
public:
|
|
static Logical Make(int, Vector2DOf<int>, Entity *, GaugeRenderer *); // @004c3f08
|
|
ColorMapperHeat( // @004c3f6c
|
|
GaugeRate, ModeMask, L4GaugeRenderer *, int, int,
|
|
Entity *, const char *, const char *,
|
|
const char *heat_subsystem_name, const char *);
|
|
~ColorMapperHeat();
|
|
|
|
// Registered in BTL4MethodDescription[] (btl4grnd.cpp) so the config
|
|
// interpreter builds this gauge from the CFG "cmHeat" primitive.
|
|
static MethodDescription methodDescription;
|
|
};
|
|
|
|
|
|
//#######################################################################
|
|
//#######################################################################
|
|
// Two-part fill bars (: GraphicGauge)
|
|
//
|
|
// A bar is split into a "filled" colour and a "background" colour at a
|
|
// pixel computed from a Scalar input. HorizTwoPartBar grows left->right,
|
|
// VertTwoPartBar grows bottom->top. Both blit a tile bitmap behind the
|
|
// fill (FUN_004c2ff8 = tiled blit helper).
|
|
//#######################################################################
|
|
//#######################################################################
|
|
|
|
class HorizTwoPartBar :
|
|
public GraphicGauge
|
|
{
|
|
public:
|
|
static Logical Make(int, Vector2DOf<int>, Entity *, GaugeRenderer *); // @004c407c
|
|
HorizTwoPartBar( // @004c4170
|
|
GaugeRate, ModeMask, L4GaugeRenderer *, 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);
|
|
~HorizTwoPartBar();
|
|
|
|
Logical TestInstance() const;
|
|
void BecameActive(); // @004c4324
|
|
void Execute(); // @004c4340
|
|
|
|
protected:
|
|
Scalar value; // @0x90 this[0x24] (connection)
|
|
Scalar low; // @0x94 this[0x25]
|
|
Scalar high; // @0x98 this[0x26]
|
|
char *tileImage; // @0x9C this[0x27]
|
|
int fillColor; // @0xA0 this[0x28]
|
|
int backgroundColor; // @0xA4 this[0x29]
|
|
int width; // @0xA8 this[0x2A] right-left
|
|
int height; // @0xAC this[0x2B] (top-bottom)-1
|
|
int previousFill; // @0xB0 this[0x2C]
|
|
int previousFull; // @0xB4 this[0x2D]
|
|
};
|
|
|
|
class VertTwoPartBar :
|
|
public GraphicGauge
|
|
{
|
|
public:
|
|
// Registered in BTL4MethodDescription[] (btl4grnd.cpp) as "vertBar".
|
|
static MethodDescription methodDescription;
|
|
|
|
static Logical Make(int, Vector2DOf<int>, Entity *, GaugeRenderer *); // @004c462c
|
|
VertTwoPartBar( // @004c4724 (ctor arg order = binary param_12..17)
|
|
GaugeRate, ModeMask, L4GaugeRenderer *, int graphics_port_number,
|
|
int left, int bottom, int right, int top,
|
|
const char *tile_image,
|
|
int background_color, int fill_color, int extra_color,
|
|
Scalar *value_pointer, Scalar *low_pointer, Scalar *high_pointer,
|
|
const char *identification_string);
|
|
~VertTwoPartBar();
|
|
|
|
Logical TestInstance() const;
|
|
void BecameActive(); // @004c48e0
|
|
void Execute(); // @004c48fc
|
|
|
|
protected:
|
|
char *tileImage; // @0x90 this[0x24]
|
|
int backgroundColor; // @0x94 this[0x25]
|
|
int fillColor; // @0x98 this[0x26]
|
|
int extraColor; // @0x9C this[0x27]
|
|
int width; // @0xA0 this[0x28] (right-left)-1
|
|
int height; // @0xA4 this[0x29] top-bottom
|
|
Scalar value; // @0xB0 this[0x2C] (connection)
|
|
Scalar low; // @0xB4 this[0x2D]
|
|
Scalar high; // @0xB8 this[0x2E]
|
|
int previousFill; // @0xA8 this[0x2A]
|
|
int previousFull; // @0xAC this[0x2B]
|
|
};
|
|
|
|
//
|
|
// VertNormalSlider -- a single-colour rectangle whose height tracks a
|
|
// normalised [0,1] value (clamped at @004c4cc0). (name unconfirmed but
|
|
// matches the "VertNormalSlider" pool entry and the vtable ordering.)
|
|
//
|
|
class VertNormalSlider :
|
|
public GraphicGauge
|
|
{
|
|
public:
|
|
// gauge wave P2: the "vertNormalSlider" config factory (the condenser VALVE
|
|
// slider @2 in GenericHeatGauges1/2). Registered in BTL4MethodDescription[]
|
|
// (btl4grnd.cpp); the ctor/Execute existed only as prose, so the keyword was
|
|
// parse-skipped and the SET column never built.
|
|
static MethodDescription methodDescription;
|
|
static Logical Make(int, Vector2DOf<int>, Entity *, GaugeRenderer *); // @004c4b08
|
|
|
|
VertNormalSlider( // @004c4b84
|
|
GaugeRate, ModeMask, L4GaugeRenderer *, int,
|
|
int left, int bottom, int right, int top,
|
|
int fill_color, int background_color, int baseline,
|
|
Scalar *value_pointer, const char *identification_string);
|
|
~VertNormalSlider(); // @004c4c68
|
|
|
|
Logical TestInstance() const; // @004c4c94 -> GraphicGauge::TestInstance
|
|
void BecameActive(); // @004c4cac
|
|
void Execute(); // @004c4cc0 -> Draw @004c4d48
|
|
private:
|
|
void Draw(); // @004c4d48 (XOR indicator blit; non-virtual)
|
|
|
|
protected:
|
|
// Corrected byte-exact layout (from the ctor's this[N] stores @004c4b84;
|
|
// the earlier order was jumbled). 8 words, 0x90..0xAF, sizeof == 0xB0.
|
|
int previousFill; // @0x90 this[0x24] XOR indicator row; -1 = none
|
|
int width; // @0x94 this[0x25] (right-left)-1
|
|
int height; // @0x98 this[0x26] top-bottom (track height)
|
|
int baseline; // @0x9C this[0x27] indicator thickness
|
|
int span; // @0xA0 this[0x28] height-baseline (travel)
|
|
int fillColor; // @0xA4 this[0x29] indicator colour
|
|
int backgroundColor; // @0xA8 this[0x2A] stored, unused by Draw
|
|
Scalar value; // @0xAC this[0x2B] connection dst [0,1]
|
|
};
|
|
|
|
|
|
//#######################################################################
|
|
//#######################################################################
|
|
// OneOfSeveral family -- multi-frame bitmap selectors
|
|
//
|
|
// A strip bitmap holds N frames; the gauge blits whichever frame the
|
|
// driving value selects. The base (OneOfSeveral) stores the strip and
|
|
// the per-frame size; subclasses add the value source.
|
|
//#######################################################################
|
|
//#######################################################################
|
|
|
|
class OneOfSeveral :
|
|
public GraphicGauge
|
|
{
|
|
public:
|
|
OneOfSeveral( // @004c4d88
|
|
GaugeRate, ModeMask, L4GaugeRenderer *, int,
|
|
int x, int y, Logical from_image_strip,
|
|
const char *image_name,
|
|
int /*reserved*/, int /*reserved*/,
|
|
int columns, int rows,
|
|
const char *identification_string);
|
|
~OneOfSeveral();
|
|
|
|
Logical TestInstance() const;
|
|
void BecameActive(); // @004c4f14
|
|
void Execute(); // @004c4f28
|
|
|
|
protected:
|
|
Logical fromImageStrip; // @0x90 this[0x24]
|
|
char *imageName; // @0x94 this[0x25]
|
|
int backgroundColor; // @0x98 this[0x26]
|
|
int foregroundColor; // @0x9C this[0x27] (DrawBitMapOpaque bg arg)
|
|
int columns; // @0xA0 this[0x28]
|
|
int selected; // @0xAC this[0x2B] (connection)
|
|
int previousSelected; // @0xB0 this[0x2C]
|
|
int frameWidth; // @0xA4 this[0x29]
|
|
int frameHeight; // @0xA8 this[0x2A]
|
|
};
|
|
|
|
//
|
|
// OneOfSeveralInt -- frame = a direct int input. @004c5148 Make @004c5068
|
|
//
|
|
class OneOfSeveralInt :
|
|
public OneOfSeveral
|
|
{
|
|
public:
|
|
static Logical Make(int, Vector2DOf<int>, Entity *, GaugeRenderer *);
|
|
OneOfSeveralInt(GaugeRate, ModeMask, L4GaugeRenderer *, int,
|
|
int x, int y, const char *image, int columns, int rows,
|
|
int *value_pointer, const char *);
|
|
~OneOfSeveralInt(); // @004c51d8
|
|
};
|
|
|
|
//
|
|
// OneOfSeveralPixInt -- frame from a packed-pixel int strip.
|
|
// @004c52d8 Make @004c5204
|
|
//
|
|
class OneOfSeveralPixInt :
|
|
public OneOfSeveral
|
|
{
|
|
public:
|
|
// Registered in BTL4MethodDescription[] (btl4grnd.cpp) as "oneOfSeveralPixInt".
|
|
static MethodDescription methodDescription;
|
|
|
|
static Logical Make(int, Vector2DOf<int>, Entity *, GaugeRenderer *); // @004c5204
|
|
OneOfSeveralPixInt( // @004c52d8
|
|
GaugeRate, ModeMask, L4GaugeRenderer *, int graphics_port_number,
|
|
int x, int y, const char *image, int columns, int rows,
|
|
int *value_pointer, const char *identification_string);
|
|
~OneOfSeveralPixInt(); // @004c5364
|
|
};
|
|
|
|
//
|
|
// OneOfSeveralStates -- frame from a subsystem state value (clamped >=0).
|
|
// @004c5470 Make @004c5390 Execute clamp @004c552c
|
|
// Connection: @004c3324 (reads Subsystem state @0x14).
|
|
//
|
|
class OneOfSeveralStates :
|
|
public OneOfSeveral
|
|
{
|
|
public:
|
|
static Logical Make(int, Vector2DOf<int>, Entity *, GaugeRenderer *);
|
|
OneOfSeveralStates(GaugeRate, ModeMask, L4GaugeRenderer *, int,
|
|
int x, int y, const char *image, int columns, int rows,
|
|
Entity *subsystem_source, const char *);
|
|
~OneOfSeveralStates(); // @004c5500
|
|
void BecameActive(); // @004c552c
|
|
};
|
|
|
|
|
|
//#######################################################################
|
|
// HeadingPointer -- a rotating numeric compass-heading readout.
|
|
// @004c562c Make @004c554c Execute @004c5914 (rotate by torso yaw,
|
|
// degrees = radian * 57.2958). Owns a NumericDisplay (@0x44 object,
|
|
// FUN_004700bc) and a GraphicsViewRecord (@0xA4) for erase tracking.
|
|
//#######################################################################
|
|
class HeadingPointer :
|
|
public GraphicGauge
|
|
{
|
|
public:
|
|
// Registered in BTL4MethodDescription[] (btl4grnd.cpp) as "headingPointer".
|
|
static MethodDescription methodDescription;
|
|
|
|
static Logical Make(int, Vector2DOf<int>, Entity *, GaugeRenderer *); // @004c554c
|
|
|
|
//
|
|
// The binary ctor (@004c562c) takes 14 args -- the earlier header collapsed
|
|
// owner_ID/graphics_port_number and merged the colours. Also: fields
|
|
// @0x98/@0x9C are the needle's inner/outer RADIUS (Execute multiplies them
|
|
// by sin/cos of the heading), NOT a colour+spacing as the old names implied.
|
|
//
|
|
HeadingPointer( // @004c562c
|
|
GaugeRate, ModeMask, L4GaugeRenderer *,
|
|
unsigned int owner_ID,
|
|
int graphics_port_number,
|
|
int x, int y,
|
|
int needle_color, // -> @0x90 the drawn needle colour
|
|
int numeric_color, // -> NumericDisplay foreground (readout)
|
|
int erase_color, // -> @0x94 erase + NumericDisplay background
|
|
int inner_radius, // -> @0x98 needle near-end radius
|
|
int outer_radius, // -> @0x9C needle tip radius (the change key)
|
|
const char *font_name,
|
|
const char *identification_string = "HeadingPointer");
|
|
~HeadingPointer(); // @004c573c
|
|
|
|
Logical TestInstance() const;
|
|
void ShowInstance(char *indent); // @004c57d0
|
|
void BecameActive(); // @004c58e8
|
|
void Execute(); // @004c5914
|
|
|
|
protected:
|
|
int needleColor; // @0x90 needle (fg) colour
|
|
int eraseColor; // @0x94 erase (bg) colour
|
|
int innerRadius; // @0x98 needle near-end radius
|
|
int outerRadius; // @0x9C needle tip radius (change key)
|
|
char *imageName; // @0xA0 interned font name
|
|
GraphicsViewRecord
|
|
previousDrawing; // @0xA4 erase-tracking record
|
|
int previousX; // @0xB4
|
|
int previousY; // @0xB8
|
|
NumericDisplay
|
|
*numericDisplay; // @0xBC
|
|
};
|
|
|
|
|
|
//#######################################################################
|
|
// BitMap "wipe" gauges -- a fuel/leak style bar that reveals a bitmap up
|
|
// to a level. (names "BitMapInverseWipe" / "BitMapInverseWipeScalar" are
|
|
// best-effort from the pool; the Scalar variant adds a GaugeConnection.)
|
|
// BitMapInverseWipe @004c5b7c (used as a base by btl4gau2 LeakGauge)
|
|
// <wipe base> @004c5e84
|
|
// <wipe base>Scalar @004c61c8 (adds GaugeConnectionDirectOf<Scalar>)
|
|
//#######################################################################
|
|
class BitMapInverseWipe : // (name unconfirmed)
|
|
public GraphicGauge
|
|
{
|
|
public:
|
|
// gauge wave P2: registered in BTL4MethodDescription[] (btl4grnd.cpp) as
|
|
// "LeakGauge" -- the config factory the class was missing (the ctor/Execute
|
|
// already existed but the keyword was parse-skipped so it never built).
|
|
static MethodDescription methodDescription;
|
|
static Logical Make(int, Vector2DOf<int>, Entity *, GaugeRenderer *); // @004c... (config factory)
|
|
|
|
BitMapInverseWipe( // @004c5b7c
|
|
GaugeRate, ModeMask, L4GaugeRenderer *, int,
|
|
int x, int y, const char *image,
|
|
int color_a, int color_b, int third, int frames,
|
|
Scalar *value_pointer, const char *);
|
|
~BitMapInverseWipe(); // @004c5c80
|
|
Logical TestInstance() const;
|
|
void BecameActive(); // @004c5cf4
|
|
void Execute(); // @004c5d08
|
|
protected:
|
|
char *imageName; // @0x90 this[0x24]
|
|
int colorA; // @0x94 this[0x25]
|
|
int colorB; // @0x98 this[0x26]
|
|
int fullWidth; // @0x9C this[0x27] frames*2
|
|
int frameWidth; // @0xA8 this[0x2A] width/3
|
|
int frameHeight; // @0xA4 this[0x29]
|
|
int frames; // @0xA0 this[0x28]
|
|
int previousLevel; // @0xAC this[0x2B]
|
|
int third; // @0xB0 this[0x2C]
|
|
Scalar value; // @0xB4 this[0x2D] (connection)
|
|
};
|
|
|
|
//#######################################################################
|
|
// SegmentArc gauges -- needle / dial over a 270-degree arc. Derived from
|
|
// the MUNGA L4 arc primitives (FUN_004745e0 / FUN_00473f44).
|
|
// SegmentArc270 @004c6244
|
|
// SegmentArcRatio @004c6394 Make @004c62fc (adds two connections)
|
|
//#######################################################################
|
|
class SegmentArc270 :
|
|
public SegmentArc // MUNGA L4 base (engine class SegmentArc)
|
|
{
|
|
public:
|
|
SegmentArc270( // @004c6244
|
|
GaugeRate, ModeMask, L4GaugeRenderer *, int owner_ID,
|
|
int graphics_port_number, int center_x, int center_y,
|
|
Scalar inner0, Scalar outer0, Scalar inner1, Scalar outer1,
|
|
Scalar deg0, Scalar deg1, int number_of_segs,
|
|
int background_color, int foreground_color,
|
|
Scalar *value_pointer, Logical use_thick_lines,
|
|
const char *identification_string);
|
|
~SegmentArc270(); // dtor thunk @004c66b3
|
|
void Execute(); // PORT diag wrapper (chains SegmentArc::Execute)
|
|
const char *diagName; // PORT diagnostic (frozen-dial hunt)
|
|
protected:
|
|
Scalar segmentSpan; // @0xC0 this[0x30]
|
|
};
|
|
|
|
class SegmentArcRatio :
|
|
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<int>, Entity *, GaugeRenderer *); // @004c62fc
|
|
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)
|
|
Scalar segmentSpan; // @0xC8 this[0x32] (float, read by Execute)
|
|
};
|
|
|
|
#endif
|