<?xml version="1.0" ?> <!-- Saitek X36F + X35T binding. Copyright (C) 2005-2012 Anders Gidenstam (anders(at)gidenstam.org) This file is released under the GPL license version 2 or later. --> <!-- Remember to tell the joystick driver that it is a full CHF stick: On GNU/Linux this can be done in this way: Linux 2.4.x kernel: modprobe analog js=0x7ff,0x7ff Linux 2.6.x kernel: modprobe analog map=fullchf --> <PropertyList> <!-- NOTE: The X36 is a game port device so it may get a generic name. --> <name type="string">Saitek X36</name> <name type="string">Saitek Saitek X36</name> <name type="string">Analog 4-axis 6-button 2-hat CHF joystick</name> <data> <view-mode type="int">0</view-mode> <quick-view-active type="int">0</quick-view-active> <stick-active type="int">1</stick-active> </data> <nasal> <script> <![CDATA[ var self = cmdarg().getParent(); var data = self.getNode("data"); var view_mode = data.getNode("view-mode"); var quick_view_active = data.getNode("quick-view-active"); var stick_active = data.getNode("stick-active"); var old_view = view.point.save(); var goal_heading_offset = props.globals.getNode("/sim/current-view/goal-heading-offset-deg", 1); var goal_pitch_offset = props.globals.getNode("/sim/current-view/goal-pitch-offset-deg", 1); var kbdshift = props.globals.getNode("/devices/status/keyboard/shift", 1); var kbdctrl = props.globals.getNode("/devices/status/keyboard/ctrl", 1); var kbdalt = props.globals.getNode("/devices/status/keyboard/alt", 1); var quick_view = func { var dir = arg[0]; if (dir == 0) { quick_view_active.setIntValue(0); view.point.move(old_view, 0.1); } else { if (quick_view_active.getValue() == 0) { quick_view_active.setIntValue(1); old_view = view.point.save(); if (dir == 1) { goal_heading_offset.setDoubleValue (getprop("/sim/view/config/left-direction-deg")); goal_pitch_offset.setDoubleValue (getprop("/sim/view/config/pitch-offset-deg")); view.fovProp.setDoubleValue (getprop("/sim/view/config/default-field-of-view-deg")); } if (dir == 2) { goal_heading_offset.setDoubleValue (getprop("/sim/view/config/right-direction-deg")); goal_pitch_offset.setDoubleValue (getprop("/sim/view/config/pitch-offset-deg")); view.fovProp.setDoubleValue (getprop("/sim/view/config/default-field-of-view-deg")); } if (dir == 3) { goal_heading_offset.setDoubleValue (getprop("/sim/view/config/front-direction-deg")); goal_pitch_offset.setDoubleValue (getprop("/sim/view/config/pitch-offset-deg")); view.fovProp.setDoubleValue (getprop("/sim/view/config/default-field-of-view-deg")); } if (dir == 4) { goal_heading_offset.setDoubleValue (getprop("/sim/view/config/back-direction-deg")); goal_pitch_offset.setDoubleValue (getprop("/sim/view/config/pitch-offset-deg")); view.fovProp.setDoubleValue (getprop("/sim/view/config/default-field-of-view-deg")); } } } } var aileron = props.globals.getNode("/controls/flight/aileron", 1); var elevator = props.globals.getNode("/controls/flight/elevator", 1); var rudder = props.globals.getNode("/controls/flight/rudder", 1); var aileron_js = props.globals.getNode("/controls/flight/aileron-js", 1); var elevator_js = props.globals.getNode("/controls/flight/elevator-js", 1); var rudder_js = props.globals.getNode("/controls/flight/rudder-js", 1); var js_active = func { settimer(js_active, 0); if (stick_active.getValue()) { aileron.setDoubleValue(aileron_js.getValue()); elevator.setDoubleValue(elevator_js.getValue()); rudder.setDoubleValue(rudder_js.getValue()); } } setlistener("/sim/signals/fdm-initialized", js_active); ]]> </script> </nasal> <!-- Analog axis 0. Aileron --> <axis n="0"> <desc>aileron</desc> <binding> <command>property-scale</command> <property>/controls/flight/aileron-js</property> <dead-band type="double">0.0</dead-band> <offset type="double">0.0</offset> <squared type="bool">true</squared> </binding> </axis> <!-- Analog axis 1. Elevator --> <axis n="1"> <desc>elevator</desc> <binding> <command>property-scale</command> <property>/controls/flight/elevator-js</property> <dead-band type="double">0.0</dead-band> <offset type="double">0.0</offset> <factor type="double">-1.0</factor> <squared type="bool">true</squared> </binding> </axis> <!-- Analog axis 3. Rudder --> <axis n="3"> <desc>rudder</desc> <binding> <command>property-scale</command> <property>/controls/flight/rudder-js</property> <dead-band type="double">0.010</dead-band> <offset type="double">0.0</offset> <factor type="double">1.0</factor> <squared type="bool">true</squared> </binding> </axis> <!-- Analog axis 2. Throttle --> <axis n="2"> <desc>throttle</desc> <binding> <command>nasal</command> <script>controls.throttleAxis()</script> </binding> </axis> <!-- Axis 4. Hat 1 --> <axis n="4"> <name>Right hat left/right</name> <desc> view-mode 0: horizontal view pan, view-mode 1: quick view left/right </desc> <low> <repeatable type="bool">true</repeatable> <binding> <command>nasal</command> <script> <![CDATA[ #print("X36.xml: Axis 4, Hat 1: low!"); var m = view_mode.getValue(); if (m == 0) { view.panViewDir(0.5); } if (m == 1) { quick_view(1); } ]]> </script> </binding> <mod-up> <binding> <command>nasal</command> <script> #print("X36.xml: Axis 4, Hat 1: low released!"); var m = view_mode.getValue(); if (m == 1) { quick_view(0); } </script> </binding> </mod-up> </low> <high> <repeatable type="bool">true</repeatable> <binding> <command>nasal</command> <script> <![CDATA[ #print("X36.xml: Axis 4, Hat 1: high!"); var m = view_mode.getValue(); if (m == 0) { view.panViewDir(-0.5); } if (m == 1) { quick_view(2); } ]]> </script> </binding> <mod-up> <binding> <command>nasal</command> <script> #print("X36.xml: Axis 4, Hat 1: low released!"); var m = view_mode.getValue(); if (m == 1) { quick_view(0); } </script> </binding> </mod-up> </high> </axis> <!-- Axis 5. Hat 1 --> <axis n="5"> <name>Right hat up/down</name> <desc> view-mode 0: vertical view pan, view-mode 1: quick view front/view reset </desc> <low> <repeatable type="bool">true</repeatable> <binding> <command>nasal</command> <script> <![CDATA[ #print("X36.xml: Axis 5, Hat 1: low!"); var m = view_mode.getValue(); if (m == 0) { view.panViewPitch(0.5); } if (m == 1) { quick_view(3); } ]]> </script> </binding> <mod-up> <binding> <command>nasal</command> <script> #print("X36.xml: Axis 4, Hat 1: low released!"); var m = view_mode.getValue(); if (m == 1) { quick_view(0); } </script> </binding> </mod-up> </low> <high> <repeatable type="bool">true</repeatable> <binding> <command>nasal</command> <script> <![CDATA[ #print("X36.xml: Axis 5, Hat 1: low!"); var m = view_mode.getValue(); if (m == 0) { view.panViewPitch(-0.5); } if (m == 1) { view.resetView(); #quick_view(4); } ]]> </script> </binding> <mod-up> <binding> <command>nasal</command> <script> #print("X36.xml: Axis 4, Hat 1: low released!"); var m = view_mode.getValue(); if (m == 1) { #quick_view(0); } </script> </binding> </mod-up> </high> </axis> <!-- Axis 6. Hat 2. NOTE: The axes of hat 2 are messed up on the X36. Up - Down := Axis 6.low - Axis 7.high Left - Right := Axis 6.high - Axis 7.low --> <axis n="6"> <desc>elevator trim (hat up/down)</desc> <low> <repeatable type="bool">true</repeatable> <binding> <command>nasal</command> <script> #print("X36.xml: Axis 6, Hat 1: low!"); controls.elevatorTrim(-1) </script> </binding> </low> <high> <repeatable type="bool">true</repeatable> <binding> <command>nasal</command> <script> #print("X36.xml: Axis 6, Hat 1: high!"); view.increase() </script> </binding> </high> </axis> <!-- Axis 7. Hat 2. --> <axis n="7"> <desc>Zoom out/in (hat left/right)</desc> <low> <repeatable type="bool">true</repeatable> <binding> <command>nasal</command> <script> #print("X36.xml: Axis 7, Hat 1: low!"); view.decrease() </script> </binding> </low> <high> <repeatable type="bool">true</repeatable> <binding> <command>nasal</command> <script> #print("X36.xml: Axis 7, Hat 1: high!"); controls.elevatorTrim(1) </script> </binding> </high> </axis> <!-- Button: Trigger --> <button n="0"> <name>Trigger</name> <desc>brakes, +Shift: Toggle parking brake, +Ctrl: trigger</desc> <binding> <command>nasal</command> <script> #print("X36.xml: Button 0 pressed!"); if (kbdctrl.getBoolValue()) { controls.trigger(1); } else { if (kbdshift.getBoolValue()) { controls.applyParkingBrake(1); } else { controls.applyBrakes(1); } } </script> </binding> <mod-up> <binding> <command>nasal</command> <script> controls.applyBrakes(0); controls.trigger(0); </script> </binding> </mod-up> </button> <!-- Button: Fire C --> <button n="1"> <name>Fire C</name> <desc>next view +Shift: previous view +Ctrl: next weapon +Ctrl+Shift: previous weapon</desc> <repeatable>false</repeatable> <binding> <command>nasal</command> <script> #print("X36.xml: Button 1 pressed!"); if (kbdctrl.getBoolValue()) { if (kbdshift.getBoolValue()) { controls.weaponSelect(-1); } else { controls.weaponSelect(1); } } else { if (kbdshift.getBoolValue()) { view.stepView(-1) } else { view.stepView(1) } } </script> </binding> </button> <!-- Button: A --> <button n="2"> <name>A</name> <desc>left brake</desc> <binding> <command>nasal</command> <script> #print("X36.xml: Button 2 pressed!"); controls.applyBrakes(1, -1); </script> </binding> <mod-up> <binding> <command>nasal</command> <script> controls.applyBrakes(0, -1); </script> </binding> </mod-up> </button> <!-- Button: B --> <button n="3"> <name>B</name> <desc>right brake</desc> <binding> <command>nasal</command> <script> #print("X36.xml: Button 3 pressed!"); controls.applyBrakes(1, 1); </script> </binding> <mod-up> <binding> <command>nasal</command> <script> controls.applyBrakes(0, 1); </script> </binding> </mod-up> </button> <!-- Button: Launch --> <button n="4"> <name>Launch</name> <desc>toggle view mode</desc> <binding> <command>nasal</command> <script> #print("X36.xml: Button 4 pressed!"); if (view_mode.getValue() == 0) { view_mode.setIntValue(1); } else { view_mode.setIntValue(0); } </script> </binding> <mod-up> <binding> <command>nasal</command> <script> </script> </binding> </mod-up> </button> <!-- Button: F.lock --> <button n="5"> <name>F.lock</name> <desc>disarm speed brakes, +Shift: deploy speed brakes</desc> <binding> <command>nasal</command> <script> #print("X36.xml: Button 5 pressed!"); var sb = "/controls/flight/speedbrake"; if (kbdshift.getBoolValue()) { setprop(sb, 1.0); } else { setprop(sb, 0.0); } if (kbdalt.getBoolValue()) { stick_active.setIntValue(!stick_active.getValue()); } </script> </binding> </button> </PropertyList>