Flight controls: executable versus manual
2026-09-18. Canonical unpacked image offsets. Compared with the supplied manual, printed English pages 17–19 and 22 (PDF pages 10, 11 and 13).
The event dispatcher at B780–B7B6 indexes an 83-entry table at B7FA
with (scan - 1) * 2. 32 entries have a nontrivial handler. Continuous
controls also read the key bitmap at 15A7; they need not appear in this table.
The following covers these flight input paths, not every menu or configuration
screen. Availability depends on craft, equipment, mission and cutscene state.
Main controls and manual coverage
| Key | Flight action | Code evidence | Manual coverage |
|---|---|---|---|
| Left / right arrows | Bank left / right | Held-key steering, 7AD6 onward |
p.17. |
| Up / down arrows | Nose down / up | Same | p.17. |
| Ctrl + arrows | Increase control force | Modifier read from 15AA; manual p.17 |
p.17. |
| Opposing arrows together | Reduce force in first direction | Manual p.17; steering consumes both bits | p.17. |
| A | Toggle automatic altitude adjustment, Caero fighter | B97A, flag 7ED2 |
p.17. |
| E | Engine toggle; craft-dependent behavior | B8CE, flag 4552 |
p.17: Caero explicit; other-craft function only hinted. |
| Enter | Boost; craft-dependent behavior | B956; energy deduction and message |
p.17: Caero explicit; other-craft function only hinted. |
| Number-row − / = (manual says − / +) | Other-craft speed settings | B913/B918, values 248/500 to 7F20, gated by craft |
p.17: keys hinted; speed settings unspecified. |
| Backspace | Brake | Input mask at 7F59, used 7F55, 7FE0, 81D4 |
p.17. |
| Caps Lock | Clear/reacquire target lock | 797B calls CFCB |
p.17. |
| Space | Primary fire | Held-action mask; configurable | p.19. |
| Alt | Secondary fire | Held-action mask; configurable | p.19. |
| 1, 2, 3 | Select available primary weapon | C8A0; mode-dependent |
p.19: keys listed; later weapon names left blank. |
| 5, 6 | Select available secondary ground weapon | C885 |
p.19: keys listed; names left blank. |
| 8, 9, 0 | Select available secondary air weapon | C885 |
p.19: keys listed; names left blank. |
| Insert / keypad 0 | Hold enlarged radar overlay | 55A5, default mask 1000 |
p.18 explicitly documents keypad 0 and magnification; p.22 identifies Insert equivalence. |
| Tab | Hold third-person look-around mode; steering device controls view | 7872, default mask 0180 includes joystick button; third-person transition confirmed during playtesting |
p.18: look-around documented; third-person transition not explicit. |
| F1 | Cockpit; missile-follow view in missile mode | B8AC, view index 0 |
p.18. |
| F2 | Behind craft/missile | Same, index 1 | p.18. |
| F3 | Level behind craft/missile | Same, index 2 | p.18. |
| F4 | Full-screen inside / missile-eye view | Same, index 3 | p.18. |
| F5 | Drop camera, follow craft/missile | B8A0, index 4 |
p.18. |
| F6 | Drop camera, fixed view | B8A0, index 5 |
p.18. |
| F7 | Drop camera on object pointed at | 257D |
p.18. |
| M | Toggle missile-view mode | B8C1, XOR 54CA with 7; disabled for mode 2 |
p.18. |
| Comma / period (manual labels < / >) | Move following camera closer / farther | B8B2/B8B5, six-position index B8B8, consumed 2554 |
p.18. |
| Pause / Num Lock | Pause until another key | Scan 45, B7BB |
p.19. |
| Escape | Quit/confirmation UI | B7CE |
p.19. |
| Q after Escape | Confirm quit | B7DA; requires nonzero 3EA5 |
Not listed in the reviewed control section. |
These are scan codes, not character comparisons. Shift is not necessary for
comma/period zoom or the = event. Dedicated versus keypad equivalents depend
on the keyboard/emulator's extended scan-code delivery. The supplied batch file
runs X Lang=0 Mus=1 without control remappings.
The manual documents mouse/joystick steering and firing as well. It lists command-line
options for changing action masks, but this executable differs from the manual's
fire-option names and has an apparent mask-inversion defect. See the complete
command-line reference and native parser checks before using remapping recipes.
The mask's keyboard half is: Tab 0100, Backspace 0200, equals 0400,
minus 0800, Insert 1000, Caps Lock 2000, Space 4000, Alt 8000.
Lower bits represent mouse/joystick buttons. The bitmap aggregation is B9F3–BA20.
The enlarged radar is therefore documented, though easy to miss: printed p.18 explicitly calls it an overlaid, magnified display. The undocumented bindings in the extras table are distinguished from the merely hinted craft-specific functions above. The Skimma’s repeated 1–3 enable/disable behaviour is not explained in the reviewed control section.
Caero weapon number keys
The manual leaves the later weapon names blank. The following mapping is recovered from the executable's number-row bindings and mission-script weapon introductions. Selections work only when the mission has made that weapon available; these names apply to the Caero, not the Skimma's craft-dependent 1–3 controls.
| Number-row key | Weapon | Fire action |
|---|---|---|
| 1 | Pinner Direct | Primary |
| 2 | Pinner Mimic | Primary |
| 3 | Brent Forbes Dual Launch | Primary; automatically selects its follow-up homing unit after the capsule launches |
| 4 | No direct weapon binding | — |
| 5 | Forbes Diffuser | Secondary; automatically alternates gas capsule and trigger |
| 6 | Brent Ground | Secondary |
| 7 | No direct weapon binding | — |
| 8 | Caero Weapon | Secondary |
| 9 | Pinner/Forbes Chargeable | Secondary; hold to charge, release to launch at a valid target |
| 0 | Brent Hunter | Secondary |
Default keyboard fire actions are Space (primary) and Alt (secondary). The paired weapons use internal selection IDs 4 and 7, but pressing those number keys does not select the corresponding components. In particular, 3 selects both stages of Dual Launch through its automatic sequence; its follow-up remains on the primary-fire path.
Evidence: dispatch B793–B7B8, key table B7FA, selection handlers C8A0/C885,
weapon indexing C9D1–C9D8, and mission availability handler C281.
See weapon identities and behaviour for the slot mapping,
mission evidence and special firing/impact rules.
Extras and hidden controls
| Key | Finding | Evidence and limits | Manual coverage |
|---|---|---|---|
| Z | Toggle player-ship freeze after Lyndon's little snooze |
Playtesting confirms enemies continue, firing and external views work; callback swap at B938 |
Not listed in the reviewed manual control/configuration sections. |
| X | Immediately start next-level transition after Level X |
Playtesting confirms cutscene then progression; B926 |
Not listed in the reviewed manual control/configuration sections. |
| Grave / backtick | Alias for F7's object camera action | Both table words point to 257D; not listed in English controls |
Not listed in the reviewed manual control/configuration sections. |
| F9 | Switch Gouraud-shaded polygons to the flat-colour path and back | 33B4 changes relative jump operands at FC13/FE13, selecting 30EB/30A1 versus 312A/30BD; extra bytes are vertex shades, not UVs; see model-colours.md |
Not listed in the reviewed manual control/configuration sections. |
| J | Reset joystick sampling/calibration state | B7F4 calls 171C and 1731; not a demonstrated mouse/joystick selector |
Not listed in the reviewed manual control/configuration sections. |
| Keypad minus | Cycle paired-view camera separation through 8,16,24,32,40; no effect on the ordinary single-view path | B7E5 changes immediate 2B69; 2B51 gates the paired camera offsets on display mode 3CFD >= 1. Stereo-separation interpretation follows from the two displaced scene draws; full alternate-display output not tested |
Not listed in the reviewed manual control/configuration sections. |
Shift also participates in a camera-state latch (3E20, 257E); this has not
been assigned a separate player-facing action. No active event-table bindings
for F8, F10, number-row 4 or 7 were found. This does not make them unavailable
in other screens or through a different input device.
Keypad minus has five states, with an initial parameter of 16: successive presses select 24, 32, 40, 8, 16. At 2B51, mode 3CFD < 1 jumps straight to the ordinary scene draw at 2BC1, bypassing this parameter entirely. Otherwise the renderer saves the camera position, applies a half-parameter offset (2B6E), draws one view, applies a negative full-parameter offset (2B7C), restores the saved camera values, switches drawing destination and draws the other view. 2B97 projects these offsets using camera-orientation coefficients. This strongly identifies a stereo/paired-view separation adjustment: look for changed relative parallax between the two views, not a detail or shading change. No visible change is expected in the standard single-view mode, consistent with the test. Hardware/display-mode activation and full output remain unverified.
Reproduction
python3 tools/inspect_flight_keys.py writes all 83 entries, including no-ops,
and the relevant held-key bit locations to analysis/flight-keys/bindings.json.
This is static extraction plus manual comparison, not a claim that every key
has been exercised in a complete playthrough. The existing hidden-command
harness separately executes the Z/X handlers and their gates.
Halon / Skimma differences
Playtesting confirms that after level 99 the player moves into the Halon city and flies a Skimma, and that E switches its shields on/off. Bank 31's role is therefore identified by gameplay, not merely guessed from its geometry.
Craft configuration is separate from city-bank selection. Loader BC50–BC66
reads 24-byte records at 1B66 + 24 * byte[F003]:
| Configuration index | Control discriminator B91F |
City bank | Initial callback |
|---|---|---|---|
| 1 | 19 |
30 | 7E7F (Caero) |
| 2 | 1A |
31 | 8108 |
| 3 | 1B |
31 | 7E49 |
| 4 | 19 |
32 | D510 (underground) |
Playtesting confirms that the higher Enter speed is turbo on the upgraded Skimma.
This identifies the 1B behavior as the upgraded configuration; the complete
mission-to-configuration schedule remains to be mapped.
| Control | Caero (19) |
Halon configuration 1A |
Halon configuration 1B |
|---|---|---|---|
| E | Engine toggle | Shield toggle | Same non-Caero shield branch |
| Number-row − | No speed-setting write | Set speed parameter 248 | Set speed parameter 248 |
| Number-row = | No speed-setting write | Set speed parameter 500 | Set speed parameter 500 |
| Enter | Spend 32 boost reserve; activate boost | No action in this handler | Set speed parameter 640 |
| A | Altitude-hold toggle | Normal 8108 flight path ignores this toggle |
Needs configuration-specific callback assessment |
| 1–3, where available | Select weapon | Select/toggle weapon enable | Select/toggle weapon enable |
The speed keys select discrete parameters; they do not increment/decrement a
throttle value. The numbers are internal parameters, not established mph.
Holding the brake bypasses the selected parameter in the 81D1–81E0 path.
The manual's printed p.14 mentions cruising/turbo speeds and upgrades, but does
not supply these key assignments. Playtesting has now confirmed − / = as speed
down/up, and Enter as the upgraded Skimma’s higher maximum speed (turbo).
For non-Caero weapons (C8B6–C8DB), a repeated press on an already selected
available weapon toggles its low enable bit. Changing selection also clears
other enable bits (C8DD). This differs from ordinary Caero selection. The
isolated probe verifies key 1 twice yields 1,0 in the Halon configurations,
versus 1,1 for Caero. Availability is still gated by the equipment mask.
Shields and landing
E sets a startup deadline at 57B8 = timer[0BF8] + 06FF when enabling shields.
The display logic at 57B7–5828 uses that deadline and the resource at 810A.
Thus the code distinguishes enabling shields from their later displayed state;
no conversion of the timer interval into real seconds is claimed.
With the shield flag enabled, 84E7–84FC subtracts incoming damage from 810A
and sets a different damage status when depleted. With shields off, it instead
sets damage status 4. This identifies the earlier “incoming quantity” test more
precisely for the Halon craft: it is shield-resource depletion, not a universal
health field. A 21-point probe takes reserve 100 to 79 with shields enabled.
The supply-pad approach path (C6FB–C76E) requires shields off, object flag
10 clear, bank mode 1, and suitable movement/position conditions. It tests the
cell's type for 3, then installs automatic landing callback 7D9A and sets
object flag 10. E refuses to leave shields enabled while that flag is set.
This matches the manual's p.15 requirement to disable shields before landing.
It also identifies bank 31, type 3 as the supply-pad geometry used by this
landing check.
tools/verify_flight_controls.py executes 16 original-handler probes covering
speed/boost differences, E's landing-state restriction, shield damage and repeated
weapon selection. Sound/UI notification and target-refresh helpers are stubbed;
this is not a substitute for testing each late-game configuration in DOSBox.
Manual shield timing observation
We measured shield charge/startup as approximately 4 seconds with manual reaction-time uncertainty. The PIT setup subsequently traced to divisor 2,386 predicts about 500.075 ticks/second, putting the 06FFh deadline at 3.58146 seconds. The approximately 0.42-second difference is retained rather than declaring an exact confirmation or changing the clock rate to fit it. The display routine 57B7–5828 has several phases based on the remaining deadline and shield reserve; which visible transition was timed is not established. No extra fixed delay has been established by this inspection. Video timing of consistent start/end landmarks would resolve the comparison more tightly.
See recorded measurement.