diff --git a/context/pod-hardware.md b/context/pod-hardware.md index b90744c..c525d5e 100644 --- a/context/pod-hardware.md +++ b/context/pod-hardware.md @@ -339,6 +339,39 @@ Steam MP needs the **client installed and logged in** (AppID 480/Spacewar, so an purchase); installed on the cart 2026-08-06. ⚠ **#68: a failed JOIN/HOST exits the process SILENTLY** — "Steam not running" and a real crash look identical to a player. +### The HARDWARE RIO is live on the cart (2026-08-06) [T2] +`L4CONTROLS=RIO:COM1,KEYBOARD` in the frozen profile — the real cockpit board instead of PadRIO. +The whole stock path above the seam (mapper, lamps, streamed `.CTL` mappings) runs unchanged; the +109-mapping `L4` control table installs exactly as it does on a desktop. **This is independent of +the platform profile** — the cab keeps the GLASS display stack (panels + RGB split) and only the +input device changes, which is what the glass/PadRIO seam was built for. Do NOT reach for +`BT_PLATFORM=pod` to get it. + +- **Wiring:** `RIO:COMn` → `\\.\COMn` at **9600 8N1** (`L4SERIAL`); bare `RIO` defaults to COM1. + Reads are non-blocking (`ReadIntervalTimeout=MAXDWORD`, totals 0), so an absent or dead board + cannot hang the game — it just goes quiet. +- **RIO and PAD are MUTUALLY EXCLUSIVE** — both assign `rioPointer` in the `L4CONTROLS` parser, so + the last token wins. Selecting the hardware RIO turns the XInput pad OFF on that machine. + `KEYBOARD` is safe alongside: it only sets `flags.keyboardExists` and never touches + `primaryControlType`. +- **The board's own self-test is the diagnostic.** `RIO::RIO` runs it (`perform_tests = True` by + default) and writes `content\FAILURE.LOG` pages `RIOBoardErrors` / `RIODeadLamps` / `RIOErrors`, + deleting them first so the file is always current. On the cart, reproducibly: **4 missing boards** + (`Slot=3:Address=0`, `3:2`, `4:0`, `5:0`) and **16 dead lamps** (`AuxUpperRight1-8`, + `AuxUpperCenter1`, `TeslaRelay1/3`, `PanicButton`, `IcomAmpEnableRelay`, `IcomIncRelay`, + `FloorEntry`, `undefined_0x17`) — the crash cart is a PARTIAL cab, and those are the boards it + does not have. **A specific 4-of-many inventory is itself the proof the link is good**: a dead + serial line reports the whole address space missing, not four slots. +- **Input reaching the mech** was seen live as `[ctrlmap] push stick x=0.0595238 y=0` with nobody + at the cab — the physical stick sitting just outside the 5% deadband. NB when the stick is + centred this reads `x=0`, which is indistinguishable from no data: a centred-stick zero proves + nothing either way. ⚠ **Not yet checked by hand:** that stick/throttle/pedal travel and the + physical buttons drive the mech correctly, and whether the cab's pots match the `Ranger` + calibration baked into `RIO::RIO` (`JoystickX -96..96`, `JoystickY -97..108`, `Throttle 0..800`, + pedals `0..470`). A mismatch shows up as drift or short travel, not as an error. +- The boot banner names the resolved device — `GLASS (hardware RIO; plasma off [L4PLASMA])`. It + used to hardcode "PadRIO", which is a lie on a wired cab and exactly the line you read to check. + **Working on the cart, remotely.** SSH over Tailscale lands in **session 0**, which has a dummy "WinDisc" display and CANNOT see or enumerate session 1's windows — GUI work must go through `schtasks /run /tn BT411Run` (task registered `/IT`), and window enumeration over SSH silently diff --git a/game/btl4main.cpp b/game/btl4main.cpp index cd05208..96c89f6 100644 --- a/game/btl4main.cpp +++ b/game/btl4main.cpp @@ -419,6 +419,20 @@ static bool BTPlasmaDisabled(void) strcmp(p, "0") == 0); } +// +// Which control device the GLASS profile actually resolved to. The banner +// used to hardcode "PadRIO", which is a lie on a cab wired to the real board +// -- and precisely the log line someone reads to check that (2026-08-06). +// +static const char *BTControlsSummary(void) +{ + const char *c = getenv("L4CONTROLS"); + if (c == NULL) return "PadRIO"; + if (_strnicmp(c, "RIO", 3) == 0) return "hardware RIO"; + if (_strnicmp(c, "PAD", 3) == 0) return "PadRIO"; + return c; +} + static void BTEnsureContentDirectory(void) { if (GetFileAttributesA("BTL4.RES") != INVALID_FILE_ATTRIBUTES) @@ -1169,10 +1183,11 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine std::cout << "[boot] platform profile: " << (fe_menu_mode ? "MENU (front end -- no profile applied)" : gBTPlatformPod ? "POD (RIO cockpit input; multi-surface gauges/MFDs via pod hardware or explicit L4GAUGE)" - : gBTPlatformGlass ? (BTPlasmaDisabled() - ? "GLASS (PadRIO; plasma off [L4PLASMA])" - : "GLASS (PadRIO + plasma window)") + : gBTPlatformGlass ? "GLASS" : "DEV (single window + keyboard)"); + if (gBTPlatformGlass && !fe_menu_mode) + std::cout << " (" << BTControlsSummary() + << (BTPlasmaDisabled() ? "; plasma off [L4PLASMA])" : " + plasma window)"); if (!fe_menu_mode) std::cout << " [secondary displays: " << kGlassLayoutName[glassLayout] << "]"; std::cout << std::endl << std::flush; diff --git a/scratchpad/pod/podprofile.ini b/scratchpad/pod/podprofile.ini index 89d0d01..ad937ac 100644 --- a/scratchpad/pod/podprofile.ini +++ b/scratchpad/pod/podprofile.ini @@ -37,6 +37,18 @@ BT_START_INSIDE=1 # Main view fills its 800x600 panel (DISPLAY3, the primary) with no border. BT_FIT=1 +# THE REAL COCKPIT BOARD. RIO:COM1 -> \\.\COM1 at 9600 8N1 (L4SERIAL); the +# stock control path above the seam (mapper, lamps, streamed .CTL mappings) +# runs unchanged -- PadRIO was only ever standing in for this. +# * RIO and PAD are MUTUALLY EXCLUSIVE: both assign rioPointer in the +# L4CONTROLS parser, so the last token wins. This turns the XInput pad +# off on this machine. To get it back for a session, override in the +# launcher: set L4CONTROLS=PAD,KEYBOARD (the real environment wins). +# * KEYBOARD stays in the list as the fallback. It does NOT demote the RIO +# (it only sets a flag), and a silent total loss of input would be +# indistinguishable from a hang. +L4CONTROLS=RIO:COM1,KEYBOARD + # No 128x32 marquee wired on this cart -- and the glass profile would # otherwise default L4PLASMA to SCREEN and drop a plasma window on the glass. L4PLASMA=NONE diff --git a/scratchpad/pod/runpod_rio.bat b/scratchpad/pod/runpod_rio.bat new file mode 100644 index 0000000..ad67263 --- /dev/null +++ b/scratchpad/pod/runpod_rio.bat @@ -0,0 +1,24 @@ +@echo off +REM BT411 pod -- HARDWARE RIO test. Same frozen glass/RGB rig, but the input +REM device is the real cockpit board on COM1 instead of PadRIO. +REM L4CONTROLS=RIO:COM1 -> RIO opens \.\COM1 at 9600 8N1 (L4SERIAL). +REM KEYBOARD stays in the list so the cab is still playable if the board is +REM dead -- a silent loss of all input would be indistinguishable from a hang. +setlocal +set ROOT=C:\bt411 +set INSTALL= +for /f "delims=" %%d in ('dir /b /ad /o-d "%ROOT%\BT411_*" 2^>nul') do ( + if not defined INSTALL set INSTALL=%ROOT%\%%d +) +if not defined INSTALL goto noinstall +powershell -NoProfile -ExecutionPolicy Bypass -File "%ROOT%\podkit.ps1" -Content "%INSTALL%\content" >nul +cd /d %INSTALL%\content +set L4CONTROLS=RIO:COM1,KEYBOARD +set BT_CTRLMAP_LOG=1 +set BT_GLASS_LOG=1 +set BT_LOG=podrio.log +start "" ..\build\Release\btl4.exe -egg PODTEST.EGG +exit /b +:noinstall +echo No BT411_* folder found under %ROOT%. +exit /b 1