diff --git a/Input/Joysticks/Microsoft/sidewinder-force-feed2.xml b/Input/Joysticks/Microsoft/sidewinder-force-feed2.xml index c4707a068..d56d10091 100644 --- a/Input/Joysticks/Microsoft/sidewinder-force-feed2.xml +++ b/Input/Joysticks/Microsoft/sidewinder-force-feed2.xml @@ -1,200 +1,544 @@ -<?xml version="1.0" ?> +<?xml version="1.0"?> +<!-- +$Id$ + +Note: This is asimple edit of Melchor Franz Cyborg-Gold-3d-USB.xml file. This Saitek +joystick has the same number of buttons as the MS Sidewinder Force Feedback 2. +_______________________________________ Layout _______________________________________ + + +axis 0: aileron +axis 1: elevator +axis 2: rudder +axis 3: throttle + + + no modifier K7=B6 K8=B7 K7+K8 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +button 0 (trigger): brakes parking brake speed brake thrust revers. +button 2 (left): flaps up gear up previous view * +button 1 (middle): reset view dir tail wheel lock cockpit view reset all trim +button 3 (right): flaps down gear down next view * +button 4 (K5): brakes right * zoom in * +button 5 (K6): brakes left * zoom out * +button 6 (K7): //////////////////////// modifier 0 ///////////////////////// +button 7 (K8): //////////////////////// modifier 1 ///////////////////////// +hat left: look left leaner mixture aileron trim rudder trim +hat right: look right richer mixture aileron trim rudder trim +hat back: look up dec prop pitch elevator trim * +hat forward: look down inc prop pitch elevator trim * + + +K7 and K8 are used like "Shift", "Control", or "Alternate" on computer keyboards. +For example: press K7 and keep holding it down while pressing the fire +button/trigger -> toggle parking brake + +When flying the Harrier, "K7/hat left" and "right" control the thrust vector. + + + +___________________________________ Customization ____________________________________ + + + +If you want to change some (or all) of the bindings, the recommended way is +to copy this file to your home directory, make your changes there, and include +it from your personal preferences.xml file. You can use any number lower than +1000 for n in <js-named n="0">. The lowest takes precedence in case of identical +names. You can include such a preferences.xml file with the ~~config option, +e.g. ~~config=$HOME/.fgfs/preferences.xml, and you can put that ~~config line +into your personal $HOME/.fgfsrc file. + +<?xml version="1.0"?> +<PropertyList> + <input> + <js-named n="100"> + <joysticks include="your-modified-copy.xml"/> + </js-named> + </input> +</PropertyList> + + +The property "/input/joysticks/js[0]/data/modifier" indicates the "shift" level. +K7 sets bit 0, K8 sets bit 1. The property is zero if none of the shift buttons +is pressed, 1 if K7 is pressed, 2 if K8 is pressed, and 3 if both K7 and K8 are +pressed. + +Note that you have to enclose nasal scripts in <script><![CDATA[...]]></script> +if they contain characters that interfere with the xml markup. This is the case +if you are, for example, using < (lower than). Alternatively, you can 'escape' +the character with "<". + +Also note that all nasal code shares a common namespace, so it's possible to set +a variable in one nasal binding, and to read it in another. + + + +____________________________________ References ______________________________________ + + + +Joysticks: $FG_ROOT/Docs/README.Joystick.html +Properties: see property browser (fgfs menu: "File"->"Browse internal properties") + +Nasal: http://www.plausible.org/nasal/ +Nasal examples: $FG_ROOT/Nasal/ + + +______________________________________________________________________________________ + + ~~ Melchior FRANZ <mfranz # aon : at> + This MS Sidewinder Force Feedback 2 xml is a straight forward edit by Dave Perry + of the Saitek Cyborg-Gold-3d-USB.xml file written by Melchior Franz. +--> <PropertyList> + <name>Microsoft SideWinder Force Feedback 2</name> + <data> + <mode type="int">0</mode> + <modifier type="int">0</modifier> + </data> - <name>Microsoft SideWinder Force Feedback 2</name> + <nasal> + <script><![CDATA[ + data = props.globals.getNode(this).getNode("data"); + mode = data.getNode("mode"); + modifier = data.getNode("modifier"); + f1 = f2 = 0; + left_brake = right_brake = 0; - <axis n="0"> - <desc>Aileron</desc> - <binding> - <command>property-scale</command> - <property>/controls/flight/aileron</property> - <squared type="bool">true</squared> - </binding> - </axis> + get_mode = func { modifier.getValue() + mode.getValue() * 4 } - <axis n="1"> - <desc>Elevator</desc> - <binding> - <command>property-scale</command> - <property>/controls/flight/elevator</property> - <factor type="double">-1.0</factor> - <squared type="bool">true</squared> - </binding> - </axis> + harrier = func { + if (getprop("/sim/aero") == "harrier") { + thv = getprop("/controls/engines/engine[0]/mixture"); + gui.popupTip("Thrust vector " ~ int(thv * 120 - 20)); + } + } + ]]></script> + </nasal> - <axis n="3"> - <desc>Rudder</desc> - <binding> - <command>property-scale</command> - <property>/controls/flight/rudder</property> - <factor type="double">1.0</factor> - </binding> - </axis> + <axis n="0"> + <desc>Aileron</desc> + <binding> + <command>property-scale</command> + <property>/controls/flight/aileron</property> + <power type="double">2.0</power> + </binding> + </axis> - <axis n="2"> - <desc>Throttle</desc> - <binding> - <command>property-scale</command> - <property>/controls/engines/engine[0]/throttle</property> - <offset type="double">-1.0</offset> - <factor type="double">-0.5</factor> - </binding> - <binding> - <command>property-scale</command> - <property>/controls/engines/engine[1]/throttle</property> - <offset type="double">-1.0</offset> - <factor type="double">-0.5</factor> - </binding> - <binding> - <command>property-scale</command> - <property>/controls/engines/engine[2]/throttle</property> - <offset type="double">-1.0</offset> - <factor type="double">-0.5</factor> - </binding> - <binding> - <command>property-scale</command> - <property>/controls/engines/engine[3]/throttle</property> - <offset type="double">-1.0</offset> - <factor type="double">-0.5</factor> - </binding> - <binding> - <command>property-scale</command> - <property>/controls/engines/engine[4]/throttle</property> - <offset type="double">-1.0</offset> - <factor type="double">-0.5</factor> - </binding> - <binding> - <command>property-scale</command> - <property>/controls/engines/engine[5]/throttle</property> - <offset type="double">-1.0</offset> - <factor type="double">-0.5</factor> - </binding> - <binding> - <command>property-scale</command> - <property>/controls/engines/engine[6]/throttle</property> - <offset type="double">-1.0</offset> - <factor type="double">-0.5</factor> - </binding> - <binding> - <command>property-scale</command> - <property>/controls/engines/engine[7]/throttle</property> - <offset type="double">-1.0</offset> - <factor type="double">-0.5</factor> - </binding> - </axis> + <axis n="1"> + <desc>Elevator</desc> + <binding> + <command>property-scale</command> + <property>/controls/flight/elevator</property> + <factor type="double">-1.0</factor> + <power type="double">2.0</power> + </binding> + </axis> - <axis n="6"> - <desc>View Direction</desc> - <low> - <repeatable>true</repeatable> - <binding> - <command>property-adjust</command> - <property>/sim/current-view/goal-heading-offset-deg</property> - <step type="double">1.0</step> - </binding> - </low> - <high> - <repeatable>true</repeatable> - <binding> - <command>property-adjust</command> - <property>/sim/current-view/goal-heading-offset-deg</property> - <step type="double">-1.0</step> - </binding> - </high> - </axis> + <axis> + <desc>Rudder</desc> + <number> + <unix>2</unix> + <mac>2</mac> + <windows>3</windows> + </number> + <binding> + <command>property-scale</command> + <property>/controls/flight/rudder</property> + <offset type="double">0.0</offset> + <factor type="double">1.0</factor> + <power type="double">2.0</power> + </binding> + </axis> - <axis n="7"> - <desc>View Elevation</desc> - <low> - <repeatable>true</repeatable> - <binding> - <command>property-adjust</command> - <property>/sim/current-view/goal-pitch-offset-deg</property> - <step type="double">-1.0</step> - </binding> - </low> - <high> - <repeatable>true</repeatable> - <binding> - <command>property-adjust</command> - <property>/sim/current-view/goal-pitch-offset-deg</property> - <step type="double">1.0</step> - </binding> - </high> - </axis> + <axis> + <desc>Throttle</desc> + <number> + <unix>3</unix> + <mac>2</mac> + <windows>2</windows> + </number> + <binding> + <command>nasal</command> + <script>controls.throttleAxis()</script> + </binding> + </axis> - <button n="1"> - <desc>View Cycle</desc> - <repeatable>false</repeatable> - <binding> - <command>view-cycle</command> - <step type="double">1</step> - </binding> - </button> +<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Hat Switch ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> - <button n="0"> - <desc>Brakes</desc> - <binding> - <command>nasal</command> - <script>controls.applyBrakes(1)</script> - </binding> - <mod-up> - <binding> - <command>nasal</command> - <script>controls.applyBrakes(0)</script> - </binding> - </mod-up> - </button> + <axis> + <desc>View Direction; Mixture; Aileron Trim; Rudder Trim;</desc> + <number> + <unix>4</unix> + <mac>4</mac> + <windows>6</windows> + </number> + <low> + <repeatable>true</repeatable> + <binding> + <command>nasal</command> + <script> + m = get_mode(); + if (m == 0) { + v = getprop("/sim/current-view/view-number"); + view.panViewDir(v == 0 or v == 4 ? 1 : -1); + } elsif (m == 1) { + controls.adjMixture(-1); + harrier(); + } elsif (m == 2) { + controls.aileronTrim(-0.75); + } elsif (m == 3) { + controls.rudderTrim(-0.75); + } + </script> + </binding> + </low> + <high> + <repeatable>true</repeatable> + <binding> + <command>nasal</command> + <script> + m = get_mode(); + if (m == 0) { + v = getprop("/sim/current-view/view-number"); + view.panViewDir(v == 0 or v == 4 ? -1 : 1); + } elsif (m == 1) { + controls.adjMixture(1); + harrier(); + } elsif (m == 2) { + controls.aileronTrim(0.75); + } elsif (m == 3) { + controls.rudderTrim(0.75); + } + </script> + </binding> + </high> + </axis> - <button n="2"> - <desc>Left Brake</desc> - <binding> - <command>nasal</command> - <script>controls.applyBrakes(1, -1)</script> - </binding> - <mod-up> - <binding> - <command>nasal</command> - <script>controls.applyBrakes(0, -1)</script> - </binding> - </mod-up> - </button> + <axis> + <desc>View Elevation; Prop Pitch; Elevator Trim;</desc> + <number> + <unix>5</unix> + <mac>5</mac> + <windows>7</windows> + </number> + <low> + <repeatable>true</repeatable> + <binding> + <command>nasal</command> + <script> + m = get_mode(); + if (m == 0) { + view.panViewPitch(-1); + } elsif (m == 1) { + controls.adjPropeller(-1); + } elsif (m == 2) { + controls.elevatorTrim(-0.75); + } elsif (m == 3) { + # + } + </script> + </binding> + </low> + <high> + <repeatable>true</repeatable> + <binding> + <command>nasal</command> + <script> + m = get_mode(); + if (m == 0) { + view.panViewPitch(1); + } elsif (m == 1) { + controls.adjPropeller(1); + } elsif (m == 2) { + controls.elevatorTrim(0.75); + } elsif (m == 3) { + # + } + </script> + </binding> + </high> + </axis> - <button n="3"> - <desc>Right Brake</desc> - <binding> - <command>nasal</command> - <script>controls.applyBrakes(1, 1)</script> - </binding> - <mod-up> - <binding> - <command>nasal</command> - <script>controls.applyBrakes(0, 1)</script> - </binding> - </mod-up> - </button> +<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Buttons ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> - <button n="6"> - <desc>Flaps Up</desc> - <repeatable>false</repeatable> - <binding> - <command>property-adjust</command> - <property>/controls/flight/flaps</property> - <step type="double">-0.34</step> - </binding> - </button> + <button n="0"><!-- trigger --> + <desc>Brakes; Parking Brake; Speed Brake; Thrust Reverse;</desc> + <repeatable type="bool">false</repeatable> + <binding> + <command>nasal</command> + <script> + m = get_mode(); + if (m == 0) { + controls.applyBrakes(1); + } elsif (m == 1) { + controls.applyBrakes(1); + } elsif (m == 2) { + # + } elsif (m == 3) { + # + } + </script> + </binding> + <mod-up> + <binding> + <command>nasal</command> + <script> + m = get_mode(); + if (m == 0) { + controls.applyBrakes(0); + } elsif (m == 1) { + i = controls.applyParkingBrake(1); + gui.popupTip("Parking Brake " ~ ["OFF", "ON"][i]); + controls.applyBrakes(0); + } elsif (m == 2) { + i = !getprop("/controls/flight/speedbrake"); + setprop("/controls/flight/speedbrake", i); + gui.popupTip("Speed Brake " ~ ["OFF", "ON"][i]); + } elsif (m == 3) { + i = !getprop("/controls/engines/engine[0]/reverser"); + props.setAll("/controls/engines/engine", "reverser", i); + gui.popupTip("Thrust Reverser " ~ ["OFF", "ON"][i]); + } + </script> + </binding> + </mod-up> + </button> - <button n="5"> - <desc>Flaps Down</desc> - <repeatable>false</repeatable> - <binding> - <command>property-adjust</command> - <property>/controls/flight/flaps</property> - <step type="double">0.34</step> - </binding> - </button> + <button n="2"><!-- Labeled 3, Left Below Hat --> + <desc>Flaps Up; Gear Up; Previous View</desc> + <repeatable type="bool">false</repeatable> + <binding> + <command>nasal</command> + <script> + m = get_mode(); + if (m == 0) { + controls.flapsDown(-1); + } elsif (m == 1) { + controls.gearDown(-1); + } elsif (m == 2) { + view.stepView(-1); + } elsif (m == 3) { + # + } + </script> + </binding> + <mod-up> + <binding> + <command>nasal</command> + <script> + m = get_mode(); + if (m == 0) { + controls.flapsDown(0); + } elsif (m == 1) { + controls.gearDown(0); + } elsif (m == 2) { + # + } elsif (m == 3) { + # + } + </script> + </binding> + </mod-up> + </button> + + <button n="1"><!-- Labeled 2, Middle Below Hat--> + <desc>Reset View; Toggle Tail-wheel lock; Reset Trim;</desc> + <repeatable type="bool">false</repeatable> + <binding> + <command>nasal</command> + <script> + m = get_mode(); + if (m == 0) { + view.resetView(); + } elsif (m == 1) { + i = !getprop("/controls/gear/tailwheel-lock"); + setprop("/controls/gear/tailwheel-lock", i); + gui.popupTip("Tail Wheel " ~ ["UNLOCKED", "LOCKED"][i]); + } elsif (m == 2) { + setprop("/sim/current-view/view-number", 0); + view.resetView(); + } elsif (m == 3) { + setprop("/controls/flight/elevator-trim", 0); + setprop("/controls/flight/aileron-trim", 0); + setprop("/controls/flight/rudder-trim", 0); + } + </script> + </binding> + </button> + + <button n="3"><!-- Labeled 4, Right Below Hat --> + <desc>Flaps Down; Gear Down; Next View;</desc> + <repeatable type="bool">false</repeatable> + <binding> + <command>nasal</command> + <script> + m = get_mode(); + if (m == 0) { + controls.flapsDown(1); + } elsif (m == 1) { + controls.gearDown(1); + } elsif (m == 2) { + view.stepView(1); + } elsif (m == 3) { + # + } + </script> + </binding> + <mod-up> + <binding> + <command>nasal</command> + <script> + m = get_mode(); + if (m == 0) { + controls.flapsDown(0); + } elsif (m == 1) { + controls.gearDown(0); + } elsif (m == 2) { + # + } elsif (m == 3) { + # + } + </script> + </binding> + </mod-up> + </button> + + <button n="5"><!-- Labeled 6, Left key on Bottom Row on base --> + <desc>Brakes left</desc> + <repeatable type="bool">true</repeatable> + <binding> + <command>nasal</command> + <script> + f1 = 1; + m = get_mode(); + if (m == 0) { + if (!left_brake) { + controls.applyBrakes(left_brake = 1, -1); + } + } elsif (m == 1) { + # + } elsif (m == 2) { + f2 ? view.resetFOV() : view.increase(); + } elsif (m == 3) { + # + } + </script> + </binding> + <mod-up> + <binding> + <command>nasal</command> + <script> + f1 = 0; + m = get_mode(); + if (m == 0) { + controls.applyBrakes(left_brake = 0, -1); + } elsif (m == 1) { + # + } elsif (m == 2) { + # + } elsif (m == 3) { + # + } + </script> + </binding> + </mod-up> + </button> + + <button n="4"><!-- Labeled 5, Right key on Bottom Row on base --> + <desc>Brakes right</desc> + <repeatable type="bool">true</repeatable> + <binding> + <command>nasal</command> + <script> + f2 = 1; + m = get_mode(); + if (m == 0) { + if (!right_brake) { + controls.applyBrakes(right_brake = 1, 1); + } + } elsif (m == 1) { + # + } elsif (m == 2) { + f1 ? view.resetFOV() : view.decrease(); + } elsif (m == 3) { + # + } + </script> + </binding> + <mod-up> + <binding> + <command>nasal</command> + <script> + f2 = 0; + m = get_mode(); + if (m == 0) { + controls.applyBrakes(right_brake = 0, 1); + } elsif (m == 1) { + # + } elsif (m == 2) { + # + } elsif (m == 3) { + # + } + </script> + </binding> + </mod-up> + </button> + +<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Modifier Keys ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> + + <button n="6"><!-- K7 = Labeled 7, Left on Top Row on Base --> + <desc>Modifier Bit 0</desc> + <repeatable type="bool">false</repeatable> + <binding> + <command>nasal</command> + <script> + m = modifier.getValue(); + if (m == 0 or m == 2) { + modifier.setIntValue(m + 1); + } + </script> + </binding> + <mod-up> + <binding> + <command>nasal</command> + <script> + m = modifier.getValue(); + if (m == 1 or m == 3) { + modifier.setIntValue(m - 1); + } + </script> + </binding> + </mod-up> + </button> + + <button n="7"><!-- K8 = Labeled 8, Right on Top Row on Base --> + <desc>Modifier Bit 1</desc> + <repeatable type="bool">false</repeatable> + <binding> + <command>nasal</command> + <script> + m = modifier.getValue(); + if (m == 0 or m == 1) { + modifier.setIntValue(m + 2); + } + </script> + </binding> + <mod-up> + <binding> + <command>nasal</command> + <script> + m = modifier.getValue(); + if (m == 2 or m == 3) { + modifier.setIntValue(m - 2); + } + </script> + </binding> + </mod-up> + </button> </PropertyList> -<!-- end of joystick.xml -->