POD MFD bring-up: BT_POD_SURFACES bare-panel mode + placement receipts + probe
Nick's crash cart is the first shot at driving the real MFD panels, so the
pieces the cab needs that the desktop glass path lacked:
- BT_POD_SURFACES=1 (L4GLASSWIN): crop every display window to its SURFACE
(MFDs exactly 640x480, radar 480x640 portrait), drop the on-screen RIO
button banks -- the cab's buttons are PHYSICAL, so drawing fake ones onto a
real panel is exactly wrong -- go frameless, and skip the Flight Controls
pad entirely (6 windows, not 7). Per-window ",bare" in glass_layout.cfg
for mixed rigs (idempotent with the global mode).
- Placement receipts: each window logs which PHYSICAL monitor it landed on
("[glasswin] 'Heat MFD' surface=Heat at X,Y 640x480 bare -> monitor
\.\DISPLAYn (...)"). Nobody can see 7 surfaces at once on a cab, and over
Chrome Remote Desktop you cannot see the panels at all -- the log is the
only confirmation the map is right.
- tools/podprobe.ps1: run-on-the-pod topology probe (no install/admin) --
GPUs, every monitor's virtual-desktop rect, EDID make/model, serial ports
(the RIO board), session type, plus a PROPOSED glass_layout.cfg assigning
the six surfaces to the non-primary monitors. Self-tested here (correctly
reports a single-monitor laptop and declines to map).
Local verify: 5 MFDs at 640x480 bare + portrait radar + Flight Controls
dropped, receipts printed. KB: pod-hardware §MFD PANELS ON REAL HARDWARE
(incl. WHY the 1995 path is not the route -- NVIDIA Horizontal Span is gone
from post-XP drivers and per-adapter exclusive fullscreen is fragile over a
remote session) + glass-cockpit env table.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
bf39b81b9d
commit
67a4f09e86
@@ -0,0 +1,150 @@
|
||||
# podprobe.ps1 -- pod / crash-cart display + I/O topology probe.
|
||||
#
|
||||
# Run ON THE POD PC (PowerShell, no install, no admin):
|
||||
# powershell -ExecutionPolicy Bypass -File podprobe.ps1
|
||||
#
|
||||
# Prints and writes podprobe.txt: GPUs, every monitor with its VIRTUAL DESKTOP
|
||||
# rect (the coordinates glass_layout.cfg needs), EDID make/model (to identify
|
||||
# the original pod panels), serial ports (the RIO board), and a PROPOSED
|
||||
# glass_layout.cfg mapping the six pod surfaces onto the non-primary monitors.
|
||||
#
|
||||
# Then, in the game's working directory:
|
||||
# copy the proposed glass_layout.cfg in
|
||||
# set BT_GLASS=1 & set BT_GLASS_PANELS=1 & set BT_POD_SURFACES=1
|
||||
# set BT_GLASS_LAYOUT=load (add =save to persist drags instead)
|
||||
# btl4.exe -platform pod
|
||||
# The log prints one "[glasswin] '<title>' ... -> monitor \\.\DISPLAYn" line per
|
||||
# surface: that is the receipt that a picture landed on the right panel.
|
||||
|
||||
$ErrorActionPreference = 'Continue'
|
||||
$out = New-Object System.Collections.ArrayList
|
||||
function W($s) { [void]$out.Add($s); Write-Host $s }
|
||||
|
||||
W "==================== BT411 POD PROBE ===================="
|
||||
W ("host : {0}" -f $env:COMPUTERNAME)
|
||||
W ("when : {0}" -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'))
|
||||
W ("windows : {0}" -f (Get-CimInstance Win32_OperatingSystem).Caption)
|
||||
W ""
|
||||
|
||||
W "---- GPUs ----"
|
||||
try {
|
||||
Get-CimInstance Win32_VideoController | ForEach-Object {
|
||||
W (" {0}" -f $_.Name)
|
||||
W (" driver {0} ({1}) mode {2}x{3} ram {4} MB" -f `
|
||||
$_.DriverVersion, $_.DriverDate, $_.CurrentHorizontalResolution,
|
||||
$_.CurrentVerticalResolution, [int]($_.AdapterRAM / 1MB))
|
||||
}
|
||||
} catch { W " (video controller query failed: $_)" }
|
||||
W ""
|
||||
|
||||
W "---- MONITORS (virtual-desktop rects -- these are the layout coordinates) ----"
|
||||
Add-Type -AssemblyName System.Windows.Forms | Out-Null
|
||||
$screens = [System.Windows.Forms.Screen]::AllScreens
|
||||
$i = 0
|
||||
foreach ($s in $screens) {
|
||||
$b = $s.Bounds
|
||||
W (" [{0}] {1}{2} x={3} y={4} {5}x{6} bpp={7}" -f `
|
||||
$i, $s.DeviceName, $(if ($s.Primary) { " *PRIMARY*" } else { "" }),
|
||||
$b.X, $b.Y, $b.Width, $b.Height, $s.BitsPerPixel)
|
||||
$i++
|
||||
}
|
||||
W (" total screens: {0}" -f $screens.Count)
|
||||
W ""
|
||||
|
||||
W "---- EDID identity (which physical panel is which) ----"
|
||||
try {
|
||||
Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID | ForEach-Object {
|
||||
$mk = -join ($_.ManufacturerName | Where-Object { $_ -ne 0 } | ForEach-Object { [char]$_ })
|
||||
$nm = -join ($_.UserFriendlyName | Where-Object { $_ -ne 0 } | ForEach-Object { [char]$_ })
|
||||
$sn = -join ($_.SerialNumberID | Where-Object { $_ -ne 0 } | ForEach-Object { [char]$_ })
|
||||
W (" {0} | make={1} model='{2}' serial={3} year={4}" -f `
|
||||
$_.InstanceName, $mk, $nm, $sn, $_.YearOfManufacture)
|
||||
}
|
||||
} catch { W " (EDID query failed -- normal over some remote sessions: $_)" }
|
||||
W ""
|
||||
|
||||
W "---- SERIAL PORTS (the RIO board lives on one of these) ----"
|
||||
try {
|
||||
$sp = Get-CimInstance Win32_SerialPort
|
||||
if ($sp) { $sp | ForEach-Object { W (" {0} {1}" -f $_.DeviceID, $_.Name) } }
|
||||
else {
|
||||
$reg = 'HKLM:\HARDWARE\DEVICEMAP\SERIALCOMM'
|
||||
if (Test-Path $reg) {
|
||||
(Get-ItemProperty $reg).PSObject.Properties |
|
||||
Where-Object { $_.Name -notlike 'PS*' } |
|
||||
ForEach-Object { W (" {0} -> {1}" -f $_.Name, $_.Value) }
|
||||
} else { W " (none found)" }
|
||||
}
|
||||
} catch { W " (serial query failed: $_)" }
|
||||
W ""
|
||||
|
||||
W "---- REMOTE SESSION ----"
|
||||
W (" SESSIONNAME={0} (a console session drives the real panels; an RDP" -f $env:SESSIONNAME)
|
||||
W " session gets a VIRTUAL display and will NOT light the pod monitors."
|
||||
W " Chrome Remote Desktop attaches to the CONSOLE -- that is what we want."
|
||||
W ""
|
||||
|
||||
# ---------------- proposed layout ----------------
|
||||
# Pod surface roles, in the order the cab reads them. Sizes are the native
|
||||
# surface sizes the game creates in BT_POD_SURFACES mode.
|
||||
$roles = @(
|
||||
@{ title = 'Heat MFD'; w = 640; h = 480; note = 'upper LEFT (coolant)' },
|
||||
@{ title = 'Engineering'; w = 640; h = 480; note = 'upper CENTER (engineering)' },
|
||||
@{ title = 'Comm MFD'; w = 640; h = 480; note = 'upper RIGHT (hot box / comm)' },
|
||||
@{ title = 'Left Weapons'; w = 640; h = 480; note = 'lower LEFT (weapons)' },
|
||||
@{ title = 'Right Weapons'; w = 640; h = 480; note = 'lower RIGHT (weapons)' },
|
||||
@{ title = 'Secondary / Radar'; w = 480; h = 640; note = 'secondary screen (radar, portrait)' }
|
||||
)
|
||||
|
||||
$targets = @($screens | Where-Object { -not $_.Primary } | Sort-Object { $_.Bounds.Y }, { $_.Bounds.X })
|
||||
W "---- PROPOSED glass_layout.cfg ----"
|
||||
if ($targets.Count -eq 0) {
|
||||
W " ! No non-primary monitors found. Either the pod panels are not attached to"
|
||||
W " this PC, or this is a remote/virtual display session. Nothing to map yet."
|
||||
} else {
|
||||
W (" {0} non-primary monitor(s) available; assigning in top-to-bottom, left-to-right order." -f $targets.Count)
|
||||
if ($targets.Count -lt $roles.Count) {
|
||||
W (" ! Fewer panels than surfaces -- the last {0} surface(s) stay on the primary display." -f ($roles.Count - $targets.Count))
|
||||
}
|
||||
}
|
||||
|
||||
$cfg = New-Object System.Collections.ArrayList
|
||||
[void]$cfg.Add('# BT411 glass cockpit window layout -- generated by tools/podprobe.ps1')
|
||||
[void]$cfg.Add('# "<title>=x,y,w,h,noframe,bare" (bare = surface only, no desktop buttons)')
|
||||
[void]$cfg.Add('# Coordinates are VIRTUAL DESKTOP pixels; run the probe again after any')
|
||||
[void]$cfg.Add('# display rearrangement, because Windows renumbers the desktop origin.')
|
||||
for ($r = 0; $r -lt $roles.Count; $r++) {
|
||||
$role = $roles[$r]
|
||||
if ($r -lt $targets.Count) {
|
||||
$b = $targets[$r].Bounds
|
||||
# centre the surface on the panel (exact fit when the panel is 640x480)
|
||||
$x = $b.X + [int](($b.Width - $role.w) / 2)
|
||||
$y = $b.Y + [int](($b.Height - $role.h) / 2)
|
||||
$line = "{0}={1},{2},{3},{4},noframe,bare" -f $role.title, $x, $y, $role.w, $role.h
|
||||
[void]$cfg.Add($line)
|
||||
W (" {0,-18} -> {1} ({2}x{3}) at {4},{5} [{6}]" -f `
|
||||
$role.title, $targets[$r].DeviceName, $b.Width, $b.Height, $x, $y, $role.note)
|
||||
} else {
|
||||
[void]$cfg.Add(("# {0}=<x>,<y>,{1},{2},noframe,bare # no panel assigned" -f $role.title, $role.w, $role.h))
|
||||
}
|
||||
}
|
||||
|
||||
$cfgPath = Join-Path (Get-Location) 'glass_layout.cfg.proposed'
|
||||
$cfg | Set-Content -Path $cfgPath -Encoding ASCII
|
||||
W ""
|
||||
W (" wrote {0}" -f $cfgPath)
|
||||
W " -> review it, rename to glass_layout.cfg in the game's working directory."
|
||||
W ""
|
||||
W "---- NOTES ----"
|
||||
W " * The pod's main 3D view is the GAME's own window (not a glass panel); put it"
|
||||
W " on the main-view monitor with the normal window/fullscreen controls."
|
||||
W " * 640x480 panels: if Windows does not offer that mode, the surface still"
|
||||
W " renders 640x480 inside whatever mode the panel runs -- centred, not scaled."
|
||||
W " * The 1995 rig spanned the five MFDs as ONE 1280x480 surface via NVIDIA"
|
||||
W " Horizontal Span, which modern drivers removed. This per-panel window path"
|
||||
W " replaces it and needs no special driver."
|
||||
|
||||
$txt = Join-Path (Get-Location) 'podprobe.txt'
|
||||
$out | Set-Content -Path $txt -Encoding ASCII
|
||||
Write-Host ""
|
||||
Write-Host ("full report written to {0}" -f $txt)
|
||||
Reference in New Issue
Block a user