diff --git a/Limelight/Base.lproj/iPad.storyboard b/Limelight/Base.lproj/iPad.storyboard index 3a0c1f79..0b777799 100644 --- a/Limelight/Base.lproj/iPad.storyboard +++ b/Limelight/Base.lproj/iPad.storyboard @@ -500,8 +500,8 @@ ICAgICAgICAgICAgICA - - + + @@ -535,6 +535,7 @@ ICAgICAgICAgICAgICA + @@ -542,7 +543,6 @@ ICAgICAgICAgICAgICA - diff --git a/Limelight/Base.lproj/iPhone.storyboard b/Limelight/Base.lproj/iPhone.storyboard index 9c24d32a..611765bc 100644 --- a/Limelight/Base.lproj/iPhone.storyboard +++ b/Limelight/Base.lproj/iPhone.storyboard @@ -552,6 +552,7 @@ ICAgICAgICAgICAgIA + @@ -559,7 +560,6 @@ ICAgICAgICAgICAgIA - diff --git a/Limelight/Database/DataManager.h b/Limelight/Database/DataManager.h index 78bbbe66..d1a5d226 100644 --- a/Limelight/Database/DataManager.h +++ b/Limelight/Database/DataManager.h @@ -26,7 +26,7 @@ pointerVelocityModeDivider:(CGFloat)pointerVelocityModeDivider touchPointerVelocityFactor:(CGFloat)touchPointerVelocityFactor mousePointerVelocityFactor:(CGFloat)mousePointerVelocityFactor - oscVisualFeedback:(BOOL)oscVisualFeedback + largerStickLR1:(BOOL)largerStickLR1 liftStreamViewForKeyboard:(BOOL)liftStreamViewForKeyboard showKeyboardToolbar:(BOOL)showKeyboardToolbar optimizeGames:(BOOL)optimizeGames diff --git a/Limelight/Database/DataManager.m b/Limelight/Database/DataManager.m index ae852178..09f78c5b 100644 --- a/Limelight/Database/DataManager.m +++ b/Limelight/Database/DataManager.m @@ -65,7 +65,7 @@ pointerVelocityModeDivider:(CGFloat)pointerVelocityModeDivider touchPointerVelocityFactor:(CGFloat)touchPointerVelocityFactor mousePointerVelocityFactor:(CGFloat)mousePointerVelocityFactor - oscVisualFeedback:(BOOL)oscVisualFeedback + largerStickLR1:(BOOL)largerStickLR1 liftStreamViewForKeyboard:(BOOL)liftStreamViewForKeyboard showKeyboardToolbar:(BOOL)showKeyboardToolbar optimizeGames:(BOOL)optimizeGames @@ -96,7 +96,7 @@ settingsToSave.pointerVelocityModeDivider = [NSNumber numberWithFloat:pointerVelocityModeDivider]; settingsToSave.touchPointerVelocityFactor = [NSNumber numberWithFloat:touchPointerVelocityFactor]; settingsToSave.mousePointerVelocityFactor = [NSNumber numberWithFloat:mousePointerVelocityFactor]; - settingsToSave.oscVisualFeedback = oscVisualFeedback; + settingsToSave.largerStickLR1 = largerStickLR1; settingsToSave.liftStreamViewForKeyboard = liftStreamViewForKeyboard; settingsToSave.showKeyboardToolbar = showKeyboardToolbar; settingsToSave.optimizeGames = optimizeGames; diff --git a/Limelight/Database/TemporarySettings.h b/Limelight/Database/TemporarySettings.h index 9d3f6d17..c9fed339 100644 --- a/Limelight/Database/TemporarySettings.h +++ b/Limelight/Database/TemporarySettings.h @@ -38,7 +38,7 @@ CODEC_PREF_HEVC, CODEC_PREF_AV1, } preferredCodec; -@property (nonatomic) BOOL oscVisualFeedback; +@property (nonatomic) BOOL largerStickLR1; @property (nonatomic) BOOL useFramePacing; @property (nonatomic) BOOL multiController; @property (nonatomic) BOOL swapABXYButtons; diff --git a/Limelight/Database/TemporarySettings.m b/Limelight/Database/TemporarySettings.m index 9588c34e..b96825a1 100644 --- a/Limelight/Database/TemporarySettings.m +++ b/Limelight/Database/TemporarySettings.m @@ -82,7 +82,7 @@ self.multiController = settings.multiController; self.swapABXYButtons = settings.swapABXYButtons; self.onscreenControls = settings.onscreenControls; - self.oscVisualFeedback = settings.oscVisualFeedback; + self.largerStickLR1 = settings.largerStickLR1; self.btMouseSupport = settings.btMouseSupport; // self.absoluteTouchMode = settings.absoluteTouchMode; self.touchMode = settings.touchMode; diff --git a/Limelight/Images.xcassets/StartButton.imageset/StickInner.imageset/Contents.json b/Limelight/Images.xcassets/StartButton.imageset/StickInner.imageset/Contents.json new file mode 100755 index 00000000..6b13eb09 --- /dev/null +++ b/Limelight/Images.xcassets/StartButton.imageset/StickInner.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x", + "filename" : "stick_inner_48x49@1x.png" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "stick_inner_96x97@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x", + "filename" : "stick_inner_144x146@3x.png" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Limelight/Images.xcassets/StartButton.imageset/StickInner.imageset/stick_inner_144x146@3x.png b/Limelight/Images.xcassets/StartButton.imageset/StickInner.imageset/stick_inner_144x146@3x.png new file mode 100755 index 00000000..e32c054e Binary files /dev/null and b/Limelight/Images.xcassets/StartButton.imageset/StickInner.imageset/stick_inner_144x146@3x.png differ diff --git a/Limelight/Images.xcassets/StartButton.imageset/StickInner.imageset/stick_inner_48x49@1x.png b/Limelight/Images.xcassets/StartButton.imageset/StickInner.imageset/stick_inner_48x49@1x.png new file mode 100755 index 00000000..8c18094a Binary files /dev/null and b/Limelight/Images.xcassets/StartButton.imageset/StickInner.imageset/stick_inner_48x49@1x.png differ diff --git a/Limelight/Images.xcassets/StartButton.imageset/StickInner.imageset/stick_inner_96x97@2x.png b/Limelight/Images.xcassets/StartButton.imageset/StickInner.imageset/stick_inner_96x97@2x.png new file mode 100755 index 00000000..7041ec37 Binary files /dev/null and b/Limelight/Images.xcassets/StartButton.imageset/StickInner.imageset/stick_inner_96x97@2x.png differ diff --git a/Limelight/Images.xcassets/StickInner.imageset/Contents.json b/Limelight/Images.xcassets/StickInner.imageset/Contents.json old mode 100644 new mode 100755 diff --git a/Limelight/Images.xcassets/StickInner.imageset/stick_inner_144x146@3x.png b/Limelight/Images.xcassets/StickInner.imageset/stick_inner_144x146@3x.png old mode 100644 new mode 100755 index 5471a5a2..e32c054e Binary files a/Limelight/Images.xcassets/StickInner.imageset/stick_inner_144x146@3x.png and b/Limelight/Images.xcassets/StickInner.imageset/stick_inner_144x146@3x.png differ diff --git a/Limelight/Images.xcassets/StickInner.imageset/stick_inner_48x49@1x.png b/Limelight/Images.xcassets/StickInner.imageset/stick_inner_48x49@1x.png old mode 100644 new mode 100755 index 779c6a27..8c18094a Binary files a/Limelight/Images.xcassets/StickInner.imageset/stick_inner_48x49@1x.png and b/Limelight/Images.xcassets/StickInner.imageset/stick_inner_48x49@1x.png differ diff --git a/Limelight/Images.xcassets/StickInner.imageset/stick_inner_96x97@2x.png b/Limelight/Images.xcassets/StickInner.imageset/stick_inner_96x97@2x.png old mode 100644 new mode 100755 index c09763ab..7041ec37 Binary files a/Limelight/Images.xcassets/StickInner.imageset/stick_inner_96x97@2x.png and b/Limelight/Images.xcassets/StickInner.imageset/stick_inner_96x97@2x.png differ diff --git a/Limelight/Input/CustomOSC/LayoutOnScreenControls.m b/Limelight/Input/CustomOSC/LayoutOnScreenControls.m index 889f5c58..e2a04f68 100644 --- a/Limelight/Input/CustomOSC/LayoutOnScreenControls.m +++ b/Limelight/Input/CustomOSC/LayoutOnScreenControls.m @@ -50,6 +50,7 @@ - (void) drawButtons { [super setDPadCenter]; // Set custom position for D-Pad here [super setAnalogStickPositions]; // Set custom position for analog sticks here + [super drawBumpers]; [super drawButtons]; UIImage* downButtonImage = [UIImage imageNamed:@"DownButton"]; diff --git a/Limelight/Input/OnScreenControls.h b/Limelight/Input/OnScreenControls.h index fccd4a9e..6b2dbcc5 100644 --- a/Limelight/Input/OnScreenControls.h +++ b/Limelight/Input/OnScreenControls.h @@ -75,6 +75,7 @@ typedef NS_ENUM(NSInteger, OnScreenControlsLevel) { - (void) show; - (void) setupComplexControls; - (void) drawButtons; +- (void) drawBumpers; - (void) updateControls; - (OnScreenControlsLevel) getLevel; - (void) setDPadCenter; diff --git a/Limelight/Input/OnScreenControls.m b/Limelight/Input/OnScreenControls.m index 6d2f34f6..16fd4530 100644 --- a/Limelight/Input/OnScreenControls.m +++ b/Limelight/Input/OnScreenControls.m @@ -57,7 +57,7 @@ static NSMutableSet* touchAddrsCapturedByOnScreenControls; Controller *_controller; NSMutableArray* _deadTouches; BOOL _swapABXY; - BOOL _visualFeedback; + BOOL _largerStickLR1; OSCProfilesManager *profilesManager; NSMutableDictionary *_activeCustomOscButtonPositionDict; } @@ -146,8 +146,12 @@ static float L3_Y; _deadTouches = [[NSMutableArray alloc] init]; if (streamConfig) { _swapABXY = streamConfig.swapABXYButtons; - _visualFeedback = streamConfig.oscVisualFeedback; // turn visual feedback of the OSC buttons on or off } + // we have to retrieve largerStickLR1 setting direct from the database, since streamConfig is invalid in LayoutOnScreenControls + DataManager* dataMan = [[DataManager alloc] init]; + Settings* settings = [dataMan retrieveSettings]; + _largerStickLR1 = settings.largerStickLR1; + _iPad = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad); _controlArea = CGRectMake(0, 0, _view.frame.size.width, _view.frame.size.height); @@ -595,8 +599,12 @@ static float L3_Y; /** * Loads the selected OSC profile and lays out each button associated with that profile onto the screen */ + +# define LR2_Y_UP_OFFSET 8 +# define LR1_Y_DOWN_OFFSET 3.5 - (void) positionOSCButtons { OSCProfile *oscProfile = [profilesManager getSelectedProfile]; + bool defaultProfileSelected = [profilesManager getIndexOfSelectedProfile] == 0; for (NSData *buttonStateEncoded in oscProfile.buttonStates) { @@ -605,17 +613,20 @@ static float L3_Y; for (CALayer *buttonLayer in self.OSCButtonLayers) { // iterate through each button layer on screen and position and hide/unhide each according to the instructions of its associated 'buttonState' if ([buttonLayer.name isEqualToString:buttonStateDecoded.name]) { - if ([buttonLayer.name isEqualToString:@"upButton"] == NO && [buttonLayer.name isEqualToString:@"rightButton"] == NO && [buttonLayer.name isEqualToString:@"downButton"] == NO && [buttonLayer.name isEqualToString:@"leftButton"] == NO && [buttonLayer.name isEqualToString:@"leftStick"] == NO && [buttonLayer.name isEqualToString:@"rightStick"] == NO) { // Don't move these buttons since they've already been positioned correctly in the 'drawButtons' and 'drawSticks' methods called before this method is called. The 'buttonStateDecoded' object associated with these buttons contains positions relative to a parent CALayer which only exists on 'LayoutOnScreenControls'. These positions relative to the parent layers would translate incorrectly when placed on the game stream VC's 'view' layer - buttonLayer.position = buttonStateDecoded.position; } buttonLayer.hidden = buttonStateDecoded.isHidden; + + // adjust default layout for largerStickLR1 + if( defaultProfileSelected && _largerStickLR1) + if([buttonLayer.name isEqualToString:@"l2Button"] || [buttonLayer.name isEqualToString:@"r2Button"]) buttonLayer.position = CGPointMake(buttonLayer.position.x, buttonLayer.position.y - LR2_Y_UP_OFFSET); + if([buttonLayer.name isEqualToString:@"l1Button"] || [buttonLayer.name isEqualToString:@"r1Button"]) buttonLayer.position = CGPointMake(buttonLayer.position.x, buttonLayer.position.y + LR1_Y_DOWN_OFFSET); } } } @@ -636,6 +647,9 @@ static float L3_Y; } - (void) drawBumpers { + // adjust layout for larger L2 & R2 button settings + if(_largerStickLR1) L1_Y = R1_Y = L1_Y + LR1_Y_DOWN_OFFSET; + // create L1 button UIImage* l1ButtonImage = [UIImage imageNamed:@"L1"]; _l1Button.frame = CGRectMake(L1_X - l1ButtonImage.size.width / 2, L1_Y - l1ButtonImage.size.height / 2, l1ButtonImage.size.width, l1ButtonImage.size.height); @@ -646,10 +660,20 @@ static float L3_Y; UIImage* r1ButtonImage = [UIImage imageNamed:@"R1"]; _r1Button.frame = CGRectMake(R1_X - r1ButtonImage.size.width / 2, R1_Y - r1ButtonImage.size.height / 2, r1ButtonImage.size.width, r1ButtonImage.size.height); _r1Button.contents = (id) r1ButtonImage.CGImage; + + // make l1 r1 the same size as l2 r2 + if(_largerStickLR1){ + UIImage* l2ButtonImage = [UIImage imageNamed:@"L2"]; + _l1Button.bounds = _r1Button.bounds = CGRectMake(0, 0, l2ButtonImage.size.width, l2ButtonImage.size.height); + } + [_view.layer addSublayer:_r1Button]; } - (void) drawTriggers { + // adjust layout for larger L2 & R2 button settings + if(_largerStickLR1) L2_Y = R2_Y = L2_Y - LR2_Y_UP_OFFSET; + // create L2 button UIImage* l2ButtonImage = [UIImage imageNamed:@"L2"]; _l2Button.frame = CGRectMake(L2_X - l2ButtonImage.size.width / 2, L2_Y - l2ButtonImage.size.height / 2, l2ButtonImage.size.width, l2ButtonImage.size.height); @@ -681,13 +705,27 @@ static float L3_Y; _rightStickBackground.contents = (id) rightStickBgImage.CGImage; [_view.layer addSublayer:_rightStickBackground]; + + UIImage* rightStickImage = [UIImage imageNamed:@"StickInner"]; _rightStick.frame = CGRectMake(RS_CENTER_X - rightStickImage.size.width / 2, RS_CENTER_Y - rightStickImage.size.height / 2, rightStickImage.size.width, rightStickImage.size.height); + _rightStick.contents = (id) rightStickImage.CGImage; [_view.layer addSublayer:_rightStick]; - STICK_INNER_SIZE = rightStickImage.size.width; - STICK_OUTER_SIZE = rightStickBgImage.size.width; + // make stick larger + if(_largerStickLR1){ + STICK_INNER_SIZE = rightStickImage.size.width *1.37; + STICK_OUTER_SIZE = rightStickBgImage.size.width *1.17; + _rightStick.bounds = _leftStick.bounds = CGRectMake(0, 0, STICK_INNER_SIZE, STICK_INNER_SIZE); + _rightStickBackground.bounds = _leftStickBackground.bounds = CGRectMake(0, 0, STICK_OUTER_SIZE, STICK_OUTER_SIZE); + } + else{ + STICK_INNER_SIZE = rightStickImage.size.width; + STICK_OUTER_SIZE = rightStickBgImage.size.width; + _rightStick.bounds = _leftStick.bounds = CGRectMake(0, 0, STICK_INNER_SIZE, STICK_INNER_SIZE); + _rightStickBackground.bounds = _leftStickBackground.bounds = CGRectMake(0, 0, STICK_OUTER_SIZE, STICK_OUTER_SIZE); + } } - (void) drawL3R3 { @@ -861,7 +899,6 @@ static float L3_Y; - (void)oscButtonTouchDownVisualEffect:(CALayer* )button{ - if(_visualFeedback){ [CATransaction begin]; [CATransaction setDisableActions:YES]; // Disable implicit animations @@ -883,7 +920,6 @@ static float L3_Y; button.shadowOpacity = 1.0; button.shadowRadius = 0.0; // Adjust the radius to simulate border thickness [CATransaction commit]; - } } diff --git a/Limelight/Limelight.xcdatamodeld/Moonlight v1.10.xcdatamodel/contents b/Limelight/Limelight.xcdatamodeld/Moonlight v1.10.xcdatamodel/contents index 0ab0c38f..2256759e 100644 --- a/Limelight/Limelight.xcdatamodeld/Moonlight v1.10.xcdatamodel/contents +++ b/Limelight/Limelight.xcdatamodeld/Moonlight v1.10.xcdatamodel/contents @@ -30,13 +30,13 @@ + - diff --git a/Limelight/Stream/StreamConfiguration.h b/Limelight/Stream/StreamConfiguration.h index 501d83df..3073ea62 100644 --- a/Limelight/Stream/StreamConfiguration.h +++ b/Limelight/Stream/StreamConfiguration.h @@ -26,7 +26,7 @@ @property BOOL optimizeGameSettings; @property BOOL playAudioOnPC; @property BOOL swapABXYButtons; -@property BOOL oscVisualFeedback; +@property BOOL largerStickLR1; @property int audioConfiguration; @property int supportedVideoFormats; @property BOOL multiController; diff --git a/Limelight/ViewControllers/MainFrameViewController.m b/Limelight/ViewControllers/MainFrameViewController.m index 9b5ae776..4886ee05 100644 --- a/Limelight/ViewControllers/MainFrameViewController.m +++ b/Limelight/ViewControllers/MainFrameViewController.m @@ -668,7 +668,7 @@ static NSMutableSet* hostList; _streamConfig.playAudioOnPC = streamSettings.playAudioOnPC; _streamConfig.useFramePacing = streamSettings.useFramePacing; _streamConfig.swapABXYButtons = streamSettings.swapABXYButtons; - _streamConfig.oscVisualFeedback = streamSettings.oscVisualFeedback; // new streamConfig segment + _streamConfig.largerStickLR1 = streamSettings.largerStickLR1; // new streamConfig segment // multiController must be set before calling getConnectedGamepadMask _streamConfig.multiController = streamSettings.multiController; diff --git a/Limelight/ViewControllers/SettingsViewController.h b/Limelight/ViewControllers/SettingsViewController.h index ba97b173..ed273a44 100644 --- a/Limelight/ViewControllers/SettingsViewController.h +++ b/Limelight/ViewControllers/SettingsViewController.h @@ -22,7 +22,7 @@ @property (strong, nonatomic) IBOutlet UISegmentedControl *touchModeSelector; @property (strong, nonatomic) IBOutlet UILabel *onscreenControllerLabel; @property (strong, nonatomic) IBOutlet UISegmentedControl *onscreenControlSelector; -@property (strong, nonatomic) IBOutlet UISegmentedControl *oscVisualFeedbackSelector; +@property (strong, nonatomic) IBOutlet UISegmentedControl *largerStickLR1Selector; @property (strong, nonatomic) IBOutlet UISegmentedControl *optimizeSettingsSelector; @property (strong, nonatomic) IBOutlet UISegmentedControl *multiControllerSelector; @property (strong, nonatomic) IBOutlet UISegmentedControl *swapABXYButtonsSelector; diff --git a/Limelight/ViewControllers/SettingsViewController.m b/Limelight/ViewControllers/SettingsViewController.m index b3e6ddb4..cc8682b0 100644 --- a/Limelight/ViewControllers/SettingsViewController.m +++ b/Limelight/ViewControllers/SettingsViewController.m @@ -441,10 +441,10 @@ BOOL isCustomResolution(CGSize res) { [self.onscreenControlSelector setSelectedSegmentIndex:onscreenControlsLevel]; [self.onscreenControlSelector addTarget:self action:@selector(onscreenControlChanged) forControlEvents:UIControlEventValueChanged]; [self onscreenControlChanged]; - [self.oscVisualFeedbackSelector setSelectedSegmentIndex:currentSettings.oscVisualFeedback ? 1 : 0]; // load old setting of oscVisualFeedback + [self.largerStickLR1Selector setSelectedSegmentIndex:currentSettings.largerStickLR1 ? 1 : 0]; // load old setting of largerStickLR1 // [self.touchModeSelector setSelectedSegmentIndex:currentSettings.absoluteTouchMode ? 1 : 0]; - // this part will enable/disable oscSelector & the visual feedback selector + // this part will enable/disable oscSelector & the largerStickLR1 selector [self.touchModeSelector setSelectedSegmentIndex:currentSettings.touchMode.intValue]; //Load old touchMode setting [self.touchModeSelector addTarget:self action:@selector(touchModeChanged) forControlEvents:UIControlEventValueChanged]; [self touchModeChanged]; @@ -635,7 +635,7 @@ BOOL isCustomResolution(CGSize res) { bool isNativeTouch = [self.touchModeSelector selectedSegmentIndex] == PURE_NATIVE_TOUCH || [self.touchModeSelector selectedSegmentIndex] == REGULAR_NATIVE_TOUCH; [self.onscreenControlSelector setEnabled:oscSelectorEnabled]; - [self.oscVisualFeedbackSelector setEnabled:oscSelectorEnabled]; // this selector stay aligned with oscSelector + [self.largerStickLR1Selector setEnabled:oscSelectorEnabled]; // this selector stay aligned with oscSelector [self widget:self.pointerVelocityModeDividerSlider setEnabled:isNativeTouch]; // pointer velocity scaling works only in native touch mode. [self widget:self.touchPointerVelocityFactorSlider setEnabled:isNativeTouch]; // pointer velocity scaling works only in native touch mode. @@ -945,7 +945,7 @@ BOOL isCustomResolution(CGSize res) { CGFloat pointerVelocityModeDivider = (CGFloat)(uint8_t)self.pointerVelocityModeDividerSlider.value/100; CGFloat touchPointerVelocityFactor =(CGFloat)(uint16_t)[self map_velocFactorDisplay_fromSliderValue:self.touchPointerVelocityFactorSlider.value]/100; CGFloat mousePointerVelocityFactor =(CGFloat)(uint16_t)self.mousePointerVelocityFactorSlider.value/100; - BOOL oscVisualFeedback = [self.oscVisualFeedbackSelector selectedSegmentIndex] == 1; + BOOL largerStickLR1 = [self.largerStickLR1Selector selectedSegmentIndex] == 1; BOOL liftStreamViewForKeyboard = [self.liftStreamViewForKeyboardSelector selectedSegmentIndex] == 1; BOOL showKeyboardToolbar = [self.showKeyboardToolbarSelector selectedSegmentIndex] == 1; BOOL optimizeGames = [self.optimizeSettingsSelector selectedSegmentIndex] == 1; @@ -973,7 +973,7 @@ BOOL isCustomResolution(CGSize res) { pointerVelocityModeDivider:pointerVelocityModeDivider touchPointerVelocityFactor:touchPointerVelocityFactor mousePointerVelocityFactor:mousePointerVelocityFactor - oscVisualFeedback:oscVisualFeedback + largerStickLR1:largerStickLR1 liftStreamViewForKeyboard:liftStreamViewForKeyboard showKeyboardToolbar:showKeyboardToolbar optimizeGames:optimizeGames diff --git a/Limelight/mul.lproj/iPad.xcstrings b/Limelight/mul.lproj/iPad.xcstrings index dc736f8b..f41f324f 100644 --- a/Limelight/mul.lproj/iPad.xcstrings +++ b/Limelight/mul.lproj/iPad.xcstrings @@ -2,31 +2,31 @@ "sourceLanguage" : "en", "strings" : { "2Bp-XZ-cCw.text" : { - "comment" : "Class = \"UILabel\"; text = \"Turn on On-Screen Controls Visual Feedback \"; ObjectID = \"2Bp-XZ-cCw\";", + "comment" : "Class = \"UILabel\"; text = \"Larger Sticks & L1/R1 Buttons\"; ObjectID = \"2Bp-XZ-cCw\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Turn on On-Screen Controls Visual Feedback " + "value" : "Larger Sticks & L1/R1 Buttons" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "打开屏显手柄视觉反馈" + "value" : "更大的摇杆和L1/R1按键" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "打开屏显手柄视觉反馈" + "value" : "更大的摇杆和L1/R1按键" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "打开屏显手柄视觉反馈" + "value" : "更大的摇杆和L1/R1按键" } } }