motion control for external gamepad

This commit is contained in:
True Zhuanjia
2026-04-27 16:23:45 +08:00
parent e8d864ff66
commit ce67aefc3b
14 changed files with 832 additions and 329 deletions
+56 -8
View File
@@ -1769,10 +1769,34 @@
<constraint firstAttribute="width" constant="380" id="cHp-hJ-PUQ"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="6Lo-Vn-3fP" userLabel="mapGyroToStack">
<rect key="frame" x="22" y="3026" width="380" height="56.5"/>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="G0n-nm-G2Y">
<rect key="frame" x="22" y="3090" width="380" height="56.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Map Built-in Gyro to" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6gY-8I-NWq">
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Gyro Source" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pjK-jB-97s">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.93902439019999995" green="0.9625305918" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<segmentedControl verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="lVF-ve-kTt">
<rect key="frame" x="0.0" y="25.5" width="380" height="32"/>
<segments>
<segment title="Built-in"/>
<segment title="Controller"/>
</segments>
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="selectedSegmentTintColor" systemColor="linkColor"/>
</segmentedControl>
</subviews>
<constraints>
<constraint firstAttribute="width" constant="380" id="Bj1-fa-Ff4"/>
<constraint firstAttribute="height" constant="56.5" id="a6g-4z-s6v"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="6Lo-Vn-3fP" userLabel="mapGyroToStack">
<rect key="frame" x="24" y="3234" width="380" height="56.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Map Gyro to" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6gY-8I-NWq">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.93902439019999995" green="0.9625305918" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -1879,7 +1903,7 @@
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="8eE-nU-sk5" userLabel="gyroToStickStack">
<rect key="frame" x="23" y="3111" width="336" height="67"/>
<rect key="frame" x="25" y="3319" width="336" height="67"/>
<subviews>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="RJa-fo-81z">
<rect key="frame" x="0.0" y="0.0" width="336" height="31"/>
@@ -1927,7 +1951,7 @@
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" axis="vertical" spacing="13.800000000000001" translatesAutoresizingMaskIntoConstraints="NO" id="9Cg-zf-Fjl" userLabel="yawPitchSensitivityStack">
<rect key="frame" x="20" y="3211" width="380" height="125"/>
<rect key="frame" x="22" y="3419" width="380" height="125"/>
<subviews>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="4Ee-fb-lEr" userLabel="yawSensitivityStack">
<rect key="frame" x="0.0" y="0.0" width="380" height="55.5"/>
@@ -1972,7 +1996,7 @@
</subviews>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="iey-Nn-eFG" userLabel="rollSensitivityStack">
<rect key="frame" x="21" y="3360" width="380" height="55.5"/>
<rect key="frame" x="23" y="3568" width="380" height="55.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Roll Sensitivity" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="u9Q-wm-UBm" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="380" height="16.5"/>
@@ -1992,7 +2016,7 @@
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="KRh-UP-TYS" userLabel="gyroMinStickOffset">
<rect key="frame" x="22" y="3447" width="380" height="55.5"/>
<rect key="frame" x="24" y="3655" width="380" height="55.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Minimum Offset (Gyro→Stick)" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HqA-an-KEe" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="380" height="16.5"/>
@@ -2032,7 +2056,7 @@
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="1yf-rP-jgt">
<rect key="frame" x="20" y="3530" width="345.5" height="31"/>
<rect key="frame" x="22" y="3738" width="345.5" height="31"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Blend Physical Stick Input" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="uFg-dv-6nT" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="195.5" height="31"/>
@@ -2137,6 +2161,26 @@
<constraint firstAttribute="height" constant="31" id="85R-lB-gVS"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="EsN-yO-7OW">
<rect key="frame" x="28" y="3165" width="275" height="31"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Swap Yaw &amp; Roll" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="MXH-vb-Zyb" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="125" height="31"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="O3h-we-v4X">
<rect key="frame" x="145" y="0.0" width="132" height="31"/>
<constraints>
<constraint firstAttribute="width" constant="130" id="9wY-CS-4Ag"/>
</constraints>
</switch>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="31" id="ZNm-dU-VEp"/>
</constraints>
</stackView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
@@ -2208,6 +2252,8 @@
<outlet property="gyroModeStack" destination="kAD-mK-aP8" id="GvL-Yx-S2t"/>
<outlet property="gyroSensitivitySlider" destination="3Ge-IB-PBj" id="Pdg-ke-KG3"/>
<outlet property="gyroSensitivityStack" destination="T3L-Kz-2yA" id="iQS-ce-h0z"/>
<outlet property="gyroSourceSelector" destination="lVF-ve-kTt" id="IeN-uQ-dI5"/>
<outlet property="gyroSourceStack" destination="G0n-nm-G2Y" id="v70-cs-Jsy"/>
<outlet property="gyroToStickMinOffsetSlider" destination="Ywy-Tz-L2L" id="4VQ-HW-lqF"/>
<outlet property="gyroToStickMinOffsetStack" destination="KRh-UP-TYS" id="loh-o6-s9D"/>
<outlet property="gyroToStickSwitchStack" destination="8eE-nU-sk5" id="oZB-AM-iHM"/>
@@ -2315,6 +2361,8 @@
<outlet property="statsOverlayStack" destination="UcP-0b-nJD" id="UdI-NS-O6k"/>
<outlet property="swapAbxyStack" destination="2rP-Ui-wVU" id="gUR-Vz-ORP"/>
<outlet property="swapAbxySwitch" destination="hv7-6b-rez" id="iKX-qk-Dep"/>
<outlet property="swapYawAndRollStack" destination="EsN-yO-7OW" id="Ncq-Y1-lku"/>
<outlet property="swapYawAndRollSwitch" destination="O3h-we-v4X" id="lea-Tj-LPV"/>
<outlet property="synthPhysicalInputStack" destination="1yf-rP-jgt" id="Mbn-eV-j3G"/>
<outlet property="synthPhysicalInputSwitch" destination="Ixf-14-Du8" id="wgc-mg-oGN"/>
<outlet property="testStack" destination="aP7-M9-psT" id="xAv-s6-rea"/>
+250 -202
View File
@@ -1449,7 +1449,7 @@
<objects>
<viewController storyboardIdentifier="settingsViewController" id="Hqr-d6-YrK" customClass="SettingsViewController" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Xq6-9l-Oey" customClass="UIScrollView">
<rect key="frame" x="0.0" y="0.0" width="1200" height="5000"/>
<rect key="frame" x="0.0" y="0.0" width="1251" height="5000"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="sbK-BT-6rK" userLabel="Resolutionstak">
@@ -2586,166 +2586,6 @@
<constraint firstAttribute="height" constant="31" id="FH8-Xv-wYq"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="NFm-mv-3qh" userLabel="mapGyroToStack">
<rect key="frame" x="0.0" y="2660" width="380" height="56.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Map Built-in Gyro to" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GX4-zV-pQ8" userLabel="Show Local Keyboard Toolbar">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.93902439019999995" green="0.9625305918" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<segmentedControl verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" apportionsSegmentWidthsByContent="YES" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="0OC-rX-CHK" userLabel="Show Local Keyboard Toolbar Selector">
<rect key="frame" x="0.0" y="25.5" width="380" height="32"/>
<segments>
<segment title="Mouse"/>
<segment title="Controller Stick"/>
<segment title="Drift Correction"/>
</segments>
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="selectedSegmentTintColor" systemColor="linkColor"/>
</segmentedControl>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="56.5" id="5S9-1U-k5K"/>
<constraint firstAttribute="width" constant="380" id="ffG-VJ-93D"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="xMx-7R-pmH" userLabel="gyroToStickStack">
<rect key="frame" x="3" y="2738" width="336" height="67"/>
<subviews>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="68R-uR-4PI">
<rect key="frame" x="0.0" y="0.0" width="336" height="31"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Yaw&amp;Pitch → Right Stick" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="AN9-U4-nUG" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="186" height="31"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="npQ-yh-2MA" userLabel="yawPitchToRightStickSwitch">
<rect key="frame" x="206" y="0.0" width="132" height="31"/>
<constraints>
<constraint firstAttribute="width" constant="130" id="kQr-At-VS9"/>
</constraints>
</switch>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="31" id="8bw-pt-rsb"/>
<constraint firstAttribute="width" constant="336" id="Oti-eo-Hbw"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="tvL-sE-fGi">
<rect key="frame" x="0.0" y="36" width="336" height="31"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Roll → Left Stick" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3LT-qb-ZEB" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="186" height="31"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="caz-QH-4dS" userLabel="rollToLeftStickSwitch">
<rect key="frame" x="206" y="0.0" width="132" height="31"/>
<constraints>
<constraint firstAttribute="width" constant="130" id="b3T-zI-mrq"/>
</constraints>
</switch>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="31" id="eI7-1J-KrE"/>
</constraints>
</stackView>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="67" id="bcM-Pz-UFh"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="13.800000000000001" id="1z6-G8-X45" userLabel="yawPitchSensitivityStack">
<rect key="frame" x="5" y="2819" width="380" height="125"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="pyS-Cc-IC3" userLabel="yawSensitivityStack">
<rect key="frame" x="0.0" y="0.0" width="380" height="55.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Yaw Sensitivity" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aSq-2H-FPk" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="380" height="16.5"/>
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<slider verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="100" minValue="0.0" maxValue="300" translatesAutoresizingMaskIntoConstraints="NO" id="JBP-uF-88R">
<rect key="frame" x="0.0" y="21.5" width="380" height="34"/>
<color key="tintColor" systemColor="linkColor"/>
</slider>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="55.5" id="9YP-eb-7uG"/>
<constraint firstAttribute="width" constant="380" id="yGK-yS-yMI"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="pYu-QR-UfH" userLabel="pitchSensitivityStack">
<rect key="frame" x="0.0" y="69.5" width="380" height="55.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Pitch Sensitivity" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yJv-xb-5HL" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<slider verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="100" minValue="0.0" maxValue="300" translatesAutoresizingMaskIntoConstraints="NO" id="4AR-S2-QX8">
<rect key="frame" x="0.0" y="25.5" width="380" height="30"/>
<color key="tintColor" systemColor="linkColor"/>
</slider>
</subviews>
<constraints>
<constraint firstAttribute="width" constant="380" id="ccF-lv-vv4"/>
<constraint firstAttribute="height" constant="55.5" id="u97-Kt-elr"/>
</constraints>
</stackView>
</subviews>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="5Zq-ch-iZ4" userLabel="rollSensitivityStack">
<rect key="frame" x="5" y="2958" width="380" height="55.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Roll Sensitivity" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dxk-33-Nbx" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<slider verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="100" minValue="0.0" maxValue="300" translatesAutoresizingMaskIntoConstraints="NO" id="SQ5-oO-S7X">
<rect key="frame" x="0.0" y="25.5" width="380" height="30"/>
<color key="tintColor" systemColor="linkColor"/>
</slider>
</subviews>
<constraints>
<constraint firstAttribute="width" constant="380" id="1bD-h1-NW3"/>
<constraint firstAttribute="height" constant="55.5" id="9ho-dq-LZS"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="Orr-Nz-gJS" userLabel="gyroMinStickOffsetStack">
<rect key="frame" x="5" y="3044" width="380" height="55.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Minimum Offset (Gyro→Stick)" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="52u-T9-1Hv" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<slider verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" minValue="0.0" maxValue="16383" translatesAutoresizingMaskIntoConstraints="NO" id="45X-gK-1ez">
<rect key="frame" x="0.0" y="25.5" width="380" height="30"/>
<color key="tintColor" systemColor="linkColor"/>
</slider>
</subviews>
<constraints>
<constraint firstAttribute="width" constant="380" id="B9Q-sl-emx"/>
<constraint firstAttribute="height" constant="55.5" id="fI1-bQ-oWk"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="qaV-ZR-fo7">
<rect key="frame" x="459" y="2763" width="380" height="55.5"/>
<subviews>
@@ -3169,46 +3009,6 @@
<constraint firstAttribute="height" constant="56.5" id="MNC-Cn-lnb"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="gkU-Rq-gB0">
<rect key="frame" x="5" y="3124" width="345.5" height="31"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Blend Physical Stick Input" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Bx3-CM-wet" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="195.5" height="31"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="HUF-g8-GD3">
<rect key="frame" x="215.5" y="0.0" width="132" height="31"/>
<constraints>
<constraint firstAttribute="width" constant="130" id="b8v-mZ-1xt"/>
</constraints>
</switch>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="31" id="JWd-0U-BlR"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="97k-tp-tqF">
<rect key="frame" x="5" y="3181" width="306" height="31"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Reverse Hold Button" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="m3M-yS-Wt6" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="156" height="31"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Aey-h4-DoE">
<rect key="frame" x="176" y="0.0" width="132" height="31"/>
<constraints>
<constraint firstAttribute="width" constant="130" id="BuF-mu-nxn"/>
</constraints>
</switch>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="31" id="rXC-R1-f3Z"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="Twt-JJ-ihg">
<rect key="frame" x="459" y="3218" width="380" height="55.5"/>
<subviews>
@@ -3349,11 +3149,255 @@
<constraint firstAttribute="height" constant="31" id="Mtc-ge-20Q"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="V6M-7E-Mly">
<rect key="frame" x="13" y="2713" width="380" height="56.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Gyro Source" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8AT-tJ-mCN">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.93902439019999995" green="0.9625305918" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<segmentedControl verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="p1G-aH-6bV">
<rect key="frame" x="0.0" y="25.5" width="380" height="32"/>
<segments>
<segment title="Built-in"/>
<segment title="Controller"/>
</segments>
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="selectedSegmentTintColor" systemColor="linkColor"/>
</segmentedControl>
</subviews>
<constraints>
<constraint firstAttribute="width" constant="380" id="IhL-kw-rRr"/>
<constraint firstAttribute="height" constant="56.5" id="pzv-fO-v91"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="bOa-JN-z7e">
<rect key="frame" x="13" y="2787" width="275" height="31"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Swap Yaw &amp; Roll" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9KX-hM-6El" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="125" height="31"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Njm-pv-auJ">
<rect key="frame" x="145" y="0.0" width="132" height="31"/>
<constraints>
<constraint firstAttribute="width" constant="130" id="HbX-cd-U49"/>
</constraints>
</switch>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="31" id="RTV-gs-L3d"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="NFm-mv-3qh" userLabel="mapGyroToStack">
<rect key="frame" x="13" y="2840" width="380" height="56.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Map Gyro to" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GX4-zV-pQ8" userLabel="Show Local Keyboard Toolbar">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.93902439019999995" green="0.9625305918" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<segmentedControl verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" apportionsSegmentWidthsByContent="YES" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="0OC-rX-CHK" userLabel="Show Local Keyboard Toolbar Selector">
<rect key="frame" x="0.0" y="25.5" width="380" height="32"/>
<segments>
<segment title="Mouse"/>
<segment title="Controller Stick"/>
<segment title="Drift Correction"/>
</segments>
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="selectedSegmentTintColor" systemColor="linkColor"/>
</segmentedControl>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="56.5" id="5S9-1U-k5K"/>
<constraint firstAttribute="width" constant="380" id="ffG-VJ-93D"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="xMx-7R-pmH" userLabel="gyroToStickStack">
<rect key="frame" x="16" y="2918" width="336" height="67"/>
<subviews>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="68R-uR-4PI">
<rect key="frame" x="0.0" y="0.0" width="336" height="31"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Yaw&amp;Pitch → Right Stick" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="AN9-U4-nUG" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="186" height="31"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="npQ-yh-2MA" userLabel="yawPitchToRightStickSwitch">
<rect key="frame" x="206" y="0.0" width="132" height="31"/>
<constraints>
<constraint firstAttribute="width" constant="130" id="kQr-At-VS9"/>
</constraints>
</switch>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="31" id="8bw-pt-rsb"/>
<constraint firstAttribute="width" constant="336" id="Oti-eo-Hbw"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="tvL-sE-fGi">
<rect key="frame" x="0.0" y="36" width="336" height="31"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Roll → Left Stick" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3LT-qb-ZEB" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="186" height="31"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="caz-QH-4dS" userLabel="rollToLeftStickSwitch">
<rect key="frame" x="206" y="0.0" width="132" height="31"/>
<constraints>
<constraint firstAttribute="width" constant="130" id="b3T-zI-mrq"/>
</constraints>
</switch>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="31" id="eI7-1J-KrE"/>
</constraints>
</stackView>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="67" id="bcM-Pz-UFh"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="13.800000000000001" id="1z6-G8-X45" userLabel="yawPitchSensitivityStack">
<rect key="frame" x="18" y="2999" width="380" height="125"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="pyS-Cc-IC3" userLabel="yawSensitivityStack">
<rect key="frame" x="0.0" y="0.0" width="380" height="55.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Yaw Sensitivity" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aSq-2H-FPk" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="380" height="16.5"/>
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<slider verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="100" minValue="0.0" maxValue="300" translatesAutoresizingMaskIntoConstraints="NO" id="JBP-uF-88R">
<rect key="frame" x="0.0" y="21.5" width="380" height="34"/>
<color key="tintColor" systemColor="linkColor"/>
</slider>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="55.5" id="9YP-eb-7uG"/>
<constraint firstAttribute="width" constant="380" id="yGK-yS-yMI"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="pYu-QR-UfH" userLabel="pitchSensitivityStack">
<rect key="frame" x="0.0" y="69.5" width="380" height="55.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Pitch Sensitivity" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yJv-xb-5HL" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<slider verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="100" minValue="0.0" maxValue="300" translatesAutoresizingMaskIntoConstraints="NO" id="4AR-S2-QX8">
<rect key="frame" x="0.0" y="25.5" width="380" height="30"/>
<color key="tintColor" systemColor="linkColor"/>
</slider>
</subviews>
<constraints>
<constraint firstAttribute="width" constant="380" id="ccF-lv-vv4"/>
<constraint firstAttribute="height" constant="55.5" id="u97-Kt-elr"/>
</constraints>
</stackView>
</subviews>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="5Zq-ch-iZ4" userLabel="rollSensitivityStack">
<rect key="frame" x="18" y="3138" width="380" height="55.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Roll Sensitivity" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dxk-33-Nbx" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<slider verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="100" minValue="0.0" maxValue="300" translatesAutoresizingMaskIntoConstraints="NO" id="SQ5-oO-S7X">
<rect key="frame" x="0.0" y="25.5" width="380" height="30"/>
<color key="tintColor" systemColor="linkColor"/>
</slider>
</subviews>
<constraints>
<constraint firstAttribute="width" constant="380" id="1bD-h1-NW3"/>
<constraint firstAttribute="height" constant="55.5" id="9ho-dq-LZS"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="Orr-Nz-gJS" userLabel="gyroMinStickOffsetStack">
<rect key="frame" x="18" y="3224" width="380" height="55.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Minimum Offset (Gyro→Stick)" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="52u-T9-1Hv" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<slider verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" minValue="0.0" maxValue="16383" translatesAutoresizingMaskIntoConstraints="NO" id="45X-gK-1ez">
<rect key="frame" x="0.0" y="25.5" width="380" height="30"/>
<color key="tintColor" systemColor="linkColor"/>
</slider>
</subviews>
<constraints>
<constraint firstAttribute="width" constant="380" id="B9Q-sl-emx"/>
<constraint firstAttribute="height" constant="55.5" id="fI1-bQ-oWk"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="gkU-Rq-gB0">
<rect key="frame" x="18" y="3304" width="345.5" height="31"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Blend Physical Stick Input" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Bx3-CM-wet" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="195.5" height="31"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="HUF-g8-GD3">
<rect key="frame" x="215.5" y="0.0" width="132" height="31"/>
<constraints>
<constraint firstAttribute="width" constant="130" id="b8v-mZ-1xt"/>
</constraints>
</switch>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="31" id="JWd-0U-BlR"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="97k-tp-tqF">
<rect key="frame" x="18" y="3361" width="306" height="31"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Reverse Hold Button" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="m3M-yS-Wt6" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="156" height="31"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Aey-h4-DoE">
<rect key="frame" x="176" y="0.0" width="132" height="31"/>
<constraints>
<constraint firstAttribute="width" constant="130" id="BuF-mu-nxn"/>
</constraints>
</switch>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="31" id="rXC-R1-f3Z"/>
</constraints>
</stackView>
</subviews>
<viewLayoutGuide key="safeArea" id="0sf-mG-PCk"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
<size key="freeformSize" width="1200" height="5000"/>
<size key="freeformSize" width="1251" height="5000"/>
<connections>
<outlet property="appThemeSelector" destination="pNz-vd-Sr9" id="nYB-7o-wkT"/>
<outlet property="appThemeStack" destination="Wpg-TL-KJy" id="Vhd-oB-Sy3"/>
@@ -3417,6 +3461,8 @@
<outlet property="gyroModeStack" destination="5Ep-SA-IBh" id="2qw-Sb-8O6"/>
<outlet property="gyroSensitivitySlider" destination="mHC-z4-AWQ" id="GHN-po-QYw"/>
<outlet property="gyroSensitivityStack" destination="Nd5-0L-wpv" id="Qo0-Z3-gkm"/>
<outlet property="gyroSourceSelector" destination="p1G-aH-6bV" id="qlT-WD-XOP"/>
<outlet property="gyroSourceStack" destination="V6M-7E-Mly" id="luO-gB-kte"/>
<outlet property="gyroToStickMinOffsetSlider" destination="45X-gK-1ez" id="McO-cA-MQc"/>
<outlet property="gyroToStickMinOffsetStack" destination="Orr-Nz-gJS" id="R0p-0J-nKz"/>
<outlet property="gyroToStickSwitchStack" destination="xMx-7R-pmH" id="LbK-ie-Hsl"/>
@@ -3511,6 +3557,8 @@
<outlet property="statsOverlayStack" destination="dby-k3-aiH" id="1Ha-Y3-su4"/>
<outlet property="swapAbxyStack" destination="reE-vr-Mdk" id="y3v-ac-LHy"/>
<outlet property="swapAbxySwitch" destination="T5q-1k-zB3" id="153-6O-0Pv"/>
<outlet property="swapYawAndRollStack" destination="bOa-JN-z7e" id="Xrg-wN-OIu"/>
<outlet property="swapYawAndRollSwitch" destination="Njm-pv-auJ" id="Dbr-mf-STF"/>
<outlet property="synthPhysicalInputStack" destination="gkU-Rq-gB0" id="GtQ-CM-8Qh"/>
<outlet property="synthPhysicalInputSwitch" destination="HUF-g8-GD3" id="z9c-dX-eqQ"/>
<outlet property="touchModeLabel" destination="v5B-5J-veL" id="ewI-fd-FnI"/>
+3
View File
@@ -45,6 +45,9 @@
@property (nonatomic, retain) NSNumber * gyroBiasX;
@property (nonatomic, retain) NSNumber * gyroBiasY;
@property (nonatomic, retain) NSNumber * gyroBiasZ;
@property (nonatomic, retain) NSNumber * controllerGyroBiasX;
@property (nonatomic, retain) NSNumber * controllerGyroBiasY;
@property (nonatomic, retain) NSNumber * controllerGyroBiasZ;
@property (nonatomic, retain) NSNumber * backgroundSessionTimer;
@property (nonatomic) enum {
CODEC_PREF_AUTO,
+3
View File
@@ -140,6 +140,9 @@
self.gyroBiasX = settings.gyroBiasX;
self.gyroBiasY = settings.gyroBiasY;
self.gyroBiasZ = settings.gyroBiasZ;
self.controllerGyroBiasX = settings.controllerGyroBiasX;
self.controllerGyroBiasY = settings.controllerGyroBiasY;
self.controllerGyroBiasZ = settings.controllerGyroBiasZ;
self.singleTapSensitivity = settings.singleTapSensitivity;
self.backgroundSessionTimer = settings.backroundSessionTimer;
self.edgeSlidingSensitivity = settings.edgeSlidingSensitivity;
+2
View File
@@ -41,6 +41,8 @@ typedef NS_ENUM(NSInteger, PencilHoverMode) {
@property (nonatomic, assign) int16_t unfoldedExclusiveFolderSequence;
@property NSSet<NSNumber *> *postExclusiveUnfoldedSequences;
@property BOOL isSelected;
@property (nonatomic, assign) bool useBuiltinGyro;
@property (nonatomic, assign) bool swapYawAndRoll;
@property (nonatomic, assign) MapGyroTo mapGyroTo;
@property (nonatomic, assign) bool yawPitchToRightStick;
@property (nonatomic, assign) bool rollToLeftStick;
+7
View File
@@ -34,6 +34,8 @@
[encoder encodeInt32:self.unfoldedExclusiveFolderSequence forKey:@"unfoldedExclusiveFolderSequence"];
[encoder encodeObject:self.postExclusiveUnfoldedSequences forKey:@"postExclusiveUnfoldedSequences"];
[encoder encodeBool:self.isSelected forKey:@"isSelected"];
[encoder encodeBool:self.useBuiltinGyro forKey:@"useBuiltinGyro"];
[encoder encodeBool:self.swapYawAndRoll forKey:@"swapYawAndRoll"];
[encoder encodeInt64:self.mapGyroTo forKey:@"mapGyroTo"];
[encoder encodeBool:self.yawPitchToRightStick forKey:@"yawPitchToRightStick"];
[encoder encodeBool:self.rollToLeftStick forKey:@"rollToLeftStick"];
@@ -99,6 +101,8 @@
forKey:@"postExclusiveUnfoldedSequences"] :
[NSSet set];
self.isSelected = [decoder decodeBoolForKey:@"isSelected"];
self.useBuiltinGyro = [decoder containsValueForKey:@"useBuiltinGyro"] ? [decoder decodeBoolForKey:@"useBuiltinGyro"] : true;
self.swapYawAndRoll = [decoder containsValueForKey:@"swapYawAndRoll"] ? [decoder decodeBoolForKey:@"swapYawAndRoll"] : false;
self.mapGyroTo = [decoder containsValueForKey:@"mapGyroTo"] ? [decoder decodeInt64ForKey:@"mapGyroTo"] : mapGyroToMouse;
self.yawPitchToRightStick = [decoder containsValueForKey:@"yawPitchToRightStick"] ? [decoder decodeBoolForKey:@"yawPitchToRightStick"] : true;
self.rollToLeftStick = [decoder containsValueForKey:@"rollToLeftStick"] ? [decoder decodeBoolForKey:@"rollToLeftStick"] : false;
@@ -201,6 +205,9 @@
copy.unfoldedExclusiveFolderSequence = self.unfoldedExclusiveFolderSequence;
copy.postExclusiveUnfoldedSequences = [self.postExclusiveUnfoldedSequences copy];
copy.isSelected = self.isSelected;
copy.useBuiltinGyro = self.useBuiltinGyro;
copy.swapYawAndRoll = self.swapYawAndRoll;
copy.isSelected = self.isSelected;
copy.mapGyroTo = self.mapGyroTo;
copy.yawPitchToRightStick = self.yawPitchToRightStick;
copy.rollToLeftStick = self.rollToLeftStick;
+150 -74
View File
@@ -47,6 +47,8 @@ import CoreMotion
@objc class func shared(profile: OSCProfile?) -> MotionHandler {
let sharedInstance = MotionHandler.sharedInstance
guard let profile = profile else { return sharedInstance }
sharedInstance.useBuiltinGyro = profile.useBuiltinGyro
sharedInstance.swapYawAndRoll = profile.swapYawAndRoll
sharedInstance.mapGyroTo = profile.mapGyroTo
sharedInstance.synthesizePhysicalStick = profile.synthesizePhysicalStick
sharedInstance.rollToLeftStick = profile.rollToLeftStick
@@ -60,10 +62,12 @@ import CoreMotion
}
@objc public var gyroControlStarted: Bool = false
@objc var useBuiltinGyro: Bool = true
@objc var swapYawAndRoll: Bool = false
private var gyroIsWorking: Bool = false
private var accelControlStarted: Bool = false
private let motionManager = CMMotionManager()
private weak var activeGCController:GCController?
private var synthesizePhysicalStick:Bool = false
private var mapGyroTo:MapGyroTo = .mapGyroToControllerStick
private var rollToLeftStick:Bool = false
@@ -96,6 +100,9 @@ import CoreMotion
@objc public var gyroBiasX: Double = 0
@objc public var gyroBiasY: Double = 0
@objc public var gyroBiasZ: Double = 0
@objc public var controllerGyroBiasX: Double = 0
@objc public var controllerGyroBiasY: Double = 0
@objc public var controllerGyroBiasZ: Double = 0
@objc public var gyroToStickMinOffset:Double = 0
private var yawBias:Double = 0
private var pitchBias:Double = 0
@@ -122,7 +129,7 @@ import CoreMotion
}
@objc public override init() {
let oscProfileMan = OSCProfilesManager.sharedManager(CGRectZero)
// _ = OSCProfilesManager.sharedManager(CGRectZero)
super.init()
if #available(iOS 13.0, *) {
let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene
@@ -161,16 +168,47 @@ import CoreMotion
self.startGyroUpdate()
}
/// 启动传感器数据更新
@objc public func startGyroUpdate() {
if !gyroControlStarted {
gyroControlStarted = true
if motionManager.isGyroAvailable {
motionManager.startGyroUpdates(to: .main) { [weak self] gyroData, _ in
guard let self = self, let data = gyroData else { return }
self.handleGyroData(x: data.rotationRate.x,
y: data.rotationRate.y,
z: data.rotationRate.z)
print("startGyroUpdate useBuiltinGyro \(useBuiltinGyro) \(CACurrentMediaTime())")
if useBuiltinGyro {
if motionManager.isGyroAvailable {
motionManager.startGyroUpdates(to: .main) { [weak self] gyroData, _ in
guard let self = self, let data = gyroData else { return }
self.handleGyroData(x: data.rotationRate.x,
y: data.rotationRate.y,
z: data.rotationRate.z)
}
}
}
else {
if #available(iOS 14.0, *) {
if activeGCController == nil {
if let controllers = ControllerUtil.activeGCControllers as? Set<GCController> {
for controller in controllers {
if controller.playerIndex == .index1 {
activeGCController = controller
break
}
}
}
}
if let motion = activeGCController?.motion {
if motion.sensorsRequireManualActivation {
motion.sensorsActive = true
}
if motion.sensorsActive {
motion.valueChangedHandler = { [weak self] motion in
self?.handleGyroData(x: motion.rotationRate.x,
y: motion.rotationRate.y,
z: motion.rotationRate.z)
}
}
}
}
}
}
@@ -198,6 +236,9 @@ import CoreMotion
if motionManager.isGyroActive{
motionManager.stopGyroUpdates()
}
if #available(iOS 14.0, *) {
activeGCController?.motion?.sensorsActive = false
}
self.clearGyroInput(interruptNonGyroInput:interruptNoneGyroInput, resetLeftStick:resetLeftStick)
}
@@ -226,67 +267,77 @@ import CoreMotion
let correctedY:Double = y - gyroBiasY
let correctedZ:Double = z - gyroBiasZ */
if #available(iOS 13.0, *) {
let orientation = (windowScene as! UIWindowScene).interfaceOrientation
switch orientation {
case .landscapeLeft:
yawBias = gyroBiasX
pitchBias = -gyroBiasY
rollBias = -gyroBiasZ
yawSource = x-yawBias
pitchSource = -y-pitchBias
rollSource = -z-rollBias
case .landscapeRight:
yawBias = -gyroBiasX
pitchBias = gyroBiasY
rollBias = -gyroBiasZ
yawSource = -x-yawBias
pitchSource = y-pitchBias
rollSource = -z-rollBias
case .portrait:
yawBias = -gyroBiasY
pitchBias = -gyroBiasX
rollBias = -gyroBiasZ
yawSource = -y-yawBias
pitchSource = -x-pitchBias
rollSource = -z-rollBias
case .portraitUpsideDown:
yawBias = gyroBiasY
pitchBias = gyroBiasX
rollBias = -gyroBiasZ
yawSource = y-yawBias
pitchSource = x-pitchBias
rollSource = -z-rollBias
default:
yawBias = gyroBiasX
pitchBias = -gyroBiasY
rollBias = -gyroBiasZ
yawSource = x-yawBias
pitchSource = -y-pitchBias
rollSource = -z-rollBias
}
} else {
let orientation = UIApplication.shared.statusBarOrientation
if orientation.isLandscape {
yawBias = gyroBiasX
pitchBias = -gyroBiasY
rollBias = -gyroBiasZ
yawSource = x-yawBias
pitchSource = -y-pitchBias
rollSource = -z-rollBias
} else if orientation.isPortrait {
yawBias = -gyroBiasY
pitchBias = -gyroBiasX
rollBias = -gyroBiasZ
yawSource = -y-yawBias
pitchSource = -x-pitchBias
rollSource = -z-rollBias
if useBuiltinGyro {
if #available(iOS 13.0, *) {
let orientation = (windowScene as! UIWindowScene).interfaceOrientation
switch orientation {
case .landscapeLeft:
yawBias = gyroBiasX
pitchBias = -gyroBiasY
rollBias = -gyroBiasZ
yawSource = x-yawBias
pitchSource = -y-pitchBias
rollSource = -z-rollBias
case .landscapeRight:
yawBias = -gyroBiasX
pitchBias = gyroBiasY
rollBias = -gyroBiasZ
yawSource = -x-yawBias
pitchSource = y-pitchBias
rollSource = -z-rollBias
case .portrait:
yawBias = -gyroBiasY
pitchBias = -gyroBiasX
rollBias = -gyroBiasZ
yawSource = -y-yawBias
pitchSource = -x-pitchBias
rollSource = -z-rollBias
case .portraitUpsideDown:
yawBias = gyroBiasY
pitchBias = gyroBiasX
rollBias = -gyroBiasZ
yawSource = y-yawBias
pitchSource = x-pitchBias
rollSource = -z-rollBias
default:
yawBias = gyroBiasX
pitchBias = -gyroBiasY
rollBias = -gyroBiasZ
yawSource = x-yawBias
pitchSource = -y-pitchBias
rollSource = -z-rollBias
}
} else {
let orientation = UIApplication.shared.statusBarOrientation
if orientation.isLandscape {
yawBias = gyroBiasX
pitchBias = -gyroBiasY
rollBias = -gyroBiasZ
yawSource = x-yawBias
pitchSource = -y-pitchBias
rollSource = -z-rollBias
} else if orientation.isPortrait {
yawBias = -gyroBiasY
pitchBias = -gyroBiasX
rollBias = -gyroBiasZ
yawSource = -y-yawBias
pitchSource = -x-pitchBias
rollSource = -z-rollBias
}
}
}
else {
yawBias = swapYawAndRoll ? controllerGyroBiasY : -controllerGyroBiasZ
pitchBias = -controllerGyroBiasX
rollBias = swapYawAndRoll ? -controllerGyroBiasZ : controllerGyroBiasY
yawSource = (swapYawAndRoll ? y : -z) - yawBias
pitchSource = -x-pitchBias
rollSource = (swapYawAndRoll ? -z : y) - rollBias
}
if !gyroControlStarted {
self.clearGyroInput(interruptNonGyroInput: interruptNoneGyroInput)
print("Gyro: stopped")
// print("Gyro: stopped")
return
}
@@ -361,12 +412,30 @@ import CoreMotion
var sumX = 0.0, sumY = 0.0, sumZ = 0.0
var sampleCount = 0
motionManager.startGyroUpdates(to: .main) { [weak self] gyroData, _ in
guard let self = self, self.isCalibrating, let data = gyroData else { return }
sumX += data.rotationRate.x
sumY += data.rotationRate.y
sumZ += data.rotationRate.z
sampleCount += 1
if useBuiltinGyro {
motionManager.startGyroUpdates(to: .main) { [weak self] gyroData, _ in
guard let self = self, self.isCalibrating, let data = gyroData else { return }
sumX += data.rotationRate.x
sumY += data.rotationRate.y
sumZ += data.rotationRate.z
sampleCount += 1
}
}
else if #available(iOS 14.0, *) {
if let motion = activeGCController?.motion {
if motion.sensorsRequireManualActivation {
motion.sensorsActive = true
}
if motion.sensorsActive {
motion.valueChangedHandler = { [weak self] motion in
guard let self = self, self.isCalibrating else { return }
sumX += motion.rotationRate.x
sumY += motion.rotationRate.y
sumZ += motion.rotationRate.z
sampleCount += 1
}
}
}
}
// 5秒后计算平均值
@@ -374,9 +443,16 @@ import CoreMotion
guard let self = self else { return }
self.motionManager.stopGyroUpdates()
if sampleCount > 0 {
gyroBiasX = sumX / Double(sampleCount)
gyroBiasY = sumY / Double(sampleCount)
gyroBiasZ = sumZ / Double(sampleCount)
if useBuiltinGyro {
gyroBiasX = sumX / Double(sampleCount)
gyroBiasY = sumY / Double(sampleCount)
gyroBiasZ = sumZ / Double(sampleCount)
}
else {
controllerGyroBiasX = sumX / Double(sampleCount)
controllerGyroBiasY = sumY / Double(sampleCount)
controllerGyroBiasZ = sumZ / Double(sampleCount)
}
}
self.isCalibrating = false
completion()
@@ -36,6 +36,9 @@
<attribute name="bitrate" attributeType="Integer 32" defaultValueString="10000" usesScalarValueType="NO" syncable="YES"/>
<attribute name="btMouseSupport" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="buttonVisualFeedback" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="controllerGyroBiasX" optional="YES" attributeType="Double" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="controllerGyroBiasY" optional="YES" attributeType="Double" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="controllerGyroBiasZ" optional="YES" attributeType="Double" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="controllerMouseExpo" optional="YES" attributeType="Float" defaultValueString="1.6" usesScalarValueType="NO" syncable="YES"/>
<attribute name="controllerMouseLeftButton" attributeType="Integer 32" defaultValueString="16777215" usesScalarValueType="NO" syncable="YES"/>
<attribute name="controllerMousePointerVelocity" optional="YES" attributeType="Float" defaultValueString="12" usesScalarValueType="NO" syncable="YES"/>
@@ -116,4 +119,4 @@
<attribute name="useBuiltinMic" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="width" attributeType="Integer 32" defaultValueString="1280" usesScalarValueType="NO" syncable="YES"/>
</entity>
</model>
</model>
@@ -11591,6 +11591,35 @@
}
}
},
"swapYawAndRollStackTip" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Enable this option when the controller moves together with the screen (e.g., when using a telescopic controller)"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "当手柄随屏幕同一运动时(例如使用拉伸手柄)启用该选项"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "當手把隨螢幕同步移動時(例如使用拉伸式手把)啟用此選項"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "當手把隨螢幕同步移動時(例如使用拉伸式手把)啟用此選項"
}
}
}
},
"Switch on/off a floating gamepad overlay with live input feedback" : {
"extractionState" : "manual",
"localizations" : {
@@ -153,6 +153,12 @@
@property (strong, nonatomic) IBOutlet UIStackView *rememberFoldStateStack;
@property (strong, nonatomic) IBOutlet UISwitch *rememberFoldStateSwitch;
@property (weak, nonatomic) IBOutlet UIStackView *gyroSourceStack;
@property (weak, nonatomic) IBOutlet UISegmentedControl *gyroSourceSelector;
@property (weak, nonatomic) IBOutlet UIStackView *swapYawAndRollStack;
@property (weak, nonatomic) IBOutlet UISwitch *swapYawAndRollSwitch;
@property (strong, nonatomic) IBOutlet UIStackView *mapGyroToStack;
@property (strong, nonatomic) IBOutlet UISegmentedControl *mapGyroToSelector;
@@ -370,6 +370,11 @@ BOOL isCustomResolution(int resolutionSelected) {
[self.reverseHoldButtonSwitch setOn:oscProfile.reverseGyroHoldButton];
[self.gyroSourceSelector setSelectedSegmentIndex:oscProfile.useBuiltinGyro ? 0 : 1];
[self gyroSourceChanged:self.gyroSourceSelector];
[self.swapYawAndRollSwitch setOn:oscProfile.swapYawAndRoll];
[self.mapGyroToSelector setSelectedSegmentIndex:oscProfile.mapGyroTo];
[self mapGyroToChanged:self.mapGyroToSelector];
@@ -412,7 +417,12 @@ BOOL isCustomResolution(int resolutionSelected) {
CGFloat pitchSensitivityPercent = [self map_velocFactorDisplay_fromSliderValue:self.pitchSensitivitySlider.value];
CGFloat rollSensitivityPercent = [self map_velocFactorDisplay_fromSliderValue:self.rollSensitivitySlider.value];
bool configNotChanged = (oscProfile.mapGyroTo == self.mapGyroToSelector.selectedSegmentIndex
bool configNotChanged = (
(int16_t)(oscProfile.pointerVelocityModeDivider*100) == (int16_t)(self.pointerVelocityModeDividerSlider.value)
&& (int16_t)(oscProfile.touchPointerVelocityFactor*100) == (int16_t)touchPointerVelocityFactorPercent
&& oscProfile.useBuiltinGyro == self.gyroSourceSelector.selectedSegmentIndex == 0
&& oscProfile.swapYawAndRoll == self.swapYawAndRollSwitch.isOn
&& oscProfile.mapGyroTo == self.mapGyroToSelector.selectedSegmentIndex
&& oscProfile.yawPitchToRightStick == self.yawPitchToRightStickSwitch.isOn
&& oscProfile.rollToLeftStick == self.rollToLeftStickSwitch.isOn
&& (int16_t)(oscProfile.pointerVelocityModeDivider*100) == (int16_t)self.pointerVelocityModeDividerSlider.value
@@ -438,6 +448,8 @@ BOOL isCustomResolution(int resolutionSelected) {
oscProfile = [oscProfileMan getSelectedProfile];
oscProfile.pointerVelocityModeDivider = self.pointerVelocityModeDividerSlider.value/100;
oscProfile.touchPointerVelocityFactor = touchPointerVelocityFactorPercent/100;
oscProfile.useBuiltinGyro = self.gyroSourceSelector.selectedSegmentIndex == 0;
oscProfile.swapYawAndRoll = self.swapYawAndRollSwitch.isOn;
oscProfile.mapGyroTo = self.mapGyroToSelector.selectedSegmentIndex;
oscProfile.yawPitchToRightStick = self.yawPitchToRightStickSwitch.isOn;
oscProfile.rollToLeftStick = self.rollToLeftStickSwitch.isOn;
@@ -957,6 +969,13 @@ BOOL isCustomResolution(int resolutionSelected) {
self.reverseHoldButtonStack.hasDynamicLabel = YES;
[self addSetting:self.reverseHoldButtonStack ofId:@"reverseHoldButtonStack" to:motionControlSection];
self.gyroSourceStack.isGameProfileSetting = YES;
[self addSetting:self.gyroSourceStack ofId:@"gyroSourceStack" to:motionControlSection];
self.swapYawAndRollStack.hasInfoTag = YES;
self.swapYawAndRollStack.isGameProfileSetting = YES;
[self addSetting:self.swapYawAndRollStack ofId:@"swapYawAndRollStack" to:motionControlSection];
self.mapGyroToStack.hasInfoTag = YES;
self.mapGyroToStack.isGameProfileSetting = YES;
[self addSetting:self.mapGyroToStack ofId:@"mapGyroToStack" to:motionControlSection];
@@ -1737,7 +1756,11 @@ BOOL isCustomResolution(int resolutionSelected) {
tipText = [LocalizationHelper localizedStringForKey:@"softKeyboardHeightStackTip"];
showOnlineDocAction = false;
}
if([sender.superview.accessibilityIdentifier isEqualToString: @"swapYawAndRollStack"]){
tipText = [LocalizationHelper localizedStringForKey:@"swapYawAndRollStackTip"];
showOnlineDocAction = false;
}
UIStackView* parentStack = (UIStackView* )sender.superview;
NSString* edgeSide = self.slideToSettingsScreenEdgeSelector.selectedSegmentIndex == 1 ? [LocalizationHelper localizedStringForKey:@"left"] : [LocalizationHelper localizedStringForKey:@"right"];
NSString* slideDist = [NSString stringWithFormat:@"%d%%", (int)(self.slideToMenuDistanceSlider.value*100)];
@@ -2410,6 +2433,7 @@ BOOL isCustomResolution(int resolutionSelected) {
[self.controllerMouseExpoSlider addTarget:self action:@selector(controllerMouseExpoSliderMoved:) forControlEvents:UIControlEventValueChanged];
[self controllerMouseExpoSliderMoved:self.controllerMouseExpoSlider];
[self.gyroSourceSelector addTarget:self action:@selector(gyroSourceChanged:) forControlEvents:UIControlEventValueChanged];
[self.mapGyroToSelector addTarget:self action:@selector(mapGyroToChanged:) forControlEvents:UIControlEventValueChanged];
[self.yawPitchToRightStickSwitch addTarget:self action:@selector(yawPitchToRightStickSwitchFlipped:) forControlEvents:UIControlEventValueChanged];
[self.rollToLeftStickSwitch addTarget:self action:@selector(rollToLeftStickSwitchFlipped:) forControlEvents:UIControlEventValueChanged];
@@ -2631,6 +2655,10 @@ BOOL isCustomResolution(int resolutionSelected) {
}
}
- (void)gyroSourceChanged:(UISegmentedControl* )sender{
[self setHidden:sender.selectedSegmentIndex != 1 forStack:_swapYawAndRollStack];
}
- (void)mapGyroToChanged:(UISegmentedControl* )sender{
// [self setHidden:sender.selectedSegmentIndex != mapGyroToControllerStick forStack:_gyroToStickSwitchStack];
bool mapGyroToMouseEnabled = sender.selectedSegmentIndex == mapGyroToMouse;
@@ -2666,9 +2694,16 @@ BOOL isCustomResolution(int resolutionSelected) {
MotionHandler* motionHandler = [MotionHandler sharedWithProfile:nil];
[motionHandler calibrateGyroBiasWithDuration:5 completion:^{
Settings* currentSettings = [self->dataMan retrieveSettings];
currentSettings.gyroBiasX = [NSNumber numberWithDouble:motionHandler.gyroBiasX];
currentSettings.gyroBiasY = [NSNumber numberWithDouble:motionHandler.gyroBiasY];
currentSettings.gyroBiasZ = [NSNumber numberWithDouble:motionHandler.gyroBiasZ];
if(self.gyroSourceSelector.selectedSegmentIndex == 0){
currentSettings.gyroBiasX = [NSNumber numberWithDouble:motionHandler.gyroBiasX];
currentSettings.gyroBiasY = [NSNumber numberWithDouble:motionHandler.gyroBiasY];
currentSettings.gyroBiasZ = [NSNumber numberWithDouble:motionHandler.gyroBiasZ];
}
else{
currentSettings.controllerGyroBiasX = [NSNumber numberWithDouble:motionHandler.controllerGyroBiasX];
currentSettings.controllerGyroBiasY = [NSNumber numberWithDouble:motionHandler.controllerGyroBiasY];
currentSettings.controllerGyroBiasZ = [NSNumber numberWithDouble:motionHandler.controllerGyroBiasZ];
}
[self->dataMan saveData];
}];
[AlertControllerUtil showAlertIn:self
@@ -453,8 +453,11 @@
_motionHandler = [MotionHandler sharedWithProfile: nil];
_motionHandler.gyroBiasX = _settings.gyroBiasX.doubleValue;
_motionHandler.gyroBiasY = _settings.gyroBiasY.doubleValue;
_motionHandler.gyroBiasZ = _settings.gyroBiasZ.doubleValue;
_motionHandler.gyroBiasZ = _settings.gyroBiasZ.doubleValue;
_motionHandler.controllerGyroBiasX = _settings.controllerGyroBiasX.doubleValue;
_motionHandler.controllerGyroBiasY = _settings.controllerGyroBiasY.doubleValue;
_motionHandler.controllerGyroBiasZ = _settings.controllerGyroBiasZ.doubleValue;
TouchPadGestureHandler.enablePinch = _settings.enablePinch;
TouchPadGestureHandler.ctrlDownForPinch = _settings.ctrlDownForPinch;
TouchPadGestureHandler.scrollSensitivity = _settings.scrollSensitivity.floatValue;
+129 -9
View File
@@ -578,31 +578,31 @@
}
},
"6gY-8I-NWq.text" : {
"comment" : "Class = \"UILabel\"; text = \"Map Built-in Gyro to\"; ObjectID = \"6gY-8I-NWq\";",
"comment" : "Class = \"UILabel\"; text = \"Map Gyro to\"; ObjectID = \"6gY-8I-NWq\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Map Built-in Gyro to"
"value" : "Map Gyro to"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "内置陀螺仪映射为"
"value" : "陀螺仪映射为"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "内建陀螺儀映射為"
"state" : "translated",
"value" : "陀螺儀映射為"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "内建陀螺儀映射為"
"state" : "translated",
"value" : "陀螺儀映射為"
}
}
}
@@ -3524,13 +3524,13 @@
},
"zh-Hant" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "最小偏移量(陀螺儀→搖桿)"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "最小偏移量(陀螺儀→搖桿)"
}
}
@@ -4352,6 +4352,66 @@
}
}
},
"lVF-ve-kTt.segmentTitles[0]" : {
"comment" : "Class = \"UISegmentedControl\"; lVF-ve-kTt.segmentTitles[0] = \"Built-in\"; ObjectID = \"lVF-ve-kTt\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Built-in"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "内置"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "內建"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "內建"
}
}
}
},
"lVF-ve-kTt.segmentTitles[1]" : {
"comment" : "Class = \"UISegmentedControl\"; lVF-ve-kTt.segmentTitles[1] = \"Controller\"; ObjectID = \"lVF-ve-kTt\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Controller"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "手柄"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "手把"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "手把"
}
}
}
},
"MaN-f7-I3g.text" : {
"comment" : "Class = \"UILabel\"; text = \"Frame Pacing\"; ObjectID = \"MaN-f7-I3g\";",
"extractionState" : "extracted_with_value",
@@ -4634,6 +4694,36 @@
}
}
},
"MXH-vb-Zyb.text" : {
"comment" : "Class = \"UILabel\"; text = \"Swap Yaw & Roll\"; ObjectID = \"MXH-vb-Zyb\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Swap Yaw & Roll"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "偏航/横滚互换"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "偏航/橫滾互換"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "偏航/橫滾互換"
}
}
}
},
"MyP-Aq-htW.text" : {
"comment" : "Class = \"UILabel\"; text = \" Reveal mode \"; ObjectID = \"MyP-Aq-htW\";",
"extractionState" : "extracted_with_value",
@@ -5150,6 +5240,36 @@
}
}
},
"pjK-jB-97s.text" : {
"comment" : "Class = \"UILabel\"; text = \"Gyro Source\"; ObjectID = \"pjK-jB-97s\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Gyro Source"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "陀螺仪输入来源"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "陀螺儀輸入來源"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "陀螺儀輸入來源"
}
}
}
},
"pMN-6T-aYE.text" : {
"comment" : "Class = \"UILabel\"; text = \"Gesture Sliding Distance\"; ObjectID = \"pMN-6T-aYE\";",
"extractionState" : "extracted_with_value",
+148 -28
View File
@@ -811,6 +811,36 @@
}
}
},
"8AT-tJ-mCN.text" : {
"comment" : "Class = \"UILabel\"; text = \"Gyro Source\"; ObjectID = \"8AT-tJ-mCN\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Gyro Source"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "陀螺仪输入来源"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "陀螺儀輸入來源"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "陀螺儀輸入來源"
}
}
}
},
"9Dr-3c-z61.text" : {
"comment" : "Class = \"UILabel\"; text = \"Label alpha\"; ObjectID = \"9Dr-3c-z61\";",
"extractionState" : "extracted_with_value",
@@ -943,6 +973,36 @@
}
}
},
"9KX-hM-6El.text" : {
"comment" : "Class = \"UILabel\"; text = \"Swap Yaw & Roll\"; ObjectID = \"9KX-hM-6El\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Swap Yaw & Roll"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "偏航/横滚互换"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "偏航/橫滾互換"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "偏航/橫滾互換"
}
}
}
},
"52u-T9-1Hv.text" : {
"comment" : "Class = \"UILabel\"; text = \"Minimum Offset (Gyro→Stick)\"; ObjectID = \"52u-T9-1Hv\";",
"extractionState" : "extracted_with_value",
@@ -955,19 +1015,19 @@
},
"zh-Hans" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "最小偏移量(陀螺仪→摇杆)"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "最小偏移量(陀螺儀→搖桿)"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "最小偏移量(陀螺儀→搖桿)"
}
}
@@ -2522,31 +2582,31 @@
}
},
"GX4-zV-pQ8.text" : {
"comment" : "Class = \"UILabel\"; text = \"Map Built-in Gyro to\"; ObjectID = \"GX4-zV-pQ8\";",
"comment" : "Class = \"UILabel\"; text = \"Map Gyro to\"; ObjectID = \"GX4-zV-pQ8\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Map Built-in Gyro to"
"value" : "Map Gyro to"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "内置陀螺仪映射为"
"value" : "陀螺仪映射为"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "内建陀螺儀映射為"
"state" : "translated",
"value" : "陀螺儀映射為"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "内建陀螺儀映射為"
"state" : "translated",
"value" : "陀螺儀映射為"
}
}
}
@@ -2569,13 +2629,13 @@
},
"zh-Hant" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "指針速度"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "指針速度"
}
}
@@ -2731,13 +2791,13 @@
},
"zh-Hant" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "滑鼠靈敏度"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "滑鼠靈敏度"
}
}
@@ -2821,13 +2881,13 @@
},
"zh-Hant" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "串流位元速率"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "串流位元速率"
}
}
@@ -2851,13 +2911,13 @@
},
"zh-Hant" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "靈敏度分割位置"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "靈敏度分割位置"
}
}
@@ -4357,6 +4417,66 @@
}
}
},
"p1G-aH-6bV.segmentTitles[0]" : {
"comment" : "Class = \"UISegmentedControl\"; p1G-aH-6bV.segmentTitles[0] = \"Built-in\"; ObjectID = \"p1G-aH-6bV\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Built-in"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "内置"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "内建"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "内建"
}
}
}
},
"p1G-aH-6bV.segmentTitles[1]" : {
"comment" : "Class = \"UISegmentedControl\"; p1G-aH-6bV.segmentTitles[1] = \"Controller\"; ObjectID = \"p1G-aH-6bV\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Controller"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "手柄"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "手把"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "手把"
}
}
}
},
"P4N-i6-1zD.text" : {
"comment" : "Class = \"UILabel\"; text = \"Enable Timebase\"; ObjectID = \"P4N-i6-1zD\";",
"extractionState" : "extracted_with_value",
@@ -4567,13 +4687,13 @@
},
"zh-Hant" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "內建"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "內建"
}
}
@@ -4879,7 +4999,7 @@
},
"zh-HK" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "延遲滑鼠左單擊"
}
}
@@ -5155,7 +5275,7 @@
},
"zh-HK" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "顯示本地軟鍵盤工具列"
}
}
@@ -5185,7 +5305,7 @@
},
"zh-HK" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "按鍵視覺回饋"
}
}
@@ -5245,7 +5365,7 @@
},
"zh-HK" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "恢復範本"
}
}
@@ -5287,7 +5407,7 @@
},
"zh-HK" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "串流解析度"
}
}
@@ -5347,7 +5467,7 @@
},
"zh-HK" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "左鍵"
}
}
@@ -5377,7 +5497,7 @@
},
"zh-HK" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "中鍵"
}
}
@@ -5407,7 +5527,7 @@
},
"zh-HK" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "右鍵"
}
}