diff --git a/VoidLink/Base.lproj/iPad.storyboard b/VoidLink/Base.lproj/iPad.storyboard index 042209d5..524971e9 100644 --- a/VoidLink/Base.lproj/iPad.storyboard +++ b/VoidLink/Base.lproj/iPad.storyboard @@ -1769,10 +1769,34 @@ - - + + - + + + + + + + + + - + @@ -1927,7 +1951,7 @@ - + @@ -1972,7 +1996,7 @@ - + - + - + + + + + + + + + + + + + + + + @@ -2208,6 +2252,8 @@ + + @@ -2315,6 +2361,8 @@ + + diff --git a/VoidLink/Base.lproj/iPhone.storyboard b/VoidLink/Base.lproj/iPhone.storyboard index acbd660b..597cabb5 100644 --- a/VoidLink/Base.lproj/iPhone.storyboard +++ b/VoidLink/Base.lproj/iPhone.storyboard @@ -1449,7 +1449,7 @@ - + @@ -2586,166 +2586,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -3169,46 +3009,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -3349,11 +3149,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -3417,6 +3461,8 @@ + + @@ -3511,6 +3557,8 @@ + + diff --git a/VoidLink/Database/TemporarySettings.h b/VoidLink/Database/TemporarySettings.h index 4847c18c..f3780b9d 100644 --- a/VoidLink/Database/TemporarySettings.h +++ b/VoidLink/Database/TemporarySettings.h @@ -45,6 +45,9 @@ @property (nonatomic, retain) NSNumber * gyroBiasX; @property (nonatomic, retain) NSNumber * gyroBiasY; @property (nonatomic, retain) NSNumber * gyroBiasZ; +@property (nonatomic, retain) NSNumber * controllerGyroBiasX; +@property (nonatomic, retain) NSNumber * controllerGyroBiasY; +@property (nonatomic, retain) NSNumber * controllerGyroBiasZ; @property (nonatomic, retain) NSNumber * backgroundSessionTimer; @property (nonatomic) enum { CODEC_PREF_AUTO, diff --git a/VoidLink/Database/TemporarySettings.m b/VoidLink/Database/TemporarySettings.m index 1328d6c6..ff88b302 100644 --- a/VoidLink/Database/TemporarySettings.m +++ b/VoidLink/Database/TemporarySettings.m @@ -140,6 +140,9 @@ self.gyroBiasX = settings.gyroBiasX; self.gyroBiasY = settings.gyroBiasY; self.gyroBiasZ = settings.gyroBiasZ; + self.controllerGyroBiasX = settings.controllerGyroBiasX; + self.controllerGyroBiasY = settings.controllerGyroBiasY; + self.controllerGyroBiasZ = settings.controllerGyroBiasZ; self.singleTapSensitivity = settings.singleTapSensitivity; self.backgroundSessionTimer = settings.backroundSessionTimer; self.edgeSlidingSensitivity = settings.edgeSlidingSensitivity; diff --git a/VoidLink/Input/CustomOSC/OSCProfile.h b/VoidLink/Input/CustomOSC/OSCProfile.h index d074183c..e28beafd 100644 --- a/VoidLink/Input/CustomOSC/OSCProfile.h +++ b/VoidLink/Input/CustomOSC/OSCProfile.h @@ -41,6 +41,8 @@ typedef NS_ENUM(NSInteger, PencilHoverMode) { @property (nonatomic, assign) int16_t unfoldedExclusiveFolderSequence; @property NSSet *postExclusiveUnfoldedSequences; @property BOOL isSelected; +@property (nonatomic, assign) bool useBuiltinGyro; +@property (nonatomic, assign) bool swapYawAndRoll; @property (nonatomic, assign) MapGyroTo mapGyroTo; @property (nonatomic, assign) bool yawPitchToRightStick; @property (nonatomic, assign) bool rollToLeftStick; diff --git a/VoidLink/Input/CustomOSC/OSCProfile.m b/VoidLink/Input/CustomOSC/OSCProfile.m index 19142946..16b53d9e 100644 --- a/VoidLink/Input/CustomOSC/OSCProfile.m +++ b/VoidLink/Input/CustomOSC/OSCProfile.m @@ -34,6 +34,8 @@ [encoder encodeInt32:self.unfoldedExclusiveFolderSequence forKey:@"unfoldedExclusiveFolderSequence"]; [encoder encodeObject:self.postExclusiveUnfoldedSequences forKey:@"postExclusiveUnfoldedSequences"]; [encoder encodeBool:self.isSelected forKey:@"isSelected"]; + [encoder encodeBool:self.useBuiltinGyro forKey:@"useBuiltinGyro"]; + [encoder encodeBool:self.swapYawAndRoll forKey:@"swapYawAndRoll"]; [encoder encodeInt64:self.mapGyroTo forKey:@"mapGyroTo"]; [encoder encodeBool:self.yawPitchToRightStick forKey:@"yawPitchToRightStick"]; [encoder encodeBool:self.rollToLeftStick forKey:@"rollToLeftStick"]; @@ -99,6 +101,8 @@ forKey:@"postExclusiveUnfoldedSequences"] : [NSSet set]; self.isSelected = [decoder decodeBoolForKey:@"isSelected"]; + self.useBuiltinGyro = [decoder containsValueForKey:@"useBuiltinGyro"] ? [decoder decodeBoolForKey:@"useBuiltinGyro"] : true; + self.swapYawAndRoll = [decoder containsValueForKey:@"swapYawAndRoll"] ? [decoder decodeBoolForKey:@"swapYawAndRoll"] : false; self.mapGyroTo = [decoder containsValueForKey:@"mapGyroTo"] ? [decoder decodeInt64ForKey:@"mapGyroTo"] : mapGyroToMouse; self.yawPitchToRightStick = [decoder containsValueForKey:@"yawPitchToRightStick"] ? [decoder decodeBoolForKey:@"yawPitchToRightStick"] : true; self.rollToLeftStick = [decoder containsValueForKey:@"rollToLeftStick"] ? [decoder decodeBoolForKey:@"rollToLeftStick"] : false; @@ -201,6 +205,9 @@ copy.unfoldedExclusiveFolderSequence = self.unfoldedExclusiveFolderSequence; copy.postExclusiveUnfoldedSequences = [self.postExclusiveUnfoldedSequences copy]; copy.isSelected = self.isSelected; + copy.useBuiltinGyro = self.useBuiltinGyro; + copy.swapYawAndRoll = self.swapYawAndRoll; + copy.isSelected = self.isSelected; copy.mapGyroTo = self.mapGyroTo; copy.yawPitchToRightStick = self.yawPitchToRightStick; copy.rollToLeftStick = self.rollToLeftStick; diff --git a/VoidLink/Input/MotionHandler.swift b/VoidLink/Input/MotionHandler.swift index fc585f09..b9ac2601 100644 --- a/VoidLink/Input/MotionHandler.swift +++ b/VoidLink/Input/MotionHandler.swift @@ -47,6 +47,8 @@ import CoreMotion @objc class func shared(profile: OSCProfile?) -> MotionHandler { let sharedInstance = MotionHandler.sharedInstance guard let profile = profile else { return sharedInstance } + sharedInstance.useBuiltinGyro = profile.useBuiltinGyro + sharedInstance.swapYawAndRoll = profile.swapYawAndRoll sharedInstance.mapGyroTo = profile.mapGyroTo sharedInstance.synthesizePhysicalStick = profile.synthesizePhysicalStick sharedInstance.rollToLeftStick = profile.rollToLeftStick @@ -60,10 +62,12 @@ import CoreMotion } @objc public var gyroControlStarted: Bool = false + @objc var useBuiltinGyro: Bool = true + @objc var swapYawAndRoll: Bool = false private var gyroIsWorking: Bool = false private var accelControlStarted: Bool = false private let motionManager = CMMotionManager() - + private weak var activeGCController:GCController? private var synthesizePhysicalStick:Bool = false private var mapGyroTo:MapGyroTo = .mapGyroToControllerStick private var rollToLeftStick:Bool = false @@ -96,6 +100,9 @@ import CoreMotion @objc public var gyroBiasX: Double = 0 @objc public var gyroBiasY: Double = 0 @objc public var gyroBiasZ: Double = 0 + @objc public var controllerGyroBiasX: Double = 0 + @objc public var controllerGyroBiasY: Double = 0 + @objc public var controllerGyroBiasZ: Double = 0 @objc public var gyroToStickMinOffset:Double = 0 private var yawBias:Double = 0 private var pitchBias:Double = 0 @@ -122,7 +129,7 @@ import CoreMotion } @objc public override init() { - let oscProfileMan = OSCProfilesManager.sharedManager(CGRectZero) + // _ = OSCProfilesManager.sharedManager(CGRectZero) super.init() if #available(iOS 13.0, *) { let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene @@ -161,16 +168,47 @@ import CoreMotion self.startGyroUpdate() } - /// 启动传感器数据更新 @objc public func startGyroUpdate() { if !gyroControlStarted { gyroControlStarted = true - if motionManager.isGyroAvailable { - motionManager.startGyroUpdates(to: .main) { [weak self] gyroData, _ in - guard let self = self, let data = gyroData else { return } - self.handleGyroData(x: data.rotationRate.x, - y: data.rotationRate.y, - z: data.rotationRate.z) + + print("startGyroUpdate useBuiltinGyro \(useBuiltinGyro) \(CACurrentMediaTime())") + + + if useBuiltinGyro { + if motionManager.isGyroAvailable { + motionManager.startGyroUpdates(to: .main) { [weak self] gyroData, _ in + guard let self = self, let data = gyroData else { return } + self.handleGyroData(x: data.rotationRate.x, + y: data.rotationRate.y, + z: data.rotationRate.z) + } + } + } + else { + if #available(iOS 14.0, *) { + if activeGCController == nil { + if let controllers = ControllerUtil.activeGCControllers as? Set { + for controller in controllers { + if controller.playerIndex == .index1 { + activeGCController = controller + break + } + } + } + } + if let motion = activeGCController?.motion { + if motion.sensorsRequireManualActivation { + motion.sensorsActive = true + } + if motion.sensorsActive { + motion.valueChangedHandler = { [weak self] motion in + self?.handleGyroData(x: motion.rotationRate.x, + y: motion.rotationRate.y, + z: motion.rotationRate.z) + } + } + } } } } @@ -198,6 +236,9 @@ import CoreMotion if motionManager.isGyroActive{ motionManager.stopGyroUpdates() } + if #available(iOS 14.0, *) { + activeGCController?.motion?.sensorsActive = false + } self.clearGyroInput(interruptNonGyroInput:interruptNoneGyroInput, resetLeftStick:resetLeftStick) } @@ -226,67 +267,77 @@ import CoreMotion let correctedY:Double = y - gyroBiasY let correctedZ:Double = z - gyroBiasZ */ - if #available(iOS 13.0, *) { - let orientation = (windowScene as! UIWindowScene).interfaceOrientation - switch orientation { - case .landscapeLeft: - yawBias = gyroBiasX - pitchBias = -gyroBiasY - rollBias = -gyroBiasZ - yawSource = x-yawBias - pitchSource = -y-pitchBias - rollSource = -z-rollBias - case .landscapeRight: - yawBias = -gyroBiasX - pitchBias = gyroBiasY - rollBias = -gyroBiasZ - yawSource = -x-yawBias - pitchSource = y-pitchBias - rollSource = -z-rollBias - case .portrait: - yawBias = -gyroBiasY - pitchBias = -gyroBiasX - rollBias = -gyroBiasZ - yawSource = -y-yawBias - pitchSource = -x-pitchBias - rollSource = -z-rollBias - case .portraitUpsideDown: - yawBias = gyroBiasY - pitchBias = gyroBiasX - rollBias = -gyroBiasZ - yawSource = y-yawBias - pitchSource = x-pitchBias - rollSource = -z-rollBias - default: - yawBias = gyroBiasX - pitchBias = -gyroBiasY - rollBias = -gyroBiasZ - yawSource = x-yawBias - pitchSource = -y-pitchBias - rollSource = -z-rollBias - } - } else { - let orientation = UIApplication.shared.statusBarOrientation - if orientation.isLandscape { - yawBias = gyroBiasX - pitchBias = -gyroBiasY - rollBias = -gyroBiasZ - yawSource = x-yawBias - pitchSource = -y-pitchBias - rollSource = -z-rollBias - } else if orientation.isPortrait { - yawBias = -gyroBiasY - pitchBias = -gyroBiasX - rollBias = -gyroBiasZ - yawSource = -y-yawBias - pitchSource = -x-pitchBias - rollSource = -z-rollBias + if useBuiltinGyro { + if #available(iOS 13.0, *) { + let orientation = (windowScene as! UIWindowScene).interfaceOrientation + switch orientation { + case .landscapeLeft: + yawBias = gyroBiasX + pitchBias = -gyroBiasY + rollBias = -gyroBiasZ + yawSource = x-yawBias + pitchSource = -y-pitchBias + rollSource = -z-rollBias + case .landscapeRight: + yawBias = -gyroBiasX + pitchBias = gyroBiasY + rollBias = -gyroBiasZ + yawSource = -x-yawBias + pitchSource = y-pitchBias + rollSource = -z-rollBias + case .portrait: + yawBias = -gyroBiasY + pitchBias = -gyroBiasX + rollBias = -gyroBiasZ + yawSource = -y-yawBias + pitchSource = -x-pitchBias + rollSource = -z-rollBias + case .portraitUpsideDown: + yawBias = gyroBiasY + pitchBias = gyroBiasX + rollBias = -gyroBiasZ + yawSource = y-yawBias + pitchSource = x-pitchBias + rollSource = -z-rollBias + default: + yawBias = gyroBiasX + pitchBias = -gyroBiasY + rollBias = -gyroBiasZ + yawSource = x-yawBias + pitchSource = -y-pitchBias + rollSource = -z-rollBias + } + } else { + let orientation = UIApplication.shared.statusBarOrientation + if orientation.isLandscape { + yawBias = gyroBiasX + pitchBias = -gyroBiasY + rollBias = -gyroBiasZ + yawSource = x-yawBias + pitchSource = -y-pitchBias + rollSource = -z-rollBias + } else if orientation.isPortrait { + yawBias = -gyroBiasY + pitchBias = -gyroBiasX + rollBias = -gyroBiasZ + yawSource = -y-yawBias + pitchSource = -x-pitchBias + rollSource = -z-rollBias + } } } + else { + yawBias = swapYawAndRoll ? controllerGyroBiasY : -controllerGyroBiasZ + pitchBias = -controllerGyroBiasX + rollBias = swapYawAndRoll ? -controllerGyroBiasZ : controllerGyroBiasY + yawSource = (swapYawAndRoll ? y : -z) - yawBias + pitchSource = -x-pitchBias + rollSource = (swapYawAndRoll ? -z : y) - rollBias + } if !gyroControlStarted { self.clearGyroInput(interruptNonGyroInput: interruptNoneGyroInput) - print("Gyro: stopped") + // print("Gyro: stopped") return } @@ -361,12 +412,30 @@ import CoreMotion var sumX = 0.0, sumY = 0.0, sumZ = 0.0 var sampleCount = 0 - motionManager.startGyroUpdates(to: .main) { [weak self] gyroData, _ in - guard let self = self, self.isCalibrating, let data = gyroData else { return } - sumX += data.rotationRate.x - sumY += data.rotationRate.y - sumZ += data.rotationRate.z - sampleCount += 1 + if useBuiltinGyro { + motionManager.startGyroUpdates(to: .main) { [weak self] gyroData, _ in + guard let self = self, self.isCalibrating, let data = gyroData else { return } + sumX += data.rotationRate.x + sumY += data.rotationRate.y + sumZ += data.rotationRate.z + sampleCount += 1 + } + } + else if #available(iOS 14.0, *) { + if let motion = activeGCController?.motion { + if motion.sensorsRequireManualActivation { + motion.sensorsActive = true + } + if motion.sensorsActive { + motion.valueChangedHandler = { [weak self] motion in + guard let self = self, self.isCalibrating else { return } + sumX += motion.rotationRate.x + sumY += motion.rotationRate.y + sumZ += motion.rotationRate.z + sampleCount += 1 + } + } + } } // 5秒后计算平均值 @@ -374,9 +443,16 @@ import CoreMotion guard let self = self else { return } self.motionManager.stopGyroUpdates() if sampleCount > 0 { - gyroBiasX = sumX / Double(sampleCount) - gyroBiasY = sumY / Double(sampleCount) - gyroBiasZ = sumZ / Double(sampleCount) + if useBuiltinGyro { + gyroBiasX = sumX / Double(sampleCount) + gyroBiasY = sumY / Double(sampleCount) + gyroBiasZ = sumZ / Double(sampleCount) + } + else { + controllerGyroBiasX = sumX / Double(sampleCount) + controllerGyroBiasY = sumY / Double(sampleCount) + controllerGyroBiasZ = sumZ / Double(sampleCount) + } } self.isCalibrating = false completion() diff --git a/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents b/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents index d49b97a0..068f5ec4 100644 --- a/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents +++ b/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents @@ -36,6 +36,9 @@ + + + @@ -116,4 +119,4 @@ - + \ No newline at end of file diff --git a/VoidLink/Localization/Localizable.xcstrings b/VoidLink/Localization/Localizable.xcstrings index cd7df14a..216b63a3 100644 --- a/VoidLink/Localization/Localizable.xcstrings +++ b/VoidLink/Localization/Localizable.xcstrings @@ -11591,6 +11591,35 @@ } } }, + "swapYawAndRollStackTip" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enable this option when the controller moves together with the screen (e.g., when using a telescopic controller)" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "当手柄随屏幕同一运动时(例如使用拉伸手柄)启用该选项" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "當手把隨螢幕同步移動時(例如使用拉伸式手把)啟用此選項" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "當手把隨螢幕同步移動時(例如使用拉伸式手把)啟用此選項" + } + } + } + }, "Switch on/off a floating gamepad overlay with live input feedback" : { "extractionState" : "manual", "localizations" : { diff --git a/VoidLink/ViewControllers/SettingsViewController.h b/VoidLink/ViewControllers/SettingsViewController.h index 669fd9f5..89ea4c83 100644 --- a/VoidLink/ViewControllers/SettingsViewController.h +++ b/VoidLink/ViewControllers/SettingsViewController.h @@ -153,6 +153,12 @@ @property (strong, nonatomic) IBOutlet UIStackView *rememberFoldStateStack; @property (strong, nonatomic) IBOutlet UISwitch *rememberFoldStateSwitch; +@property (weak, nonatomic) IBOutlet UIStackView *gyroSourceStack; +@property (weak, nonatomic) IBOutlet UISegmentedControl *gyroSourceSelector; + +@property (weak, nonatomic) IBOutlet UIStackView *swapYawAndRollStack; +@property (weak, nonatomic) IBOutlet UISwitch *swapYawAndRollSwitch; + @property (strong, nonatomic) IBOutlet UIStackView *mapGyroToStack; @property (strong, nonatomic) IBOutlet UISegmentedControl *mapGyroToSelector; diff --git a/VoidLink/ViewControllers/SettingsViewController.m b/VoidLink/ViewControllers/SettingsViewController.m index b5bc10a0..e4b5b47d 100644 --- a/VoidLink/ViewControllers/SettingsViewController.m +++ b/VoidLink/ViewControllers/SettingsViewController.m @@ -370,6 +370,11 @@ BOOL isCustomResolution(int resolutionSelected) { [self.reverseHoldButtonSwitch setOn:oscProfile.reverseGyroHoldButton]; + [self.gyroSourceSelector setSelectedSegmentIndex:oscProfile.useBuiltinGyro ? 0 : 1]; + [self gyroSourceChanged:self.gyroSourceSelector]; + + [self.swapYawAndRollSwitch setOn:oscProfile.swapYawAndRoll]; + [self.mapGyroToSelector setSelectedSegmentIndex:oscProfile.mapGyroTo]; [self mapGyroToChanged:self.mapGyroToSelector]; @@ -412,7 +417,12 @@ BOOL isCustomResolution(int resolutionSelected) { CGFloat pitchSensitivityPercent = [self map_velocFactorDisplay_fromSliderValue:self.pitchSensitivitySlider.value]; CGFloat rollSensitivityPercent = [self map_velocFactorDisplay_fromSliderValue:self.rollSensitivitySlider.value]; - bool configNotChanged = (oscProfile.mapGyroTo == self.mapGyroToSelector.selectedSegmentIndex + bool configNotChanged = ( + (int16_t)(oscProfile.pointerVelocityModeDivider*100) == (int16_t)(self.pointerVelocityModeDividerSlider.value) + && (int16_t)(oscProfile.touchPointerVelocityFactor*100) == (int16_t)touchPointerVelocityFactorPercent + && oscProfile.useBuiltinGyro == self.gyroSourceSelector.selectedSegmentIndex == 0 + && oscProfile.swapYawAndRoll == self.swapYawAndRollSwitch.isOn + && oscProfile.mapGyroTo == self.mapGyroToSelector.selectedSegmentIndex && oscProfile.yawPitchToRightStick == self.yawPitchToRightStickSwitch.isOn && oscProfile.rollToLeftStick == self.rollToLeftStickSwitch.isOn && (int16_t)(oscProfile.pointerVelocityModeDivider*100) == (int16_t)self.pointerVelocityModeDividerSlider.value @@ -438,6 +448,8 @@ BOOL isCustomResolution(int resolutionSelected) { oscProfile = [oscProfileMan getSelectedProfile]; oscProfile.pointerVelocityModeDivider = self.pointerVelocityModeDividerSlider.value/100; oscProfile.touchPointerVelocityFactor = touchPointerVelocityFactorPercent/100; + oscProfile.useBuiltinGyro = self.gyroSourceSelector.selectedSegmentIndex == 0; + oscProfile.swapYawAndRoll = self.swapYawAndRollSwitch.isOn; oscProfile.mapGyroTo = self.mapGyroToSelector.selectedSegmentIndex; oscProfile.yawPitchToRightStick = self.yawPitchToRightStickSwitch.isOn; oscProfile.rollToLeftStick = self.rollToLeftStickSwitch.isOn; @@ -957,6 +969,13 @@ BOOL isCustomResolution(int resolutionSelected) { self.reverseHoldButtonStack.hasDynamicLabel = YES; [self addSetting:self.reverseHoldButtonStack ofId:@"reverseHoldButtonStack" to:motionControlSection]; + self.gyroSourceStack.isGameProfileSetting = YES; + [self addSetting:self.gyroSourceStack ofId:@"gyroSourceStack" to:motionControlSection]; + + self.swapYawAndRollStack.hasInfoTag = YES; + self.swapYawAndRollStack.isGameProfileSetting = YES; + [self addSetting:self.swapYawAndRollStack ofId:@"swapYawAndRollStack" to:motionControlSection]; + self.mapGyroToStack.hasInfoTag = YES; self.mapGyroToStack.isGameProfileSetting = YES; [self addSetting:self.mapGyroToStack ofId:@"mapGyroToStack" to:motionControlSection]; @@ -1737,7 +1756,11 @@ BOOL isCustomResolution(int resolutionSelected) { tipText = [LocalizationHelper localizedStringForKey:@"softKeyboardHeightStackTip"]; showOnlineDocAction = false; } - + if([sender.superview.accessibilityIdentifier isEqualToString: @"swapYawAndRollStack"]){ + tipText = [LocalizationHelper localizedStringForKey:@"swapYawAndRollStackTip"]; + showOnlineDocAction = false; + } + UIStackView* parentStack = (UIStackView* )sender.superview; NSString* edgeSide = self.slideToSettingsScreenEdgeSelector.selectedSegmentIndex == 1 ? [LocalizationHelper localizedStringForKey:@"left"] : [LocalizationHelper localizedStringForKey:@"right"]; NSString* slideDist = [NSString stringWithFormat:@"%d%%", (int)(self.slideToMenuDistanceSlider.value*100)]; @@ -2410,6 +2433,7 @@ BOOL isCustomResolution(int resolutionSelected) { [self.controllerMouseExpoSlider addTarget:self action:@selector(controllerMouseExpoSliderMoved:) forControlEvents:UIControlEventValueChanged]; [self controllerMouseExpoSliderMoved:self.controllerMouseExpoSlider]; + [self.gyroSourceSelector addTarget:self action:@selector(gyroSourceChanged:) forControlEvents:UIControlEventValueChanged]; [self.mapGyroToSelector addTarget:self action:@selector(mapGyroToChanged:) forControlEvents:UIControlEventValueChanged]; [self.yawPitchToRightStickSwitch addTarget:self action:@selector(yawPitchToRightStickSwitchFlipped:) forControlEvents:UIControlEventValueChanged]; [self.rollToLeftStickSwitch addTarget:self action:@selector(rollToLeftStickSwitchFlipped:) forControlEvents:UIControlEventValueChanged]; @@ -2631,6 +2655,10 @@ BOOL isCustomResolution(int resolutionSelected) { } } +- (void)gyroSourceChanged:(UISegmentedControl* )sender{ + [self setHidden:sender.selectedSegmentIndex != 1 forStack:_swapYawAndRollStack]; +} + - (void)mapGyroToChanged:(UISegmentedControl* )sender{ // [self setHidden:sender.selectedSegmentIndex != mapGyroToControllerStick forStack:_gyroToStickSwitchStack]; bool mapGyroToMouseEnabled = sender.selectedSegmentIndex == mapGyroToMouse; @@ -2666,9 +2694,16 @@ BOOL isCustomResolution(int resolutionSelected) { MotionHandler* motionHandler = [MotionHandler sharedWithProfile:nil]; [motionHandler calibrateGyroBiasWithDuration:5 completion:^{ Settings* currentSettings = [self->dataMan retrieveSettings]; - currentSettings.gyroBiasX = [NSNumber numberWithDouble:motionHandler.gyroBiasX]; - currentSettings.gyroBiasY = [NSNumber numberWithDouble:motionHandler.gyroBiasY]; - currentSettings.gyroBiasZ = [NSNumber numberWithDouble:motionHandler.gyroBiasZ]; + if(self.gyroSourceSelector.selectedSegmentIndex == 0){ + currentSettings.gyroBiasX = [NSNumber numberWithDouble:motionHandler.gyroBiasX]; + currentSettings.gyroBiasY = [NSNumber numberWithDouble:motionHandler.gyroBiasY]; + currentSettings.gyroBiasZ = [NSNumber numberWithDouble:motionHandler.gyroBiasZ]; + } + else{ + currentSettings.controllerGyroBiasX = [NSNumber numberWithDouble:motionHandler.controllerGyroBiasX]; + currentSettings.controllerGyroBiasY = [NSNumber numberWithDouble:motionHandler.controllerGyroBiasY]; + currentSettings.controllerGyroBiasZ = [NSNumber numberWithDouble:motionHandler.controllerGyroBiasZ]; + } [self->dataMan saveData]; }]; [AlertControllerUtil showAlertIn:self diff --git a/VoidLink/ViewControllers/StreamFrameViewController.m b/VoidLink/ViewControllers/StreamFrameViewController.m index 6fe07200..638e83bc 100644 --- a/VoidLink/ViewControllers/StreamFrameViewController.m +++ b/VoidLink/ViewControllers/StreamFrameViewController.m @@ -453,8 +453,11 @@ _motionHandler = [MotionHandler sharedWithProfile: nil]; _motionHandler.gyroBiasX = _settings.gyroBiasX.doubleValue; _motionHandler.gyroBiasY = _settings.gyroBiasY.doubleValue; - _motionHandler.gyroBiasZ = _settings.gyroBiasZ.doubleValue; - + _motionHandler.gyroBiasZ = _settings.gyroBiasZ.doubleValue; + _motionHandler.controllerGyroBiasX = _settings.controllerGyroBiasX.doubleValue; + _motionHandler.controllerGyroBiasY = _settings.controllerGyroBiasY.doubleValue; + _motionHandler.controllerGyroBiasZ = _settings.controllerGyroBiasZ.doubleValue; + TouchPadGestureHandler.enablePinch = _settings.enablePinch; TouchPadGestureHandler.ctrlDownForPinch = _settings.ctrlDownForPinch; TouchPadGestureHandler.scrollSensitivity = _settings.scrollSensitivity.floatValue; diff --git a/VoidLink/mul.lproj/iPad.xcstrings b/VoidLink/mul.lproj/iPad.xcstrings index c2bebfdb..3c737fe4 100644 --- a/VoidLink/mul.lproj/iPad.xcstrings +++ b/VoidLink/mul.lproj/iPad.xcstrings @@ -578,31 +578,31 @@ } }, "6gY-8I-NWq.text" : { - "comment" : "Class = \"UILabel\"; text = \"Map Built-in Gyro to\"; ObjectID = \"6gY-8I-NWq\";", + "comment" : "Class = \"UILabel\"; text = \"Map Gyro to\"; ObjectID = \"6gY-8I-NWq\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Map Built-in Gyro to" + "value" : "Map Gyro to" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "内置陀螺仪映射为" + "value" : "陀螺仪映射为" } }, "zh-Hant" : { "stringUnit" : { - "state" : "needs_review", - "value" : "内建陀螺儀映射為" + "state" : "translated", + "value" : "陀螺儀映射為" } }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", - "value" : "内建陀螺儀映射為" + "state" : "translated", + "value" : "陀螺儀映射為" } } } @@ -3524,13 +3524,13 @@ }, "zh-Hant" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "最小偏移量(陀螺儀→搖桿)" } }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "最小偏移量(陀螺儀→搖桿)" } } @@ -4352,6 +4352,66 @@ } } }, + "lVF-ve-kTt.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; lVF-ve-kTt.segmentTitles[0] = \"Built-in\"; ObjectID = \"lVF-ve-kTt\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Built-in" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "内置" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "內建" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "內建" + } + } + } + }, + "lVF-ve-kTt.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; lVF-ve-kTt.segmentTitles[1] = \"Controller\"; ObjectID = \"lVF-ve-kTt\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Controller" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "手柄" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "手把" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "手把" + } + } + } + }, "MaN-f7-I3g.text" : { "comment" : "Class = \"UILabel\"; text = \"Frame Pacing\"; ObjectID = \"MaN-f7-I3g\";", "extractionState" : "extracted_with_value", @@ -4634,6 +4694,36 @@ } } }, + "MXH-vb-Zyb.text" : { + "comment" : "Class = \"UILabel\"; text = \"Swap Yaw & Roll\"; ObjectID = \"MXH-vb-Zyb\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Swap Yaw & Roll" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "偏航/横滚互换" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "偏航/橫滾互換" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "偏航/橫滾互換" + } + } + } + }, "MyP-Aq-htW.text" : { "comment" : "Class = \"UILabel\"; text = \" Reveal mode \"; ObjectID = \"MyP-Aq-htW\";", "extractionState" : "extracted_with_value", @@ -5150,6 +5240,36 @@ } } }, + "pjK-jB-97s.text" : { + "comment" : "Class = \"UILabel\"; text = \"Gyro Source\"; ObjectID = \"pjK-jB-97s\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Gyro Source" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "陀螺仪输入来源" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "陀螺儀輸入來源" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "陀螺儀輸入來源" + } + } + } + }, "pMN-6T-aYE.text" : { "comment" : "Class = \"UILabel\"; text = \"Gesture Sliding Distance\"; ObjectID = \"pMN-6T-aYE\";", "extractionState" : "extracted_with_value", diff --git a/VoidLink/mul.lproj/iPhone.xcstrings b/VoidLink/mul.lproj/iPhone.xcstrings index f2aca9d7..2d15200a 100644 --- a/VoidLink/mul.lproj/iPhone.xcstrings +++ b/VoidLink/mul.lproj/iPhone.xcstrings @@ -811,6 +811,36 @@ } } }, + "8AT-tJ-mCN.text" : { + "comment" : "Class = \"UILabel\"; text = \"Gyro Source\"; ObjectID = \"8AT-tJ-mCN\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Gyro Source" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "陀螺仪输入来源" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "陀螺儀輸入來源" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "陀螺儀輸入來源" + } + } + } + }, "9Dr-3c-z61.text" : { "comment" : "Class = \"UILabel\"; text = \"Label alpha\"; ObjectID = \"9Dr-3c-z61\";", "extractionState" : "extracted_with_value", @@ -943,6 +973,36 @@ } } }, + "9KX-hM-6El.text" : { + "comment" : "Class = \"UILabel\"; text = \"Swap Yaw & Roll\"; ObjectID = \"9KX-hM-6El\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Swap Yaw & Roll" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "偏航/横滚互换" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "偏航/橫滾互換" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "偏航/橫滾互換" + } + } + } + }, "52u-T9-1Hv.text" : { "comment" : "Class = \"UILabel\"; text = \"Minimum Offset (Gyro→Stick)\"; ObjectID = \"52u-T9-1Hv\";", "extractionState" : "extracted_with_value", @@ -955,19 +1015,19 @@ }, "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "最小偏移量(陀螺仪→摇杆)" } }, "zh-Hant" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "最小偏移量(陀螺儀→搖桿)" } }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "最小偏移量(陀螺儀→搖桿)" } } @@ -2522,31 +2582,31 @@ } }, "GX4-zV-pQ8.text" : { - "comment" : "Class = \"UILabel\"; text = \"Map Built-in Gyro to\"; ObjectID = \"GX4-zV-pQ8\";", + "comment" : "Class = \"UILabel\"; text = \"Map Gyro to\"; ObjectID = \"GX4-zV-pQ8\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Map Built-in Gyro to" + "value" : "Map Gyro to" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "内置陀螺仪映射为" + "value" : "陀螺仪映射为" } }, "zh-Hant" : { "stringUnit" : { - "state" : "needs_review", - "value" : "内建陀螺儀映射為" + "state" : "translated", + "value" : "陀螺儀映射為" } }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", - "value" : "内建陀螺儀映射為" + "state" : "translated", + "value" : "陀螺儀映射為" } } } @@ -2569,13 +2629,13 @@ }, "zh-Hant" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "指針速度" } }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "指針速度" } } @@ -2731,13 +2791,13 @@ }, "zh-Hant" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "滑鼠靈敏度" } }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "滑鼠靈敏度" } } @@ -2821,13 +2881,13 @@ }, "zh-Hant" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "串流位元速率" } }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "串流位元速率" } } @@ -2851,13 +2911,13 @@ }, "zh-Hant" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "靈敏度分割位置" } }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "靈敏度分割位置" } } @@ -4357,6 +4417,66 @@ } } }, + "p1G-aH-6bV.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; p1G-aH-6bV.segmentTitles[0] = \"Built-in\"; ObjectID = \"p1G-aH-6bV\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Built-in" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "内置" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "内建" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "内建" + } + } + } + }, + "p1G-aH-6bV.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; p1G-aH-6bV.segmentTitles[1] = \"Controller\"; ObjectID = \"p1G-aH-6bV\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Controller" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "手柄" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "手把" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "手把" + } + } + } + }, "P4N-i6-1zD.text" : { "comment" : "Class = \"UILabel\"; text = \"Enable Timebase\"; ObjectID = \"P4N-i6-1zD\";", "extractionState" : "extracted_with_value", @@ -4567,13 +4687,13 @@ }, "zh-Hant" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "內建" } }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "內建" } } @@ -4879,7 +4999,7 @@ }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "延遲滑鼠左單擊" } } @@ -5155,7 +5275,7 @@ }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "顯示本地軟鍵盤工具列" } } @@ -5185,7 +5305,7 @@ }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "按鍵視覺回饋" } } @@ -5245,7 +5365,7 @@ }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "恢復範本" } } @@ -5287,7 +5407,7 @@ }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "串流解析度" } } @@ -5347,7 +5467,7 @@ }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "左鍵" } } @@ -5377,7 +5497,7 @@ }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "中鍵" } } @@ -5407,7 +5527,7 @@ }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "右鍵" } }