initial build for motion mode

This commit is contained in:
TrueZhuanjia
2025-06-29 19:59:56 +08:00
parent 00aff53e35
commit 88414cd3db
40 changed files with 2275 additions and 1491 deletions
+77 -24
View File
@@ -154,7 +154,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="gWg-BF-yDI" userLabel="codec Stack">
<rect key="frame" x="16" y="1554" width="380" height="56.5"/>
<rect key="frame" x="21" y="1835" width="380" height="56.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Preferred Codec" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6w5-Md-NpV" userLabel="Preferred Codec">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
@@ -179,7 +179,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" fixedFrame="YES" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="dH7-Sy-EdJ" userLabel="HDRStack">
<rect key="frame" x="18" y="1618" width="280" height="31"/>
<rect key="frame" x="23" y="1899" width="280" height="31"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="HDR" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2w1-Vw-GVy">
<rect key="frame" x="0.0" y="0.0" width="130" height="31"/>
@@ -199,7 +199,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="9C2-td-rMV" userLabel="framepacing Stack">
<rect key="frame" x="15" y="1712" width="380" height="56.5"/>
<rect key="frame" x="20" y="1993" width="380" height="56.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Frame Pacing Preference" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ZWC-Gw-pSq">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
@@ -400,7 +400,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="2GS-cX-u4i" userLabel="swapABXYButtons Stack">
<rect key="frame" x="15" y="1471" width="380" height="56.5"/>
<rect key="frame" x="20" y="1752" width="380" height="56.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Swap A/B and X/Y Buttons" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Dll-7x-18l">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
@@ -450,8 +450,57 @@
<constraint firstAttribute="width" constant="380" id="1bX-IR-Vkj"/>
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="kAD-mK-aP8" userLabel="gyroModeStack">
<rect key="frame" x="15" y="973" width="380" height="56.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Gyro Mode" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="7tq-jU-C6l">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<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>
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="1" id="aa5-3y-I4d" userLabel="gyroModeSelector">
<rect key="frame" x="0.0" y="25.5" width="380" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<segments>
<segment title="Off"/>
<segment title="Auto"/>
<segment title="Device"/>
<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="Lb7-hi-xph"/>
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="T3L-Kz-2yA" userLabel="gyroSensitivityStack">
<rect key="frame" x="15" y="1051" width="380" height="56.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Gyro Sensitivity" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="9XL-xt-Q57">
<rect key="frame" x="0.0" y="0.0" width="380" height="18.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<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 opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="100" minValue="0.0" maxValue="300" id="3Ge-IB-PBj" userLabel="mousePointerVelocityFactor">
<rect key="frame" x="-2" y="23.5" width="384" height="34"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="tintColor" systemColor="linkColor"/>
</slider>
</subviews>
<constraints>
<constraint firstAttribute="width" constant="380" id="W3Y-QW-piG"/>
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="mes-so-dfK" userLabel="liftStreamViewForKeyboard Stack">
<rect key="frame" x="17" y="958" width="380" height="56.5"/>
<rect key="frame" x="22" y="1239" width="380" height="56.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Lift Stream View for Local Keyboard " textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="QYJ-84-bvc">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
@@ -475,7 +524,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="tgA-05-vWV" userLabel="slideToSettingsScreenEdge Stack">
<rect key="frame" x="15" y="1113" width="380" height="56.5"/>
<rect key="frame" x="20" y="1394" width="380" height="56.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Open Settings in Streaming" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="IvI-tw-APj">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
@@ -499,7 +548,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="msN-pa-Kn3" userLabel="slideToToolboxScreenEdge Stack">
<rect key="frame" x="15" y="1189" width="380" height="56.5"/>
<rect key="frame" x="20" y="1470" width="380" height="56.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Open Toolbox in Streaming" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Zp4-fA-IeL">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
@@ -524,7 +573,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="pN7-bs-8yu" userLabel="slideToSettingsDistance Stack">
<rect key="frame" x="16" y="1263" width="380" height="55.5"/>
<rect key="frame" x="21" y="1544" width="380" height="55.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Gesture Slide Distance" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pMN-6T-aYE" userLabel="Slide To Settings Distance UI Label">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
@@ -543,7 +592,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="YBu-VX-wpN" userLabel="externalDisplayMode Stack">
<rect key="frame" x="15" y="2216" width="380" height="56.5"/>
<rect key="frame" x="20" y="2497" width="380" height="56.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="External Display Mode" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4Qy-hB-oa5">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
@@ -566,7 +615,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="nE1-Al-qRc" userLabel="localMousePointerMode Stack">
<rect key="frame" x="15" y="2291" width="380" height="56.5"/>
<rect key="frame" x="20" y="2572" width="380" height="56.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Local Mouse Pointer" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tAd-bm-2IO">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
@@ -590,7 +639,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="2P0-Tg-zWd" userLabel="reverseMouseWheelDirection Stack">
<rect key="frame" x="15" y="1784" width="380" height="56.5"/>
<rect key="frame" x="20" y="2065" width="380" height="56.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Physical Mouse Wheel Scroll" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="FwK-oG-vuz">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
@@ -613,7 +662,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" spacing="20" id="gjX-s1-k61" userLabel="CitrixX1MouseStack">
<rect key="frame" x="20" y="1973" width="280" height="31"/>
<rect key="frame" x="25" y="2254" width="280" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Citrix X1 Mouse" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5aI-Zx-dNf">
@@ -634,7 +683,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="UcP-0b-nJD" userLabel="statsOverlay Stack">
<rect key="frame" x="15" y="2063" width="380" height="56.5"/>
<rect key="frame" x="20" y="2344" width="380" height="56.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Statistics Overlay" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="s2i-ZL-Gz4" userLabel="Statistics Overlay">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
@@ -658,7 +707,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="90g-DY-GKi" userLabel="showKeyboardToolbar Stack">
<rect key="frame" x="15" y="1037" width="380" height="56.5"/>
<rect key="frame" x="20" y="1318" width="380" height="56.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Show Local Keyboard Toolbar " textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="aup-5k-z6P">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
@@ -682,7 +731,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="5dA-cw-gOa" userLabel="unlockDisplayOrientation Stack">
<rect key="frame" x="16" y="2140" width="380" height="56.5"/>
<rect key="frame" x="21" y="2421" width="380" height="56.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="90° Display Rotation" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hAo-1k-oYF" userLabel="Lock Display Orientation">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
@@ -705,7 +754,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" spacing="20" id="Qfd-bG-FSa" userLabel="yuv444Stack">
<rect key="frame" x="15" y="1673" width="280" height="31"/>
<rect key="frame" x="20" y="1954" width="280" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="YUV 4:4:4" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="MNm-86-RGl" userLabel="yuv444Label">
@@ -726,7 +775,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" spacing="20" id="TvS-69-vcF" userLabel="optimizeGameSettingStack">
<rect key="frame" x="20" y="2012" width="280" height="31"/>
<rect key="frame" x="25" y="2293" width="280" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Optimize Game Settings" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.65000000000000002" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="d1N-HH-Aq9" userLabel="Optimize Game Settings">
@@ -744,7 +793,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" spacing="20" id="Bbr-Wj-Z75" userLabel="audioOnPCStack">
<rect key="frame" x="20" y="1934" width="280" height="31"/>
<rect key="frame" x="25" y="2215" width="280" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Play Audio on PC" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8wW-Sq-EOE" userLabel="Optimize Game Settings">
@@ -762,7 +811,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" spacing="20" id="RrU-mx-9jP" userLabel="multiControllerStack">
<rect key="frame" x="16" y="1330" width="280" height="31"/>
<rect key="frame" x="21" y="1611" width="280" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Multi-Controller Mode" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SAQ-04-n4h" userLabel="Multi-Controller Mode">
@@ -780,7 +829,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" spacing="20" id="EKY-6m-OBd" userLabel="softKeyboardToolbarStack">
<rect key="frame" x="16" y="1369" width="280" height="31"/>
<rect key="frame" x="21" y="1650" width="280" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Soft Keyboard Toolbar" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="QdG-9a-5AZ" userLabel="softKeyboardToolbarStack">
@@ -821,6 +870,10 @@
<outlet property="framePacingSelector" destination="OOg-A3-DdM" id="XJL-lk-f5K"/>
<outlet property="framepacingStack" destination="9C2-td-rMV" id="5wc-qn-fo5"/>
<outlet property="framerateSelector" destination="8hF-kb-2uV" id="dfT-hb-csE"/>
<outlet property="gyroModeSelector" destination="aa5-3y-I4d" id="FsX-kH-h7w"/>
<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="hdrSwitch" destination="wIq-fF-X8l" id="Ozz-h0-nJL"/>
<outlet property="liftStreamViewForKeyboardSelector" destination="MM5-O0-vK3" id="tSC-Rp-Qfg"/>
<outlet property="liftStreamViewForKeyboardStack" destination="mes-so-dfK" id="nXR-Ot-Ydf"/>
@@ -1470,19 +1523,19 @@
<image name="tray.full.fill" catalog="system" width="128" height="88"/>
<image name="video.and.waveform" catalog="system" width="128" height="94"/>
<systemColor name="linkColor">
<color red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.0" green="0.47843137254901963" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="systemBrownColor">
<color red="0.63529411759999999" green="0.51764705879999995" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.63529411764705879" green="0.51764705882352946" blue="0.36862745098039218" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemGray3Color">
<color red="0.78039215689999997" green="0.78039215689999997" blue="0.80000000000000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.7803921568627451" green="0.7803921568627451" blue="0.80000000000000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemTealColor">
<color red="0.18823529410000001" green="0.69019607839999997" blue="0.78039215689999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.18823529411764706" green="0.69019607843137254" blue="0.7803921568627451" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
</resources>
</document>
+9 -1
View File
@@ -35,6 +35,14 @@ typedef NS_ENUM(NSInteger, TouchEventPriorityEnum) {
TouchMovePriority// deprecated by GUI
};
typedef NS_ENUM(NSInteger, GyroMode) {
GyroModeOff,
GyroModeAuto,
AlwaysDevice,
AlwaysController
};
typedef NS_ENUM(NSInteger, SettingsMenuMode) {
AllSettings,
FavoriteSettings,
@@ -47,7 +55,7 @@ typedef NS_ENUM(NSInteger, SettingsMenuMode) {
width:(NSInteger)width
audioConfig:(NSInteger)audioConfig
onscreenControls:(NSInteger)onscreenControls
motionMode:(NSInteger)motionMode
gyroMode:(NSInteger)gyroMode
keyboardToggleFingers:(NSInteger)keyboardToggleFingers
oscLayoutToolFingers:(NSInteger)oscLayoutToolFingers
slideToSettingsScreenEdge:(NSInteger)slideToSettingsScreenEdge
+2 -2
View File
@@ -61,7 +61,7 @@
width:(NSInteger)width
audioConfig:(NSInteger)audioConfig
onscreenControls:(NSInteger)onscreenControls
motionMode:(NSInteger)motionMode
gyroMode:(NSInteger)gyroMode
keyboardToggleFingers:(NSInteger)keyboardToggleFingers
oscLayoutToolFingers:(NSInteger)oscLayoutToolFingers
slideToSettingsScreenEdge:(NSInteger)slideToSettingsScreenEdge
@@ -100,7 +100,7 @@
settingsToSave.width = [NSNumber numberWithInteger:width];
settingsToSave.audioConfig = [NSNumber numberWithInteger:audioConfig];
settingsToSave.onscreenControls = [NSNumber numberWithInteger:onscreenControls];
settingsToSave.motionMode = [NSNumber numberWithInteger:motionMode];
settingsToSave.gyroMode = [NSNumber numberWithInteger:gyroMode];
settingsToSave.keyboardToggleFingers = [NSNumber numberWithInteger:(uint16_t)keyboardToggleFingers];
settingsToSave.oscLayoutToolFingers = [NSNumber numberWithInteger:(uint16_t)oscLayoutToolFingers];
settingsToSave.slideToSettingsScreenEdge = [NSNumber numberWithInteger:(uint32_t)slideToSettingsScreenEdge];
+1 -1
View File
@@ -25,7 +25,7 @@
@property (nonatomic, retain) NSNumber * width;
@property (nonatomic, retain) NSNumber * audioConfig;
@property (nonatomic, retain) NSNumber * onscreenControls;
@property (nonatomic, retain) NSNumber * motionMode;
@property (nonatomic, retain) NSNumber * gyroMode;
@property (nonatomic, retain) NSNumber * keyboardToggleFingers;
@property (nonatomic, retain) NSNumber * oscLayoutToolFingers;
@property (nonatomic, retain) NSNumber * slideToSettingsScreenEdge;
+1 -1
View File
@@ -89,7 +89,7 @@
self.multiController = settings.multiController;
self.swapABXYButtons = settings.swapABXYButtons;
self.onscreenControls = settings.onscreenControls;
self.motionMode = settings.motionMode;
self.gyroMode = settings.gyroMode;
self.reverseMouseWheelDirection = settings.reverseMouseWheelDirection;
self.asyncNativeTouchPriority = settings.asyncNativeTouchPriority;
self.btMouseSupport = settings.btMouseSupport;
Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

@@ -1,11 +1,13 @@
{
"images" : [
{
"filename" : "Icon-App-40x40@1x 2.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "Icon-App-20x20@3x 1.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
@@ -47,11 +49,13 @@
"size" : "60x60"
},
{
"filename" : "Icon-App-20x20@1x 1.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"filename" : "Icon-App-40x40@1x 1.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

+5
View File
@@ -59,4 +59,9 @@ typedef struct {
@property (nonatomic) BOOL reportedArrival;
@property (nonatomic) Controller* _Nullable mergedWithController;
@property(nonatomic, assign) uint8_t motionType;
@property(nonatomic, assign) uint16_t reportRateHz;
@property(nonatomic, assign) uint16_t controllerNumber;
@end
+2
View File
@@ -52,4 +52,6 @@
-(NSUInteger) getConnectedGamepadCount;
-(void)updateConfig:(StreamConfiguration*)streamConfig delegate:(id<ControllerSupportDelegate>)delegate;
@end
+297 -263
View File
@@ -52,7 +52,7 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
char _controllerNumbers;
bool _multiController;
bool _swapABXYButtons;
int _motionMode;
int _gyroMode;
bool _captureMouse;
}
@@ -92,189 +92,206 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
[controller.rightTriggerMotor setMotorAmplitude:rightTrigger];
}
- (void) setMotionEventState:(uint16_t)controllerNumber motionType:(uint8_t)motionType reportRateHz:(uint16_t)reportRateHz
{
-(void)updateTimerStateForController:(Controller* )controller{
if (@available(iOS 14.0, tvOS 14.0, *)) {
Controller* controller = [_controllers objectForKey:[NSNumber numberWithInteger:controllerNumber]];
#if !TARGET_OS_TV //tvOS has no device motion
NSInteger motionMode = _motionMode; //motionMode 0 = auto | 1 = always device | 2 = always controller
NSLog(@"motionMode: %ld", (long)motionMode);
if(motionMode !=2 && controllerNumber < 2){
if(controller == nil || controller.gamepad.motion == nil || motionMode == 1){
//Player has no controller *or* no motion for controller 1 *or* wants to override controller 1 motion with device motion
//using device motion
if (controller == nil) {
// No connected controller for this player, use the _oscController instead
controller = _oscController;
}
if(!controller.motionManager) {
controller.motionManager = [[CMMotionManager alloc] init];
}
NSLog(@"device gyro codes, gyroMode: %d", _gyroMode);
switch (motionType) {
case LI_MOTION_TYPE_ACCEL:
[controller.accelTimer invalidate];
controller.accelTimer = nil;
// Reset the last motion sample
CMAcceleration emptyDeviceAccelSample = {};
controller.lastDeviceAccelSample = emptyDeviceAccelSample;
{dispatch_sync(dispatch_get_main_queue(), ^{
controller.accelTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / reportRateHz repeats:YES block:^(NSTimer *timer) {
// Don't send duplicate samples
CMAcceleration lastDeviceAccelSample = controller.lastDeviceAccelSample;
CMAcceleration deviceAccelSample = controller.motionManager.deviceMotion.userAcceleration;
//userAcceleration does not contain gravity, add gravity to x, y and z values:
deviceAccelSample.x += controller.motionManager.deviceMotion.gravity.x;
deviceAccelSample.y += controller.motionManager.deviceMotion.gravity.y;
deviceAccelSample.z += controller.motionManager.deviceMotion.gravity.z;
if (memcmp(&deviceAccelSample, &lastDeviceAccelSample, sizeof(deviceAccelSample)) == 0) {
return;
}
controller.lastDeviceAccelSample = deviceAccelSample;
// Convert g to m/s^2
NSLog(@"gyro input no.1 %f", CACurrentMediaTime());
if(UIApplication.sharedApplication.windows.firstObject.windowScene.interfaceOrientation == 4){ //check for landscape left or landscape right
LiSendControllerMotionEvent((uint8_t)controllerNumber,
LI_MOTION_TYPE_ACCEL,
deviceAccelSample.y * -9.80665f,
deviceAccelSample.z * -9.80665f,
deviceAccelSample.x * -9.80665f);
}
else{
LiSendControllerMotionEvent((uint8_t)controllerNumber,
LI_MOTION_TYPE_ACCEL,
deviceAccelSample.y * +9.80665f,
deviceAccelSample.z * -9.80665f,
deviceAccelSample.x * +9.80665f);
}
}];
});}
break;
case LI_MOTION_TYPE_GYRO:
[controller.gyroTimer invalidate];
controller.gyroTimer = nil;
// Reset the last motion sample
CMRotationRate emptyDeviceGyroSample = {};
controller.lastDeviceGyroSample = emptyDeviceGyroSample;
[controller.motionManager startDeviceMotionUpdates];
dispatch_sync(dispatch_get_main_queue(), ^{
controller.gyroTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / reportRateHz repeats:YES block:^(NSTimer *timer) {
// Don't send duplicate samples
CMRotationRate lastDeviceGyroSample = controller.lastDeviceGyroSample;
CMRotationRate deviceGyroSample = controller.motionManager.deviceMotion.rotationRate;
if (memcmp(&deviceGyroSample, &lastDeviceGyroSample, sizeof(deviceGyroSample)) == 0) {
return;
}
controller.lastDeviceGyroSample = deviceGyroSample;
// Convert rad/s to deg/s
NSLog(@"gyro input no.2 %f", CACurrentMediaTime());
if(UIApplication.sharedApplication.windows.firstObject.windowScene.interfaceOrientation == 4){//check for landscape left or landscape right
LiSendControllerMotionEvent((uint8_t)controllerNumber,
LI_MOTION_TYPE_GYRO,
deviceGyroSample.y * 57.2957795f,
deviceGyroSample.z * 57.2957795f,
deviceGyroSample.x * 57.2957795f);
}
else{
LiSendControllerMotionEvent((uint8_t)controllerNumber,
LI_MOTION_TYPE_GYRO,
deviceGyroSample.y * -57.2957795f,
deviceGyroSample.z * 57.2957795f,
deviceGyroSample.x * -57.2957795f);
}
}];
});
break;
}
return;
}
}
#endif
switch (motionType) {
case LI_MOTION_TYPE_ACCEL:
[controller.accelTimer invalidate];
controller.accelTimer = nil;
if (reportRateHz && controller.gamepad.motion.hasGravityAndUserAcceleration) {
// Reset the last motion sample
GCAcceleration emptyAccelSample = {};
controller.lastAccelSample = emptyAccelSample;
dispatch_sync(dispatch_get_main_queue(), ^{
controller.accelTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / reportRateHz repeats:YES block:^(NSTimer *timer) {
// Don't send duplicate samples
GCAcceleration lastAccelSample = controller.lastAccelSample;
GCAcceleration accelSample = controller.gamepad.motion.acceleration;
if (memcmp(&accelSample, &lastAccelSample, sizeof(accelSample)) == 0) {
return;
}
controller.lastAccelSample = accelSample;
// Convert g to m/s^2
NSLog(@"gyro input no.3 %f", CACurrentMediaTime());
LiSendControllerMotionEvent((uint8_t)controllerNumber,
LI_MOTION_TYPE_ACCEL,
accelSample.x * -9.80665f,
accelSample.y * -9.80665f,
accelSample.z * -9.80665f);
}];
});
}
break;
case LI_MOTION_TYPE_GYRO:
[controller.gyroTimer invalidate];
controller.gyroTimer = nil;
if (reportRateHz && controller.gamepad.motion.hasRotationRate) {
// Reset the last motion sample
GCRotationRate emptyGyroSample = {};
controller.lastGyroSample = emptyGyroSample;
dispatch_sync(dispatch_get_main_queue(), ^{
controller.gyroTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / reportRateHz repeats:YES block:^(NSTimer *timer) {
// Don't send duplicate samples
GCRotationRate lastGyroSample = controller.lastGyroSample;
GCRotationRate gyroSample = controller.gamepad.motion.rotationRate;
if (memcmp(&gyroSample, &lastGyroSample, sizeof(gyroSample)) == 0) {
return;
}
controller.lastGyroSample = gyroSample;
// Convert rad/s to deg/s
NSLog(@"gyro input no.4 %f", CACurrentMediaTime());
LiSendControllerMotionEvent((uint8_t)controllerNumber,
LI_MOTION_TYPE_GYRO,
gyroSample.x * 57.2957795f,
gyroSample.z * 57.2957795f,
gyroSample.y * -57.2957795f);
}];
});
}
break;
if(_gyroMode == GyroModeOff){
[self stopTimerForController:controller];
return;
}
// Set the motion sensor state if they require manual activation
if (controller.gamepad.motion.sensorsRequireManualActivation) {
if (controller.gyroTimer || controller.accelTimer) {
controller.gamepad.motion.sensorsActive = YES;
}
else {
controller.gamepad.motion.sensorsActive = NO;
if(_gyroMode != AlwaysController && controller.controllerNumber < 2){
NSLog(@"device gyro codes");
#if !TARGET_OS_TV //tvOS has no device motion
if(controller.gamepad.motion == nil || _gyroMode == AlwaysDevice){
//Player has no controller *or* no motion for controller 1 *or* wants to override controller 1 motion with device motion
if(!controller.motionManager) {
controller.motionManager = [[CMMotionManager alloc] init];
}
NSLog(@"device gyro codes 2, motionType: %d", controller.motionType);
switch (controller.motionType) {
case LI_MOTION_TYPE_ACCEL:
[controller.accelTimer invalidate];
controller.accelTimer = nil;
// Reset the last motion sample
CMAcceleration emptyDeviceAccelSample = {};
controller.lastDeviceAccelSample = emptyDeviceAccelSample;
{dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"device gyro codes 3");
controller.accelTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / controller.reportRateHz repeats:YES block:^(NSTimer *timer) {
// Don't send duplicate samples
CMAcceleration lastDeviceAccelSample = controller.lastDeviceAccelSample;
CMAcceleration deviceAccelSample = controller.motionManager.deviceMotion.userAcceleration;
//userAcceleration does not contain gravity, add gravity to x, y and z values:
deviceAccelSample.x += controller.motionManager.deviceMotion.gravity.x;
deviceAccelSample.y += controller.motionManager.deviceMotion.gravity.y;
deviceAccelSample.z += controller.motionManager.deviceMotion.gravity.z;
if (memcmp(&deviceAccelSample, &lastDeviceAccelSample, sizeof(deviceAccelSample)) == 0) {
return;
}
controller.lastDeviceAccelSample = deviceAccelSample;
// Convert g to m/s^2
NSLog(@"gyro input no.1 %f", CACurrentMediaTime());
if(UIApplication.sharedApplication.windows.firstObject.windowScene.interfaceOrientation == 4){ //check for landscape left or landscape right
LiSendControllerMotionEvent((uint8_t)controller.controllerNumber,
LI_MOTION_TYPE_ACCEL,
deviceAccelSample.y * -9.80665f,
deviceAccelSample.z * -9.80665f,
deviceAccelSample.x * -9.80665f);
}
else{
LiSendControllerMotionEvent((uint8_t)controller.controllerNumber,
LI_MOTION_TYPE_ACCEL,
deviceAccelSample.y * +9.80665f,
deviceAccelSample.z * -9.80665f,
deviceAccelSample.x * +9.80665f);
}
}];
});}
break;
case LI_MOTION_TYPE_GYRO:
[controller.gyroTimer invalidate];
controller.gyroTimer = nil;
// Reset the last motion sample
CMRotationRate emptyDeviceGyroSample = {};
controller.lastDeviceGyroSample = emptyDeviceGyroSample;
[controller.motionManager startDeviceMotionUpdates];
dispatch_sync(dispatch_get_main_queue(), ^{
controller.gyroTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / controller.reportRateHz repeats:YES block:^(NSTimer *timer) {
// Don't send duplicate samples
CMRotationRate lastDeviceGyroSample = controller.lastDeviceGyroSample;
CMRotationRate deviceGyroSample = controller.motionManager.deviceMotion.rotationRate;
if (memcmp(&deviceGyroSample, &lastDeviceGyroSample, sizeof(deviceGyroSample)) == 0) {
return;
}
controller.lastDeviceGyroSample = deviceGyroSample;
// Convert rad/s to deg/s
NSLog(@"gyro input no.2 %f", CACurrentMediaTime());
if(UIApplication.sharedApplication.windows.firstObject.windowScene.interfaceOrientation == 4){//check for landscape left or landscape right
LiSendControllerMotionEvent((uint8_t)controller.controllerNumber,
LI_MOTION_TYPE_GYRO,
deviceGyroSample.y * 57.2957795f,
deviceGyroSample.z * 57.2957795f,
deviceGyroSample.x * 57.2957795f);
}
else{
LiSendControllerMotionEvent((uint8_t)controller.controllerNumber,
LI_MOTION_TYPE_GYRO,
deviceGyroSample.y * -57.2957795f,
deviceGyroSample.z * 57.2957795f,
deviceGyroSample.x * -57.2957795f);
}
}];
});
break;
}
}
}
#endif
else{
switch (controller.motionType) {
case LI_MOTION_TYPE_ACCEL:
[controller.accelTimer invalidate];
controller.accelTimer = nil;
if (controller.reportRateHz && controller.gamepad.motion.hasGravityAndUserAcceleration) {
// Reset the last motion sample
GCAcceleration emptyAccelSample = {};
controller.lastAccelSample = emptyAccelSample;
dispatch_sync(dispatch_get_main_queue(), ^{
controller.accelTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / controller.reportRateHz repeats:YES block:^(NSTimer *timer) {
// Don't send duplicate samples
GCAcceleration lastAccelSample = controller.lastAccelSample;
GCAcceleration accelSample = controller.gamepad.motion.acceleration;
if (memcmp(&accelSample, &lastAccelSample, sizeof(accelSample)) == 0) {
return;
}
controller.lastAccelSample = accelSample;
// Convert g to m/s^2
NSLog(@"gyro input no.3 %f", CACurrentMediaTime());
LiSendControllerMotionEvent((uint8_t)controller.controllerNumber,
LI_MOTION_TYPE_ACCEL,
accelSample.x * -9.80665f,
accelSample.y * -9.80665f,
accelSample.z * -9.80665f);
}];
});
}
break;
case LI_MOTION_TYPE_GYRO:
[controller.gyroTimer invalidate];
controller.gyroTimer = nil;
if (controller.reportRateHz && controller.gamepad.motion.hasRotationRate) {
// Reset the last motion sample
GCRotationRate emptyGyroSample = {};
controller.lastGyroSample = emptyGyroSample;
dispatch_sync(dispatch_get_main_queue(), ^{
controller.gyroTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / controller.reportRateHz repeats:YES block:^(NSTimer *timer) {
// Don't send duplicate samples
GCRotationRate lastGyroSample = controller.lastGyroSample;
GCRotationRate gyroSample = controller.gamepad.motion.rotationRate;
if (memcmp(&gyroSample, &lastGyroSample, sizeof(gyroSample)) == 0) {
return;
}
controller.lastGyroSample = gyroSample;
// Convert rad/s to deg/s
NSLog(@"gyro input no.4 %f", CACurrentMediaTime());
LiSendControllerMotionEvent((uint8_t)controller.controllerNumber,
LI_MOTION_TYPE_GYRO,
gyroSample.x * 57.2957795f,
gyroSample.z * 57.2957795f,
gyroSample.y * -57.2957795f);
}];
});
}
break;
}
}
}
}
- (void) setMotionEventState:(uint16_t)controllerNumber motionType:(uint8_t)motionType reportRateHz:(uint16_t)reportRateHz {
if (@available(iOS 14.0, tvOS 14.0, *)) {
NSLog(@"gyroMode: %ld", (long)_gyroMode);
Controller* controller = [_controllers objectForKey:[NSNumber numberWithInteger:controllerNumber]];
//using device motion
if (controller == nil) {
// No connected controller for this player, use the _oscController instead
controller = _oscController;
}
controller.motionType = motionType;
controller.reportRateHz = reportRateHz;
controller.controllerNumber = controllerNumber;
NSLog(@"device gyro codes 0, %d, og: %d, %@", controller.motionType, motionType, controller);
[self updateTimerStateForController:controller];
}
}
@@ -1201,16 +1218,11 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
return _controllers.count;
}
-(id) initWithConfig:(StreamConfiguration*)streamConfig delegate:(id<ControllerSupportDelegate>)delegate
{
self = [super init];
_controllerStreamLock = [[NSLock alloc] init];
_controllers = [[NSMutableDictionary alloc] init];
_controllerNumbers = 0;
-(void)updateConfig:(StreamConfiguration*)streamConfig delegate:(id<ControllerSupportDelegate>)delegate {
_multiController = streamConfig.multiController;
_swapABXYButtons = streamConfig.swapABXYButtons;
_motionMode = streamConfig.motionMode;
_gyroMode = streamConfig.gyroMode;
_delegate = delegate;
_oscController = [[Controller alloc] init];
@@ -1222,16 +1234,6 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
Log(LOG_I, @"Number of supported controllers connected: %d", [ControllerSupport getGamepadCount]);
Log(LOG_I, @"Multi-controller: %d", _multiController);
for (GCController* controller in [GCController controllers]) {
if ([ControllerSupport isSupportedGamepad:controller]) {
[self assignController:controller];
[self registerControllerCallbacks:controller];
// Note: We cannot report controller arrival to the host here,
// because the connection has not been established yet.
}
}
_captureMouse = (streamConfig.localMousePointerMode == 0);
if (@available(iOS 14.0, tvOS 14.0, *)) {
for (GCMouse* mouse in [GCMouse mice]) {
@@ -1239,73 +1241,6 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
}
}
_controllerConnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidConnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
Log(LOG_I, @"Controller connected!");
GCController* controller = note.object;
if (![ControllerSupport isSupportedGamepad:controller]) {
// Ignore micro gamepads and motion controllers
return;
}
Controller* limeController = [self assignController:controller];
if (limeController) {
// Register callbacks on the new controller
[self registerControllerCallbacks:controller];
// Report the controller arrival to the host if we're connected
[self reportControllerArrival:limeController];
// Re-evaluate the on-screen control mode
[self updateAutoOnScreenControlMode];
// Notify the delegate
[self->_delegate gamepadPresenceChanged];
}
}];
_controllerDisconnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidDisconnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
Log(LOG_I, @"Controller disconnected!");
GCController* controller = note.object;
if (![ControllerSupport isSupportedGamepad:controller]) {
// Ignore micro gamepads and motion controllers
return;
}
[self unregisterControllerCallbacks:controller];
self->_controllerNumbers &= ~(1 << controller.playerIndex);
Log(LOG_I, @"Unassigning controller index: %ld", (long)controller.playerIndex);
Controller* limeController = [self->_controllers objectForKey:[NSNumber numberWithInteger:controller.playerIndex]];
if (limeController) {
// Stop haptics on this controller
[self cleanupControllerHaptics:limeController];
// Stop motion reports on this controller
[self cleanupControllerMotion:limeController];
// Stop battery reports on this controller
[self cleanupControllerBattery:limeController];
// Disassociate this controller from any controllers merged with it
if (limeController.mergedWithController) {
assert(limeController.mergedWithController.mergedWithController == limeController);
limeController.mergedWithController.mergedWithController = nil;
}
// Inform the server of the updated active gamepads before removing this controller
[self updateFinished:limeController];
[self->_controllers removeObjectForKey:[NSNumber numberWithInteger:controller.playerIndex]];
// Re-evaluate the on-screen control mode
[self updateAutoOnScreenControlMode];
// Notify the delegate
[self->_delegate gamepadPresenceChanged];
}
}];
if (@available(iOS 14.0, tvOS 14.0, *)) {
_mouseConnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCMouseDidConnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
@@ -1348,8 +1283,99 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
// Re-evaluate the on-screen control mode
[self updateAutoOnScreenControlMode];
}];
NSLog(@"device gyro codes,update gyroMode: %d, controller count: %lu", _gyroMode, (unsigned long)_controllers.count);
for(Controller* controller in _controllers) [self updateTimerStateForController:controller];
}
}
-(id)initWithConfig:(StreamConfiguration*)streamConfig delegate:(id<ControllerSupportDelegate>)delegate
{
self = [super init];
_controllerNumbers = 0;
_controllerStreamLock = [[NSLock alloc] init];
_controllers = [[NSMutableDictionary alloc] init];
for (GCController* controller in [GCController controllers]) {
if ([ControllerSupport isSupportedGamepad:controller]) {
[self assignController:controller];
[self registerControllerCallbacks:controller];
// Note: We cannot report controller arrival to the host here,
// because the connection has not been established yet.
}
}
_controllerConnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidConnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
Log(LOG_I, @"Controller connected!");
GCController* controller = note.object;
if (![ControllerSupport isSupportedGamepad:controller]) {
// Ignore micro gamepads and motion controllers
return;
}
Controller* limeController = [self assignController:controller];
if (limeController) {
// Register callbacks on the new controller
[self registerControllerCallbacks:controller];
// Report the controller arrival to the host if we're connected
[self reportControllerArrival:limeController];
// Re-evaluate the on-screen control mode
[self updateAutoOnScreenControlMode];
// Notify the delegate
[self->_delegate gamepadPresenceChanged];
}
}];
_controllerDisconnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidDisconnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
Log(LOG_I, @"Controller disconnected!");
GCController* controller = note.object;
if (![ControllerSupport isSupportedGamepad:controller]) {
// Ignore micro gamepads and motion controllers
return;
}
[self unregisterControllerCallbacks:controller];
self->_controllerNumbers &= ~(1 << controller.playerIndex);
Log(LOG_I, @"Unassigning controller index: %ld", (long)controller.playerIndex);
Controller* limeController = [self->_controllers objectForKey:[NSNumber numberWithInteger:controller.playerIndex]];
if (limeController) {
// Stop haptics on this controller
[self cleanupControllerHaptics:limeController];
// Stop motion reports on this controller
[self cleanupControllerMotion:limeController];
// Stop battery reports on this controller
[self cleanupControllerBattery:limeController];
// Disassociate this controller from any controllers merged with it
if (limeController.mergedWithController) {
assert(limeController.mergedWithController.mergedWithController == limeController);
limeController.mergedWithController.mergedWithController = nil;
}
// Inform the server of the updated active gamepads before removing this controller
[self updateFinished:limeController];
// Re-evaluate the on-screen control mode
[self updateAutoOnScreenControlMode];
// Notify the delegate
[self->_delegate gamepadPresenceChanged];
}
}];
[self updateConfig:streamConfig delegate:delegate];
return self;
}
@@ -1361,6 +1387,13 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
}
}
-(void)stopTimerForController:(Controller* )controller{
[controller.accelTimer invalidate];
controller.accelTimer = nil;
[controller.gyroTimer invalidate];
controller.gyroTimer = nil;
}
-(void) cleanup
{
[[NSNotificationCenter defaultCenter] removeObserver:_controllerConnectObserver];
@@ -1380,6 +1413,7 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
_controllerNumbers = 0;
for (Controller* controller in [_controllers allValues]) {
[self stopTimerForController:controller];
[self cleanupControllerHaptics:controller];
[self cleanupControllerMotion:controller];
[self cleanupControllerBattery:controller];
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="23602" systemVersion="24C5089c" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="23788.4" systemVersion="24F74" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<entity name="App" representedClassName="App" syncable="YES" codeGenerationType="class">
<attribute name="hdrSupported" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="hidden" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
@@ -21,18 +21,18 @@
<relationship name="appList" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="App" inverseName="host" inverseEntity="App" syncable="YES"/>
</entity>
<entity name="Settings" representedClassName="Settings" syncable="YES" codeGenerationType="class">
<attribute name="asyncNativeTouchPriority" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="audioConfig" attributeType="Integer 32" defaultValueString="2" usesScalarValueType="NO" syncable="YES"/>
<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="deviceGyroMode" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="enableHdr" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="enableYUV444" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="externalDisplayMode" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="externalDisplayMode" optional="YES" attributeType="Integer 16" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
<attribute name="framerate" attributeType="Integer 32" defaultValueString="60" usesScalarValueType="NO" syncable="YES"/>
<attribute name="gyroMode" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="height" attributeType="Integer 32" defaultValueString="720" usesScalarValueType="NO" syncable="YES"/>
<attribute name="motionMode" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="keyboardToggleFingers" optional="YES" attributeType="Integer 16" defaultValueString="3" usesScalarValueType="NO" syncable="YES"/>
<attribute name="largerStickLR1" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="liftStreamViewForKeyboard" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="localMousePointerMode" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="mousePointerVelocityFactor" optional="YES" attributeType="Float" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
@@ -40,23 +40,25 @@
<attribute name="onscreenControls" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
<attribute name="optimizeGames" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="oscLayoutToolFingers" optional="YES" attributeType="Integer 16" defaultValueString="4" usesScalarValueType="NO" syncable="YES"/>
<attribute name="oscTapExlusionAreaSize" optional="YES" attributeType="Float" defaultValueString="1.03" usesScalarValueType="NO" syncable="YES"/>
<attribute name="playAudioOnPC" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="pointerVelocityModeDivider" optional="YES" attributeType="Float" defaultValueString="0.5" usesScalarValueType="NO" syncable="YES"/>
<attribute name="preferredCodec" attributeType="Integer 32" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="resolutionSelected" optional="YES" attributeType="Integer 16" defaultValueString="5" usesScalarValueType="NO" syncable="YES"/>
<attribute name="reverseMouseWheelDirection" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="settingsMenuMode" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="settingsMenuWidth" attributeType="Float" defaultValueString="370" usesScalarValueType="NO" syncable="YES"/>
<attribute name="showKeyboardToolbar" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="slideToSettingsDistance" optional="YES" attributeType="Float" defaultValueString="0.5" usesScalarValueType="NO" syncable="YES"/>
<attribute name="slideToSettingsDistance" optional="YES" attributeType="Float" defaultValueString="0.25" usesScalarValueType="NO" syncable="YES"/>
<attribute name="slideToSettingsScreenEdge" optional="YES" attributeType="Integer 32" defaultValueString="2" usesScalarValueType="NO" syncable="YES"/>
<attribute name="statsOverlayEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="statsOverlayLevel" optional="YES" attributeType="Integer 16" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
<attribute name="swapABXYButtons" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="touchMode" optional="YES" attributeType="Integer 16" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
<attribute name="touchMoveEventInterval" optional="YES" attributeType="Integer 16" defaultValueString="320" usesScalarValueType="NO" syncable="YES"/>
<attribute name="touchPointerVelocityFactor" optional="YES" attributeType="Float" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
<attribute name="uniqueId" attributeType="String" syncable="YES"/>
<attribute name="unlockDisplayOrientation" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="useFramePacing" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="width" attributeType="Integer 32" defaultValueString="1280" usesScalarValueType="NO" syncable="YES"/>
</entity>
</model>
</model>
+172 -4
View File
@@ -703,6 +703,35 @@
}
}
},
"bitrateStackTip" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Only increase the bitrate if your network is capable, be particularly careful above 50 Mbps."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "调高码率, 尤其是超过50Mbps时, 请确保具备相应网络条件."
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "调高码率, 尤其是超过50Mbps时, 请确保具备相应网络条件."
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "调高码率, 尤其是超过50Mbps时, 请确保具备相应网络条件."
}
}
}
},
"Border Width" : {
"extractionState" : "manual",
"localizations" : {
@@ -2717,6 +2746,64 @@
}
}
},
"pointerVelocityDividerStackTip" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sensitivity divider line: used to separate the pass-through zone from the adjustment zone for touch-point movement speed in multi-touch games (e.g. Genshin Impact, Honkai: Star Rail). For details, see the online documentation."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "灵敏度分割线, 用于划分多点触控游戏(原神/崩坏星穹铁道)中触点移速的透传区域和调整区域. 详见在线文档."
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "灵敏度分割线, 用于划分多点触控游戏(原神/崩坏星穹铁道)中触点移速的透传区域和调整区域. 详见在线文档."
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "灵敏度分割线, 用于划分多点触控游戏(原神/崩坏星穹铁道)中触点移速的透传区域和调整区域. 详见在线文档."
}
}
}
},
"pointerVelocityFactorStackTip" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Touch Sensitivity: Adjusts the movement speed of touch points on the right half of the screen, allowing you to control in-game camera sensitivity (for Genshin Impact & Honkai: Star Rail). See the online documentation for details."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "触点灵敏度, 用于调节右半屏触点的移速, 进而实现(原神/崩坏星穹铁道)游戏内视角转动的灵敏度调节.详见在线文档."
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "触点灵敏度, 用于调节右半屏触点的移速, 进而实现(原神/崩坏星穹铁道)游戏内视角转动的灵敏度调节.详见在线文档."
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "触点灵敏度, 用于调节右半屏触点的移速, 进而实现(原神/崩坏星穹铁道)游戏内视角转动的灵敏度调节.详见在线文档."
}
}
}
},
"Poor connection to PC" : {
"extractionState" : "manual",
"localizations" : {
@@ -3672,6 +3759,29 @@
}
}
},
"Tips" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "提示"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "提示"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "提示"
}
}
}
},
"To Toggle Local Keyboard: Tap %d Fingers" : {
"extractionState" : "manual",
"localizations" : {
@@ -3701,25 +3811,25 @@
}
}
},
"Touch Control" : {
"Touch & Control" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "触控"
"value" : "触屏与控制"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "触控"
"value" : "触屏与控制"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "触控"
"value" : "触屏与控制"
}
}
}
@@ -3862,6 +3972,35 @@
}
}
},
"touchModeStackTip" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "- Touchpad: Dragging works exactly like on Windows laptop touchpad. A quick double-tap, starting from the second tap, enters drag mode.\n\n- Native Touch: Aka multi-touch passthrough, not supported on macOS.\n\n- Absolute Touch: Provides a touchscreen-like experience on macOS."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "- 触控板: 拖移方式与Windows笔记本电脑触控板相同, 快速双击的第2下开始进入拖动状态.\n\n- 多点触控: 不支持macOS.\n\n- 单点鼠标: 可为macOS提供类触屏体验."
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "- 触控板: 拖移方式与Windows笔记本电脑触控板相同, 快速双击的第2下开始进入拖动状态.\n\n- 多点触控: 不支持macOS.\n\n- 单点鼠标: 可为macOS提供类触屏体验."
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "- 触控板: 拖移方式与Windows笔记本电脑触控板相同, 快速双击的第2下开始进入拖动状态.\n\n- 多点触控: 不支持macOS.\n\n- 单点鼠标: 可为macOS提供类触屏体验."
}
}
}
},
"Unsupported on this device" : {
"extractionState" : "manual",
"localizations" : {
@@ -4074,6 +4213,35 @@
}
}
}
},
"yuv444StackTip" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "- Enabling the YUV 4:4:4 option provides higher color fidelity but also requires greater bandwidth.\n\n- Since Apple does not provide an API to determine whether a device supports hardware decoding of YUV 4:4:4 video, you will need to enable this option manually to verify compatibility. On some devices, this may cause issues such as loss of video brightness."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "- 开启YUV 4:4:4 选项可提供更高色彩保真度, 但对带宽要求也更高. \n\n- 由于Apple并未提供API判断设备是否支持YUV 4:4:4视频硬解码, 您需要自行打开该选项确认是否可用. 某些设备会因此产生视频亮度丢失的问题."
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "- 开启YUV 4:4:4 选项可提供更高色彩保真度, 但对带宽要求也更高. \n\n- 由于Apple并未提供API判断设备是否支持YUV 4:4:4视频硬解码, 您需要自行打开该选项确认是否可用. 某些设备会因此产生视频亮度丢失的问题."
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "- 开启YUV 4:4:4 选项可提供更高色彩保真度, 但对带宽要求也更高. \n\n- 由于Apple并未提供API判断设备是否支持YUV 4:4:4视频硬解码, 您需要自行打开该选项确认是否可用. 某些设备会因此产生视频亮度丢失的问题."
}
}
}
}
},
"version" : "1.0"
+5 -2
View File
@@ -5,6 +5,9 @@
// Created by Diego Waxemberg on 10/20/14.
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
//
// Modified by True砖家 since 2024.8.10
// Copyright © 2024 True砖家 @ Bilibili. All rights reserved.
//
@interface StreamConfiguration : NSObject
@@ -27,8 +30,8 @@
@property BOOL optimizeGameSettings;
@property BOOL playAudioOnPC;
@property BOOL swapABXYButtons;
@property int motionMode;
@property BOOL largerStickLR1;
@property BOOL asyncNativeTouchPriority;
@property int gyroMode;
@property int audioConfiguration;
@property int supportedVideoFormats;
@property BOOL multiController;
+1 -1
View File
@@ -9,5 +9,5 @@
#import "StreamConfiguration.h"
@implementation StreamConfiguration
@synthesize host, httpsPort, appID, width, height, frameRate, bitRate, riKeyId, riKey, gamepadMask, appName, optimizeGameSettings, playAudioOnPC, swapABXYButtons, motionMode, audioConfiguration, supportedVideoFormats, multiController, serverCert, rtspSessionUrl, serverCodecModeSupport, enableYUV444;
@synthesize host, httpsPort, appID, width, height, frameRate, bitRate, riKeyId, riKey, gamepadMask, appName, optimizeGameSettings, playAudioOnPC, swapABXYButtons, gyroMode, audioConfiguration, supportedVideoFormats, multiController, serverCert, rtspSessionUrl, serverCodecModeSupport, enableYUV444;
@end
File diff suppressed because it is too large Load Diff
@@ -98,6 +98,13 @@
@property (strong, nonatomic) IBOutlet UISegmentedControl *externalDisplayModeSelector;
@property (strong, nonatomic) IBOutlet UISegmentedControl *localMousePointerModeSelector;
@property (strong, nonatomic) IBOutlet UIStackView *gyroModeStack;
@property (strong, nonatomic) IBOutlet UISegmentedControl *gyroModeSelector;
@property (strong, nonatomic) IBOutlet UIStackView *gyroSensitivityStack;
@property (strong, nonatomic) IBOutlet UISlider *gyroSensitivitySlider;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability"
@@ -501,7 +501,7 @@ BOOL isCustomResolution(CGSize res) {
touchControlSection = [[MenuSectionView alloc] init];
touchControlSection.delegate = self;
touchControlSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Touch Control"];
touchControlSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Touch & Control"];
if (@available(iOS 13.0, *)) {
[touchControlSection setSectionWithIcon:[UIImage imageNamed:@"arcade.stick.console"] andSize:20.5];
}
@@ -511,6 +511,9 @@ BOOL isCustomResolution(CGSize res) {
[self addSetting:self.mousePointerVelocityStack ofId:@"mousePointerVelocityStack" withInfoTag:NO withDynamicLabel:YES to:touchControlSection];
[self addSetting:self.onScreenWidgetStack ofId:@"onScreenWidgetStack" withInfoTag:YES withDynamicLabel:YES to:touchControlSection];
[self addSetting:self.swapAbaxyStack ofId:@"swapAbaxyStack" withInfoTag:NO withDynamicLabel:NO to:touchControlSection];
[self addSetting:self.gyroModeStack ofId:@"gyroModeStack" withInfoTag:YES withDynamicLabel:NO to:touchControlSection];
[self addSetting:self.gyroSensitivityStack ofId:@"gyroSensitivityStack" withInfoTag:NO withDynamicLabel:YES to:touchControlSection];
[touchControlSection addToParentStack:_parentStack];
[touchControlSection setExpanded:YES];
@@ -977,10 +980,52 @@ BOOL isCustomResolution(CGSize res) {
- (void)infoButtonTapped:(UIButton* )sender{
NSString* tipText = [NSString stringWithFormat:@"dummy text for setting stack: %@", sender.superview.accessibilityIdentifier];
NSString* tipText = @"";
bool showOnlineDocAction = false;
tipText = sender.superview.accessibilityIdentifier;
if([sender.superview.accessibilityIdentifier isEqualToString: @"bitrateStack"]){
tipText = [LocalizationHelper localizedStringForKey:@"bitrateStackTip"];
showOnlineDocAction = false;
}
if([sender.superview.accessibilityIdentifier isEqualToString: @"yuv444Stack"]){
tipText = [LocalizationHelper localizedStringForKey:@"yuv444StackTip"];
showOnlineDocAction = true;
}
if([sender.superview.accessibilityIdentifier isEqualToString: @"touchModeStack"]){
tipText = [LocalizationHelper localizedStringForKey:@"touchModeStackTip"];
showOnlineDocAction = false;
}
if([sender.superview.accessibilityIdentifier isEqualToString: @"pointerVelocityDividerStack"]){
tipText = [LocalizationHelper localizedStringForKey:@"pointerVelocityDividerStackTip"];
showOnlineDocAction = true;
}
if([sender.superview.accessibilityIdentifier isEqualToString: @"pointerVelocityFactorStack"]){
tipText = [LocalizationHelper localizedStringForKey:@"pointerVelocityFactorStackTip"];
showOnlineDocAction = true;
}
UIAlertController *tipsAlertController = [UIAlertController alertControllerWithTitle: [LocalizationHelper localizedStringForKey:@"Tips"] message: [LocalizationHelper localizedStringForKey:@"%@", tipText] preferredStyle:UIAlertControllerStyleAlert];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.alignment = NSTextAlignmentLeft;
NSDictionary *attributes = @{
NSParagraphStyleAttributeName: paragraphStyle,
NSFontAttributeName: [UIFont systemFontOfSize:14]
};
NSAttributedString *attributedMessage = [[NSAttributedString alloc] initWithString:tipText
attributes:attributes];
// 使用 KVC 设置 attributedMessage(注意审核风险)
[tipsAlertController setValue:attributedMessage forKey:@"attributedMessage"];
UIAlertAction *readInstruction = [UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Online Documentation"]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action){
@@ -989,11 +1034,15 @@ BOOL isCustomResolution(CGSize res) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
}
}];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"OK"]
style:UIAlertActionStyleDefault
handler:nil];
[tipsAlertController addAction:readInstruction];
if(showOnlineDocAction) [tipsAlertController addAction:readInstruction];
[tipsAlertController addAction:okAction];
[self presentViewController:tipsAlertController animated:YES completion:nil];
}
@@ -1292,6 +1341,8 @@ BOOL isCustomResolution(CGSize res) {
[self.framePacingSelector setSelectedSegmentIndex:currentSettings.useFramePacing ? 1 : 0];
[self.multiControllerSwitch setOn:currentSettings.multiController];
[self.swapABXYButtonsSelector setSelectedSegmentIndex:currentSettings.swapABXYButtons ? 1 : 0];
[self.gyroModeSelector setSelectedSegmentIndex:currentSettings.gyroMode.intValue];
[self.audioOnPcSwitch setOn:currentSettings.playAudioOnPC];
_lastSelectedResolutionIndex = resolution;
[self.resolutionSelector setSelectedSegmentIndex:resolution];
@@ -1986,6 +2037,7 @@ BOOL isCustomResolution(CGSize res) {
BOOL optimizeGames = self.optimizeGamesSwitch.isOn;
BOOL multiController = self.multiControllerSwitch.isOn;
BOOL swapABXYButtons = [self.swapABXYButtonsSelector selectedSegmentIndex] == 1;
NSInteger gyroMode = self.gyroModeSelector.selectedSegmentIndex;
BOOL audioOnPC = self.audioOnPcSwitch.isOn;
uint32_t preferredCodec = [self getChosenCodecPreference];
BOOL enableYUV444 = self.yuv444Switch.isOn;
@@ -2005,6 +2057,7 @@ BOOL isCustomResolution(CGSize res) {
width:width
audioConfig:2 // Stereo
onscreenControls:onscreenControls
gyroMode:gyroMode
keyboardToggleFingers:keyboardToggleFingers
oscLayoutToolFingers:oscLayoutToolFingers
slideToSettingsScreenEdge:slideToSettingsScreenEdge
@@ -195,7 +195,7 @@
[self->_streamView disableOnScreenControls]; //don't know why but this must be called outside the streamview class, just put it here. execute in streamview class cause hang
[self.mainFrameViewcontroller reloadStreamConfig]; // reload streamconfig
_controllerSupport = [[ControllerSupport alloc] initWithConfig:self.streamConfig delegate:self]; // reload controllerSupport obj, this is mandatory for OSC reload,especially when the stream view is launched without OSC
[_controllerSupport updateConfig:self.streamConfig delegate:self];// reload controllerSupport obj, this is mandatory for OSC reload,especially when the stream view is launched without OSC
[_streamView setupStreamView:_controllerSupport interactionDelegate:self config:self.streamConfig streamFrameTopLayerView:self.view]; //reinitiate setupStreamView process.
// we got self.view passed to streamView class as the topLayerView, will be useful in many cases
[self->_streamView reloadOnScreenControlsRealtimeWith:(ControllerSupport*)_controllerSupport
@@ -525,7 +525,9 @@
- (void)willMoveToParentViewController:(UIViewController *)parent {
// Only cleanup when we're being destroyed
if (parent == nil) {
//NSLog(@"gyro cleanup, count: %ld", _controller.count);
[_controllerSupport cleanup];
[UIApplication sharedApplication].idleTimerDisabled = NO;
[_streamMan stopStream];
if (_inactivityTimer != nil) {
File diff suppressed because it is too large Load Diff