diff --git a/DS4Windows/App.xaml.cs b/DS4Windows/App.xaml.cs index dacfcfb5..2baa5c09 100644 --- a/DS4Windows/App.xaml.cs +++ b/DS4Windows/App.xaml.cs @@ -1193,10 +1193,11 @@ private void SetUICulture(string culture) CultureInfo ci = CultureInfo.GetCultureInfo(culture); LocalizeDictionary.Instance.SetCurrentThreadCulture = true; LocalizeDictionary.Instance.Culture = ci; + DS4Forms.RuntimeXamlTranslator.Initialize(ci); // fixes the culture in threads CultureInfo.DefaultThreadCurrentCulture = ci; CultureInfo.DefaultThreadCurrentUICulture = ci; - //DS4WinWPF.Properties.Resources.Culture = ci; + DS4WinWPF.Properties.Resources.Culture = ci; Thread.CurrentThread.CurrentCulture = ci; Thread.CurrentThread.CurrentUICulture = ci; } diff --git a/DS4Windows/DS4Forms/AudioHapticsControl.xaml.cs b/DS4Windows/DS4Forms/AudioHapticsControl.xaml.cs index 5e90bc96..56ed5c97 100644 --- a/DS4Windows/DS4Forms/AudioHapticsControl.xaml.cs +++ b/DS4Windows/DS4Forms/AudioHapticsControl.xaml.cs @@ -277,8 +277,8 @@ private void UpdateStatus(AudioHapticsProfileSettings settings) { if (settings == null) { - statusText.Text = "Select a controller"; - sourceStatusText.Text = "No source"; + statusText.Text = Properties.Resources.AHStatusSelectController; + sourceStatusText.Text = Properties.Resources.AHStatusNoSource; statusDot.Fill = FindBrush("MutedForegroundColor", Brushes.Gray); return; } @@ -286,7 +286,7 @@ private void UpdateStatus(AudioHapticsProfileSettings settings) sourceStatusText.Text = SourceDisplayName(settings); if (!settings.Enabled) { - statusText.Text = "Off"; + statusText.Text = Properties.Resources.AHStatusOff; statusDot.Fill = FindBrush("MutedForegroundColor", Brushes.Gray); return; } @@ -296,7 +296,7 @@ private void UpdateStatus(AudioHapticsProfileSettings settings) Program.rootHub?.DS4Controllers[deviceIndex] != null; if (!liveController) { - statusText.Text = "Saved to profile"; + statusText.Text = Properties.Resources.AHStatusSavedToProfile; statusDot.Fill = FindBrush("AccentColor", Brushes.DodgerBlue); return; } @@ -304,7 +304,7 @@ private void UpdateStatus(AudioHapticsProfileSettings settings) AudioHapticsRuntimeStatus runtime = Program.rootHub.GetAudioHapticsStatus(deviceIndex); statusText.Text = runtime.Active && - !settings.AutomaticGameDetection ? "Active" : runtime.Message; + !settings.AutomaticGameDetection ? Properties.Resources.AHStatusActive : runtime.Message; statusDot.Fill = runtime.Active ? FindBrush("SuccessColor", Brushes.LimeGreen) : FindBrush("AccentColor", Brushes.DodgerBlue); @@ -312,13 +312,13 @@ private void UpdateStatus(AudioHapticsProfileSettings settings) private static string SourceDisplayName(AudioHapticsProfileSettings settings) => settings.Source switch { - AudioHapticsSourceKind.ControllerAudio => "Controller audio", + AudioHapticsSourceKind.ControllerAudio => Properties.Resources.AHSourceControllerAudio, AudioHapticsSourceKind.AppSession when - settings.AutomaticGameDetection => "Automatic game detection", + settings.AutomaticGameDetection => Properties.Resources.AHSourceAutoGameDetection, AudioHapticsSourceKind.AppSession => string.IsNullOrWhiteSpace(settings.DisplayName) - ? (string.IsNullOrWhiteSpace(settings.ExecutableName) ? "Selected app" : settings.ExecutableName) + ? (string.IsNullOrWhiteSpace(settings.ExecutableName) ? Properties.Resources.AHSourceSelectedApp : settings.ExecutableName) : settings.DisplayName, - _ => "System audio · default output", + _ => Properties.Resources.AHSourceSystemAudioDefault, }; private Brush FindBrush(string key, Brush fallback) => TryFindResource(key) as Brush ?? fallback; diff --git a/DS4Windows/DS4Forms/MappingLiveInputControl.xaml.cs b/DS4Windows/DS4Forms/MappingLiveInputControl.xaml.cs index 8f6c287f..65ca733a 100644 --- a/DS4Windows/DS4Forms/MappingLiveInputControl.xaml.cs +++ b/DS4Windows/DS4Forms/MappingLiveInputControl.xaml.cs @@ -82,7 +82,7 @@ internal void RenderSnapshot(DS4State raw, InputDeviceType type) { projection.Update(raw, type); if (!projection.Valid) { RenderStatus(MappingLiveInputStatus.Waiting); return; } - liveStatus.Text = "Live"; + liveStatus.Text = Properties.Resources.MLLive; RenderStick(leftStickPlot, leftStickDot, leftStickValue, projection.LeftX, projection.LeftY, projection.LeftPresent); RenderStick(rightStickPlot, rightStickDot, rightStickValue, projection.RightX, projection.RightY, projection.RightPresent); leftTriggerName.Text = projection.LeftTriggerName; @@ -91,7 +91,7 @@ internal void RenderSnapshot(DS4State raw, InputDeviceType type) rightTriggerMeter.Value = projection.RightTrigger; leftTriggerValue.Text = $"{projection.LeftTrigger:0}%"; rightTriggerValue.Text = $"{projection.RightTrigger:0}%"; - pressedButtons.Text = projection.PressedButtons.Length == 0 ? "No buttons pressed" : projection.PressedButtons; + pressedButtons.Text = projection.PressedButtons.Length == 0 ? Properties.Resources.MLNoButtonsPressed : projection.PressedButtons; pressedButtons.ToolTip = pressedButtons.Text; } @@ -110,21 +110,22 @@ internal void RenderStatus(MappingLiveInputStatus status) { liveStatus.Text = status switch { - MappingLiveInputStatus.Disconnected => "Disconnected", - MappingLiveInputStatus.Replaced => "Controller changed", - MappingLiveInputStatus.Stale => "No recent input", - _ => "Waiting" + MappingLiveInputStatus.Disconnected => Properties.Resources.Disconnected, + MappingLiveInputStatus.Replaced => Properties.Resources.MLControllerChanged, + MappingLiveInputStatus.Stale => Properties.Resources.MLNoRecentInput, + _ => Properties.Resources.MLWaiting }; pressedButtons.Text = status switch { - MappingLiveInputStatus.Replaced => "Reopen the editor to preview the new controller.", - MappingLiveInputStatus.Disconnected => "Controller disconnected. Reconnect and reopen the editor.", - MappingLiveInputStatus.Stale => "Waiting for fresh controller input…", - _ => snapshot.HasBoundDevice ? "Waiting for controller input…" : - "Open this profile from a connected controller." + MappingLiveInputStatus.Replaced => Properties.Resources.MLReopenForNewController, + MappingLiveInputStatus.Disconnected => Properties.Resources.MLControllerDisconnectedReopen, + MappingLiveInputStatus.Stale => Properties.Resources.MLWaitingForFreshInput, + _ => snapshot.HasBoundDevice ? Properties.Resources.MLWaitingForInput : + Properties.Resources.MLOpenFromConnectedController }; pressedButtons.ToolTip = pressedButtons.Text; - leftStickValue.Text = rightStickValue.Text = "X —\nY —"; + leftStickValue.Text = rightStickValue.Text = + DS4WinWPF.Translations.Strings.ResourceManager.GetString("MappingLive.AxisPlaceholder", DS4WinWPF.Translations.Strings.Culture); leftTriggerValue.Text = rightTriggerValue.Text = "—"; leftTriggerMeter.Value = rightTriggerMeter.Value = 0; leftStickPlot.Opacity = rightStickPlot.Opacity = 0.35; diff --git a/DS4Windows/DS4Forms/RuntimeXamlTranslator.cs b/DS4Windows/DS4Forms/RuntimeXamlTranslator.cs new file mode 100644 index 00000000..67ddcba7 --- /dev/null +++ b/DS4Windows/DS4Forms/RuntimeXamlTranslator.cs @@ -0,0 +1,231 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Text.RegularExpressions; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Documents; +using DS4WinWPF.Translations; + +namespace DS4WinWPF.DS4Forms +{ + /// + /// Translates plain English text written directly in XAML (Text, Content, Header, + /// ToolTip, Title, and inline Runs) when the selected language is not English. + /// XAML keeps its English literals, so markup stays readable and tests that inspect + /// it keep working; the English value in Translations/Strings.resx is the lookup key. + /// Bound and styled values are left alone, and text already localized through + /// {lex:Loc} no longer matches an English entry. + /// + internal static class RuntimeXamlTranslator + { + private static readonly Regex Whitespace = new(@"\s+", RegexOptions.Compiled); + private static readonly ConditionalWeakTable visited = new(); + + private static Dictionary> exactKeys; + private static Dictionary> looseKeys; + private static Dictionary englishValues; + private static CultureInfo culture; + private static bool registered; + + internal static void Initialize(CultureInfo selectedCulture) + { + culture = selectedCulture; + if (culture.TwoLetterISOLanguageName == "en" || culture.Equals(CultureInfo.InvariantCulture)) + { + exactKeys = null; + looseKeys = null; + return; + } + + BuildLookup(); + if (!registered) + { + // Loaded is only broadcast to elements with instance handlers, so it would + // skip most controls. Every element gets SizeChanged on its first layout, + // before it is rendered, including template and late-shown content. + EventManager.RegisterClassHandler(typeof(FrameworkElement), FrameworkElement.SizeChangedEvent, + new SizeChangedEventHandler(OnElementSized), true); + registered = true; + } + } + + private static void BuildLookup() + { + exactKeys = new Dictionary>(StringComparer.Ordinal); + looseKeys = new Dictionary>(StringComparer.Ordinal); + englishValues = new Dictionary(StringComparer.Ordinal); + ResourceSet english = Strings.ResourceManager.GetResourceSet(CultureInfo.InvariantCulture, true, true); + if (english == null) + { + return; + } + + foreach (DictionaryEntry entry in english.Cast().OrderBy(entry => (string)entry.Key, StringComparer.Ordinal)) + { + if (entry.Value is not string value || string.IsNullOrWhiteSpace(value)) + { + continue; + } + + string key = (string)entry.Key; + englishValues[key] = value; + AddKey(exactKeys, value, key); + AddKey(looseKeys, Loose(value), key); + } + } + + private static void AddKey(Dictionary> lookup, string text, string key) + { + if (!lookup.TryGetValue(text, out List keys)) + { + lookup[text] = keys = new List(); + } + + keys.Add(key); + } + + private static string Loose(string text) => + Whitespace.Replace(text, string.Empty).ToLowerInvariant(); + + internal static string Translate(string english) + { + if (exactKeys == null || string.IsNullOrWhiteSpace(english)) + { + return null; + } + + // The same English text can live under several keys; use the first one the + // selected language actually translates. + string normalized = Whitespace.Replace(english, " ").Trim(); + IEnumerable candidates = Candidates(exactKeys, english) + .Concat(Candidates(exactKeys, normalized)) + .Concat(Candidates(looseKeys, Loose(english))); + foreach (string key in candidates) + { + string translated = Strings.ResourceManager.GetString(key, culture); + if (!string.IsNullOrEmpty(translated) && translated != englishValues[key]) + { + return translated; + } + } + + return null; + } + + private static IEnumerable Candidates(Dictionary> lookup, string text) => + lookup.TryGetValue(text, out List keys) ? keys : Enumerable.Empty(); + + private static void OnElementSized(object sender, SizeChangedEventArgs e) + { + if (exactKeys == null || sender is not FrameworkElement element || + visited.TryGetValue(element, out _)) + { + return; + } + + visited.Add(element, null); + + TranslateProperty(element, FrameworkElement.ToolTipProperty); + switch (element) + { + case Window: + TranslateProperty(element, Window.TitleProperty); + break; + case TextBlock textBlock: + TranslateTextBlock(textBlock); + break; + case HeaderedContentControl: + TranslateProperty(element, HeaderedContentControl.HeaderProperty); + break; + case HeaderedItemsControl: + TranslateProperty(element, HeaderedItemsControl.HeaderProperty); + break; + case ListView { View: GridView gridView }: + foreach (GridViewColumn column in gridView.Columns) + { + TranslateProperty(column, GridViewColumn.HeaderProperty); + } + break; + } + + if (element is ContentControl) + { + TranslateProperty(element, ContentControl.ContentProperty); + } + } + + private static void TranslateTextBlock(TextBlock textBlock) + { + // A set Text (literal or bound) is mirrored into an internal Run, so the + // inlines are only examined when the text came from element content. + if (textBlock.ReadLocalValue(TextBlock.TextProperty) != DependencyProperty.UnsetValue) + { + TranslateProperty(textBlock, TextBlock.TextProperty); + return; + } + + // Literal element content becomes Runs; translate the whole block when it is + // plain text, otherwise each Run (e.g. inside a Hyperlink) on its own. + if (textBlock.Inlines.All(inline => inline is Run or LineBreak) && + textBlock.Inlines.OfType().All(IsLocalLiteral)) + { + string combined = string.Concat(textBlock.Inlines.Select(inline => inline is Run run ? run.Text : "\n")); + string translated = Translate(combined); + if (translated != null) + { + textBlock.Inlines.Clear(); + textBlock.Inlines.Add(new Run(translated)); + return; + } + } + + TranslateInlines(textBlock.Inlines); + } + + private static void TranslateInlines(InlineCollection inlines) + { + foreach (Inline inline in inlines.ToList()) + { + switch (inline) + { + case Run run: + TranslateProperty(run, Run.TextProperty); + break; + case Span span: + TranslateInlines(span.Inlines); + break; + } + } + } + + private static bool IsLocalLiteral(DependencyObject target) => + IsLocalLiteral(target, Run.TextProperty); + + // A binding or markup extension is stored as an expression, not a string, so + // only text that was written as a literal is ever replaced. + private static bool IsLocalLiteral(DependencyObject target, DependencyProperty property) => + target.ReadLocalValue(property) is string; + + private static bool TranslateProperty(DependencyObject target, DependencyProperty property) + { + if (target.GetValue(property) is not string english || !IsLocalLiteral(target, property)) + { + return false; + } + + string translated = Translate(english); + if (translated == null) + { + return false; + } + + target.SetValue(property, translated); + return true; + } + } +} diff --git a/DS4Windows/DS4Forms/Switch2StickCalibrationWindow.xaml.cs b/DS4Windows/DS4Forms/Switch2StickCalibrationWindow.xaml.cs index 16766d2e..7f1fbf22 100644 --- a/DS4Windows/DS4Forms/Switch2StickCalibrationWindow.xaml.cs +++ b/DS4Windows/DS4Forms/Switch2StickCalibrationWindow.xaml.cs @@ -36,7 +36,7 @@ internal Switch2StickCalibrationWindow(Switch2RuntimeInputDevice runtime) private async void Reset_Click(object sender, RoutedEventArgs e) { if (viewModel.CanStart && MessageBox.Show(this, viewModel.ResetConfirmation, - "Reset PC stick calibration", MessageBoxButton.YesNo, MessageBoxImage.Question, + Properties.Resources.Switch2CalibResetDialogTitle, MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.Yes) await viewModel.ResetAsync(); } diff --git a/DS4Windows/DS4Forms/TriggerLabControl.xaml.cs b/DS4Windows/DS4Forms/TriggerLabControl.xaml.cs index f31fbb69..f012c38d 100644 --- a/DS4Windows/DS4Forms/TriggerLabControl.xaml.cs +++ b/DS4Windows/DS4Forms/TriggerLabControl.xaml.cs @@ -65,39 +65,39 @@ private sealed class FullPullModeChoice { new FullPullModeChoice { - Name = "Off", + Name = Properties.Resources.TLModeOff, Mode = TwoStageTriggerMode.Disabled, - Description = "Only the regular trigger action runs.", + Description = Properties.Resources.TLModeOffDesc, }, new FullPullModeChoice { - Name = "Add at full pull", + Name = Properties.Resources.TLModeAddAtFullPull, Mode = TwoStageTriggerMode.Normal, - Description = "Keep the regular trigger action active and also run the full-pull action at the end of travel.", + Description = Properties.Resources.TLModeAddAtFullPullDesc, }, new FullPullModeChoice { - Name = "Replace at full pull", + Name = Properties.Resources.TLModeReplaceAtFullPull, Mode = TwoStageTriggerMode.ExclusiveButtons, - Description = "Release the regular trigger action and replace it with the full-pull action at the end of travel.", + Description = Properties.Resources.TLModeReplaceAtFullPullDesc, }, new FullPullModeChoice { - Name = "Hair trigger", + Name = Properties.Resources.TLModeHairTrigger, Mode = TwoStageTriggerMode.HairTrigger, - Description = "Run both actions at full pull, then release both as soon as the trigger backs away from the end stop.", + Description = Properties.Resources.TLModeHairTriggerDesc, }, new FullPullModeChoice { - Name = "Hip fire", + Name = Properties.Resources.TLModeHipFire, Mode = TwoStageTriggerMode.HipFire, - Description = "Wait for the chosen delay, then run the regular or full-pull action based on how far the trigger was pressed.", + Description = Properties.Resources.TLModeHipFireDesc, }, new FullPullModeChoice { - Name = "Hip fire (exclusive)", + Name = Properties.Resources.TLModeHipFireExclusive, Mode = TwoStageTriggerMode.HipFireExclusiveButtons, - Description = "Wait for the chosen delay and run only one action: regular pull or full pull.", + Description = Properties.Resources.TLModeHipFireExclusiveDesc, }, }; @@ -183,7 +183,7 @@ public void RefreshSettings() IsEnabled = available; if (!available) { - labStatusText.Text = "Select a controller or profile to open Trigger Lab."; + labStatusText.Text = Properties.Resources.TLSelectToOpen; return; } @@ -231,13 +231,13 @@ private UIElement BuildSideCard(SideUi ui) }; heading.Children.Add(triggerGraphic); StackPanel title = new StackPanel { VerticalAlignment = VerticalAlignment.Center }; - title.Children.Add(new TextBlock { Text = ui.IsLeft ? "Left Trigger" : "Right Trigger", FontSize = 17, FontWeight = FontWeights.SemiBold }); - title.Children.Add(new TextBlock { Text = $"Shape the {(ui.IsLeft ? "L2" : "R2")} trigger feel", Foreground = FindBrush("MutedForegroundColor", Brushes.Gray) }); + title.Children.Add(new TextBlock { Text = ui.IsLeft ? Properties.Resources.TLLeftTrigger : Properties.Resources.TLRightTrigger, FontSize = 17, FontWeight = FontWeights.SemiBold }); + title.Children.Add(new TextBlock { Text = string.Format(Properties.Resources.TLShapeTriggerFeelFormat, ui.IsLeft ? "L2" : "R2"), Foreground = FindBrush("MutedForegroundColor", Brushes.Gray) }); Grid.SetColumn(title, 1); heading.Children.Add(title); StackPanel active = new StackPanel { Orientation = Orientation.Horizontal, VerticalAlignment = VerticalAlignment.Center }; ui.ActiveLabel = new TextBlock { - Text = "Active", + Text = Properties.Resources.TLActiveLabel, Margin = new Thickness(0, 0, 8, 0), VerticalAlignment = VerticalAlignment.Center, }; @@ -255,9 +255,9 @@ private UIElement BuildSideCard(SideUi ui) profileRow.Children.Add(ui.Profile); StackPanel profileActions = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(8, 0, 0, 0) }; Grid.SetColumn(profileActions, 1); - profileActions.Children.Add(MakeIconButton("\uE74E", "Save new trigger profile", (_, _) => SaveCustomProfile(ui))); - ui.RenameProfile = MakeIconButton("\uE70F", "Rename trigger profile", (_, _) => RenameCustomProfile(ui)); - ui.DeleteProfile = MakeIconButton("\uE74D", "Delete trigger profile", (_, _) => DeleteCustomProfile(ui)); + profileActions.Children.Add(MakeIconButton("\uE74E", Properties.Resources.TLSaveProfileTip, (_, _) => SaveCustomProfile(ui))); + ui.RenameProfile = MakeIconButton("\uE70F", Properties.Resources.TLRenameProfileTip, (_, _) => RenameCustomProfile(ui)); + ui.DeleteProfile = MakeIconButton("\uE74D", Properties.Resources.TLDeleteProfileTip, (_, _) => DeleteCustomProfile(ui)); profileActions.Children.Add(ui.RenameProfile); profileActions.Children.Add(ui.DeleteProfile); profileRow.Children.Add(profileActions); @@ -272,24 +272,24 @@ private UIElement BuildSideCard(SideUi ui) Grid modes = new Grid(); for (int i = 0; i < 3; i++) modes.ColumnDefinitions.Add(new ColumnDefinition()); - ui.Feedback = MakeModeButton("Feedback", ui, TriggerLabMode.Feedback, 0); - ui.Weapon = MakeModeButton("Weapon", ui, TriggerLabMode.Weapon, 1); - ui.Vibration = MakeModeButton("Vibration", ui, TriggerLabMode.Vibration, 2); + ui.Feedback = MakeModeButton(Properties.Resources.TLModeFeedback, ui, TriggerLabMode.Feedback, 0); + ui.Weapon = MakeModeButton(Properties.Resources.TLModeWeapon, ui, TriggerLabMode.Weapon, 1); + ui.Vibration = MakeModeButton(Properties.Resources.TLModeVibration, ui, TriggerLabMode.Vibration, 2); modes.Children.Add(ui.Feedback); modes.Children.Add(ui.Weapon); modes.Children.Add(ui.Vibration); root.Children.Add(modes); - root.Children.Add(MakeMeter("Start", ui, out ui.Start, out ui.StartValue)); - root.Children.Add(MakeMeter("Wall", ui, out ui.Wall, out ui.WallValue)); - root.Children.Add(MakeMeter("Force", ui, out ui.Force, out ui.ForceValue)); + root.Children.Add(MakeMeter(Properties.Resources.TLMeterStart, "Start", ui, out ui.Start, out ui.StartValue)); + root.Children.Add(MakeMeter(Properties.Resources.TLMeterWall, "Wall", ui, out ui.Wall, out ui.WallValue)); + root.Children.Add(MakeMeter(Properties.Resources.TLMeterForce, "Force", ui, out ui.Force, out ui.ForceValue)); root.Children.Add(BuildFullPullSection(ui)); root.Children.Add(BuildGameRumbleVibrationSection(ui)); Grid actions = new Grid { Margin = new Thickness(0, 14, 0, 0) }; actions.ColumnDefinitions.Add(new ColumnDefinition()); actions.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(8) }); actions.ColumnDefinitions.Add(new ColumnDefinition()); - Button preview = new Button { Content = "\u25B6 Preview", MinHeight = 38, Style = FindResource("BridgeSecondaryButtonStyle") as Style }; + Button preview = new Button { Content = "\u25B6 " + Properties.Resources.TLPreview, MinHeight = 38, Style = FindResource("BridgeSecondaryButtonStyle") as Style }; preview.Click += (_, _) => Preview(ui); - Button reset = new Button { Content = $"\u21BB Reset {(ui.IsLeft ? "L2" : "R2")}", MinHeight = 38, Style = FindResource("BridgeSecondaryButtonStyle") as Style }; + Button reset = new Button { Content = "\u21BB " + string.Format(Properties.Resources.TLResetFormat, ui.IsLeft ? "L2" : "R2"), MinHeight = 38, Style = FindResource("BridgeSecondaryButtonStyle") as Style }; reset.Click += (_, _) => ResetSide(ui); Grid.SetColumn(reset, 2); actions.Children.Add(preview); actions.Children.Add(reset); root.Children.Add(actions); return root; @@ -307,13 +307,15 @@ private Border BuildGameRumbleVibrationSection(SideUi ui) StackPanel copy = new StackPanel(); copy.Children.Add(new TextBlock { - Text = "Game rumble vibration", + Text = Properties.Resources.TLGameRumbleTitle, FontSize = 15, FontWeight = FontWeights.SemiBold, }); copy.Children.Add(new TextBlock { - Text = $"Stream the game's {(ui.IsLeft ? "heavy / left" : "light / right")} HID rumble motor to {(ui.IsLeft ? "L2" : "R2")} as a low-latency vibration effect.", + Text = string.Format(Properties.Resources.TLGameRumbleDescFormat, + ui.IsLeft ? Properties.Resources.TLHeavyLeft : Properties.Resources.TLLightRight, + ui.IsLeft ? "L2" : "R2"), Margin = new Thickness(0, 4, 14, 0), Foreground = FindBrush("MutedForegroundColor", Brushes.Gray), TextWrapping = TextWrapping.Wrap, @@ -324,7 +326,7 @@ private Border BuildGameRumbleVibrationSection(SideUi ui) { Style = FindResource("LabToggle") as Style, VerticalAlignment = VerticalAlignment.Center, - ToolTip = $"Independently enable game-rumble vibration for {(ui.IsLeft ? "L2" : "R2")}. This does not link the other trigger.", + ToolTip = string.Format(Properties.Resources.TLGameRumbleTipFormat, ui.IsLeft ? "L2" : "R2"), }; ui.GameRumbleVibration.Click += (_, _) => GameRumbleVibrationChanged(ui); @@ -361,7 +363,7 @@ private Border BuildFullPullSection(SideUi ui) }); heading.Children.Add(new TextBlock { - Text = "Full-pull action", + Text = Properties.Resources.TLFullPullActionTitle, FontSize = 15, FontWeight = FontWeights.SemiBold, VerticalAlignment = VerticalAlignment.Center, @@ -375,7 +377,7 @@ private Border BuildFullPullSection(SideUi ui) Padding = new Thickness(7, 3, 7, 3), Child = new TextBlock { - Text = "END OF TRAVEL", + Text = Properties.Resources.TLEndOfTravelBadge, FontSize = 9, FontWeight = FontWeights.Bold, Foreground = FindBrush("MutedForegroundColor", Brushes.Gray), @@ -386,7 +388,7 @@ private Border BuildFullPullSection(SideUi ui) content.Children.Add(heading); content.Children.Add(new TextBlock { - Text = $"When {(ui.IsLeft ? "L2" : "R2")} is pressed completely, run the action below using the selected behavior.", + Text = string.Format(Properties.Resources.TLFullPullDescFormat, ui.IsLeft ? "L2" : "R2"), Margin = new Thickness(0, 4, 0, 10), Foreground = FindBrush("MutedForegroundColor", Brushes.Gray), TextWrapping = TextWrapping.Wrap, @@ -401,14 +403,14 @@ private Border BuildFullPullSection(SideUi ui) StackPanel actionText = new StackPanel(); actionText.Children.Add(new TextBlock { - Text = "Assigned action", + Text = Properties.Resources.TLAssignedActionLabel, FontSize = 10, FontWeight = FontWeights.SemiBold, Foreground = FindBrush("MutedForegroundColor", Brushes.Gray), }); ui.FullPullActionName = new TextBlock { - Text = "Unassigned", + Text = Properties.Resources.Unassigned, Margin = new Thickness(0, 2, 10, 0), FontWeight = FontWeights.SemiBold, TextTrimming = TextTrimming.CharacterEllipsis, @@ -417,7 +419,7 @@ private Border BuildFullPullSection(SideUi ui) actionContent.Children.Add(actionText); TextBlock changeLabel = new TextBlock { - Text = "Change ›", + Text = Properties.Resources.TLChangeLabel, Foreground = FindBrush("AccentColor", Brushes.DodgerBlue), FontWeight = FontWeights.SemiBold, VerticalAlignment = VerticalAlignment.Center, @@ -449,7 +451,7 @@ private Border BuildFullPullSection(SideUi ui) modeRow.ColumnDefinitions.Add(new ColumnDefinition()); modeRow.Children.Add(new TextBlock { - Text = "Behavior", + Text = Properties.Resources.TLBehaviorLabel, FontWeight = FontWeights.SemiBold, Foreground = FindBrush("MutedForegroundColor", Brushes.Gray), VerticalAlignment = VerticalAlignment.Center, @@ -490,7 +492,7 @@ private Border BuildFullPullSection(SideUi ui) }); ui.HipFireDelayRow.Children.Add(new TextBlock { - Text = "Delay", + Text = Properties.Resources.TLDelayLabel, FontWeight = FontWeights.SemiBold, Foreground = FindBrush("MutedForegroundColor", Brushes.Gray), VerticalAlignment = VerticalAlignment.Center, @@ -550,7 +552,7 @@ private Button MakeModeButton(string text, SideUi ui, TriggerLabMode mode, int c return button; } - private Grid MakeMeter(string label, SideUi ui, out Slider slider, out TextBlock value) + private Grid MakeMeter(string label, string property, SideUi ui, out Slider slider, out TextBlock value) { Grid grid = new Grid { Margin = new Thickness(0, 15, 0, 0) }; grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(46) }); @@ -561,7 +563,6 @@ private Grid MakeMeter(string label, SideUi ui, out Slider slider, out TextBlock Grid.SetColumn(slider, 1); grid.Children.Add(slider); value = new TextBlock { HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Center, FontWeight = FontWeights.SemiBold }; Grid.SetColumn(value, 2); grid.Children.Add(value); - string property = label; slider.ValueChanged += (_, e) => MeterChanged(ui, property, (int)e.NewValue); return grid; } @@ -581,7 +582,7 @@ private void LoadSide(SideUi ui, TriggerLabEffectSettings effect, { Id = profile.Id, Name = profile.Name, - Description = "Saved custom effect.", + Description = Properties.Resources.TLSavedCustomEffect, IsCustom = true, })); ui.Profile.ItemsSource = profiles; @@ -626,7 +627,7 @@ private void RefreshFullPullUi(SideUi ui) ui.HipFireDelay.IsEnabled = available; if (!available) { - ui.FullPullActionName.Text = "Select a controller or profile"; + ui.FullPullActionName.Text = Properties.Resources.TLSelectControllerOrProfile; ui.FullPullModeDescription.Text = string.Empty; ui.HipFireDelayRow.Visibility = Visibility.Collapsed; return; @@ -916,7 +917,7 @@ private static string EnsureAutoCustomProfile(TriggerLabProfileSettings settings .FirstOrDefault(profile => profile.Id == profileId); if (custom == null) { - custom = new TriggerLabCustomProfile { Id = "custom", Name = "Custom" }; + custom = new TriggerLabCustomProfile { Id = "custom", Name = Properties.Resources.TLCustom }; settings.CustomProfiles.Insert(0, custom); } custom.Mode = effect.Mode; custom.StartPercent = effect.StartPercent; custom.WallPercent = effect.WallPercent; custom.ForcePercent = effect.ForcePercent; @@ -925,7 +926,7 @@ private static string EnsureAutoCustomProfile(TriggerLabProfileSettings settings private void SaveCustomProfile(SideUi ui) { - string name = PromptName("Save trigger profile", $"Custom Trigger {CurrentSettings.CustomProfiles.Count + 1}"); + string name = PromptName(Properties.Resources.TLSaveProfileDialogTitle, string.Format(Properties.Resources.TLDefaultCustomTriggerNameFormat, CurrentSettings.CustomProfiles.Count + 1)); if (string.IsNullOrWhiteSpace(name)) return; Commit(settings => { @@ -941,7 +942,7 @@ private void RenameCustomProfile(SideUi ui) { TriggerLabCustomProfile profile = CurrentSettings.CustomProfiles.FirstOrDefault(item => item.Id == CurrentEffect(ui).ProfileId); if (profile == null) return; - string name = PromptName("Rename trigger profile", profile.Name); + string name = PromptName(Properties.Resources.TLRenameProfileTip, profile.Name); if (string.IsNullOrWhiteSpace(name)) return; Commit(settings => profile.Name = name); } @@ -950,7 +951,7 @@ private void DeleteCustomProfile(SideUi ui) { TriggerLabCustomProfile profile = CurrentSettings.CustomProfiles.FirstOrDefault(item => item.Id == CurrentEffect(ui).ProfileId); if (profile == null) return; - if (MessageBox.Show($"Delete {profile.Name}?", "Trigger Lab", MessageBoxButton.YesNo, MessageBoxImage.Warning) != MessageBoxResult.Yes) return; + if (MessageBox.Show(string.Format(Properties.Resources.TLDeleteConfirmFormat, profile.Name), Properties.Resources.TLDialogTitle, MessageBoxButton.YesNo, MessageBoxImage.Warning) != MessageBoxResult.Yes) return; Commit(settings => { settings.CustomProfiles.Remove(profile); @@ -969,8 +970,8 @@ private string PromptName(string title, string initial) TextBox text = new TextBox { Text = initial, MaxLength = 48, MinHeight = 36, VerticalContentAlignment = VerticalAlignment.Center }; grid.Children.Add(text); StackPanel buttons = new StackPanel { Orientation = Orientation.Horizontal, HorizontalAlignment = HorizontalAlignment.Right, Margin = new Thickness(0, 14, 0, 0) }; - Button cancel = new Button { Content = "Cancel", Width = 86, Height = 34, IsCancel = true }; - Button save = new Button { Content = "Save", Width = 86, Height = 34, Margin = new Thickness(8, 0, 0, 0), IsDefault = true, Style = FindResource("BridgePrimaryButtonStyle") as Style }; + Button cancel = new Button { Content = Properties.Resources.Cancel, Width = 86, Height = 34, IsCancel = true }; + Button save = new Button { Content = Properties.Resources.Save, Width = 86, Height = 34, Margin = new Thickness(8, 0, 0, 0), IsDefault = true, Style = FindResource("BridgePrimaryButtonStyle") as Style }; save.Click += (_, _) => dialog.DialogResult = true; buttons.Children.Add(cancel); buttons.Children.Add(save); Grid.SetRow(buttons, 1); grid.Children.Add(buttons); dialog.Content = grid; text.SelectAll(); text.Focus(); diff --git a/DS4Windows/DS4Forms/ViewModels/Switch2StickCalibrationViewModel.cs b/DS4Windows/DS4Forms/ViewModels/Switch2StickCalibrationViewModel.cs index bbe30c3c..0f95e8b2 100644 --- a/DS4Windows/DS4Forms/ViewModels/Switch2StickCalibrationViewModel.cs +++ b/DS4Windows/DS4Forms/ViewModels/Switch2StickCalibrationViewModel.cs @@ -47,16 +47,16 @@ internal Switch2StickCalibrationViewModel(Switch2RuntimeInputDevice runtime) InputDeviceType.Switch2JoyConRight => new[] { Switch2StickSide.Right }, _ => throw new ArgumentException("A Switch 2 controller is required.", nameof(runtime)), }; - SideLabels = Array.ConvertAll(sides, side => side == Switch2StickSide.Left ? "Left stick" : "Right stick"); + SideLabels = Array.ConvertAll(sides, side => side == Switch2StickSide.Left ? Properties.Resources.Switch2CalibLeftStick : Properties.Resources.Switch2CalibRightStick); ControllerLabel = runtime.DeviceType switch { - InputDeviceType.Switch2Pro => "Switch 2 Pro Controller", - InputDeviceType.Switch2JoyConJoined => "Joined Joy-Con 2", - InputDeviceType.Switch2JoyConLeft => "Joy-Con 2 (Left)", - _ => "Joy-Con 2 (Right)", - } + (runtime.Transport == Switch2Transport.Usb ? " · USB" : " · Bluetooth"); - Heading = "Choose a physical stick"; - Instructions = "Rotate the selected stick around its full edge, then let it rest in the center. Nothing is saved until you choose Save calibration."; + InputDeviceType.Switch2Pro => Properties.Resources.Switch2CalibProControllerName, + InputDeviceType.Switch2JoyConJoined => Properties.Resources.Switch2CalibJoinedJoyCon, + InputDeviceType.Switch2JoyConLeft => Properties.Resources.Switch2CalibJoyConLeft, + _ => Properties.Resources.Switch2CalibJoyConRight, + } + (runtime.Transport == Switch2Transport.Usb ? Properties.Resources.Switch2CalibUsbSuffix : Properties.Resources.Switch2CalibBluetoothSuffix); + Heading = Properties.Resources.Switch2CalibChoosePhysicalStick; + Instructions = Properties.Resources.Switch2CalibInitialInstructions; Poll(); } @@ -76,19 +76,19 @@ public int SelectedSideIndex public string SelectedSideLabel => SideLabels[selectedSideIndex]; public string CalibrationStatus => (sides[selectedSideIndex] == Switch2StickSide.Left ? runtime.HasLocalLeftStickCalibration : runtime.HasLocalRightStickCalibration) ? - "PC calibration is active for this stick." : "Using original controller calibration, or defaults if unavailable."; + Properties.Resources.Switch2CalibPcActive : Properties.Resources.Switch2CalibUsingOriginal; public string Heading { get; private set; } public string Instructions { get; private set; } public string ResultText { get; private set; } = string.Empty; public double Progress { get; private set; } - public string ProgressLabel { get; private set; } = "Not started"; + public string ProgressLabel { get; private set; } = Properties.Resources.Switch2CalibNotStarted; public bool IsBusy => busy; public bool CanStart => !closed && !busy && operation == null && ContextIsCurrent; public bool CanChooseSide => CanStart; public bool CanSave => !closed && !busy && operation != null && stage == Switch2RawStickCalibrationStage.Ready && ContextIsCurrent; public bool CanCancel => !closed && operation != null; - public string ResetConfirmation => $"Remove the PC calibration for the {SelectedSideLabel.ToLowerInvariant()} on this controller?\n\nThe original factory calibration will not be changed. Other sticks and controllers are unaffected."; + public string ResetConfirmation => string.Format(Properties.Resources.Switch2CalibResetConfirmFormat, SelectedSideLabel.ToLowerInvariant()); private bool ContextIsCurrent => !contextEnded && runtime.RuntimeState == Switch2RuntimeInputDeviceState.Active && @@ -109,10 +109,10 @@ private async Task BeginAsync(bool reset) var selected = sides[selectedSideIndex]; busy = true; ResultText = string.Empty; - Heading = reset ? "Preparing reset" : "Preparing calibration"; - Instructions = "Releasing this controller's mapped input…"; + Heading = reset ? Properties.Resources.Switch2CalibPreparingReset : Properties.Resources.Switch2CalibPreparingCalibration; + Instructions = Properties.Resources.Switch2CalibReleasingInput; Progress = 0; - ProgressLabel = "Please wait"; + ProgressLabel = Properties.Resources.Switch2CalibPleaseWait; RaiseAll(); Switch2RawStickCalibrationOperation started = null; var beginCancellation = new CancellationTokenSource(); @@ -128,9 +128,9 @@ private async Task BeginAsync(bool reset) } if (started == null) { - Heading = "Calibration could not start"; - Instructions = "Wait for live controller input and finish any other calibration, then try again. A remembered controller identity and writable PC calibration store are required."; - ProgressLabel = "Not started"; + Heading = Properties.Resources.Switch2CalibCouldNotStart; + Instructions = Properties.Resources.Switch2CalibCouldNotStartDetail; + ProgressLabel = Properties.Resources.Switch2CalibNotStarted; return false; } operation = started; @@ -140,7 +140,7 @@ private async Task BeginAsync(bool reset) catch { if (started != null) runtime.CancelRawStickCalibration(started); - if (!closed) ResultText = "Calibration could not start. No calibration was saved."; + if (!closed) ResultText = Properties.Resources.Switch2CalibCouldNotStartError; return false; } finally @@ -158,10 +158,10 @@ public async Task SaveAsync() var saving = operation; string side = SelectedSideLabel; busy = true; - Heading = saving.Reset ? "Resetting PC calibration" : "Saving PC calibration"; - Instructions = "Controller input remains released while the result is stored and applied."; + Heading = saving.Reset ? Properties.Resources.Switch2CalibResettingPc : Properties.Resources.Switch2CalibSavingPc; + Instructions = Properties.Resources.Switch2CalibInputReleasedWhileSaving; ResultText = string.Empty; - ProgressLabel = "Please wait"; + ProgressLabel = Properties.Resources.Switch2CalibPleaseWait; RaiseAll(); try { @@ -171,40 +171,40 @@ public async Task SaveAsync() if (result == Switch2RawStickCalibrationCommitResult.AppliedAndStored) { operation = null; - Heading = saving.Reset ? "PC calibration reset" : "Calibration saved"; - Instructions = "You can calibrate another stick or close this window."; - ResultText = saving.Reset ? $"{side}: the PC override was removed. Source calibration is active again." : - $"{side}: saved on this PC and applied to this controller connection."; + Heading = saving.Reset ? Properties.Resources.Switch2CalibResetDone : Properties.Resources.Switch2CalibSaveDone; + Instructions = Properties.Resources.Switch2CalibCanCalibrateAnother; + ResultText = saving.Reset ? string.Format(Properties.Resources.Switch2CalibResetResultFormat, side) : + string.Format(Properties.Resources.Switch2CalibSaveResultFormat, side); Progress = 100; - ProgressLabel = "Complete"; + ProgressLabel = Properties.Resources.Switch2CalibComplete; } else if (result == Switch2RawStickCalibrationCommitResult.StorageFailed && stillOwnsReceipt) { - ResultText = "The PC calibration file could not be updated. The previous live calibration is unchanged. Retry Save calibration or cancel."; + ResultText = Properties.Resources.Switch2CalibStorageFailed; UpdateProgress(); } else if ((result is Switch2RawStickCalibrationCommitResult.NotReady or Switch2RawStickCalibrationCommitResult.Busy) && stillOwnsReceipt) { - ResultText = "The operation is not ready to finish. Wait for valid samples or cancel and retry."; + ResultText = Properties.Resources.Switch2CalibNotReady; UpdateProgress(); } else { runtime.CancelRawStickCalibration(saving); operation = null; - Heading = "Calibration ended"; - Instructions = "Close this window and reopen calibration from the current controller before trying again."; - ProgressLabel = "Not applied"; + Heading = Properties.Resources.Switch2CalibEnded; + Instructions = Properties.Resources.Switch2CalibReopenBeforeRetry; + ProgressLabel = Properties.Resources.Switch2CalibNotApplied; ResultText = result == Switch2RawStickCalibrationCommitResult.StoredNotApplied ? - "The PC file was updated, but the change was not applied to the active connection. Reconnect to load it, or explicitly reset it. Cancellation cannot undo a write already in progress." : - "This operation is no longer current. It did not complete a calibration change."; + Properties.Resources.Switch2CalibStoredNotApplied : + Properties.Resources.Switch2CalibNoLongerCurrent; } } catch { runtime.CancelRawStickCalibration(saving); operation = null; - if (!closed) ResultText = "Calibration could not finish. The file outcome could not be confirmed; reconnect and check the selected stick before retrying."; + if (!closed) ResultText = Properties.Resources.Switch2CalibFinishFailed; } finally { @@ -218,11 +218,11 @@ public void Cancel() if (closed || operation == null) return; runtime.CancelRawStickCalibration(operation); operation = null; - Heading = "Calibration cancelled"; - Instructions = "Ordinary controller input can resume. You can start again when ready."; - ResultText = busy ? "A save already in progress may still update the PC file. Its final result will appear here." : - "The unsaved capture was discarded; the existing calibration was not changed."; - ProgressLabel = "Cancelled"; + Heading = Properties.Resources.Switch2CalibCancelled; + Instructions = Properties.Resources.Switch2CalibResumeInput; + ResultText = busy ? Properties.Resources.Switch2CalibSaveInProgress : + Properties.Resources.Switch2CalibDiscarded; + ProgressLabel = Properties.Resources.Switch2CalibCancelledStatus; Progress = 0; RaiseAll(); } @@ -240,24 +240,24 @@ private void UpdateProgress() if (!runtime.TryGetRawStickCalibrationProgress(operation, out var progress)) { operation = null; - Heading = "Calibration ended"; - Instructions = "The controller or calibration changed. Start again from the current controller."; - ProgressLabel = "Not saved"; + Heading = Properties.Resources.Switch2CalibEnded; + Instructions = Properties.Resources.Switch2CalibChangedRetry; + ProgressLabel = Properties.Resources.Switch2CalibNotSaved; return; } stage = progress.Stage; Progress = (stage == Switch2RawStickCalibrationStage.Rotate ? progress.RotationProgress : progress.StationaryProgress) * 100; (Heading, Instructions, ProgressLabel) = stage switch { - Switch2RawStickCalibrationStage.Rotate => ($"1 · Rotate the {SelectedSideLabel.ToLowerInvariant()}", - "Move slowly around the full outer edge in both directions. Keep moving until this step completes; pauses do not count.", - $"{Math.Max(0, Math.Ceiling(10 * (1 - progress.RotationProgress))):0} moving seconds remaining"), - Switch2RawStickCalibrationStage.Settle => ("2 · Release the stick", "Take your hand off the stick and let it return to center.", "Waiting for 2 seconds of rest"), - Switch2RawStickCalibrationStage.Center => ("3 · Hold still", "Leave the stick untouched while its center is measured. Touching it restarts the rest period.", - $"{Math.Max(0, Math.Ceiling(3 * (1 - progress.StationaryProgress))):0} still seconds remaining"), - Switch2RawStickCalibrationStage.Ready => (progress.Reset ? "Ready to reset" : "Ready to save", "Choose Save calibration to apply this result, or Cancel to discard it.", "Ready"), - Switch2RawStickCalibrationStage.InsufficientTravel => ("More stick travel is needed", "Cancel and try again. Reach the full edge in every direction, then let the stick center itself.", "Calibration rejected"), - _ => ("Calibration cancelled", "Start a new calibration when the controller is ready.", "Cancelled"), + Switch2RawStickCalibrationStage.Rotate => (string.Format(Properties.Resources.Switch2CalibRotateHeadingFormat, SelectedSideLabel.ToLowerInvariant()), + Properties.Resources.Switch2CalibRotateInstructions, + string.Format(Properties.Resources.Switch2CalibMovingSecondsFormat, Math.Max(0, Math.Ceiling(10 * (1 - progress.RotationProgress))).ToString("0"))), + Switch2RawStickCalibrationStage.Settle => (Properties.Resources.Switch2CalibSettleHeading, Properties.Resources.Switch2CalibSettleInstructions, Properties.Resources.Switch2CalibWaitingRest), + Switch2RawStickCalibrationStage.Center => (Properties.Resources.Switch2CalibCenterHeading, Properties.Resources.Switch2CalibCenterInstructions, + string.Format(Properties.Resources.Switch2CalibStillSecondsFormat, Math.Max(0, Math.Ceiling(3 * (1 - progress.StationaryProgress))).ToString("0"))), + Switch2RawStickCalibrationStage.Ready => (progress.Reset ? Properties.Resources.Switch2CalibReadyToReset : Properties.Resources.Switch2CalibReadyToSave, Properties.Resources.Switch2CalibChooseSaveOrCancel, Properties.Resources.Switch2CalibReady), + Switch2RawStickCalibrationStage.InsufficientTravel => (Properties.Resources.Switch2CalibMoreTravelNeeded, Properties.Resources.Switch2CalibReachFullEdge, Properties.Resources.Switch2CalibRejected), + _ => (Properties.Resources.Switch2CalibCancelled, Properties.Resources.Switch2CalibStartNewWhenReady, Properties.Resources.Switch2CalibCancelledStatus), }; } @@ -267,9 +267,9 @@ private void EndContext() pendingBegin?.Cancel(); if (operation != null) runtime.CancelRawStickCalibration(operation); operation = null; - Heading = "Controller context changed"; - Instructions = "The controller, profile or pair changed. Close this window and reopen calibration from the controller you want to use."; - ProgressLabel = "Calibration stopped"; + Heading = Properties.Resources.Switch2CalibContextChanged; + Instructions = Properties.Resources.Switch2CalibContextChangedDetail; + ProgressLabel = Properties.Resources.Switch2CalibStopped; // Preserve the explicit asynchronous disk outcome, if one exists. } diff --git a/DS4Windows/DS4Forms/ViewModels/TouchButtonUserControlViewModel.cs b/DS4Windows/DS4Forms/ViewModels/TouchButtonUserControlViewModel.cs index ada90cca..61eaf06f 100644 --- a/DS4Windows/DS4Forms/ViewModels/TouchButtonUserControlViewModel.cs +++ b/DS4Windows/DS4Forms/ViewModels/TouchButtonUserControlViewModel.cs @@ -38,9 +38,9 @@ public int DeviceIndex private EnumChoiceSelection[] touchButtonModes = new EnumChoiceSelection[] { - new EnumChoiceSelection("Click", TouchButtonActivationMode.Click), - new EnumChoiceSelection("Touch", TouchButtonActivationMode.Touch), - new EnumChoiceSelection("Release", TouchButtonActivationMode.Release), + new EnumChoiceSelection(Properties.Resources.TouchButtonModeClick, TouchButtonActivationMode.Click), + new EnumChoiceSelection(Properties.Resources.TouchButtonModeTouch, TouchButtonActivationMode.Touch), + new EnumChoiceSelection(Properties.Resources.TouchButtonModeRelease, TouchButtonActivationMode.Release), }; public EnumChoiceSelection[] TouchButtonModes => touchButtonModes; diff --git a/DS4Windows/DS4Forms/ViiperSetupProgress.xaml.cs b/DS4Windows/DS4Forms/ViiperSetupProgress.xaml.cs index fca128eb..9bc1e3c3 100644 --- a/DS4Windows/DS4Forms/ViiperSetupProgress.xaml.cs +++ b/DS4Windows/DS4Forms/ViiperSetupProgress.xaml.cs @@ -32,7 +32,7 @@ public ViiperSetupProgress(string logPath) public void ShowPreparing() { - phaseText.Text = "Verifying the DS4Windows package..."; + phaseText.Text = Properties.Resources.VPVerifyingPackage; Show(); logTimer.Start(); // Render the window before the protected package snapshot begins. diff --git a/DS4Windows/DS4Forms/ViiperSetupPrompt.xaml.cs b/DS4Windows/DS4Forms/ViiperSetupPrompt.xaml.cs index 25cb620f..d0aea39a 100644 --- a/DS4Windows/DS4Forms/ViiperSetupPrompt.xaml.cs +++ b/DS4Windows/DS4Forms/ViiperSetupPrompt.xaml.cs @@ -35,18 +35,15 @@ public ViiperSetupPrompt(string currentStatus, if (citrixUsbMonitorConflict) { - headingText.Text = "VIIPER paused for system safety"; - summaryText.Text = - "A conflicting Citrix USB monitor is active."; - requirementsText.Text = - "• Disable Citrix generic USB redirection only\n" + - "• Restart Windows before VIIPER starts again"; - installButton.Content = "Disable conflicting USB monitor"; + headingText.Text = Properties.Resources.VPCitrixHeading; + summaryText.Text = Properties.Resources.VPCitrixSummary; + requirementsText.Text = Properties.Resources.VPCitrixRequirements; + installButton.Content = Properties.Resources.VPDisableConflictingUsbMonitor; installPortableButton.Visibility = Visibility.Collapsed; portableWarningPanel.Visibility = Visibility.Collapsed; suppressPromptCheck.Visibility = Visibility.Collapsed; - notNowButton.Content = "Continue without virtual output"; - closeButton.ToolTip = "Continue without virtual output"; + notNowButton.Content = Properties.Resources.VPContinueWithoutVirtualOutput; + closeButton.ToolTip = Properties.Resources.VPContinueWithoutVirtualOutput; return; } @@ -59,43 +56,36 @@ public ViiperSetupPrompt(string currentStatus, if (verifiedUpdateRequired) { headingText.Text = usbipReplacementRequired - ? "USB-IP version must be replaced" - : "VIIPER verification failed"; + ? Properties.Resources.VPUsbipReplaceHeading + : Properties.Resources.VPVerificationFailedHeading; summaryText.Text = usbipReplacementRequired ? currentStatus - : "The installed VIIPER does not match this DS4Windows package."; - requirementsHeadingText.Text = "Verified update required"; + : Properties.Resources.VPVerificationFailedSummary; + requirementsHeadingText.Text = Properties.Resources.VPVerifiedUpdateRequired; requirementsText.Text = usbipReplacementRequired - ? "• Install and verify bundled VIIPER 0.1.9-rc4.6.6\n" + - "• Safely remove the unsupported USB-IP package\n" + - "• Restart, then finish installing USB-IP 0.9.7.7" - : "• Install the exact bundled VIIPER build\n" + - "• Keep your existing installation location\n" + - "• The unverified backend will not be started"; + ? Properties.Resources.VPUsbipReplaceRequirements + : Properties.Resources.VPVerificationFailedRequirements; installButton.Content = usbipReplacementRequired - ? "Repair VIIPER + USB-IP" - : "Install / Repair"; + ? Properties.Resources.VPRepairViiperUsbip + : Properties.Resources.VPInstallRepair; installPortableButton.Content = - "Keep DS4Windows portable"; + Properties.Resources.VPKeepPortable; existingViiperPanel.Visibility = Visibility.Collapsed; suppressPromptCheck.Visibility = Visibility.Collapsed; - notNowButton.Content = "Continue without virtual output"; - closeButton.ToolTip = "Continue without virtual output"; + notNowButton.Content = Properties.Resources.VPContinueWithoutVirtualOutput; + closeButton.ToolTip = Properties.Resources.VPContinueWithoutVirtualOutput; } else if (this.mandatoryRepairRequired) { - headingText.Text = "VIIPER setup required"; + headingText.Text = Properties.Resources.VPSetupRequiredHeading; summaryText.Text = currentStatus; - requirementsHeadingText.Text = "Required before DS4Windows can run"; - requirementsText.Text = - "• Install the bundled VIIPER 0.1.9-rc4.6.6 build\n" + - "• Install and verify USB-IP 0.9.7.7\n" + - "• Start DS4Windows only after the runtime probe passes"; - installButton.Content = "Install / Repair"; - installPortableButton.Content = "Keep DS4Windows portable"; + requirementsHeadingText.Text = Properties.Resources.VPRequiredBeforeRun; + requirementsText.Text = Properties.Resources.VPMandatoryRequirements; + installButton.Content = Properties.Resources.VPInstallRepair; + installPortableButton.Content = Properties.Resources.VPKeepPortable; suppressPromptCheck.Visibility = Visibility.Collapsed; - notNowButton.Content = "Continue without virtual output"; - closeButton.ToolTip = "Continue without virtual output"; + notNowButton.Content = Properties.Resources.VPContinueWithoutVirtualOutput; + closeButton.ToolTip = Properties.Resources.VPContinueWithoutVirtualOutput; } } diff --git a/DS4Windows/DS4WinWPF.csproj b/DS4Windows/DS4WinWPF.csproj index f7db86b5..23b30ab8 100644 --- a/DS4Windows/DS4WinWPF.csproj +++ b/DS4Windows/DS4WinWPF.csproj @@ -516,6 +516,9 @@ PublicResXFileCodeGenerator Resources.Designer.cs + + Resources.resx + Resources.resx diff --git a/DS4Windows/Properties/Resources.Designer.cs b/DS4Windows/Properties/Resources.Designer.cs index 6d3cc00d..ee965459 100644 --- a/DS4Windows/Properties/Resources.Designer.cs +++ b/DS4Windows/Properties/Resources.Designer.cs @@ -1673,5 +1673,1418 @@ public static string XMLFiles { return ResourceManager.GetString("XMLFiles", resourceCulture); } } + + /// + /// Looks up a localized string similar to Cancel. + /// + public static string Cancel { + get { + return ResourceManager.GetString("Cancel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save. + /// + public static string Save { + get { + return ResourceManager.GetString("Save", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Select a controller. + /// + public static string AHStatusSelectController { + get { + return ResourceManager.GetString("AHStatusSelectController", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No source. + /// + public static string AHStatusNoSource { + get { + return ResourceManager.GetString("AHStatusNoSource", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Off. + /// + public static string AHStatusOff { + get { + return ResourceManager.GetString("AHStatusOff", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Saved to profile. + /// + public static string AHStatusSavedToProfile { + get { + return ResourceManager.GetString("AHStatusSavedToProfile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Active. + /// + public static string AHStatusActive { + get { + return ResourceManager.GetString("AHStatusActive", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Controller audio. + /// + public static string AHSourceControllerAudio { + get { + return ResourceManager.GetString("AHSourceControllerAudio", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Automatic game detection. + /// + public static string AHSourceAutoGameDetection { + get { + return ResourceManager.GetString("AHSourceAutoGameDetection", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Selected app. + /// + public static string AHSourceSelectedApp { + get { + return ResourceManager.GetString("AHSourceSelectedApp", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to System audio · default output. + /// + public static string AHSourceSystemAudioDefault { + get { + return ResourceManager.GetString("AHSourceSystemAudioDefault", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Live. + /// + public static string MLLive { + get { + return ResourceManager.GetString("MLLive", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Waiting. + /// + public static string MLWaiting { + get { + return ResourceManager.GetString("MLWaiting", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Controller changed. + /// + public static string MLControllerChanged { + get { + return ResourceManager.GetString("MLControllerChanged", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No recent input. + /// + public static string MLNoRecentInput { + get { + return ResourceManager.GetString("MLNoRecentInput", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Reopen the editor to preview the new controller.. + /// + public static string MLReopenForNewController { + get { + return ResourceManager.GetString("MLReopenForNewController", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Controller disconnected. Reconnect and reopen the editor.. + /// + public static string MLControllerDisconnectedReopen { + get { + return ResourceManager.GetString("MLControllerDisconnectedReopen", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Waiting for fresh controller input…. + /// + public static string MLWaitingForFreshInput { + get { + return ResourceManager.GetString("MLWaitingForFreshInput", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Waiting for controller input…. + /// + public static string MLWaitingForInput { + get { + return ResourceManager.GetString("MLWaitingForInput", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Open this profile from a connected controller.. + /// + public static string MLOpenFromConnectedController { + get { + return ResourceManager.GetString("MLOpenFromConnectedController", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No buttons pressed. + /// + public static string MLNoButtonsPressed { + get { + return ResourceManager.GetString("MLNoButtonsPressed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to VIIPER paused for system safety. + /// + public static string VPCitrixHeading { + get { + return ResourceManager.GetString("VPCitrixHeading", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A conflicting Citrix USB monitor is active.. + /// + public static string VPCitrixSummary { + get { + return ResourceManager.GetString("VPCitrixSummary", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to • Disable Citrix generic USB redirection only + ///• Restart Windows before VIIPER starts again. + /// + public static string VPCitrixRequirements { + get { + return ResourceManager.GetString("VPCitrixRequirements", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Disable conflicting USB monitor. + /// + public static string VPDisableConflictingUsbMonitor { + get { + return ResourceManager.GetString("VPDisableConflictingUsbMonitor", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Continue without virtual output. + /// + public static string VPContinueWithoutVirtualOutput { + get { + return ResourceManager.GetString("VPContinueWithoutVirtualOutput", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to USB-IP version must be replaced. + /// + public static string VPUsbipReplaceHeading { + get { + return ResourceManager.GetString("VPUsbipReplaceHeading", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to VIIPER verification failed. + /// + public static string VPVerificationFailedHeading { + get { + return ResourceManager.GetString("VPVerificationFailedHeading", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The installed VIIPER does not match this DS4Windows package.. + /// + public static string VPVerificationFailedSummary { + get { + return ResourceManager.GetString("VPVerificationFailedSummary", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Verified update required. + /// + public static string VPVerifiedUpdateRequired { + get { + return ResourceManager.GetString("VPVerifiedUpdateRequired", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to • Install and verify bundled VIIPER 0.1.9-rc4.6.6 + ///• Safely remove the unsupported USB-IP package + ///• Restart, then finish installing USB-IP 0.9.7.7. + /// + public static string VPUsbipReplaceRequirements { + get { + return ResourceManager.GetString("VPUsbipReplaceRequirements", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to • Install the exact bundled VIIPER build + ///• Keep your existing installation location + ///• The unverified backend will not be started. + /// + public static string VPVerificationFailedRequirements { + get { + return ResourceManager.GetString("VPVerificationFailedRequirements", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Repair VIIPER + USB-IP. + /// + public static string VPRepairViiperUsbip { + get { + return ResourceManager.GetString("VPRepairViiperUsbip", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Install standard. + /// + public static string VPInstallStandard { + get { + return ResourceManager.GetString("VPInstallStandard", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Keep DS4Windows portable. + /// + public static string VPKeepPortable { + get { + return ResourceManager.GetString("VPKeepPortable", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to VIIPER setup required. + /// + public static string VPSetupRequiredHeading { + get { + return ResourceManager.GetString("VPSetupRequiredHeading", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Required before DS4Windows can run. + /// + public static string VPRequiredBeforeRun { + get { + return ResourceManager.GetString("VPRequiredBeforeRun", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to • Install the bundled VIIPER 0.1.9-rc4.6.6 build + ///• Install and verify USB-IP 0.9.7.7 + ///• Start DS4Windows only after the runtime probe passes. + /// + public static string VPMandatoryRequirements { + get { + return ResourceManager.GetString("VPMandatoryRequirements", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Install / Repair. + /// + public static string VPInstallRepair { + get { + return ResourceManager.GetString("VPInstallRepair", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Verifying the DS4Windows package.... + /// + public static string VPVerifyingPackage { + get { + return ResourceManager.GetString("VPVerifyingPackage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Active. + /// + public static string TLActiveLabel { + get { + return ResourceManager.GetString("TLActiveLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Left Trigger. + /// + public static string TLLeftTrigger { + get { + return ResourceManager.GetString("TLLeftTrigger", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Right Trigger. + /// + public static string TLRightTrigger { + get { + return ResourceManager.GetString("TLRightTrigger", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Shape the {0} trigger feel. + /// + public static string TLShapeTriggerFeelFormat { + get { + return ResourceManager.GetString("TLShapeTriggerFeelFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save new trigger profile. + /// + public static string TLSaveProfileTip { + get { + return ResourceManager.GetString("TLSaveProfileTip", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rename trigger profile. + /// + public static string TLRenameProfileTip { + get { + return ResourceManager.GetString("TLRenameProfileTip", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete trigger profile. + /// + public static string TLDeleteProfileTip { + get { + return ResourceManager.GetString("TLDeleteProfileTip", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Feedback. + /// + public static string TLModeFeedback { + get { + return ResourceManager.GetString("TLModeFeedback", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Weapon. + /// + public static string TLModeWeapon { + get { + return ResourceManager.GetString("TLModeWeapon", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Vibration. + /// + public static string TLModeVibration { + get { + return ResourceManager.GetString("TLModeVibration", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Start. + /// + public static string TLMeterStart { + get { + return ResourceManager.GetString("TLMeterStart", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Wall. + /// + public static string TLMeterWall { + get { + return ResourceManager.GetString("TLMeterWall", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Force. + /// + public static string TLMeterForce { + get { + return ResourceManager.GetString("TLMeterForce", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Preview. + /// + public static string TLPreview { + get { + return ResourceManager.GetString("TLPreview", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Reset {0}. + /// + public static string TLResetFormat { + get { + return ResourceManager.GetString("TLResetFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Game rumble vibration. + /// + public static string TLGameRumbleTitle { + get { + return ResourceManager.GetString("TLGameRumbleTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Stream the game's {0} HID rumble motor to {1} as a low-latency vibration effect.. + /// + public static string TLGameRumbleDescFormat { + get { + return ResourceManager.GetString("TLGameRumbleDescFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to heavy / left. + /// + public static string TLHeavyLeft { + get { + return ResourceManager.GetString("TLHeavyLeft", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to light / right. + /// + public static string TLLightRight { + get { + return ResourceManager.GetString("TLLightRight", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Independently enable game-rumble vibration for {0}. This does not link the other trigger.. + /// + public static string TLGameRumbleTipFormat { + get { + return ResourceManager.GetString("TLGameRumbleTipFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Full-pull action. + /// + public static string TLFullPullActionTitle { + get { + return ResourceManager.GetString("TLFullPullActionTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to END OF TRAVEL. + /// + public static string TLEndOfTravelBadge { + get { + return ResourceManager.GetString("TLEndOfTravelBadge", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to When {0} is pressed completely, run the action below using the selected behavior.. + /// + public static string TLFullPullDescFormat { + get { + return ResourceManager.GetString("TLFullPullDescFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Assigned action. + /// + public static string TLAssignedActionLabel { + get { + return ResourceManager.GetString("TLAssignedActionLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Change ›. + /// + public static string TLChangeLabel { + get { + return ResourceManager.GetString("TLChangeLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Behavior. + /// + public static string TLBehaviorLabel { + get { + return ResourceManager.GetString("TLBehaviorLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delay. + /// + public static string TLDelayLabel { + get { + return ResourceManager.GetString("TLDelayLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Select a controller or profile. + /// + public static string TLSelectControllerOrProfile { + get { + return ResourceManager.GetString("TLSelectControllerOrProfile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Select a controller or profile to open Trigger Lab.. + /// + public static string TLSelectToOpen { + get { + return ResourceManager.GetString("TLSelectToOpen", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Saved custom effect.. + /// + public static string TLSavedCustomEffect { + get { + return ResourceManager.GetString("TLSavedCustomEffect", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save trigger profile. + /// + public static string TLSaveProfileDialogTitle { + get { + return ResourceManager.GetString("TLSaveProfileDialogTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Custom Trigger {0}. + /// + public static string TLDefaultCustomTriggerNameFormat { + get { + return ResourceManager.GetString("TLDefaultCustomTriggerNameFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Custom. + /// + public static string TLCustom { + get { + return ResourceManager.GetString("TLCustom", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete {0}?. + /// + public static string TLDeleteConfirmFormat { + get { + return ResourceManager.GetString("TLDeleteConfirmFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Trigger Lab. + /// + public static string TLDialogTitle { + get { + return ResourceManager.GetString("TLDialogTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Off. + /// + public static string TLModeOff { + get { + return ResourceManager.GetString("TLModeOff", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Only the regular trigger action runs.. + /// + public static string TLModeOffDesc { + get { + return ResourceManager.GetString("TLModeOffDesc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add at full pull. + /// + public static string TLModeAddAtFullPull { + get { + return ResourceManager.GetString("TLModeAddAtFullPull", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Keep the regular trigger action active and also run the full-pull action at the end of travel.. + /// + public static string TLModeAddAtFullPullDesc { + get { + return ResourceManager.GetString("TLModeAddAtFullPullDesc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Replace at full pull. + /// + public static string TLModeReplaceAtFullPull { + get { + return ResourceManager.GetString("TLModeReplaceAtFullPull", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Release the regular trigger action and replace it with the full-pull action at the end of travel.. + /// + public static string TLModeReplaceAtFullPullDesc { + get { + return ResourceManager.GetString("TLModeReplaceAtFullPullDesc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hair trigger. + /// + public static string TLModeHairTrigger { + get { + return ResourceManager.GetString("TLModeHairTrigger", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Run both actions at full pull, then release both as soon as the trigger backs away from the end stop.. + /// + public static string TLModeHairTriggerDesc { + get { + return ResourceManager.GetString("TLModeHairTriggerDesc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hip fire. + /// + public static string TLModeHipFire { + get { + return ResourceManager.GetString("TLModeHipFire", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Wait for the chosen delay, then run the regular or full-pull action based on how far the trigger was pressed.. + /// + public static string TLModeHipFireDesc { + get { + return ResourceManager.GetString("TLModeHipFireDesc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hip fire (exclusive). + /// + public static string TLModeHipFireExclusive { + get { + return ResourceManager.GetString("TLModeHipFireExclusive", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Wait for the chosen delay and run only one action: regular pull or full pull.. + /// + public static string TLModeHipFireExclusiveDesc { + get { + return ResourceManager.GetString("TLModeHipFireExclusiveDesc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Click. + /// + public static string TouchButtonModeClick { + get { + return ResourceManager.GetString("TouchButtonModeClick", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Touch. + /// + public static string TouchButtonModeTouch { + get { + return ResourceManager.GetString("TouchButtonModeTouch", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Release. + /// + public static string TouchButtonModeRelease { + get { + return ResourceManager.GetString("TouchButtonModeRelease", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Left stick. + /// + public static string Switch2CalibLeftStick { + get { + return ResourceManager.GetString("Switch2CalibLeftStick", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Right stick. + /// + public static string Switch2CalibRightStick { + get { + return ResourceManager.GetString("Switch2CalibRightStick", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Switch 2 Pro Controller. + /// + public static string Switch2CalibProControllerName { + get { + return ResourceManager.GetString("Switch2CalibProControllerName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Joined Joy-Con 2. + /// + public static string Switch2CalibJoinedJoyCon { + get { + return ResourceManager.GetString("Switch2CalibJoinedJoyCon", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Joy-Con 2 (Left). + /// + public static string Switch2CalibJoyConLeft { + get { + return ResourceManager.GetString("Switch2CalibJoyConLeft", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Joy-Con 2 (Right). + /// + public static string Switch2CalibJoyConRight { + get { + return ResourceManager.GetString("Switch2CalibJoyConRight", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to · USB. + /// + public static string Switch2CalibUsbSuffix { + get { + return ResourceManager.GetString("Switch2CalibUsbSuffix", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to · Bluetooth. + /// + public static string Switch2CalibBluetoothSuffix { + get { + return ResourceManager.GetString("Switch2CalibBluetoothSuffix", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Choose a physical stick. + /// + public static string Switch2CalibChoosePhysicalStick { + get { + return ResourceManager.GetString("Switch2CalibChoosePhysicalStick", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rotate the selected stick around its full edge, then let it rest in the center. Nothing is saved until you choose Save calibration.. + /// + public static string Switch2CalibInitialInstructions { + get { + return ResourceManager.GetString("Switch2CalibInitialInstructions", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to PC calibration is active for this stick.. + /// + public static string Switch2CalibPcActive { + get { + return ResourceManager.GetString("Switch2CalibPcActive", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Using original controller calibration, or defaults if unavailable.. + /// + public static string Switch2CalibUsingOriginal { + get { + return ResourceManager.GetString("Switch2CalibUsingOriginal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Not started. + /// + public static string Switch2CalibNotStarted { + get { + return ResourceManager.GetString("Switch2CalibNotStarted", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Remove the PC calibration for the {0} on this controller? + /// + ///The original factory calibration will not be changed. Other sticks and controllers are unaffected.. + /// + public static string Switch2CalibResetConfirmFormat { + get { + return ResourceManager.GetString("Switch2CalibResetConfirmFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Preparing reset. + /// + public static string Switch2CalibPreparingReset { + get { + return ResourceManager.GetString("Switch2CalibPreparingReset", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Preparing calibration. + /// + public static string Switch2CalibPreparingCalibration { + get { + return ResourceManager.GetString("Switch2CalibPreparingCalibration", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Releasing this controller's mapped input…. + /// + public static string Switch2CalibReleasingInput { + get { + return ResourceManager.GetString("Switch2CalibReleasingInput", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Please wait. + /// + public static string Switch2CalibPleaseWait { + get { + return ResourceManager.GetString("Switch2CalibPleaseWait", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Calibration could not start. + /// + public static string Switch2CalibCouldNotStart { + get { + return ResourceManager.GetString("Switch2CalibCouldNotStart", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Wait for live controller input and finish any other calibration, then try again. A remembered controller identity and writable PC calibration store are required.. + /// + public static string Switch2CalibCouldNotStartDetail { + get { + return ResourceManager.GetString("Switch2CalibCouldNotStartDetail", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Calibration could not start. No calibration was saved.. + /// + public static string Switch2CalibCouldNotStartError { + get { + return ResourceManager.GetString("Switch2CalibCouldNotStartError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Resetting PC calibration. + /// + public static string Switch2CalibResettingPc { + get { + return ResourceManager.GetString("Switch2CalibResettingPc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Saving PC calibration. + /// + public static string Switch2CalibSavingPc { + get { + return ResourceManager.GetString("Switch2CalibSavingPc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Controller input remains released while the result is stored and applied.. + /// + public static string Switch2CalibInputReleasedWhileSaving { + get { + return ResourceManager.GetString("Switch2CalibInputReleasedWhileSaving", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to PC calibration reset. + /// + public static string Switch2CalibResetDone { + get { + return ResourceManager.GetString("Switch2CalibResetDone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Calibration saved. + /// + public static string Switch2CalibSaveDone { + get { + return ResourceManager.GetString("Switch2CalibSaveDone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You can calibrate another stick or close this window.. + /// + public static string Switch2CalibCanCalibrateAnother { + get { + return ResourceManager.GetString("Switch2CalibCanCalibrateAnother", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0}: the PC override was removed. Source calibration is active again.. + /// + public static string Switch2CalibResetResultFormat { + get { + return ResourceManager.GetString("Switch2CalibResetResultFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0}: saved on this PC and applied to this controller connection.. + /// + public static string Switch2CalibSaveResultFormat { + get { + return ResourceManager.GetString("Switch2CalibSaveResultFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Complete. + /// + public static string Switch2CalibComplete { + get { + return ResourceManager.GetString("Switch2CalibComplete", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The PC calibration file could not be updated. The previous live calibration is unchanged. Retry Save calibration or cancel.. + /// + public static string Switch2CalibStorageFailed { + get { + return ResourceManager.GetString("Switch2CalibStorageFailed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The operation is not ready to finish. Wait for valid samples or cancel and retry.. + /// + public static string Switch2CalibNotReady { + get { + return ResourceManager.GetString("Switch2CalibNotReady", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Calibration ended. + /// + public static string Switch2CalibEnded { + get { + return ResourceManager.GetString("Switch2CalibEnded", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Close this window and reopen calibration from the current controller before trying again.. + /// + public static string Switch2CalibReopenBeforeRetry { + get { + return ResourceManager.GetString("Switch2CalibReopenBeforeRetry", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Not applied. + /// + public static string Switch2CalibNotApplied { + get { + return ResourceManager.GetString("Switch2CalibNotApplied", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The PC file was updated, but the change was not applied to the active connection. Reconnect to load it, or explicitly reset it. Cancellation cannot undo a write already in progress.. + /// + public static string Switch2CalibStoredNotApplied { + get { + return ResourceManager.GetString("Switch2CalibStoredNotApplied", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This operation is no longer current. It did not complete a calibration change.. + /// + public static string Switch2CalibNoLongerCurrent { + get { + return ResourceManager.GetString("Switch2CalibNoLongerCurrent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Calibration could not finish. The file outcome could not be confirmed; reconnect and check the selected stick before retrying.. + /// + public static string Switch2CalibFinishFailed { + get { + return ResourceManager.GetString("Switch2CalibFinishFailed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Calibration cancelled. + /// + public static string Switch2CalibCancelled { + get { + return ResourceManager.GetString("Switch2CalibCancelled", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ordinary controller input can resume. You can start again when ready.. + /// + public static string Switch2CalibResumeInput { + get { + return ResourceManager.GetString("Switch2CalibResumeInput", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A save already in progress may still update the PC file. Its final result will appear here.. + /// + public static string Switch2CalibSaveInProgress { + get { + return ResourceManager.GetString("Switch2CalibSaveInProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The unsaved capture was discarded; the existing calibration was not changed.. + /// + public static string Switch2CalibDiscarded { + get { + return ResourceManager.GetString("Switch2CalibDiscarded", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cancelled. + /// + public static string Switch2CalibCancelledStatus { + get { + return ResourceManager.GetString("Switch2CalibCancelledStatus", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The controller or calibration changed. Start again from the current controller.. + /// + public static string Switch2CalibChangedRetry { + get { + return ResourceManager.GetString("Switch2CalibChangedRetry", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Not saved. + /// + public static string Switch2CalibNotSaved { + get { + return ResourceManager.GetString("Switch2CalibNotSaved", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to 1 · Rotate the {0}. + /// + public static string Switch2CalibRotateHeadingFormat { + get { + return ResourceManager.GetString("Switch2CalibRotateHeadingFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Move slowly around the full outer edge in both directions. Keep moving until this step completes; pauses do not count.. + /// + public static string Switch2CalibRotateInstructions { + get { + return ResourceManager.GetString("Switch2CalibRotateInstructions", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0} moving seconds remaining. + /// + public static string Switch2CalibMovingSecondsFormat { + get { + return ResourceManager.GetString("Switch2CalibMovingSecondsFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to 2 · Release the stick. + /// + public static string Switch2CalibSettleHeading { + get { + return ResourceManager.GetString("Switch2CalibSettleHeading", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Take your hand off the stick and let it return to center.. + /// + public static string Switch2CalibSettleInstructions { + get { + return ResourceManager.GetString("Switch2CalibSettleInstructions", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Waiting for 2 seconds of rest. + /// + public static string Switch2CalibWaitingRest { + get { + return ResourceManager.GetString("Switch2CalibWaitingRest", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to 3 · Hold still. + /// + public static string Switch2CalibCenterHeading { + get { + return ResourceManager.GetString("Switch2CalibCenterHeading", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Leave the stick untouched while its center is measured. Touching it restarts the rest period.. + /// + public static string Switch2CalibCenterInstructions { + get { + return ResourceManager.GetString("Switch2CalibCenterInstructions", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0} still seconds remaining. + /// + public static string Switch2CalibStillSecondsFormat { + get { + return ResourceManager.GetString("Switch2CalibStillSecondsFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ready to reset. + /// + public static string Switch2CalibReadyToReset { + get { + return ResourceManager.GetString("Switch2CalibReadyToReset", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ready to save. + /// + public static string Switch2CalibReadyToSave { + get { + return ResourceManager.GetString("Switch2CalibReadyToSave", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Choose Save calibration to apply this result, or Cancel to discard it.. + /// + public static string Switch2CalibChooseSaveOrCancel { + get { + return ResourceManager.GetString("Switch2CalibChooseSaveOrCancel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ready. + /// + public static string Switch2CalibReady { + get { + return ResourceManager.GetString("Switch2CalibReady", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to More stick travel is needed. + /// + public static string Switch2CalibMoreTravelNeeded { + get { + return ResourceManager.GetString("Switch2CalibMoreTravelNeeded", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cancel and try again. Reach the full edge in every direction, then let the stick center itself.. + /// + public static string Switch2CalibReachFullEdge { + get { + return ResourceManager.GetString("Switch2CalibReachFullEdge", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Calibration rejected. + /// + public static string Switch2CalibRejected { + get { + return ResourceManager.GetString("Switch2CalibRejected", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Start a new calibration when the controller is ready.. + /// + public static string Switch2CalibStartNewWhenReady { + get { + return ResourceManager.GetString("Switch2CalibStartNewWhenReady", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Controller context changed. + /// + public static string Switch2CalibContextChanged { + get { + return ResourceManager.GetString("Switch2CalibContextChanged", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The controller, profile or pair changed. Close this window and reopen calibration from the controller you want to use.. + /// + public static string Switch2CalibContextChangedDetail { + get { + return ResourceManager.GetString("Switch2CalibContextChangedDetail", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Calibration stopped. + /// + public static string Switch2CalibStopped { + get { + return ResourceManager.GetString("Switch2CalibStopped", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Reset PC stick calibration. + /// + public static string Switch2CalibResetDialogTitle { + get { + return ResourceManager.GetString("Switch2CalibResetDialogTitle", resourceCulture); + } + } } } diff --git a/DS4Windows/Properties/Resources.ar.resx b/DS4Windows/Properties/Resources.ar.resx new file mode 100644 index 00000000..af2f097c --- /dev/null +++ b/DS4Windows/Properties/Resources.ar.resx @@ -0,0 +1,824 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + هذا الاسم مستخدم بالفعل لهذا الفعل + + + جارٍ الإضافة إلى القائمة... + + + إضافة برامج + + + يجب اختيار موقع للمتابعة + + + وضع قوس قزح دائمًا + + + تعيين لليد المتحكم *number* + + + البطارية: *number*٪ + + + يُفضل استخدامه مع الجانب الأيمن كوظيفة ماوس + + + تصفح... + + + يحدد معدل الاستطلاع المستخدم لجهاز DS4 عند الاتصال عبر البلوتوث. (يسري عند حفظ الملف التعريفي) + + + تعذّر نقل الملفات إلى الموقع الجديد، يرجى إعادة تسمية مجلد DS4Tool إلى "DS4Windows" + + + تعذّرت الكتابة في الموقع الحالي. هل تريد نسخ الإعدادات إلى appdata؟ + + + اشحن البطارية + + + مشحونة + + + جارٍ الشحن: *number*٪ + + + فحص البطارية + + + سيؤدي هذا إلى قطع اتصال جميع أيادي التحكم المتصلة. هل تريد المتابعة؟ + + + إغلاق DS4Windows؟ + + + إغلاق النافذة الرئيسية يصغّر التطبيق فقط. سيتم الخروج من التطبيق عبر أيقونة الإشعارات + + + اللون + + + اللون حسب نسبة البطارية + + + تأكيد... + + + جارٍ الاتصال... + + + تعديل ملف تعريف يد التحكم *number* + + + إنشاء ملف تعريف ليد التحكم *number* + + + تمت إزالة يد التحكم *Mac address* أو فقدت الاتصال + + + اكتمل النسخ، يرجى إعادة تشغيل DS4Windows وإزالة الإعدادات من مجلد البرنامج + + + انقر لنسخ اللون الكامل + + + تحذير: تعذّر فتح DS4 *Mac address* بشكل حصري. + + + يوم + + + أيام + + + حذف الملف التعريفي؟ + + + تعتيم حسب نسبة البطارية + + + قطع اتصال البلوتوث + + + غير متصل + + + جارٍ التنزيل *number*٪ + + + تنزيل الإصدار *number* الآن؟ + + + أسفل + + + + ..\Resources\DS4.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + يتوفر تحديث لـ DS4Windows! + + + ..\Resources\DS4W.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + لا يمكن لـ DS4Windows تعديل الإعدادات هنا، سيتم الإغلاق الآن + + + ..\Resources\DS4W - White.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + تعديل + + + الرجوع + + + الرجوع إلى *button* + + + ضغط زر الماوس الخامس + + + تحرير زر الماوس الخامس + + + انقر لتغيير لون الوميض. الأسود = اللون الافتراضي + + + تفريغ HID + + + تفريغ قائمة انتظار HID بعد كل قراءة + + + تم العثور على يد تحكم: + + + ضغط زر الماوس الرابع + + + تحرير زر الماوس الرابع + + + كامل + + + انقر لعرض قراءات Sixaxis Gyro + + + فعّل هذا الخيار ليبقى الجايرو نشطًا أثناء تفعيل الزناد. ألغِ تفعيله لتعطيل الجايرو أثناء تفعيل الزناد. + + + GyroX، إمالة يسار ويمين + + + GyroY، إمالة أمام وخلف + + + GyroZ، إمالة أعلى وأسفل + + + ساعة + + + ساعات + + + مرر المؤشر فوق العناصر لرؤية الوصف أو المزيد من المعلومات + + + إذا كنت تزيل DS4Windows، يمكنك حذف الإعدادات باتباع رابط مجلد الملف التعريفي + + + الفاصل الزمني الملاحَظ للتقرير الفعلي: {0:0.##} ms + + + اكتمل التثبيت + + + ثبّت برامج التشغيل هنا + + + فشل التثبيت، يرجى إعادة المحاولة + + + جارٍ التثبيت... + + + استخدم Sixaxis للمساعدة في حساب حركة لوحة اللمس + + + الاحتفاظ بحجم هذه النافذة بعد الإغلاق + + + سيسري تغيير حزمة اللغة بعد إعادة تشغيل تطبيق DS4Windows. + + + زمن استجابة يد التحكم *number* أصبح الآن أقل من 10 مللي ثانية + + + زمن استجابة يد التحكم {0} تجاوز 10 مللي ثانية ({1} ms) + + + تشغيل *program* + + + تعتيم الإضاءة أيضًا حسب مهلة الخمول إذا كان مفعّلاً عندما تكون DS4 مشحونة بالكامل + + + جارٍ التحميل... + + + تحميل *profile* + + + ماكرو + + + تم تسجيل الماكرو + + + إنشاء ملف تعريف جديد + + + زر متعدد الأفعال + + + غير متاح + + + جديد + + + لم يتم تسجيل أي ماكرو + + + (لا شيء) + + + لا شيء + + + لم يتم تحميل أي ملف تعريفي + + + يد التحكم {0} لا تستخدم ملفًا تعريفيًا. مستوى البطارية {1}٪ + + + غير صالح + + + جارٍ فتح المثبِّت + + + يرجى فتح ScpDriver.exe + + + ، سيتم حذف ملفات المواقع الأخرى + + + يرجى تنزيل المحدِّث الآن، ووضعه في مجلد البرامج وإعادة تسميته إلى DS4Updater.exe إذا كنت تستخدم x86، ثم تحقق من التحديث مرة أخرى. سيحاول DS4Windows فتح صفحة إصدار DS4Updater عند إغلاق هذه النافذة. + + + يرجى استيراد أو إنشاء ملف تعريفي + + + ملف تعريفي جديد + + + لا يمكن استعادة *Profile name*. + + + تم نقل مجلد الملفات التعريفية إلى مجلد البرنامج + + + البرامج + + + تعطيل البلوتوث تلقائيًا عند الاتصال بـ USB + + + أغلق التطبيقات التي تستخدم حاليًا يد التحكم الفعلية قبل تفعيل "استخدام HidHide لمنع الإدخال المزدوج". + + + تسجيل + + + انقر بزر الماوس الأيمن لتعيين إعدادات مسبقة لمجموعة من عناصر التحكم + + + يُخبر Windows ببدء تشغيل DS4Windows بعد تسجيل الدخول + + + حفظ الماكرو المسجَّل؟ + + + Scan Code + + + جارٍ البحث عن أيادي تحكم... + + + اختر فعلاً لـ *action* + + + اختر ماكرو + + + تعيين الزناد العادي + + + تعيين زناد الإلغاء + + + الاختصارات + + + معايرة محاكاة عجلة القيادة بالجايرو السداسي + + + (1) ضع يد التحكم في المنتصف، ثبّتها واضغط "X" + + + (2) أدر إلى وضعية 90 درجة يسارًا (أو يمينًا) واضغط "X" + + + (3) أدر إلى وضعية 90 درجة يمينًا (أو يسارًا) واضغط "X" + + + يتم تعيين جميع نقاط المعايرة عندما يتحول لون الشريط الضوئي إلى الأخضر. أثناء تدوير يد التحكم، يومض لون الشريط الضوئي عندما تكون يد التحكم عند نقطة المعايرة. اقبل المعايرة بزر OK + + + لا يمكن معايرة قيم محاكاة عجلة القيادة بالجايرو (sixaxis) دون وجود يد تحكم. وصّل يد تحكم عبر البلوتوث أو USB + + + خيار محور محاكاة عجلة القيادة بالجايرو مضبوط على NONE (المحاكاة غير مستخدمة). يرجى اختيار خيار محور قبل معايرة محاكاة عجلة القيادة بالجايرو السداسي + + + انقر لقراءة Sixaxis المتقدمة + + + جارٍ البدء... + + + بدء + + + الخطوة 1: تثبيت بنية VIIPER الخلفية + + + إيقاف قوي + + + إيقاف خفيف + + + تم إيقاف DS4Windows + + + جارٍ إيقاف أيادي تحكم DS4 المدخلة + + + جارٍ إيقاف أيادي التحكم الافتراضية للإخراج + + + إيقاف + + + تمرير لأسفل + + + تمرير لليسار + + + تمرير لليمين + + + تمرير لوحة اللمس لتغيير الملفات التعريفية + + + تمرير لأعلى + + + النقر مع الاستمرار للسحب، مع تأخير بسيط للنقرات المفردة + + + اختبار قوي + + + اختبار خفيف + + + اختبار + + + مستند نصي (*.txt) + + + إمالة لأسفل + + + إمالة لليسار + + + إمالة لليمين + + + إمالة لأعلى + + + حركة لوحة اللمس الآن معطّلة + + + حركة لوحة اللمس الآن مفعّلة + + + أعد التفعيل بالضغط على PS+Touchpad + + + تمرير بإصبعين على لوحة اللمس يسارًا أو يمينًا + + + اكتب الاسم الجديد هنا + + + اكتب اسم الملف التعريفي هنا + + + تحتاج إلى تشغيل DS4Windows كمسؤول لتفعيل هذا الوضع. + + + غير مُعيَّن + + + أعلى + + + تطبيق DS4Windows محدَّث. + + + يمكنك أيضًا استخدام يد التحكم لتغيير عناصر التحكم + + + جارٍ استخدام الوضع الحصري + + + يد التحكم {0} تستخدم الملف التعريفي "{1}". مستوى البطارية {2}٪ + + + جارٍ استخدام الوضع المشترك + + + هذا يعطّل لوحة اللمس كماوس + + + يرجى إدخال اسم صالح + + + انتظر *number* مللي ثانية + + + سيتم الاحتفاظ به + + + ملفات XML (*.xml) + + + السماح بتبديل وظيفة ماوس لوحة اللمس بواسطة PS + النقر على لوحة اللمس. + + + تفعيل خادم UDP. عنوان ومنفذ استماع الخادم. خيارات قيمة العنوان: 127.0.0.1 لـ localhost فقط | 0.0.0.0 كل العناوين | اسم مضيف أو عنوان IP محدد. + + + ^ABC = التطابق في بداية النص (^) | ABC$ = التطابق في نهاية النص ($) | *ABC = يحتوي على نص (*) + + + إذا كان مفعّلاً، تعرض صفحة تبويب Log رسائل مفصّلة لأحداث الملفات التعريفية التلقائية. + + + استخدم قيمة رمز مسح (Scan Code) لمفاتيح لوحة المفاتيح في الماكرو + + + شغّل الماكرو عند تحرير مفتاح الزناد + + + شغّل عدة ماكروهات بترتيب متزامن إذا كان لنفس الزناد عدة ماكروهات (يكتمل ماكرو الضغط قبل تشغيل ماكرو التحرير) + + + كرر الماكرو أثناء الضغط المستمر على مفتاح الزناد + + + احتفظ بحالة المفتاح الأخيرة عند اكتمال تنفيذ الماكرو (أي إذا بقي مفتاح في حالة مضغوطة فلن يعود تلقائيًا إلى الحالة الافتراضية) + + + استدارة زوايا العصا المربعة + + + ملف Actions.xml كان تالفًا. جارٍ البدء من جديد. + + + تفعيل خادم OSC. الاستماع إلى المنفذ على جميع العناوين. + + + يد التحكم {0} تستخدم الملف التعريفي المؤقت "{1}" + + + + + + اختر نوع يد التحكم الافتراضية للإخراج (يسري عند حفظ الملف التعريفي) + + + بدأ اللمس + + + انتهى اللمس + + + إلغاء + حفظ + اختر يد تحكم + لا يوجد مصدر + معطّل + تم الحفظ في الملف التعريفي + نشط + صوت يد التحكم + الكشف التلقائي عن اللعبة + التطبيق المحدد + صوت النظام · المخرج الافتراضي + مباشر + في الانتظار + تغيّرت يد التحكم + لا يوجد إدخال حديث + أعد فتح المحرر لمعاينة يد التحكم الجديدة. + انقطع اتصال يد التحكم. أعد الاتصال وأعد فتح المحرر. + في انتظار إدخال جديد من يد التحكم… + في انتظار إدخال يد التحكم… + افتح هذا الملف التعريفي من يد تحكم متصلة. + لا توجد أزرار مضغوطة + تم إيقاف VIIPER مؤقتًا لسلامة النظام + يوجد تعارض مع مراقب USB الخاص بـ Citrix نشط حاليًا. + • تعطيل إعادة توجيه USB العامة في Citrix فقط +• إعادة تشغيل Windows قبل بدء تشغيل VIIPER مرة أخرى + تعطيل مراقب USB المتعارض + المتابعة بدون إخراج افتراضي + يجب استبدال إصدار USB-IP + فشل التحقق من VIIPER + إصدار VIIPER المثبَّت لا يطابق حزمة DS4Windows هذه. + مطلوب تحديث موثَّق + • تثبيت والتحقق من VIIPER 0.1.9-rc4.6.6 المرفق +• إزالة حزمة USB-IP غير المدعومة بأمان +• إعادة التشغيل، ثم إتمام تثبيت USB-IP 0.9.7.7 + • تثبيت نفس نسخة VIIPER المرفقة بالضبط +• الإبقاء على موقع التثبيت الحالي +• لن يتم تشغيل البنية الخلفية غير الموثقة + إصلاح VIIPER + USB-IP + تثبيت عادي + إبقاء DS4Windows محمولاً + إعداد VIIPER مطلوب + مطلوب قبل تشغيل DS4Windows + • تثبيت VIIPER 0.1.9-rc4.6.6 المرفق +• تثبيت والتحقق من USB-IP 0.9.7.7 +• تشغيل DS4Windows فقط بعد نجاح فحص وقت التشغيل + تثبيت / إصلاح + جارٍ التحقق من حزمة DS4Windows... + نشط + الزناد الأيسر + الزناد الأيمن + شكّل إحساس زناد {0} + حفظ ملف تعريف زناد جديد + إعادة تسمية ملف تعريف الزناد + حذف ملف تعريف الزناد + استجابة + سلاح + اهتزاز + البداية + الجدار + القوة + معاينة + إعادة تعيين {0} + اهتزاز رامبل اللعبة + بث محرك اهتزاز HID {0} الخاص باللعبة إلى {1} كتأثير اهتزاز منخفض الكمون. + قوي / أيسر + خفيف / أيمن + تفعيل اهتزاز رامبل اللعبة بشكل مستقل لـ {0}. هذا لا يربط الزناد الآخر. + فعل الضغط الكامل + نهاية المسار + عندما يُضغط {0} بالكامل، شغّل الفعل أدناه باستخدام السلوك المحدد. + الفعل المُعيَّن + تغيير › + السلوك + التأخير + اختر يد تحكم أو ملف تعريفي + اختر يد تحكم أو ملف تعريفي لفتح Trigger Lab. + تأثير مخصص محفوظ. + حفظ ملف تعريف الزناد + زناد مخصص {0} + مخصص + حذف {0}؟ + Trigger Lab + معطّل + يعمل فعل الزناد العادي فقط. + إضافة عند الضغط الكامل + أبقِ فعل الزناد العادي نشطًا وشغّل أيضًا فعل الضغط الكامل عند نهاية المسار. + استبدال عند الضغط الكامل + حرّر فعل الزناد العادي واستبدله بفعل الضغط الكامل عند نهاية المسار. + زناد شعري + شغّل كلا الفعلين عند الضغط الكامل، ثم حرّرهما بمجرد ابتعاد الزناد عن نهاية المسار. + إطلاق سريع + انتظر التأخير المختار، ثم شغّل الفعل العادي أو فعل الضغط الكامل حسب مدى ضغط الزناد. + إطلاق سريع (حصري) + انتظر التأخير المختار وشغّل فعلاً واحدًا فقط: الضغط العادي أو الضغط الكامل. + نقر + لمس + تحرير + العصا اليسرى + العصا اليمنى + Switch 2 Pro Controller + Joy-Con 2 المدمج + Joy-Con 2 (الأيسر) + Joy-Con 2 (الأيمن) + · USB + · بلوتوث + اختر عصا فعلية + أدر العصا المحددة حول كامل حافتها، ثم دعها تستقر في المنتصف. لن يُحفظ شيء حتى تختار حفظ المعايرة. + معايرة الكمبيوتر نشطة لهذه العصا. + يُستخدم معايرة يد التحكم الأصلية، أو الإعدادات الافتراضية إذا لم تكن متوفرة. + لم يبدأ + إزالة معايرة الكمبيوتر لـ {0} على يد التحكم هذه؟ + +لن يتم تغيير معايرة المصنع الأصلية. بقية العصي وأيادي التحكم لن تتأثر. + جارٍ تحضير إعادة التعيين + جارٍ تحضير المعايرة + جارٍ تحرير إدخال يد التحكم المُعيَّن… + يرجى الانتظار + تعذّر بدء المعايرة + انتظر إدخالاً حيًا من يد التحكم وأكمل أي معايرة أخرى، ثم أعد المحاولة. مطلوب هوية يد تحكم محفوظة ومخزن معايرة قابل للكتابة على الكمبيوتر. + تعذّر بدء المعايرة. لم يتم حفظ أي معايرة. + جارٍ إعادة تعيين معايرة الكمبيوتر + جارٍ حفظ معايرة الكمبيوتر + يبقى إدخال يد التحكم محررًا أثناء تخزين النتيجة وتطبيقها. + تمت إعادة تعيين معايرة الكمبيوتر + تم حفظ المعايرة + يمكنك معايرة عصا أخرى أو إغلاق هذه النافذة. + {0}: تمت إزالة تجاوز الكمبيوتر. معايرة المصدر نشطة مرة أخرى. + {0}: تم الحفظ على هذا الكمبيوتر وتطبيقه على اتصال يد التحكم هذا. + اكتمل + تعذّر تحديث ملف معايرة الكمبيوتر. المعايرة الحية السابقة لم تتغيّر. أعد محاولة حفظ المعايرة أو ألغِ. + العملية ليست جاهزة للانتهاء بعد. انتظر عينات صالحة أو ألغِ وأعد المحاولة. + انتهت المعايرة + أغلق هذه النافذة وأعد فتح المعايرة من يد التحكم الحالية قبل المحاولة مرة أخرى. + لم يُطبَّق + تم تحديث ملف الكمبيوتر، لكن التغيير لم يُطبَّق على الاتصال النشط. أعد الاتصال لتحميله، أو أعد تعيينه صراحةً. الإلغاء لا يمكنه التراجع عن كتابة قيد التنفيذ بالفعل. + هذه العملية لم تعد سارية. لم تُكمل تغيير المعايرة. + تعذّر إنهاء المعايرة. تعذّر تأكيد نتيجة الملف؛ أعد الاتصال وتحقق من العصا المحددة قبل إعادة المحاولة. + تم إلغاء المعايرة + يمكن استئناف إدخال يد التحكم العادي. يمكنك البدء مرة أخرى عندما تكون جاهزًا. + قد يستمر حفظ قيد التنفيذ بالفعل في تحديث ملف الكمبيوتر. ستظهر نتيجته النهائية هنا. + تم تجاهل الالتقاط غير المحفوظ؛ لم تتغير المعايرة الحالية. + ألغيت + تغيّرت يد التحكم أو المعايرة. ابدأ مرة أخرى من يد التحكم الحالية. + لم يُحفظ + 1 · أدر {0} + حرّك ببطء حول كامل الحافة الخارجية في كلا الاتجاهين. استمر في الحركة حتى تكتمل هذه الخطوة؛ التوقفات لا تُحتسب. + {0} ثانية حركة متبقية + 2 · حرّر العصا + ارفع يدك عن العصا ودعها تعود إلى المنتصف. + في انتظار ثانيتين من السكون + 3 · ابقَ ثابتًا + اترك العصا بدون لمس أثناء قياس مركزها. لمسها يعيد بدء فترة السكون. + {0} ثانية سكون متبقية + جاهز لإعادة التعيين + جاهز للحفظ + اختر حفظ المعايرة لتطبيق هذه النتيجة، أو إلغاء لتجاهلها. + جاهز + مطلوب مزيد من حركة العصا + ألغِ وأعد المحاولة. اصل إلى الحافة الكاملة في كل اتجاه، ثم دع العصا تتمركز تلقائيًا. + تم رفض المعايرة + ابدأ معايرة جديدة عندما تكون يد التحكم جاهزة. + تغيّر سياق يد التحكم + تغيّرت يد التحكم أو الملف التعريفي أو الزوج. أغلق هذه النافذة وأعد فتح المعايرة من يد التحكم التي تريد استخدامها. + توقفت المعايرة + إعادة تعيين معايرة الكمبيوتر للعصا + diff --git a/DS4Windows/Properties/Resources.resx b/DS4Windows/Properties/Resources.resx index a030d126..23c9366a 100644 --- a/DS4Windows/Properties/Resources.resx +++ b/DS4Windows/Properties/Resources.resx @@ -655,4 +655,176 @@ Touch Ended + + Cancel + Save + + Select a controller + No source + Off + Saved to profile + Active + Controller audio + Automatic game detection + Selected app + System audio · default output + + Live + Waiting + Controller changed + No recent input + Reopen the editor to preview the new controller. + Controller disconnected. Reconnect and reopen the editor. + Waiting for fresh controller input… + Waiting for controller input… + Open this profile from a connected controller. + No buttons pressed + + VIIPER paused for system safety + A conflicting Citrix USB monitor is active. + • Disable Citrix generic USB redirection only +• Restart Windows before VIIPER starts again + Disable conflicting USB monitor + Continue without virtual output + USB-IP version must be replaced + VIIPER verification failed + The installed VIIPER does not match this DS4Windows package. + Verified update required + • Install and verify bundled VIIPER 0.1.9-rc4.6.6 +• Safely remove the unsupported USB-IP package +• Restart, then finish installing USB-IP 0.9.7.7 + • Install the exact bundled VIIPER build +• Keep your existing installation location +• The unverified backend will not be started + Repair VIIPER + USB-IP + Install standard + Keep DS4Windows portable + VIIPER setup required + Required before DS4Windows can run + • Install the bundled VIIPER 0.1.9-rc4.6.6 build +• Install and verify USB-IP 0.9.7.7 +• Start DS4Windows only after the runtime probe passes + Install / Repair + Verifying the DS4Windows package... + + Active + Left Trigger + Right Trigger + Shape the {0} trigger feel + Save new trigger profile + Rename trigger profile + Delete trigger profile + Feedback + Weapon + Vibration + Start + Wall + Force + Preview + Reset {0} + Game rumble vibration + Stream the game's {0} HID rumble motor to {1} as a low-latency vibration effect. + heavy / left + light / right + Independently enable game-rumble vibration for {0}. This does not link the other trigger. + Full-pull action + END OF TRAVEL + When {0} is pressed completely, run the action below using the selected behavior. + Assigned action + Change › + Behavior + Delay + Select a controller or profile + Select a controller or profile to open Trigger Lab. + Saved custom effect. + Save trigger profile + Custom Trigger {0} + Custom + Delete {0}? + Trigger Lab + Off + Only the regular trigger action runs. + Add at full pull + Keep the regular trigger action active and also run the full-pull action at the end of travel. + Replace at full pull + Release the regular trigger action and replace it with the full-pull action at the end of travel. + Hair trigger + Run both actions at full pull, then release both as soon as the trigger backs away from the end stop. + Hip fire + Wait for the chosen delay, then run the regular or full-pull action based on how far the trigger was pressed. + Hip fire (exclusive) + Wait for the chosen delay and run only one action: regular pull or full pull. + + Click + Touch + Release + + Left stick + Right stick + Switch 2 Pro Controller + Joined Joy-Con 2 + Joy-Con 2 (Left) + Joy-Con 2 (Right) + · USB + · Bluetooth + Choose a physical stick + Rotate the selected stick around its full edge, then let it rest in the center. Nothing is saved until you choose Save calibration. + PC calibration is active for this stick. + Using original controller calibration, or defaults if unavailable. + Not started + Remove the PC calibration for the {0} on this controller? + +The original factory calibration will not be changed. Other sticks and controllers are unaffected. + Preparing reset + Preparing calibration + Releasing this controller's mapped input… + Please wait + Calibration could not start + Wait for live controller input and finish any other calibration, then try again. A remembered controller identity and writable PC calibration store are required. + Calibration could not start. No calibration was saved. + Resetting PC calibration + Saving PC calibration + Controller input remains released while the result is stored and applied. + PC calibration reset + Calibration saved + You can calibrate another stick or close this window. + {0}: the PC override was removed. Source calibration is active again. + {0}: saved on this PC and applied to this controller connection. + Complete + The PC calibration file could not be updated. The previous live calibration is unchanged. Retry Save calibration or cancel. + The operation is not ready to finish. Wait for valid samples or cancel and retry. + Calibration ended + Close this window and reopen calibration from the current controller before trying again. + Not applied + The PC file was updated, but the change was not applied to the active connection. Reconnect to load it, or explicitly reset it. Cancellation cannot undo a write already in progress. + This operation is no longer current. It did not complete a calibration change. + Calibration could not finish. The file outcome could not be confirmed; reconnect and check the selected stick before retrying. + Calibration cancelled + Ordinary controller input can resume. You can start again when ready. + A save already in progress may still update the PC file. Its final result will appear here. + The unsaved capture was discarded; the existing calibration was not changed. + Cancelled + The controller or calibration changed. Start again from the current controller. + Not saved + 1 · Rotate the {0} + Move slowly around the full outer edge in both directions. Keep moving until this step completes; pauses do not count. + {0} moving seconds remaining + 2 · Release the stick + Take your hand off the stick and let it return to center. + Waiting for 2 seconds of rest + 3 · Hold still + Leave the stick untouched while its center is measured. Touching it restarts the rest period. + {0} still seconds remaining + Ready to reset + Ready to save + Choose Save calibration to apply this result, or Cancel to discard it. + Ready + More stick travel is needed + Cancel and try again. Reach the full edge in every direction, then let the stick center itself. + Calibration rejected + Start a new calibration when the controller is ready. + Controller context changed + The controller, profile or pair changed. Close this window and reopen calibration from the controller you want to use. + Calibration stopped + Reset PC stick calibration diff --git a/DS4Windows/Translations/Strings.ar.resx b/DS4Windows/Translations/Strings.ar.resx index ce312819..9bbceeac 100644 --- a/DS4Windows/Translations/Strings.ar.resx +++ b/DS4Windows/Translations/Strings.ar.resx @@ -428,7 +428,7 @@ Gryo معين كفأرة ملفات التعريف - (لا توجد أيادي تحكم متصلة (الأقصى {0} + لا توجد أيادي تحكم متصلة (الأقصى {0}) بداية النقرة @@ -442,4 +442,3278 @@ Gryo معين كفأرة المعايرة في العالم الحقيقي - + + + اختيار إعداد مسبق + + + الاحتفاظ بحجم هذه النافذة بعد الإغلاق + + + الاحتفاظ بالحجم + + + مخطط يد التحكم + + + اختر عنصر تحكم مباشرة على يد التحكم. + + + DualShock 4 + + + DualSense + + + DualSense Edge + + + Switch 2 Pro + + + زوج Joy-Con + + + Joy-Con L (عمودي) + + + Joy-Con R (عمودي) + + + Joy-Con L (أفقي) + + + Joy-Con R (أفقي) + + + لوحة الاتجاهات + + + معكوس + + + معكوس X + + + معكوس Y + + + تدوير 90 درجة + + + تدوير -90 درجة + + + الأزرار الأمامية + + + WASD + + + مفاتيح الأسهم + + + Cross + + + Circle + + + Square + + + Triangle + + + L1 + + + R1 + + + L2 + + + R2 + + + Share + + + Options + + + Guide + + + Capture + + + C + + + كتم الصوت + + + Function يسار + + + Function يمين + + + المجداف السفلي الأيسر + + + المجداف السفلي الأيمن + + + لمس يسار + + + لمس متعدد + + + لمس يمين + + + لمس أعلى + + + L3 + + + LSU + + + LSR + + + LSD + + + LSL + + + R3 + + + RSU + + + RSR + + + RSD + + + RSL + + + أعلى + + + يمين + + + أسفل + + + يسار + + + نصيحة: انقر بزر الفأرة الأيمن على عناصر التحكم المدعومة لعرض الإعدادات المسبقة. + + + تعيينات الأزرار + + + انقر نقرًا مزدوجًا على صف لتغيير إجراءه. + + + إظهار المعاينة المباشرة + + + قائمة فقط + + + الإجراءات الخاصة + + + L2/R2 + + + تم إنشاؤه باستخدام Trigger Lab + + + يقوم هذا التأثير المحمي في الملف الشخصي بتجاوز خرج الزناد التكيفي الوارد من اللعبة. عدّله في Trigger Lab. + + + محمي + + + قراءات يد التحكم + + + LS + + + القوة + + + وحدات + + + مللي ثانية + + + عكس + + + ثا. + + + هذا الزر محجوز للمعايرة أثناء استخدام العصا اليسرى لوضع Flick Stick. + + + احفظ الملف الشخصي، ثم اضغط على الزر المحدد داخل اللعبة لتنفيذ دورة نظر 360° بالفأرة. يعمل فقط في وضع Flick Stick. + + + قم بزيادة Real World Calibration إذا كانت الدورة أقل من المطلوب، أو قلّلها إذا كانت أكثر من اللازم. اختر «غير معيّن» لتحرير الزر. + + + RS + + + الدوران: + + + هذا الزر محجوز للمعايرة أثناء استخدام العصا اليمنى لوضع Flick Stick. + + + L2 و R2 + + + X + + + Z + + + R + + + G + + + B + + + فارغ + + + وميض عند + + + نبض عند + + + أثناء الشحن: + + + نبض + + + قوس قزح + + + اللون حسب نسبة البطارية + + + ثا/دورة + + + تعويض الاهتزاز + + + نقرة مزدوجة + + + أسفل اليمين كزر الفأرة الأيمن + + + إجراء نقر التمرير (وضع DS4) + + + البدء مع إيقاف Slide/Scroll + + + الحد الأدنى للعتبة + + + الكرة التتبعية + + + الاحتكاك: + + + Y + + + X+Y + + + تعطيل العكس + + + الإصبع على لوحة اللمس + + + PS + + + نقرة لوحة اللمس + + + الجانب الأيسر + + + الجانب الأيمن + + + التمرير لأعلى + + + التمرير لأسفل + + + التمرير لليسار + + + التمرير لليمين + + + عصا الخرج + + + محاور الخرج + + + أفقي وعمودي + + + أفقي فقط + + + عمودي فقط + + + الحد الأدنى X + + + الحد الأدنى Y + + + عكس X + + + عكس Y + + + التنعيم + + + خيارات التنعيم + + + الحد الأقصى للمنطقة X: + + + الحد الأقصى للمنطقة Y: + + + العودة إلى المركز عند التحرير: + + + الإمالة لأعلى + + + الإمالة لأسفل + + + الإمالة لليسار + + + الإمالة لليمين + + + الزنادات + + + سلوك الدوران - محرك الجيروسكوب + + + شرط التقييم + + + و + + + أو + + + محور عجلة القيادة + + + محور X الأيسر + + + محور Y الأيسر + + + محور X الأيمن + + + محور Y الأيمن + + + محور L+R للزناد + + + محور X في VJoy1 + + + محور Y في VJoy1 + + + محور Z في VJoy1 + + + محور X في VJoy2 + + + محور Y في VJoy2 + + + محور Z في VJoy2 + + + نطاق عجلة القيادة + + + معايرة + + + معايرة الجيروسكوب + + + حساسية الجيروسكوب: + + + محور X + + + المتوسط الموزون + + + وزن التنعيم + + + محور X + + + الوزن + + + درجة/ثا + + + وقت التأخير + + + Trigger Lab + + + خيارات Nintendo + + + تُحفظ هذه الإعدادات مع الملف الشخصي وتُطبَّق على أجهزة التحكم التي تدعمها. + + + كيف تريد أن تلعب؟ + + + أشر إلى القوائم. صوّب بالإمالة. اشعر باللعبة. ابدأ بما تريد فعله؛ الضبط الدقيق مخفي داخل كل قسم. + + + يُحفظ مع هذا الملف الشخصي لأي جهاز تحكم. الميزات التي لا يدعمها جهاز التحكم لا تأثير لها. فأرة المكتب والتصويب الحركي ميزتان منفصلتان. + + + فأرة على المكتب + + + حرّك Joy-Con للإشارة أو التصويب. استخدم عصاه للتمرير. + + + حرّك Joy-Con لتحريك الفأرة + + + حرّك Joy-Con على سطح للتحكم في مؤشر الفأرة. + + + ضع حافة المستشعر على مكتب أو سجادة فأرة، ثم حرّك Joy-Con. رفعه يتيح لك إعادة التموضع دون تحريك المؤشر. + + + حرّك للتصويب أو الإشارة إلى القوائم. استخدم العصا للتمرير أثناء ملامسة المستشعر للسطح. + + + عيّن نقرات الفأرة في تعيينات الأزرار. لإجراءات مختلفة أثناء التواجد على المكتب فقط، استخدم مستشعر IR المطابق كـ Shift Modifier. + + + أي Joy-Con: + + + تلقائي + + + كلاهما + + + تمرير العصا: + + + اختر ما إذا كانت العصا تمرر عموديًا فقط أو في جميع الاتجاهات الأربعة. + + + أعلى / أسفل + + + رباعي الاتجاهات + + + الحساسية اليسرى: + + + الحساسية اليمنى: + + + اكتشاف السطح + + + جرّب وضع Relaxed إذا لم يتم اكتشاف سطحك. تؤثر هذه الإعدادات أيضًا على إجراءات الأزرار المرتبطة بالسطح والتصويب. + + + اكتشاف السطح الأيسر: + + + صارم + + + مرن + + + اكتشاف السطح الأيمن: + + + التصويب بالإمالة + + + تصويب دقيق بيديك، مع أو بدون مؤشر فأرة. + + + اختر ماذا تفعل الإمالة + + + أزرار الإمالة المعيّنة (بدون فأرة) + + + مؤشر الفأرة + + + عصا التصويب الافتراضية + + + إجراءات الإمالة السريعة + + + عناصر التحكم الحركي الخاصة باللعبة + + + متى تصوّب: + + + دائمًا مفعّل + + + اضغط مطولاً ZL / L2 + + + اضغط مطولاً ZR / R2 + + + مخصص — راجع إعدادات الجيروسكوب + + + تتبع خيارات الزناد تخطيط أزرارك. التركيبات المخصصة وخيار toggle-to-aim متاحة في إعدادات الجيروسكوب. + + + سرعة تصويب الفأرة: + + + فتح إعدادات الجيروسكوب الكاملة… + + + اختر أزرار التصويب، وخرج العصا، والحساسية، والتنعيم. + + + ضبط دقيق للتصويب + + + تقليل انحراف الجيروسكوب الجانبي + + + يساعد على تقليل انحراف الجيروسكوب الجانبي. أوقف هذا إذا أثرت الأجهزة الإلكترونية القريبة على التصويب. + + + تجاهل حركات الجيروسكوب الصغيرة جدًا لتثبيت التصويب. اضبط على 0 لأقصى حساسية. + + + تجاهل الحركات الصغيرة: + + + استخدم العصا مع تصويب الجيروسكوب للدوران أكثر. اضبط على 0 لإيقاف هذا. + + + التصويب المدعوم بالعصا: + + + حركة فأرة أكثر سلاسة + + + يجعل حركة الفأرة أكثر سلاسة بين تحديثات جهاز التحكم. هذا لا يسرّع جهاز التحكم نفسه. + + + اضبط حساسية الحركة الجانبية في المحاكيات المتوافقة. 1 هو المستوى العادي. + + + حساسية دوران المحاكي: + + + الحفاظ على استواء التصويب الحركي + + + يحافظ على استواء التصويب الحركي عند إمالة جهاز التحكم. + + + إيقاف التصويب مؤقتًا بزر + + + أوقف التصويب الحركي مؤقتًا بزر حتى تتمكن من إعادة وضع جهاز التحكم. + + + اضغط مطولاً لإيقاف التصويب مؤقتًا، أو اضغط لتبديل الإيقاف المؤقت. يُمسح الإيقاف المؤقت عند التوقف عن استخدام الجيروسكوب. + + + إعدادات التصويب للتعديل: + + + أزرار الضغط المطول للقفل: + + + أزرار الضغط لتبديل القفل: + + + تثبيت التصويب عند الضغط على الأزرار + + + يقلل حركة التصويب الناتجة عن الضغط على الأزرار أو تحريرها. + + + اضبط بدقة وضعًا قمت بتفعيله بالفعل أعلاه. هذه الخيارات لا تغيّر خرج التصويب لديك. + + + مصدر التفعيل: + + + الأزرار التي تثبّت التصويب: + + + المنطقة الميتة: + + + إيقاف مؤقت عند الضغط: + + + إيقاف مؤقت عند التحرير: + + + المنطقة الميتة بعد التحرير: + + + الأزرار التي تبطئ التصويب: + + + التخميد: + + + بعد التحرير: + + + تثبيت التصويب عند لمس المكتب + + + اختر مستشعر IR الأيسر أو الأيمن في قائمة زناد الجيروسكوب للتصويب أثناء لمس سطح. + + + أوقف التصويب مؤقتًا حول الضغط على الأزرار، أو تجاهل الحركات الصغيرة، أو قلّل الحساسية أثناء الضغط على زر. + + + المستشعر الضوئي الأيسر + + + أزرار المنطقة الميتة / تثبيت النقر: + + + أزرار التخميد: + + + المستشعر الضوئي الأيمن + + + التصويب المزدوج بـ Joy-Con + + + دع يديك تتشاركان التصويب، أو بدّل بينهما. + + + التصويب باستخدام كلا Joy-Con (DJG) + + + دع الزوج المتصل يتشارك التصويب الحركي. أوقف هذا لاستخدام مصدر الحركة الفردي المعتاد. + + + اختر أي يد توفر الحركة. هذا لا يقرن Joy-Con الخاصين بك ولا يفعّل تصويب الفأرة. + + + للتصويب بالفأرة أو العصا، ابدأ من التصويب بالإمالة ← متى تصوّب: دائمًا مفعّل. اختيار زر هناك يضيف تحكمًا منفصلًا للتشغيل/الإيقاف؛ ولا يختار يدًا. + + + إعداد التصويب الحركي… + + + اختر كيف تعمل اليدان معًا + + + اليد القائدة، وتبديل الجانب، وأزرار الإيقاف المؤقت. + + + الوضع: + + + كلتا اليدين — تبديل اليد القائدة + + + يد واحدة في كل مرة + + + كلتا اليدين — إيقاف كل جانب + + + اليد المفضلة للتصويب: + + + اختر اليد التي تقود تصويبك، أو ادمج كلتيهما عند إيقاف كل جانب على حدة. + + + دمج كليهما + + + سلوك الزر: + + + أثناء الضغط المطول + + + اضغط للتبديل + + + أزرار Joy-Con الأيسر + + + أزرار Joy-Con الأيمن + + + استشعار ملاحظات اللعبة + + + استشعر الاصطدامات والملمس وتأثيرات الزناد كاهتزاز HD. + + + اضبط قوة الاهتزاز الإجمالية. 100% هو المستوى العادي؛ 0% يوقف اهتزاز الجسم. + + + قوة اهتزاز الجسم: + + + تضمين اهتزاز زناد Xbox + + + استشعر اهتزازات زناد Xbox على الجانب المطابق من جهاز التحكم الخاص بك. يشترك هذا الإعداد مع Advanced. + + + تنويع إحساس اهتزاز الزناد + + + غيّر إحساس اهتزاز الزناد مع تغيّر قوته. + + + قوة اهتزاز الزناد: + + + إحساس اهتزاز ثابت: + + + تضمين اهتزازات DualSense المفصلة + + + يحوّل اهتزازات DualSense المفصلة إلى اهتزاز HD أيسر وأيمن. + + + تضمين تأثيرات زناد DualSense + + + يحوّل تأثيرات زناد DualSense إلى اهتزازات. لا يمكن لزنادات Switch 2 إضافة مقاومة فيزيائية. + + + استخدام اهتزاز الجسم بأسلوب Xbox + + + امنح اهتزاز الجسم إحساسًا متسقًا بأسلوب Xbox بدلاً من اتباع تفاصيل اهتزاز كل لعبة. + + + إحساس اهتزاز الجسم: + + + أخّر الاهتزاز ليتوافق مع صوت اللعبة المتأخر. اتركه عند 0 لأسرع استجابة. + + + تأخير اهتزاز اللعبة: + + + استمع وتحدث عبر منفذ سماعة الرأس في Switch 2 Pro الخاص بك. + + + يمر الصوت مباشرة عبر Windows. يعمل بشكل مستقل عن جهاز التحكم الافتراضي الذي اخترته؛ لا حاجة لتبديل صوت DS4Windows. + + + USB فقط. صوت سماعة الرأس عبر البلوتوث غير مدعوم بعد. يحمل كابل AUX عادي الصوت للخارج، لكنه لا يمكنه اختبار ميكروفون السماعة. + + + امنح الأزرار مهمة ثانية + + + اضغط مطولاً أو بدّل زرًا للوصول إلى مجموعة أخرى من الإجراءات. + + + مثال: احتفظ بالإجراء المعتاد لزر، ثم امنحه مهمة مختلفة أثناء ضغطك المطول على زر آخر. + + + مجموعة الإجراءات للتعديل: + + + اضغط على زر لتبديل الإجراءات: + + + يفتح لك الاختصار Shift Modifier. بالنسبة لإجراء ثانٍ جديد، يكون Switch 2 Mode Shift محددًا مسبقًا. يتم الاحتفاظ بزنادات shift الموجودة. + + + تعديل الإجراء الثاني… + + + فتح تعيينات الأزرار + + + اختر الإجراء في النافذة، ثم احفظ هذا الملف الشخصي. يُحجز زر shift لتبديل الإجراءات، لذا لا يُرسل إجراء اللعبة العادي الخاص به. + + + الإجراءات الثانية التلقائية (اختياري) + + + عند التفعيل أدناه، يبدأ التصويب في الإجراءات الثانية. تعود أزرار الضغط المطول أو التبديل الخاصة بك إلى الإجراءات العادية بدلاً من ذلك. هذه الخيارات لا تُفعّل التصويب. + + + البدء تلقائيًا في الإجراءات الثانية أثناء: + + + التصويب بالفأرة نشط + + + التصويب بالعصا نشط + + + التوجيه الحركي + + + أشر أو مرّر أو اضغط بعصا + + + اضبط بدقة العصي التي عيّنتها لإجراءات الفأرة أو الأزرار. + + + تمرير العصا + + + عيّن إجراءات التمرير في تعيينات الأزرار أولاً. النقر يمرر مرة واحدة؛ الضغط المطول يواصل التمرير. + + + العصا اليسرى: + + + ضغط مطول + + + العصا اليمنى: + + + إجراءات زر العصا + + + الضغط المطول يبقي الإجراء مضغوطًا. النقر يُفعّله مرة واحدة في كل مرة تحرك فيها العصا إلى ذلك الاتجاه. + + + العصا اليسرى + + + العصا اليمنى + + + سرعة فأرة العصا + + + اضبط السرعة للعصي المعيّنة لحركة الفأرة. 5 هي السرعة العادية؛ 0 توقف الحركة. + + + التخطيط والبطارية + + + طابق ملصقات أزرارك، أو أمسك Joy-Con واحد أفقيًا، أو وفّر البطارية. + + + يتبع Xbox مواضع الأزرار. يتبع Nintendo الملصقات المطبوعة A وB وX وY. + + + تخطيط الأزرار الأمامية: + + + Xbox + + + Nintendo + + + أسلوب إمساك Joy-Con: + + + اختر اتجاه البدء. الاختيار الذي يتم في تبويب Controllers له الأولوية لذلك Joy-Con. + + + عمودي + + + أفقي + + + قطع البلوتوث التلقائي + + + اقطع الاتصال بعد فترة خمول لتوفير البطارية، أو بعد مدة محددة حتى أثناء اللعب. + + + عند الخمول + + + بعد مدة محددة + + + قطع الاتصال بعد: + + + يوم + + + ساعة + + + دقيقة + + + اضبط المدة على صفر لتعطيل المؤقت. حتى يتم تغييره هنا، تحتفظ الملفات الشخصية الحالية بإعداد Idle Disconnect الخاص بها. + + + الاهتزاز عند الاتصال + + + شغّل اهتزازًا قصيرًا عندما يكون جهاز التحكم جاهزًا. + + + تصحيح الانحراف ونطاق العصا + + + استخدم المعايرة الموجهة إذا شعرت أن العصا غير طبيعية أو أن التصويب ينحرف. + + + معايرة العصا + + + اتبع الخطوات الموجهة لتصحيح مراكز العصا ونطاقها. تبقى إعدادات المصنع دون تغيير. + + + معايرة العصي… + + + ضع جهاز التحكم على سطح ثابت واتركه ساكنًا لمدة خمس ثوانٍ على الأقل بعد البدء. + + + إعادة بدء معايرة الجيروسكوب + + + صحّح انحراف الجيروسكوب. أبقِ جهاز التحكم ساكنًا لمدة خمس ثوانٍ على الأقل. + + + قم بتدوير جهاز التحكم ببطء على شكل الرقم 8. تتوقف مدخلات اللعبة أثناء المعايرة. + + + معايرة تصحيح الانحراف + + + استخدم هذا إذا بدا تصحيح الانحراف الجانبي غير دقيق. + + + متقدم + + + Xbox 360 + + + Xbox One / Series + + + A + + + التخطيط الأمامي لـ Nintendo + + + Plus وMinus وHome وCapture وL/R وZL/ZR + + + إزالة الارتداد (Debouncing) + + + ترجمة اهتزاز impulse-trigger الخاص بـ Xbox + + + استشعر اهتزازات زناد Xbox من خلال زنادات أو محركات اهتزاز جهاز التحكم الخاص بك. يعمل بشكل مستقل عن Trigger Lab. + + + إرسال اهتزاز impulse إلى الزنادات التكيفية + + + DualSense وEdge: يستخدمان الزنادات التكيفية لاهتزاز impulse الخاص بـ Xbox. أوقف هذا لاستخدام اهتزاز الجسم. يتطلب ترجمة impulse أعلاه. + + + ميزات جهاز تحكم PlayStation + + + الإحساس اللمسي لـ DualSense + + + يكتم السماعة المدمجة بينما يواصل نفس البث عبر سماعة رأس متصلة بمنفذ AUX الخاص بجهاز التحكم. + + + كتم سماعة جهاز التحكم بزر الكتم + + + عند تفعيل Mute Button Mutes Input/Output، يؤدي إضاءة مؤشر LED الكتم إلى إيقاف خرج سماعة جهاز التحكم. لا تأثير للإعداد أثناء إيقاف المفتاح الرئيسي. + + + مصدر الصوت: + + + لصوت اللعبة، اختر نقطة النهاية الافتراضية Wireless Controller التي أنشأها خرج VIIPER PlayStation. يُعكس الزوج الستيريو الأول إلى سماعة جهاز التحكم الفعلية. + + + يقوم Audio Haptics حاليًا بتزويد هذا التحكم بالتطبيق المحدد. اختر مصدر صوت آخر هنا لتحرير هذا التجاوز. + + + سماعة DualSense عبر USB: + + + يُستخدم فقط لجهاز DualSense فعلي متصل عبر USB. تبث أجهزة التحكم عبر البلوتوث الصوت مباشرة إلى جهاز التحكم. + + + مستوى صوت السماعة: + + + النطاق الديناميكي: + + + معالجة سماعة البلوتوث. يرفع Balanced التفاصيل الهادئة ويكبح التأثيرات الصاخبة. يُضيّق Strong النطاق أكثر. تُطبَّق المعالجة قبل الترميز الأصلي (Opus في DualSense، SBC في DualShock 4) دون تأخير look-ahead. + + + تعزيز الباس/الجسم: + + + يضيف حتى 6 ديسيبل حول 200 هرتز مع تصفية الباس الفرعي غير القابل للاستخدام. ينطبق فقط على بث سماعة البلوتوث الخاصة بجهاز التحكم. + + + كتم ميكروفون جهاز التحكم بزر الكتم + + + عند تفعيل Mute Button Mutes Input/Output، يؤدي إضاءة مؤشر LED الكتم إلى إيقاف دخل ميكروفون جهاز التحكم. لا تأثير للإعداد أثناء إيقاف المفتاح الرئيسي. + + + مستوى الميكروفون: + + + يضبط مستوى الميكروفون الفعلي والإشارة المشذّبة بأمان المعروضة على Windows. + + + إلغاء الضوضاء: + + + يُطبّق Balanced تنظيف الكلام بواسطة RNNoise. يقلل Strong أيضًا الضوضاء المتبقية منخفضة المستوى. يحتفظ Off فقط بالكسب والترشيح العالي وحماية القطع. + + + صوت متقدم + + + مستوى صوت سماعة الرأس / AUX: + + + يتحكم في منفذ سماعة الرأس بشكل مستقل عن سماعة جهاز التحكم. يعيّن DualShock 4 نطاق المنزلق الكامل إلى كسب سماعة الرأس الموثّق من Sony من 0 إلى 80. + + + يلتقط توجيه الميكروفون عبر USB/القديم نقطة نهاية ميكروفون جهاز التحكم الفعلي في Windows ويرسلها إلى جهاز عرض صوت افتراضي مثل VB-CABLE Input. لا يحتاج توجيه ميكروفون VIIPER عبر البلوتوث إلى نقاط النهاية هذه. + + + ميكروفون جهاز التحكم: + + + الخرج الافتراضي: + + + زر الكتم في DualSense + + + زر الكتم يكتم الدخل/الخرج + + + يستخدم زر كتم جهاز التحكم كأداة تحكم رئيسية لأهداف السماعة والميكروفون المحددة أعلاه. يضيء مؤشر LED الكتم بينما تلك الأهداف مكتومة ويُطفأ عندما تكون نشطة. + + + تفعيل ضوء زر الكتم + + + يعكس حالة زر الكتم الفعلي في DualSense إلى مؤشر LED الكتم في جهاز التحكم أثناء تفعيل هذا الملف الشخصي. يتحكم هذا فقط في الضوء، وليس توجيه ميكروفون Windows. + + + زر الكتم يبدّل الملفات الشخصية + + + يبدّل بين الملفات الشخصية المحددة عند تغيّر الكتم. يؤدي تفعيل Mute Button Mutes Input/Output إلى إيقاف هذا الخيار وتعطيله دون مسح اختيارات الملف الشخصي المحفوظة. + + + الملف الشخصي عند الكتم: + + + اختياري. بدّل إلى هذا الملف الشخصي عندما يتحول زر الكتم الفعلي في DualSense إلى التشغيل. + + + اتركه فارغًا لتجنب تغيير الملفات الشخصية عند تفعيل الكتم. + + + الملف الشخصي عند إيقاف الكتم: + + + اختياري. بدّل إلى هذا الملف الشخصي عندما يتحول زر الكتم الفعلي في DualSense إلى الإيقاف. + + + اتركه فارغًا لتجنب تغيير الملفات الشخصية عند إيقاف الكتم. + + + للقراءة + + + Game Bar + + + تفعيل توافق جهاز التحكم مع Game Bar + + + بينما يكون Xbox Game Bar ظاهرًا، يُوجّه إدخال هذا الملف الشخصي المعيّن مؤقتًا عبر جهاز تحكم متوافق مع Xbox. يبقى الملف الشخصي المحدد وخرج DualSense الأصلي مُهيّأين. + + + يُبقي هذا الملف الشخصي وخرجه الأصلي نشطين. يُرسل فقط الإدخال المعيّن مؤقتًا عبر مرافق متوافق مع Xbox أثناء فتح Game Bar؛ يبقى الصوت والإحساس اللمسي والإضاءة وتوجيه الميكروفون دون مساس. + + + دقائق + + + الحد الأقصى (1 مللي ثانية) + + + إظهار المعاينة المباشرة + + + شاهد ما يرسله جهاز التحكم أثناء اختيار الإجراء. + + + لمس أعلى + + + Sixaxis أعلى + + + Sixaxis أسفل + + + Sixaxis يسار + + + Sixaxis يمين + + + وظيفة اليسار DSE + + + وظيفة اليمين DSE + + + دواسة اليسار DSE + + + دواسة اليمين DSE + + + Switch 2 Joy-Con يسار - مستشعر IR + + + Switch 2 Joy-Con يمين - مستشعر IR + + + Switch 2 تغيير الوضع + + + Switch 2 Joy-Con يسار SL + + + Switch 2 Joy-Con يسار SR + + + Switch 2 Joy-Con يمين SL + + + Switch 2 Joy-Con يمين SR + + + Switch 2 C / دردشة + + + D + + + E + + + F + + + H + + + I + + + J + + + K + + + L + + + M + + + N + + + O + + + P + + + Q + + + S + + + T + + + U + + + V + + + W + + + F1 + + + F2 + + + F3 + + + F4 + + + F5 + + + F6 + + + F7 + + + F8 + + + F9 + + + F10 + + + F11 + + + F12 + + + Tab + + + Esc + + + Prt + + + Del + + + RCtrl + + + Brk + + + Ins + + + NumLk + + + Home + + + BkSpace + + + Space + + + LAlt + + + End + + + LCtrl + + + RShift + + + PgUp + + + Scl + + + LWin + + + RAlt + + + Enter + + + LShift + + + RWin + + + PgDown + + + Caps + + + R → + + + نظرة عامة + + + عام + + + تحديث + + + Ping + + + الوقت + + + البيانات + + + انقر بزر الفأرة الأيمن لفصل الاتصال اللاسلكي + + + استخدام نفس ملف التعريف في كل مرة تُعاد فيها توصيل يد التحكم الفعلية هذه. + + + وضع إمساك Joy-Con + + + تعريف + + + يهتز مقبض التحكم هذا لتتمكن من تمييزه عن غيره. + + + شريط الإضاءة + + + اختر لوناً مؤقتاً لشريط الإضاءة + + + ملفات التعريف الخاصة بك + + + حدد ملف تعريف لتنفيذ إجراءات، أو انقر نقراً مزدوجاً على البطاقة لتحريره. + + + البحث عن ملفات التعريف بالاسم + + + مسح البحث + + + P + + + ملف تعريف يد التحكم + + + لا توجد ملفات تعريف بعد + + + أنشئ أو استورد ملف تعريف للبدء. + + + جارٍ تحميل محرر ملف التعريف + + + جارٍ تطبيق ملف التعريف وتجهيز عناصر التحكم الخاصة به... + + + إعدادات بدء التشغيل والإشعارات والشحن والمظهر وسلوك التحديث التي يستخدمها معظم اللاعبين. + + + يمنع الألعاب من رؤية يد التحكم الفعلية وناتجها الافتراضي معاً. يُنصح باستخدام HidHide في إصدارات Windows الحالية. + + + استعادة يد التحكم من Steam Input تلقائياً + + + يُخفي يد التحكم الفعلية باستخدام HidHide، ثم يعيد تشغيل مجموعة HID الخاصة بها فقط وبأمان حتى يُحرر Steam أي مقبض (handle) فتحه مسبقاً. تبقى يد التحكم الافتراضية متاحة للألعاب. + + + اختر ملفات التعريف التي يُسمح لسحبة الإصبعين بالتبديل بينها + + + اختر ما إذا كان يجب فتح DS4Windows عند تسجيل الدخول إلى Windows. إذا كان الإعداد معلقاً، يُحفظ اختيارك وتوضح الرسالة أدناه الخطوة التالية. + + + قطع اتصال أجهزة التحكم عبر البلوتوث عند إيقاف خدمة DS4Windows. + + + فتح DS4Windows بهدوء دون إظهار النافذة الرئيسية. + + + تسجيل مفصّل (Verbose) + + + يكتب علامات تشخيصية مفصّلة في السجل. عطّله بعد الانتهاء من الاختبار. + + + التحقق الدوري من GitHub بحثاً عن إصدار أحدث من DS4Windows. + + + الإعدادات المتقدمة + + + خوادم الشبكة وتجاوزات التوافق وتسجيل الأجهزة والتشخيص وأدوات الصيانة. الإعدادات الافتراضية هي الأنسب لمعظم المستخدمين. + + + دعم DS4Windows + + + ساهم في تمويل أجهزة التحكم واختبارها وتطويرها. + + + دعم يد التحكم الافتراضية VIIPER + + + حالة VIIPER غير معروفة + + + تثبيت / إصلاح VIIPER + + + مطلوب لمخرجات VIIPER: DualSense وDualSense Edge وSwitch 2 Pro وDS4 وXbox 360 وXbox One / Series عبر USB/IP. + + + تنبيهي عندما يحتاج VIIPER إلى الإعداد + + + أوقف هذا الخيار لإيقاف تنبيهات إعداد VIIPER التلقائية. يبقى خيارا التثبيت/الإصلاح والتحديث متاحين هنا. + + + أجهزة تحكم Switch 2 اللاسلكية + + + اضغط مطولاً على زر المزامنة (sync) في يد التحكم حتى تومض أضواؤها، ثم حددها أدناه. أجهزة التحكم التي أضفتها مسبقاً تُعاد توصيلها عند تنشيطها. + + + يتم إقران أجهزة Joy-Con تلقائياً + + + دمج أجهزة Joy-Con اليسرى واليمنى المتاحة في يد تحكم واحدة. يستمر جهاز Joy-Con المنفرد بالعمل بشكل منفصل. + + + اضغط تحديث للتحقق من حالة اكتشاف البلوتوث. + + + إضافة يد تحكم + + + دمج أجهزة Joy-Con + + + يعمل كل Joy-Con بمفرده. لدمج اثنين، حددهما هنا أو استخدم أزرار الربط (Link) في تبويب Controllers. + + + لم يتم رصد أي اتصالات Joy-Con 2 غير مُقترنة حتى الآن. + + + Joy-Con 2 الأيسر + + + Joy-Con 2 الأيمن + + + دمج زوج Joy-Con 2 المحدد + + + استخدام اليسار المحدد بشكل منفصل + + + استخدام اليمين المحدد بشكل منفصل + + + Joy-Con 2 غير مُقترن + + + انقر على Link لأحد أجهزة Joy-Con، ثم على Link للآخر. تحتفظ يد التحكم الأولى بملف تعريفها ولوحتها الافتراضية. + + + دعم تعديلات الألعاب (DSX) + + + السماح لتعديلات اللعبة بالتحكم في الزناد والأضواء + + + لتعديلات ألعاب DSX المتوافقة على هذا الحاسوب مع DualSense أو DualSense Edge. يحظى Trigger Lab بالأولوية على كل زناد تُفعّله. لا يبث هذا الخيار الـ audio haptics. + + + تفاصيل الاتصال + + + استخدم نفس العنوان والمنفذ في تعديلك. تستخدم معظم التعديلات 127.0.0.1 والمنفذ 6969. أغلق DSX أو أي مستمع آخر يستخدم هذا المنفذ أولاً. + + + عنوان هذا الحاسوب + + + تطبيق / إعادة المحاولة + + + المساهمون + + + الوصف + + + استخدم برنامج تشغيل FakerInput لتوفير لوحة مفاتيح وماوس نسبي وماوس مطلق افتراضيين على مستوى النظام. يسمح هذا باستخدام أحداث لوحة المفاتيح والماوس الافتراضية في بعض الحالات التي يفشل فيها SendInput. مثل هذه الحالات تشمل العمليات والألعاب ذات الصلاحيات المرتفعة، ورسائل UAC، وأنظمة مكافحة الغش التي تحظر أحداث SendInput. استخدام FakerInput ضروري لتشغيل DS4Windows مع بعض الألعاب التي تحتوي على حماية ضد الغش مثل Valorant. + + + DS4Windows - إصدار hbashton (الإصدار + + + استخدم HidHide لإعداد وإخفاء أي أيادي تحكم من التطبيقات الأخرى التي تعمل على نظامك. بعض الألعاب تتطلب وجود يد تحكم واحدة فقط وإلا سيسبب الإدخال المزدوج مشاكل في اللعبة. بقلم nefarius. + + + استخدم HidHide لمنع الإدخال المزدوج: يخفي يد التحكم الفعلية عن الألعاب بينما يستمر DS4Windows باستخدامها، مما يمنع تكرار الإدخال +النقر على الجانب الأيسر من لوحة اللمس: لمسة يسرى +النقر على الجانب الأيمن من لوحة اللمس: لمسة يمنى +النقر على لوحة اللمس بإصبعين: لمس متعدد +النقر على الجزء العلوي من لوحة اللمس: لمسة علوية +PS + Options أو الضغط المطول على PS لمدة 10 ثوانٍ: قطع اتصال يد التحكم (فقط عبر البلوتوث) +لمس لوحة اللمس + PS: إيقاف حركة لوحة اللمس (النقر لا يزال يعمل) +النقر على أسفل يمين لوحة اللمس: نقر بزر الماوس الأيمن (يُفضل استخدامه عندما يُستخدم الجانب الأيمن كزر ماوس) +تحريك إصبعين لأعلى/لأسفل على لوحة اللمس*: تمرير لأعلى/لأسفل +النقر مع الاستمرار على لوحة اللمس*: سحب بزر الماوس الأيسر +تمرير إصبعين يسارًا أو يمينًا على لوحة اللمس: التنقل بين ملفات التعريف +مُعدِّل Shift: اضغط مع الاستمرار على فعل لاستخدام مجموعة أخرى من عناصر التحكم +عند تعيين لوحة المفاتيح والماوس: +Toggle: سيبقى المفتاح في حالة "مضغوط" حتى يُضغط مرة أخرى +Macro: تعيين عدة مفاتيح لإدخال واحد +Scan Code: يتم تفسير المفاتيح بشكل مختلف. قد يكون ضروريًا لبعض الألعاب +*إذا كان مفعّلاً + + + رابط المشروع: + + + المصدر + + + المساهمون + + + إضافات + + + الاختصارات + + + الترخيص + + + المترجمون: + + + ماوس مطلق + + + خيارات الماوس المطلق + + + قبول + + + نشط + + + إضافة + + + إضافة قاعدة عنوان النافذة + + + دعم متقدم + + + تناظري + + + منطقة ميتة عكسية + + + تعمل المنطقة الميتة العكسية كإزاحة تُستخدم مع محور لتحديد أدنى قيمة إخراج تُنتج بعد خروج المحور من منطقته الميتة المحددة. الغرض الرئيسي منها هو المساعدة في تعيين محور إلى قيمة المنطقة الميتة المحددة المستخدمة لمحور في لعبة فيديو. على سبيل المثال، المنطقة الميتة النموذجية المحددة لـ XInput LS في لعبة فيديو تكون حوالي 8000 (25%). بدون تحديد منطقة ميتة عكسية، سيحتاج المحور إلى التحرك متجاوزًا المنطقة الميتة المحددة في DS4Windows بالإضافة إلى المنطقة الميتة المحددة للمحور في اللعبة. + + + نصف القطر العكسي + + + منع الارتداد + + + توقيت منع الارتداد + + + سمة التطبيق + + + Appdata + + + عدواني + + + التبديل إلى صوت اللعبة النشطة باستخدام سجلات ألعاب ويندوز وبيانات المشغلات المثبتة. + + + يتبع الألعاب التي يتعرف عليها Windows أو Steam أو Epic أو GOG. يبقى التطبيق المحدد كخيار احتياطي. + + + متابعة الألعاب تلقائيًا + + + تركيز الباس + + + اختر أي نطاق تردد منخفض يتحول إلى اهتزاز. + + + ديناميكي + + + مفعّل + + + التلاشي + + + تحكم في سرعة تلاشي الاهتزاز اللمسي بعد انخفاض الصوت. + + + تلاشي سريع + + + تصاعد سريع + + + يرسل التطبيق الملتقَط فقط عبر منفذ AUX الخاص بيد التحكم. + + + يوجّه صوت التطبيق الملتقَط إلى سماعات الرأس المتصلة بيد التحكم ويكتم مكبر صوت يد التحكم. + + + سماعة الرأس فقط + + + عالٍ + + + تصاعد فوري + + + تلاشي طويل + + + منخفض + + + متوسط + + + تلاشي متوسط + + + تصاعد متوسط + + + مزج + + + إضافة استجابة لمسية مستمدة من الصوت إلى الاهتزاز اللمسي والاهتزاز العادي للعبة. + + + الوضع + + + يبث أيضًا هذا التطبيق المحدد إلى مكبر صوت يد التحكم وسماعة AUX. + + + يتجاوز "مصدر صوت يد التحكم" في قسم Advanced أثناء تفعيله. اختيار مصدر آخر من هناك يلغي هذا التجاوز. + + + تشغيل التطبيق عبر يد التحكم + + + التصاعد + + + تحكم في سرعة تصاعد الاهتزاز اللمسي مع الصوت. + + + تحديث جلسات الصوت الجارية + + + استبدال + + + استخدم فقط الاستجابة اللمسية المستمدة من الصوت. + + + الاستجابة + + + تركيز التردد والشدة + + + تحكم في شدة استجابة الاهتزاز اللمسي، خصوصًا عند الذُرى. + + + الاستجابة + + + تلاشي بطيء + + + تصاعد بطيء + + + المصدر + + + يستخدم صوت النظام فقط مخرج Windows الافتراضي، وليس كل مخرجات Sonar. اختر تطبيقًا لمتابعة صوته على أي مخرج. + + + Audio Haptics معطّل. + + + استجابة لمسية ليد التحكم مستمدة من الصوت + + + خفيف + + + صوت النظام + + + Audio Haptics + + + عرض تبديل الملف التعريفي عبر + + + سجل + إشعار + + + إعادة معايرة العصا تلقائيًا + + + محوري + + + إعدادات المحور + + + ماوس مطلق + + + ماوس مطلق لأسفل + + + ماوس مطلق لليسار + + + ماوس مطلق لليمين + + + ماوس مطلق لأعلى + + + تغيير الإضاءة + + + تغيير حساسية الماوس + + + لوحة مفاتيح وماوس نسبي + + + لوحة المفاتيح والماوس + + + الماكرو مفعّل، اختر مفتاحًا لتعطيله، أو أغلق هذه النافذة للحفظ + + + تسجيل ماكرو + + + اختر مُشغّل Shift + + + أسود + + + الأزرار + + + فشل فحص سلامة البيانات للجهاز اللاسلكي. جارٍ إغلاق الجهاز. + + + إلغاء الماكرو الحالي + + + يحدد ما إذا كان تشغيل هذا الماكرو يجب أن يوقف ماكرو آخر قيد التشغيل حاليًا + + + تسري التغييرات عند اتصال جهاز جديد + + + التحقق كل + + + اللون والمدة + + + ملوّن + + + تأكيد + + + تفعيل مؤشر LED الرئيسي + + + مزوّد الجايرو المدمج + + + وضع الربط + + + وضع كتم مؤشر LED + + + وضع مؤشر LED للاعب + + + خيارات نوع يد التحكم + + + دعم يد تحكم DS3 + + + دعم يد تحكم DS4 + + + دعم يد تحكم DualSense + + + دعم يد تحكم JoyCon + + + دعم يد التحكم الافتراضية + + + دعم يد تحكم Switch Pro + + + عناصر التحكم + + + Copycat + + + تغيير بعض الإعدادات المستخدمة ليد تحكم DS4 غير الأصلية. قد يصلح دعم الاهتزاز والشريط الضوئي لبعض نسخ DS4 من جهات أخرى + + + إنشاء ماكرو للشريط الضوئي + + + تكعيبي + + + الحالي + + + مخصص + + + معدل استطلاع DS4 عبر البلوتوث + + + هذه الميزة معطّلة حاليًا في التطبيق بسبب مشاكل في برنامج التشغيل. نأمل حل المشكلة في تحديث مستقبلي. + + + افتراضي (تناظري + أزرار) + + + داكن + + + أيام + + + المنطقة الميتة + + + المنطقة الميتة X + + + المنطقة الميتة Y + + + نوع المنطقة الميتة + + + افتراضي + + + تسارع دلتا + + + أيادي التحكم المكتشفة + + + خيارات الجهاز + + + نوع الجهاز + + + تمرير اتجاهي + + + تعطيل يد التحكم الافتراضية + + + عدم إنشاء/ربط أيادي تحكم افتراضية لأيادي التحكم المتصلة باستخدام هذا الملف التعريفي (يسري عند حفظ الملف التعريفي) + + + قطع اتصال البلوتوث عند الإيقاف + + + فرض استخدام كلا مستويي القوة (العام والخاص بـ DualSense) + + + يُنصح بتركه معطّلاً. | | - معطّل: سيُعاد تدريج الاهتزاز بشكل أصلي بواسطة يد التحكم وفقًا لمستوى القوة المحدد (جودة أفضل) | | - مفعّل: يعمل كل من إعادة تدريج الاهتزاز العام في DS4Windows والتحكم الأصلي في DualSense معًا + + + دقيق + + + معطّل + + + قديم + + + وضع الاهتزاز ومستوى القوة: + + + تمرير مباشر + + + الوضع الدقيق (يُنصح به): | - يُحاكي بشكل أفضل إحساس اهتزاز DualShock 4/Xbox 360 | - ينفّذ تأثيرات الاهتزاز المقصودة من اللعبة بدقة أكبر | - الاهتزاز أكثر عمقًا. ضمن نفس مستوى القوة هناك فرق أكبر بين أدنى وأقصى تفعيل للاهتزاز داخل اللعبة، | يتراوح من منخفض جدًا حتى أقصى قوة للمستوى المحدد | | الوضع القديم: | - أقوى بشكل عام، لكنه يفتقر للعمق | - له إحساس "أكثر حدة" | - سيكون أدنى وأقصى تفعيل داخل اللعبة أقل بقليل وأعلى بقليل على التوالي من قوة المستوى المختار | | معطّل: | - يعطّل الاهتزاز بالكامل + + + مُعدِّل مستوى قوة الاهتزاز الأصلي لـ DualSense. | | - في الوضع الدقيق، سيكون [ الحد الأدنى // الأقصى ] للاهتزاز [ 1% /// مستوى القوة المختار ] | - مثال (62%): [ الأدنى = 1% /// الأقصى = 62% ] | | - في الوضع القديم، سيكون [الأدنى /// الأقصى] للاهتزاز تقريبًا [ مستوى القوة - 12% /// مستوى القوة + 12% ] | - مثال (62%): [ الأدنى = 50% /// الأقصى = 74% ] + + + إعدادات الاهتزاز الخاصة بـ DualSense + + + ديناميكي + + + Easeout تكعيبي + + + Easeout تربيعي + + + مدة التنعيم + + + يد التحكم المحاكاة + + + تفسير رسائل المراقبة + + + تفعيل خدمة المراقبة + + + تفعيل خادم التحكم + + + تفعيل تبديل لوحة اللمس + + + تفعيل السجل المفصّل + + + عرض رسائل سجل إضافية عند اتصال يد تحكم + + + مفعّل + + + دقة معززة + + + وصول حصري + + + تصدير الأفعال + + + إضافي + + + فشل جلب أحدث إصدار + + + دعم جهاز DS3 + + + دعم أيادي تحكم DualShock 3 (PS3). يتطلب استخدام برنامج تشغيل DsHidMini من مشروع ViGEm (nefarius). + + + دعم جهاز DS4 + + + دعم أيادي تحكم DualShock 4 المعروفة + + + دعم جهاز DualSense + + + دعم أيادي تحكم DualSense (PS5). الطراز الأساسي وDS Edge + + + نظرًا لأن برامج تعيين أخرى تفعّل دعم أنواع أجهزة متعددة افتراضيًا (Steam Input)، فإن DS4Windows يفعّل افتراضيًا فقط دعم القراءة من أيادي تحكم DS4. يمكنك هنا تحديد دعم برنامج التعيين لأنواع الأجهزة المدعومة الأخرى. كن حذرًا عند استخدام DS4Windows مع برامج تعيين أخرى محتملة تعمل في نفس الوقت. + + + دعم الأجهزة + + + تفعيل دعم برنامج تعيين الأجهزة + + + دعم جهاز JoyCon + + + دعم أيادي تحكم JoyCon (Nintendo Switch) + + + دعم جهاز Switch Pro + + + دعم أيادي تحكم Switch Pro (Nintendo Switch) + + + التشغيل الأول + + + وميض الشريط الضوئي عند زمن استجابة مرتفع + + + معدل الوميض + + + Flick Stick + + + ضغط الزر الكامل + + + لم يتم اكتشاف .NET 5 Runtime على نظامك. يرجى تنزيل وتثبيت .NET 5 Runtime لضمان التوافق مع إصدارات DS4Windows المستقبلية. سيتم توجيهك إلى صفحة تنزيل .NET 5 Runtime عند إغلاق هذه النافذة. + + + Fuzz + + + عناصر التحكم (تسارع) + + + إضافة تقييد إضافي عند الطرف المنخفض من المنحنى لمراعاة اهتزاز الجهاز + + + قوي + + + الارتفاع + + + وصول HidGuardian + + + HidHide + + + وصول HidHide + + + عميل إعداد HidHide + + + استخدم HidHide لمنع الإدخال المزدوج + + + تأخير إطلاق النار السريع + + + اضغط مع الاستمرار لمدة + + + الاختصارات/حول + + + ساعات + + + المعرّف + + + اختيار الأيقونة + + + قطع الاتصال عند عدم النشاط + + + مقدمة + + + عكس المحركات + + + استخدام حزمة اللغة + + + تشغيل برنامج مع الملف التعريفي + + + خفيف + + + الشريط الضوئي + + + وضع الشريط الضوئي + + + خطي + + + ربط الملف التعريفي/المعرّف + + + ماكرو + + + شاشة العرض المطلقة + + + تفعيل الخادم + + + 1€ Beta + + + 1€ MinCutoff + + + العصا اليسرى + + + وصّل يد تحكم، ثم أعد فتح هذا المحرر. + + + مضغوط + + + العصا اليمنى + + + يد التحكم الفعلية · قبل إعادة التعيين + + + الإدخال المباشر + + + في الانتظار + + + أقصى إخراج + + + أقصى مسافة حركة + + + المنطقة القصوى + + + الحد الأدنى للمعامل + + + أدنى مسافة حركة + + + التصغير إلى شريط المهام + + + التصغير إلى شريط المهام بدلاً من علبة النظام + + + الوضع + + + الماوس + + + تسارع الماوس + + + عصا التحكم كماوس + + + إزاحة الماوس + + + حساسية الماوس + + + المقياس الرأسي للماوس + + + المضاعِف + + + سيتطلب DS4Windows الإصدار 3.3 تثبيت .NET 8 Desktop Runtime على نظامك | [https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-8.0.0-windows-{0}-installer](https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-8.0.0-windows-{0}-installer) | | يرجى الضغط على موافق لتأكيد قراءة الرسالة. اضغط إلغاء ليتم تذكيرك مجددًا عند تشغيل التطبيق القادم. + + + لم يتم العثور على .NET 8 + + + لا + + + عادي + + + إشعار + + + موافق + + + التحكم والمراقبة الخارجية عبر OSC + + + أخرى + + + اختر نوع يد التحكم الافتراضية للإخراج (يسري عند حفظ الملف التعريفي) + + + الربط الخارجي + + + الزر الخارجي + + + منطقة ميتة للزر الخارجي + + + منحنى الإخراج + + + وضع الإخراج + + + رقم الإدخال # + + + رقم XInput # + + + فتحات الإخراج + + + تُحفظ الإعدادات أدناه في هذا الملف التعريفي + + + الملف التعريفي النشط + + + Audio Haptics يزوّد هذا البث حاليًا. أوقف "تشغيل هذا التطبيق عبر يد التحكم" لاختيار مصدر آخر. + + + مصدر الصوت + + + يلتقط الافتراضي مزيج نقطة النهاية العادية. اختر تطبيقًا لبث صوت ذلك التطبيق فقط. + + + متوازن + + + الباس / الكثافة + + + يضيف كثافة حول 200 هرتز مع تصفية الباس العميق غير القابل للاستخدام. + + + البطارية + + + الاتصال + + + تفاصيل يد التحكم + + + مكبر صوت يد التحكم + + + حالة يد التحكم + + + قطع الاتصال + + + المدى الديناميكي + + + يرفع التفاصيل الهادئة ويحدّ بأمان من التأثيرات الصاخبة دون تأخير استباقي. + + + تعديل الملف التعريفي النشط + + + يد التحكم الافتراضية المعروضة للألعاب. + + + يؤدي تغيير هذا الإعداد إلى حفظ الملف التعريفي، ثم إجراء إعادة تحميل واحدة متحكم بها للإخراج. + + + يد التحكم المحاكاة + + + يُطبَّق من خلال الملف التعريفي النشط + + + الجهاز المحاكى + + + سماعة الرأس / AUX + + + يتحكم في منفذ سماعة رأس يد التحكم بشكل مستقل عن مكبر الصوت المدمج فيها. + + + يكتم مكبر الصوت المدمج مع استمرار البث عبر سماعة رأس متصلة بمنفذ AUX الخاص بيد التحكم. + + + سماعة الرأس فقط (كتم مكبر صوت يد التحكم) + + + تحكم بالشريط الضوئي + + + استخدم إعدادات الشريط الضوئي في الملف التعريفي أو اختر لونًا مخصصًا مؤقتًا + + + مستوى الميكروفون + + + الميكروفون + + + وصّل يد تحكم، ثم اخترها من بطاقات الأجهزة في الزاوية العلوية اليسرى. + + + لم يتم اختيار يد تحكم + + + إلغاء ضوضاء + + + NVIDIA AI + + + معطّل + + + فتح إعدادات الصوت في Windows + + + اختر وجهة صوت لعبتك ومحادثتك الصوتية. + + + مستويات الإخراج + + + الملف التعريفي + + + انتقل إلى المحرر الكامل أو أدر يد التحكم الفعلية المحددة. + + + إجراءات سريعة + + + يُحفظ كل تغيير في الملف التعريفي النشط ليد التحكم المحددة ويُطبَّق تلقائيًا. + + + عناصر تحكم سريعة للملف التعريفي + + + تحديث مصادر الصوت الجارية + + + الفاصل الزمني ومعدل تقرير الإدخال الملاحَظ + + + الفاصل الزمني والمعدل الملاحَظ لتسليم الإدخال. تستخدم أيادي التحكم المدمجة معدل تقريرها المركّب. هذا ليس زمن إتمام النواة (kernel) ولا زمن استجابة اللعبة الشامل. + + + يد التحكم المحددة + + + معالجة مكبر الصوت + + + يبث الصوت المحدد إلى يد التحكم. يستخدم مكبر الصوت المدمج فيها ما لم يقم "سماعة الرأس فقط" بتوجيهه حصريًا إلى منفذ AUX. + + + بث الصوت إلى يد التحكم + + + قوي + + + يعمل بشكل مستقل عن يد التحكم الافتراضية. صوت سماعة الرأس عبر البلوتوث غير مدعوم بعد. + + + وصّل Switch 2 Pro الخاص بك عبر USB وصل سماعات الرأس أو سماعة الرأس. اختر Headphones (Switch 2 Pro Controller) في إعدادات اللعبة أو صوت Windows. اضبط مستوى الصوت من هناك. + + + للمحادثة الصوتية، اختر Microphone (Switch 2 Pro Controller) واستخدم سماعة رأس بها ميكروفون. + + + استخدام سماعة رأس عبر USB + + + تمرير مباشر + + + دائم + + + Pitch + + + توصيل + + + منفذ + + + يد التحكم للإخراج + + + قائمة الإعدادات المسبقة + + + أولوية العملية + + + وضع إخراج زناد DS4 + + + عرض إشعار تبديل الملف التعريفي + + + البرنامج + + + مجلد البرنامج + + + تربيعي + + + شعاعي + + + البطارية: 0% + + + تأخير الإدخال: غير متاح + + + SixAxis: محور X مقلوب لتسهيل القراءة + + + يتطلب اختيار أولوية الوقت الفعلي تشغيل التطبيق في وضع المسؤول. + + + إضافة اهتزاز + + + تغيير لون الشريط الضوئي + + + انقر مرتين على انتظار لتعديل الوقت + + + زر الماوس الخامس + + + زر الماوس الرابع + + + إدراج انتظار + + + تحميل إعداد مسبق + + + ترتيب الماكرو + + + تشغيل مرة واحدة + + + تسجيل فترات الانتظار + + + تكرار أثناء الضغط المستمر + + + حفظ إعداد مسبق + + + استخدم لوحة المفاتيح/الماوس + يد التحكم 1 للتسجيل + + + تعديل الماكرو + + + عادي + + + إعادة تسمية + + + يرجى كتابة الاسم الجديد لملف XML الخاص بالملف التعريفي المحدد. + + + إعادة تسمية الملف التعريفي + + + مطلوب + + + العودة إلى الملف التعريفي الافتراضي عند عدم المعرفة + + + Roll + + + الدوران + + + تشغيل كـ + + + يحدد Fuzz الحد الأدنى لعدد وحدات الجهاز، ضمن المنطقة النشطة، التي يجب أن يدور بها Accel قبل تسجيل الإخراج كمتغيّر في المُعيِّن. تُعبَّر القيمة بوحدات Accel الخام. + + + لمن يفضلون التثبيت العادي. تُحفظ الإعدادات في %appdata%\DS4Windows + + + لا تحذف الإعدادات الأخرى بعد + + + تم اكتشاف مواقع حفظ متعددة + + + اختر مكان حفظ الملفات التعريفية والإعدادات + + + لمن يفضلون برنامجًا محمولاً. | ملاحظة: هذا الخيار لا يعمل إذا كان في مجلد مسؤول بدون UAC + + + اختر مكان الحفظ + + + Scan Code + + + الملف التعريفي المحدد + + + إرسال استجابة اللعبة إلى يد التحكم الفعلية + + + يُنصح به. يرسل الاهتزاز، واستجابة DualSense اللمسية المحوَّلة، وتأثيرات الزناد التكيفي المتوافقة، وإضاءة يد التحكم من الألعاب إلى يد التحكم الفعلية المتصلة. أوقف هذا فقط عندما لا تستطيع يد التحكم استقبال الإخراج؛ تعطيله يزيل تأثيرات استجابة اللعبة هذه. أعد توصيل يد التحكم بعد تغيير هذا الإعداد. + + + الحساسية + + + وصول مشترك + + + مُعدِّل Shift + + + عرض رسائل تصحيح الملفات التعريفية التلقائية + + + Six Axis (تسارع) + + + تخطي الإصدار + + + الانجذاب للمركز + + + لون ثابت + + + معايرة الجايرو + + + فحص مستوى البطارية + + + قطع الاتصال عن البلوتوث + + + نقر مزدوج على الزناد + + + اضغط مع الاستمرار لمدة + + + اضغط مع الاستمرار على الزناد + + + الحفاظ على حالة المفتاح + + + تشغيل برنامج + + + تحميل ملف تعريفي + + + تم تسجيل الماكرو + + + زر متعدد الأفعال + + + ضغط/تبديل مفتاح + + + عند ضغط زناد الإلغاء + + + تسجيل ماكرو + + + عند تحرير زناد الإلغاء + + + تكرار أثناء الضغط المستمر + + + تشغيل عند تحرير الزناد + + + -اختر فعلاً- + + + اختر مفتاحًا + + + اختر ماكرو + + + تعيين زناد الإلغاء + + + معايرة عجلة القيادة بالجايرو السداسي + + + تشغيل متزامن + + + نقر الزناد + + + إلغاء عند تحرير الزناد + + + إلغاء تبديل المفتاح بواسطة + + + عبر الشريط الضوئي + + + عبر الإشعار + + + عصا مربعة + + + يرجى تحريك العصا إلى الجوانب وتحريرها عدة مرات، ثم بعد الانتهاء اضغط على حفظ. + + + معايرة العصا + + + معايرة العصا + + + يحدد Fuzz الحد الأدنى لعدد الوحدات التي تتحرك بها العصا التناظرية، ضمن المنطقة النشطة، قبل تسجيل الإخراج كمتغيّر في المُعيِّن. قد يكون هذا الإعداد مفيدًا للعصي المهترئة التي لا يمكنها الحفاظ على وضع ثابت. تُعبَّر القيمة بوحدات العصا الخام. + + + إعداد قديم متروك. محاولة تطبيق منحنى بناءً على إحداثيات الإدخال الخام قبل تطبيق أي معلومات للمنطقة الميتة. غير مستقر + + + فرض إعداد أقصى إخراج دائمًا. مفيد لأقصى إخراج 100% وحصر القيمة في قيمة إخراج دائرية + + + في بعض الحالات، قد يكون من المفيد تحديد القيمة القصوى التي تُخرَج من العصا التناظرية. يسمح أقصى إخراج بتقييد القيمة النهائية لإخراج العصا التناظرية. + + + الحد الذي عنده يُطلَق الفعل + + + يجعل الربط الخارجي يُطلَق قبل بلوغ الحد. يتحرر الفعل بمجرد تجاوز الحد + + + الفعل الذي يُنفَّذ عندما تتجاوز حركة العصا حدًا معينًا. مفيد لتعيين مفاتيح لأفعال المشي أو الركض. الانعكاس يجعل الفعل يُطلَق حتى بلوغ الحد + + + + = باتجاه عقارب الساعة. - = عكس عقارب الساعة. | | يهدف إعداد الدوران إلى المساعدة في تصحيح اتجاه العصا التناظرية إذا كان إبهامك منزاحًا قليلاً عند تحريك العصا. على سبيل المثال، قد ينزاح إبهامك قليلاً عن المركز عند تحريك العصا بالكامل نحو الشمال. تنزاح إبهامي قليلاً نحو اليمين عند تحريك العصا بالكامل نحو الشمال بسبب طريقة إمساك يدي لـ DS4. تُشير القيمة المستخدمة إلى عدد الدرجات المستخدمة لتعديل قيمة إخراج المحور النهائية. تتراوح القيم المسموحة من -180 إلى 180. الافتراضي هو 0. + + + إلغاء تحديد الكل + + + حدد الملفات التعريفية التي يُسمح لتمرير لوحة اللمس بإصبعين بالتبديل بينها. إذا لم يُحدَّد شيء، يتنقل التمرير بين جميع الملفات التعريفية (السلوك الافتراضي). + + + تحديد الكل + + + إعداد ملفات تعريف التمرير + + + تمرير لوحة اللمس لتبديل الملفات التعريفية + + + إ_لغاء الالتقاط + + + إ_غلاق + + + يؤدي الإغلاق إلى إلغاء الالتقاط والتفعيل المباشر. قد يكتمل حفظ يجري الكتابة على القرص بالفعل؛ الإغلاق لا يتراجع عن تلك الكتابة. + + + عايِر عصيّك + + + العصا الفعلية + + + إ_عادة تعيين معايرة هذا الكمبيوتر لهذه العصا… + + + _حفظ المعايرة + + + _بدء المعايرة + + + تُحفظ المعايرة على هذا الكمبيوتر لهذه العصا الفعلية، وليس في ملف تعريفي أو ذاكرة يد التحكم. قد تكون سجلات USB والبلوتوث منفصلة. يُطلَق إدخال يد التحكم المعيَّن أثناء تفعيل المعايرة. + + + معايرة عصا Switch 2 + + + مهمة + + + اختبار + + + اختبار قوي + + + اختبار خفيف + + + تبديل + + + وضع تفعيل الزر + + + لوحة اللمس + + + يقيّد الطرف المنخفض من حركة لوحة اللمس. يقلل من حركة مؤشر الماوس العرضية عند الإبقاء على موضع شبه ثابت على لوحة اللمس + + + أدنى مسافة حركة إخراج محسوبة قبل إرسال حدث ماوس إلى النظام + + + يعدّل تمرير لوحة اللمس بزاوية دوران معينة. مفيد عندما لا يكون التمرير العادي للوحة اللمس خطًا مستقيمًا. تتراوح القيم المسموحة من -180 إلى 180. الافتراضي هو 0. + + + الحساسية المستخدمة لتفعيل فعل تمرير عجلة الماوس متعدد اللمس + + + تفعيل نقرة زر الماوس الأيسر بنقرة على لوحة اللمس. أقصى فاصل زمني محدد هو (القيمة × 2) مللي ثانية. + + + يضيف زخمًا لتمرير لوحة اللمس بمجرد رفع الإصبع. يضيف مسافة إضافية لحركة مؤشر الماوس أكبر مما هو ممكن ضمن المساحة المحدودة للوحة اللمس + + + إضافة احتكاك للكرة التتبعية الافتراضية. تقليل الاحتكاك يزيد زمن حركة مؤشر الماوس النهائي + + + تأثير الزناد + + + تأثيرات المختبر النشطة تتجاوز إخراج الزناد التكيفي الوارد من اللعبة. + + + تصميم التأثير + + + مفعّل + + + مرتبط + + + استخدم تصميم تأثير مشترك واحد لـ L2 وR2. تتطابق الإعدادات المسبقة والأوضاع والمنزلقات بين الجانبين؛ يبقى مفتاح "نشط" لكل زناد مستقلاً. + + + تجاوز المختبر + + + منفصل + + + اضبط تصاميم تأثير منفصلة لـ L2 وR2. العودة إلى "منفصل" تستعيد إعداداتك المستقلة الأخيرة، بما في ذلك أي زناد كان نشطًا. + + + إيقاف DS4Windows مؤقتًا + + + وضع المرحلتين + + + خادم UDP + + + غير مُعيَّن + + + زناد الإلغاء + + + فصل + + + نافذة التحديث + + + يرجى تحديث .NET Runtime + + + استخدام يد التحكم + + + استخدام مجلد Steam مخصص + + + [تجريبي] استخدام محاكاة جايرو DS3 + + + استخدام التنعيم + + + أدوات + + + المقياس الرأسي + + + يعمل فقط مع ViGEmBus 1.17.333.0 وأحدث + + + فشل تشغيل إضافة جهاز ViGEm. رمز الخطأ {0}. غالبًا مشكلة داخلية في ViGEmBus. جارٍ إغلاق الاتصال. إذا استمرت المشكلة، يرجى إغلاق DS4Windows ثم إعادة تشغيل Windows. + + + أبقِ هذه النافذة مفتوحة. سينتهي الإعداد تلقائيًا. + + + جارٍ إعداد VIIPER + + + جارٍ تحضير الحزمة الموثقة... + + + • تثبيت VIIPER 0.1.9-rc4.6.6 + + + • التحقق من الملفات المعبأة + + + • التحقق من بدء التشغيل وواجهة API + + + • التحقق من USB-IP 0.9.7.7 + + + DS4Windows يتحقق من البنية الخلفية الكاملة ليد التحكم. + + + إعداد VIIPER + + + إغلاق + + + الحالة الحالية + + + لن يتم رفع صلاحيات هذا الملف التنفيذي أو اختياره. يستخدم التثبيت أو الإصلاح البنية الخلفية الموثقة في Program Files ويزيل فقط ملفات VIIPER القديمة المعروفة: + + + تم اكتشاف VIIPER منافس + + + VIIPER يحتاج إلى انتباه + + + إبقاء DS4Windows محمولاً + + + تثبيت عادي + + + ليس الآن + + + يترك "إبقاء DS4Windows محمولاً" هذا التطبيق تمامًا في مكانه، بينما يثبّت بنية VIIPER الخلفية المرفوعة الصلاحيات في Program Files المحمية. التثبيت العادي أيضًا ينقل فقط ملفات DS4Windows المملوكة للحزمة إلى Program Files. الملفات التعريفية والإعدادات والملفات غير المعروفة محفوظة دائمًا. + + + ما يحتاجه DS4Windows + + + • خادم/مساعد VIIPER +• برنامج تشغيل USB/IP الخاص بويندوز usbip-win2 + + + يستخدم هذا الملف التعريفي إخراج يد تحكم VIIPER الافتراضية. + + + عدم إظهار رسالة الإعداد هذه مجددًا + + + يمكنك إعادة تفعيل رسائل الإعداد من Settings ← VIIPER Virtual Controller Support. + + + إعداد يد تحكم VIIPER الافتراضية + + + إعدادات يد التحكم الافتراضية + + + الاستيقاظ من وضع التعليق + + + إعدادات البلوتوث + + + إذا ظهرت هذه النافذة مجددًا بعد التثبيت، فقد تحتاج لإعادة تشغيل جهازك. + + + الخطوة 1: تثبيت برنامج تشغيل ViGEmBus + + + إذا كنت قد استخدمت يد تحكم 360 على هذا الجهاز من قبل، يمكنك تخطي هذه الخطوة. + + + الخطوة 2: إذا كنت على Windows 7، ثبّت برنامج تشغيل 360 + + + بعد بدء الوميض، اذهب إلى إعدادات البلوتوث واتصل بـ "Wireless Controller". إذا طُلب منك، أدخل رمز الإقران 0000. بعد الإقران، أنت جاهز. استمتع! + + + الخطوة 3: توصيل يد تحكم DualShock 4. | للإعداد السلكي/USB: | ببساطة وصّل كابل micro-USB بجهازك وبيد تحكم DualShock 4. | | للإعداد عبر البلوتوث (اختياري): اضغط مع الاستمرار على زر PS وShare لمدة 3 ثوانٍ. سيبدأ الشريط الضوئي بالوميض المزدوج. + + + استخدم HidHide لإعداد وإخفاء أي أيادي تحكم من التطبيقات الأخرى التي تعمل على نظامك. بعض الألعاب تتطلب وجود يد تحكم واحدة فقط وإلا سيسبب الإدخال المزدوج مشاكل في اللعبة. + + + (اختياري) الخطوة 4: تثبيت برنامج تشغيل HidHide + + + استخدم برنامج تشغيل FakerInput لتوفير لوحة مفاتيح وماوس نسبي وماوس مطلق افتراضيين على مستوى النظام. يسمح هذا باستخدام أحداث لوحة المفاتيح والماوس الافتراضية في بعض الحالات التي يفشل فيها SendInput. مثل هذه الحالات تشمل العمليات والألعاب ذات الصلاحيات المرتفعة، ورسائل UAC، وأنظمة مكافحة الغش التي تحظر أحداث SendInput. استخدام FakerInput ضروري لتشغيل DS4Windows مع بعض الألعاب التي تحتوي على حماية ضد الغش مثل Valorant. + + + (اختياري) الخطوة 5: تثبيت برنامج تشغيل FakerInput + + + مرحبًا بك في DS4Windows + + + أبيض + + + العرض + + + قاعدة عنوان النافذة + + + إزاحة المحور X + + + مركز X + + + إزاحة المحور Y + + + مركز Y + + + Yaw + + + نعم + + + DS4Windows + رفيق يد التحكم + وصّل يد تحكم للبدء + التنقل + محرر الملفات الشخصية + P + مساحة عمل مركزة + تعديل الملف الشخصي + مساحة عمل الملف الشخصي + العودة إلى الملفات الشخصية + إلغاء التعديل والعودة إلى قائمة الملفات الشخصية + تعيين الأزرار + الأزرار، العصي، إيماءات اللمس، والاختصارات + الماكروهات، التشغيل، التبديل، والإجراءات المتعددة + المدخلات المباشرة والمعايرة + العصي، الزناد، المناطق الميتة، والمنحنيات + اللون، البطارية، الوميض، والشحن + الفأرة، الإيماءات، التمرير، والتموضع + التصويب الحركي، التوجيه، والتمرير + تحويل صوت النظام أو التطبيق إلى اهتزاز متقدم + إنشاء تأثيرات زناد تكيفية دائمة + اهتزاز HD، الحركة، الفأرة الضوئية، والمعايرة + الإخراج، الاهتزاز، زمن الاستجابة، والتوافق + أحداث الخدمة دون مغادرة المحرر + + LX (I): + LX (O): + LY (I): + LY (O): + RX (I): + RX (O): + RY (I): + RY (O): + X (I): + X (O): + Z (I): + Z (O): + I: + O: + TX: + TY: + + الاسم: + حدد الأزرار التي تبدأ هذا الإجراء. يجب الضغط على عدة أزرار معًا. + حدد الأزرار التي تنهي هذا الإجراء أو تعيدك إلى الملف الشخصي السابق. + تشغيل برنامج + ثوانٍ + المعطيات + تحميل ملف شخصي + ضغط مفتاح + قطع البلوتوث + فحص البطارية + إجراء متعدد + عجلة Sixaxis + + قبول وحدات تحكم Moonlight / Sunshine الافتراضية + قبول كل وحدة تحكم افتراضية مدعومة يتم إنشاؤها أثناء تشغيل Sunshine. تُستثنى دائمًا مخرجات VIIPER الخاصة بـ DS4Windows. + DS4 + Switch Pro + JoyCon + + الجهاز + عنوان النافذة... + البحث حسب الملف الشخصي أو عنوان النافذة أو الملف التنفيذي أو المسار + الجهاز + + FakerInput + CRC32 + H.NotifyIcon + vJoyInterfaceCS + + X — Y — + + الواجهة الخلفية المطلوبة لوحدة التحكم الافتراضية. يطلب DS4Windows صلاحيات المسؤول ويثبّت VIIPER إلى جانب usbip-win2 نيابةً عنك. + + التنقل بين البرامج + من ملف... + + تم + اختيار إعداد مسبق + تمكين جسر وحدة التحكم المباشر لـ Sunshine + السماح لـ Sunshine بإرسال إدخال وحدة التحكم مباشرة إلى DS4Windows. سيُنشئ DS4Windows وحدة التحكم الافتراضية الموجهة للعبة، ولن يتم إنشاء وحدة تحكم إدخال افتراضية لـ Sunshine. فعّل الخيار المطابق في Sunshine أيضًا. + يقوم الإصلاح بتحديث التثبيت الحالي. يتم الاحتفاظ بملفاتك التعريفية وإعداداتك. + تثبيت / إصلاح + \ No newline at end of file diff --git a/DS4Windows/Translations/Strings.resx b/DS4Windows/Translations/Strings.resx index ea99ade2..87c3f9e5 100644 --- a/DS4Windows/Translations/Strings.resx +++ b/DS4Windows/Translations/Strings.resx @@ -1490,4 +1490,2258 @@ Please click OK to confirm that you have read the message. Press Cancel to be re Inverse motors - + + DS4Windows - hbashton Build (Version + + + Hotkeys + + + Use HidHide to Prevent Double Input: Hides the physical controller from games while DS4Windows continues using it, preventing duplicate inputs +Click left side of touchpad: Left Touch +Click right side of touchpad: Right Touch +Click touchpad with 2 fingers: Multitouch +Click upper part of touchpad: Upper Touch +PS + Options or hold PS for 10 secs: Disconnect Controller (Only on Bluetooth) +Touch Touchpad + PS: Turn off touchpad movement (clicking still works) +Pad click on lower right: Right click (Best used when right side is used as a mouse button) +Two fingers up/down on touchpad*: Scroll Up/Down +Tap then hold touchpad*: Left mouse drag +2 finger touchpad swipe left or right: Cycle through profiles +Shift Modifer: Hold an action to use another set of controls +When mapping keyboard and mouse: +Toggle: The key will remain in a "held down" state until pressed again +Macro: Assign multiple keys to one input +Scan Code: Keys are interpreted differently. May be needed for certain games +*If enabled + + + License + + + Credits + + + Source + + + Contributors + + + Translators: + + + Extras + + + Project URL: + + + Description + + + Use HidHide to configure and hide any input controllers from other apps running on your system. Some games require only one controller to be present or double input will cause problems in game. Written by nefarius. + + + Use FakerInput driver to expose system-wide virtual keyboard, relative mouse, and absolute mouse. Allows virtual KB+M events to be usable in some situations when SendInput fails. Such situations are elevated process and games, UAC prompts, and anti-cheat systems that block SendInput events. Use of FakerInput is necessary to allow DS4Windows to work with some games with anti-cheat protection like Valorant. + + + No controller selected + + + Connect a controller, then choose it from the device cards in the upper-left corner. + + + SELECTED CONTROLLER + + + Profile + + + BATTERY + + + CONNECTION + + + Observed input report interval · rate + + + Observed input delivery interval and rate. Joined controllers use their composite report cadence. This is not kernel completion time or end-to-end game latency. + + + ACTIVE PROFILE + + + Settings below save to this profile + + + EMULATED DEVICE + + + Applied through the active profile + + + CONTROLLER STATUS + + + Quick profile controls + + + Every change is saved to the selected controller's active profile and applied automatically. + + + Emulated controller + + + The virtual controller presented to games. + + + Changing this setting saves the profile, then performs one controlled output reload. + + + Stream audio to controller + + + Streams the selected audio to the controller. Uses its built-in speaker unless Headset only routes it exclusively to the AUX port. + + + Headset only (mute controller speaker) + + + Mutes the built-in speaker while continuing the stream through a headset connected to the controller's AUX port. + + + Audio source + + + Default captures the normal endpoint mix. Choose an app to stream only that app. + + + Refresh running audio sources + + + Audio Haptics is supplying this stream. Turn off Play this app through controller to choose another source. + + + Use a headset over USB + + + Connect your Switch 2 Pro by USB and plug in headphones or a headset. Choose Headphones (Switch 2 Pro Controller) in your game or Windows Sound settings. Adjust the volume there. + + + For voice chat, choose Microphone (Switch 2 Pro Controller) and use a headset with a microphone. + + + Works independently of your virtual controller. Bluetooth headset audio is not supported yet. + + + Open Windows Sound settings + + + Choose where your game sound and voice chat go. + + + Output levels + + + Controller speaker + + + Headset / AUX + + + Controls the controller headset jack independently from its built-in speaker. + + + Speaker processing + + + Dynamic range + + + Raises quiet detail and safely restrains loud effects without look-ahead latency. + + + Off + + + Balanced + + + Strong + + + Bass / body + + + Adds body around 200 Hz while filtering unusable sub-bass. + + + Microphone + + + Microphone level + + + Noise suppression + + + NVIDIA AI + + + Quick actions + + + Jump into the full editor or manage the selected physical controller. + + + Edit active profile + + + Controller details + + + Lightbar controls + + + Use profile lightbar controls or choose a temporary custom color + + + Disconnect + + + Enabled + + + Audio Haptics + + + Audio-driven controller feedback + + + Low + + + Medium + + + High + + + SOURCE + + + Refresh running audio sessions + + + System audio uses only Windows' default output, not every Sonar output. Choose an app to follow its audio on any output. + + + Automatically follow games + + + Switch to the active game's audio using Windows game records and installed launcher manifests. + + + Follows games recognized by Windows, Steam, Epic, or GOG. The selected app remains the fallback. + + + Play app through controller + + + Also stream this selected app to the controller speaker and AUX headset. + + + Overrides Advanced > Controller audio source while enabled. Choosing another source there releases this override. + + + Headset only + + + Send the captured app only through the controller AUX port. + + + Routes captured app audio to headphones connected to the controller and mutes the controller speaker. + + + MODE + + + Mix + + + Add audio-derived feedback to game haptics and rumble. + + + Replace + + + Use only audio-derived feedback. + + + Response + + + Frequency focus and strength + + + Bass Focus + + + Choose which low-frequency region becomes vibration. + + + Response + + + Control how strongly haptics react, especially to peaks. + + + Subtle + + + Dynamic + + + Aggressive + + + Ramp + + + Control how quickly haptics rise with the sound. + + + Slow Ramp + + + Medium Ramp + + + Fast Ramp + + + Instant Ramp + + + Fade + + + Control how quickly haptics fade after the sound drops. + + + Fast Fade + + + Medium Fade + + + Slow Fade + + + Long Fade + + + Audio Haptics is disabled. + + + System audio + + + Live input + + + Physical controller · before remapping + + + Waiting + + + L stick + + + R stick + + + PRESSED + + + Connect a controller, then reopen this editor. + + + LAB OVERRIDE + + + Effect design + + + Linked + + + Use one shared effect design for L2 and R2. Presets, modes, and sliders mirror between both sides; each trigger's Active switch remains independent. + + + Split + + + Configure separate effect designs for L2 and R2. Returning to Split restores your last independent settings, including which trigger was active. + + + Enabled + + + Active lab effects override incoming game adaptive-trigger output. + + + VIIPER virtual controller setup + + + Close + + + VIIPER needs attention + + + This profile uses a VIIPER virtual controller output. + + + What DS4Windows needs + + + • VIIPER helper/server +• usbip-win2 Windows USB/IP driver + + + Current status + + + Competing VIIPER detected + + + This executable will not be elevated or selected. Install or Repair uses the verified Program Files backend and removes only recognized legacy VIIPER files: + + + Don't show this setup prompt again + + + You can turn setup prompts back on from Settings → VIIPER Virtual Controller Support. + + + Keep DS4Windows portable leaves this app exactly where it is, while installing the elevated VIIPER backend in protected Program Files. Standard also moves only package-owned DS4Windows files into Program Files. Profiles, settings, and unrecognized files are always preserved. + + + Not now + + + Keep DS4Windows portable + + + Install standard + + + VIIPER setup + + + Setting up VIIPER + + + DS4Windows is verifying the complete controller backend. + + + Preparing verified package... + + + • Verify packaged files + + + • Install VIIPER 0.1.9-rc4.6.6 + + + • Verify USB-IP 0.9.7.7 + + + • Verify startup and API + + + Keep this window open. Setup will finish automatically. + + + Config Swipe Profiles + + + Tick the profiles the two-finger touchpad swipe is allowed to switch between. If nothing is ticked, the swipe cycles through every profile (default behaviour). + + + Select All + + + Clear All + + + Switch 2 stick calibration + + + Calibrate your sticks + + + Closing cancels capture and live activation. A save already writing to disk may still finish; closing does not undo that write. + + + _Close + + + PHYSICAL STICK + + + _Start calibration + + + Sa_ve calibration + + + _Cancel capture + + + Calibration is saved on this PC for this physical stick, not in a profile or the controller's memory. USB and Bluetooth records may be separate. Mapped controller input is released while calibration is active. + + + _Reset this stick's PC calibration… + + + StickCalibration + + + Please move your stick to the sides and release it a few times, then after you are done press Save. + + + Button Activation Mode + + + + Select Preset + + + Keep this window size after closing + + + Keep size + + + Controller map + + + Choose a control directly on the controller. + + + DualShock 4 + + + DualSense + + + DualSense Edge + + + Switch 2 Pro + + + Joy-Con pair + + + Joy-Con L (upright) + + + Joy-Con R (upright) + + + Joy-Con L (sideways) + + + Joy-Con R (sideways) + + + DPad + + + Inverted + + + Inverted X + + + Inverted Y + + + Rotate 90° + + + Rotate -90° + + + Face Buttons + + + WASD + + + Arrow Keys + + + Cross + + + Circle + + + Square + + + Triangle + + + L1 + + + R1 + + + L2 + + + R2 + + + Share + + + Options + + + Guide + + + Capture + + + C + + + Mute + + + Function Left + + + Function Right + + + Bottom Left Paddle + + + Bottom Right Paddle + + + Left Touch + + + Multi Touch + + + Right Touch + + + Top Touch + + + L3 + + + LSU + + + LSR + + + LSD + + + LSL + + + R3 + + + RSU + + + RSR + + + RSD + + + RSL + + + Up + + + Right + + + Down + + + Left + + + Tip: right-click supported controls for presets. + + + Button mappings + + + Double-click a row to change its action. + + + Show live preview + + + LIST ONLY + + + Special Actions + + + L2/R2 + + + Made with Trigger Lab + + + This protected profile effect overrides incoming game adaptive-trigger output. Edit it in Trigger Lab. + + + PROTECTED + + + Controller Readings + + + LS + + + Force + + + units + + + ms + + + Invert + + + sec. + + + This button is reserved for calibration while the left stick uses Flick Stick. + + + Save the profile, then tap the selected button in-game for a 360° mouse-look turn. Active only in Flick Stick mode. + + + Increase Real World Calibration if the turn falls short; decrease it if the turn goes too far. Choose Not assigned to release the button. + + + RS + + + Rotation: + + + This button is reserved for calibration while the right stick uses Flick Stick. + + + L2 & R2 + + + X + + + Z + + + R + + + G + + + B + + + Empty + + + Flash at + + + Pulse at + + + While Charging: + + + Pulse + + + Rainbow + + + Color by Battery % + + + secs/cycle + + + Jitter Compensation + + + Double Tap + + + Lower Right as RMB + + + Passthru Click Action (DS4 mode) + + + Start with Slide/Scroll Off + + + Min Threshold + + + Trackball + + + Friction: + + + Y + + + X+Y + + + Disable Invert + + + Finger on Touchpad + + + PS + + + Touchpad Click + + + Side L + + + Side R + + + Swipe Up + + + Swipe Down + + + Swipe Left + + + Swipe Right + + + Output Stick + + + Output Axes + + + Horizontal and Vertical + + + Horizontal Only + + + Vertical Only + + + Minimum X + + + Minimum Y + + + Invert X + + + Invert Y + + + Smoothing + + + Smoothing Options + + + Max Zone X: + + + Max Zone Y: + + + Snap To Center on Release: + + + Tilt Up + + + Tilt Down + + + Tilt Left + + + Tilt Right + + + Triggers + + + Turn Behavior - Turns Gyro + + + Eval Cond. + + + And + + + Or + + + Steering wheel axis + + + Left X-Axis + + + Left Y-Axis + + + Right X-Axis + + + Right Y-Axis + + + Trigger L+R Axis + + + VJoy1 X-Axis + + + VJoy1 Y-Axis + + + VJoy1 Z-Axis + + + VJoy2 X-Axis + + + VJoy2 Y-Axis + + + VJoy2 Z-Axis + + + Steering wheel range + + + Calibrate + + + Gyro Calibration + + + Gyro Sensitivity: + + + X Axis + + + Weighted Average + + + Smooth Weight + + + X-Axis + + + Weight + + + deg/sec. + + + Delay Time + + + Trigger Lab + + + Nintendo Options + + + These settings are saved with the profile and apply to controllers that support them. + + + How do you want to play? + + + Point at menus. Aim by tilting. Feel the game. Start with what you want to do; fine-tuning is tucked inside each section. + + + Saved with this profile for any controller. Features your controller doesn't support have no effect. Desk mouse and motion aiming are separate features. + + + Mouse on a desk + + + Slide a Joy-Con to point or aim. Use its stick to scroll. + + + Slide a Joy-Con to move the mouse + + + Move a Joy-Con across a surface to control the mouse pointer. + + + Place the sensor edge against a desk or mouse mat, then slide the Joy-Con. Lifting it lets you reposition without moving the pointer. + + + Slide to aim or point at menus. Use the stick to scroll while the sensor touches the surface. + + + Assign mouse clicks in Button Mapping. For different actions only while on the desk, use the matching IR Sensor as the Shift Modifier. + + + Which Joy-Con: + + + Automatic + + + Both + + + Stick scroll: + + + Choose whether the stick scrolls vertically only or in all four directions. + + + Up / Down + + + Four-way + + + Left sensitivity: + + + Right sensitivity: + + + Surface detection + + + Try Relaxed if your surface is not detected. These settings also affect surface-triggered button actions and aiming. + + + Left surface detection: + + + Strict + + + Relaxed + + + Right surface detection: + + + Aim by tilting + + + Fine aim with your hands, with or without a mouse pointer. + + + Choose what tilting does + + + Mapped tilt buttons (no mouse) + + + Mouse pointer + + + Virtual aiming stick + + + Quick-tilt actions + + + Game's own motion controls + + + When to aim: + + + Always on + + + Hold ZL / L2 + + + Hold ZR / R2 + + + Custom — see Gyro settings + + + Trigger choices follow your button layout. Custom combinations and toggle-to-aim are available in Gyro settings. + + + Mouse aiming speed: + + + Open full Gyro settings… + + + Choose aim buttons, stick output, sensitivity and smoothing. + + + Fine-tune aiming + + + Reduce sideways gyro drift + + + Help reduce sideways gyro drift. Turn this off if nearby electronics affect aiming. + + + Ignore tiny gyro movements to steady aim. Set to 0 for maximum sensitivity. + + + Ignore small movements: + + + Use the stick alongside gyro aiming to turn further. Set to 0 to turn this off. + + + Stick-assisted aiming: + + + Smoother mouse movement + + + Make mouse movement smoother between controller updates. This does not speed up the controller itself. + + + Adjust sideways motion sensitivity in compatible emulators. 1 is the normal level. + + + Emulator turn sensitivity: + + + Keep motion aiming level + + + Keep motion aiming level when you tilt the controller. + + + Pause aiming with a button + + + Pause motion aiming with a button so you can reposition the controller. + + + Hold to pause aiming, or press to toggle the pause. The pause clears when you stop using gyro. + + + Aiming settings to edit: + + + Hold-to-lock buttons: + + + Press-to-toggle lock buttons: + + + Steady aim around button presses + + + Reduce aim movement caused by pressing or releasing buttons. + + + Fine-tune a mode you have already enabled above. These choices do not switch your aiming output. + + + activation source: + + + Buttons that steady aim: + + + Deadzone: + + + press pause: + + + Release pause: + + + deadzone after release: + + + Buttons that slow aim: + + + Dampening: + + + after release: + + + Steady aiming when touching a desk + + + Choose the left or right IR Sensor in the Gyro trigger menu to aim while touching a surface. + + + Pause aiming around button presses, ignore small movements, or reduce sensitivity while a button is held. + + + Left optical sensor + + + Deadzone / click-stabilization buttons: + + + Dampening buttons: + + + Right optical sensor + + + Dual Joy-Con aiming + + + Let your two hands share the aim, or switch between them. + + + Aim with both Joy-Cons (DJG) + + + Let a joined pair share motion aiming. Turn off to use the normal single motion source. + + + Choose which hand supplies motion. This does not pair your Joy-Cons or turn on mouse aiming. + + + For mouse or stick aiming, start with Aim by tilting → When to aim: Always on. Choosing a button there adds a separate on/off control; it does not choose a hand. + + + Set up motion aiming… + + + Choose how the two hands work together + + + Lead hand, side switching and pause buttons. + + + Mode: + + + Both hands — switch lead hand + + + One hand at a time + + + Both hands — pause each side + + + Preferred aiming hand: + + + Choose the hand that leads your aim, or combine both when pausing each side separately. + + + Combine both + + + Button behavior: + + + While held + + + Press to toggle + + + Left Joy-Con buttons + + + Right Joy-Con buttons + + + Feel game feedback + + + Feel impacts, textures and trigger effects as HD rumble. + + + Adjust overall rumble strength. 100% is the normal level; 0% turns body rumble off. + + + Body rumble strength: + + + Include Xbox trigger rumble + + + Feel Xbox trigger vibrations on the matching side of your controller. Shares the setting in Advanced. + + + Vary trigger rumble feel + + + Change the feel of trigger rumble as its strength changes. + + + Trigger rumble strength: + + + Fixed rumble feel: + + + Include detailed DualSense vibrations + + + Turn detailed DualSense vibrations into left and right HD rumble. + + + Include DualSense trigger effects + + + Turn DualSense trigger effects into vibrations. Switch 2 triggers cannot add physical resistance. + + + Use Xbox-style body rumble + + + Give body rumble a consistent Xbox-style feel instead of following each game's vibration detail. + + + Body rumble feel: + + + Delay rumble to match delayed game audio. Leave at 0 for the quickest response. + + + Game rumble delay: + + + Listen and chat through your Switch 2 Pro's headphone jack. + + + Audio goes directly through Windows. It works independently of your chosen virtual controller; no DS4Windows audio toggle is needed. + + + USB only. Bluetooth headset audio is not supported yet. A regular AUX cable carries sound out, but cannot test the headset microphone. + + + Give buttons a second job + + + Hold or toggle a button to access another set of actions. + + + Example: keep a button’s usual action, then give it a different job while you hold another button. + + + Action set to edit: + + + Press a button to switch actions: + + + The shortcut opens Shift Modifier for you. For a new second action, Switch 2 Mode Shift is already selected. Existing shift triggers are kept. + + + Edit second action… + + + Open Button Mapping + + + Choose the action in the window, then save this profile. A shift button is reserved for switching actions, so its normal game action is not sent. + + + Automatic second actions (optional) + + + When enabled below, aiming starts in second actions. Your hold or toggle buttons switch back to normal actions instead. These options do not enable aiming. + + + Automatically start in second actions while: + + + Mouse aiming is active + + + Stick aiming is active + + + Motion steering + + + Point, scroll or tap with a stick + + + Fine-tune sticks you have assigned to mouse or button actions. + + + Stick scrolling + + + Assign scroll actions in Button Mapping first. Tap scrolls once; Hold keeps scrolling. + + + Left stick: + + + Hold + + + Right stick: + + + Stick button actions + + + Hold keeps an action pressed. Tap triggers it once each time you move the stick into that direction. + + + Left stick + + + Right stick + + + Stick mouse speed + + + Adjust speed for sticks mapped to mouse movement. 5 is the normal speed; 0 stops movement. + + + Layout & battery + + + Match your button labels, hold a single Joy-Con sideways, or save battery. + + + Xbox follows button positions. Nintendo follows the printed A, B, X and Y labels. + + + Face-button layout: + + + Xbox + + + Nintendo + + + Joy-Con holding style: + + + Choose the starting orientation. A choice made on the Controllers tab takes priority for that Joy-Con. + + + Upright + + + Sideways + + + Automatic Bluetooth disconnect + + + Disconnect after inactivity to save battery, or after a set time even while playing. + + + When idle + + + After a set time + + + Disconnect after: + + + day + + + hour + + + minute + + + Set the duration to zero to disable the timer. Until changed here, existing profiles keep their Idle Disconnect setting. + + + Vibrate when connected + + + Play a short vibration when the controller is ready. + + + Correct drift & stick range + + + Use guided calibration if a stick feels off or the aim drifts. + + + Stick calibration + + + Follow the guided steps to correct stick centers and range. Factory settings stay unchanged. + + + Calibrate sticks… + + + Place the controller on a stable surface and leave it still for at least five seconds after starting. + + + Restart gyro calibration + + + Correct gyro drift. Keep the controller still for at least five seconds. + + + Slowly rotate the controller in a figure-eight. Game input pauses during calibration. + + + Calibrate drift correction + + + Use this if sideways drift correction feels inaccurate. + + + Advanced + + + Xbox 360 + + + Xbox One / Series + + + A + + + Nintendo face layout + + + Plus, Minus, Home, Capture, L/R, ZL/ZR + + + Debouncing + + + Translate Xbox impulse-trigger vibration + + + Feel Xbox trigger vibrations through your controller's triggers or rumble motors. Works independently of Trigger Lab. + + + Send impulse vibration to adaptive triggers + + + DualSense and Edge: use adaptive triggers for Xbox impulse vibration. Turn off to use body rumble. Requires impulse translation above. + + + PlayStation controller features + + + DualSense haptics + + + Mutes the built-in speaker while continuing the same stream through a headset connected to the controller's AUX port. + + + Mute controller speaker with mute button + + + When Mute Button Mutes Input/Output is enabled, a lit mute LED turns off controller-speaker output. The setting has no effect while the master toggle is off. + + + Audio source: + + + For game audio, select the virtual Wireless Controller endpoint created by a VIIPER PlayStation output. The first stereo pair is mirrored to the physical controller speaker. + + + Audio Haptics is currently supplying the selected app to this controller. Choose another Audio source here to release that override. + + + USB DualSense speaker: + + + Only used for a physical USB DualSense. Bluetooth controllers stream audio directly to the controller. + + + Speaker volume: + + + Dynamic range: + + + Bluetooth speaker processing. Balanced raises quieter details and restrains loud effects. Strong narrows the range further. Processing is applied before native encoding (Opus on DualSense, SBC on DualShock 4) without look-ahead latency. + + + Bass/body boost: + + + Adds up to 6 dB around 200 Hz while filtering unusable sub-bass. Applies only to the Bluetooth controller speaker stream. + + + Mute controller microphone with mute button + + + When Mute Button Mutes Input/Output is enabled, a lit mute LED turns off controller-microphone input. The setting has no effect while the master toggle is off. + + + Microphone level: + + + Adjusts the physical microphone level and the safely trimmed signal exposed to Windows. + + + Noise suppression: + + + Balanced applies RNNoise speech cleanup. Strong also reduces low-level residual noise. Off retains only gain, high-pass, and clipping protection. + + + Advanced audio + + + Headset / AUX volume: + + + Controls the headset jack independently from the controller speaker. DualShock 4 maps the full slider range to Sony's documented 0-80 headset gain. + + + USB/legacy microphone routing captures the physical Windows controller-mic endpoint and sends it to a virtual audio render device such as VB-CABLE Input. Bluetooth VIIPER microphone routing does not need these endpoints. + + + Controller mic: + + + Virtual output: + + + DualSense mute button + + + Mute Button Mutes Input/Output + + + Uses the controller mute button as a master for the speaker and microphone targets selected above. The mute LED is on while those targets are muted and off while they are live. + + + Enable mute button light + + + Mirrors the physical DualSense mute button state to the controller mute LED while this profile is active. This only controls the light, not Windows microphone routing. + + + Mute button switches profiles + + + Switches between the selected profiles when mute changes. Enabling Mute Button Mutes Input/Output turns this option off and greys it out without erasing the saved profile choices. + + + Mute on profile: + + + Optional. Switch to this profile when the physical DualSense mute button toggles on. + + + Leave blank to avoid changing profiles when mute turns on. + + + Mute off profile: + + + Optional. Switch to this profile when the physical DualSense mute button toggles off. + + + Leave blank to avoid changing profiles when mute turns off. + + + for readout + + + Game Bar + + + Enable Game Bar controller compatibility + + + While Xbox Game Bar is visible, temporarily route this profile's mapped input through an Xbox-compatible controller. The selected profile and native DualSense output stay configured. + + + Keeps this profile and its native output active. Only mapped input is temporarily sent through an Xbox-compatible companion while Game Bar is open; audio, haptics, lighting, and microphone routing stay untouched. + + + mins + + + Max (1 ms) + + + Show live preview + + + See what your controller is sending while you choose an action. + + + Upper Touch + + + Sixaxis Up + + + Sixaxis Down + + + Sixaxis Left + + + Sixaxis Right + + + DSE Function Left + + + DSE Function Right + + + DSE Left Paddle + + + DSE Right Paddle + + + Switch 2 Joy-Con Left IR Sensor + + + Switch 2 Joy-Con Right IR Sensor + + + Switch 2 Mode Shift + + + Switch 2 Joy-Con Left SL + + + Switch 2 Joy-Con Left SR + + + Switch 2 Joy-Con Right SL + + + Switch 2 Joy-Con Right SR + + + Switch 2 C / Chat + + + D + + + E + + + F + + + H + + + I + + + J + + + K + + + L + + + M + + + N + + + O + + + P + + + Q + + + S + + + T + + + U + + + V + + + W + + + F1 + + + F2 + + + F3 + + + F4 + + + F5 + + + F6 + + + F7 + + + F8 + + + F9 + + + F10 + + + F11 + + + F12 + + + Tab + + + Esc + + + Prt + + + Del + + + RCtrl + + + Brk + + + Ins + + + NumLk + + + Home + + + BkSpace + + + Space + + + LAlt + + + End + + + LCtrl + + + RShift + + + PgUp + + + Scl + + + LWin + + + RAlt + + + Enter + + + LShift + + + RWin + + + PgDown + + + Caps + + + R → + + + Overview + + + General + + + Refresh + + + Ping + + + Time + + + Data + + + Right click to disconnect wireless + + + Use the same profile whenever this physical controller reconnects. + + + JOY-CON HOLD + + + IDENTIFY + + + Vibrate this controller so you can tell which one it is. + + + LIGHTBAR + + + Choose a temporary lightbar color + + + Your profiles + + + Select a profile for actions, or double-click a card to edit it. + + + Search profiles by name + + + Clear search + + + P + + + Controller profile + + + No profiles yet + + + Create or import a profile to get started. + + + Loading profile editor + + + Applying the profile and preparing its controls... + + + Startup, notifications, charging, appearance, and update behavior used by most players. + + + Prevents games from seeing both the physical controller and its virtual output. HidHide is recommended on current Windows versions. + + + Reclaim controller from Steam Input automatically + + + Cloaks the physical controller with HidHide, then safely restarts only its HID collection so Steam releases any handle it opened first. The virtual controller remains available to games. + + + Choose which profiles the two-finger swipe is allowed to switch between + + + Choose whether DS4Windows should open when you sign in to Windows. If setup is pending, your choice is saved and the message below explains the next step. + + + Disconnect Bluetooth controllers when the DS4Windows service is stopped. + + + Open DS4Windows quietly without showing the main window. + + + Verbose logging + + + Writes detailed diagnostic markers to the log. Disable after testing. + + + Periodically check GitHub for a newer DS4Windows release. + + + Advanced settings + + + Network servers, compatibility overrides, device registration, diagnostics, and maintenance tools. Defaults are best for most users. + + + Support DS4Windows + + + Help fund controller hardware, testing, and development. + + + VIIPER Virtual Controller Support + + + VIIPER status unknown + + + Install / Repair VIIPER + + + Required for VIIPER outputs: DualSense, DualSense Edge, Switch 2 Pro, DS4, Xbox 360, and Xbox One / Series over USB/IP. + + + Prompt me when VIIPER needs setup + + + Turn this off to suppress automatic VIIPER setup prompts. Install / Repair and Refresh remain available here. + + + Switch 2 wireless controllers + + + Hold the controller’s sync button until its lights flash, then select it below. Controllers you have already added reconnect when you wake them. + + + Joy-Cons are automatically paired + + + Join available left and right Joy-Cons into one controller. A Joy-Con on its own still works separately. + + + Refresh to check Bluetooth discovery status. + + + Add controller + + + Join Joy-Cons + + + Each Joy-Con works on its own. To join two, select them here or use their link buttons on the Controllers tab. + + + No unmatched Joy-Con 2 connections have been observed yet. + + + Left Joy-Con 2 + + + Right Joy-Con 2 + + + Join selected Joy-Con 2 pair + + + Use selected left separately + + + Use selected right separately + + + UNMATCHED JOY-CON 2 + + + Click Link on one Joy-Con, then Link on the other. The first controller keeps its profile and virtual pad. + + + Game mod support (DSX) + + + Let game mods control triggers and lights + + + For compatible DSX game mods on this PC and a DualSense or DualSense Edge. Trigger Lab takes priority on each trigger you enable. This does not stream audio haptics. + + + Connection details + + + Use the same address and port in your mod. Most mods use 127.0.0.1 and port 6969. Close DSX or another listener using that port first. + + + This PC address + + + Apply / Retry + + + DS4Windows + Controller companion + Connect a controller to begin + NAVIGATION + Profile Editor + P + Focused workspace + EDITING PROFILE + PROFILE WORKSPACE + Back to Profiles + Cancel editing and return to the profile list + Button Mapping + Buttons, sticks, touch gestures, and shortcuts + Macros, launches, shifts, and multi-actions + Live inputs and calibration + Sticks, triggers, dead zones, and curves + Color, battery, flash, and charging + Mouse, gestures, passthrough, and positioning + Motion aiming, steering, and swipes + Turn system or app audio into advanced haptics + Build persistent adaptive-trigger effects + HD rumble, motion, optical mouse, and calibration + Output, rumble, latency, and compatibility + Service events without leaving the editor + + LX (I): + LX (O): + LY (I): + LY (O): + RX (I): + RX (O): + RY (I): + RY (O): + X (I): + X (O): + Z (I): + Z (O): + I: + O: + TX: + TY: + + Name: + Check the buttons that start this action. Multiple buttons must be held together. + Check the buttons that end this action or return to the previous profile. + Launch Program + secs + Arguments + Load Profile + Press Key + DisBT + Check Battery + MultiAct + Sixaxis Wheel + + Accept Moonlight / Sunshine virtual controllers + Accept every supported virtual controller created while Sunshine is running. DS4Windows' own VIIPER outputs are always excluded. + DS4 + Switch Pro + JoyCon + + Device + Window title... + Search by profile, window title, executable, or path + DEVICE + + FakerInput + CRC32 + H.NotifyIcon + vJoyInterfaceCS + + X — Y — + + Required virtual-controller backend. DS4Windows requests administrator access and installs VIIPER plus usbip-win2 for you. + + Cycle Programs + From File... + + Finished + Select Preset + Enable Sunshine direct controller bridge + Let Sunshine send controller input directly to DS4Windows. DS4Windows will create the game-facing virtual controller; no Sunshine virtual input controller is created. Enable the matching option in Sunshine too. + Repair updates your existing installation. Your profiles and settings are kept. + Install / Repair + \ No newline at end of file diff --git a/DS4WindowsTests/RuntimeXamlTranslatorTests.cs b/DS4WindowsTests/RuntimeXamlTranslatorTests.cs new file mode 100644 index 00000000..70c7c617 --- /dev/null +++ b/DS4WindowsTests/RuntimeXamlTranslatorTests.cs @@ -0,0 +1,112 @@ +using System; +using System.Globalization; +using System.Linq; +using System.Runtime.ExceptionServices; +using System.Threading; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Documents; +using System.Windows.Markup; +using System.Windows.Threading; +using DS4WinWPF.DS4Forms; +using DS4WinWPF.Translations; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace DS4WindowsTests; + +[TestClass] +[DoNotParallelize] +public class RuntimeXamlTranslatorTests +{ + private const string Markup = @" + +