<?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>