Files
BT411/engine/MUNGA_L4/L4PADBINDINGS.h
T
CydandClaude Fable 5 ac57a474ef Input: the RIOBase seam + PadRIO -- the glass cockpit gets hands (step 2b)
L4RIO.h splits the abstract cockpit-control surface (RIOBase: enums, the five
analog Scalars, GetNextEvent/SetLamp, no-op serial ops, NEW IsOperational) out
of the serial RIO (RIO : PCSerialPacket, RIOBase -- byte-for-byte behavior kept,
ctor assigns as before); LBE4ControlsManager holds a RIOBase* and gains the
gated L4CONTROLS=PAD factory arm (BT_GLASS; OFF build logs+ignores the token).
NEW gated TUs: L4PADRIO (XInput+keyboard synthesize the surface; 3s hot-plug
re-probe; focus-guarded keys; per-poll AnalogEvent heartbeat; lampState[] +
static SetScreenButton/GetLampState for the panel) and L4PADBINDINGS
(content\bindings.txt profile, self-documenting default written on first run;
deflect/slew/set axis model; addresses validated against ButtonCount).
Verified live (glass build, L4CONTROLS=PAD): bindings written+parsed 44/10/5,
XInput pad detected, 121 streamed mappings install via stock PrimaryRIO path,
2157 frames clean. Pod build (gates OFF) compiles the split with zero
behavioral delta.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 22:11:16 -05:00

114 lines
3.1 KiB
C++

#pragma once
//###########################################################################
//
// L4PADBINDINGS -- the PadRIO input-binding profile (BT_GLASS only).
//
// Maps PC keyboard keys and XInput pad controls onto the pod's abstract
// control surface: RIO button addresses (buttonGroup elements), MFD keypad
// units, and the five analog channels (Throttle, JoystickX/Y, Left/Right
// Pedal). The profile is read from "bindings.txt" in the working directory
// (content\); a self-documenting default file is written on first run.
// Grammar (one binding per line, '#' comments):
//
// key <KEYNAME> button <addr>
// key <KEYNAME> keypad <unit> <key>
// key <KEYNAME> axis <channel> deflect <+|-> <rate>
// key <KEYNAME> axis <channel> slew <+|-> <rate>
// key <KEYNAME> axis <channel> set <value>
// pad <PADBTN> button <addr>
// padaxis <PADAXIS> axis <channel> [invert] [slew <rate>]
//
// deflect = held drives the channel toward +/-1 at <rate>/s, auto-centers
// on release (the spring-centered stick model).
// slew = held moves the channel at <rate>/s and it STAYS (the throttle
// lever model).
// set = press jumps the channel to <value> (all-stop detent).
//
//###########################################################################
class PadBindingProfile
{
public:
enum Channel {
ChannelThrottle = 0,
ChannelJoystickX,
ChannelJoystickY,
ChannelLeftPedal,
ChannelRightPedal,
ChannelCount
};
enum ActionKind {
ActionButton, // RIO button address (buttonGroup element)
ActionKeypad, // MFD keypad unit + key
ActionAxisDeflect,
ActionAxisSlew,
ActionAxisSet
};
struct Action
{
ActionKind kind;
int address; // ActionButton: RIO address; ActionKeypad: unit
int key; // ActionKeypad: key number (0-9=digits, 10+=A..)
int channel; // ActionAxis*: Channel
float rate; // deflect/slew: units per second (signed);
// set: the target value
};
struct KeyBinding
{
int virtualKey; // Win32 VK code
Action action;
};
struct PadButtonBinding
{
unsigned buttonMask; // XINPUT_GAMEPAD_* bit
Action action; // ActionButton / ActionKeypad only
};
enum PadAxis {
PadAxisLX = 0, PadAxisLY, PadAxisRX, PadAxisRY,
PadAxisLT, PadAxisRT,
PadAxisCount
};
struct PadAxisBinding
{
int axis; // PadAxis
int channel; // Channel
int invert; // flip the sign
int slew; // 0 = direct absolute, 1 = value drives d/dt
float slewRate; // full-deflection slew speed (units/s)
};
PadBindingProfile();
~PadBindingProfile();
//
// Load "bindings.txt" from the working directory; if it does not exist,
// write the default profile there first (self-documenting). Always
// leaves a usable profile (falls back to built-in defaults on a
// malformed file, logging each rejected line).
//
void
Load();
int keyBindingCount;
KeyBinding keyBindings[192];
int padButtonBindingCount;
PadButtonBinding padButtonBindings[32];
int padAxisBindingCount;
PadAxisBinding padAxisBindings[12];
protected:
void
LoadDefaults();
void
WriteDefaultFile(const char *path);
int
ParseLine(char *line, int line_number);
};