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
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.
+
+ 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.
+
+ 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 page
The outer buttons jump straight to a populated Eng page.
+
Eng page
Generator select A–D, bus mode, coolant toggle, trigger configure, and eject.
+
Jams & fires
A 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.
+
+
+
+
+
+ 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.
+
All five MFDs, as a percentage of pod size. 25–200, default 100
+
BT_MFD_SCALE_xx
Any one on its own — UL UC UR LL LR. Unset inherits the line above.
+
BT_RADAR_SCALE
The map alone.
+
BT_RADAR_POS
CENTER · LEFT · RIGHT · MIDLEFT · MIDRIGHT
+
BT_GLASS_PANELS
1 = 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.
+
# 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
0x16 0x17 0x19 0x1E 0x1F 0x38–0x3E — the pod never wired these
+
Key names
A–Z · 0–9 · F1–F12 · NUMPAD0–9 · NUMPADDOT · UP DOWN LEFT RIGHT · SPACE · LSHIFT LCTRL LALT · MINUS EQUALS COMMA PERIOD LBRACKET RBRACKET BACKTICK
+
Pad
A B X Y · DPAD_UP/DOWN/LEFT/RIGHT · LB RB · BACK START · LS RS
+
Pad axes
LX 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.
+
+
+
+
+
+
+
+
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)