BT410 5.3.41: the plane-write hunt -- two more hypotheses dead, defect bounded

PlayerStatus (dirty-gated, blits an 8-bit pixmap -- but the widget map for a
DIRTY run contains no playerStatus at all; it belongs to cameraInit and never
exists in a mech cockpit) and heat-driven redraw (a BT_FORCE_FIRE run came
back clean).  Seven hypotheses killed by measurement so far.

It is a heisenbug: dirty on ~3 runs in 25, and every run since instrumenting
has been clean.  The pattern tracks STARTUP LOG VOLUME -- the three dirty
runs all had the lighter conf, and a chatty trace slows init enough to
suppress it.  The blit trace is therefore narrowed to fire only for pixmaps
landing on a non-palette port, which is near-silent when nothing is wrong.

That narrowed trace caught real traffic: 17x17 PixelMap8 blits onto
Mfd1/2/3 -- 8-bit pixmaps on single-bit planes.  They render correctly, so
the library thresholds them; not the culprit but the right bug class.

Also banked a hunting recipe, because two detector traps cost runs: Eng1 == 0
means the cockpit is not up (not dirty), and an early capture during mission
start caught a full 3-D cockpit frame with the gauges at pod positions
(Eng1 62927) that did not recur over the next minute.  BTDPL.INI is in the
mount and DPLRenderer is linked, so the dPL path may emit a frame during
launch even with L4VIDEO=OFF -- first evidence the 3-D path produces
anything, and explicitly NOT a claim that btl4vid works.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-27 22:43:13 -05:00
co-authored by Claude Fable 5
parent 90daf5e9b7
commit 50341b4a66
2 changed files with 78 additions and 0 deletions
@@ -1020,3 +1020,44 @@ correctly to 3/5/7). Suspect the tile/strip blit for VertTwoPartBar-family
widgets writing tile pixel VALUES rather than using them as a mask with the
port colour -- the same widget draws correctly on the MFD heads, so it is
specific to this port or this call site.
--------------------------------------------------------------------------------
5.3.41 -- the hunt for the plane-write defect: not caught, but bounded
--------------------------------------------------------------------------------
Two more hypotheses died, and the defect gained a nasty property.
5. PlayerStatus blitting `recoloredMech` through DrawPixelMap8 -- it is
dirty-gated (change-driven, matching the intermittency) and DOES blit an
8-bit pixmap. KILLED: the widget map for a DIRTY run contains no
playerStatus at all. It is built by cameraInit (the observer page) and
never exists in a mech cockpit.
6. Heat driving the coolant values and thus the change-driven redraw.
KILLED: a run with BT_FORCE_FIRE=1 (weapons firing, heat climbing) came
back clean.
IT IS A HEISENBUG. Rate across this session: dirty on roughly 3 runs in 25.
Every run since instrumentation was added has been clean -- and the pattern
lines up with STARTUP LOG VOLUME: runs with the attribute log or the blit
trace enabled (hundreds of DEBUG_STREAM lines during init) are clean; the
three dirty runs all had the lighter conf. A chatty trace slows startup
enough to suppress it, which is why the blit trace was narrowed to fire only
for pixmaps landing on a NON-palette port (near-silent in the clean case).
That narrowed trace did catch real traffic -- 17x17 PixelMap8 blits onto
Mfd1/Mfd2/Mfd3, i.e. 8-bit pixmaps on single-bit planes -- but those render
correctly (the MFD heads are within ~150px on clean runs), so the library
evidently thresholds them. Not the culprit, but the right bug class to keep
watching.
HUNTING RECIPE FOR NEXT TIME (two traps cost runs here):
* Detect dirty as Eng1 in (17981, 25000]. Eng1 == 0 means the cockpit is
not up yet, and my first detector read that as "dirty".
* Require the reading to be STABLE across two captures ~20s apart. An
early capture during mission start caught a completely different frame --
a full 3-D cockpit view, purple sky, canopy struts, HUD reticle, with the
gauges at POD positions rather than plane-packed (Eng1 read 62927). It
did not recur across 8 samples over the following minute, so it is an
early-run transient, not a persistent render. Worth a look on its own
though: BTDPL.INI is in the mount and the engine's DPLRenderer is linked,
so the dPL path may be producing a frame during the launch sequence even
with L4VIDEO=OFF. That is the first evidence this session that the 3-D
path emits anything at all -- do not confuse it with btl4vid being done.
+37
View File
@@ -2588,6 +2588,43 @@ void
if (ClipImage(&sourceBounds, &position, pixelmap->Data.Size))
{
//
// BLIT TRACE (env BT_VIS_BLIT): every 8-bit pixmap that reaches
// a port, with the port it lands on and the rect it covers.
// Hunting the write that puts raw packed bytes into the
// plane-packed gauge buffer.
//
//
// Log ONLY pixmap blits landing on a port that is NOT one of the
// two palette ports (sec / overlay). An 8-bit pixmap reaching a
// single-bit plane is the thing being hunted, and filtering here
// keeps the trace near-silent -- which matters, because the
// defect is a STARTUP TIMING race and a chatty trace suppresses
// it (six consecutive clean runs once logging was added).
//
if (getenv("BT_VIS_BLIT") != NULL
&& graphicsPort != NULL && graphicsPort->name != NULL
&& stricmp(graphicsPort->name, "sec") != 0
&& stricmp(graphicsPort->name, "overlay") != 0)
{
static int blitSamples = 0;
if (blitSamples < 400)
{
++blitSamples;
DEBUG_STREAM << "[blit] port='"
<< ((graphicsPort != NULL && graphicsPort->name != NULL)
? graphicsPort->name : "(null)")
<< "' at " << position.x << "," << position.y
<< " src " << sourceBounds.bottomLeft.x << ","
<< sourceBounds.bottomLeft.y << ".."
<< sourceBounds.topRight.x << ","
<< sourceBounds.topRight.y
<< " size " << pixelmap->Data.Size.x << "x"
<< pixelmap->Data.Size.y
<< " opaque=" << (opaque ? 1 : 0)
<< " rot=" << rotation << "\n" << flush;
}
}
graphicsPort->
DrawPixelMap8(
currentOperation,