技术文档

Cockpit controls: MSFS interactions

此页为项目的英文技术文档原文。 docs/COCKPIT_CONTROLS.md

tools/msfs/generate_behaviors.py --sci data/sci gives every click spot of the cockpit an MSFS-style interaction: knobs turn with the wheel and a drag, switches flip by click or drag, levers drag through their detents. Every gesture sends only the stable-interface events the click spot sent before (H:LU737_<CONTROL>_<ACTION>, docs/SCI_IMPLEMENTATION.md §8), so the WASM module and the IO instrument are unchanged. --plain-clicks brings back the old plain click spots (same output as before, byte for byte).

How it is built#

The callback code follows Asobo's generic interaction templates (Asobo\Generic\Interactions.xml: ASOBO_GT_Interaction_WheelAndContinuousLeft_LeftSingle, ASOBO_GT_Interaction_LeftSingle_Code, ASOBO_GT_Interaction_DraggingAxis_Code; offline copy in docs/reference/msfs2024/). It is expanded inline into each <MouseRect> instead of <UseTemplate> so that the exact SCI events are sent and the model does not depend on the SDK template include path. One code serves both cockpit interaction modes (IMDefault = legacy, IMDrag = lock):

  • press = LeftSingle or Lock, release = LeftRelease or Unlock (O:_Down drops the duplicate);
  • a drag compares M:RelativeX/Y with the position of the last step: one step per DRAG_STEP of mouse travel (constants at the top of the interaction code, tune them there);
  • a left press that is released without a drag step is a click.

Mapping (counts for the 737-800 cockpit, 991 click spots)#

Class Count From Gestures → SCI events
button 615 command push buttons, EFB / CDU / keypad keys unchanged plain click: PRESS on down, RELEASE on up
guard 22 covers (*cover*, GUARD_TOGGLE) unchanged plain click (the click toggles the guard)
toggle_cmd 70 single toggle command on a switch / selector / lever (up_down, left_right, rotate cursors; parking brake, manual gear handle) PRESS on down (held), RELEASE on up, so a click or a drag flips it; rotary ones also step with the wheel (PRESS+RELEASE)
toggle 17 X-Plane toggle (fuel pumps, light switches, start-lever toggles) click or drag (once per gesture) → TOGGLE
switch 74 command_switch_up_down (Y) / _left_right (X) with arrow cursors drag up/right → first command (INC side), down/left → second; the dragged position is held until mouse up, then RELEASE (spring positions return); click on the upper / right half (cursor UpArrow / RightArrow) → first command, on the lower / left half (DownArrow / LeftArrow) → second, + RELEASE; wheel up/down → one step each way
knob 133 command_knob, axis_knob, rotary-cursor command_switch_* wheel up = INC, down = DEC; drag right/up = INC, left/down = DEC (one step per threshold); left click on the left half (cursor TurnLeft) = DEC, on the right half (TurnRight) = INC, decided where the button went down; RELEASE where the control had it
lever 22 drag_rotate, drag_axis, drag_xy (throttles, reversers, start levers, flaps, speed brake, gear, tiller, checklist bugs, EFB stand) drag along the lever: INC/DEC per step (the control goes to the next detent, flaps / speed brake / gear, or 10 % of the range); wheel up = INC, down = DEC; no click action
pair 38 split controls: two neighbouring spots with opposite commands (overwing exits open/close, yoke electric trim, standby altimeter +/−) each half keeps its own click (PRESS at once, held until mouse up, as in X-Plane); both halves: wheel up/down = the up/plus half's / the other half's PRESS+RELEASE; drag up (or right/up for +/−) = up half, down = other half (switch pairs hold the dragged half until mouse up)

Event set: the 2123 H:LU737_* events emitted before are all still emitted; none added (data/cockpit_io.json → sci_events, interactions).

Lever drag direction comes from the X-Plane manipulator: rotation about +x (flaps, speed brake, gear, reversers) increases when the handle moves aft/down, about −x (throttles, start levers) when it moves forward/up; drag_axis uses the axis vector (forward counts as up). drag_xy drives only its X dataref (the Y dataref has no SCI control).

What to test in MSFS (both cockpit interaction modes: Legacy and Lock)#

  1. Knobs (heading, course, altitude, EFIS range/mode, engine start, lights dimmers): wheel both ways; left click on the left half (TurnLeft cursor) = decrease, right half (TurnRight) = increase; press and drag left/right and up/down. Check the step size (DRAG_STEP["knob"]).
  2. Switches (overhead toggles, GEN / GPU / APU GEN spring switches, battery, standby power, APU START): click, drag up and down, wheel. Spring positions: drag and keep the button down: the switch must stay there and return on release (GEN ON/OFF, APU START, fire test).
  3. Guards: click opens/closes; a guarded switch under a closed guard must still be blocked.
  4. Levers: throttles (each and both), reversers, start levers, flaps through every detent, speed brake (ARM / FLT / UP), gear, parking brake, tiller: drag direction feels right, detents are reached, wheel works.
  5. Split controls: overwing exits, yoke trim (hold to trim, drag down = nose up), standby altimeter baro: click each half, wheel, drag.
  6. Buttons and EFB / CDU keys: unchanged; check a few still press and release.

Known limits: a plain left click on a switch acts on mouse up (so that a drag never first sends the opposite command); to hold a spring position use a drag. The right button does nothing on any control (build 36): MSFS looks around with it held, and a right press over a control used to move it. No control in the contract has INC_FAST/DEC_FAST or DRAG, so fast turning and absolute lever positions are not used yet; a later contract with DRAG/SET_n can map lever drags directly to positions.

Cursors (2026-11-01)#

Like Asobo's templates, the MouseRects use position-dependent cursors (CursorLeft/CursorRight/CursorUp/CursorDown): knobs show TurnLeft on their left half and TurnRight on their right half, up/down switches UpArrow/DownArrow, left/right switches LeftArrow/RightArrow, levers Grab; while dragging (drag interaction mode) the cursor is Grab. A left click acts toward the half the cursor shows. If a switch or knob turns the opposite way to its cursor, (M:RelativeY) / (M:RelativeX) have the other sign than assumed: report it (one sign flip in the generator).