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 @@
-
-
+
+
-
+
+
+
+
+
+
+
+
+
@@ -1879,7 +1903,7 @@
-
+
@@ -1927,7 +1951,7 @@
-
+
@@ -1972,7 +1996,7 @@
-
+
@@ -1992,7 +2016,7 @@
-
+
@@ -2032,7 +2056,7 @@
-
+
@@ -2137,6 +2161,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -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" : "右鍵"
}
}