Files
BT411/engine/MUNGA_L4/l4glasswin.h
T
Joe DiPrimaandClaude Opus 5 ec080cd61d pod displays: bind glass panels to EDID identity, not to Windows' shifting display numbers
Nick, after re-cabling + rebooting the pod: "the order changed ... sometimes
they change when one gets turned off and back on, at least how windows SEEs
them, even if the visual desktop tool looks the same."

Both existing binding forms are boot-fragile: `monitor:2` is an ENUMERATION
INDEX and `monitor:\.\DISPLAY4` is a GDI name Windows reassigns.  Neither
survives a panel power-cycle.  (His gos-displays.txt shows the same trap next
door in GameOS: -tmon takes DIRECTDRAW device indices -- not Windows monitor
numbers -- and a NULL-device merge shifts every index down by one on top.)

FIX: bind to the panel's own hardware identity.  EnumDisplayDevices on a
display's MONITOR child returns a DeviceID embedding the EDID manufacturer +
product code and the connector instance; neither moves across a reboot.

  DISCOVER  BT_GLASS_IDS=1 logs every attached panel's stable-id AND a
            ready-to-paste `cfg form = monitor🆔<fragment>`.  It prints the
            VOLATILE identifiers alongside on purpose: run it either side of a
            power-cycle and index/device move while stable-id does not.
  BIND      Heat MFD=monitor:id:AUO10ED,bare

NOTHING CHANGES BY DEFAULT -- no env and no `id:` prefix means identical
behaviour; `monitor:<name|index>` and raw x,y keep working, so playtester glass
builds are untouched.

An `id:` that matches nothing WARNS and falls back to computed placement.
Silence would put a picture on the wrong glass and look exactly like the bug
this form exists to prevent.

VERIFIED on a 1-monitor dev box (the pod is offline), end to end:
  * discovery printed
      stable-id = \?\DISPLAY#AUO10ED#4&31323a6c&1&UID265988#{e6f07b5f-...}
      cfg form  = monitor:id:AUO10ED
  * `Heat MFD=monitor:id:AUO10ED,bare` resolved and CENTRED correctly
      [glasswin] 'Heat MFD' bound to monitor 0,0 1920x1080 -> window at 640,300
  * a bogus id warned instead of misplacing.
The EDID-code extractor is deliberately STRUCTURAL (3 letters + 4 hex digits,
tokenising on \ # ?) rather than positional: the first cut walked separators by
position and returned EMPTY for the `\?\DISPLAY#...` interface-name form, which
is exactly the form this machine produces.  Which form you get depends on
whether EDD_GET_DEVICE_INTERFACE_NAME succeeds, so both must parse.

STILL UNPROVEN [T3] -- the pod is offline: multi-panel disambiguation when
several MFDs share one model (EDID codes collide).  The documented answer is a
longer fragment from stable-id, whose UID/instance tail differs per connector,
but that needs the cab to confirm.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018SgmXGNMXavXiafKXf9MDC
2026-08-08 14:20:38 -05:00

58 lines
2.4 KiB
C

#pragma once
//###########################################################################
//
// L4GLASSWIN -- per-display glass cockpit windows (BT_GLASS only; this TU is
// only in the build when the gate is on -- see CMakeLists.txt).
//
// Under `-platform glass` with BT_GLASS_PANELS=1 (the glass preset default),
// each pod SECONDARY display gets its OWN desktop window carrying that
// display's surface AND its RIO button bank placed AROUND it, mirroring the
// physical pod cockpit:
//
// Heat (UL) / Mfd2 (UC) / Comm (UR) / Mfd1 (LL) / Mfd3 (LR) -- red MFD
// banks split 4 buttons ABOVE / 4 BELOW the surface;
// sec radar (center, portrait) -- yellow
// Secondary buttons split LEFT / RIGHT of the surface;
// Flight Controls -- the
// no-display banks (throttle 0x38-3F, joystick/fire 0x40-47, panic).
//
// Each window is a GDI window (like L4PADPANEL + L4PLASMAWIN): the surface is
// CPU-expanded from the shared gauge pixelBuffer (SVGA16::ExpandPlaneToBGRA)
// and StretchDIBits'd in -- NO D3D, so the whole D3D dev-composite path
// (dock / separate window / overlay) stands down while these are up. Clicks
// inject through PadRIO::SetScreenButton; lamps render from GetLampState.
// Created / destroyed by the PadRIO ctor / dtor.
//
//###########################################################################
void
BTGlassPanels_Create();
void
BTGlassPanels_Destroy();
// BT_GLASS_IDS=1 -- log every attached panel's BOOT-STABLE hardware identity
// plus a ready-to-paste `monitor:id:<fragment>` line for glass_layout.cfg.
// Called from BTGlassPanels_Create; no-op unless the env is set.
void
BTGlassDumpMonitorIds();
//
// 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
// suppress the single L4PADPANEL and the D3D gauge compositing. Cheap +
// cached; safe to call before the windows exist.
//
int
BTGlassPanelsActive();