BT410 Phase 5.3.31: traced the stray blocks -- PilotList, not PlayerStatus

Three rounds of source inspection produced three wrong suspects; one
instrumented run settled it:

    [pl] PilotList slot=0 at (180,225)      <- the only drawer
    (no [ps] lines at all)

So the magenta blocks over the top-left title are PilotList's slot-0 entry
(the local pilot's name art + mech icon) on the Comm port -- content that
SHOULD draw; what is wrong is the entry's coordinate convention inside that
port.  The port geometry itself is proven right: the Comm background
(btcomm.pcx, the KILLS/DEATHS columns) lands pixel-identical in both exes.

Second, separate finding: PlayerStatus never draws at all.  The cfg builds
8 of them (sec port, 4x2, players 1..8) but our roster resolve is 0-based
against 1-based cfg player numbers, so every panel stays unbound and its
Execute returns early.  Fixing that will add a whole scoreboard page, so it
belongs in an A/B session against the shipped reference rather than a blind
edit -- both leads are written up in GAUGE-BLOCK.NOTES.md.

Also recorded: the capture rig's occlusion failure mode (CopyFromScreen
grabs whatever is in front -- one run scored 77%/47% purely because an
editor covered half the window) and the PrintWindow fix for unattended runs.

Verified build, zero faults; last valid A/B measurement stands at 94.7%
identical / 92% coverage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-27 10:45:20 -05:00
co-authored by Claude Fable 5
parent 10e1a70055
commit c6cafadb28
@@ -578,3 +578,47 @@ should also land "Aeolus" where the shipped binary draws it).
NOTE for whoever picks this up: a wrong-looking blit here is a LAYOUT bug, NOTE for whoever picks this up: a wrong-looking blit here is a LAYOUT bug,
not an art or lookup bug -- the pipeline from egg hex rows to a live BitMap not an art or lookup bug -- the pipeline from egg hex rows to a live BitMap
pointer is verified end to end. pointer is verified end to end.
## 5.3.31 -- WHO DRAWS THE STRAY BLOCKS (traced, not guessed)
Instrumented both suspects and ran. Result, unambiguous:
[pl] PilotList slot=0 at (180,225) <- the ONLY drawer
(no [ps] lines at all)
So the two magenta blocks over the top-left title are **PilotList's slot-0
entry on the Comm port**, drawing the pilot's name art + mech icon.
PlayerStatus never draws: the cfg builds 8 of them (sec port, 4x2 grid,
players 1..8) but our ResolveRosterPlayer(playerIndex) is 0-based while the
cfg's player numbers are 1-BASED, so panel 1 looks for roster index 1 and a
solo mission has only index 0 -> every panel stays unbound and its Execute
returns early. TWO SEPARATE FINDINGS, both previously mis-attributed:
1. PilotList slot 0 IS supposed to draw (the local pilot's roster row).
Its layout entry {180,225,mode 0} is the PE-recovered table value, and
the Comm port's background (btcomm.pcx, KILLS/DEATHS columns) lands
pixel-identical in both exes -- so the PORT geometry is right and what
remains is the entry's coordinate CONVENTION inside that port
(bottom-relative vs top-relative, and the name/mech sub-offsets at
mode 0: name_x = x+0x95, name_y = y-0x0d). Compare against where the
shipped exe puts "Aeolus" (framebuffer ~x 200-290, y 183).
2. PlayerStatus is off by one and therefore INERT. Feeding it
playerIndex-1 (or making the resolver 1-based) would bind the local
pilot to panel 1 and light the 4x2 scoreboard -- do this WITH the
shipped exe open in the A/B rig, since it will add a whole page of new
pixels that must be checked against the reference rather than assumed.
Method note: three rounds of source inspection produced three wrong
suspects; ONE instrumented run settled it. For anything cockpit-visual,
trace first -- the A/B rig plus a one-shot DEBUG_STREAM is cheaper than
reading call graphs.
RIG CAVEAT (hit twice): grab.ps1 uses CopyFromScreen, so a window in front
of DOSBox lands in the capture and the diff scores collapse (one run read
77%/47% purely because an editor covered the right half). SetForegroundWindow
helps but Windows refuses to raise a window when another app holds the
foreground lock. If the rig is to run unattended while the desktop is in
use, switch the grab to PrintWindow(hwnd, hdc, PW_RENDERFULLCONTENT), which
asks the window to render itself and works while occluded (verify it against
the OpenGL output mode first -- if PrintWindow comes back blank on GL, set
[sdl] output=surface in the vis_*.conf for capture runs).