Gauges: trigger-config joystick is LIVE -- @004c6ee0 is LinkToEntity, not SetColor

The weapon panel's btjoy trigger-config display (ConfigMapGauge) never rendered
because the reconstruction labelled @004c6ee0 as "SetColor(int)" and, finding no
caller, concluded the gauge was authentically dormant (task #6), gating it
behind a BT_CONFIGMAP dev env.

The user challenged this (the PROGRAM/TRIGGER CONFIG button implies the display
visualizes your config).  Re-verification found the old analysis failed twice:
the "no caller" search looked for direct calls to a VIRTUAL, and its slot math
used the wrong vtable copy.  The real ConfigMapGauge vtable @0051a1b8, matched
against the T0 GaugeBase virtual roster (GAUGE.h), pins @004c6ee0 at slot 9
(+0x24) == GaugeBase::LinkToEntity, and @0x94 is the linkedEntity -- the
Execute gate is "not yet linked", not "disabled".  The engine broadcasts
LinkToEntity(viewpointEntity) to every gauge at viewpoint bind (APP.cpp:1277 ->
GaugeRenderer::LinkToEntity GAUGREND.cpp:3011), arming the gate -- the joystick
DOES render in the shipped game, showing per-trigger mapping state (solid =
mapped, matching the DOSBox reference).

Port fix: SetColor(int color) -> LinkToEntity(Entity*), color -> linkedEntity,
BT_CONFIGMAP dev enable deleted (the authentic path lights it).  Render-verified
with no env override: the joystick + mapped-trigger lamp draw on weapon panels.

KB swept per the correction mandate: gauges-hud.md, decomp-reference.md,
open-questions.md, GAUGE_COMPOSITE.md, VEHICLE_SUBSYSTEMS.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-21 08:49:58 -05:00
co-authored by Claude Opus 4.8
parent 77cc62886f
commit 89b4f53046
7 changed files with 55 additions and 34 deletions
+16 -14
View File
@@ -544,7 +544,7 @@ void SeekVoltageGraph::Execute()
// @004c6d80 -- ctor (vtable PTR_FUN_0051a1b8). GraphicGauge base; interns the
// joystick base bitmap "btjoy.pcc" (BitMapCache AddRef) + the four config-state
// pixmaps cm_off/cm_other/cm_only/cm_both.pcc (PixMapCache AddRef); sets the port
// origin (x,y); subsystem = param_9; color = 0.
// origin (x,y); subsystem = param_9; linkedEntity = 0.
//
ConfigMapGauge::ConfigMapGauge(
GaugeRate rate,
@@ -567,14 +567,14 @@ ConfigMapGauge::ConfigMapGauge(
localView.SetOrigin(x, y); // vtbl+0x10 (this+0x48)
color = 0; // @0x94 this[0x25]
// task #6 finding [T1]: NO caller of SetColor (@004c6ee0) exists in the
// shipped binary -- the only accesses to the WeaponCluster's configMap
// child (@0xD4) are BecameActive forwards and SetEnable -- so the gauge is
// authentically DORMANT in BTL4OPT (color stays 0; Execute early-outs).
// BT_CONFIGMAP=1 is the PORT's dev enable to watch the state loop live.
if (getenv("BT_CONFIGMAP"))
color = 0xff;
linkedEntity = 0; // @0x94 this[0x25]
// CORRECTION (2026-07-21, retires the task #6 "dormant" claim): @0x94 is NOT
// a colour and @004c6ee0 is NOT an uncalled SetColor -- it is the virtual
// GaugeBase::LinkToEntity override (vtbl slot 9, +0x24; verified against the
// binary vtable @0051a1b8 + the engine GaugeBase roster). The engine
// broadcasts LinkToEntity(viewpointEntity) to every gauge when the viewpoint
// binds (APP.cpp:1277 -> GAUGREND.cpp:3011), which arms this gate -- the
// trigger-config joystick DOES render in the shipped game.
subsystem = subsystem_in; // @0x90 this[0x24]
L4Warehouse *warehouse = (L4Warehouse *)renderer_in->warehousePointer;
@@ -601,12 +601,14 @@ Logical
}
//
// @004c6ee0 -- SetColor: color (this[0x25]) = the passed value.
// @004c6ee0 -- LinkToEntity (GaugeBase vtbl slot 9): linkedEntity (this[0x25]) =
// the viewpoint entity. Broadcast by GaugeRenderer::LinkToEntity when the
// viewpoint binds; arms the Execute gate.
//
void
ConfigMapGauge::SetColor(int color_in) // @004c6ee0
ConfigMapGauge::LinkToEntity(Entity *entity) // @004c6ee0
{
color = color_in;
linkedEntity = entity;
}
//
@@ -621,7 +623,7 @@ void
}
//
// @004c6f1c -- Execute. When enabled (color != 0): on the dirty flag, blit the
// @004c6f1c -- Execute. Once linked (linkedEntity != 0): on the dirty flag, blit the
// base joystick bitmap; then for each of the 4 config-map slots read the fire
// button's map state and, if changed, blit the matching cm_* pixmap.
//
@@ -644,7 +646,7 @@ extern void BTSubsystemControlFeed(void *subsystem_in, void **destination_out,
void
ConfigMapGauge::Execute()
{
if (color == 0)
if (linkedEntity == 0) // @004c6f28: not yet linked to the viewpoint
return;
L4Warehouse *warehouse = (L4Warehouse *)renderer->warehousePointer;