Files
BT412/scratchpad/wf_3_MessageBoard_verify.md
T
arcattackandClaude Opus 4.8 4a4ec6855c gauge-complete P4e: SectorDisplay reconstructed + registered -> radar SECTOR X/Z read-out LIVE
The "sectorDisplay" cockpit primitive (Secondary overlay, the radar SECTOR X/Z
coordinate read-out) was PROSE-ONLY in btl4gau3 (placeholder Make, no ctor/
methodDescription/registration) -> the config line was parse-SKIPPED and never built.

Reconstructed byte-verified from the disassembly (ctor @4c9e10, Execute @4ca07c,
methodDescription PE-parse): SectorDisplay : GraphicGauge, sizeof 0xC4. Its Execute
reads the linked mech's world position and shows two 100-unit sector numerics:
  numericA = Round(-localOrigin.z * 0.01) + 500
  numericB = Round( localOrigin.x * 0.01) + 500
(rounding = round-to-nearest == FUN_004dcd94, corrected from the reviewer's wrong
"truncate" claim; 0.01 const PE-verified; -Z/+X axis + fchs confirmed from asm).
Overridden slots: LinkToEntity(9) caches the subject, BecameActive(3, non-inactivating),
Execute(16) -> satisfies the container-Execute rule. Layout overflow-locked
(static_assert sizeof<=0xC4). Make/ctor/dtor mirror the registered PilotList sibling;
the config image name is copied (nameCopy) since Execute reads it per-frame.
Registered in BTL4MethodDescription[].

VERIFIED LIVE (BT_SECTOR_LOG): Make port=1 pos=(125,579) image=helv15.pcc gridCached=1;
Execute -Z=960.4 X=361.6 -> sectorA=510 sectorB=504 (Round(9.6)+500=510, Round(3.6)+500=504
-- authentic 100-unit sectors from live mech position). Gauge composite renders full,
no crash. The skip list is now exactly the two remaining widgets (prepEngr x12, messageBoard).

Also: a permanent BT_GAUGE_SKIP_LOG diagnostic (GAUGREND.cpp, gated) that logs each
unregistered gauge primitive the dev-parse skips -- the tool that pinned this down
(earlier "not built" runs were killed before the lazy gauge-renderer init).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 21:25:48 -05:00

42 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
I have completed the adversarial verification against the raw decomp, the CFG, the sibling templates, and the data-binding source files. Every load-bearing claim in the spec was checked. Here is the corrected verdict.
---
# ADVERSARIAL VERIFY — MessageBoard reconstruction spec
**Bottom line:** the spec is **substantially CORRECT and ready-to-implement**. All addresses, `sizeof`, ctor offset writes, the base class, the methodDescription row set, the Make/dtor conventions, and the DEFERRED-data verdict are verified against the binary. The spec's **three header corrections are all genuinely correct**, and its **correction of the task hint** (source is BTPlayer status queue, *not* SubsystemMessageManager 0xBD3) is verified. I found **one wrong citation**, **one fidelity deviation to flag**, and **two small notes**. No blocking errors.
## What I verified as CORRECT (accept as-is)
- **Identity / addresses** (all confirmed `part_014.c`): Make `@004cb678:3825`, ctor `@004cb704:3849`, dtor `@004cb788:3872`, TestInstance `@004cb7e4:3892``FUN_004448ac`, no-op slot `@004cb7f4:3903`, BecameActive `@004cb7fc:3913`, SetSource `@004cb818:3925`, Execute `@004cb82c:3936`, vtable `PTR_FUN_0051bddc` (`:3858/:3876`). Base = `GraphicGauge` (`FUN_00444818`), ends at 0x90.
- **sizeof 0xA4 == Make alloc** `FUN_00402298(0xa4)` (`:3832`). ✓
- **ctor offset writes** (`:3859-3864`): `[0x25]`=stripImage(0x94), `[0x26]`=color(0x98), `[0x24]`=trackedMech(0x90)=0; `SetOrigin(x,y)` via `localView` vtbl+0x10. ✓
- **The three header fixes are all correct:**
- `enabled`**`Entity *trackedMech`**: 0x90 is a pointer dereferenced at `+0x190` (`iVar1 = *(*(param_1+0x90)+400)`, `:3950`) and written only by `SetSource` (`:3928`). It is not a bool. ✓
- **previousMessageId / previousNameId are SWAPPED** in the current header. Binary proof: BecameActive writes `0x9c=-1, 0xa0=-2` (`:3916-3917`); Execute compares **messageId vs 0xa0** (`:3960`) and **nameEntity(iVar5) vs 0x9c** (`:3983`). ⇒ `0x9c=previousNameId(-1)`, `0xa0=previousMessageId(-2)` — exactly the spec's relabel, and it matches the prose at `btl4gau3.cpp:784`. ✓
- **methodDescription rows** match the CFG call `messageBoard(E, ModeAlwaysActive, btsmsgs.pcx, 0)` at `L4GAUGE.CFG:4913-4917` under the `offset=(113,607)` at `:4912` → 4 rows `typeRate/typeModeMask/typeString/typeColor`; position threaded from the `offset` directive; **entity param ignored** (binary Make never touches `param_4`, `:3825-3843`). This is exactly the PilotList template (`btl4gau3.cpp:218-239`), except MessageBoard *does* use `position` (SetOrigin). ✓
- **Make presence-check + return** is byte-faithful *and* matches the codebase template `VertTwoPartBar::Make` (`btl4gaug.cpp:1099-1107`: `Get(string); if NULL return False; Release; return True`). `content/GAUGE/BTSMSGS.PCX` exists → returns True in practice. ✓
- **dtor** correctly omits the base-dtor call (`FUN_00444870` is compiler epilogue glue, `:3880`) — avoids the double-dtor bug. `FUN_004700ac` is the string-dup helper used across widgets; freeing via `delete[]`/`FUN_004022e8` is consistent. ✓
- **Data-binding blocker — CONFIRMED on both legs:**
- **SetSource (`FUN_004cb818`) has ZERO callers** anywhere in `reference/decomp/all/` (grep returns only its own definition) → `trackedMech` stays NULL. ✓
- **`StatusMessagePool = 0`** — the NULL stub is real (`btstubs.cpp:62`), and the only writer of `BTPlayer+0x1dc` is gated `if (sender_owner && StatusMessagePool)` (`btplayer.cpp:508`) → no messages ever created. ✓
- **Task-hint correction is right:** `SubsystemMessageManager` (`messmgr.cpp`) *is* reconstructed but is the per-mech damage/explosion hub (`ConsolidateAndSendDamage`/`weaponExplosions`), not a `{msgId,nameEntity}` source; MessageBoard never references it. `mech+0x190`=owningPlayer confirmed (`btplayer.cpp:68`, `MECH_OWNING_PLAYER`); `DAT_004efc94`==application (App+0xc8 name cache, `btplayer.cpp:53`). ✓
- **Systemic checks:** leaf `GraphicGauge` (not a container) that overrides both Execute and a non-inactivating BecameActive → Container-Execute/Fail rule satisfied. No shadow/alias/phantom fields (all new slots 0x900xA3, ends exactly at 0xA4). Raw `mech+0x190`/`player+0x1dc`/`+0x1e0`/App+0xc8 reads kept out of the widget TU via the `BTResolveMessageBoard` bridge (databinding trap avoided). Every-mech crash risk: none (early return on NULL). `/FORCE` stub for the bridge required. ✓
## CORRECTIONS (the list of what I changed)
1. **[Citation fix — §2, §5, §6] `StatusMessagePool`'s NULL definition is `btstubs.cpp:62`** (`MemoryBlock *StatusMessagePool = 0;`), **not** `btplayer.cpp:135/508`. Those btplayer lines are the `extern` decl and the guard site; the actual stub lives in `btstubs.cpp`. The conclusion (feed is dead) is unchanged — only name the correct file so the follow-up (wiring the pool) edits the right place.
2. **[Fidelity deviation — §4.8, must be flagged, not fixed] The Execute name-cell path is a STRUCTURAL simplification, not byte-faithful.** The binary stores the *previous name ENTITY POINTER* at 0x9c and, when the sender changes to "none", looks up that previous entity's name bitmap via its `+0x1e0` key and **erases** it with `DrawBitMap` (vtbl+0x54, `:3992-3996`). The spec collapses 0x9c to a boolean `nameState` (0/1) and drops the erase-previous path. **While DEFERRED this is functionally identical** (nameEntity always 0, previousNameId init 1 → first Execute takes the `iVar5==0 && prev==-1` clear branch, `:3986-3990`, matching the binary), so it is safe for the landing. **But it changes `previousNameId`'s semantics from pointer→int**, so when the status feed goes live the entity-pointer tracking + erase branch must be restored for correct name repainting. Keep the spec's body for the deferred landing; add a code comment marking this as the restore point. (The spec does acknowledge the deviation; I am raising it to an explicit action item because it silently redefines a member.)
3. **[Minor note — §1/§4.5] The no-op vtable slot `@004cb7f4` ("ShowInstance"):** the binary override is a bare `return`. The spec omits it and inherits (per the PilotList/PlayerStatus precedent). This is only byte-faithful **if** the `GraphicGauge` base slot is itself trivial for this call site; if strict fidelity is wanted, add an empty override. Low risk (leaf widget, slot rarely hit) — accept the omission but note it.
4. **[No change, confirmation] Make's `bool` return on a missing bitmap** is binary-faithful and template-matched; because `BTSMSGS.PCX` is present it returns True, so registration/parse is unaffected. No action.
Everything else in the spec — the layout table + `static_assert` locks, ctor/dtor/BecameActive/TestInstance/SetSource/Make bodies, the `BTResolveMessageBoard` bridge + returns-`False` stub in `btplayer.cpp`, the `methodDescription` literal, and the registration line inserted before `&BTL4ChainToPrevious` in `btl4grnd.cpp` (after `GeneratorCluster`) plus adding `static MethodDescription methodDescription;` to the class — is **verified and should be implemented as written**.
## FINAL CONFIDENCE: **HIGH**
- Layout/methods/registration/sizeof/offsets: **HIGH** — fully recovered and cross-checked against `part_014.c:3823-4013` and the `PilotList`/`VertTwoPartBar` templates.
- DEFERRED/empty verdict: **HIGH** — both blockers independently confirmed in-source (`btstubs.cpp:62` NULL pool; SetSource zero callers).
- Only residual **UNKNOWN** (non-blocking, for the *alive* path, not the landing): the exact `Player__StatusMessage` record layout (`+0xc` messageId, `+0x10` nameEntity) and the App+0xc8 name-bitmap cache shape needed inside `BTResolveMessageBoard` once `StatusMessagePool` is wired — decode `FUN_0042e580` (AddStatusMessage) + the message-record ctor `FUN_0042d990` to expose them as compiled accessors. The default landing (safe no-op) does not touch these.