The sweep steps past a display it cannot draw

A Live Cam's map was blank and its score frozen at 1000 while the gauge
canvas underneath was being drawn perfectly - 50 static entities and one
mover, every sample, centre tracking the camera. The trace that settled it
found zero "map copy running" lines against that: the canvas was alive and
simply never reached the pane.

SVGA16::Update services one display per call and steps mDisplayToUpdate at
the END of the function. Both of its early bails returned before ever
getting there. A camera's cameraInit page configures the secondary port
and nothing else - no auxUL2, auxC, auxUR2, auxLL or auxLR - so the MFD
branch could never be serviced, and the first time the counter landed on
an MFD slot it stopped dead. Display 0's copy is the map, so it ran once,
early, and never again. The pane kept that one frame for the whole race: a
blank map, because nothing had registered with the renderer that early,
and a score showing its opening value. "It had name and score at the start
of the mission" was the tell, and it was accurate.

Both bails now step the rotation on the way out, so the sweep moves past a
display it cannot service instead of parking on it. A station with no MFDs
therefore copies its secondary every third call, which is the same cadence
a pod gets.

Pod regression: the map copy still runs every pass at the same ~9900 lit
pixels as before. A pod has all five MFD ports and never takes either
bail, so that path is untouched.

Three wrong diagnoses preceded this one - the gauge page, the renderer
link, and a snapshot theory - and each died to a measurement rather than
an argument. The trace that found it was worth more than any of them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-08-10 22:05:49 -05:00
co-authored by Claude Opus 5
parent d08404bf50
commit 7a3b117f61
+26 -1
View File
@@ -5169,6 +5169,25 @@ Logical SVGA16::Update(Logical forceAll)
//No MFDs to draw, break out early. The sweep counter resets
//too: leaving it part-used would keep the renderer in its
//copy phase, and it never draws another gauge while there.
//
// The ROTATION has to step on the way out as well, and did
// not. It lives at the END of this function, so returning
// from here parked mDisplayToUpdate on the display we cannot
// service - and a station with no MFD ports can never
// service it, so the counter stopped dead the first time it
// landed there. Display 0's copy, which is the map, then
// never ran again: a Live Cam, whose cameraInit page
// configures the secondary port and nothing else, kept
// whatever the one early pass had put on the pane. A blank
// map, because nothing had registered with the renderer that
// early, beside a score frozen at its opening value - while
// the canvas underneath went on being drawn perfectly, which
// is what made this so hard to see.
mDisplayToUpdate++;
if (mDisplayToUpdate >= NUMGAUGEWINDOWS)
{
mDisplayToUpdate = 0;
}
mDisplaysCopiedThisPass = 0;
return False;
}
@@ -5181,7 +5200,13 @@ Logical SVGA16::Update(Logical forceAll)
secPalette = &((SVGA16 *) secPort->graphicsDisplay)->palette[secPort->paletteID];
} else
{
//No secondary, skip - and end the sweep, as above.
//No secondary, skip - and end the sweep, as above, stepping
//past the display we cannot service for the same reason.
mDisplayToUpdate++;
if (mDisplayToUpdate >= NUMGAUGEWINDOWS)
{
mDisplayToUpdate = 0;
}
mDisplaysCopiedThisPass = 0;
return False;
}