Glass panels: flash at full rate when unfocused + red Panic/Eject button
Two glass-panel indicator fixes reported by playtesters. 1. FLASH SLOW UNLESS FOCUSED. The per-display panel windows repaint off a 62ms WM_TIMER, and Windows coalesces/throttles timer + paint messages for a window that is in the BACKGROUND (unfocused) -- so with the game window holding focus the panels' lamp flash (a repaint-driven animation) crawled, and giving a panel focus un-throttled it. (My earlier surround fix drew in the main D3D frame and never touched these separate windows.) New BTGlassPanels_Tick(), called once per frame from the main render loop (L4VIDEO), drives a synchronous InvalidateRect+UpdateWindow at the ~16Hz flash cadence -- the main loop runs every frame regardless of which window has focus, and the forced paint bypasses the throttled timer-message path. The WM_TIMER stays for its one-shot re-snap. 2. RED PANIC/EJECT. 0x3D is the Panic/Eject button; on the blue flight panel it was just another blue block. The shared flight-grid geometry (L4RIOBANK) now tags 0x3D as colorClass 0 (red); L4GLASSWIN's AdoptBank maps colorClass 0 -> ClrRed explicitly (the flight bank's ClrBlue default no longer swallows it), and the surround (L4VB16) already renders non-blue/yellow as red -- so the eject stands out red in both the surround and the exploded window. Verified: Release links clean (40 tolerated /FORCE externals only); exploded panels boot + run 13s no crash under the per-frame repaint pump; riobank dump confirms 0x3d class=0 (red), neighbours class=2 (blue). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -190,7 +190,9 @@ static void
|
||||
GButton &b = w.buttons[w.buttonCount++];
|
||||
b.address = src.address;
|
||||
b.color = (src.colorClass == 1) ? ClrYellow
|
||||
: (src.colorClass == 2) ? ClrBlue : color;
|
||||
: (src.colorClass == 2) ? ClrBlue
|
||||
: (src.colorClass == 0) ? ClrRed // 0 = red (MFD, and the red Panic/Eject 0x3D)
|
||||
: color;
|
||||
b.rect.left = src.x + dx;
|
||||
b.rect.top = src.y + dy;
|
||||
b.rect.right = src.x + dx + src.w;
|
||||
@@ -1050,3 +1052,43 @@ void
|
||||
if (subFont) { DeleteObject(subFont); subFont = NULL; }
|
||||
if (gStage) { delete[] gStage; gStage = NULL; }
|
||||
}
|
||||
|
||||
//###########################################################################
|
||||
// Per-frame repaint pump (2026-08-04, "indicators flash slowly unless focused").
|
||||
//
|
||||
// These windows repaint off a 62 ms WM_TIMER. Windows COALESCES/THROTTLES timer
|
||||
// AND paint messages for a window that is in the BACKGROUND (not focused) -- so
|
||||
// when the game window (or another app) holds focus, the panel's WM_TIMER slows
|
||||
// to a crawl and the lamp FLASH (a repaint-driven animation: BTLampBrightnessOf
|
||||
// alternates the shade off GetTickCount every paint) drags. Giving the panel
|
||||
// focus un-throttles its timer, which is exactly what playtesters saw.
|
||||
//
|
||||
// Fix: drive the repaint from the MAIN render loop (BTGlassPanels_Tick, called
|
||||
// once per frame from L4VIDEO), gated to the same ~16 Hz flash cadence. The main
|
||||
// loop runs every frame while the game is up regardless of which window has focus,
|
||||
// and InvalidateRect + UpdateWindow forces a SYNCHRONOUS WM_PAINT -- bypassing the
|
||||
// throttled timer-message path entirely. The WM_TIMER stays (it still owns the
|
||||
// one-shot re-snap); a focused window just repaints from whichever fires first.
|
||||
//###########################################################################
|
||||
|
||||
void
|
||||
BTGlassPanels_Tick()
|
||||
{
|
||||
if (gWinCount == 0)
|
||||
return;
|
||||
|
||||
static unsigned long sLastPaint = 0;
|
||||
unsigned long now = GetTickCount();
|
||||
if (now - sLastPaint < (unsigned long)RepaintMilliseconds)
|
||||
return;
|
||||
sLastPaint = now;
|
||||
|
||||
for (int i = 0; i < gWinCount; ++i)
|
||||
{
|
||||
if (gWins[i].hwnd != NULL)
|
||||
{
|
||||
InvalidateRect(gWins[i].hwnd, NULL, FALSE);
|
||||
UpdateWindow(gWins[i].hwnd); // synchronous paint, not the throttled queue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,7 +258,10 @@ void
|
||||
int row = i / columns;
|
||||
int x = originX + column * (cw + gap);
|
||||
int y = originY + row * (ch + gap);
|
||||
Push(out, baseAddress + i, x, y, cw, ch, 2,
|
||||
// Flight blocks are blue (colorClass 2), EXCEPT the Panic/Eject at 0x3D:
|
||||
// red (colorClass 0) so the eject stands out on the blue panel.
|
||||
int cc = (baseAddress + i == 0x3D) ? 0 : 2;
|
||||
Push(out, baseAddress + i, x, y, cw, ch, cc,
|
||||
(inert != 0) ? inert[i] : 0,
|
||||
(labels != 0) ? labels[i] : 0);
|
||||
GrowBounds(out, x, y, cw, ch);
|
||||
|
||||
@@ -8952,6 +8952,17 @@ void DPLRenderer::ExecuteImplementation(RendererComplexity, RendererOrigin::Inte
|
||||
extern void BTGaugeWindowRenderAndPresent(LPDIRECT3DDEVICE9 device);
|
||||
BTGaugeWindowRenderAndPresent(mDevice);
|
||||
|
||||
#ifdef BT_GLASS
|
||||
// Drive the per-display glass panels' repaint from the (always-running) main
|
||||
// loop so their lamp flash keeps animating when they're in the background --
|
||||
// Windows throttles an unfocused window's own WM_TIMER ("indicators flash
|
||||
// slowly unless you focus that window"). No-op unless the panels are up.
|
||||
{
|
||||
extern void BTGlassPanels_Tick();
|
||||
BTGlassPanels_Tick();
|
||||
}
|
||||
#endif
|
||||
|
||||
// DIAG (turn-hitch hunt): draw CPU is _rt0..here; Present blocks on the GPU.
|
||||
LARGE_INTEGER _rt1; QueryPerformanceCounter(&_rt1);
|
||||
// COCKPIT LETTERBOX: uniform-scale the canvas into the client (NULL = the
|
||||
|
||||
@@ -31,6 +31,16 @@ void
|
||||
void
|
||||
BTGlassPanels_Destroy();
|
||||
|
||||
//
|
||||
// Per-frame repaint pump. Call once per frame from the main render loop so the
|
||||
// per-display windows' lamp flash keeps animating even when they are in the
|
||||
// background (Windows throttles a background window's own WM_TIMER; this drives a
|
||||
// synchronous repaint at the flash cadence instead). No-op unless the windows
|
||||
// are up. See the note at the definition (L4GLASSWIN.cpp).
|
||||
//
|
||||
void
|
||||
BTGlassPanels_Tick();
|
||||
|
||||
//
|
||||
// True when BT_GLASS_PANELS mode is selected (default ON under `-platform
|
||||
// glass`, OFF otherwise). Read by the render loop / L4VB16 dev-composite to
|
||||
|
||||
Reference in New Issue
Block a user