Files
RP412/MUNGA_L4/L4PADRIO.h
T
CydandClaude Fable 5 b0def79de2 Rebindable input: vRIO bindings profile ported, full board coverage
PadRIO now loads bindings.txt (vRIO profile grammar: key/pad/padaxis
lines with toggle, deflect/rate, invert/deadzone options) written
self-documenting with the full default layout on first run. The
default is vRIO board-complete map - number and letter rows are the
MFD banks as printed on the panel, F-keys the secondary/screen
columns, numpad the pilot keypad (0x50-0x5F delivered as arcade RIO
KeyEvents, a new PadRIO capability), Space/arrows the joystick
column - with the desktop driving keys carved out: WASD stick, Q/E
pedals, PgUp/PgDn throttle, B reverse (vRIO gap key; R returns to
its bank). Pad bindings unchanged in spirit, plus Panic on LB and
config on Start/Back; axis signs are encoded in the profile now, so
L4PADFLIP flips on top of it.

Default profile parses with zero rejected lines (68 key buttons, 8
key axes, 12 pad buttons, 5 pad axes); single-player cycle and the
key-bomb tests stay green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 10:18:36 -05:00

120 lines
2.9 KiB
C++

#pragma once
#include "l4rio.h"
#include "l4padbindings.h"
//########################################################################
//############################### PadRIO #################################
//########################################################################
//
// A cockpit-less RIO: synthesizes the RIOBase control surface from an
// XInput controller and the PC keyboard. Selected with L4CONTROLS=PAD.
//
// Every input is REBINDABLE: bindings.txt beside the exe (vRIO's
// profile format, written with the full default layout on first run)
// maps keys and pad controls to RIO button addresses (0x00-0x47), the
// pilot/external keypads (0x50-0x6F, delivered as arcade KeyEvents),
// and the five axes with deflect/rate semantics. Defaults follow
// vRIO's board-complete layout with the driving keys carved out:
// WASD stick, Q/E pedals, PgUp/PgDn throttle, Space trigger, B
// reverse, arrows hat, letter rows = MFD banks, F-keys = secondary
// columns, numpad = pilot keypad.
//
// Set L4PADFLIP to a string containing 'X' and/or 'Y' to invert the
// stick axes on top of whatever the profile produces.
//
class PadRIO :
public RIOBase
{
public:
PadRIO();
~PadRIO();
Logical
TestInstance() const;
Logical
GetNextEvent(RIOEvent *destinationPointer);
void
RequestAnalogUpdate();
void
GeneralReset();
void
ResetThrottle();
void
SetLamp(int lampNumber, int state);
// Lamp state the game has commanded, indexed by RIO lamp number.
// The on-screen cockpit buttons read this to light themselves.
enum { lampCount = 64 };
unsigned char
lampState[lampCount];
//---------------------------------------------------------------
// On-screen cockpit buttons (MFDSplitView strips) press RIO units
// through these; they are no-ops when no PadRIO is active (e.g.
// real serial hardware selected).
//---------------------------------------------------------------
static void
SetScreenButton(int unit, Logical pressed);
static int
GetLampState(int unit);
static Logical
IsActive()
{ return activeInstance != NULL; }
protected:
void
PollInputs();
void
QueueEvent(const RIOEvent &an_event);
enum { queueSize = 64 };
enum { buttonUnits = 0x48 }; // through LastMappableButton
RIOEvent
eventQueue[queueSize];
int
queueHead, queueTail;
static PadRIO
*activeInstance;
// pressed state driven by the on-screen cockpit buttons
unsigned char
screenButton[0x48];
unsigned long
lastPollTick,
lastPadCheckTick;
int
padIndex; // connected XInput slot, -1 = none
Logical
padReported; // one-time connect/disconnect log flags
Logical
analogRequested;
unsigned char
buttonDown[buttonUnits];
// keypad pressed-state (0x50-0x6F), for KeyEvent edges
enum { keypadUnits = 0x20 };
unsigned char
keypadDown[keypadUnits];
PadBindingProfile
profile;
Scalar
throttleAccum;
Logical
invertX, invertY;
Scalar
sentThrottle, sentLeftPedal, sentRightPedal,
sentJoystickX, sentJoystickY;
};