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>
115 lines
5.4 KiB
Markdown
115 lines
5.4 KiB
Markdown
# BattleTech 4.11 — controls reference
|
||
|
||
Two ways to fly: the **keyboard/pad** (the ~25 core actions) and the **cockpit panel**, where
|
||
every one of the pod's 72 illuminated buttons is mouse-clickable exactly where it sat in the
|
||
cabinet. Left-click presses; **right-click latches** a button held.
|
||
|
||
Rebind keys in `content\bindings.txt` (delete it to regenerate the defaults).
|
||
Cockpit layout and display sizes live in `content\environ.ini` (likewise self-documenting).
|
||
|
||
---
|
||
|
||
## 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 |
|
||
|---|---|---|---|---|
|
||
| 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 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.
|
||
|
||
### The panel — letter and number rows
|
||
|
||
```
|
||
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
|
||
|
||
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
|
||
```
|
||
|
||
G and B are deliberately unbound: they are the physical gap between the lower clusters.
|
||
|
||
**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 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).
|
||
|
||
### What a bound key gives up
|
||
|
||
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.
|
||
|
||
Addresses with no function at all — the pod never wired them — are `0x16` `0x17` `0x19`
|
||
`0x1E` `0x1F` and `0x38`-`0x3E`.
|
||
|
||
## Controllers
|
||
|
||
An **Xbox controller** works out of the box.
|
||
|
||
**Flight sticks, HOTAS and pedals:** run `joyconfig.bat` once. A wizard asks you to move each
|
||
control in turn — stick, twist, throttle, fire buttons — writes the bindings, and drops you into
|
||
the solo menu to try them. It only rewrites its own section of `bindings.txt`, so hand edits
|
||
elsewhere in the file survive.
|
||
|
||
**Mouse buttons** are bindable like any key — `MOUSE4`, `MOUSE5` (the side buttons),
|
||
`MOUSEMIDDLE`, and `MOUSELEFT`/`MOUSERIGHT`. The side and middle buttons are the free ones; left
|
||
and right are how you press cockpit buttons, so binding those fires on every panel click too.
|
||
Mouse *movement* is not bindable — see `docs/MOUSELOOK_PLAN.md`.
|
||
|
||
```
|
||
key MOUSE4 button 0x40 # side button = main trigger
|
||
key MOUSE5 button 0x46 # side button = middle thumb
|
||
```
|
||
|
||
**RGB keyboards** with Windows Dynamic Lighting mirror the panel: any key you have bound to a
|
||
lamp button glows in the panel's own colours and flashes in step with the on-screen buttons. Turn
|
||
it off with `BT_KEYLIGHT=0` in `environ.ini`.
|
||
|
||
---
|
||
|
||
## Cockpit layout
|
||
|
||
Set these in `content\environ.ini`:
|
||
|
||
- **`BT_MFD_SCALE`** (and `_UL`/`_UC`/`_UR`/`_LL`/`_LR`) — size of the five MFDs, as a percentage
|
||
of their pod size. Turn them up if you want to actually read them while you fly.
|
||
- **`BT_RADAR_SCALE`**, **`BT_RADAR_POS`** — size the map, and move it out of the middle of the
|
||
road: `CENTER`, `LEFT`, `RIGHT`, `MIDLEFT`, `MIDRIGHT`.
|
||
- **`BT_GLASS_PANELS=1`** — break every display out into its own desktop window instead of the
|
||
composited cockpit. Good for reading one display at full size.
|
||
|
||
Run with **`-fit`** for a borderless window over the whole monitor. The cockpit scales to any
|
||
window shape at one uniform scale, so nothing ever stretches — a window that isn't the cockpit's
|
||
shape just gets black bars.
|