Glass panel flicker FIXED: layered window + lamp-period repaint timer (issue #13)

Human-verified (epilectrik, live): the panel is steady on the SAME monitor
as the game.  Two root causes, both cured:
1. D3D-vs-GDI presentation contention -- the game's ~60Hz presents fought
   the panel's GDI redraws on a shared display (single-monitor users had
   no escape; moving the panel to another monitor cleaned it, the tell).
   WS_EX_LAYERED + opaque SetLayeredWindowAttributes: DWM now composites
   the panel independently of the D3D swap chain.
2. Sampling beat -- the 100ms repaint timer sampled the authentic RIO lamp
   flash half-periods (125/250/500ms) into an irregular 'broken lamp'
   strobe.  Timer -> 62ms (~half the fastest half-period): flashing lamps
   now blink at their even, authored tempo.
(Stacked on the earlier double-buffer/erase-suppression cleanup.)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-20 07:50:44 -05:00
co-authored by Claude Fable 5
parent aa2432be7e
commit cb190aa00a
+10 -2
View File
@@ -37,7 +37,9 @@ enum
PanelMargin = 6,
FirstRow = 1, // the shared layout leaves grid row 0 empty
RepaintTimerId = 1,
RepaintMilliseconds = 100
RepaintMilliseconds = 62 // issue #13: ~half the fastest lamp-flash half-period
// (125ms) -- the old 100ms SAMPLED the 125/250/500ms
// flash rhythms into an irregular "broken lamp" beat
};
enum GroupKind { KindMfd, KindColumn, KindKeypad };
@@ -551,8 +553,13 @@ void
panel_x = 0;
}
// Issue #13: WS_EX_LAYERED -- a layered window is composited by DWM
// independently of the game's D3D swap chain, ending the D3D-vs-GDI
// presentation contention that strobed the panel on the game's monitor
// (single-monitor setups had no escape). Fully opaque; behavior is
// otherwise identical.
panelWindow = CreateWindowExW(
WS_EX_TOPMOST,
WS_EX_TOPMOST | WS_EX_LAYERED,
L"BTPadPanelWnd", L"BattleTech - Cockpit Buttons",
style,
panel_x, 12,
@@ -563,6 +570,7 @@ void
DEBUG_STREAM << "[padpanel] CreateWindow failed\n" << std::flush;
return;
}
SetLayeredWindowAttributes(panelWindow, 0, 255, LWA_ALPHA); // opaque layer
SetTimer(panelWindow, RepaintTimerId, RepaintMilliseconds, NULL);
ShowWindow(panelWindow, SW_SHOWNOACTIVATE);
DEBUG_STREAM << "[padpanel] cockpit button panel up ("