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>
114 lines
3.1 KiB
C++
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);
|
|
};
|