- feat: controller gyro button (toggle & hold)

- feat: synthesize physical stick input with gyro
This commit is contained in:
TrueZhuanjia
2025-11-26 11:48:34 +08:00
parent d7bc73250d
commit 379d965769
17 changed files with 1156 additions and 102 deletions
+33 -6
View File
@@ -1721,7 +1721,7 @@
<rect key="frame" x="852" y="899" width="380" height="55.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Pointer Velocity" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Xnd-C4-8N9" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="380" height="21"/>
<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"/>
@@ -1741,7 +1741,7 @@
<rect key="frame" x="852" y="974" width="380" height="55.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Curve Exponent" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6Cy-aH-DXp" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="380" height="21"/>
<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"/>
@@ -1757,6 +1757,31 @@
<constraint firstAttribute="height" constant="55.5" id="kLV-xF-5SV"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="v6i-HA-XRx">
<rect key="frame" x="440" y="1405" width="380" height="56.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Switch Gyro by Controller" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="26O-xW-5EH">
<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="OWG-zd-e3I">
<rect key="frame" x="0.0" y="25.5" width="380" height="32"/>
<segments>
<segment title="Disabled"/>
<segment title="Press-toggle"/>
<segment title="Hold down"/>
</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="loF-uJ-Fuw"/>
<constraint firstAttribute="width" constant="380" id="qOk-ee-a8A"/>
</constraints>
</stackView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
@@ -1781,6 +1806,8 @@
<outlet property="citrixX1MouseSwitch" destination="GQM-NR-WIO" id="RNm-18-mrK"/>
<outlet property="codecSelector" destination="aFy-0w-YPe" id="DlU-0l-gwz"/>
<outlet property="codecStack" destination="gWg-BF-yDI" id="GGc-JQ-N8y"/>
<outlet property="controllerGyroSwitchButtonSetter" destination="OWG-zd-e3I" id="XSf-09-DRc"/>
<outlet property="controllerGyroSwitchButtonStack" destination="v6i-HA-XRx" id="cZv-P9-05B"/>
<outlet property="controllerMouseExpoSlider" destination="ciD-6k-n6o" id="HzO-8E-u9N"/>
<outlet property="controllerMouseExpoStack" destination="5gN-F1-wWR" id="hgt-xH-dts"/>
<outlet property="controllerMouseVelocitySlider" destination="w6S-nD-AXU" id="rws-D6-zMT"/>
@@ -2733,7 +2760,7 @@
<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.47843137254901963" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="secondarySystemGroupedBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@@ -2742,13 +2769,13 @@
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="systemBrownColor">
<color red="0.67450980392156867" green="0.49803921568627452" blue="0.36862745098039218" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.63529411759999999" green="0.51764705879999995" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemGray3Color">
<color red="0.7803921568627451" green="0.7803921568627451" blue="0.80000000000000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.78039215689999997" green="0.78039215689999997" blue="0.80000000000000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemTealColor">
<color red="0.0" green="0.76470588235294112" blue="0.81568627450980391" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.18823529410000001" green="0.69019607839999997" blue="0.78039215689999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
</resources>
</document>
+31 -4
View File
@@ -2284,16 +2284,16 @@
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="N0i-z6-WgC" userLabel="singleTapSensitivityStack">
<rect key="frame" x="437" y="2383" width="596" height="55.5"/>
<rect key="frame" x="437" y="2383" width="380" height="55.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Single Tap Sensitivity" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WzD-wo-Wum">
<rect key="frame" x="0.0" y="0.0" width="596" height="20.5"/>
<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="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<slider verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="2" minValue="0.0" maxValue="5" minimumValueImage="0.square" catalog="system" maximumValueImage="5.square" translatesAutoresizingMaskIntoConstraints="NO" id="uCa-Oa-7mv" userLabel="Single Tap Sensitivity Slider">
<rect key="frame" x="0.0" y="25.5" width="596" height="30"/>
<rect key="frame" x="0.0" y="25.5" width="380" height="30"/>
<constraints>
<constraint firstAttribute="height" constant="30" id="XXP-GP-uhn"/>
</constraints>
@@ -2590,6 +2590,31 @@
<constraint firstAttribute="width" constant="380" id="mG1-Vg-QwM"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="5fm-3b-ixg">
<rect key="frame" x="437" y="594" width="380" height="56.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Switch Gyro by Controller" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bAZ-bm-h3I">
<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="mpa-8g-1Ug">
<rect key="frame" x="0.0" y="25.5" width="380" height="32"/>
<segments>
<segment title="Disabled"/>
<segment title="Press-toggle"/>
<segment title="Hold down"/>
</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="Ign-NM-9UD"/>
<constraint firstAttribute="height" constant="56.5" id="MNC-Cn-lnb"/>
</constraints>
</stackView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
@@ -2614,6 +2639,8 @@
<outlet property="citrixX1MouseSwitch" destination="zw9-ok-nQC" id="5w4-2h-gCP"/>
<outlet property="codecSelector" destination="5Y7-To-ca2" id="Kmt-sp-eXj"/>
<outlet property="codecStack" destination="cVe-Uk-gXv" id="826-Tv-rMl"/>
<outlet property="controllerGyroSwitchButtonSetter" destination="mpa-8g-1Ug" id="2y0-jr-5mh"/>
<outlet property="controllerGyroSwitchButtonStack" destination="5fm-3b-ixg" id="Rkn-t7-opn"/>
<outlet property="controllerMouseExpoSlider" destination="scG-Rx-agb" id="K6s-eG-Zcu"/>
<outlet property="controllerMouseExpoStack" destination="QuI-NM-qCU" id="Kmp-Cc-bWI"/>
<outlet property="controllerMouseVelocitySlider" destination="CkB-cG-N8r" id="AMa-cl-2Wz"/>
@@ -2756,7 +2783,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iqb-Sd-6g2" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-3268" y="1032"/>
<point key="canvasLocation" x="-3268.115942028986" y="1031.9196428571429"/>
</scene>
</scenes>
<resources>
+7
View File
@@ -21,6 +21,12 @@ typedef NS_ENUM(NSUInteger, UINavigationBarHeight) {
UINavigationBarHeightIPhone = 44
};
typedef NS_ENUM(NSInteger, ControllerGyroSwitchMode) {
ControllerGyroSwitchDisabled,
ControllerGyroSwitchPressToToggle,
ControllerGyroSwitchHoldDown
};
typedef NS_ENUM(NSInteger, AudioEngine) {
SystemAudioEngine,
SDLAudioEngine
@@ -145,6 +151,7 @@ typedef NS_ENUM(NSInteger, WidgetSizeTransition) {
mapControllerToMouse:(BOOL)mapControllerToMouse
controllerMousePointerVelocity:(CGFloat)controllerMousePointerVelocity
controllerMouseExpo:(CGFloat)controllerMouseExpo
controllerGyroSwitchMode:(NSInteger)controllerGyroSwitchMode
backgroundSessionTimer:(NSInteger)backgroundSessionTimer;
- (NSArray*) getHosts;
+2
View File
@@ -123,6 +123,7 @@
mapControllerToMouse:(BOOL)mapControllerToMouse
controllerMousePointerVelocity:(CGFloat)controllerMousePointerVelocity
controllerMouseExpo:(CGFloat)controllerMouseExpo
controllerGyroSwitchMode:(NSInteger)controllerGyroSwitchMode
backgroundSessionTimer:(NSInteger)backgroundSessionTimer{
[_managedObjectContext performBlockAndWait:^{
@@ -196,6 +197,7 @@
settingsToSave.mapControllerToMouse = mapControllerToMouse;
settingsToSave.controllerMousePointerVelocity = [NSNumber numberWithFloat:controllerMousePointerVelocity];
settingsToSave.controllerMouseExpo = [NSNumber numberWithFloat:controllerMouseExpo];
settingsToSave.controllerGyroSwitchMode = [NSNumber numberWithInteger:controllerGyroSwitchMode];
settingsToSave.rememberFoldState = rememberFoldState;
[self saveData];
}];
+3
View File
@@ -102,6 +102,9 @@
@property (nonatomic) BOOL mapControllerToMouse;
@property (nonatomic, retain) NSNumber * controllerMousePointerVelocity;
@property (nonatomic, retain) NSNumber * controllerMouseExpo;
@property (nonatomic, retain) NSNumber * controllerGyroSwitchToggle;
@property (nonatomic, retain) NSNumber * controllerGyroSwitchHold;
@property (nonatomic, retain) NSNumber * controllerGyroSwitchMode;
- (id) initFromSettings:(Settings*)settings;
+3
View File
@@ -158,6 +158,9 @@
self.controllerMouseStick = settings.controllerMouseStick;
self.controllerMousePointerVelocity = settings.controllerMousePointerVelocity;
self.controllerMouseExpo = settings.controllerMouseExpo;
self.controllerGyroSwitchToggle = settings.controllerGyroSwitchToggle;
self.controllerGyroSwitchHold = settings.controllerGyroSwitchHold;
self.controllerGyroSwitchMode = settings.controllerGyroSwitchMode;
#endif
+151 -45
View File
@@ -72,7 +72,9 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
VoidController *_oscController;
NSMutableSet* _activeGCControllers;
TemporarySettings* tempSettings;
OSCProfilesManager* oscProfileMan;
OSCProfile* oscProfile;
#define EMULATING_SELECT 0x1
#define EMULATING_SPECIAL 0x2
@@ -83,6 +85,16 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
int _gyroMode;
CGFloat _gyroSensitivity;
bool _captureMouse;
bool _startGyroByController;
bool _gyroEnabledFlag;
int _controllerGyroSwitchToggle;
int _controllerGyroSwitchHold;
bool _controllerGyroSwitchTogglePressed;
bool _controllerGyroSwitchHoldPressed;
ControllerGyroSwitchMode _gyroSwitchMode;
MotionHandler* motionHandler;
}
// UPDATE_BUTTON_FLAG(controller, flag, pressed)
@@ -243,30 +255,68 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
voidController.lastDeviceGyroSample = deviceGyroSample;
// Convert rad/s to deg/s
//NSLog(@"sending built-in gyro data, accelSample data 00: %f, playerIndex: %d",deviceGyroSample.x, voidController.playerIndex);
UIInterfaceOrientation interfaceOrientation = UIInterfaceOrientationUnknown;
if (@available(iOS 13.0, *)) {
if(UIApplication.sharedApplication.windows.firstObject.windowScene.interfaceOrientation == 4){//check for landscape left or landscape right
interfaceOrientation = UIApplication.sharedApplication.windows.firstObject.windowScene.interfaceOrientation;
} else {
interfaceOrientation = UIApplication.sharedApplication.statusBarOrientation;
}
switch (interfaceOrientation) {
case UIInterfaceOrientationLandscapeLeft:
LiSendControllerMotionEvent((uint8_t)voidController.controllerNumber,
LI_MOTION_TYPE_GYRO,
deviceGyroSample.y * 57.2957795f * self->_gyroSensitivity,
deviceGyroSample.z * 57.2957795f * self->_gyroSensitivity,
deviceGyroSample.x * 57.2957795f * self->_gyroSensitivity);
}
else{
self->_gyroEnabledFlag ? deviceGyroSample.y * 57.2957795f * self->_gyroSensitivity : 0,
self->_gyroEnabledFlag ? deviceGyroSample.z * 57.2957795f * self->_gyroSensitivity : 0,
self->_gyroEnabledFlag ? deviceGyroSample.x * 57.2957795f * self->_gyroSensitivity : 0);
break;
case UIInterfaceOrientationLandscapeRight:
LiSendControllerMotionEvent((uint8_t)voidController.controllerNumber,
LI_MOTION_TYPE_GYRO,
deviceGyroSample.y * -57.2957795f * self->_gyroSensitivity,
deviceGyroSample.z * 57.2957795f * self->_gyroSensitivity,
deviceGyroSample.x * -57.2957795f * self->_gyroSensitivity);
}
self->_gyroEnabledFlag ? deviceGyroSample.y * -57.2957795f * self->_gyroSensitivity : 0,
self->_gyroEnabledFlag ? deviceGyroSample.z * 57.2957795f * self->_gyroSensitivity : 0,
self->_gyroEnabledFlag ? deviceGyroSample.x * -57.2957795f * self->_gyroSensitivity : 0);
break;
case UIInterfaceOrientationPortrait:
LiSendControllerMotionEvent((uint8_t)voidController.controllerNumber,
LI_MOTION_TYPE_GYRO,
self->_gyroEnabledFlag ? deviceGyroSample.x * 57.2957795f * self->_gyroSensitivity : 0,
self->_gyroEnabledFlag ? deviceGyroSample.z * 57.2957795f * self->_gyroSensitivity : 0,
self->_gyroEnabledFlag ? deviceGyroSample.y * -57.2957795f * self->_gyroSensitivity : 0);
break;
case UIInterfaceOrientationPortraitUpsideDown:
LiSendControllerMotionEvent((uint8_t)voidController.controllerNumber,
LI_MOTION_TYPE_GYRO,
self->_gyroEnabledFlag ? deviceGyroSample.x * -57.2957795f * self->_gyroSensitivity : 0,
self->_gyroEnabledFlag ? deviceGyroSample.z * 57.2957795f * self->_gyroSensitivity : 0,
self->_gyroEnabledFlag ? deviceGyroSample.y * 57.2957795f * self->_gyroSensitivity : 0);
break;
default:
LiSendControllerMotionEvent((uint8_t)voidController.controllerNumber,
LI_MOTION_TYPE_GYRO,
self->_gyroEnabledFlag ? deviceGyroSample.y * 57.2957795f * self->_gyroSensitivity : 0,
self->_gyroEnabledFlag ? deviceGyroSample.z * 57.2957795f * self->_gyroSensitivity : 0,
self->_gyroEnabledFlag ? deviceGyroSample.x * 57.2957795f * self->_gyroSensitivity : 0);
break;
}
/*
if(UIApplication.sharedApplication.windows.firstObject.windowScene.interfaceOrientation == 4){//check for landscape left or landscape right
LiSendControllerMotionEvent((uint8_t)voidController.controllerNumber,
LI_MOTION_TYPE_GYRO,
self->_gyroEnabledFlag ? deviceGyroSample.y * 57.2957795f * self->_gyroSensitivity : 0,
self->_gyroEnabledFlag ? deviceGyroSample.z * 57.2957795f * self->_gyroSensitivity : 0,
self->_gyroEnabledFlag ? deviceGyroSample.x * 57.2957795f * self->_gyroSensitivity : 0);
}
else{
LiSendControllerMotionEvent((uint8_t)voidController.controllerNumber,
LI_MOTION_TYPE_GYRO,
deviceGyroSample.y * 57.2957795f * self->_gyroSensitivity,
deviceGyroSample.z * 57.2957795f * self->_gyroSensitivity,
deviceGyroSample.x * 57.2957795f * self->_gyroSensitivity);
self->_gyroEnabledFlag ? deviceGyroSample.y * -57.2957795f * self->_gyroSensitivity : 0,
self->_gyroEnabledFlag ? deviceGyroSample.z * 57.2957795f * self->_gyroSensitivity : 0,
self->_gyroEnabledFlag ? deviceGyroSample.x * -57.2957795f * self->_gyroSensitivity : 0);
}
*/
}];
break;
}
@@ -335,9 +385,9 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
// NSLog(@"sending controller gyro data, gyroSample data 00: %f, playerIndex: %ld, obj: %@",gyroSample.x, (long)voidController.gamepad.playerIndex, voidController);
LiSendControllerMotionEvent((uint8_t)voidController.controllerNumber,
LI_MOTION_TYPE_GYRO,
gyroSample.x * 57.2957795f * self->_gyroSensitivity,
gyroSample.z * 57.2957795f * self->_gyroSensitivity,
gyroSample.y * -57.2957795f * self->_gyroSensitivity);
self->_gyroEnabledFlag ? gyroSample.x * 57.2957795f * self->_gyroSensitivity : 0,
self->_gyroEnabledFlag ? gyroSample.z * 57.2957795f * self->_gyroSensitivity : 0,
self->_gyroEnabledFlag ? gyroSample.y * -57.2957795f * self->_gyroSensitivity : 0);
}];
// });
});}
@@ -992,6 +1042,11 @@ double rc_expo(double x, double expo) {
});
}
- (bool)useMotionHandler{
return self->tempSettings.emulatedControllerType.intValue!=LI_CTYPE_PS
||self->tempSettings.gyroMode.intValue==GyroModeOff;
}
-(void) registerControllerCallbacks:(GCController*) controller
{
if (controller != NULL) {
@@ -1081,54 +1136,70 @@ double rc_expo(double x, double expo) {
for(NSNumber* buttonFlagId in buttonDict){
GCControllerButtonInput * button = (GCControllerButtonInput *)buttonDict[buttonFlagId];
if(self->_mapControllerToMouse){
if(button.pressed){
if(buttonFlagId.intValue == self->_controllerMouseSwitch){
self->_mouseSwitchButtonPressed = true;
self->mouseSwitchDownTimestamp = CACurrentMediaTime();
}
}
else{
if(buttonFlagId.intValue == self->_controllerMouseSwitch && self->_mouseSwitchButtonPressed){
if(CACurrentMediaTime()-self->mouseSwitchDownTimestamp>1){
self->_controllerMouseEnabledFlag = !self->_controllerMouseEnabledFlag;
[self updateLeftStick:voidController x:0 y:0];
[self updateRightStick:voidController x:0 y:0];
}
else [self sendControllerMouseSwitchClick:voidController];
self->_mouseSwitchButtonPressed = false;
self->mouseSwitchDownTimestamp = 0;
}
}
/* if(buttonFlagId.intValue == self->_controllerMouseSwitch){
if(button.pressed){
self->_mouseSwitchButtonPressed = true;
self->mouseSwitchDownTimestamp = CACurrentMediaTime();
}
else if(self->_mouseSwitchButtonPressed){
if(CACurrentMediaTime()-self->mouseSwitchDownTimestamp>1){
self->_controllerMouseEnabledFlag = !self->_controllerMouseEnabledFlag;
self->_mouseSwitchButtonPressed = false;
self->mouseSwitchDownTimestamp = 0;
}
else [self sendControllerMouseSwitchClick:voidController];
}
else self->_mouseSwitchButtonPressed = false;
} */
}
else self->_controllerMouseEnabledFlag = false;
if(self->_startGyroByController){
if(button.pressed){
if (buttonFlagId.intValue == self->_controllerGyroSwitchToggle
&& !self->_controllerGyroSwitchTogglePressed) {
self->_controllerGyroSwitchTogglePressed = true;
self->_gyroEnabledFlag = !self->_gyroEnabledFlag;
self->_gyroEnabledFlag = self->_gyroEnabledFlag && self->_gyroSwitchMode != ControllerGyroSwitchDisabled;
if([self useMotionHandler]){
if(self->_gyroEnabledFlag) [self->motionHandler startGyroByControllerButton];
else [self->motionHandler stopGyroUpdateWithInterruptNoneGyroInput:false resetLeftStick:true];
}
}
if (buttonFlagId.intValue == self->_controllerGyroSwitchHold
&& !self->_controllerGyroSwitchHoldPressed) {
self->_controllerGyroSwitchHoldPressed = true;
self->_gyroEnabledFlag = true;
self->_gyroEnabledFlag = self->_gyroEnabledFlag && self->_gyroSwitchMode != ControllerGyroSwitchDisabled;
if([self useMotionHandler] && self->_gyroEnabledFlag) [self->motionHandler startGyroByControllerButton];
}
}
else{
if (buttonFlagId.intValue == self->_controllerGyroSwitchToggle
&& self->_controllerGyroSwitchTogglePressed) {
self->_controllerGyroSwitchTogglePressed = false;
}
if (buttonFlagId.intValue == self->_controllerGyroSwitchHold
&& self->_controllerGyroSwitchHoldPressed) {
self->_controllerGyroSwitchHoldPressed = false;
self->_gyroEnabledFlag = false;
if([self useMotionHandler]) [self->motionHandler stopGyroUpdateWithInterruptNoneGyroInput:false resetLeftStick:true];
}
}
}
if(self->_controllerMouseEnabledFlag){
if(buttonFlagId.intValue == self->_controllerMouseLeftButton || buttonFlagId.intValue == self->_controllerMouseRightButton){
if(buttonFlagId.intValue == self->_controllerMouseLeftButton) LiSendMouseButtonEvent(button.pressed ? BUTTON_ACTION_PRESS : BUTTON_ACTION_RELEASE, BUTTON_LEFT);
if(buttonFlagId.intValue == self->_controllerMouseRightButton) LiSendMouseButtonEvent(button.pressed ? BUTTON_ACTION_PRESS : BUTTON_ACTION_RELEASE, BUTTON_RIGHT);
UPDATE_BUTTON_FLAG(voidController, buttonFlagId.intValue, NO);
}
else if(buttonFlagId.intValue!=self->_controllerMouseSwitch) UPDATE_BUTTON_FLAG(voidController, buttonFlagId.intValue, button.pressed);
else if(buttonFlagId.intValue!=self->_controllerMouseSwitch || !self->_mapControllerToMouse) UPDATE_BUTTON_FLAG(voidController, buttonFlagId.intValue, button.pressed);
}
else if(buttonFlagId.intValue!=self->_controllerMouseSwitch) UPDATE_BUTTON_FLAG(voidController, buttonFlagId.intValue, button.pressed);
else if(buttonFlagId.intValue!=self->_controllerMouseSwitch || !self->_mapControllerToMouse) UPDATE_BUTTON_FLAG(voidController, buttonFlagId.intValue, button.pressed);
}
leftStickX = self->_controllerMouseEnabledFlag ? 0 :gamepad.leftThumbstick.xAxis.value * 0x7FFE;
@@ -1137,6 +1208,7 @@ double rc_expo(double x, double expo) {
rightStickX = self->_controllerMouseEnabledFlag ? 0 : gamepad.rightThumbstick.xAxis.value * 0x7FFE;
rightStickY = self->_controllerMouseEnabledFlag ? 0 : gamepad.rightThumbstick.yAxis.value * 0x7FFE;
if(self->_controllerMouseEnabledFlag){
self->stickToMouseInputX = self->_controllerMouseStick == LeftStickToMouse ? gamepad.leftThumbstick.xAxis.value : gamepad.rightThumbstick.xAxis.value;
self->stickToMouseInputY = self->_controllerMouseStick == LeftStickToMouse ? gamepad.leftThumbstick.yAxis.value : gamepad.rightThumbstick.yAxis.value;
@@ -1148,13 +1220,30 @@ double rc_expo(double x, double expo) {
self->stickToMouseInputX = 0;
self->stickToMouseInputY = 0;
}
/*
if(self->oscProfile.mapGyroTo!=mapGyroToControllerStick
||!self->oscProfile.rollToLeftStick) [self updateLeftStick:voidController x:leftStickX y:leftStickY];
*/
if([self useMotionHandler]
&& self->oscProfile.mapGyroTo==mapGyroToControllerStick
&& self->oscProfile.yawPitchToRightStick
&& self->_gyroEnabledFlag
) [self->motionHandler mixPhysicalRightStickAndGyroInputWithX:rightStickX y:rightStickY];
else [self updateRightStick: voidController.playerIndex==0?self->_oscController:voidController x:rightStickX y:rightStickY];
if([self useMotionHandler]
&& self->oscProfile.mapGyroTo==mapGyroToControllerStick
&& self->oscProfile.rollToLeftStick
&& self->_gyroEnabledFlag
) [self->motionHandler mixPhysicalLeftStickAndGyroInputWithX:leftStickX y:leftStickY];
else [self updateLeftStick: voidController.playerIndex==0?self->_oscController:voidController x:leftStickX y:leftStickY];
leftTrigger = gamepad.leftTrigger.value * 0xFF;
rightTrigger = gamepad.rightTrigger.value * 0xFF;
[self updateLeftStick:voidController x:leftStickX y:leftStickY];
[self updateRightStick:voidController x:rightStickX y:rightStickY];
[self updateTriggers:voidController left:leftTrigger right:rightTrigger];
[self updateFinished:voidController];
if (@available(iOS 14.0, *)) {
@@ -1612,6 +1701,7 @@ double rc_expo(double x, double expo) {
_oscController.playerIndex = 0;
oscProfile = [oscProfileMan getSelectedProfile];
DataManager* dataMan = [[DataManager alloc] init];
tempSettings = [dataMan getSettings];
@@ -1642,6 +1732,16 @@ double rc_expo(double x, double expo) {
}
[_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}
_startGyroByController = true;
_gyroSwitchMode = tempSettings.controllerGyroSwitchMode.intValue;
// _gyroSwitchMode = ControllerGyroSwitchHoldDownToActivate;
_controllerGyroSwitchToggle = tempSettings.controllerGyroSwitchToggle.intValue;
_controllerGyroSwitchHold = tempSettings.controllerGyroSwitchHold.intValue;
_controllerGyroSwitchTogglePressed = false;
_controllerGyroSwitchHoldPressed = false;
if(![self useMotionHandler]) [self->motionHandler stopGyroUpdateWithInterruptNoneGyroInput:false resetLeftStick:true];
}
- (void)resetGyroInputForController:(VoidController* )voidController{
@@ -1835,6 +1935,11 @@ double rc_expo(double x, double expo) {
_gyroMode = AlwaysDevice;
_controllerMouseEnabledFlag = false;
_gyroEnabledFlag = false;
motionHandler = [MotionHandler sharedInstance];
oscProfileMan = [OSCProfilesManager sharedManager:CGRectZero];
[self updateCommonConfig:streamConfig];
for(VoidController* voidController in _voidControllers.allValues){
@@ -1848,6 +1953,7 @@ double rc_expo(double x, double expo) {
_shallDisableGyroHotSwitch = streamConfig.gyroMode == GyroModeOff && _voidControllers.allValues.count == 0;
NSLog(@"shallDisableGyroHotSwitch %d", _shallDisableGyroHotSwitch);
return self;
}
+39 -18
View File
@@ -40,11 +40,13 @@ import GameController
case paddle2 = 0x020000
case paddle3 = 0x040000
case paddle4 = 0x080000
case touchpad = 0x100000
case touchpadButton = 0x100000
case misc = 0x200000
case leftTrigger = 0x400000
case rightTrigger = 0x800000
case null = 0xFFFFFF
}
@@ -139,7 +141,7 @@ import GameController
result[.paddle4] = paddle4
}
if let touchpadBtn = profile.buttons[GCInputDualShockTouchpadButton] {
result[.touchpad] = touchpadBtn
result[.touchpadButton] = touchpadBtn
}
if #available(iOS 15.0, tvOS 15.0, *) {
if let share = profile.buttons[GCInputButtonShare] {
@@ -149,23 +151,42 @@ import GameController
}
}
}
/*
if let micro = controller.microGamepad {
if #available(iOS 13.0, *) {
result[.menu] = micro.buttonMenu
result[.a] = micro.buttonA
result[.x] = micro.buttonX
result[.dpadUp] = micro.dpad.up
result[.dpadDown] = micro.dpad.down
result[.dpadLeft] = micro.dpad.left
result[.dpadRight] = micro.dpad.right
result[.menu] = micro.buttonMenu
}
}*/
return result
}
@objc static func string(for button: ControllerButton) -> String {
switch button {
case .a: return "A"
case .b: return "B"
case .x: return "X"
case .y: return "Y"
case .dpadUp: return SwiftLocalizationHelper.localizedString(forKey: "Up")
case .dpadDown: return SwiftLocalizationHelper.localizedString(forKey: "Down")
case .dpadLeft: return SwiftLocalizationHelper.localizedString(forKey: "Left")
case .dpadRight: return SwiftLocalizationHelper.localizedString(forKey: "Right")
case .leftShoulder: return "LB"
case .rightShoulder: return "RB"
case .leftStickButton: return "LS"
case .rightStickButton: return "RS"
case .menu: return "Menu"
case .back: return "Back"
case .special: return "Home"
case .paddle1: return SwiftLocalizationHelper.localizedString(forKey: "Paddle1")
case .paddle2: return SwiftLocalizationHelper.localizedString(forKey: "Paddle2")
case .paddle3: return SwiftLocalizationHelper.localizedString(forKey: "Paddle3")
case .paddle4: return SwiftLocalizationHelper.localizedString(forKey: "Paddle4")
case .touchpadButton: return SwiftLocalizationHelper.localizedString(forKey: "Touch button")
case .misc: return "Misc"
case .leftTrigger: return "LT"
case .rightTrigger: return "RT"
case .null: return SwiftLocalizationHelper.localizedString(forKey: "Null")
}
}
}
+44 -17
View File
@@ -10,23 +10,34 @@ import Foundation
import CoreMotion
@objc public protocol OnScreenWidgetStickMixedInputDelegate: AnyObject {
func mixRightStickAndGyroInput(x: CGFloat, y: CGFloat)
func mixLeftStickAndGyroInput(x: CGFloat, y: CGFloat)
func mixOnScreenRightStickAndGyroInput(x: CGFloat, y: CGFloat)
func mixOnScreenLeftStickAndGyroInput(x: CGFloat, y: CGFloat)
func gyroMixInputStarted() -> Bool
}
@objc class MotionHandler: NSObject, OscInstanceReceiverDelegate, OnScreenWidgetStickMixedInputDelegate{
public func mixRightStickAndGyroInput(x: CGFloat, y: CGFloat) {
public func mixOnScreenRightStickAndGyroInput(x: CGFloat, y: CGFloat) {
rightStickTouchInputX = x
rightStickTouchInputY = y
}
public func mixLeftStickAndGyroInput(x: CGFloat, y: CGFloat) {
public func mixOnScreenLeftStickAndGyroInput(x: CGFloat, y: CGFloat) {
// rollIntegral = 0
leftStickTouchInputX = x
leftStickTouchInputY = y
}
@objc public func mixPhysicalRightStickAndGyroInput(x: CGFloat, y: CGFloat) {
rightStickPhysicalInputX = x
rightStickPhysicalInputY = y
}
@objc public func mixPhysicalLeftStickAndGyroInput(x: CGFloat, y: CGFloat) {
// rollIntegral = 0
leftStickPhysicalInputX = x
leftStickPhysicalInputY = y
}
public func gyroMixInputStarted() -> Bool {
return gyroIsWorking
}
@@ -71,7 +82,7 @@ import CoreMotion
public var gyroStarter:Any?
private var windowScene: Any?
private var onScreenControls: OnScreenControls = OnScreenControls.init()
@objc public var onScreenControls: OnScreenControls = OnScreenControls.init()
public let stickMaxOffset: CGFloat = 0x7FFE
private var stickInputScale: CGFloat = 35
@@ -97,6 +108,12 @@ import CoreMotion
private var leftStickTouchInputX:Double = 0
private var leftStickTouchInputY:Double = 0
private var rightStickPhysicalInputX:Double = 0
private var rightStickPhysicalInputY:Double = 0
private var leftStickPhysicalInputX:Double = 0
private var leftStickPhysicalInputY:Double = 0
var updateInterval: TimeInterval = 1.0 / 120.0 {
didSet {
@@ -136,6 +153,16 @@ import CoreMotion
}
}
@objc public func startGyroByControllerButton(){
self.previousWidgetYawFactor = self.widgetYawFactor
self.previousWidgetPitchFactor = self.widgetPitchFactor
self.previousWidgetRollFactor = self.widgetRollFactor
self.widgetYawFactor = 1
self.widgetPitchFactor = 1
self.widgetRollFactor = 1
self.startGyroUpdate()
}
/// 启动传感器数据更新
@objc public func startGyroUpdate() {
if !gyroControlStarted {
@@ -165,15 +192,15 @@ import CoreMotion
}
/// 停止更新
private var interruptTouchInput:Bool = false
private var interruptNoneGyroInput:Bool = false
@objc public func stopGyroUpdate(interruptTouchInput:Bool=false, resetLeftStick:Bool=false) {
@objc public func stopGyroUpdate(interruptNoneGyroInput:Bool=false, resetLeftStick:Bool=false) {
gyroControlStarted = false
gyroIsWorking = false
if motionManager.isGyroActive{
motionManager.stopGyroUpdates()
}
self.clearGyroInput(interruptTouchInput:interruptTouchInput, resetLeftStick:resetLeftStick)
self.clearGyroInput(interruptNonGyroInput:interruptNoneGyroInput, resetLeftStick:resetLeftStick)
}
@objc public func stopAccelUpdate() {
@@ -260,7 +287,7 @@ import CoreMotion
}
if !gyroControlStarted {
self.clearGyroInput(interruptTouchInput: interruptTouchInput)
self.clearGyroInput(interruptNonGyroInput: interruptNoneGyroInput)
print("Gyro: stopped")
return
}
@@ -275,11 +302,11 @@ import CoreMotion
if oscProfile.mapGyroTo == MapGyroTo.mapGyroToControllerStick {
if oscProfile.yawPitchToRightStick {
yaw = rightStickTouchInputX + gyroInputToStickInput(input:yawSource*sensitvityYaw*widgetYawFactor*10)
yaw = rightStickTouchInputX + rightStickPhysicalInputX + gyroInputToStickInput(input:yawSource*sensitvityYaw*widgetYawFactor*10)
yaw = self.clampStickInput(input: yaw)
yaw = (yaw >= 0 ? 1.0 : -1.0) * gyroToStickMinOffset + (self.stickMaxOffset - gyroToStickMinOffset) * (yaw/self.stickMaxOffset)
pitch = rightStickTouchInputY - gyroInputToStickInput(input:pitchSource*sensitvityPitch*widgetPitchFactor*10)
pitch = rightStickTouchInputY + rightStickPhysicalInputY - gyroInputToStickInput(input:pitchSource*sensitvityPitch*widgetPitchFactor*10)
pitch = self.clampStickInput(input: pitch)
pitch = (pitch >= 0 ? 1.0 : -1.0) * gyroToStickMinOffset + (self.stickMaxOffset - gyroToStickMinOffset) * (pitch/self.stickMaxOffset)
@@ -288,25 +315,25 @@ import CoreMotion
if oscProfile.rollToLeftStick {
roll = gyroInputToStickInput(input:rollSource*sensitvityRoll*widgetRollFactor*0.2)
rollIntegral = rollIntegral + roll
var mixedLeftStickOffset = self.clampStickInput(input: rollIntegral+leftStickTouchInputX)
var mixedLeftStickOffset = self.clampStickInput(input: rollIntegral+leftStickTouchInputX+leftStickPhysicalInputX)
mixedLeftStickOffset = (mixedLeftStickOffset >= 0 ? 1.0 : -1.0) * gyroToStickMinOffset + (self.stickMaxOffset - gyroToStickMinOffset) * (mixedLeftStickOffset/self.stickMaxOffset)
self.onScreenControls.sendLeftStickTouchPadEvent(mixedLeftStickOffset, leftStickTouchInputY)
self.onScreenControls.sendLeftStickTouchPadEvent(mixedLeftStickOffset, leftStickTouchInputY+leftStickPhysicalInputY)
}
}
}
private func clearGyroInput(interruptTouchInput:Bool, resetLeftStick:Bool=false){
private func clearGyroInput(interruptNonGyroInput:Bool, resetLeftStick:Bool=false){
if oscProfile.yawPitchToRightStick{
self.onScreenControls.sendRightStickTouchPadEvent(rightStickTouchInputX-yawBias, rightStickTouchInputY-pitchBias)
self.onScreenControls.sendRightStickTouchPadEvent(rightStickPhysicalInputX+rightStickTouchInputX-yawBias, rightStickPhysicalInputY+rightStickTouchInputY-pitchBias)
}
if oscProfile.rollToLeftStick{
if resetLeftStick {
rollIntegral = 0
self.onScreenControls.sendLeftStickTouchPadEvent(leftStickTouchInputX-rollBias, leftStickTouchInputY)
self.onScreenControls.sendLeftStickTouchPadEvent(leftStickPhysicalInputX+leftStickTouchInputX-rollBias,leftStickPhysicalInputY+leftStickTouchInputY)
}
}
if(interruptTouchInput){
if(interruptNonGyroInput){
self.onScreenControls.clearLeftStickTouchPadFlag()
self.onScreenControls.clearRightStickTouchPadFlag()
}
+7 -7
View File
@@ -1301,7 +1301,7 @@ import UIKit
targetY = (targetY >= 0 ? 1.0 : -1.0) * self.minStickOffset + (self.stickMaxOffset - self.minStickOffset) * (targetY/self.stickMaxOffset)
self.onScreenControls.sendRightStickTouchPadEvent(targetX, targetY)
}
self.motionHandler.mixRightStickAndGyroInput(x: targetX, y: targetY)
self.motionHandler.mixOnScreenRightStickAndGyroInput(x: targetX, y: targetY)
}
private func sendLeftStickTouchPadEvent(inputX: CGFloat, inputY: CGFloat){
@@ -1315,7 +1315,7 @@ import UIKit
if !mixLeftStickInputToGyro || (self.motionHandler.gyroMixInputStarted() != true) {
self.onScreenControls.sendLeftStickTouchPadEvent(targetX, targetY)
}
self.motionHandler.mixLeftStickAndGyroInput(x: targetX, y: targetY)
self.motionHandler.mixOnScreenLeftStickAndGyroInput(x: targetX, y: targetY)
}
private func sendLeftTriggerTouchPadEvent(inputY: CGFloat){
@@ -1846,7 +1846,7 @@ import UIKit
case "GYRO":
self.motionHandler.startGyroByOnScreenButton(self, yawFactor: yawFactor, pitchFactor: pitchFactor, rollFactor: rollFactor)
case "GYROPAUSE":
self.motionHandler.stopGyroUpdate(interruptTouchInput:false)
self.motionHandler.stopGyroUpdate(interruptNoneGyroInput:false)
break
case "ACCEL":
break
@@ -1868,7 +1868,7 @@ import UIKit
widget.tapToToggleFlag = !widget.tapToToggleFlag
}
}
self.motionHandler.stopGyroUpdate(interruptTouchInput: false, resetLeftStick: true)
self.motionHandler.stopGyroUpdate(interruptNoneGyroInput: false, resetLeftStick: true)
self.motionHandler.gyroStarter = nil
}
else {
@@ -1931,7 +1931,7 @@ import UIKit
if !mixRightStickInputToGyro || self.motionHandler.gyroMixInputStarted() != true {
self.onScreenControls.clearRightStickTouchPadFlag()
}
self.motionHandler.mixRightStickAndGyroInput(x: 0, y: 0)
self.motionHandler.mixOnScreenRightStickAndGyroInput(x: 0, y: 0)
}
private func clearLeftStickTouchPadFlag(){
@@ -1940,7 +1940,7 @@ import UIKit
if !mixLeftStickInputToGyro || self.motionHandler.gyroMixInputStarted() != true {
self.onScreenControls.clearLeftStickTouchPadFlag()
}
self.motionHandler.mixLeftStickAndGyroInput(x: 0, y: 0)
self.motionHandler.mixOnScreenLeftStickAndGyroInput(x: 0, y: 0)
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
@@ -2168,7 +2168,7 @@ import UIKit
super.didMoveToSuperview()
if superview == nil {
if self.motionControlButtonString == "GYRO" {
self.motionHandler.stopGyroUpdate(interruptTouchInput: true)
self.motionHandler.stopGyroUpdate(interruptNoneGyroInput: true)
self.motionHandler.gyroStarter = nil
}
if self.motionControlButtonString == "ACCEL" {}
@@ -29,6 +29,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="controllerGyroSwitchHold" attributeType="Integer 32" defaultValueString="1024" usesScalarValueType="NO" syncable="YES"/>
<attribute name="controllerGyroSwitchMode" attributeType="Integer 16" defaultValueString="1024" usesScalarValueType="NO" syncable="YES"/>
<attribute name="controllerGyroSwitchToggle" attributeType="Integer 32" defaultValueString="1024" 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="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="controllerMousePointerVelocity" optional="YES" attributeType="Float" defaultValueString="12" usesScalarValueType="NO" syncable="YES"/>
+495
View File
@@ -254,6 +254,52 @@
}
}
},
" both set " : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : " 双键开关 "
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : " 雙鍵開關 "
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : " 雙鍵開關 "
}
}
}
},
" duplicated ! " : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : " 按键重复 ! "
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : " 按鍵重复 ! "
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : " 按鍵重复 !"
}
}
}
},
"!ML_TEST_RESULT_INCONCLUSIVE" : {
"extractionState" : "manual",
"localizations" : {
@@ -1445,6 +1491,35 @@
}
}
},
"controllerGyroSwitchButtonStackTip" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gyro toggle button: %@\nGyro hold-down button: %@"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "陀螺仪切换按键: %@\n陀螺仪保持按键: %@"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "陀螺儀切換按鍵: %@\n陀螺儀保持按鍵: %@"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "陀螺儀切換按鍵: %@\n陀螺儀保持按鍵: %@"
}
}
}
},
"controllerMouseExpoStackTip" : {
"extractionState" : "manual",
"localizations" : {
@@ -1474,6 +1549,35 @@
}
}
},
"controllerToMouseStackTip" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Long press to switch to mouse mode: %@\nStick for moving mouse pointer: %@\nMouse left button: %@\nMouse right button: %@"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "长按切换鼠标模式: %@\n控制鼠标的摇杆: %@\n鼠标左键: %@\n鼠标右键: %@"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "長按切換滑鼠模式: %@\n控制滑鼠的搖桿: %@\n滑鼠左鍵: %@\n滑鼠右鍵: %@"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "長按切換滑鼠模式: %@\n控制滑鼠的搖桿: %@\n滑鼠左鍵: %@\n滑鼠右鍵: %@"
}
}
}
},
"Create New" : {
"extractionState" : "manual",
"localizations" : {
@@ -1739,6 +1843,52 @@
}
}
},
"Disable hold-down button" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "禁用保持键"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "禁用保持鍵"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "禁用保持鍵"
}
}
}
},
"Disable press-toggle button" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "禁用切换键"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "禁用切換鍵"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "禁用切換鍵"
}
}
}
},
"Disconnect" : {
"extractionState" : "manual",
"localizations" : {
@@ -1785,6 +1935,29 @@
}
}
},
"Down" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "下"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "下"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "下"
}
}
}
},
"Drag and drop buttons onto this trash can to remove them from the interface" : {
"extractionState" : "manual",
"localizations" : {
@@ -2563,6 +2736,29 @@
}
}
},
"Gyro button on controller" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "手柄陀螺仪按键"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "手柄陀螺儀按鍵"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "手柄陀螺儀按鍵"
}
}
}
},
"gyroModeStackDoc" : {
"extractionState" : "manual",
"localizations" : {
@@ -3064,6 +3260,52 @@
}
}
},
"Left" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "左"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "左"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "左"
}
}
}
},
"Left stick" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "左摇杆"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "左搖桿"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "左搖桿"
}
}
}
},
"Load" : {
"extractionState" : "manual",
"localizations" : {
@@ -3687,6 +3929,29 @@
}
}
},
"Null" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "无"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "無"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "無"
}
}
}
},
"NVIDIA GameStream End-of-Service" : {
"extractionState" : "manual",
"localizations" : {
@@ -4073,6 +4338,98 @@
}
}
},
"Paddle1" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "背键1"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "背鍵1"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "背鍵1"
}
}
}
},
"Paddle2" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "背键2"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "背鍵2"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "背鍵2"
}
}
}
},
"Paddle3" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "背键3"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "背鍵3"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "背鍵3"
}
}
}
},
"Paddle4" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "背键4"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "背鍵4"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "背鍵4"
}
}
}
},
"Pairing" : {
"extractionState" : "manual",
"localizations" : {
@@ -4483,6 +4840,52 @@
}
}
},
"Press a button for keeping gyro active by holding down.\nYou can have 2 buttons for both press-toggle & hold-down switch." : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "按下保持陀螺仪模式的手柄按键。\n你可以为陀螺仪切换和保持各设置一个按键。"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "按下保持陀螺儀模式的手把按鍵。\n您可以為陀螺儀切換和保持各設置一個按鍵。"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "按下保持陀螺儀模式的手把按鍵。\n您可以為陀螺儀切換和保持各設置一個按鍵。"
}
}
}
},
"Press a button for switching gyro on & off with a press.\nYou can have 2 buttons for both press-toggle & hold-down switch." : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "按下切换陀螺仪模式的手柄按键。\n你可以为陀螺仪切换和保持各设置一个按键。"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "按下切換陀螺儀模式的手把按鍵。\n您可以為陀螺儀切換和保持各設置一個按鍵。"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "按下切換陀螺儀模式的手把按鍵。\n您可以為陀螺儀切換和保持各設置一個按鍵。"
}
}
}
},
"Press a button for switching to controller mouse mode (long press for 1 second during streaming)" : {
"extractionState" : "manual",
"localizations" : {
@@ -5174,6 +5577,52 @@
}
}
},
"Right" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "右"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "右"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "右"
}
}
}
},
"Right stick" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "右摇杆"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "右搖桿"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "右搖桿"
}
}
}
},
"Roll factor: %.2f" : {
"extractionState" : "manual",
"localizations" : {
@@ -6292,6 +6741,29 @@
}
}
},
"Touchpad button" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "触摸板按键"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "触摸板按键"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "触摸板按键"
}
}
}
},
"Undo" : {
"extractionState" : "manual",
"localizations" : {
@@ -6367,6 +6839,29 @@
}
}
},
"Up" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "上"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "上"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "上"
}
}
}
},
"useBuiltinMicStackTip" : {
"extractionState" : "manual",
"localizations" : {
@@ -223,6 +223,10 @@
@property (strong, nonatomic) IBOutlet UIStackView *controllerMouseExpoStack;
@property (strong, nonatomic) IBOutlet UISlider *controllerMouseExpoSlider;
@property (strong, nonatomic) IBOutlet UIStackView *controllerGyroSwitchButtonStack;
@property (strong, nonatomic) IBOutlet UISegmentedControl *controllerGyroSwitchButtonSetter;
@property (strong, nonatomic) IBOutlet UIStackView *testStack;
@property (nonatomic, strong) MicHandler *micHandler;
@@ -763,9 +763,10 @@ BOOL isCustomResolution(int resolutionSelected) {
[self addSetting:self.emulatedControllerTypeStack ofId:@"emulatedControllerTypeStack" withInfoTag:YES withDynamicLabel:NO to:controllerSection];
[self addSetting:self.gyroModeStack ofId:@"gyroModeStack" withInfoTag:YES withDynamicLabel:YES to:controllerSection];
[self addSetting:self.gyroSensitivityStack ofId:@"gyroSensitivityStack" withInfoTag:NO withDynamicLabel:YES to:controllerSection];
[self addSetting:self.controllerToMouseStack ofId:@"controllerToMouseStack" withInfoTag:NO withDynamicLabel:YES to:controllerSection];
[self addSetting:self.controllerToMouseStack ofId:@"controllerToMouseStack" withInfoTag:YES withDynamicLabel:YES to:controllerSection];
[self addSetting:self.controllerMouseVelocityStack ofId:@"controllerMouseVelocityStack" withInfoTag:NO withDynamicLabel:YES to:controllerSection];
[self addSetting:self.controllerMouseExpoStack ofId:@"controllerMouseExpoStack" withInfoTag:YES withDynamicLabel:YES to:controllerSection];
[self addSetting:self.controllerGyroSwitchButtonStack ofId:@"controllerGyroSwitchButtonStack" withInfoTag:YES withDynamicLabel:YES to:controllerSection];
[controllerSection addToParentStack:_parentStack];
motionControlSection = [[MenuSectionView alloc] init];
@@ -1349,7 +1350,17 @@ BOOL isCustomResolution(int resolutionSelected) {
tipText = [LocalizationHelper localizedStringForKey:@"controllerMouseExpoStackTip"];
showOnlineDocAction = false;
}
if([sender.superview.accessibilityIdentifier isEqualToString: @"controllerGyroSwitchButtonStack"]){
tempSettings = [dataMan getSettings];
tipText = [LocalizationHelper localizedStringForKey:@"controllerGyroSwitchButtonStackTip", [ControllerUtil stringFor:tempSettings.controllerGyroSwitchToggle.intValue], [ControllerUtil stringFor:tempSettings.controllerGyroSwitchHold.intValue]];
showOnlineDocAction = false;
}
if([sender.superview.accessibilityIdentifier isEqualToString: @"controllerToMouseStack"]){
tempSettings = [dataMan getSettings];
tipText = [LocalizationHelper localizedStringForKey:@"controllerToMouseStackTip", [ControllerUtil stringFor:tempSettings.controllerMouseSwitch.intValue], [LocalizationHelper localizedStringForKey:tempSettings.controllerGyroSwitchHold.intValue == LeftStickToMouse ? @"Left stick" : @"Right stick"], [ControllerUtil stringFor:tempSettings.controllerMouseLeftButton.intValue], [ControllerUtil stringFor:tempSettings.controllerMouseRightButton.intValue]];
showOnlineDocAction = false;
}
UIAlertController *tipsAlertController = [UIAlertController alertControllerWithTitle: [LocalizationHelper localizedStringForKey:@"Tips"] message:tipText preferredStyle:UIAlertControllerStyleAlert];
@@ -1978,6 +1989,13 @@ BOOL isCustomResolution(int resolutionSelected) {
[self.controllerToMouseSwitch addTarget:self action:@selector(controllerToMouseSwitchFlipped:) forControlEvents:UIControlEventValueChanged];
[self controllerToMouseSwitchFlipped:self.controllerToMouseSwitch];
self.controllerGyroSwitchButtonSetter.selectedSegmentIndex = self->tempSettings.controllerGyroSwitchMode.intValue;
[self.controllerGyroSwitchButtonSetter addTarget:self action:@selector(controllerGyroSwitchModeChanged:) forControlEvents:UIControlEventValueChanged];
if(self.controllerGyroSwitchButtonSetter.selectedSegmentIndex != ControllerGyroSwitchDisabled){
bool bothButtonsSet = self->tempSettings.controllerGyroSwitchHold.intValue != ControllerButtonNull && self->tempSettings.controllerGyroSwitchToggle.intValue != ControllerButtonNull;
[self findDynamicLabelFromStack:self.controllerGyroSwitchButtonStack].text = bothButtonsSet ? [LocalizationHelper localizedStringForKey:@" both set "] : @"";
}
[self.controllerMouseVelocitySlider setValue:self->tempSettings.controllerMousePointerVelocity.floatValue];
[self.controllerMouseVelocitySlider addTarget:self action:@selector(controllerMouseVelocitySliderMoved:) forControlEvents:UIControlEventValueChanged];
[self controllerMouseVelocitySliderMoved:self.controllerMouseVelocitySlider];
@@ -2244,6 +2262,93 @@ BOOL isCustomResolution(int resolutionSelected) {
}
}
- (void)controllerGyroSwitchModeChanged:(UISegmentedControl* )sender{
UILabel* tipLabel = [self findDynamicLabelFromStack:self.controllerGyroSwitchButtonStack];
if(sender.selectedSegmentIndex == ControllerGyroSwitchDisabled){
tipLabel.text = @"";
}
else{
__block bool switchButtonCaptured = false;
Settings* currentSettings = [dataMan retrieveSettings];
[AlertControllerUtil showAlertIn:self
title:[LocalizationHelper localizedStringForKey:@"Gyro button on controller"]
message:sender.selectedSegmentIndex == ControllerGyroSwitchPressToToggle ? [LocalizationHelper localizedStringForKey:@"Press a button for switching gyro on & off with a press.\nYou can have 2 buttons for both press-toggle & hold-down switch."] : [LocalizationHelper localizedStringForKey:@"Press a button for keeping gyro active by holding down.\nYou can have 2 buttons for both press-toggle & hold-down switch."]
withCancel:NO
buttonTitle:sender.selectedSegmentIndex == ControllerGyroSwitchPressToToggle ? [LocalizationHelper localizedStringForKey:@"Disable press-toggle button"] : [LocalizationHelper localizedStringForKey:@"Disable hold-down button"]
countdown:0
action:^{
UIAlertAction* confirmAction = AlertControllerUtil.alertController.actions.firstObject;
self->capturedController = [GCController controllers].firstObject;
if(self->capturedController){
__weak typeof(self) weakSelf = self;
[ControllerUtil listenWithController:self->capturedController swapABXY:false handler:^(NSDictionary * buttonDict, GCExtendedGamepad * gamepad, GCControllerElement * element) {
__strong typeof(weakSelf) self = weakSelf;
if (!self) return;
for(NSNumber* buttonFlagId in buttonDict){
GCControllerButtonInput * button = (GCControllerButtonInput *)buttonDict[buttonFlagId];
if(button.isPressed){
if(sender.selectedSegmentIndex == ControllerGyroSwitchPressToToggle) currentSettings.controllerGyroSwitchToggle = buttonFlagId;
if(sender.selectedSegmentIndex == ControllerGyroSwitchHoldDown) currentSettings.controllerGyroSwitchHold = buttonFlagId;
switchButtonCaptured = true;
AlertControllerUtil.alertController.message = [LocalizationHelper localizedStringForKey:@"Finished"];
gamepad.valueChangedHandler = nil;
if(confirmAction) [confirmAction setValue:[LocalizationHelper localizedStringForKey:@"OK"] forKey:@"title"];
[self->dataMan saveData];
}
}
}];
}
else{
[AlertControllerUtil.alertController dismissViewControllerAnimated:NO completion:^{
[AlertControllerUtil showAlertIn:self
title:[LocalizationHelper localizedStringForKey:@""]
message:[LocalizationHelper localizedStringForKey:@"Waiting for controller..."]
withCancel:YES
buttonTitle:[LocalizationHelper localizedStringForKey:@"Continue"]
countdown:3
action:^{}
completion:^{
if(AlertControllerUtil.actionCancelled){
self.controllerGyroSwitchButtonSetter.selectedSegmentIndex = ControllerGyroSwitchDisabled;
return;
}
[AlertControllerUtil.alertController dismissViewControllerAnimated:NO completion:^{}];
[self controllerGyroSwitchModeChanged:sender];
}];
}];
}
}
completion:^{
if(!switchButtonCaptured){
if(sender.selectedSegmentIndex == ControllerGyroSwitchPressToToggle) currentSettings.controllerGyroSwitchToggle = @(ControllerButtonNull);
if(sender.selectedSegmentIndex == ControllerGyroSwitchHoldDown) currentSettings.controllerGyroSwitchHold = @(ControllerButtonNull);
}
bool noSwitchButtonSet = currentSettings.controllerGyroSwitchHold.intValue == ControllerButtonNull && currentSettings.controllerGyroSwitchToggle.intValue == ControllerButtonNull;
bool duplicatedButtons = currentSettings.controllerGyroSwitchHold.intValue == currentSettings.controllerGyroSwitchToggle.intValue && currentSettings.controllerGyroSwitchToggle.intValue != ControllerButtonNull;
bool bothButtonsSet = currentSettings.controllerGyroSwitchHold.intValue != ControllerButtonNull && currentSettings.controllerGyroSwitchToggle.intValue != ControllerButtonNull;
tipLabel.text = @"";
if(bothButtonsSet) tipLabel.text = [LocalizationHelper localizedStringForKey:@" both set "];
if(duplicatedButtons){
sender.selectedSegmentIndex = ControllerGyroSwitchDisabled;
tipLabel.text = [LocalizationHelper localizedStringForKey:@" duplicated ! "];
}
if(noSwitchButtonSet) sender.selectedSegmentIndex = ControllerGyroSwitchDisabled;
if(!noSwitchButtonSet && !bothButtonsSet){
sender.selectedSegmentIndex = currentSettings.controllerGyroSwitchToggle.intValue != ControllerButtonNull ? ControllerGyroSwitchPressToToggle : ControllerGyroSwitchHoldDown;
}
[self->dataMan saveData];
if(self->capturedController && self->capturedController.extendedGamepad) self->capturedController.extendedGamepad.valueChangedHandler = nil;
}];
}
}
- (void)controllerToMouseSwitchFlipped:(UISwitch* )sender{
[self setHidden:!sender.isOn forStack:_controllerMouseVelocityStack];
[self setHidden:!sender.isOn forStack:_controllerMouseExpoStack];
@@ -2334,7 +2439,7 @@ BOOL isCustomResolution(int resolutionSelected) {
message:[LocalizationHelper localizedStringForKey:@"Waiting for controller..."]
withCancel:YES
buttonTitle:[LocalizationHelper localizedStringForKey:@"Continue"]
countdown:2
countdown:3
action:^{}
completion:^{
if(AlertControllerUtil.actionCancelled){
@@ -3162,6 +3267,7 @@ BOOL isCustomResolution(int resolutionSelected) {
BOOL mapControllerToMouse = self.controllerToMouseSwitch.isOn;
CGFloat controllerMousePointerVelocity = self.controllerMouseVelocitySlider.value;
CGFloat controllerMouseExpo = self.controllerMouseExpoSlider.value;
NSInteger controllerGyroSwitchMode = self.controllerGyroSwitchButtonSetter.selectedSegmentIndex;
NSInteger backgroundSessionTimer = self.backgroundSessionTimerSlider.value == self.backgroundSessionTimerSlider.maximumValue ? (uint32_t) INT16_MAX : (uint32_t)self.backgroundSessionTimerSlider.value;
[dataMan saveSettingsWithBitrate:_bitrate
@@ -3231,6 +3337,7 @@ BOOL isCustomResolution(int resolutionSelected) {
mapControllerToMouse:mapControllerToMouse
controllerMousePointerVelocity:controllerMousePointerVelocity
controllerMouseExpo:controllerMouseExpo
controllerGyroSwitchMode:controllerGyroSwitchMode
backgroundSessionTimer:backgroundSessionTimer];
}
@@ -1582,8 +1582,8 @@
[_motionHandler startAccelUpdate];
}
- (void)stopGyroUpdateWithInterruptTouchInput:(BOOL)interruption{
[_motionHandler stopGyroUpdateWithInterruptTouchInput:interruption resetLeftStick:false];
- (void)stopGyroUpdateWithInterruptNoneGyroInput:(BOOL)interruption{
[_motionHandler stopGyroUpdateWithInterruptNoneGyroInput:interruption resetLeftStick:false];
}
- (void)stopAccelUpdate{
+120
View File
@@ -619,6 +619,36 @@
}
}
},
"26O-xW-5EH.text" : {
"comment" : "Class = \"UILabel\"; text = \"Switch Gyro by Controller\"; ObjectID = \"26O-xW-5EH\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Switch Gyro by Controller"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "手柄开关陀螺仪"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "手把開關陀螺儀"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "手把開關陀螺儀"
}
}
}
},
"53H-ST-OtY.segmentTitles[0]" : {
"comment" : "Class = \"UISegmentedControl\"; 53H-ST-OtY.segmentTitles[0] = \"Balanced\"; ObjectID = \"53H-ST-OtY\";",
"extractionState" : "extracted_with_value",
@@ -4009,6 +4039,96 @@
}
}
},
"OWG-zd-e3I.segmentTitles[0]" : {
"comment" : "Class = \"UISegmentedControl\"; OWG-zd-e3I.segmentTitles[0] = \"Disabled\"; ObjectID = \"OWG-zd-e3I\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Disabled"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "关闭"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "關閉"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "關閉"
}
}
}
},
"OWG-zd-e3I.segmentTitles[1]" : {
"comment" : "Class = \"UISegmentedControl\"; OWG-zd-e3I.segmentTitles[1] = \"Press-toggle\"; ObjectID = \"OWG-zd-e3I\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Press-toggle"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "按下切换"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "按下切換"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "按下切換"
}
}
}
},
"OWG-zd-e3I.segmentTitles[2]" : {
"comment" : "Class = \"UISegmentedControl\"; OWG-zd-e3I.segmentTitles[2] = \"Hold down\"; ObjectID = \"OWG-zd-e3I\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Hold down"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "按住保持"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "按住保持"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "按住保持"
}
}
}
},
"OXy-y4-yO4.text" : {
"comment" : "Class = \"UILabel\"; text = \"Swap A/B X/Y Buttons\"; ObjectID = \"OXy-y4-yO4\";",
"extractionState" : "extracted_with_value",
+102
View File
@@ -1309,6 +1309,18 @@
}
}
},
"bAZ-bm-h3I.text" : {
"comment" : "Class = \"UILabel\"; text = \"Switch Gyro by Controller\"; ObjectID = \"bAZ-bm-h3I\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Switch Gyro by Controller"
}
}
}
},
"Bda-3L-Wtg.segmentTitles[0]" : {
"comment" : "Class = \"UISegmentedControl\"; Bda-3L-Wtg.segmentTitles[0] = \"Off\"; ObjectID = \"Bda-3L-Wtg\";",
"extractionState" : "extracted_with_value",
@@ -2851,6 +2863,96 @@
}
}
},
"mpa-8g-1Ug.segmentTitles[0]" : {
"comment" : "Class = \"UISegmentedControl\"; mpa-8g-1Ug.segmentTitles[0] = \"Disabled\"; ObjectID = \"mpa-8g-1Ug\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Disabled"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "关闭"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "關閉"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "關閉"
}
}
}
},
"mpa-8g-1Ug.segmentTitles[1]" : {
"comment" : "Class = \"UISegmentedControl\"; mpa-8g-1Ug.segmentTitles[1] = \"Press-toggle\"; ObjectID = \"mpa-8g-1Ug\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Press-toggle"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "按下切换"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "按下切換"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "按下切換"
}
}
}
},
"mpa-8g-1Ug.segmentTitles[2]" : {
"comment" : "Class = \"UISegmentedControl\"; mpa-8g-1Ug.segmentTitles[2] = \"Hold down\"; ObjectID = \"mpa-8g-1Ug\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Hold down"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "按住保持"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "按住保持"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "按住保持"
}
}
}
},
"msE-2o-R3Q.segmentTitles[0]" : {
"comment" : "Class = \"UISegmentedControl\"; msE-2o-R3Q.segmentTitles[0] = \"No\"; ObjectID = \"msE-2o-R3Q\";",
"extractionState" : "extracted_with_value",