Controls: the keyboard bridges STAND DOWN for a live device (step 2c)

New engine query BTRIODevicePresent() (L4CTRL.cpp, ungated -- pod-correct for
the serial RIO too): device exists AND IsOperational().  Both dev input
bridges -- the mech4.cpp mapper-attr writes and the mechmppr.cpp BT_KEY_BRIDGE
block -- now gate their WRITES on it: BT_KEY_BRIDGE unset = auto (bridge only
when no device), 0 = force off (the documented pod setting, honored), else
force on.  The BT_FORCE_THROTTLE headless harness always rides the bridge.
The mapper demand READ (turn = turnDemand) always runs.

Verified live (glass build, PAD): OS-injected LSHIFT hold slews the PadRIO
throttle 0 -> 0.33 -> 1.0 with pre==thr every frame -- the value arrives via
the ENGINE push through the streamed .CTL binding, not the bridge -- and
speedDemand=61.501 comes out of the authentic InterpretControls.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-17 22:14:37 -05:00
co-authored by Claude Fable 5
parent ac57a474ef
commit 9f35a8034a
3 changed files with 46 additions and 2 deletions
+13
View File
@@ -3141,15 +3141,28 @@ void
MechControlsMapper *mppr = MappingMapper(); // roster slot 0 (task #7)
if (s_realControls && mppr != 0)
{
// STAND-DOWN (glass-cockpit step 2c): with a LIVE cockpit device
// (serial RIO on the pod, PadRIO on a glass build) the engine
// controls push owns these attributes via the streamed .CTL
// bindings -- the keyboard writes below would clobber the device
// every frame. BT_KEY_BRIDGE: unset = auto (bridge active only
// with no device), "0" = force off, anything else = force on.
extern int BTRIODevicePresent(void);
static const char *s_kbEnv = getenv("BT_KEY_BRIDGE");
int bridge_writes = s_kbEnv ? (*s_kbEnv != '0')
: (gBTDrive.forced || !BTRIODevicePresent());
// Diagnostic: what the ENGINE controls push left in the attribute since
// our last write (a stale device element overwriting the bridge shows
// here as pre != our previous write).
float preThrottle = mppr->throttlePosition;
(void)preThrottle;
if (bridge_writes)
{
mppr->throttlePosition = (throttle >= 0.0f) ? throttle : -throttle;
mppr->reverseThrust = (throttle < 0.0f) ? 1 : 0; // ControlsButton: >=1 engaged
mppr->stickPosition.x = turn; // Basic mode: turn = stick yaw
mppr->stickPosition.y = 0.0f;
}
// Consume the PREVIOUS frame's interpreted demands (the mapper ticks in
// the roster walk after this block -- one frame of input latency).
// turnDemand is the mode-shaped steering; speedDemand (world u/s, sign =