# 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] '' ... -> 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)