The cabinets had no volume control - they ran at unity and left level to an external amplifier - so a player without that hardware had nowhere to turn it down but environ.ini and a restart. PageUp and PageDown now step the master volume by 0.05 while you play, from silent to double, and whatever you leave it on is written to volume.cfg beside the exe and used from then on. The environ.ini figure decides where a machine that has never been touched starts out; the keys are the knob, and a knob stays where it was left. Page keys because they produce no typed character, so they cannot collide with the character-keyed commands the engine already answers to, nothing else in RP binds them, and they are on every keyboard including tenkeyless. They are polled rather than read off the key-message path, which is worth recording because the message path looked like the obvious home for them and was tried first. RP's keyboard pump only takes WM_KEYUP, WM_SYSKEYUP and WM_CHAR off the front of the queue, and the front end runs message loops of its own, so key messages get raced for and lost: six deliberate, well-spaced presses arrived as two. Fine for the abort chord, useless for something you tap repeatedly to find a level. Reading key state directly costs nothing and cannot be dropped. That losses figure is a pre-existing property of the input path, not something this change introduced, and is worth knowing before anything else gets bound there. Builds clean, runs, and does not fire unprompted. The step function itself is proven - it was driven end to end through the message path before the switch, stepping the right way, clamping, and persisting. What I could not test from here is the polling trigger, because Windows would not hand the game foreground and injecting keys without it would have sprayed them across whatever else was open. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
9.2 KiB
Red Planet 4.12 — controls map
Generated from the default bindings.txt (the file the game writes
beside the exe on first run). Everything here is rebindable: edit that
file and restart, or delete it to get these defaults back.
Grammar reminder, from the file's own header:
key <name> button <addr> [toggle]
key <name> axis <axis> deflect <n> # held, springs back
key <name> axis <axis> rate <n> # walks per second, sticks
pad <button> button <addr> [toggle]
padaxis <src> axis <axis> [invert] [deadzone <d>] [rate <n>]
Xbox controller
( LB ) Panic Throttle / reverse ( RB )
( LT ) Left pedal Right pedal ( RT )
______________________________________________________
/ \
/ [Back] [Start] \
| unbound unbound |
| |
| ,--. (Y) |
| ( L ) stick X / Y Upper |
| `--' (X) (B) |
| +---+ Pinky Middle |
| D-pad --> |hat| (A) |
| +---+ Main |
| |
| ,--. |
| ( R ) throttle (Y axis) |
\ `--' /
\____________________________________________________ _/
| Control | Does | RIO address |
|---|---|---|
| Left stick | Joystick X / Y (inverted, deadzone 0.24 — pod convention) | axes |
| Right stick Y | Throttle, as a rate: hold to wind it up or down, position sticks | axis |
| Left / right trigger | Left / right pedal (deadzone 0.12) | axes |
| A | Main trigger | 0x40 |
| B | Middle | 0x46 |
| X | Pinky | 0x45 |
| Y | Upper | 0x47 |
| LB | Panic | 0x3D |
| RB | Throttle button — reverse thrust | 0x3F |
| D-pad | Hat: up / back / left / right (look) | 0x42 0x41 0x44 0x43 |
| Start, Back | unbound — yours to map | — |
The config buttons (0x37/0x36) are the first two buttons of the
Upper Right MFD's top row, reachable from the keyboard on 9 and 0.
Start and Back ship unbound so you can put anything there; the
commented lines in bindings.txt show how.
Keyboard
Flight cluster — the number pad
+-----+-----+-----+
| 7 | 8 | 9 | 7 / 9 left / right pedal
| Lped| fwd |Rped | 8 / 2 stick forward / back
+-----+-----+-----+ 4 / 6 stick left / right
| 4 | 5 | 6 | 0 main trigger
| left| |right|
+-----+-----+-----+
| 1 | 2 | 3 |
| | back| |
+-----+-----+-----+
| 0 | . |
| trigger | |
+-----------+-----+
Shift throttle up Ctrl throttle down Alt reverse thrust
(both throttle keys walk the axis and it holds where you leave it)
| Key | Does |
|---|---|
| NumPad 8 / 2 | Stick forward / back |
| NumPad 4 / 6 | Stick left / right |
| NumPad 7 / 9 | Left / right pedal |
| NumPad 0, Space | Main trigger (0x40) |
| Shift / Ctrl | Throttle up / down (position holds) |
| Alt | Reverse thrust (0x3F) |
| Arrow keys | Hat — look up / back / left / right |
| Alt + Q | Abort the mission (score banked, back to menu or lobby) |
Panel buttons — the letter and number rows
The rest of the keyboard is the pod's button board, laid out as it is printed on the panel. Each MFD has 8 buttons (a 4-wide top row and a 4-wide bottom row); the keyboard rows run left to right across the three upper MFDs, then the two lower ones.
UPPER MFDs Left MFD Middle MFD Right MFD
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 MFDs Left MFD Right MFD
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
Secondary F1 F2 F3 F4 F5 F6 0x10..0x15
Screen F7 F8 F9 F10 F11 F12 0x18..0x1D
G and B are deliberately unbound: they are the physical gap between the Lower Left and Lower Right MFD clusters on the real board.
Every one of these buttons is also clickable on screen — the red strips around each MFD and the amber strips beside the map are the same addresses, and they light up when the game commands their lamps.
Volume
Page Up and Page Down raise and lower the master volume in steps of
0.05, from silent up to 2.0. The level is written to volume.cfg beside
the exe as you change it and is picked up again next launch, so it stays
where you left it. RP412AUDIOVOLUME in environ.ini sets where a
machine starts out before anyone touches the keys; delete volume.cfg to
go back to it.
The cabinets had no volume control of their own — they ran the game at
unity and left level and tone to an external amplifier and a 3-way
crossover. These keys stand in for the amplifier; RP412AUDIOBASS in
environ.ini stands in for the crossover's low band. See
SOUND.md.
Not bound by default
The pilot keypad (0x50–0x5F) and external operator keypad
(0x60–0x6F) have no keys assigned — the game never reads them. They
remain bindable if you want them (they arrive as arcade RIO key events).
RGB keyboard lighting
If the machine has a Dynamic Lighting keyboard, bound panel keys mirror
the pod's lamps: red for the MFD banks, amber/yellow for the Secondary
and Screen columns, blinking in step with the on-screen buttons.
Unbound keys go dark. Set RP412KEYLIGHT=0 in environ.ini to switch
it off.
Flight sticks, HOTAS and rudder pedals
Anything that is not an Xbox-class pad — a flight stick, a HOTAS
throttle, a twist grip, rudder pedals, a wheel — comes in through
DirectInput rather than XInput, and needs to be told which axis is
which. Run joyconfig.bat once. It asks you to move each control in
turn, works out which device and axis you moved and which way round it
reads, and writes the joystick rows of bindings.txt. Then it carries
on into the setup screen so you can try them straight away.
It only writes its own section, between two marker lines, so anything you have edited yourself survives re-running it. Xbox-class controllers need none of this — they are the pad rows above and work out of the box.
By hand, the rows look like this:
joydev 0 T.16000M # or a bare slot number
joyaxis X axis JoystickX invert deadzone 0.08
joyaxis Y axis JoystickY invert deadzone 0.08
joyaxis RZ axis Pedals deadzone 0.08 # twist grip works both pedals
joyaxis SL0 axis Throttle deadzone 0 # a real lever owns the channel
joybutton 0 button 0x40 # trigger
joyhat 0 up button 0x42
Axis names are DirectInput's — X Y Z RX RY RZ SL0 SL1 — where a twist
grip is usually RZ and a HOTAS throttle usually Z or SL0.
Two things are worth knowing. Pedals is a signed axis that drives the
pedal pair, positive for the right pedal and negative for the left, so
one rudder bar or twist grip works both the way a foot never could. And
a joyaxis on Throttle with no rate is treated as a real lever: its
full travel is the throttle range, rather than nudging a position the
way a spring-centred pad stick has to.
Rebinding
bindings.txt sits beside the exe, written with the full default layout
and its own documentation on first run. Change a line, restart the game.
Delete the file to restore these defaults — worth doing after an update,
since an existing file is never overwritten.
Examples:
key J button 0x40 # main trigger on J as well
pad X button 0x40 # move the trigger to the X button
key NumPadAdd axis Throttle rate 0.75 # throttle on numpad +/-
key NumPadSubtract axis Throttle rate -0.75
padaxis LeftStickX axis JoystickX deadzone 0.15 # drop 'invert' to flip X
Addresses: 0x00–0x47 are the lamp buttons above, 0x50–0x6F the
keypads. Axis names: Throttle, LeftPedal, RightPedal, JoystickX,
JoystickY, Pedals. Key names follow the .NET Keys naming (A–Z, D0–D9
for the digit row, F1–F12, NumPad0–NumPad9, Up, Down,
Left, Right, Space, Return, Shift, Ctrl, Alt,
OemMinus, Oemplus, Oemcomma, OemPeriod, OemOpenBrackets,
OemCloseBrackets, …).