diff --git a/engine/MUNGA_L4/L4VIDEO.cpp b/engine/MUNGA_L4/L4VIDEO.cpp index 6bf777d..d2c6328 100644 --- a/engine/MUNGA_L4/L4VIDEO.cpp +++ b/engine/MUNGA_L4/L4VIDEO.cpp @@ -8585,12 +8585,19 @@ void DPLRenderer::ExecuteImplementation(RendererComplexity, RendererOrigin::Inte if (mCamShipHUD) mCamShipHUD->Render(0, &viewTransform); + // DEV-COMPOSITE: in DOCKED mode (BT_DEV_GAUGES_DOCK) blit the 6-surface gauge panel + // into this window as the LAST draw before EndScene (no-op otherwise / off pod). + extern void BTDrawGaugeInset(LPDIRECT3DDEVICE9 device); + BTDrawGaugeInset(mDevice); + // DIAG (off by default): BT_SHOT= dumps this instance's backbuffer to a // PNG every 90 frames -- non-disruptive per-instance frame capture without // foregrounding the window. Built for the -net render glitch (task #53); // moved AFTER the 2D pass (2026-07-18, camera-seat bring-up) so captures - // include the HUD overlays (reticle, camera-ship ranking window) the screen - // actually shows. + // include the HUD overlays (reticle, camera-ship ranking window), and AFTER + // the docked gauge inset (2026-07-19, Gitea #10 audit -- the 07-18 reorder + // had left the capture BEFORE BTDrawGaugeInset, so BT_DEV_GAUGES_DOCK shots + // were missing the gauge panel the screen actually shows). { const char *shotPath = getenv("BT_SHOT"); if (shotPath) @@ -8613,11 +8620,6 @@ void DPLRenderer::ExecuteImplementation(RendererComplexity, RendererOrigin::Inte } } - // DEV-COMPOSITE: in DOCKED mode (BT_DEV_GAUGES_DOCK) blit the 6-surface gauge panel - // into this window as the LAST draw before EndScene (no-op otherwise / off pod). - extern void BTDrawGaugeInset(LPDIRECT3DDEVICE9 device); - BTDrawGaugeInset(mDevice); - hr = mDevice->EndScene(); // DEV-COMPOSITE: default mode -- render the 6 cockpit surfaces into a SEPARATE window diff --git a/game/reconstructed/CLASSMAP.md b/game/reconstructed/CLASSMAP.md index a589996..995cce5 100644 --- a/game/reconstructed/CLASSMAP.md +++ b/game/reconstructed/CLASSMAP.md @@ -31,13 +31,18 @@ Subsystem (MUNGA base — have source: RP/MUNGA/SUBSYSTM.HPP) │ │ │ cockpit heads-up display (torso-horizon gimbal + reticle/threat/status read-outs). Confirms the │ │ │ "Resolved conflict" note: @4b7f94 is the HUD, mislabeled "MechTech" by mech.cpp's 0xBD6 factory case. │ │ │ DefaultData 00511078; resource +0xF4 FlickerRate, +0xF8 SegmentPageName(idx), +0xFC HorizontalMovementPerSecond, +0x100 HorizontalLimit. -│ │ │ members: flickerRate@0x1D8, torso/target read-outs@0x1DC-0x1EC, lockFlag@0x1F4, visible@0x1F8, -│ │ │ threatVector(Vec3)@0x1FC, compassHeading(Vec3)@0x208 (setter @4b7810), blink/slew accums@0x218-0x230, +│ │ │ members (re-based 2026-07-19, Gitea #10, per the re-dumped attr table @5110b8): flickerRate@0x1D8, +│ │ │ rotationOfTorsoHorizontal@0x1DC(<-Torso+0x1D8 twist), torsoLimits@0x1E0/0x1E4, torsoSpeed@0x1E8, +│ │ │ rangeToTarget@0x1EC, @0x1F0 unbound, visible@0x1F4(init 1), lockFlag@0x1F8(init 0), +│ │ │ hotBoxVector(Vec3)@0x1FC, threatVector(Vec3)@0x208 (setter @4b7810 = SetThreatVector, ex-"SetCompassHeading" mislabel), +│ │ │ compassHeading(Scalar)@0x214(=yaw+twist), blink/slew accums@0x218-0x230, │ │ │ linkedEntity@0x234(=Mech+0x438), statusAlarm(2)@0x238, horizontalTorsoOffset@0x294, HMPS@0x298, HorizontalLimit@0x29C, flickerActive@0x2A0. │ │ │ overrides: HandleMessage@4b7780(s9, body not captured), ResetToInitialState@4b77bc(s10). HudSimulation@4b7830 (Performance, PTR@511170). -│ │ │ attr table @5110c0 (ids 4-0xd: RotationOfTorsoHorizontal/HorizontalTorsoLimit{Right,Left}/SpeedOfTorsoHorizontal/ -│ │ │ RangeToTarget/Visible/Lock/HotBoxVector/ThreatVector/CompassHeading) — NB attr name<->offset bindings only -│ │ │ partially agree with ctor/sim usage (UNCERTAIN). TestInstance@4b81b8 (deriv @511088 "HUD"). UpdateFlicker@4b7ed4. +│ │ │ attr table @5110b8 (16-byte records; ids 3-0xd: FlickerRate@0x1D8 + RotationOfTorsoHorizontal@0x1DC/ +│ │ │ HorizontalTorsoLimit{Right@0x1E0,Left@0x1E4}/SpeedOfTorsoHorizontal@0x1E8/RangeToTarget@0x1EC/Visible@0x1F4/ +│ │ │ Lock@0x1F8/HotBoxVector@0x1FC/ThreatVector@0x208/CompassHeading@0x214) — RESOLVED 2026-07-19: the old +│ │ │ "@5110c0, ids 4-0xd" transcription had dropped the leading id-3 FlickerRate record and shifted every offset +│ │ │ one slot; ctor+HudSimulation usage now agrees exactly. TestInstance@4b81b8 (deriv @511088 "HUD"). UpdateFlicker@4b7ed4. │ │ ├─ Searchlight vtable 005114d4 classID 0xBD8 ctor @4b84dc dtor @4b8568 CSS @4b85a8 [searchlight.cpp DONE] model 0xF4 │ │ │ illumination subsystem (corroborated by btl4vid MakeMechRenderables "0xBD8 SearchLight"). DefaultData 00511198. │ │ │ empty resource (CSS only stamps). members: lightState@0x1D8 ("LightState" attr id5), diff --git a/game/reconstructed/hud.cpp b/game/reconstructed/hud.cpp index 5ab57bb..d078894 100644 --- a/game/reconstructed/hud.cpp +++ b/game/reconstructed/hud.cpp @@ -126,17 +126,21 @@ HUD::HUD( Check(owner); Check_Pointer(subsystem_resource); - flickerRate = 0.0f; // @0x1D8 (overwritten below from resource) - torsoLimitRight = 0.0f; // @0x1DC - torsoLimitLeft = 0.0f; // @0x1E0 - torsoSpeed = 0.0f; // @0x1E4 - rangeToTarget = 0.0f; // @0x1E8 - targetRange = 0.0f; // @0x1EC - lockFlag = True; // @0x1F4 = 1 - visible = False; // @0x1F8 - threatVector = HudZeroVector; // @0x1FC - compassHeading = HudZeroVector; // @0x208 - hotBoxScalar = 0.0f; // @0x214 + // (member names re-based 2026-07-19 per the re-dumped attr table @005110b8; + // the ctor @004b7f94 zeroes [0x76..0x7b] then sets [0x7d]=1 / [0x7e]=0 -- + // note [0x7c]=@0x1F0 is left uninitialized in the binary) + flickerRate = 0.0f; // @0x1D8 (overwritten below from resource) + rotationOfTorsoHorizontal = 0.0f; // @0x1DC + torsoLimitRight = 0.0f; // @0x1E0 + torsoLimitLeft = 0.0f; // @0x1E4 + torsoSpeed = 0.0f; // @0x1E8 + rangeToTarget = 0.0f; // @0x1EC + scratch1F0 = 0; // @0x1F0 (binary leaves it uninitialized; zeroed here) + visible = True; // @0x1F4 = 1 ("Visible" starts shown) + lockFlag = False; // @0x1F8 = 0 ("Lock" starts un-locked) + hotBoxVector = HudZeroVector; // @0x1FC + threatVector = HudZeroVector; // @0x208 + compassHeading = 0.0f; // @0x214 blinkTimer = 0.0f; // @0x218 flickerTimer = 0.0f; // @0x21C blinkState = True; // @0x224 = 1 @@ -162,12 +166,14 @@ HUD::HUD( // owner+0x438 is the torso-orientation source -- a Mech RAW OFFSET that does not // hold a valid pointer in the reconstructed Mech layout (and isn't linked yet at // subsystem-construction time), so dereferencing it crashes. Default the - // torso/range readouts to 0; HudSimulation refreshes them per-frame once the link + // torso/twist readouts to 0; HudSimulation refreshes them per-frame once the link // is live. TODO: wire a real Mech torso-orientation-source accessor. + // (binary snapshot @004b7f94: [0x77]@0x1DC <- linked+0x1D8 twist, [0x78]@0x1E0 + // <- +0x1DC limitR, [0x79]@0x1E4 <- +0x1E0 limitL, [0x7a]@0x1E8 <- +0x1E8 speed) linkedEntity = 0; // @0x234 + rotationOfTorsoHorizontal = 0.0f; torsoLimitRight = 0.0f; torsoLimitLeft = 0.0f; - rangeToTarget = 0.0f; torsoSpeed = 0.0f; Check_Fpu(); @@ -203,14 +209,17 @@ Logical } //########################################################################### -// SetCompassHeading -- @004b7810 +// SetThreatVector -- @004b7810 // -// Copies a Point3D into compassHeading (@0x208). +// Copies a Point3D into threatVector (@0x208). Renamed 2026-07-19 (Gitea +// #10): the re-dumped attr table @005110b8 binds "ThreatVector" (attr 12) to +// @0x208 -- the old SetCompassHeading label was the one-slot transcription +// shift (the compass is the Scalar @0x214). No port caller. // void - HUD::SetCompassHeading(const Point3D &heading) + HUD::SetThreatVector(const Point3D &threat) { - compassHeading = heading; // FUN_00408440(this+0x208, &heading) + threatVector = threat; // FUN_00408440(this+0x208, &threat) } //########################################################################### @@ -299,11 +308,12 @@ Logical // 0 -> set HUD flag bit 0x1 on the graphic, clear bit 0x2 // 3 -> set bit 0x2, clear bit 0x1 (and gate on mech +0x410) // writes the resulting "active" flag to *(mech +0x374). -// 5. Target line-of-sight: if a target entity (mech +0x388) exists and is -// not over the heat limits, computes targetRange (@0x1EC) as the distance -// between the HUD anchor (mech +0x37C) and the target (+0x100); sets -// visible (@0x1F8); otherwise blanks. A default range 1200.0 is used -// when there is no target. +// 5. Target lock + range: if a target entity (mech +0x388) exists and the +// own/target zone-damage limits pass (:5619-5634, the Lock rule), sets +// lockFlag (@0x1F8, "Lock"); rangeToTarget (@0x1EC, "RangeToTarget") is +// the distance between the HUD anchor (mech +0x37C) and the target +// (+0x100), sliding at 500 m/s (:5652-5670), default 1200.0 with no +// target; the compass Scalar @0x214 = yaw euler[0] + torso twist (:5676). // 6. Torso-horizon slew: horizontalTorsoOffset (@0x294) is moved toward the // commanded torso heading at up to MaxTorsoSlew (500/sec), clamped to // +/- horizontalLimit (@0x29C), then written to the graphic at diff --git a/game/reconstructed/hud.hpp b/game/reconstructed/hud.hpp index f586390..20d9ec7 100644 --- a/game/reconstructed/hud.hpp +++ b/game/reconstructed/hud.hpp @@ -96,18 +96,30 @@ // // AttributePointers IndexEntry table @005110c0 (each record binds a name // to an attribute id and an object offset, the offset encoded as - // byte_offset|1 -- the same scheme used by sensor.hpp). Recovered: - // id 4 "RotationOfTorsoHorizontal" -> @0x1D8 - // id 5 "HorizontalTorsoLimitRight" -> @0x1DC - // id 6 "HorizontalTorsoLimitLeft" -> @0x1E0 - // id 7 "SpeedOfTorsoHorizontal" -> @0x1E4 - // id 8 "RangeToTarget" -> @0x1E8 - // id 9 "Visible" -> @0x1EC - // id 10 "Lock" -> @0x1F4 - // id 11 "HotBoxVector" -> @0x1F8 - // id 12 "ThreatVector" -> @0x1FC (Vec3) - // id 13 "CompassHeading" -> @0x208 (Vec3) - // (FlickerRate name ptr @005110bc heads the table as the category label.) + // byte_offset|1 -- the same scheme used by sensor.hpp). + // + // RE-DUMPED 2026-07-19 (Gitea #10 audit; section_dump.txt @5110b8, 16-byte + // records {id, namePtr, offset|1, 0}, terminator @511160). The table + // actually STARTS at @005110b8 with a FULL id-3 FlickerRate record (the old + // transcription had misread it as a "category label" and shifted every + // subsequent offset down one slot): + // id 3 "FlickerRate" -> @0x1D8 + // id 4 "RotationOfTorsoHorizontal" -> @0x1DC + // id 5 "HorizontalTorsoLimitRight" -> @0x1E0 + // id 6 "HorizontalTorsoLimitLeft" -> @0x1E4 + // id 7 "SpeedOfTorsoHorizontal" -> @0x1E8 + // id 8 "RangeToTarget" -> @0x1EC + // id 9 "Visible" -> @0x1F4 (init 1; @0x1F0 is unbound) + // id 10 "Lock" -> @0x1F8 (init 0) + // id 11 "HotBoxVector" -> @0x1FC (Point3D) + // id 12 "ThreatVector" -> @0x208 (Point3D) + // id 13 "CompassHeading" -> @0x214 (Scalar: yaw + torso twist) + // CROSS-CHECKED against the ctor @004b7f94 (inits @0x1F4=1 Visible-on / + // @0x1F8=0 Lock-off; @0x1F0 uninitialized) and HudSimulation @004b7830 + // (per-frame @0x1DC <- linkedTorso+0x1D8 = Torso::currentTwist; @0x1EC + // range default 1200.0 + the 500 m/s display slide; the Lock rule writes + // @0x1F8 at :5622/:5633; @0x214 = EulerAngles(mech)[0] + @0x1DC at :5676; + // the hotbox Point3D copy @0x1FC at :5680). All consistent. // // CONFIRMED (task #37): the recovered reticle Execute @004cdcf0 binds and // USES ids 4/5/6/8/0xA/0xB/0xC/0xD exactly per these names -- @@ -115,8 +127,7 @@ // HorizontalTorsoLimit full-scales, RangeToTarget the range caret, Lock // the spinning lock ring, HotBoxVector the target box (eye-space vec3), // ThreatVector the compass threat trail, CompassHeading the rose - // rotation. (The earlier note about @0x1D8/@0x1EC/@0x1F8 usage remains - // for the ctor-side seeds only.) + // rotation. // public: enum { @@ -142,20 +153,25 @@ // Local data. Offsets are byte offsets into the shipped object; names are // best-effort from the attribute pool + ctor/HudSimulation usage. // + // Member names re-based 2026-07-19 (Gitea #10) against the RE-DUMPED attr + // table @005110b8 -- the old names were shifted one slot (see the table + // comment above). protected: - Scalar flickerRate; // @0x1D8 resource +0xF4 (flicker / blink period threshold) - // Torso / target read-outs sampled each construction from the linked - // targeting entity (owner Mech +0x438 -> this->linkedEntity @0x234): - Scalar torsoLimitRight; // @0x1DC <- linkedEntity +0x1D8 - Scalar torsoLimitLeft; // @0x1E0 <- linkedEntity +0x1DC - Scalar torsoSpeed; // @0x1E4 <- linkedEntity +0x1E0 - Scalar rangeToTarget; // @0x1E8 <- linkedEntity +0x1E8 (and recomputed in sim @0x1EC) - Scalar targetRange; // @0x1EC computed line-of-sight distance to the target - int lockFlag; // @0x1F4 init 1 - int visible; // @0x1F8 set 0/1 from heat + line-of-sight each frame - Point3D threatVector; // @0x1FC init (0,0,0) ("ThreatVector") - Point3D compassHeading; // @0x208 init (0,0,0) ("CompassHeading"); see SetCompassHeading - Scalar hotBoxScalar; // @0x214 init 0 + Scalar flickerRate; // @0x1D8 resource +0xF4 ("FlickerRate", attr id 3) + // Torso / target read-outs sampled at construction AND per-frame in + // HudSimulation from the linked Torso subsystem (owner Mech +0x438 -> + // this->linkedEntity @0x234): + Scalar rotationOfTorsoHorizontal; // @0x1DC <- linkedEntity +0x1D8 (Torso::currentTwist; attr 4) + Scalar torsoLimitRight; // @0x1E0 <- linkedEntity +0x1DC (attr 5) + Scalar torsoLimitLeft; // @0x1E4 <- linkedEntity +0x1E0 (attr 6) + Scalar torsoSpeed; // @0x1E8 <- linkedEntity +0x1E8 (attr 7 "SpeedOfTorsoHorizontal") + Scalar rangeToTarget; // @0x1EC computed target distance; 1200.0 default; 500 m/s display slide (attr 8) + int scratch1F0; // @0x1F0 unbound / not ctor-initialized in the binary + int visible; // @0x1F4 init 1 ("Visible", attr 9; heat/page gating) + int lockFlag; // @0x1F8 init 0 ("Lock", attr 10; the :5619-5634 lock rule) + Point3D hotBoxVector; // @0x1FC init (0,0,0) ("HotBoxVector", attr 11) + Point3D threatVector; // @0x208 init (0,0,0) ("ThreatVector", attr 12); see SetThreatVector + Scalar compassHeading; // @0x214 init 0 ("CompassHeading", attr 13; yaw euler[0] + torso twist @:5676) Scalar blinkTimer; // @0x218 accumulates time, reset against flickerRate Scalar flickerTimer; // @0x21C int blinkState; // @0x224 init 1 (visible phase of the blink) @@ -193,8 +209,13 @@ void HudSimulation(Scalar time_slice); // @004b7830 (Performance, PTR @00511170) + // @004b7810 writes the Point3D @0x208 -- which the RE-DUMPED attr table + // (2026-07-19) proves is the THREAT vector, not the compass (the compass + // is the Scalar @0x214). Renamed from the old mislabel SetCompassHeading; + // no port caller exists (the port threat-trail feed goes through the + // reticle globals, btl4vid.cpp). void - SetCompassHeading(const Point3D &heading); // @004b7810 (writes compassHeading @0x208) + SetThreatVector(const Point3D &threat); // @004b7810 (writes threatVector @0x208) //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Subsystem virtual overrides (vtable @00511510)