The interactive controls page had drifted from the markdown fix-ups: PgUp/PgDn
rendered as unbound keys with no meaning (the volume keys live there now), and
the Rebinding section still promised 'an existing file is never overwritten' --
made false by the board-2 migration. Both corrected; the page and CONTROLS.txt
now tell the same story.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
BUTTONS (shipped). Win32 hands mouse buttons out as virtual keys, and the
binding path already stores VKs and polls GetAsyncKeyState -- so this needed no
verb, no parser change and no new machinery, just names:
key MOUSE4 button 0x40 # side buttons
key MOUSE5 button 0x46
key MOUSEMIDDLE button 0x41
MOUSELEFT/MOUSERIGHT are named too, with a warning in the file header and the
docs: they are how the player presses cockpit buttons (left = press, right =
latch), and the poll is focus-guarded but not click-aware, so binding either
ALSO fires on every panel click. The side and middle buttons are the free
ones. Axes work as well (`key MOUSE4 axis Throttle slew + 0.7`).
One guard: the RGB lamp mirror skips mouse VKs when building its map -- a
keyboard lamp array has no mouse buttons to paint (BTPadBindingIsMouseKey).
Verified live: a bindings.txt carrying two mouse rows loads 76 keys (74 + 2),
and a real injected XBUTTON1 press produced `[emitter] FIRED #1`. Clean A/B --
the earlier run whose SendInput failed the struct-size check logged no fire at
all. Shipped commented-out examples in the default profile so the capability
is discoverable.
LOOK (scoped only). docs/MOUSELOOK_PLAN.md. Mouse MOVEMENT is a real feature,
not a table entry, and the hard part is not reading the device:
- The cursor is already spoken for. The glass cockpit's premise is that all
72 buttons are mouse targets; mouse-look wants a captured, hidden, recentred
cursor. Both cannot be true, so this is a MODE question first -- four
models compared, recommending hold-to-look (costs nothing when unbound,
cannot strand a player, behaves the same in surround and exploded layouts).
- The channels are POSITIONAL (JoystickX/Y are -1..1 deflections the mapper
reads per control mode); a mouse gives deltas. Accumulate-into-a-virtual-
stick reuses every existing rule; a rate model would need new mapper
semantics.
- Control mode changes what it MEANS: BASIC steers with the stick, MID/ADV
twist the torso -- so mouse-look steers in one and aims in the other.
Proposed grammar (new row type, so old builds skip it with a warning),
where the code goes, ~250 lines, and a verification plan whose load-bearing
item is "panel clicks still work when a mouselook binding exists but is not
engaged". Also flagged: the pod had NO mouse, so nothing here is
reconstruction -- every choice is design, judged on feel, and it must stay out
of the pod build's path.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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>