diff --git a/VoidLink/Base.lproj/iPad.storyboard b/VoidLink/Base.lproj/iPad.storyboard index 29888919..fc13429f 100644 --- a/VoidLink/Base.lproj/iPad.storyboard +++ b/VoidLink/Base.lproj/iPad.storyboard @@ -1,8 +1,8 @@ - + - + @@ -989,6 +989,30 @@ + + + + + + + + + + + + + + + + + + + @@ -1011,6 +1035,8 @@ + + diff --git a/VoidLink/Base.lproj/iPhone.storyboard b/VoidLink/Base.lproj/iPhone.storyboard index 1b461f1f..f9654825 100644 --- a/VoidLink/Base.lproj/iPhone.storyboard +++ b/VoidLink/Base.lproj/iPhone.storyboard @@ -1560,6 +1560,30 @@ + + + + + + + + + + + + + + + + + + + @@ -1580,6 +1604,8 @@ + + @@ -1662,16 +1688,16 @@ - + - + - + - + diff --git a/VoidLink/Database/DataManager.h b/VoidLink/Database/DataManager.h index 60ad9876..348247a0 100644 --- a/VoidLink/Database/DataManager.h +++ b/VoidLink/Database/DataManager.h @@ -55,7 +55,8 @@ typedef NS_ENUM(NSInteger, SettingsMenuMode) { width:(NSInteger)width audioConfig:(NSInteger)audioConfig onscreenControls:(NSInteger)onscreenControls - gyroMode:(NSInteger)gyroMode + gyroMode:(NSInteger)gyroMode + emulatedControllerType:(NSInteger)emulatedControllerType keyboardToggleFingers:(NSInteger)keyboardToggleFingers oscLayoutToolFingers:(NSInteger)oscLayoutToolFingers slideToSettingsScreenEdge:(NSInteger)slideToSettingsScreenEdge diff --git a/VoidLink/Database/DataManager.m b/VoidLink/Database/DataManager.m index 15fe83e5..e4e68648 100644 --- a/VoidLink/Database/DataManager.m +++ b/VoidLink/Database/DataManager.m @@ -61,7 +61,8 @@ width:(NSInteger)width audioConfig:(NSInteger)audioConfig onscreenControls:(NSInteger)onscreenControls - gyroMode:(NSInteger)gyroMode + gyroMode:(NSInteger)gyroMode + emulatedControllerType:(NSInteger)emulatedControllerType keyboardToggleFingers:(NSInteger)keyboardToggleFingers oscLayoutToolFingers:(NSInteger)oscLayoutToolFingers slideToSettingsScreenEdge:(NSInteger)slideToSettingsScreenEdge @@ -108,6 +109,7 @@ settingsToSave.audioConfig = [NSNumber numberWithInteger:audioConfig]; settingsToSave.onscreenControls = [NSNumber numberWithInteger:onscreenControls]; settingsToSave.gyroMode = [NSNumber numberWithInteger:gyroMode]; + settingsToSave.emulatedControllerType = [NSNumber numberWithInteger:emulatedControllerType]; settingsToSave.keyboardToggleFingers = [NSNumber numberWithInteger:(uint16_t)keyboardToggleFingers]; settingsToSave.oscLayoutToolFingers = [NSNumber numberWithInteger:(uint16_t)oscLayoutToolFingers]; settingsToSave.slideToSettingsScreenEdge = [NSNumber numberWithInteger:(uint32_t)slideToSettingsScreenEdge]; diff --git a/VoidLink/Database/TemporarySettings.h b/VoidLink/Database/TemporarySettings.h index 08105bc8..3ef7d3b0 100644 --- a/VoidLink/Database/TemporarySettings.h +++ b/VoidLink/Database/TemporarySettings.h @@ -33,6 +33,7 @@ @property (nonatomic, retain) NSNumber * touchMoveEventInterval; @property (nonatomic, retain) NSNumber * touchPointerVelocityFactor; @property (nonatomic, retain) NSNumber * gyroSensitivity; +@property (nonatomic, retain) NSNumber * emulatedControllerType; @property (nonatomic, retain) NSNumber * mousePointerVelocityFactor; @property (nonatomic, retain) NSNumber * pointerVelocityModeDivider; @property (nonatomic, retain) NSString * uniqueId; diff --git a/VoidLink/Database/TemporarySettings.m b/VoidLink/Database/TemporarySettings.m index ac1a87ff..ddf234e4 100644 --- a/VoidLink/Database/TemporarySettings.m +++ b/VoidLink/Database/TemporarySettings.m @@ -95,6 +95,7 @@ self.swapABXYButtons = settings.swapABXYButtons; self.onscreenControls = settings.onscreenControls; self.gyroMode = settings.gyroMode; + self.emulatedControllerType = settings.emulatedControllerType; self.reverseMouseWheelDirection = settings.reverseMouseWheelDirection; self.asyncNativeTouchPriority = settings.asyncNativeTouchPriority; self.btMouseSupport = settings.btMouseSupport; diff --git a/VoidLink/Input/ControllerSupport.m b/VoidLink/Input/ControllerSupport.m index 7a5bd8d6..724f7af0 100644 --- a/VoidLink/Input/ControllerSupport.m +++ b/VoidLink/Input/ControllerSupport.m @@ -507,8 +507,6 @@ static const double MOUSE_SPEED_DIVISOR = 1.25; rightStickY = MAX_MAGNITUDE(rightStickY, controller.mergedWithController.lastRightStickY); } - - //NSLog(@"gamepadMask: %@", [self binaryRepresentationOfInteger:buttonFlags]); // we got the pressed OSC buttons here. // Player 1 is always present for OSC @@ -733,19 +731,33 @@ static const double MOUSE_SPEED_DIVISOR = 1.25; capabilities |= LI_CCAP_TOUCHPAD; } - if ([controller.extendedGamepad isKindOfClass:[GCXboxGamepad class]]) { - type = LI_CTYPE_XBOX; - } - else if ([controller.extendedGamepad isKindOfClass:[GCDualShockGamepad class]]) { - type = LI_CTYPE_PS; + + // LI_CTYPE_UNKNOWN for option "Both" + if(voidController.playerIndex == 0){ + type = _streamConfig.emulatedControllerType == LI_CTYPE_UNKNOWN ? LI_CTYPE_PS : _streamConfig.emulatedControllerType; } - if (@available(iOS 14.5, tvOS 14.5, *)) { - if ([controller.extendedGamepad isKindOfClass:[GCDualSenseGamepad class]]) { + if(voidController.playerIndex == 1 && _streamConfig.emulatedControllerType == LI_CTYPE_UNKNOWN){ + type = LI_CTYPE_XBOX; + } + + if(voidController.playerIndex >= 1 && _streamConfig.emulatedControllerType != LI_CTYPE_UNKNOWN){ + if ([controller.extendedGamepad isKindOfClass:[GCXboxGamepad class]]) { + type = LI_CTYPE_XBOX; + } + if ([controller.extendedGamepad isKindOfClass:[GCDualShockGamepad class]]) { type = LI_CTYPE_PS; } + + if (@available(iOS 14.5, tvOS 14.5, *)) { + if ([controller.extendedGamepad isKindOfClass:[GCDualSenseGamepad class]]) { + type = LI_CTYPE_PS; + } + } } + + // Detect supported haptics localities if (controller.haptics) { if ([controller.haptics.supportedLocalities containsObject:GCHapticsLocalityHandles]) { @@ -765,6 +777,8 @@ static const double MOUSE_SPEED_DIVISOR = 1.25; capabilities |= LI_CCAP_GYRO; } } + + // Detect RGB LED support if (controller.light) { @@ -777,7 +791,7 @@ static const double MOUSE_SPEED_DIVISOR = 1.25; } bool controllerLacksGyro = (capabilities & LI_CCAP_GYRO) == 0; - if ((_gyroMode == AlwaysDevice) || (_gyroMode == GyroModeAuto && controllerLacksGyro)) + if(_streamConfig.emulatedControllerType == LI_CTYPE_PS && (_gyroMode == AlwaysDevice || (_gyroMode == GyroModeAuto && controllerLacksGyro))) { type = LI_CTYPE_PS; capabilities |= LI_CCAP_GYRO | LI_CCAP_ACCEL; @@ -786,7 +800,10 @@ static const double MOUSE_SPEED_DIVISOR = 1.25; } else { // This is a virtual controller corresponding to our OSC - + // set osc to PS to utilize built-in gyro when "both" is selected + type = _streamConfig.emulatedControllerType == LI_CTYPE_UNKNOWN ? LI_CTYPE_PS : _streamConfig.emulatedControllerType; + + /* if (_streamConfig.gyroMode != GyroModeOff) { type = LI_CTYPE_PS; capabilities = LI_CCAP_GYRO | LI_CCAP_ACCEL; @@ -795,6 +812,8 @@ static const double MOUSE_SPEED_DIVISOR = 1.25; type = LI_CTYPE_XBOX; capabilities = 0; } + */ + // Set the standard supported buttons for the virtual controller. supportedButtonFlags = @@ -1172,7 +1191,7 @@ static const double MOUSE_SPEED_DIVISOR = 1.25; - (void)updateVoidController:(VoidController* )voidController withGCController:(GCController* )controller{ - voidController.playerIndex = controller.playerIndex == -1 ? 0 : (uint8_t) controller.playerIndex; + //voidController.playerIndex = controller.playerIndex == -1 ? 0 : (uint8_t) controller.playerIndex; voidController.motionTypes = [[NSMutableSet alloc] init]; voidController.supportedEmulationFlags = EMULATING_SPECIAL | EMULATING_SELECT; voidController.gamepad = controller; @@ -1232,8 +1251,10 @@ static const double MOUSE_SPEED_DIVISOR = 1.25; return voidController; } + // extenal controller start from playerIndex 1 for option "Both" + int startPlayIndex = _streamConfig.emulatedControllerType == LI_CTYPE_UNKNOWN ? 1 : 0; - for (int i = 0; i < 4; i++) { + for (int i = startPlayIndex; i < 4; i++) { if (!(_controllerNumbers & (1 << i))) { _controllerNumbers |= (1 << i); diff --git a/VoidLink/Input/NativeTouchHandler.m b/VoidLink/Input/NativeTouchHandler.m index 28292cff..83b773f7 100644 --- a/VoidLink/Input/NativeTouchHandler.m +++ b/VoidLink/Input/NativeTouchHandler.m @@ -264,7 +264,7 @@ [self removePointerId:touch]; //then remove pointerId if(self->activateCoordSelector) [self removePointerObjFromDict:touch]; } - if(self->touchPointSpawnedAtUpperScreenEdge && [[event allTouches] count] == [touches count]) self->touchPointSpawnedAtUpperScreenEdge = false; + if(self->touchPointSpawnedAtUpperScreenEdge && [[event allTouches] count] == [touches count]) self->touchPointSpawnedAtUpperScreenEdge = false; //bugbugbugbugbugbugbugbug }); else{ for (UITouch* touch in touches){ diff --git a/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents b/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents index 0f4ee41f..6170214e 100644 --- a/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents +++ b/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents @@ -26,6 +26,7 @@ + diff --git a/VoidLink/Stream/StreamConfiguration.h b/VoidLink/Stream/StreamConfiguration.h index 21c38467..3be8136b 100644 --- a/VoidLink/Stream/StreamConfiguration.h +++ b/VoidLink/Stream/StreamConfiguration.h @@ -34,6 +34,7 @@ @property BOOL swapABXYButtons; @property BOOL asyncNativeTouchPriority; @property int gyroMode; +@property int emulatedControllerType; @property int audioConfiguration; @property int supportedVideoFormats; @property BOOL multiController; diff --git a/VoidLink/Stream/StreamConfiguration.m b/VoidLink/Stream/StreamConfiguration.m index 3151d80c..67329718 100644 --- a/VoidLink/Stream/StreamConfiguration.m +++ b/VoidLink/Stream/StreamConfiguration.m @@ -9,5 +9,5 @@ #import "StreamConfiguration.h" @implementation StreamConfiguration -@synthesize host, httpsPort, appID, width, height, frameRate, bitRate, riKeyId, riKey, gamepadMask, appName, optimizeGameSettings, playAudioOnPC, swapABXYButtons, gyroMode, audioConfiguration, supportedVideoFormats, multiController, serverCert, rtspSessionUrl, serverCodecModeSupport, enableYUV444, enablePIP; +@synthesize host, httpsPort, appID, width, height, frameRate, bitRate, riKeyId, riKey, gamepadMask, appName, optimizeGameSettings, playAudioOnPC, swapABXYButtons, gyroMode, emulatedControllerType, audioConfiguration, supportedVideoFormats, multiController, serverCert, rtspSessionUrl, serverCodecModeSupport, enableYUV444, enablePIP; @end diff --git a/VoidLink/ViewControllers/MainFrameViewController.m b/VoidLink/ViewControllers/MainFrameViewController.m index 46a8fb88..c398b81f 100644 --- a/VoidLink/ViewControllers/MainFrameViewController.m +++ b/VoidLink/ViewControllers/MainFrameViewController.m @@ -816,6 +816,7 @@ static NSMutableSet* hostList; _streamConfig.swapABXYButtons = streamSettings.swapABXYButtons; _streamConfig.asyncNativeTouchPriority = streamSettings.asyncNativeTouchPriority; // new streamConfig segment _streamConfig.gyroMode = [streamSettings.gyroMode intValue]; + _streamConfig.emulatedControllerType = streamSettings.emulatedControllerType.intValue; //NSLog(@"gyroMode from settings: %ld", _streamConfig.gyroMode); // multiController must be set before calling getConnectedGamepadMask @@ -1126,9 +1127,11 @@ static NSMutableSet* hostList; // enable / disable widgets acoordingly: in streamview, disable, outside of streamview, enable. if(self.settingsExpandedInStreamView) [revealController buttonsInStreaming]; else [revealController buttonsNotInStreaming]; + + DataManager* dataMan = [[DataManager alloc] init]; + TemporarySettings* currentSettings = [dataMan getSettings]; [streamFrameViewController setUserInteractionEnabledForStreamView:!_settingsExpandedInStreamView || position == FrontViewPositionLeft]; - [settingsViewController setHidden:_settingsExpandedInStreamView forStack:settingsViewController.resolutionStack]; [settingsViewController setHidden:_settingsExpandedInStreamView forStack:settingsViewController.fpsStack]; [settingsViewController widget:settingsViewController.bitrateSlider setEnabled:!self.settingsExpandedInStreamView]; @@ -1138,6 +1141,7 @@ static NSMutableSet* hostList; [settingsViewController.yuv444Switch setEnabled:!_settingsExpandedInStreamView]; [settingsViewController.hdrSwitch setEnabled:!_settingsExpandedInStreamView]; [settingsViewController.gyroModeSelector setEnabled:!_settingsExpandedInStreamView || ![streamFrameViewController shallDisableGyroHotSwitch]]; + [settingsViewController.emulatedControllerTypeSelector setEnabled:!_settingsExpandedInStreamView]; [settingsViewController setHidden:_settingsExpandedInStreamView forStack:settingsViewController.framepacingStack]; [settingsViewController setHidden:_settingsExpandedInStreamView forStack:settingsViewController.citrixX1MouseStack]; [settingsViewController setHidden:_settingsExpandedInStreamView forStack:settingsViewController.externalDisplayModeStack]; @@ -1753,7 +1757,7 @@ static NSMutableSet* hostList; object: nil]; //[self simulateSettingsButtonPress]; //force reload resolution table in the setting //[self simulateSettingsButtonPress]; - //[self updateResolutionAccordingly]; + [self updateResolutionAccordingly]; } diff --git a/VoidLink/ViewControllers/SettingsViewController.h b/VoidLink/ViewControllers/SettingsViewController.h index ae9cec6b..d4f953a6 100644 --- a/VoidLink/ViewControllers/SettingsViewController.h +++ b/VoidLink/ViewControllers/SettingsViewController.h @@ -122,6 +122,8 @@ @property (strong, nonatomic) IBOutlet UIStackView *backgroundSessionTimerStack; @property (strong, nonatomic) IBOutlet UISlider *backgroundSessionTimerSlider; +@property (strong, nonatomic) IBOutlet UIStackView *emulatedControllerTypeStack; +@property (strong, nonatomic) IBOutlet UISegmentedControl *emulatedControllerTypeSelector; #pragma clang diagnostic push diff --git a/VoidLink/ViewControllers/SettingsViewController.m b/VoidLink/ViewControllers/SettingsViewController.m index 1db931a7..63ce7e1d 100644 --- a/VoidLink/ViewControllers/SettingsViewController.m +++ b/VoidLink/ViewControllers/SettingsViewController.m @@ -35,7 +35,7 @@ CADisplayLink *_autoScrollDisplayLink; CGFloat _scrollSpeed; CGFloat _currentRefreshRate; - MenuSectionView *touchControlSection; + MenuSectionView *touchAndControlSection; NSMutableSet* hiddenStacks; NSInteger _frameQueueSize; NSInteger _graphOpacity; @@ -153,6 +153,38 @@ const int RESOLUTION_TABLE_SIZE = 6; const int RESOLUTION_TABLE_CUSTOM_INDEX = RESOLUTION_TABLE_SIZE - 1; CGSize resolutionTable[RESOLUTION_TABLE_SIZE]; +-(uint16_t)controllerTypeToSegmentIndex:(uint16_t)type{ + uint16_t index; + switch (type) { + case LI_CTYPE_XBOX: + index = 0; + break; + case LI_CTYPE_PS: + index = 1; + break; + default: + index = 2; + break; + } + return index; +} + +-(uint16_t)segmentIndexToControllerType:(uint16_t)index{ + uint16_t type; + switch (index) { + case 0: + type = LI_CTYPE_XBOX; + break; + case 1: + type = LI_CTYPE_PS; + break; + default: + type = LI_CTYPE_UNKNOWN; + break; + } + return type; +} + -(int)getSliderValueForBitrate:(NSInteger)bitrate { int i; @@ -226,7 +258,7 @@ BOOL isCustomResolution(CGSize res) { } for (int i = 0; i < RESOLUTION_TABLE_CUSTOM_INDEX; i++) { - + NSLog(@"customRes: %f, %f, isrl: %f, %f", res.width, res.height, resolutionTable[i].width, resolutionTable[i].height); if ((res.width == resolutionTable[i].width && res.height == resolutionTable[i].height) || (res.height == resolutionTable[i].width && res.width == resolutionTable[i].height)) { return NO; } @@ -256,6 +288,8 @@ BOOL isCustomResolution(CGSize res) { - (void)updateResolutionTable{ UIWindow *window = self.view.window; + NSLog(@" window %@", window); + CGFloat screenScale = window.screen.scale; CGFloat safeAreaWidth = (window.frame.size.width - window.safeAreaInsets.left - window.safeAreaInsets.right) * screenScale; CGFloat appWindowWidth = window.frame.size.width * screenScale; @@ -266,17 +300,17 @@ BOOL isCustomResolution(CGSize res) { appWindowWidth = bounds.size.width * screenScale; appWindowHeight = bounds.size.height * screenScale; } - bool needSwapWidthAndHeight = appWindowWidth > appWindowHeight; - resolutionTable[3] = CGSizeMake(safeAreaWidth, appWindowHeight); + bool needSwapWidthAndHeight = appWindowWidth < appWindowHeight; - for(uint8_t i=0;i resolutionTable[i].width ? resolutionTable[i].height : resolutionTable[i].width; CGFloat shortSideLen = resolutionTable[i].height < resolutionTable[i].width ? resolutionTable[i].height : resolutionTable[i].width; - if(needSwapWidthAndHeight) resolutionTable[i] = CGSizeMake(longSideLen, shortSideLen); - else resolutionTable[i] = CGSizeMake(shortSideLen, longSideLen); + if(needSwapWidthAndHeight) resolutionTable[i] = CGSizeMake(shortSideLen, longSideLen); + else resolutionTable[i] = CGSizeMake(longSideLen, shortSideLen); } - + + resolutionTable[3] = CGSizeMake(safeAreaWidth, appWindowHeight); resolutionTable[4] = CGSizeMake(appWindowWidth, appWindowHeight); [self updateResolutionDisplayLabel]; @@ -285,7 +319,7 @@ BOOL isCustomResolution(CGSize res) { // this will also be called back when device orientation changes - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator { [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; - double delayInSeconds = 0.2; + double delayInSeconds = 0.7; // Convert the delay into a dispatch_time_t value dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); // Perform some task after the delay @@ -295,14 +329,19 @@ BOOL isCustomResolution(CGSize res) { } - (void)viewWillAppear:(BOOL)animated{ - - [self.resolutionSelector setEnabled:!self.customResolutionSwitch.isOn]; -} + [super viewWillAppear:NO]; + } - (void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:NO]; [self updateResolutionTable]; - NSLog(@"Resolution table updated"); + [self.customResolutionSwitch addTarget:self action:@selector(customResolutionSwitched:) forControlEvents:UIControlEventValueChanged]; + + DataManager* dataMan = [[DataManager alloc] init]; + TemporarySettings *currentSettings = [dataMan getSettings]; + + CGSize currentResolution = CGSizeMake(currentSettings.width.intValue, currentSettings.height.intValue); + [self.customResolutionSwitch setOn: isCustomResolution(currentResolution)]; [self.resolutionSelector setEnabled:!self.customResolutionSwitch.isOn]; } @@ -491,22 +530,24 @@ BOOL isCustomResolution(CGSize res) { [videoSection addToParentStack:_parentStack]; [videoSection setExpanded:YES]; - touchControlSection = [[MenuSectionView alloc] init]; - touchControlSection.delegate = self; - touchControlSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Touch & Control"]; + touchAndControlSection = [[MenuSectionView alloc] init]; + touchAndControlSection.delegate = self; + touchAndControlSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Touch & Control"]; if (@available(iOS 13.0, *)) { - [touchControlSection setSectionWithIcon:[UIImage imageNamed:@"arcade.stick.console"] andSize:20.5]; + [touchAndControlSection setSectionWithIcon:[UIImage imageNamed:@"arcade.stick.console"] andSize:20.5]; } - [self addSetting:self.touchModeStack ofId:@"touchModeStack" withInfoTag:YES withDynamicLabel:NO to:touchControlSection]; - [self addSetting:self.pointerVelocityDividerStack ofId:@"pointerVelocityDividerStack" withInfoTag:YES withDynamicLabel:YES to:touchControlSection]; - [self addSetting:self.pointerVelocityFactorStack ofId:@"pointerVelocityFactorStack" withInfoTag:YES withDynamicLabel:YES to:touchControlSection]; - [self addSetting:self.mousePointerVelocityStack ofId:@"mousePointerVelocityStack" withInfoTag:NO withDynamicLabel:YES to:touchControlSection]; - [self addSetting:self.onScreenWidgetStack ofId:@"onScreenWidgetStack" withInfoTag:YES withDynamicLabel:YES to:touchControlSection]; - [self addSetting:self.swapAbaxyStack ofId:@"swapAbaxyStack" withInfoTag:NO withDynamicLabel:NO to:touchControlSection]; - [touchControlSection addToParentStack:_parentStack]; - [touchControlSection setExpanded:YES]; + [self addSetting:self.touchModeStack ofId:@"touchModeStack" withInfoTag:YES withDynamicLabel:NO to:touchAndControlSection]; + [self addSetting:self.pointerVelocityDividerStack ofId:@"pointerVelocityDividerStack" withInfoTag:YES withDynamicLabel:YES to:touchAndControlSection]; + [self addSetting:self.pointerVelocityFactorStack ofId:@"pointerVelocityFactorStack" withInfoTag:YES withDynamicLabel:YES to:touchAndControlSection]; + [self addSetting:self.mousePointerVelocityStack ofId:@"mousePointerVelocityStack" withInfoTag:NO withDynamicLabel:YES to:touchAndControlSection]; + [self addSetting:self.onScreenWidgetStack ofId:@"onScreenWidgetStack" withInfoTag:YES withDynamicLabel:YES to:touchAndControlSection]; + [self addSetting:self.swapAbaxyStack ofId:@"swapAbaxyStack" withInfoTag:NO withDynamicLabel:NO to:touchAndControlSection]; + [self addSetting:self.emulatedControllerTypeStack ofId:@"emulatedControllerTypeStack" withInfoTag:YES withDynamicLabel:NO to:touchAndControlSection]; + [self addSetting:self.gyroModeStack ofId:@"gyroModeStack" withInfoTag:YES withDynamicLabel:YES to:touchAndControlSection]; + [self addSetting:self.gyroSensitivityStack ofId:@"gyroSensitivityStack" withInfoTag:NO withDynamicLabel:YES to:touchAndControlSection]; + [touchAndControlSection addToParentStack:_parentStack]; + [touchAndControlSection setExpanded:YES]; - MenuSectionView *gesturesSection = [[MenuSectionView alloc] init]; gesturesSection.delegate = self; gesturesSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Gestures"]; @@ -574,8 +615,6 @@ BOOL isCustomResolution(CGSize res) { [experimentalSection setSectionWithIcon:[UIImage imageNamed:@"flask"] andSize:20]; } [self addSetting:self.touchMoveEventIntervalStack ofId:@"touchMoveEventIntervalStack" withInfoTag:YES withDynamicLabel:YES to:experimentalSection]; - [self addSetting:self.gyroModeStack ofId:@"gyroModeStack" withInfoTag:YES withDynamicLabel:YES to:experimentalSection]; - [self addSetting:self.gyroSensitivityStack ofId:@"gyroSensitivityStack" withInfoTag:NO withDynamicLabel:YES to:experimentalSection]; [experimentalSection addToParentStack:_parentStack]; [experimentalSection setExpanded:YES]; } @@ -1177,13 +1216,7 @@ BOOL isCustomResolution(CGSize res) { resolutionTable[3] = CGSizeMake(safeAreaWidth, fullScreenHeight); resolutionTable[4] = CGSizeMake(fullScreenWidth, fullScreenHeight); resolutionTable[5] = CGSizeMake([currentSettings.width integerValue], [currentSettings.height integerValue]); // custom initial value - [self updateResolutionTable]; - // Don't populate the custom entry unless we have a custom resolution - //self.customResolutionSwitch - if (!isCustomResolution(resolutionTable[5])) { - resolutionTable[5] = CGSizeMake(0, 0); - } NSInteger framerate; switch ([currentSettings.framerate integerValue]) { @@ -1279,15 +1312,16 @@ BOOL isCustomResolution(CGSize res) { [self.gyroSensitivitySlider setValue: (uint16_t)(currentSettings.gyroSensitivity.floatValue * 100) animated:YES]; // Load old setting. [self.gyroSensitivitySlider addTarget:self action:@selector(gyroSensitivitySliderMoved:) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved. [self gyroSensitivitySliderMoved:self.gyroSensitivitySlider]; - + + [self.emulatedControllerTypeSelector setSelectedSegmentIndex:[self controllerTypeToSegmentIndex:currentSettings.emulatedControllerType.intValue]]; + [self.emulatedControllerTypeSelector addTarget:self action:@selector(emulatedControllerTypeChanged:) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved. + [self emulatedControllerTypeChanged:self.emulatedControllerTypeSelector]; + [self.audioOnPcSwitch setOn:currentSettings.playAudioOnPC]; _lastSelectedResolutionIndex = resolution; [self.resolutionSelector setSelectedSegmentIndex:resolution]; [self.resolutionSelector addTarget:self action:@selector(newResolutionChosen) forControlEvents:UIControlEventValueChanged]; - [self.customResolutionSwitch addTarget:self action:@selector(customResolutionSwitched:) forControlEvents:UIControlEventValueChanged]; - CGSize currentResolution = CGSizeMake(currentSettings.width.intValue, currentSettings.height.intValue); - [self.customResolutionSwitch setOn: isCustomResolution(currentResolution)]; [self.framerateSelector setSelectedSegmentIndex:framerate]; [self.framerateSelector addTarget:self action:@selector(updateBitrate) forControlEvents:UIControlEventValueChanged]; @@ -1638,7 +1672,13 @@ BOOL isCustomResolution(CGSize res) { [self setHidden:![self isNotNativeTouchOnly] forStack:self.swapAbaxyStack]; [self handleOswGestureChange]; - [touchControlSection updateViewForFoldState]; + [touchAndControlSection updateViewForFoldState]; +} + +- (void)emulatedControllerTypeChanged:(UISegmentedControl* )sender{ + [self setHidden:sender.selectedSegmentIndex == 0 forStack:_gyroModeStack]; + [self setHidden:sender.selectedSegmentIndex == 0 forStack:_gyroSensitivityStack]; + [touchAndControlSection updateViewForFoldState]; } - (void)setHidden:(BOOL)hidden forStack:(UIStackView* )stack{ @@ -1656,10 +1696,10 @@ BOOL isCustomResolution(CGSize res) { - (void)enableOswForNativeTouchSwitchFlipped:(UISwitch *)sender{ //self.onScreenWidgetStack.hidden = !sender.isOn; [self setHidden:!sender.isOn forStack:_onScreenWidgetStack]; - [self setHidden:!sender.isOn forStack:_swapAbaxyStack]; + //[self setHidden:!sender.isOn forStack:_swapAbaxyStack]; [self handleOswGestureChange]; //self.swapAbaxyStack.hidden = !sender.isOn; - [touchControlSection updateViewForFoldState]; + [touchAndControlSection updateViewForFoldState]; } - (void) updateBitrate { @@ -2029,6 +2069,7 @@ BOOL isCustomResolution(CGSize res) { BOOL multiController = self.multiControllerSwitch.isOn; BOOL swapABXYButtons = [self.swapABXYButtonsSelector selectedSegmentIndex] == 1; NSInteger gyroMode = self.gyroModeSelector.selectedSegmentIndex; + NSInteger emulatedControllerType = [self segmentIndexToControllerType:self.emulatedControllerTypeSelector.selectedSegmentIndex]; //self.emulatedControllerTypeSelector.selectedSegmentIndex; BOOL audioOnPC = self.audioOnPcSwitch.isOn; uint32_t preferredCodec = [self getChosenCodecPreference]; BOOL enableYUV444 = self.yuv444Switch.isOn; @@ -2045,6 +2086,7 @@ BOOL isCustomResolution(CGSize res) { NSInteger externalDisplayMode = [self.externalDisplayModeSelector selectedSegmentIndex]; NSInteger localMousePointerMode = [self.localMousePointerModeSelector selectedSegmentIndex]; NSInteger backgroundSessionTimer = self.backgroundSessionTimerSlider.value == self.backgroundSessionTimerSlider.maximumValue ? (uint32_t) INT16_MAX : (uint32_t)self.backgroundSessionTimerSlider.value; + [dataMan saveSettingsWithBitrate:_bitrate framerate:framerate height:height @@ -2052,6 +2094,7 @@ BOOL isCustomResolution(CGSize res) { audioConfig:audioConfig onscreenControls:onscreenControls gyroMode:gyroMode + emulatedControllerType:emulatedControllerType keyboardToggleFingers:keyboardToggleFingers oscLayoutToolFingers:oscLayoutToolFingers slideToSettingsScreenEdge:slideToSettingsScreenEdge diff --git a/VoidLink/mul.lproj/iPad.xcstrings b/VoidLink/mul.lproj/iPad.xcstrings index 0870c224..c438cc0e 100644 --- a/VoidLink/mul.lproj/iPad.xcstrings +++ b/VoidLink/mul.lproj/iPad.xcstrings @@ -1765,6 +1765,90 @@ } } }, + "JaY-XA-1V6.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; JaY-XA-1V6.segmentTitles[0] = \"Xbox 360\"; ObjectID = \"JaY-XA-1V6\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Xbox 360" + } + } + } + }, + "JaY-XA-1V6.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; JaY-XA-1V6.segmentTitles[1] = \"DS4\"; ObjectID = \"JaY-XA-1V6\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "DS4" + } + } + } + }, + "JaY-XA-1V6.segmentTitles[2]" : { + "comment" : "Class = \"UISegmentedControl\"; JaY-XA-1V6.segmentTitles[2] = \"Both\"; ObjectID = \"JaY-XA-1V6\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Both" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "同时映射" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "同時映射" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "同時映射" + } + } + } + }, + "JTl-un-QJJ.text" : { + "comment" : "Class = \"UILabel\"; text = \"Emulated Controller Type\"; ObjectID = \"JTl-un-QJJ\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Emulated Controller Type" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "手柄映射类型" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "手把映射類型" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "手把映射類型" + } + } + } + }, "kho-5R-daP.segmentTitles[0]" : { "comment" : "Class = \"UISegmentedControl\"; kho-5R-daP.segmentTitles[0] = \"3 Finger Tap\"; ObjectID = \"kho-5R-daP\";", "extractionState" : "extracted_with_value", diff --git a/VoidLink/mul.lproj/iPhone.xcstrings b/VoidLink/mul.lproj/iPhone.xcstrings index a6c47209..7e5bdfff 100644 --- a/VoidLink/mul.lproj/iPhone.xcstrings +++ b/VoidLink/mul.lproj/iPhone.xcstrings @@ -1255,6 +1255,36 @@ } } }, + "dUM-r9-0Bo.text" : { + "comment" : "Class = \"UILabel\"; text = \"Emulated Controller Type\"; ObjectID = \"dUM-r9-0Bo\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Emulated Controller Type" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "手柄映射类型" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "手把映射類型" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "手把映射類型" + } + } + } + }, "E7F-vx-pnM.text" : { "comment" : "Class = \"UILabel\"; text = \"Frame Rate\"; ObjectID = \"E7F-vx-pnM\";", "extractionState" : "extracted_with_value", @@ -2305,6 +2335,60 @@ } } }, + "q6v-Jb-ysy.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; q6v-Jb-ysy.segmentTitles[0] = \"Xbox 360\"; ObjectID = \"q6v-Jb-ysy\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Xbox 360" + } + } + } + }, + "q6v-Jb-ysy.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; q6v-Jb-ysy.segmentTitles[1] = \"DS4\"; ObjectID = \"q6v-Jb-ysy\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "DS4" + } + } + } + }, + "q6v-Jb-ysy.segmentTitles[2]" : { + "comment" : "Class = \"UISegmentedControl\"; q6v-Jb-ysy.segmentTitles[2] = \"Both\"; ObjectID = \"q6v-Jb-ysy\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Both" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "同时映射" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "同時映射" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "同時映射" + } + } + } + }, "qeW-hW-tSL.text" : { "comment" : "Class = \"UILabel\"; text = \"Audio Configuration\"; ObjectID = \"qeW-hW-tSL\";", "extractionState" : "extracted_with_value",