Files
TeslaRel410/emulator/pod-launch
CydandClaude Opus 4.8 86d6b950e5 emulator: B2 RIO lamp/button bezel on the VDB heads + explode-view polish
Draw the cockpit RIO buttons around the mono-MFD and radar heads (explode
layout), lit by the host-commanded lamp state -- the display side of the
in-fork glass cockpit. Live-validated 2026-07-24 (operator).

- vpxlog.cpp: per-head button bezel in pal_draw, reading serialrio's new
  RIO_GetPanelState seam. The 5 MFD heads get red buttons (4 top / 4 bottom,
  100px tall tucked under a grown 640x500 display so a 10px lip shows); the
  radar gets amber Secondary/Screen side columns (6x 104px each) plus a
  centered bottom indicator strip (the 4 spares). Lamp byte decoded to
  off/dim/bright (vRIO RioLampState, brighter of the two brightness fields);
  a press shows white-hot. No labels -- the MFD shows each button's function.
  Also swapped the two upper-outer MFD window NAMES to match their (already
  position-swapped) desktop locations.
- serialrio.{cpp,h}: RIO_GetPanelState(lamps, pressed) accessor -- returns
  false when no rio port, so non-rio configs and other heads render normally.
- pod-launch: in explode (dev) layout the Division bridge is a normal, freely
  movable window -- not pinned topmost (Focus.cs) and nudged to 8,40 so its
  title bar clears the top of the screen (its client was at 0,0, pushing the
  frame off-screen). Cockpit/kiosk keeps the topmost + 0,0 borderless look.

Only affects the explode layout and only when a serial=rio port is present.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 10:43:41 -05:00
..

pod-launch

The supervising launch entry-point for the two DOSBox titles (BattleTech / Red Planet 4.10). TeslaConsole → TeslaLauncher invokes this exe in the game dir with args selecting game/mode; it is the single authoritative handle for the whole session. See ../DEPLOYMENT-PLAN.md.

Why an exe, not a batch/script

The entry-point must own the child processes' lifetime, not hand off and exit. pod-launch:

  1. Creates a Windows Job Object with JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.
  2. Launches DOSBox-X and the render bridge into the job.
  3. Blocks on DOSBox for the whole mission.

Kill this process (TeslaLauncher force-killing a hung DOSBox on a console command) → the job's last handle closes → the kernel kills DOSBox + the renderer. This holds even on a hard TerminateProcess, where no cooperative shutdown can run. When DOSBox exits on its own (mission end) the supervisor tears the job down and returns DOSBox's exit code.

A batch file / cmd.exe / start / Start-Process can't do this: they decouple from the child, which then survives the parent. Verified: hard-killing the supervisor reaps its child via the kernel (see the job-object cascade test).

Build

Dev (needs the .NET 8 runtime present):

dotnet build -c Release

Deploy — self-contained single-file, so the air-gapped pod needs no .NET runtime installed:

dotnet publish -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true

Console argument reference

pod-launch [mode] [options] — the single installed entry-point. The product is installed once; the console activates features by the args it passes. The per-rig layout is fixed at postinstall time, so a typical call is just pod-launch bt.

Mode — the primary feature selector (positional, or --mode <name>)

Arg Activates Status
bt BattleTech, networked cockpit (net_loop.conf, looped) wired
rp Red Planet, networked cockpit (net_rp.conf, looped) wired
test VGL_LABS factory cockpit test suite (vwetest.confC:\VWETESTTSTALL.EXE): RIO, plasma, audio, video/Division calibration, Munga-net. DOSBox window defaults to 900,600 (the DOS screen is the suite's UI) wired
review mission-review PLAYBACK of last.spl recognized, exits 3 (DOS arg TBD)
test-plasma plasma-display diagnostic recognized, exits 3
reset-rio RIO reset diagnostic recognized, exits 3
audio-test audio test diagnostic recognized, exits 3

Camera ship and LIVE mission-review are not modes — same bt/rp boot; the console sets the role per-IP via the egg hostType (0 pod / 1 camera / 2 review), see ../CAMERA-REVIEW-NOTES.md. Default mode: bt.

Feature toggles

Arg Effect
--no-sound skip the ~4-min AWE32 SoundFont upload — freezes bt/rp: no AWE32 = no SOS ticks, and the default confs use the FAST (SOS) clock, so BTL4 hangs in the RIO-reset busy-wait (L4RIO.cpp SetDTR/Now(); root-caused 2026-07-10). Only safe with a SLOW-clock conf (setenv arg2=s)
--mipmap mip-filter minified textures (fixes RP floor shimmer; non-authentic)
--layout cockpit|explode cockpit = borderless VDB head windows (default); explode = 7-window debug
--no-bridge pod only, no GL render window
--no-focus skip the renderer-topmost / DOSBox-focus pass
--pipe use the <mode>_pipe conf: serials as named pipes to vRIO (pipe:vrio) + vPLASMA (pipe:vplasma), no com0com. Dev-rig policy (2026-07-17): always --pipe on the dev machine — vRIO dist ≥ 20260716-68e3d1f speaks the pipe; the plain confs (real COM ports) are for cockpits with the physical RIO/plasma
--rio use the <mode>_rio conf: the RIO cockpit board is emulated in-fork (serial1=rio) and driven by an SDL game controller + the host keyboard inside DOSBox-X — no vRIO process, no pipe, no serial round-trip. Self-contained cockpit: pad = stick/throttle/pedals + trigger/hat/torso; keyboard = the 72-button MFD/Secondary/Screen field + internal keypad (vRIO's default layout; PAUSE toggles keyboard between panel and DOS; Ctrl/Alt chords always pass through; remap via a vRIO-grammar bindings file, conf bindings:<path> or env VWE_RIO_BINDINGS). See the fork's serialrio.cpp. Dev/standalone only; mutually exclusive with --pipe. Real pods still use the plain confs (physical RIO on COM1)

Window placement (per-rig; normally fixed, overridable per-launch)

Arg Effect
--bridge-pos x,y main render window position (default 0,0)
--bridge-size w,h main render size (default 832,512 — the dPL3 board's native framebuffer res; see ../LAUNCH.md)
--dosbox-xy x,y DOSBox window position + focus (default 10,10)

Path / asset overrides (dev / edge — postinstall already wires these)

--root <dir> · --conf <path> · --dosbox <exe> · --renderer <exe> · --bridge-script <py> · --awe-rom <raw> · --work <dir>

Diagnostics

--dry-run (resolve + print the launch plan, don't launch) · -h / --help

pod-launch bt --root C:\VWE\TeslaRel410\emulator --dry-run

Exit codes the console reads back

  • normal run → returns DOSBox's exit code = the game's ExitCodeID, passed straight through (the same remote-ops code the pod loop dispatched on).
  • 2 → bad arguments (usage on stderr).
  • 3 → recognized mode not yet wired (reason on stderr).

Deploy layout it expects (under the game dir / --root)

pod-launch.exe        dosbox-x.exe        net_loop.conf  net_rp.conf
renderer.exe (frozen) roms\awe32.raw      <game content + net-boot drivers>

postinstall.bat lays this out and renders the net_*.conf (paths, realnic, WATTCP my_ip = bayIP+100). This exe just selects + launches.

TODO (tracked in DEPLOYMENT-PLAN.md OPEN items)

  • Wire the distinct non-networked modes once their DOS launch args are confirmed: review (playback app + last.spl) and the diagnostics. (The mode table in Modes.cs is the single place to add each.)
  • Swap the dev pyw live_bridge.py for the frozen renderer exe once packaging is decided (freeze vs embedded Python — with David).
  • Per-rig cockpit head RECTS (currently the pod_deploy.ps1 defaults).