From 5f88a4eeb2c28f39711c25483004a4301c8a253c Mon Sep 17 00:00:00 2001 From: Cyd Date: Sun, 26 Jul 2026 03:23:27 -0500 Subject: [PATCH] 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) --- content/CONTROLS.MAP | 148 ++-- context/glass-cockpit.md | 47 ++ docs/CONTROLS.html | 1061 +++++++++++++++++++++++++++++ docs/CONTROLS.md | 113 ++- docs/GLASS_COCKPIT.md | 50 ++ engine/MUNGA_L4/L4GLASSWIN.cpp | 4 +- engine/MUNGA_L4/L4PADBINDINGS.cpp | 196 ++++-- engine/MUNGA_L4/L4PADPANEL.cpp | 8 +- engine/MUNGA_L4/L4PADRIO.cpp | 28 +- engine/MUNGA_L4/L4PADRIO.h | 6 + engine/MUNGA_L4/L4VB16.cpp | 4 +- tools/mkdist.py | 13 + 12 files changed, 1489 insertions(+), 189 deletions(-) create mode 100644 docs/CONTROLS.html diff --git a/content/CONTROLS.MAP b/content/CONTROLS.MAP index 6f7808a..4a65e1d 100644 --- a/content/CONTROLS.MAP +++ b/content/CONTROLS.MAP @@ -43,61 +43,105 @@ # hotkey channel (no double dispatch); unbound keys keep their authentic # 1995 meaning (see pckey above). # -# ---- WASD CLASSIC (the shipped default) ---------------------------------- +# ---- THE KEYBOARD IS THE BUTTON BOARD ------------------------------------ +# Mirrors contentindings.txt exactly, so the glass (PadRIO) and desktop +# (btinput) boots feel identical -- the letter and number rows are the MFD +# button banks laid out where they sit on the panel, and flight lives on the +# numpad. G and B are the physical gap between the lower clusters and stay +# unbound. A bound key is REMOVED from the typed 1995 hotkey channel, so +# this board gives those up by design (see pckey above to rebind any back). -# Driving: W/S sweep the throttle lever (sticks, detent at zero); A/D are -# the turn pedals (spring back); Q/E twist the torso; R/F aim the torso -# up/down (elevation); X = all stop (recenters twist AND pitch). -key W axis Throttle rate 0.7 -key S axis Throttle rate -0.7 -key Up axis Throttle rate 0.7 -key Down axis Throttle rate -0.7 -key A axis LeftPedal deflect 1 -key D axis RightPedal deflect 1 -key Left axis LeftPedal deflect 1 -key Right axis RightPedal deflect 1 -key Q axis JoystickX deflect -1 -key E axis JoystickX deflect 1 -key R axis JoystickY deflect 1 -key F axis JoystickY deflect -1 -key X action AllStop - -# Fire: the pod joystick's four buttons. -key D1 button 0x40 # Main trigger (lasers group) -key Space button 0x40 -key D2 button 0x46 # Middle thumb (PPCs group) -key D3 button 0x47 # Upper thumb (missiles group) -key Ctrl button 0x47 -key D4 button 0x45 # Pinky (4th group) -key Alt button 0x3F # throttle-head = REVERSE THRUST - -# --- numpad aim cluster (torso twist/aim -- mirrors bindings.txt so the -# --- glass (PadRIO) and desktop (btinput) boots feel identical) --- -key NumPad8 axis JoystickY deflect 1 # torso aim up -key NumPad2 axis JoystickY deflect -1 # torso aim down -key NumPad4 axis JoystickX deflect -1 # torso twist left -key NumPad6 axis JoystickX deflect 1 # torso twist right -key NumPad7 axis LeftPedal deflect 1 # turn left (alt) -key NumPad9 axis RightPedal deflect 1 # turn right (alt) +# Flight: the numpad. 8/2/4/6 stick, 7/9 pedals, 5 all-stop, 0 trigger; +# Shift/Ctrl walk the throttle lever and it sticks; Alt is reverse thrust. +key NumPad8 axis JoystickY deflect 1 +key NumPad2 axis JoystickY deflect -1 +key NumPad4 axis JoystickX deflect -1 +key NumPad6 axis JoystickX deflect 1 +key NumPad7 axis LeftPedal deflect 1 +key NumPad9 axis RightPedal deflect 1 key NumPad5 action AllStop -key Shift axis Throttle rate 0.7 # throttle up (alt) +key Shift axis Throttle rate 0.7 +key Ctrl axis Throttle rate -0.7 +key Alt button 0x3F -# Systems. -key G action ConfigHold # hold + fire keys = regroup the weapon -key C action Valve # coolant valve cycle -key H action Flush # coolant flush (HOLD -- dumps reservoir coolant) -key M action ModeCycle # Basic -> Standard -> Veteran controls -key N action DisplayCycle # secondary schematic: Damage -> Critical -> Heat -key J action Mfd1Cycle # lower-left MFD page: Quad -> Eng detail pages -key K action Mfd2Cycle # upper-center MFD page (engineering) -key L action Mfd3Cycle # lower-right MFD page -key V action ViewToggle # cockpit <-> chase camera (dev) -key B action LookBehind # HOLD = the pod's rear-view button -key F5 action Generator1 -key F6 action Generator2 -key F7 action Generator3 -key F8 action Generator4 -key F9 action Reconnect +# The four mappable fire buttons. +key Space button 0x40 +key NumPad0 button 0x40 +key NumPad1 button 0x45 +key NumPad3 button 0x46 +key Decimal button 0x47 + +# The hat, on the arrows. 0x42 is TORSO CENTER, not a look (streamed +# mapping: elem 66 -> subsys 17 Torso attr 14; the other three are the +# mapper's LookBehind/Right/Left). +key Up button 0x42 +key Down button 0x41 +key Left button 0x44 +key Right button 0x43 + +# UPPER MFD banks: number row on top, QWERTY beneath. +# Heat / coolant (1-4, QWER = Condensers 1-6, flush, balance). +key D1 button 0x2F +key D2 button 0x2E +key D3 button 0x2D +key D4 button 0x2C +key Q button 0x2B +key W button 0x2A +key E button 0x29 +key R button 0x28 +# Engineering / Mfd2. +key D5 button 0x27 +key D6 button 0x26 +key D7 button 0x25 +key D8 button 0x24 +key T button 0x23 +key Y button 0x22 +key U button 0x21 +key I button 0x20 +# Comm / target hotbox. +key D9 button 0x37 +key D0 button 0x36 +key OemMinus button 0x35 +key Oemplus button 0x34 +key O button 0x33 +key P button 0x32 +key OemOpenBrackets button 0x31 +key OemCloseBrackets button 0x30 + +# LOWER MFD banks: home row on top, the row below beneath. +key A button 0x0F +key S button 0x0E +key D button 0x0D +key F button 0x0C +key Z button 0x0B +key X button 0x0A +key C button 0x09 +key V button 0x08 +key H button 0x07 +key J button 0x06 +key K button 0x05 +key L button 0x04 +key N button 0x03 +key M button 0x02 +key Oemcomma button 0x01 +key OemPeriod button 0x00 + +# The two columns flanking the map. +key F1 button 0x10 +key F2 button 0x11 +key F3 button 0x12 +key F4 button 0x13 +key F5 button 0x14 +key F6 button 0x15 +key F7 button 0x18 +key F8 button 0x19 +key F9 button 0x1A +key F10 button 0x1B +key F11 button 0x1C +key F12 button 0x1D + +# View toggle keeps its own key (V is a board button now). +key Oemtilde action ViewToggle # ---- Xbox controller ----------------------------------------------------- # Left stick steers (the pedals), right stick twists the torso and pushes diff --git a/context/glass-cockpit.md b/context/glass-cockpit.md index c7d100c..ae4a6e2 100644 --- a/context/glass-cockpit.md +++ b/context/glass-cockpit.md @@ -235,6 +235,53 @@ Bonus confirmation: those legend widgets sit at gauge offsets 537/430/322/215/10 pitch**, independently corroborating the map legend grid measured from pixels in §Player-tunable displays. +## THE KEYBOARD IS THE BUTTON BOARD — new default keymap (2026-07-26) [T2] + +Ported from RP412's bindings design (user decision: make it the DEFAULT, not an alternate). The +letter and number rows are the MFD button banks **laid out where they sit on the panel**, and +flight moves to the NUMPAD so the board stays free: + +| Keys | Bank | +|---|---| +| `1 2 3 4` / `Q W E R` | Heat / coolant 0x2F-0x2C / 0x2B-0x28 | +| `5 6 7 8` / `T Y U I` | Engineering (Mfd2) 0x27-0x24 / 0x23-0x20 | +| `9 0 - =` / `O P [ ]` | Comm / target hotbox 0x37-0x34 / 0x33-0x30 | +| `A S D F` / `Z X C V` | Left Weapons (Mfd1) 0x0F-0x0C / 0x0B-0x08 | +| `H J K L` / `N M , .` | Right Weapons (Mfd3) 0x07-0x04 / 0x03-0x00 | +| `F1`-`F6` / `F7`-`F12` | the map's two columns 0x10-0x15 / 0x18-0x1D | +| numpad | 8/2/4/6 stick, 7/9 pedals, 5 all-stop, 0/1/3/. the four fire buttons | +| `Shift`/`Ctrl` · `Alt` · arrows · `` ` `` | throttle lever · reverse · look/torso-centre · view | + +`G` and `B` stay unbound — the physical gap between the lower clusters. **Coverage: 61 of 72 +addresses on the keyboard, and the 11 absent ones are exactly those with no authored function** +(0x16/0x17/0x1E/0x1F column gaps, 0x38-0x3E intercom/door). All 72 remain clickable. + +It lands on BT's addresses better than it deserves to: `1-4`+`QWER` are the ENTIRE coolant system +(Condensers 1-6, flush, balance), `F6`/`F7` the display/control-mode cycles, `F9`-`F12` Generators +A-D, `F4` the crouch button. + +⚠ **What it costs, deliberately.** A bound key is removed from the authentic 1995 typed-hotkey +channel to stop 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. + +⚠ **New rule: a bindings row WINS over a built-in convenience key** (`PadRIO::KeyHasBinding`). +`V` and `J/K/L` are board buttons now, so the view-toggle and preset-cycle polls stand down for +them and the view toggle lives on `` ` `` alone. Without this they would have fired BOTH. + +`content/CONTROLS.MAP` was rewritten to mirror the board (90 bindings, 0 parse complaints) so the +glass/pod/dev boots still feel identical — the 2026-07-21 settlement. An existing `bindings.txt` +is never overwritten, so a player only meets this board by deleting theirs. + +## Hat labels corrected — 0x42 is TORSO CENTER [T1, streamed mapping] + +`docs/INPUT_PATH_AUDIT.md` flagged the 0x41-0x44 labels as wrong and it was right. Settled from +`BT_CTRLMAP_LOG`: **0x42 → subsys 17 (Torso), attrID 14** — not a look at all; the other three go +to the mapper's look trio (0x44 → attrID 10 LookLeft, 0x43 → 11 LookRight, 0x41 → 12 LookBehind). +The shipped `.RES` has no "TORSO CENTER" string (its names are LookBehind/Down/Forward/Left/Right), +so the audit's phrasing was loose but its substance correct. Swept the three UI tables +(`L4GLASSWIN`, `L4PADPANEL`, `L4VB16`): 0x42 is now "Torso Ctr", 0x41/0x43/0x44 "Look Bk/R/L". + ## RGB keyboard lamp mirror — L4KEYLIGHT (2026-07-26) [T2 live, claimed a real board] Ported from RP412 (itself vRIO's `KeyboardLampMirror`). Keys bound to a lamp address in diff --git a/docs/CONTROLS.html b/docs/CONTROLS.html new file mode 100644 index 0000000..3ef800c --- /dev/null +++ b/docs/CONTROLS.html @@ -0,0 +1,1061 @@ +BattleTech 4.11 — Controls + + + +
+ +
+

Virtual World Entertainment · Tesla II pod · BT 4.11

+

BattleTech
Controls Map

+

+ Every input the pod answers to. The keyboard is the button + board: the letter and number rows are the MFD banks laid out + where they sit on the panel, and flight moved to the number pad so the + board stays free. Every one of the 72 buttons is also a mouse target on + the cockpit itself. +

+

Generated from the default bindings.txt · all of it rebindable

+
+ +
+
+
Fly
+
Num 8 2 4 6stick · 7/9 pedals · 0 fires · 5 all-stop
+
+
+
Throttle
+
Shift / Ctrlwalks the lever; it sticks where you leave it
+
+
+
Reverse
+
Altthe throttle handle's own button
+
+
+
Control mode
+
F7BAS → MID → ADV. You spawn in BASIC
+
+
+ +
+

+ YOU SPAWN IN BASIC. In BASIC the stick steers and the + pedals do nothing. Press F7 once for MID, where the pedals steer + and the stick twists the torso — the full pod experience. If "turning + doesn't work", this is why, not a bug. (Control mode is not the menu's + experience setting; that one changes the simulation, not your controls.) +

+
+ +
+

Keyboard

+

+ Colour is the bank each key drives: green flies the mech, red is an MFD + button bank, amber is a column beside the map. Dark keys are unbound and + free to take. Hover a key to read what it does. +

+ +
+
+
+ flight & fire + MFD button banks + map columns + unbound +
+
+
+ Select a key + Hover a key to read what it drives. +
+ +
+

+ COOLANT VALVES BITE. The valve detents on + 1 2 3 Q W E run 1 – 5 – 50 (max) – 0 (CLOSED) – back to + 1. One press past max shuts that loop off and everything on it + overheats. Boosting one loop starves the others — the supply is + shared. 4 is the flush (hold it), R re-balances every + valve. +

+
+
+ +
+

Where the keys live on the panel

+

+ Each MFD carries eight buttons: a four-wide top row and a four-wide row + beneath it. The keyboard rows run left to right across the upper + displays, then the lower pair — the same order your hand finds them in + the pod. +

+ +
+
+
+
1234
+
Heat / coolant0x2F – 0x2C
0x2B – 0x28
+
QWER
+
+
+
5678
+
Engineering0x27 – 0x24
0x23 – 0x20
+
TYUI
+
+
+
90-=
+
Comm / hotbox0x37 – 0x34
0x33 – 0x30
+
OP[]
+
+ +
+
ASDF
+
Left Weapons0x0F – 0x0C
0x0B – 0x08
+
ZXCV
+
+
+
+
F1F2F3F4F5F6
+
+ Map · radar + + zoom in / out
+ thermal · CROUCH
+ searchlight · display
+ 0x10 – 0x15 +
+
+
F7F8F9F10F11F12
+
+
+
+
HJKL
+
Right Weapons0x07 – 0x04
0x03 – 0x00
+
NM,.
+
+ +

+ G and B stay unbound on purpose: they are the physical gap between + the lower clusters. The right-hand map column is control mode (F7) + and Generators A–D (F9–F12); F8 is a column slot the pod never + wired. +

+
+
+ +
+ + + + + + + +
The weapon and engineering displays are page-gated
Quad pageThe outer buttons jump straight to a populated Eng page.
Eng pageGenerator select A–D, bus mode, coolant toggle, trigger configure, and eject.
Jams & firesA weapon gone quiet with ammo left has jammed — heat jams ballistics, authentically. Its Eng-page buttons flash. Tap eject to clear the round; hold ~3 s to jettison a burning bay before it detonates. An ammo bay fire gives you about ten seconds and it will kill you.
+
+
+ +
+

Gamepad

+

An Xbox-compatible pad drives all five axes and the grip buttons. Hover a control for its RIO address.

+ +
+ + + + + + LT · left pedal + RT · right pedal + LB · look left + RB · look right + + + + + STICK + + torso twist / aim + + + + + + + look · torso centre + + + THRTL + + throttle + + + + + + Y + X + B + A + + A · main trigger + X upper · B reverse · Y torso centre + + +
+
+ Select a control + Hover the diagram to read its binding. +
+ +

+ Flight sticks, HOTAS and pedals: run joyconfig.bat + once. A wizard asks you to move each control in turn, writes the + bindings, and drops you into the solo menu. It only rewrites its own + section of bindings.txt, so hand edits elsewhere survive. +

+
+ +
+

The mouse

+

+ Every button on every display is clickable and lights when the game + commands its lamp — and each reaches in under the glass + beside it, so the picture is the press target. The lit strip at the edge + is only the lamp. Right-click latches a button held. +

+ +
+
+
+
+ + press — top row + press — bottom row + +
+
+ One MFD. Four buttons above the glass and four below, each reaching + half the pane deep — so the two banks meet in the middle and + the whole face answers the mouse. Only a thin strip clears the edge + to show its lamp. +
+
+
+
+ +

Arranging the glass

+

+ The pod bolted its displays down at one size. On a desktop panel there is + room to trade viewscreen for instrument, so all six are yours to size — + and the map to place. Set these in content\environ.ini, + which the game writes on first run with every option documented. +

+ +
+
+
+
CENTERas the pod had it
+
+
+
+
LEFTbottom corner; the MFD slides inboard
+
+
+
+
RIGHTthe same, other side
+
+
+
+
MIDLEFThalfway up; leaves the bottom row alone
+
+
+
+
MIDRIGHThalfway up, right
+
+
+ +
+ + + + + + + + + +
environ.ini — display layout
BT_MFD_SCALEAll five MFDs, as a percentage of pod size. 25–200, default 100
BT_MFD_SCALE_xxAny one on its own — UL UC UR LL LR. Unset inherits the line above.
BT_RADAR_SCALEThe map alone.
BT_RADAR_POSCENTER · LEFT · RIGHT · MIDLEFT · MIDRIGHT
BT_GLASS_PANELS1 = break every display into its own desktop window instead of the composited cockpit.
+
+ +
+

+ Ask for too much and the layout wins. The surround + bands grow to fit whatever you ask for, and a map in a bottom corner + pushes the lower MFD beside it inboard — nothing overlaps and nothing + comes out stretched. +

+
+ +

Filling the screen

+

+ The cockpit fits itself to whatever window it gets at one uniform scale, + so drag it to any shape and nothing distorts — a window that isn't the + cockpit's shape just gets black bars. Launch with -fit for + borderless over the whole monitor. +

+
+ +
+

Rebinding

+

+ content\bindings.txt is written with the full default layout + on first run. Change a line, restart. Delete the file to restore these + defaults — worth doing after an update, since an existing file is never + overwritten. +

+ +
+
# grammar
+key <KEY>   button <addr>
+key <KEY>   axis <chan> deflect <+|-> <rate>
+key <KEY>   axis <chan> slew    <+|-> <rate>
+key <KEY>   axis <chan> set <value>
+pad <BTN>   button <addr>
+padaxis <SRC> axis <chan> [invert] [slew <r>]
+
+# deflect springs back, slew walks and sticks
+# (that is the throttle lever), set jumps
+ +
# examples
+key G button 0x0E      # regroup weapon 1 on G
+key B button 0x41      # look behind on B
+
+# put driving back on WASD if you prefer
+key W axis Throttle slew + 0.7
+key S axis Throttle slew - 0.7
+key A axis LeftPedal  deflect + 2.5
+key D axis RightPedal deflect + 2.5
+
+ +
+ + + + + + + + + + +
Reference — channels, addresses, key names
ChannelsThrottle · LeftPedal · RightPedal · JoystickX · JoystickY · Turn
Buttons0x00 – 0x47
No function0x16 0x17 0x19 0x1E 0x1F 0x38–0x3E — the pod never wired these
Key namesA–Z · 0–9 · F1–F12 · NUMPAD0–9 · NUMPADDOT · UP DOWN LEFT RIGHT · SPACE · LSHIFT LCTRL LALT · MINUS EQUALS COMMA PERIOD LBRACKET RBRACKET BACKTICK
PadA B X Y · DPAD_UP/DOWN/LEFT/RIGHT · LB RB · BACK START · LS RS
Pad axesLX LY RX RY LT RT
+
+ +
+

+ A BOUND KEY LOSES ITS 1995 MEANING. Binding a key + removes it from the authentic typed-hotkey channel so it cannot + double-dispatch — and this board binds nearly everything, so the old + typed hotkeys (5 = Quad page, z = Eng1, t/y/u/i/o = pilot select, +/− + = target zoom) are given up by design. Unbind a key to get its 1995 + meaning back. Same rule for the built-ins: ` is the view + toggle, and J/K/L cycle MFD preset pages only while unbound. +

+
+
+ +
+ BattleTech 4.11 + gitea.mysticmachines.com/VWE/BT411 + docs/CONTROLS.md · CONTROLS.txt ships with the game + RGB keyboards mirror the pod lamps · BT_KEYLIGHT=0 to disable +
+
+ + diff --git a/docs/CONTROLS.md b/docs/CONTROLS.md index 449f05b..136a058 100644 --- a/docs/CONTROLS.md +++ b/docs/CONTROLS.md @@ -9,84 +9,69 @@ Cockpit layout and display sizes live in `content\environ.ini` (likewise self-do --- -## Keyboard +## Keyboard — the keyboard IS the button board + +The letter and number rows are the MFD button banks, laid out where they sit on the panel. +Flight lives on the number pad so the board stays free. + +### Flight — the number pad | Key | Action | | Key | Action | |---|---|---|---|---| -| W/S or ↑/↓ | throttle lever | | X or NumPad5 | all stop | -| A/D or ←/→ | turn pedals | | Alt | reverse thrust | -| Q/E | torso twist | | Shift | throttle up | -| R/F | torso aim | | NumPad 8/2/4/6 | torso aim/twist | -| 1 or Space | main trigger | | 2 | middle thumb | -| 3 or Ctrl | upper thumb (missiles) | | 4 | pinky | -| V | external camera | | B | look behind | -| M | control mode (BAS/MID/ADV) | | N | schematic | -| J/K/L | MFD preset pages | | H (hold) | coolant flush | -| C | cycle a coolant valve | | G (hold) + fire | regroup a weapon | -| − / = | volume down/up | | F5–F9 | generator select / mode | +| NumPad 8 / 2 | torso aim up / down | | NumPad 7 / 9 | left / right pedal | +| NumPad 4 / 6 | torso twist left / right | | NumPad 5 | all stop | +| NumPad 0, Space | main trigger | | NumPad 1 / 3 / . | pinky / middle / upper | +| Shift / Ctrl | throttle up / down (the lever sticks) | | Alt | reverse thrust | +| ← ↓ → | look left / behind / right | | ↑ | torso centre | +| ` | cockpit / chase camera | | − / = *(see below)* | — | -**You spawn in BASIC control mode.** In BASIC the stick steers and the pedal keys do nothing. -Press **M** once for MID, where the pedals steer and the stick twists the torso — the full -experience. If "turning doesn't work", this is why. +**You spawn in BASIC control mode.** In BASIC the stick steers and the pedals do nothing. +Press **F7** once for MID, where the pedals steer and the stick twists the torso — the full +pod experience. If "turning doesn't work", this is why. -Numpad aim keys need **NumLock ON**. +### The panel — letter and number rows -> Control mode (BAS/MID/ADV, the M key) is *not* the menu's experience setting -> (novice/standard/veteran/expert). That one changes the simulation — heat, damage — not your -> controls. +``` + UPPER DISPLAYS Heat / coolant Engineering Comm / hotbox + top row 1 2 3 4 | 5 6 7 8 | 9 0 - = + bottom row Q W E R | T Y U I | O P [ ] + 0x2F..0x2C 0x27..0x24 0x37..0x34 + 0x2B..0x28 0x23..0x20 0x33..0x30 ---- + LOWER DISPLAYS Left Weapons Right Weapons + top row A S D F (G unbound) H J K L + bottom row Z X C V (B unbound) N M , . + 0x0F..0x0C 0x07..0x04 + 0x0B..0x08 0x03..0x00 -## The cockpit panel — all 72 pod buttons + COLUMNS beside the map + left F1 zoom+ F2 zoom- F3 thermal F4 CROUCH F5 lamp F6 display + right F7 control mode F8 - F9..F12 Generators A-D +``` -Each display carries the bank of buttons mounted around it in the real cabinet. Click anywhere on -a display: the buttons reach *under* the glass, so the whole screen is a press target and only the -lit strip at the edge shows. +G and B are deliberately unbound: they are the physical gap between the lower clusters. -### Heat / coolant display — the loop controls -| Button | Action | -|---|---| -| `0x28` | **Balance coolant** — equalise every condenser valve | -| `0x29`–`0x2F` | the six **condenser valves** (Cond 6…1) and the **coolant flush** (`0x2C`, hold) | +**1 2 3 Q W E are the coolant valves** and the detents run 1 - 5 - 50 (max) - **0 (CLOSED)** - +back to 1. One press past max shuts that loop off and everything on it overheats; boosting one +loop starves the others, since the supply is shared. **4** is the flush (hold it) and **R** +re-balances every valve. -⚠ The valve detents run 1 - 5 - 50 (max) - **0 (CLOSED)** - back to 1. One press past max shuts -that loop off and everything on it overheats. Boosting one loop starves the others — the supply -is shared. +The weapon and engineering displays are **page-gated**: on the Quad page the outer buttons jump +to a populated Eng page; on an Eng page they drive generator select A-D, bus mode, coolant +toggle, trigger configure, and **eject** (tap to clear a jam, hold ~3 s to jettison a burning +ammo bay before it detonates). -### Weapon and engineering displays -| Bank | Display | -|---|---| -| `0x00`–`0x07` | Right Weapons (lower right) | -| `0x08`–`0x0F` | Left Weapons (lower left) | -| `0x20`–`0x27` | Engineering (upper centre) | -| `0x30`–`0x37` | Comm / target hotbox (upper right) — pilot select | +### What a bound key gives up -Each display's buttons are **page-gated**: on the Quad page the outer buttons jump straight to a -populated Eng page; on an Eng page they drive the subsystem shown — generator select A–D, bus -mode, coolant toggle, trigger configure, and **eject** (tap to clear a jam, hold ~3 s to jettison -a burning ammo bay). +Binding a key removes it from the authentic 1995 typed-hotkey channel so it cannot +double-dispatch. This board binds nearly everything, so those hotkeys are given up by design: +`5` = MFD1 Quad page, `z` = MFD3 Eng1, `t/y/u/i/o` = pilot select, `+`/`-` = target zoom. +Unbind a key in `bindings.txt` to get its 1995 meaning back. Same rule for the built-ins: +**`** is the view toggle (V is a board button now), and J/K/L cycle the MFD preset pages only +while unbound. -### Map / radar — the side columns -| Button | Action | | Button | Action | -|---|---|---|---|---| -| `0x10` | map zoom in | | `0x18` | cycle control mode (BAS/MID/ADV) | -| `0x11` | map zoom out | | `0x1A`–`0x1D` | generator A–D on/off | -| `0x12` | thermal / IR sight | | `0x16`,`0x17`,`0x19`,`0x1E`,`0x1F` | no function (as shipped in 1995) | -| `0x13` | **crouch** | | | | -| `0x14` | searchlight | | | | -| `0x15` | cycle display mode | | | | - -### Flight controls -| Button | Action | -|---|---| -| `0x3D` | panic / config lamp | -| `0x3F` | throttle head — reverse thrust | -| `0x40` | main trigger | -| `0x41`–`0x44` | hat: behind / torso centre / right / left | -| `0x45`–`0x47` | pinky, middle thumb, upper thumb — the mappable fire buttons | -| `0x38`–`0x3C`, `0x3E` | intercom and door lines — no function on a desktop | - ---- +Addresses with no function at all — the pod never wired them — are `0x16` `0x17` `0x19` +`0x1E` `0x1F` and `0x38`-`0x3E`. ## Controllers diff --git a/docs/GLASS_COCKPIT.md b/docs/GLASS_COCKPIT.md index 608f496..520b6dd 100644 --- a/docs/GLASS_COCKPIT.md +++ b/docs/GLASS_COCKPIT.md @@ -682,3 +682,53 @@ each bank surrounds, with the coolant-valve detent warning and the eject/jam pro flattens it to ASCII as `CONTROLS.txt` at the zip root (the README's own flattening idiom). `players/README.txt` gained pointers to it, to environ.ini, to -fit, and to the RGB mirror. Verified: `mkdist.py` writes a 5149-byte pure-ASCII CONTROLS.txt into the zip. + +## 2026-07-26 (last) — the keyboard becomes the button board (RP412 bindings port) + +User decision: port RP412's bindings design and make it the DEFAULT (not an opt-in alternate), +plus a BT-flavoured interactive controls page. + +**The layout.** Letter and number rows = the MFD banks laid out where they sit on the panel; +flight to the numpad so the board stays free; F1-F12 = the map's two columns; G and B unbound as +the physical gap between the lower clusters. Expressed in BT's OWN grammar (slew/deflect/set, +the Turn channel) -- the bindings.txt format is a compatibility surface and was not touched. + +Coverage audit: **61 of 72 addresses on the keyboard**, and the 11 absent ones are exactly the +addresses with no authored function (0x16/0x17/0x1E/0x1F, 0x38-0x3E). 0x19 is bound (F8) purely +for column completeness. All 72 stay clickable on the panel. + +The scheme lands on BT's addresses unreasonably well: 1-4 + QWER are the whole 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 1995 typed-hotkey channel, and this board +binds nearly everything -- so 5 (Quad), z (Eng1), t/y/u/i/o (pilot select) and +/- (zoom) go. +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, so the view-toggle and preset-cycle polls stand down for them +(they poll GetAsyncKeyState directly and would otherwise have fired BOTH). View toggle lives on +BACKTICK alone. + +**CONTROLS.MAP mirrored** so glass/pod/dev still feel identical (the 2026-07-21 settlement): +90 bindings, 0 parse complaints under BT_INPUT_LOG. + +### Hat labels: 0x42 is TORSO CENTER [T1] +INPUT_PATH_AUDIT flagged 0x41-0x44 as mislabelled. Settled from the streamed mapping +(BT_CTRLMAP_LOG): `elem 66 -> subsys 17 attrID 14` = the TORSO subsystem, while 0x44/0x43/0x41 go +to the mapper's look trio (attrID 10/11/12 = LookLeft/LookRight/LookBehind). The .RES itself has +no "TORSO CENTER" string -- its names are LookBehind/Down/Forward/Left/Right -- so the audit's +wording was loose but its substance right. Swept L4GLASSWIN / L4PADPANEL / L4VB16. + +### The controls page +`docs/CONTROLS.html` -- interactive keyboard (hover any key for its address and meaning, with the +MFD clusters outlined), pad diagram, panel map, the under-glass press-target figure, the radar +placement thumbnails, and the environ.ini table. Modelled on RP412's page, rewritten for BT's +addresses and hazards (the coolant-valve detent warning, jams and ammo-bay fires, BASIC control +mode). mkdist wraps the fragment in a doctype/charset shell and ships it beside CONTROLS.txt. + +### Verified +- bindings.txt regenerates and loads: 74 keys, 0 parse errors; CONTROLS.MAP 90 bindings, 0 errors. +- 72/72 panel addresses still dispatch on click. +- surround / exploded / dock / pod / dev: boot + simulate, zero faults. +- Dist carries CONTROLS.txt + a 46 KB CONTROLS.html with doctype and charset. diff --git a/engine/MUNGA_L4/L4GLASSWIN.cpp b/engine/MUNGA_L4/L4GLASSWIN.cpp index db2bfca..065cdad 100644 --- a/engine/MUNGA_L4/L4GLASSWIN.cpp +++ b/engine/MUNGA_L4/L4GLASSWIN.cpp @@ -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]) }; diff --git a/engine/MUNGA_L4/L4PADBINDINGS.cpp b/engine/MUNGA_L4/L4PADBINDINGS.cpp index 6827a15..08cf9ce 100644 --- a/engine/MUNGA_L4/L4PADBINDINGS.cpp +++ b/engine/MUNGA_L4/L4PADBINDINGS.cpp @@ -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" diff --git a/engine/MUNGA_L4/L4PADPANEL.cpp b/engine/MUNGA_L4/L4PADPANEL.cpp index 1c4b7ac..468fbba 100644 --- a/engine/MUNGA_L4/L4PADPANEL.cpp +++ b/engine/MUNGA_L4/L4PADPANEL.cpp @@ -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" }, diff --git a/engine/MUNGA_L4/L4PADRIO.cpp b/engine/MUNGA_L4/L4PADRIO.cpp index fabd8d6..13b2c00 100644 --- a/engine/MUNGA_L4/L4PADRIO.cpp +++ b/engine/MUNGA_L4/L4PADRIO.cpp @@ -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]) { diff --git a/engine/MUNGA_L4/L4PADRIO.h b/engine/MUNGA_L4/L4PADRIO.h index b8b84b2..ea0fda4 100644 --- a/engine/MUNGA_L4/L4PADRIO.h +++ b/engine/MUNGA_L4/L4PADRIO.h @@ -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). diff --git a/engine/MUNGA_L4/L4VB16.cpp b/engine/MUNGA_L4/L4VB16.cpp index bc9e1e2..6dc1210 100644 --- a/engine/MUNGA_L4/L4VB16.cpp +++ b/engine/MUNGA_L4/L4VB16.cpp @@ -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. diff --git a/tools/mkdist.py b/tools/mkdist.py index 88902be..554f654 100644 --- a/tools/mkdist.py +++ b/tools/mkdist.py @@ -135,6 +135,19 @@ def main(): controls = controls.encode("ascii", "replace").decode("ascii") z.writestr(name + "/CONTROLS.txt", controls) print(" controls reference -> CONTROLS.txt") + + # The same map as a page, for anyone who would rather look at the + # diagrams than read them. The source is a fragment (no doctype or + # ), so wrap it: without a doctype the browser drops into quirks + # mode, and without a charset the typography arrives as mojibake. + if os.path.exists("docs/CONTROLS.html"): + page = open("docs/CONTROLS.html", encoding="utf-8").read() + page = ('\n\n\n' + '\n' + '\n' + '\n\n' + page + '\n\n\n') + z.writestr(name + "/CONTROLS.html", page.encode("utf-8")) + print(" controls page -> CONTROLS.html") for p in bats: # bats at the zip ROOT (next to arc = os.path.basename(p) # content\ + build\, per the guard) z.write(p, name + "/" + arc)