2015年4月15日 星期三

以GTAV操作手法於FlightGear飛Cessna 172P - XBOX360搖桿XML檔設定

GTAV PS4控制器按鍵對應

  • 左操作桿-左右: 副翼(Aileron),操作桿向右,飛機右滾轉
  • 左操作桿-上下: 升降舵(Elevator),操作桿向下、升降舵向下
  • L1: 方向舵(Rudder)左擺
  • R2: 方向舵右擺
  • L2: 熄火/減速
  • R2: 發動/加速
  • 右操作桿-左右: heading(or yaw) 視向(view direction),操作桿向右→往右看
  • 右操作桿-上下: pitch 視向,操作桿向下→往下看
  • 左操作桿-按下: 收/放 起落架
  • 右操作桿-按下: 按下-視向轉正後方;放開-視向轉回正前方
  • 觸控版: 改變視角
  • OPTIONS按鈕: 暫停

FlightGear控制器操作設定方法

FlightGear內的搖桿設定GUI功能有限,為達目標需編輯xml檔。

指定連結到特定xml檔

首先,編輯/FlightGear/data/joysticks.xml如下(參考網頁)
<PropertyList>
  <js n="0" include="Input/Joysticks/custom.xml"/>
</PropertyList>
如此,可強制第一支控制器js n="0"(基本上也只會插一個)以/FlightGear/data/Input/Joysticks/custom.xml對應操作按鍵。

編輯joystick xml檔

基本編輯方法建議參考此教學與/data/Docs/readme Command章節。以下僅就如何於各軸(axis)、按鈕(button)實現GTAV操作對應進行說明。

左操作桿-左右

<axis n="0">
  <binding>
property-scale command將property aileron之value設為axis值
    <command type="string">property-scale</command>
    <property type="string">/controls/flight/aileron</property>
  </binding>
</axis>

左操作桿-上下

<axis n="1">
  <binding>
    <command type="string">property-scale</command>
    <property type="string">/controls/flight/elevator</property>
因左操作桿向下為正,而elevator向上為正,故設factor為-1以反轉
    <factor type="double">-1</factor>
  </binding>
</axis>

L1-R1

XBOX 360搖桿之L1-R1不是類比,不能直接對應成L1-R1按多少→Rudder擺多少。
因此,設定成按下R1→Rudder持續向右擺,放開→回歸原點;按下L1→Rudder持續向左擺,方開→回歸原點。
L1
<button n="4">
  <binding>
property-interpolate command以設定之rate變動property rudder至value
    <command type="string">property-interpolate</command>
    <property type="string">/controls/flight/rudder</property>
Rudder左擺極值為-1
    <value type="double">-1</value>
設定rate,即每秒變動量
    <rate type="double">0.5</rate>
  </binding>
mod-up表放開按鈕
  <mod-up>
    <binding>
      <command type="string">property-interpolate</command>
      <property type="string">/controls/flight/rudder</property>
放開L1 Rudder回中心,而中心值為0
      <value type="double">0</value>
      <rate type="double">0.5</rate>
    </binding>
  </mod-up>
</button>
R1
<button n="5">
  <binding>
    <command type="string">property-interpolate</command>
    <property type="string">/controls/flight/rudder</property>
Rudder右擺極值為1
    <value type="double">1</value>
    <rate type="double">0.5</rate>
  </binding>
  <mod-up>
    <binding>
      <command type="string">property-interpolate</command>
      <property type="string">/controls/flight/rudder</property>
      <value type="double">0</value>
      <rate type="double">0.5</rate>
    </binding>
  </mod-up>
</button>

L2-R2

這個最複雜,因為R2同時要包含油門控制+引擎發動,L2要同時包含煞車+引擎熄火,使用nasal script處理
<axis n="2">
  <binding>
    <command type="string">nasal</command>
    <script type="string">
於script中取得axis值
      var axisValue = cmdarg().getNode("setting").getValue(); 

若引擎未啟動、且R2按到接近底(至底axis值為-1),將starter switch設為1,啟動引擎
      if(getprop("/engines/engine/running") != 1
    and -0.9 > axisValue){
  setprop("/controls/switches/starter", 1);

若magnetos未設為3,設為3
  if(getprop("/controls/engines/engine/magnetos") != 3){ <!-- magnetos setting -->
    setprop("/controls/engines/engine/magnetos", 3);
  }
      }
若引擎已啟動,將starter switch設回0
      else{
 setprop("/controls/switches/starter", 0); 
      }

      <!-- axisValue 0~-1, R2, throttle -->
若axis值小於0,即按R2(0~-1),設定油門(0~1)為axis反轉值
      if(0 >= axisValue){
  setprop("/controls/engines/engine/throttle", -axisValue);
      } 

      <!-- axisValue 0~1, L2, brake -->
若axis值大於0,即按L2(0~1),設定左右煞車(0~1)為axis值
      if(axisValue >= 0){ # L2 is positive (0 ~ 1)
 setprop("/controls/gear/brake-left", axisValue);
 setprop("/controls/gear/brake-right", axisValue);
      } 

若axis值大於0.8,即L2按接近底,將magnetos設為0,引擎熄火
      if(axisValue > 0.8 and getprop("/controls/engines/engine/magnetos") != 0){
 setprop("/controls/engines/engine/magnetos", 0)
      }
    </script>
  </binding>
</axis>

右操作桿-左右

<axis n="4">
axis值約小於-0.9,即右操作桿左擺至接近極限時為low。
  <low> <!-- left --> <!-- axis value < -0.9 -->
動作需重複,即右操作桿左擺時持續減小pitch數值
    <repeatable type="string">true</repeatable>
    <binding>
property-adjust command用以將property數值加上step值
      <command type="string">property-adjust</command>
      <property type="string">/sim/current-view/goal-heading-offset-deg</property>
      <step type="double">-1</step>
    </binding>
  </low>
axis值約大於0.9,即右操作桿右擺至接近極限時為high。
  <high> <!-- right --> <!-- axis value > 0.9 -->
    <repeatable type="string">true</repeatable>
    <binding>
      <command type="string">property-adjust</command>
      <property type="string">/sim/current-view/goal-heading-offset-deg</property>
      <step type="double">1</step>
    </binding>
  </high>
</axis>

右操作桿-上下

<axis n="3">
axis上擺至接近極限為low
  <low>
    <repeatable type="string">true</repeatable>
    <binding>
      <command type="string">property-adjust</command>
      <property type="string">/sim/current-view/goal-pitch-offset-deg</property>
      <step type="double">-1</step>
    </binding>
  </low>
axis上擺至接近極限為high
  <high>
    <repeatable type="string">true</repeatable>
    <binding>
      <command type="string">property-adjust</command>
      <property type="string">/sim/current-view/goal-pitch-offset-deg</property>
      <step type="double">1</step>
    </binding>
  </high>
</axis>

左操作桿-按下

Cessna 172起落架不能收,跳過

右操作桿-按下

按下看正後方,放開跳回正前方。
<button n="9">
設heading為180度 (正後方)
  <binding>
    <command type="string">property-assign</command>
    <property type="string">/sim/current-view/goal-heading-offset-deg</property>
    <value type="double">180</value>
  </binding>
設pitch為0度
  <binding>
    <command type="string">property-assign</command>
    <property type="string">/sim/current-view/goal-pitch-offset-deg</property>
    <value type="double">0</value>
  </binding>
放開
    <mod-up>
設heading為0度 (正前方)
      <binding>
 <command type="string">property-assign</command>
 <property type="string">/sim/current-view/goal-heading-offset-deg</property>
 <value type="double">0</value>
      </binding>
設pitch為0度
      <binding>
 <command type="string">property-assign</command>
 <property type="string">/sim/current-view/goal-pitch-offset-deg</property>
 <value type="double">0</value>
      </binding>
    </mod-up>
</button>

觸控板

用BACK按鈕代替,利用property-cycle command使property於設定之value循環
<button n="6">
  <binding>
    <command type="string">property-cycle</command>
    <property type="string">/sim/current-view/view-number</property>
cockpit view
    <value>0</value>
model view
    <value>7</value>
chase without yaw view
    <value>5</value>
  </binding>
</button>

OPTIONS按鈕

用START按扭代替,直接pause command就好,easy。
<button n="7"> # START button
  <desc type="string">pause</desc>
  <repeatable type="string">false</repeatable>
  <binding>
    <command type="string">pause</command>
  </binding>
</button>

dead-band

前面說明省略dead-band部分。FlightGear之dead-band 結果以下程式碼說明 (可看joystick文件?)
README.Joystick.html,User Guid to FGInput - Joystick And Keyboard Binding For FlightGear
實際dead-band效果如下函式 (1 >= input >= -1, 1 > deadBand > 0 )

double doDeadBand(double input, double deadBand)
{
  if(input >= deadBand){
    return (input - deadBand) / (1 - deadBand);
  }

  if(input > -deadBand){
    return 0.0;
  }

  return -(abs(input) - deadBand) / (1 - deadBand);
}

完整檔案

<?xml version="1.0"?>

<!-- 
  add 

  <PropertyList>
    <js n="0" include="Input/Joysticks/GTA V like joystick setting for XBOX 360 Controller.xml"/>
  </PropertyList> 

  in FlightGear/data/joysticks.xml

  put this file in FlightGear/data/Input/Joysticks
-->

<PropertyList>
  <name type="string">GTA V like joystick setting for XBOX 360 Controller</name>

  <axis n="0">
    <name type="string">left stick left-right (right positive)</name>
    <desc type="string">adjust aileron</desc>
    <dead-band type="double">0.2</dead-band> <!-- dead-band tag must precede binding tag -->
    <!-- if (input < abs(dead-band)) output = 0 -->
    <!-- if (input > dead-band) output = (output - dead-band) / (1 - dead-band) -->
    <binding>
      <command type="string">property-scale</command>
      <property type="string">/controls/flight/aileron</property>
    </binding>
  </axis>

  <axis n="1">
    <name type="string">left stick up-down (down positive)</name>
    <desc type="string">adjust elevator</desc> 
    <dead-band type="double">0.2</dead-band>
    <binding>
      <command type="string">property-scale</command>
      <property type="string">/controls/flight/elevator</property>
      <factor type="double">-1</factor> <!-- down positive, thus inverse -->
    </binding>
  </axis>

  <axis n="2">
    <name type="string">R2-L2 (L2 positive)</name>
    <desc type="string">start stop engine, adjust throttle, brake</desc>
    <dead-band type="double">0.1</dead-band>
    <binding>
      <command type="string">nasal</command>
      <script type="string">
        var axisValue = cmdarg().getNode("setting").getValue(); 
        <!-- the value of /input/joysticks/js/axis[2]/binding/setting -->

        <!-- engine start stop control -->
        if(getprop("/engines/engine/running") != 1 <!-- engine not running -->
             and -0.9 > axisValue){ <!-- R2 pushed near end -->
           setprop("/controls/switches/starter", 1);

           if(getprop("/controls/engines/engine/magnetos") != 3){ <!-- magnetos setting -->
             setprop("/controls/engines/engine/magnetos", 3);
           }
        }
        else{ <!-- engine running -->
          setprop("/controls/switches/starter", 0); 
        }

        <!-- axisValue 0~-1, R2, throttle -->
        if(0 >= axisValue){
           setprop("/controls/engines/engine/throttle", -axisValue);
        } 

        <!-- axisValue 0~1, L2, brake -->
        if(axisValue >= 0){ # L2 is positive (0 ~ 1)
          setprop("/controls/gear/brake-left", axisValue);
          setprop("/controls/gear/brake-right", axisValue);
        } 

        <!-- close engine -->
        if(axisValue > 0.8 and getprop("/controls/engines/engine/magnetos") != 0){
          setprop("/controls/engines/engine/magnetos", 0)
        }
      </script>
    </binding>
  </axis>

  <axis n="3">
    <name type="string">right stick up-down (down positive)</name>
    <desc type="string">adjust view direction pitch</desc>
    <low> <!-- up --> <!-- axis value < -0.9 -->
      <repeatable type="string">true</repeatable>
      <binding>
        <command type="string">property-adjust</command>
        <property type="string">/sim/current-view/goal-pitch-offset-deg</property>
        <step type="double">-1</step>
      </binding>
    </low>
    <high> <!-- down --> <!-- axis value > 0.9 -->
      <repeatable type="string">true</repeatable>
      <binding>
<!-- add 

  <PropertyList>
    <js n="0" include="Input/Joysticks/GTA V like joystick setting for XBOX 360 Controller.xml"/>
  </PropertyList> 

  in FlightGear/data/joysticks.xml

  put this file in FlightGear/data/Input/Joysticks
-->

<?xml version="1.0"?>

<PropertyList>
  <name type="string">GTA V like joystick setting for XBOX 360 Controller</name>

  <axis n="0">
    <name type="string">left stick left-right (right positive)</name>
    <desc type="string">adjust aileron</desc>
    <dead-band type="double">0.2</dead-band> <!-- dead-band tag must precede binding tag -->
    <!-- if (input < abs(dead-band)) output = 0 -->
    <!-- if (input > dead-band) output = (output - dead-band) / (1 - dead-band) -->
    <binding>
      <command type="string">property-scale</command>
      <property type="string">/controls/flight/aileron</property>
    </binding>
  </axis>

  <axis n="1">
    <name type="string">left stick up-down (down positive)</name>
    <desc type="string">adjust elevator</desc> 
    <dead-band type="double">0.2</dead-band>
    <binding>
      <command type="string">property-scale</command>
      <property type="string">/controls/flight/elevator</property>
      <factor type="double">-1</factor> <!-- down positive, thus inverse -->
    </binding>
  </axis>

  <axis n="2">
    <name type="string">R2-L2 (L2 positive)</name>
    <desc type="string">start stop engine, adjust throttle, brake</desc>
    <dead-band type="double">0.1</dead-band>
    <binding>
<!-- add 

  <PropertyList>
    <js n="0" include="Input/Joysticks/GTA V like joystick setting for XBOX 360 Controller.xml"/>
  </PropertyList> 

  in FlightGear/data/joysticks.xml

  put this file in FlightGear/data/Input/Joysticks
-->

<?xml version="1.0"?>

<PropertyList>
  <name type="string">GTA V like joystick setting for XBOX 360 Controller</name>

  <axis n="0">
    <name type="string">left stick left-right (right positive)</name>
    <desc type="string">adjust aileron</desc>
    <dead-band type="double">0.2</dead-band> <!-- dead-band tag must precede binding tag -->
    <!-- if (input < abs(dead-band)) output = 0 -->
    <!-- if (input > dead-band) output = (output - dead-band) / (1 - dead-band) -->
    <binding>
      <command type="string">property-scale</command>
      <property type="string">/controls/flight/aileron</property>
    </binding>
  </axis>

  <axis n="1">
    <name type="string">left stick up-down (down positive)</name>
    <desc type="string">adjust elevator</desc> 
    <dead-band type="double">0.2</dead-band>
    <binding>
      <command type="string">property-scale</command>
      <property type="string">/controls/flight/elevator</property>
      <factor type="double">-1</factor> <!-- down positive, thus inverse -->
    </binding>
  </axis>

  <axis n="2">
    <name type="string">R2-L2 (L2 positive)</name>
    <desc type="string">start stop engine, adjust throttle, brake</desc>
    <dead-band type="double">0.1</dead-band>
    <binding>
      <command type="string">nasal</command>
      <script type="string">
        var axisValue = cmdarg().getNode("setting").getValue(); 
        <!-- the value of /input/joysticks/js/axis[2]/binding/setting -->

        <!-- engine start stop control -->
        if(getprop("/engines/engine/running") != 1 <!-- engine not running -->
             and -0.9 > axisValue){ <!-- R2 pushed near end -->
           setprop("/controls/switches/starter", 1);

           if(getprop("/controls/engines/engine/magnetos") != 3){ <!-- magnetos setting -->
             setprop("/controls/engines/engine/magnetos", 3);
           }
        }
        else{ <!-- engine running -->
          setprop("/controls/switches/starter", 0); 
        }

        <!-- axisValue 0~-1, R2, throttle -->
        if(0 >= axisValue){
           setprop("/controls/engines/engine/throttle", -axisValue);
        } 

        <!-- axisValue 0~1, L2, brake -->
        if(axisValue >= 0){ # L2 is positive (0 ~ 1)
          setprop("/controls/gear/brake-left", axisValue);
          setprop("/controls/gear/brake-right", axisValue);
        } 

        <!-- close engine -->
        if(axisValue > 0.8 and getprop("/controls/engines/engine/magnetos") != 0){
          setprop("/controls/engines/engine/magnetos", 0)
        }
      </script>
    </binding>
  </axis>

  <axis n="3">
    <name type="string">right stick up-down (down positive)</name>
    <desc type="string">adjust view direction pitch</desc>
    <low> <!-- up --> <!-- axis value < -0.9 -->
      <repeatable type="string">true</repeatable>
      <binding>
        <command type="string">property-adjust</command>
        <property type="string">/sim/current-view/goal-pitch-offset-deg</property>
        <step type="double">-1</step>
      </binding>
    </low>
    <high> <!-- down --> <!-- axis value > 0.9 -->
      <repeatable type="string">true</repeatable>
      <binding>
        <command type="string">property-adjust</command>
        <property type="string">/sim/current-view/goal-pitch-offset-deg</property>
        <step type="double">1</step>
      </binding>
    </high>
  </axis>

  <axis n="4">
    <name type="string">right stick left-right (right positive)</name>
    <desc type="string">adjust view direction heading (yaw)</desc>
    <low> <!-- left --> <!-- axis value < -0.9 -->
      <repeatable type="string">true</repeatable>
      <binding>
        <command type="string">property-adjust</command>
        <property type="string">/sim/current-view/goal-heading-offset-deg</property>
        <step type="double">-1</step>
      </binding>
    </low>
    <high> <!-- right --> <!-- axis value > 0.9 -->
      <repeatable type="string">true</repeatable>
      <binding>
        <command type="string">property-adjust</command>
        <property type="string">/sim/current-view/goal-heading-offset-deg</property>
        <step type="double">1</step>
      </binding>
    </high>
  </axis>

  <button n="0">
    <name type="string">A button</name>
    <desc type="string">decrease elevator trim </desc>
    <repeatable type="string">true</repeatable>
    <binding>
      <command type="string">nasal</command>
      <script type="string">
        controls.elevatorTrim(-1);
        gui.popupTip("elevator trim: " ~ getprop("/controls/flight/elevator-trim"), 1)
      </script>
    </binding>
  </button>

  <button n="1">
    <name type="string">B button</name>
    <desc type="string">increase aileron trim </desc>
    <repeatable type="string">true</repeatable>
    <binding>
      <command type="string">nasal</command>
      <script type="string">
        controls.aileronTrim(1);
        gui.popupTip("aileron trim: " ~ getprop("/controls/flight/aileron-trim"), 1)
      </script>
    </binding>
  </button>

  <button n="2">
    <name type="string">X button</name>
    <desc type="string">decrease aileron trim </desc>
    <repeatable type="string">true</repeatable>
    <binding>
      <command type="string">nasal</command>
      <script type="string">
        controls.aileronTrim(-1);
        gui.popupTip("aileron trim: " ~ getprop("/controls/flight/aileron-trim"), 1)  
      </script>
    </binding>
  </button>

  <button n="3">
    <name type="string">Y button</name>
    <desc type="string">increase elevator trim </desc>
    <repeatable type="string">true</repeatable>
    <binding>
      <command type="string">nasal</command>
      <script type="string">
        controls.elevatorTrim(1);
        gui.popupTip("elevator trim: " ~ getprop("/controls/flight/elevator-trim"), 1)
      </script>
    </binding>
  </button> 
  
  <button n="4">
    <name type="string">L1 button</name>
    <desc type="string">Rudder Right (Turn Left)</desc>
    <binding>
      <command type="string">property-interpolate</command>
      <property type="string">/controls/flight/rudder</property>
      <value type="double">-1</value>
      <rate type="double">0.5</rate>
    </binding>
    <mod-up> <!-- release L1 button --> 
      <binding>
        <command type="string">property-interpolate</command>
        <property type="string">/controls/flight/rudder</property>
        <value type="double">0</value>
        <rate type="double">0.5</rate>
      </binding>
    </mod-up>
  </button>

  <button n="5">
    <name type="string">R2 button</name>
    <desc type="string">Rudder Left (Turn Right)</desc>
    <binding>
      <command type="string">property-interpolate</command>
      <property type="string">/controls/flight/rudder</property>
      <value type="double">1</value>
      <rate type="double">0.5</rate>
    </binding>
    <mod-up> <!-- release R2 button -->
      <binding>
        <command type="string">property-interpolate</command>
        <property type="string">/controls/flight/rudder</property>
        <value type="double">0</value>
        <rate type="double">0.5</rate>
      </binding>
    </mod-up>
  </button>

  <button n="6">
    <name type="string">BACK button</name>
    <desc type="string">change view</desc>
    <binding>
      <command type="string">property-cycle</command>
      <property type="string">/sim/current-view/view-number</property>
      <value>0</value> <!-- cockpit view -->
      <value>7</value> <!-- model view -->
      <value>5</value> <!-- chase without yaw view -->
    </binding>
  </button>

  <button n="7">
    <name type="string">START button</name>
    <desc type="string">pause</desc>
    <binding>
      <command type="string">pause</command>
    </binding>
  </button>

  <button n="9">
    <name type="string">right stick button</name>
    <desc type = "string">look back, look forward when released</desc>
    <binding>
      <command type="string">nasal</command>
      <script type="string">
        setprop("/sim/current-view/goal-heading-offset-deg", 180);
        setprop("/sim/current-view/goal-pitch-offset-deg", 0);
      </script>
    </binding>
    <mod-up>
      <binding>
        <command type="string">nasal</command>
        <script type="string">
          setprop("/sim/current-view/goal-heading-offset-deg", 0);
          setprop("/sim/current-view/goal-pitch-offset-deg", 0);
        </script>
      </binding>
    </mod-up>
  </button>
</PropertyList>
      <command type="string">nasal</command>
      <script type="string">
        var axisValue = cmdarg().getNode("setting").getValue(); 
        <!-- the value of /input/joysticks/js/axis[2]/binding/setting -->

        <!-- engine start stop control -->
        if(getprop("/engines/engine/running") != 1 <!-- engine not running -->
             and -0.9 > axisValue){ <!-- R2 pushed near end -->
           setprop("/controls/switches/starter", 1);

           if(getprop("/controls/engines/engine/magnetos") != 3){ <!-- magnetos setting -->
             setprop("/controls/engines/engine/magnetos", 3);
           }
        }
        else{ <!-- engine running -->
          setprop("/controls/switches/starter", 0); 
        }

        <!-- axisValue 0~-1, R2, throttle -->
        if(0 >= axisValue){
           setprop("/controls/engines/engine/throttle", -axisValue);
        } 

        <!-- axisValue 0~1, L2, brake -->
        if(axisValue >= 0){ # L2 is positive (0 ~ 1)
          setprop("/controls/gear/brake-left", axisValue);
          setprop("/controls/gear/brake-right", axisValue);
        } 

        <!-- close engine -->
        if(axisValue > 0.8 and getprop("/controls/engines/engine/magnetos") != 0){
          setprop("/controls/engines/engine/magnetos", 0)
        }
      </script>
    </binding>
  </axis>

  <axis n="3">
    <name type="string">right stick up-down (down positive)</name>
    <desc type="string">adjust view direction pitch</desc>
    <low> <!-- up --> <!-- axis value < -0.9 -->
      <repeatable type="string">true</repeatable>
      <binding>
        <command type="string">property-adjust</command>
        <property type="string">/sim/current-view/goal-pitch-offset-deg</property>
        <step type="double">-1</step>
      </binding>
    </low>
    <high> <!-- down --> <!-- axis value > 0.9 -->
      <repeatable type="string">true</repeatable>
      <binding>
        <command type="string">property-adjust</command>
        <property type="string">/sim/current-view/goal-pitch-offset-deg</property>
        <step type="double">1</step>
      </binding>
    </high>
  </axis>

  <axis n="4">
    <name type="string">right stick left-right (right positive)</name>
    <desc type="string">adjust view direction heading (yaw)</desc>
    <low> <!-- left --> <!-- axis value < -0.9 -->
      <repeatable type="string">true</repeatable>
      <binding>
        <command type="string">property-adjust</command>
        <property type="string">/sim/current-view/goal-heading-offset-deg</property>
        <step type="double">-1</step>
      </binding>
    </low>
    <high> <!-- right --> <!-- axis value > 0.9 -->
      <repeatable type="string">true</repeatable>
      <binding>
        <command type="string">property-adjust</command>
        <property type="string">/sim/current-view/goal-heading-offset-deg</property>
        <step type="double">1</step>
      </binding>
    </high>
  </axis>
<!-- add 

  <PropertyList>
    <js n="0" include="Input/Joysticks/GTA V like joystick setting for XBOX 360 Controller.xml"/>
  </PropertyList> 

  in FlightGear/data/joysticks.xml

  put this file in FlightGear/data/Input/Joysticks
-->

<?xml version="1.0"?>

<PropertyList>
  <name type="string">GTA V like joystick setting for XBOX 360 Controller</name>

  <axis n="0">
    <name type="string">left stick left-right (right positive)</name>
    <desc type="string">adjust aileron</desc>
    <dead-band type="double">0.2</dead-band> <!-- dead-band tag must precede binding tag -->
    <!-- if (input < abs(dead-band)) output = 0 -->
    <!-- if (input > dead-band) output = (output - dead-band) / (1 - dead-band) -->
    <binding>
      <command type="string">property-scale</command>
      <property type="string">/controls/flight/aileron</property>
    </binding>
  </axis>

  <axis n="1">
    <name type="string">left stick up-down (down positive)</name>
    <desc type="string">adjust elevator</desc> 
    <dead-band type="double">0.2</dead-band>
    <binding>
      <command type="string">property-scale</command>
      <property type="string">/controls/flight/elevator</property>
      <factor type="double">-1</factor> <!-- down positive, thus inverse -->
    </binding>
  </axis>

  <axis n="2">
    <name type="string">R2-L2 (L2 positive)</name>
    <desc type="string">start stop engine, adjust throttle, brake</desc>
    <dead-band type="double">0.1</dead-band>
    <binding>
      <command type="string">nasal</command>
      <script type="string">
        var axisValue = cmdarg().getNode("setting").getValue(); 
        <!-- the value of /input/joysticks/js/axis[2]/binding/setting -->

        <!-- engine start stop control -->
        if(getprop("/engines/engine/running") != 1 <!-- engine not running -->
             and -0.9 > axisValue){ <!-- R2 pushed near end -->
           setprop("/controls/switches/starter", 1);

           if(getprop("/controls/engines/engine/magnetos") != 3){ <!-- magnetos setting -->
             setprop("/controls/engines/engine/magnetos", 3);
           }
        }
        else{ <!-- engine running -->
          setprop("/controls/switches/starter", 0); 
        }

        <!-- axisValue 0~-1, R2, throttle -->
        if(0 >= axisValue){
           setprop("/controls/engines/engine/throttle", -axisValue);
        } 

        <!-- axisValue 0~1, L2, brake -->
        if(axisValue >= 0){ # L2 is positive (0 ~ 1)
          setprop("/controls/gear/brake-left", axisValue);
          setprop("/controls/gear/brake-right", axisValue);
        } 

        <!-- close engine -->
        if(axisValue > 0.8 and getprop("/controls/engines/engine/magnetos") != 0){
          setprop("/controls/engines/engine/magnetos", 0)
        }
      </script>
    </binding>
  </axis>

  <axis n="3">
    <name type="string">right stick up-down (down positive)</name>
    <desc type="string">adjust view direction pitch</desc>
    <low> <!-- up --> <!-- axis value < -0.9 -->
      <repeatable type="string">true</repeatable>
      <binding>
        <command type="string">property-adjust</command>
        <property type="string">/sim/current-view/goal-pitch-offset-deg</property>
        <step type="double">-1</step>
      </binding>
    </low>
    <high> <!-- down --> <!-- axis value > 0.9 -->
      <repeatable type="string">true</repeatable>
      <binding>
        <command type="string">property-adjust</command>
        <property type="string">/sim/current-view/goal-pitch-offset-deg</property>
        <step type="double">1</step>
      </binding>
    </high>
  </axis>

  <axis n="4">
    <name type="string">right stick left-right (right positive)</name>
    <desc type="string">adjust view direction heading (yaw)</desc>
    <low> <!-- left --> <!-- axis value < -0.9 -->
      <repeatable type="string">true</repeatable>
      <binding>
        <command type="string">property-adjust</command>
        <property type="string">/sim/current-view/goal-heading-offset-deg</property>
        <step type="double">-1</step>
      </binding>
    </low>
    <high> <!-- right --> <!-- axis value > 0.9 -->
      <repeatable type="string">true</repeatable>
      <binding>
        <command type="string">property-adjust</command>
        <property type="string">/sim/current-view/goal-heading-offset-deg</property>
        <step type="double">1</step>
      </binding>
    </high>
  </axis>

  <button n="0">
    <name type="string">A button</name>
    <desc type="string">decrease elevator trim </desc>
    <repeatable type="string">true</repeatable>
    <binding>
      <command type="string">nasal</command>
      <script type="string">
        controls.elevatorTrim(-1);
        gui.popupTip("elevator trim: " ~ getprop("/controls/flight/elevator-trim"), 1)
      </script>
    </binding>
  </button>

  <button n="1">
    <name type="string">B button</name>
    <desc type="string">increase aileron trim </desc>
    <repeatable type="string">true</repeatable>
    <binding>
      <command type="string">nasal</command>
      <script type="string">
        controls.aileronTrim(1);
        gui.popupTip("aileron trim: " ~ getprop("/controls/flight/aileron-trim"), 1)
      </script>
    </binding>
  </button>

  <button n="2">
    <name type="string">X button</name>
    <desc type="string">decrease aileron trim </desc>
    <repeatable type="string">true</repeatable>
    <binding>
      <command type="string">nasal</command>
      <script type="string">
        controls.aileronTrim(-1);
        gui.popupTip("aileron trim: " ~ getprop("/controls/flight/aileron-trim"), 1)  
      </script>
    </binding>
  </button>

  <button n="3">
    <name type="string">Y button</name>
    <desc type="string">increase elevator trim </desc>
    <repeatable type="string">true</repeatable>
    <binding>
      <command type="string">nasal</command>
      <script type="string">
        controls.elevatorTrim(1);
        gui.popupTip("elevator trim: " ~ getprop("/controls/flight/elevator-trim"), 1)
      </script>
    </binding>
  </button> 
  
  <button n="4">
    <name type="string">L1 button</name>
    <desc type="string">Rudder Right (Turn Left)</desc>
    <binding>
      <command type="string">property-interpolate</command>
      <property type="string">/controls/flight/rudder</property>
      <value type="double">-1</value>
      <rate type="double">0.5</rate>
    </binding>
    <mod-up> <!-- release L1 button --> 
      <binding>
        <command type="string">property-interpolate</command>
        <property type="string">/controls/flight/rudder</property>
        <value type="double">0</value>
        <rate type="double">0.5</rate>
      </binding>
    </mod-up>
  </button>

  <button n="5">
    <name type="string">R2 button</name>
    <desc type="string">Rudder Left (Turn Right)</desc>
    <binding>
      <command type="string">property-interpolate</command>
      <property type="string">/controls/flight/rudder</property>
      <value type="double">1</value>
      <rate type="double">0.5</rate>
    </binding>
    <mod-up> <!-- release R2 button -->
      <binding>
        <command type="string">property-interpolate</command>
        <property type="string">/controls/flight/rudder</property>
        <value type="double">0</value>
        <rate type="double">0.5</rate>
      </binding>
    </mod-up>
  </button>

  <button n="6">
    <name type="string">BACK button</name>
    <desc type="string">change view</desc>
    <binding>
      <command type="string">property-cycle</command>
      <property type="string">/sim/current-view/view-number</property>
      <value>0</value> <!-- cockpit view -->
      <value>7</value> <!-- model view -->
      <value>5</value> <!-- chase without yaw view -->
    </binding>
  </button>

  <button n="7">
    <name type="string">START button</name>
    <desc type="string">pause</desc>
    <binding>
      <command type="string">pause</command>
    </binding>
  </button>

  <button n="9">
    <name type="string">right stick button</name>
    <desc type = "string">look back, look forward when released</desc>
    <binding>
      <command type="string">nasal</command>
      <script type="string">
        setprop("/sim/current-view/goal-heading-offset-deg", 180);
        setprop("/sim/current-view/goal-pitch-offset-deg", 0);
      </script>
    </binding>
    <mod-up>
      <binding>
        <command type="string">nasal</command>
        <script type="string">
          setprop("/sim/current-view/goal-heading-offset-deg", 0);
          setprop("/sim/current-view/goal-pitch-offset-deg", 0);
        </script>
      </binding>
    </mod-up>
  </button>
</PropertyList>

  <button n="0">
    <name type="string">A button</name>
    <desc type="string">decrease elevator trim </desc>
    <repeatable type="string">true</repeatable>
    <binding>
      <command type="string">nasal</command>
      <script type="string">
        controls.elevatorTrim(-1);
        gui.popupTip("elevator trim: " ~ getprop("/controls/flight/elevator-trim"), 1)
      </script>
    </binding>
  </button>

  <button n="1">
    <name type="string">B button</name>
    <desc type="string">increase aileron trim </desc>
    <repeatable type="string">true</repeatable>
    <binding>
      <command type="string">nasal</command>
      <script type="string">
        controls.aileronTrim(1);
        gui.popupTip("aileron trim: " ~ getprop("/controls/flight/aileron-trim"), 1)
      </script>
    </binding>
  </button>

  <button n="2">
    <name type="string">X button</name>
    <desc type="string">decrease aileron trim </desc>
    <repeatable type="string">true</repeatable>
    <binding>
      <command type="string">nasal</command>
      <script type="string">
        controls.aileronTrim(-1);
        gui.popupTip("aileron trim: " ~ getprop("/controls/flight/aileron-trim"), 1)  
      </script>
    </binding>
  </button>

  <button n="3">
    <name type="string">Y button</name>
    <desc type="string">increase elevator trim </desc>
    <repeatable type="string">true</repeatable>
    <binding>
      <command type="string">nasal</command>
      <script type="string">
        controls.elevatorTrim(1);
        gui.popupTip("elevator trim: " ~ getprop("/controls/flight/elevator-trim"), 1)
      </script>
    </binding>
  </button> 
  
  <button n="4">
    <name type="string">L1 button</name>
    <desc type="string">Rudder Right (Turn Left)</desc>
    <binding>
      <command type="string">property-interpolate</command>
      <property type="string">/controls/flight/rudder</property>
      <value type="double">-1</value>
      <rate type="double">0.5</rate>
    </binding>
    <mod-up> <!-- release L1 button --> 
      <binding>
        <command type="string">property-interpolate</command>
        <property type="string">/controls/flight/rudder</property>
        <value type="double">0</value>
        <rate type="double">0.5</rate>
      </binding>
    </mod-up>
  </button>

  <button n="5">
    <name type="string">R2 button</name>
    <desc type="string">Rudder Left (Turn Right)</desc>
    <binding>
      <command type="string">property-interpolate</command>
      <property type="string">/controls/flight/rudder</property>
      <value type="double">1</value>
      <rate type="double">0.5</rate>
    </binding>
    <mod-up> <!-- release R2 button -->
      <binding>
        <command type="string">property-interpolate</command>
        <property type="string">/controls/flight/rudder</property>
        <value type="double">0</value>
        <rate type="double">0.5</rate>
      </binding>
    </mod-up>
  </button>

  <button n="6">
    <name type="string">BACK button</name>
    <desc type="string">change view</desc>
    <binding>
      <command type="string">property-cycle</command>
      <property type="string">/sim/current-view/view-number</property>
      <value>0</value> <!-- cockpit view -->
      <value>7</value> <!-- model view -->
      <value>5</value> <!-- chase without yaw view -->
    </binding>
  </button>

  <button n="7">
    <name type="string">START button</name>
    <desc type="string">pause</desc>
    <binding>
      <command type="string">pause</command>
    </binding>
  </button>

  <button n="9">
    <name type="string">right stick button</name>
    <desc type = "string">look back, look forward when released</desc>
    <binding>
      <command type="string">nasal</command>
      <script type="string">
        setprop("/sim/current-view/goal-heading-offset-deg", 180);
        setprop("/sim/current-view/goal-pitch-offset-deg", 0);
      </script>
    </binding>
    <mod-up>
      <binding>
        <command type="string">nasal</command>
        <script type="string">
          setprop("/sim/current-view/goal-heading-offset-deg", 0);
          setprop("/sim/current-view/goal-pitch-offset-deg", 0);
        </script>
      </binding>
    </mod-up>
  </button>
</PropertyList>
        <command type="string">property-adjust</command>
        <property type="string">/sim/current-view/goal-pitch-offset-deg</property>
        <step type="double">1</step>
      </binding>
    </high>
  </axis>

  <axis n="4">
    <name type="string">right stick left-right (right positive)</name>
    <desc type="string">adjust view direction heading (yaw)</desc>
    <low> <!-- left --> <!-- axis value < -0.9 -->
      <repeatable type="string">true</repeatable>
      <binding>
        <command type="string">property-adjust</command>
        <property type="string">/sim/current-view/goal-heading-offset-deg</property>
        <step type="double">-1</step>
      </binding>
    </low>
    <high> <!-- right --> <!-- axis value > 0.9 -->
      <repeatable type="string">true</repeatable>
      <binding>
        <command type="string">property-adjust</command>
        <property type="string">/sim/current-view/goal-heading-offset-deg</property>
        <step type="double">1</step>
      </binding>
    </high>
  </axis>

  <button n="4">
    <name type="string">L1 button</name>
    <desc type="string">Rudder Right (Turn Left)</desc>
    <binding>
      <command type="string">property-interpolate</command>
      <property type="string">/controls/flight/rudder</property>
      <value type="double">-1</value>
      <rate type="double">0.5</rate>
    </binding>
    <mod-up> <!-- release L1 button --> 
      <binding>
        <command type="string">property-interpolate</command>
        <property type="string">/controls/flight/rudder</property>
        <value type="double">0</value>
        <rate type="double">0.5</rate>
      </binding>
    </mod-up>
  </button>

  <button n="5">
    <name type="string">R2 button</name>
    <desc type="string">Rudder Left (Turn Right)</desc>
    <binding>
      <command type="string">property-interpolate</command>
      <property type="string">/controls/flight/rudder</property>
      <value type="double">1</value>
      <rate type="double">0.5</rate>
    </binding>
    <mod-up> <!-- release R2 button -->
      <binding>
        <command type="string">property-interpolate</command>
        <property type="string">/controls/flight/rudder</property>
        <value type="double">0</value>
        <rate type="double">0.5</rate>
      </binding>
    </mod-up>
  </button>

  <button n="6">
    <name type="string">BACK button</name>
    <desc type="string">change view</desc>
    <binding>
      <command type="string">property-cycle</command>
      <property type="string">/sim/current-view/view-number</property>
      <value>0</value> <!-- cockpit view -->
      <value>7</value> <!-- model view -->
      <value>5</value> <!-- chase without yaw view -->
    </binding>
  </button>

  <button n="7">
    <name type="string">START button</name>
    <desc type="string">pause</desc>
    <binding>
      <command type="string">pause</command>
    </binding>
  </button>

  <button n="9">
    <name type="string">right stick button</name>
    <desc type = "string">look back, look forward when released</desc>
    <binding>
      <command type="string">property-assign</command>
      <property type="string">/sim/current-view/goal-heading-offset-deg</property>
      <value type="double">180</value>
    </binding>
    <binding>
      <command type="string">property-assign</command>
      <property type="string">/sim/current-view/goal-pitch-offset-deg</property>
      <value type="double">0</value>
    </binding>
    <mod-up>
      <binding>
 <command type="string">property-assign</command>
 <property type="string">/sim/current-view/goal-heading-offset-deg</property>
 <value type="double">0</value>
      </binding>
      <binding>
 <command type="string">property-assign</command>
 <property type="string">/sim/current-view/goal-pitch-offset-deg</property>
 <value type="double">0</value>
      </binding>
    </mod-up>
  </button>
</PropertyList>

沒有留言:

張貼留言