The keyboard becomes the button board (RP412 bindings port) + a controls page
Ported RP412's bindings design and made it the DEFAULT: the letter and number rows are the MFD button banks laid out WHERE THEY SIT ON THE PANEL, flight moves to the numpad so the board stays free, F1-F12 are the map's two columns, and G/B stay unbound as the physical gap between the lower clusters. Expressed in BT's OWN grammar (slew/deflect/set, the Turn channel) -- bindings.txt is a documented compatibility surface and was not touched. Coverage: 61 of 72 addresses on the keyboard, and the 11 absent ones are exactly those the pod never wired (0x16/0x17/0x1E/0x1F column gaps, 0x38-0x3E intercom/door). All 72 stay clickable on the panel. It lands on BT's addresses unreasonably well: 1-4 + QWER are the ENTIRE coolant system (Condensers 1-6, flush, balance), F6/F7 the display and control-mode cycles, F9-F12 Generators A-D, F4 the crouch button reconstructed earlier today. THE DELIBERATE COST. A bound key is removed from the authentic 1995 typed-hotkey channel so it cannot double-dispatch, and this board binds nearly everything -- so 5 (Quad page), z (Eng1), t/y/u/i/o (pilot select) and +/- (target zoom) are given up. Unbind a key to get its 1995 meaning back. Documented in the file header, the markdown and the page. NEW RULE: A BINDINGS ROW WINS OVER A BUILT-IN CONVENIENCE KEY (PadRIO::KeyHasBinding). V and J/K/L are board buttons now, and those polls read GetAsyncKeyState directly -- without this they would have fired BOTH the button and the built-in. View toggle lives on BACKTICK alone. CONTROLS.MAP rewritten to mirror the board so glass/pod/dev still feel identical (the 2026-07-21 settlement): 90 bindings, 0 parse complaints. HAT LABELS CORRECTED [T1]. INPUT_PATH_AUDIT flagged 0x41-0x44 and was right. Settled from the streamed mapping (BT_CTRLMAP_LOG): elem 66 -> subsys 17 attrID 14, i.e. 0x42 is the TORSO subsystem, not a look; 0x44/0x43/0x41 are the mapper's LookLeft/LookRight/LookBehind (attrID 10/11/12). The .RES has no "TORSO CENTER" string -- its names are LookBehind/Down/Forward/Left/Right -- so the audit's wording was loose but its substance correct. Swept L4GLASSWIN, L4PADPANEL and L4VB16. docs/CONTROLS.html: interactive keyboard (hover a key for its address and meaning, MFD clusters outlined), pad diagram, panel map, the under-glass press-target figure, radar placement thumbnails and the environ.ini table -- modelled on RP412's page, rewritten for BT's addresses and hazards. mkdist wraps the fragment in a doctype/charset shell and ships it beside CONTROLS.txt. Verified: bindings.txt regenerates and loads (74 keys, 0 errors); CONTROLS.MAP 90 bindings, 0 errors; 72/72 panel addresses still dispatch; surround / exploded / dock / pod / dev boot and simulate with zero faults. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -111,8 +111,8 @@ struct NamedButton { int address; const char *name; };
|
||||
static const NamedButton namedButtons[] =
|
||||
{
|
||||
{ 0x3D, "Panic" }, { 0x3F, "Throttle" },
|
||||
{ 0x40, "Main" }, { 0x41, "Hat Bk" }, { 0x42, "Hat Up" },
|
||||
{ 0x43, "Hat R" }, { 0x44, "Hat L" }, { 0x45, "Pinky" },
|
||||
{ 0x40, "Main" }, { 0x41, "Look Bk" }, { 0x42, "Torso Ctr" },
|
||||
{ 0x43, "Look R" }, { 0x44, "Look L" }, { 0x45, "Pinky" },
|
||||
{ 0x46, "Middle"}, { 0x47, "Upper" },
|
||||
};
|
||||
enum { NamedButtonCount = sizeof(namedButtons) / sizeof(namedButtons[0]) };
|
||||
|
||||
@@ -161,20 +161,35 @@ static int
|
||||
// the 12 secondary-panel buttons, 0x00-0x0F the lower aux banks, 0x20-0x37
|
||||
// the upper aux banks. Keypad unit 0 = the pilot's MFD keypad.
|
||||
//
|
||||
// KEYBOARD RECONCILIATION (2026-07-20, input-coverage audit): the keyboard
|
||||
// carries the ~20 core gameplay actions on the SAME keys the desktop
|
||||
// CONTROLS.MAP uses (W/S/A/D drive, Q/E twist, R/F elevation, X all-stop,
|
||||
// 1-4/Space/Ctrl fire, M/N mode/display cycle, H flush, C valve, B look
|
||||
// behind, G configure, V view); FULL pod-address coverage lives on the
|
||||
// on-screen panel (every one of the 72 buttons is one click away,
|
||||
// right-click = hold latch). Keys DISPLACED from the previous default
|
||||
// (each still reachable by editing bindings.txt or on the panel):
|
||||
// - number row 1-0/-/= -> secondary-panel 0x10-0x1D (1-4 now fire)
|
||||
// - QWERTY row Q..P -> pilot MFD keypad unit 0 (dropped)
|
||||
// - arrow keys -> hat looks 0x41-0x44 (arrows now drive)
|
||||
// - V/C/B -> fire 0x47/0x46/0x45 (now view/valve/behind)
|
||||
// - LCTRL -> throttle slew down (now fire 0x47)
|
||||
// The XInput pad section is unchanged.
|
||||
// THE KEYBOARD IS THE BUTTON BOARD (2026-07-26, ported from RP412).
|
||||
//
|
||||
// Every one of the pod's 72 buttons is reachable from the keyboard, laid out
|
||||
// WHERE IT SITS ON THE PANEL: the number row is the upper MFDs' top row and
|
||||
// QWERTY the row beneath it, running left to right across Heat / Engineering /
|
||||
// Comm; the home row and the row below it do the same for the two lower
|
||||
// weapon MFDs; F1-F12 are the two columns flanking the map. G and B stay
|
||||
// unbound on purpose -- they are the physical gap between the lower clusters.
|
||||
// Flight moves to the NUMPAD (which already carried it as an alternative), so
|
||||
// the letter field is free for the board.
|
||||
//
|
||||
// It lands on BT's own addresses better than it has any right to: 1-4 and
|
||||
// QWER are the Heat display's two rows, which is the entire coolant system
|
||||
// (Condensers 1-6, the flush and the balance button); F6/F7 are the display
|
||||
// and control-mode cycles; F9-F12 are Generators A-D.
|
||||
//
|
||||
// WHAT THIS COSTS (the deliberate trade). A bound key is REMOVED from the
|
||||
// authentic 1995 typed-hotkey channel to stop double-dispatch, and this board
|
||||
// binds nearly the whole field -- so the typed hotkeys go: 5 = MFD1 Quad page,
|
||||
// z = MFD3 Eng1, t/y/u/i/o = pilot select 3-7, +/- = target zoom. They remain
|
||||
// reachable on the panel and by editing this file. The built-in convenience
|
||||
// keys yield the same way: V and J/K/L are board buttons now, so PadRIO's
|
||||
// view-toggle and preset-cycle polls stand down for them (KeyHasBinding) and
|
||||
// the view toggle lives on BACKTICK alone.
|
||||
//
|
||||
// PREVIOUS DEFAULT (2026-07-20 - 2026-07-26) was the ~20-action CONTROLS.MAP
|
||||
// mirror: W/S/A/D drive, Q/E twist, R/F elevation, 1-4/Space/Ctrl fire,
|
||||
// M/N/H/C/G systems. An existing bindings.txt is never overwritten, so a
|
||||
// player only meets this board by deleting theirs.
|
||||
//###########################################################################
|
||||
|
||||
static const char *defaultProfileText =
|
||||
@@ -192,66 +207,121 @@ static const char *defaultProfileText =
|
||||
"# made for mapping a gamepad stick to turning)\n"
|
||||
"# Pad buttons: A B X Y LB RB BACK START LS RS DPAD_* Axes: LX LY RX RY LT RT\n"
|
||||
"#\n"
|
||||
"# LAYOUT: the keyboard hosts the core gameplay actions on the desktop\n"
|
||||
"# CONTROLS.MAP keys; the on-screen cockpit panel covers EVERY pod button\n"
|
||||
"# by click (right-click = press-and-hold latch). A key bound here is\n"
|
||||
"# REMOVED from the authentic 1995 typed-hotkey channel (no double\n"
|
||||
"# dispatch); unbound keys keep their 1995 meaning -- 5 = MFD1 Quad page,\n"
|
||||
"# z = MFD3 Eng1 page, t/y/u/i/o = pilot select 3-7, + / - = target zoom.\n"
|
||||
"# Hardcoded (not rebindable here): ` or V = view toggle, J/K/L = cycle\n"
|
||||
"# the Mfd1/Mfd2/Mfd3 preset page.\n"
|
||||
"# LAYOUT: THE KEYBOARD IS THE POD'S BUTTON BOARD. The letter and number\n"
|
||||
"# rows are the MFD button banks laid out where they sit on the panel, and\n"
|
||||
"# flight lives on the numpad so the board stays free. Every one of the 72\n"
|
||||
"# pod buttons is also one mouse click away on the cockpit itself\n"
|
||||
"# (right-click = press-and-hold latch).\n"
|
||||
"#\n"
|
||||
"# A key bound here is REMOVED from the authentic 1995 typed-hotkey channel\n"
|
||||
"# so it cannot double-dispatch -- and this board binds nearly everything,\n"
|
||||
"# so those hotkeys (5 = MFD1 Quad, z = MFD3 Eng1, t/y/u/i/o = pilot select,\n"
|
||||
"# +/- = target zoom) are given up by design. Unbind a key here to get its\n"
|
||||
"# 1995 meaning back. Same rule for the built-ins: BACKTICK = view toggle\n"
|
||||
"# (V is a board button now), and J/K/L cycle the Mfd1/2/3 preset pages ONLY\n"
|
||||
"# while unbound.\n"
|
||||
"\n"
|
||||
"# --- drive: W/S sweep the throttle lever (sticks; X = all-stop detent),\n"
|
||||
"# --- A/D spring the turn pedals, Q/E twist the torso, R/F aim it up/down\n"
|
||||
"key W axis Throttle slew + 0.7\n"
|
||||
"key S axis Throttle slew - 0.7\n"
|
||||
"key UP axis Throttle slew + 0.7\n"
|
||||
"key DOWN axis Throttle slew - 0.7\n"
|
||||
"key A axis LeftPedal deflect + 2.5\n"
|
||||
"key D axis RightPedal deflect + 2.5\n"
|
||||
"key LEFT axis LeftPedal deflect + 2.5\n"
|
||||
"key RIGHT axis RightPedal deflect + 2.5\n"
|
||||
"key Q axis JoystickX deflect - 2.5\n"
|
||||
"key E axis JoystickX deflect + 2.5\n"
|
||||
"key R axis JoystickY deflect + 2.5\n"
|
||||
"key F axis JoystickY deflect - 2.5\n"
|
||||
"key X axis Throttle set 0\n"
|
||||
"\n"
|
||||
"# --- numpad flight cluster (alternative stick/pedals/lever) ---\n"
|
||||
"# --- flight: the numpad ------------------------------------------------\n"
|
||||
"# 8/2/4/6 stick, 7/9 pedals, 5 all-stop detent, 0 main trigger.\n"
|
||||
"# SHIFT/CTRL walk the throttle lever and it STICKS where you leave it;\n"
|
||||
"# ALT is the throttle handle's reverse-thrust button.\n"
|
||||
"key NUMPAD8 axis JoystickY deflect + 2.5\n"
|
||||
"key NUMPAD2 axis JoystickY deflect - 2.5\n"
|
||||
"key NUMPAD4 axis JoystickX deflect - 2.5\n"
|
||||
"key NUMPAD6 axis JoystickX deflect + 2.5\n"
|
||||
"key NUMPAD7 axis LeftPedal deflect + 2.5\n"
|
||||
"key NUMPAD9 axis RightPedal deflect + 2.5\n"
|
||||
"key LSHIFT axis Throttle slew + 0.7\n"
|
||||
"key NUMPAD5 axis Throttle set 0\n"
|
||||
"\n"
|
||||
"# --- fire groups (the joystick's four mappable buttons) + reverse + look\n"
|
||||
"key 1 button 0x40\n"
|
||||
"key SPACE button 0x40\n"
|
||||
"key 2 button 0x46\n"
|
||||
"key 3 button 0x47\n"
|
||||
"key LCTRL button 0x47\n"
|
||||
"key RCTRL button 0x47\n"
|
||||
"key 4 button 0x45\n"
|
||||
"key LSHIFT axis Throttle slew + 0.7\n"
|
||||
"key RSHIFT axis Throttle slew + 0.7\n"
|
||||
"key LCTRL axis Throttle slew - 0.7\n"
|
||||
"key RCTRL axis Throttle slew - 0.7\n"
|
||||
"key LALT button 0x3F\n"
|
||||
"key B button 0x41\n"
|
||||
"key RALT button 0x3F\n"
|
||||
"\n"
|
||||
"# --- systems (pod console buttons) ---\n"
|
||||
"key M button 0x18 # cycle control mode (BAS/MID/ADV)\n"
|
||||
"key N button 0x15 # cycle secondary schematic (Damage/Critical/Heat)\n"
|
||||
"key H button 0x2C # HOLD = coolant flush (Reservoir InjectCoolant)\n"
|
||||
"key C button 0x2F # cycle Condenser1 coolant valve (MoveValve)\n"
|
||||
"key G button 0x0E # HOLD + fire key = regroup weapon 1 (Mfd1 Quad page)\n"
|
||||
"# --- the four mappable fire buttons ------------------------------------\n"
|
||||
"key SPACE button 0x40 # main trigger\n"
|
||||
"key NUMPAD0 button 0x40 # main trigger\n"
|
||||
"key NUMPAD1 button 0x45 # pinky\n"
|
||||
"key NUMPAD3 button 0x46 # middle thumb\n"
|
||||
"key NUMPADDOT button 0x47 # upper thumb\n"
|
||||
"\n"
|
||||
"# --- Mfd2 bank on F5-F8 + F9 (page-gated: Quad page = select the Eng\n"
|
||||
"# --- pages, Eng page = generator A-D select / F9 gen-mode toggle) ---\n"
|
||||
"key F5 button 0x27\n"
|
||||
"key F6 button 0x26\n"
|
||||
"key F7 button 0x25\n"
|
||||
"key F8 button 0x24\n"
|
||||
"key F9 button 0x22\n"
|
||||
"# --- the hat: look around, on the arrows -------------------------------\n"
|
||||
"key UP button 0x42 # torso CENTER (the shipped .RES name)\n"
|
||||
"key DOWN button 0x41 # look behind\n"
|
||||
"key LEFT button 0x44 # look left\n"
|
||||
"key RIGHT button 0x43 # look right\n"
|
||||
"\n"
|
||||
"# --- UPPER MFD banks: number row on top, QWERTY beneath ----------------\n"
|
||||
"# Heat / coolant (0x28-0x2F) -- 1-4 and QWER ARE the coolant system:\n"
|
||||
"# 1/2/3 Condenser 1-3 valve, 4 coolant FLUSH (hold), Q/W/E Condenser\n"
|
||||
"# 4-6 valve, R balance coolant. The valve detents run 1-5-50-CLOSED.\n"
|
||||
"key 1 button 0x2F\n"
|
||||
"key 2 button 0x2E\n"
|
||||
"key 3 button 0x2D\n"
|
||||
"key 4 button 0x2C\n"
|
||||
"key Q button 0x2B\n"
|
||||
"key W button 0x2A\n"
|
||||
"key E button 0x29\n"
|
||||
"key R button 0x28\n"
|
||||
"# Engineering / Mfd2 (0x20-0x27) -- page-gated: Quad page picks an Eng\n"
|
||||
"# page, Eng page drives generator select A-D / bus mode / coolant.\n"
|
||||
"key 5 button 0x27\n"
|
||||
"key 6 button 0x26\n"
|
||||
"key 7 button 0x25\n"
|
||||
"key 8 button 0x24\n"
|
||||
"key T button 0x23\n"
|
||||
"key Y button 0x22\n"
|
||||
"key U button 0x21\n"
|
||||
"key I button 0x20\n"
|
||||
"# Comm / target hotbox (0x30-0x37) -- pilot select.\n"
|
||||
"key 9 button 0x37\n"
|
||||
"key 0 button 0x36\n"
|
||||
"key MINUS button 0x35\n"
|
||||
"key EQUALS button 0x34\n"
|
||||
"key O button 0x33\n"
|
||||
"key P button 0x32\n"
|
||||
"key LBRACKET button 0x31\n"
|
||||
"key RBRACKET button 0x30\n"
|
||||
"\n"
|
||||
"# --- LOWER MFD banks: home row on top, the row below beneath -----------\n"
|
||||
"# G and B are the PANEL GAP between the two lower clusters -- left\n"
|
||||
"# unbound on purpose, so they keep their 1995 typed meaning.\n"
|
||||
"# Left Weapons / Mfd1 (0x08-0x0F).\n"
|
||||
"key A button 0x0F\n"
|
||||
"key S button 0x0E\n"
|
||||
"key D button 0x0D\n"
|
||||
"key F button 0x0C\n"
|
||||
"key Z button 0x0B\n"
|
||||
"key X button 0x0A\n"
|
||||
"key C button 0x09\n"
|
||||
"key V button 0x08\n"
|
||||
"# Right Weapons / Mfd3 (0x00-0x07).\n"
|
||||
"key H button 0x07\n"
|
||||
"key J button 0x06\n"
|
||||
"key K button 0x05\n"
|
||||
"key L button 0x04\n"
|
||||
"key N button 0x03\n"
|
||||
"key M button 0x02\n"
|
||||
"key COMMA button 0x01\n"
|
||||
"key PERIOD button 0x00\n"
|
||||
"\n"
|
||||
"# --- the two columns flanking the map, top to bottom -------------------\n"
|
||||
"# Left (0x10-0x15): map zoom in/out, thermal IR, CROUCH, searchlight,\n"
|
||||
"# cycle secondary display. Right (0x18-0x1D): cycle control mode\n"
|
||||
"# (BAS/MID/ADV), unused, Generator A-D on/off.\n"
|
||||
"key F1 button 0x10\n"
|
||||
"key F2 button 0x11\n"
|
||||
"key F3 button 0x12\n"
|
||||
"key F4 button 0x13\n"
|
||||
"key F5 button 0x14\n"
|
||||
"key F6 button 0x15\n"
|
||||
"key F7 button 0x18\n"
|
||||
"key F8 button 0x19\n"
|
||||
"key F9 button 0x1A\n"
|
||||
"key F10 button 0x1B\n"
|
||||
"key F11 button 0x1C\n"
|
||||
"key F12 button 0x1D\n"
|
||||
"\n"
|
||||
"# --- XInput pad ---\n"
|
||||
"# POD-FAITHFUL (default): stick X = torso twist, triggers = pedals.\n"
|
||||
|
||||
@@ -96,10 +96,10 @@ static const NamedButton namedButtons[] =
|
||||
{ 0x3D, "Panic" },
|
||||
{ 0x3F, "Throttle" },
|
||||
{ 0x40, "Main" },
|
||||
{ 0x41, "Hat Back" },
|
||||
{ 0x42, "Hat Up" },
|
||||
{ 0x43, "Hat Right" },
|
||||
{ 0x44, "Hat Left" },
|
||||
{ 0x41, "Look Back" },
|
||||
{ 0x42, "Torso Ctr" },
|
||||
{ 0x43, "Look Right" },
|
||||
{ 0x44, "Look Left" },
|
||||
{ 0x45, "Pinky" },
|
||||
{ 0x46, "Middle" },
|
||||
{ 0x47, "Upper" },
|
||||
|
||||
@@ -69,6 +69,24 @@ int
|
||||
// takes no engine headers (l4keylight.h is scalars only), so it hands us
|
||||
// finished lines instead.
|
||||
//
|
||||
//
|
||||
// Does the loaded profile bind this virtual key? The built-in convenience
|
||||
// keys (view toggle, preset cycles) consult this and stand down when the
|
||||
// player's bindings claim the key -- see the note at their poll sites.
|
||||
//
|
||||
Logical
|
||||
PadRIO::KeyHasBinding(int virtualKey) const
|
||||
{
|
||||
for (int i = 0; i < bindings.keyBindingCount; ++i)
|
||||
{
|
||||
if (bindings.keyBindings[i].virtualKey == virtualKey)
|
||||
{
|
||||
return True;
|
||||
}
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
static void
|
||||
KeyLightLog(const char *line)
|
||||
{
|
||||
@@ -615,11 +633,17 @@ void
|
||||
// message-path-free) and consumed by the game's view-toggle block via
|
||||
// BTPadViewToggleEdge.
|
||||
//
|
||||
// ⚠ A bindings.txt ROW WINS over these built-in convenience keys
|
||||
// (2026-07-26). The default profile now hands the whole letter field to
|
||||
// the MFD banks -- V is a Left Weapons button, J/K/L are Right Weapons --
|
||||
// and polling them here as well would fire BOTH the button and the
|
||||
// built-in, which is the double-dispatch the typed-channel suppression
|
||||
// exists to prevent. Bind the key, and the built-in stands down.
|
||||
{
|
||||
static int s_backtickWas = 0;
|
||||
int backtick_held = focused &&
|
||||
(((GetAsyncKeyState(VK_OEM_3) & 0x8000) != 0) ||
|
||||
((GetAsyncKeyState('V') & 0x8000) != 0));
|
||||
(!KeyHasBinding('V') && (GetAsyncKeyState('V') & 0x8000) != 0));
|
||||
if (backtick_held && !s_backtickWas)
|
||||
{
|
||||
extern int gBTPadViewToggleEdges;
|
||||
@@ -638,7 +662,7 @@ void
|
||||
static const int s_presetKey[3] = { 'J', 'K', 'L' };
|
||||
for (int g = 0; g < 3; ++g)
|
||||
{
|
||||
int held = focused &&
|
||||
int held = focused && !KeyHasBinding(s_presetKey[g]) &&
|
||||
(GetAsyncKeyState(s_presetKey[g]) & 0x8000) != 0;
|
||||
if (held && !s_presetWas[g])
|
||||
{
|
||||
|
||||
@@ -148,6 +148,12 @@ protected:
|
||||
Logical
|
||||
keyLightActive;
|
||||
|
||||
// True when the loaded bindings claim this virtual key. The built-in
|
||||
// convenience keys (` / V view toggle, J/K/L preset cycles) yield to an
|
||||
// explicit row rather than double-dispatching with it.
|
||||
Logical
|
||||
KeyHasBinding(int virtualKey) const;
|
||||
|
||||
//
|
||||
// Typed-channel suppression tables (built from the loaded bindings +
|
||||
// the hardcoded view/preset keys; see SuppressKey).
|
||||
|
||||
@@ -551,8 +551,8 @@ void BTCockpitComputeLayout(int canvasW, int canvasH, BTCockpitLayout *out)
|
||||
{
|
||||
static const char *thrLabel[8] = { 0, 0, 0, 0, 0, "Panic", 0, "Throttle" }; // 0x38..0x3F
|
||||
static const int thrInert[8] = { 1, 1, 1, 1, 1, 0, 1, 0 };
|
||||
static const char *joyLabel[8] = { "Main", "Hat Bk", "Hat Up", "Hat R",
|
||||
"Hat L", "Pinky", "Middle", "Upper" }; // 0x40..0x47
|
||||
static const char *joyLabel[8] = { "Main", "Look Bk", "Torso Ctr", "Look R",
|
||||
"Look L", "Pinky", "Middle", "Upper" }; // 0x40..0x47
|
||||
// These cells carry TEXT, so the surround runs them bigger than the
|
||||
// exploded window's 58x28 -- the caller owns the cell size
|
||||
// (l4riobank.h), only the grid walk is shared.
|
||||
|
||||
Reference in New Issue
Block a user