[GUI] Added Custom Environment Variables dialog and settings
This commit is contained in:
parent
15a94a3859
commit
ca5767e57f
|
|
@ -0,0 +1,76 @@
|
|||
<!--
|
||||
Copyright (C) 2026 SharpEmu Emulator Project
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
-->
|
||||
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:SharpEmu.GUI"
|
||||
x:Class="SharpEmu.GUI.CustomEnvironmentDialog"
|
||||
Width="620"
|
||||
Height="520"
|
||||
MinWidth="520"
|
||||
MinHeight="430"
|
||||
CanResize="True"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Background="{StaticResource BgBrush}"
|
||||
Title="{Binding [Launch.CustomEnv.Title], Source={x:Static local:Localization.Instance}}">
|
||||
<Grid Margin="24" RowDefinitions="Auto,Auto,Auto,*,Auto,Auto">
|
||||
<TextBlock Grid.Row="0"
|
||||
Text="{Binding [Launch.CustomEnv.Title], Source={x:Static local:Localization.Instance}}"
|
||||
FontSize="24"
|
||||
FontWeight="Bold" />
|
||||
|
||||
<TextBlock Grid.Row="1"
|
||||
Margin="0,8,0,16"
|
||||
Text="{Binding [Launch.CustomEnv.Desc], Source={x:Static local:Localization.Instance}}"
|
||||
Foreground="{StaticResource MutedBrush}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<Button x:Name="DocumentationButton"
|
||||
Grid.Row="2"
|
||||
Classes="ghost"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="0,0,0,12"
|
||||
Padding="0,4"
|
||||
Content="{Binding [Launch.CustomEnv.Documentation], Source={x:Static local:Localization.Instance}}" />
|
||||
|
||||
<TextBox x:Name="EnvironmentTextBox"
|
||||
Grid.Row="3"
|
||||
AcceptsReturn="True"
|
||||
TextWrapping="NoWrap"
|
||||
FontFamily="Consolas,monospace"
|
||||
FontSize="13"
|
||||
VerticalContentAlignment="Top"
|
||||
PlaceholderText="{Binding [Launch.CustomEnv.Placeholder], Source={x:Static local:Localization.Instance}}" />
|
||||
|
||||
<TextBlock x:Name="StatusText"
|
||||
Grid.Row="4"
|
||||
Margin="0,12,0,0"
|
||||
Foreground="{StaticResource MutedBrush}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<Grid Grid.Row="5"
|
||||
Margin="0,18,0,0"
|
||||
ColumnDefinitions="Auto,Auto,*,Auto,Auto">
|
||||
<Button x:Name="SaveGameButton"
|
||||
Grid.Column="0"
|
||||
Classes="ghost"
|
||||
Margin="0,0,8,0"
|
||||
Content="{Binding [Launch.CustomEnv.SaveGame], Source={x:Static local:Localization.Instance}}" />
|
||||
<Button x:Name="SaveGlobalButton"
|
||||
Grid.Column="1"
|
||||
Classes="ghost"
|
||||
Content="{Binding [Launch.CustomEnv.SaveGlobal], Source={x:Static local:Localization.Instance}}" />
|
||||
<Button x:Name="CancelButton"
|
||||
Grid.Column="3"
|
||||
Classes="ghost"
|
||||
Margin="0,0,8,0"
|
||||
Content="{Binding [Common.Cancel], Source={x:Static local:Localization.Instance}}" />
|
||||
<Button x:Name="PlayButton"
|
||||
Grid.Column="4"
|
||||
Classes="accent"
|
||||
Content="{Binding [Launch.CustomEnv.Play], Source={x:Static local:Localization.Instance}}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
// Copyright (C) 2026 SharpEmu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
using Avalonia.Controls;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace SharpEmu.GUI;
|
||||
|
||||
public partial class CustomEnvironmentDialog : Window
|
||||
{
|
||||
private readonly string? _titleId;
|
||||
|
||||
public CustomEnvironmentDialog()
|
||||
: this(null, [])
|
||||
{
|
||||
}
|
||||
|
||||
public CustomEnvironmentDialog(string? titleId, IEnumerable<string> initialEntries)
|
||||
{
|
||||
InitializeComponent();
|
||||
_titleId = titleId;
|
||||
EnvironmentTextBox.Text = string.Join(Environment.NewLine, initialEntries);
|
||||
SaveGameButton.IsEnabled = !string.IsNullOrWhiteSpace(titleId);
|
||||
|
||||
SaveGameButton.Click += (_, _) => SaveForGame();
|
||||
SaveGlobalButton.Click += (_, _) => SaveGlobally();
|
||||
DocumentationButton.Click += (_, _) => OpenDocumentation();
|
||||
CancelButton.Click += (_, _) => Close(null);
|
||||
PlayButton.Click += (_, _) => Play();
|
||||
}
|
||||
|
||||
public event Action<IReadOnlyList<string>>? SaveGlobalRequested;
|
||||
public event Action<string, IReadOnlyList<string>>? SaveGameRequested;
|
||||
|
||||
private static void OpenDocumentation()
|
||||
{
|
||||
Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName = ProjectLinks.DocumentUrl("docs/sharpemu-gui-undocumented-env-vars.md"),
|
||||
UseShellExecute = true,
|
||||
});
|
||||
}
|
||||
|
||||
private bool TryGetEntries(out IReadOnlyList<string> entries)
|
||||
{
|
||||
if (!CustomEnvironmentVariables.TryParseLines(
|
||||
EnvironmentTextBox.Text,
|
||||
out var parsed,
|
||||
out var invalidLine))
|
||||
{
|
||||
StatusText.Text = string.Format(
|
||||
Localization.Instance.Get("Launch.CustomEnv.Invalid"),
|
||||
invalidLine);
|
||||
entries = [];
|
||||
return false;
|
||||
}
|
||||
|
||||
StatusText.Text = string.Empty;
|
||||
entries = parsed;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void SaveForGame()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(_titleId) || !TryGetEntries(out var entries))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SaveGameRequested?.Invoke(_titleId, entries);
|
||||
StatusText.Text = Localization.Instance.Get("Launch.CustomEnv.SavedGame");
|
||||
}
|
||||
|
||||
private void SaveGlobally()
|
||||
{
|
||||
if (!TryGetEntries(out var entries))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SaveGlobalRequested?.Invoke(entries);
|
||||
StatusText.Text = Localization.Instance.Get("Launch.CustomEnv.SavedGlobal");
|
||||
}
|
||||
|
||||
private void Play()
|
||||
{
|
||||
if (TryGetEntries(out var entries))
|
||||
{
|
||||
Close(entries);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
// Copyright (C) 2026 SharpEmu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
namespace SharpEmu.GUI;
|
||||
|
||||
internal static class CustomEnvironmentVariables
|
||||
{
|
||||
public static bool TryParseLines(
|
||||
string? text,
|
||||
out IReadOnlyList<string> entries,
|
||||
out string invalidLine)
|
||||
{
|
||||
var parsed = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var rawLine in (text ?? string.Empty).Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
var line = rawLine.Trim();
|
||||
if (line.Length == 0 || line.StartsWith('#'))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!TryParseEntry(line, out var name, out var value))
|
||||
{
|
||||
entries = [];
|
||||
invalidLine = line;
|
||||
return false;
|
||||
}
|
||||
|
||||
parsed[name] = value;
|
||||
}
|
||||
|
||||
entries = parsed.Select(pair => $"{pair.Key}={pair.Value}").ToArray();
|
||||
invalidLine = string.Empty;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static IReadOnlyList<string> Merge(
|
||||
params IEnumerable<string>?[] sources)
|
||||
{
|
||||
var merged = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var source in sources)
|
||||
{
|
||||
if (source is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var entry in source)
|
||||
{
|
||||
if (TryParseEntry(entry, out var name, out var value))
|
||||
{
|
||||
merged[name] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return merged.Select(pair => $"{pair.Key}={pair.Value}").ToArray();
|
||||
}
|
||||
|
||||
public static bool TryParseEntry(string entry, out string name, out string value)
|
||||
{
|
||||
var separator = entry.IndexOf('=');
|
||||
name = (separator >= 0 ? entry[..separator] : entry).Trim();
|
||||
value = separator >= 0 ? entry[(separator + 1)..] : "1";
|
||||
|
||||
return name.Length != 0 &&
|
||||
!name.Contains('\0') &&
|
||||
!name.Contains('=');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
// Copyright (C) 2026 SharpEmu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
using System.Text.Json;
|
||||
|
||||
namespace SharpEmu.GUI;
|
||||
|
||||
internal sealed class GlobalCustomEnvironmentSettings
|
||||
{
|
||||
private static readonly JsonSerializerOptions SerializerOptions = new()
|
||||
{
|
||||
WriteIndented = true,
|
||||
};
|
||||
|
||||
public List<string> EnvironmentVariables { get; set; } = new();
|
||||
|
||||
public static string FilePath =>
|
||||
Path.Combine(AppContext.BaseDirectory, "user", "custom_envs.json");
|
||||
|
||||
public static IReadOnlyList<string> Load()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!File.Exists(FilePath))
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
var settings = JsonSerializer.Deserialize<GlobalCustomEnvironmentSettings>(
|
||||
File.ReadAllText(FilePath),
|
||||
SerializerOptions);
|
||||
return Normalize(settings?.EnvironmentVariables);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
public static void Save(IEnumerable<string> entries)
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(FilePath)!);
|
||||
var settings = new GlobalCustomEnvironmentSettings
|
||||
{
|
||||
EnvironmentVariables = Normalize(entries).ToList(),
|
||||
};
|
||||
File.WriteAllText(FilePath, JsonSerializer.Serialize(settings, SerializerOptions));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private static IReadOnlyList<string> Normalize(IEnumerable<string>? entries) =>
|
||||
CustomEnvironmentVariables.Merge(entries);
|
||||
}
|
||||
|
|
@ -72,6 +72,8 @@ public sealed class GuiSettings
|
|||
/// <summary>Names of SHARPEMU_* switches set to "1" in the emulator's environment at launch.</summary>
|
||||
public List<string> EnvironmentToggles { get; set; } = new();
|
||||
|
||||
public string BinkPlaybackMode { get; set; } = "Host";
|
||||
|
||||
/// <summary>Internal render resolution scale (1.0 = native, 0.5 = half).</summary>
|
||||
public double RenderResolutionScale { get; set; } = 1.0;
|
||||
|
||||
|
|
@ -139,6 +141,7 @@ public sealed class GuiSettings
|
|||
settings.Resolution = NormalizeResolution(settings.Resolution);
|
||||
settings.ScalingMode = NormalizeChoice(settings.ScalingMode, "Fit", "Cover", "Stretch", "Integer");
|
||||
settings.HdrMode = NormalizeChoice(settings.HdrMode, "Auto", "On", "Off");
|
||||
settings.BinkPlaybackMode = NormalizeChoice(settings.BinkPlaybackMode, "Host", "Guest", "Skip");
|
||||
settings.DisplayIndex = Math.Max(0, settings.DisplayIndex);
|
||||
settings.RefreshRate = Math.Clamp(settings.RefreshRate, 0, 1000);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"Options.Env.BinkPlayback.Label": "تشغيل فيديو Bink",
|
||||
"Options.Env.BinkPlayback.Desc": "يقوم Host بتشغيل فيديوهات Bink عبر جسر FFmpeg، لكن قد تظهر مشكلات في بعض الألعاب.\nيستخدم Guest وحدة فك الترميز الخاصة بمحرك اللعبة، والتي يدعمها SharpEmu حاليًا بشكل جزئي فقط.\nيتخطى Skip فيديوهات Bink، مما قد يجعل التطوير أسهل.",
|
||||
"Options.Env.BinkPlayback.Host": "Host (FFmpeg)",
|
||||
"Options.Env.BinkPlayback.Guest": "Guest",
|
||||
"Options.Env.BinkPlayback.Skip": "تخطي",
|
||||
"_languageName": "العربية",
|
||||
|
||||
"Page.Library": "المكتبة",
|
||||
|
|
@ -90,6 +95,17 @@
|
|||
"Launch.Idle": "خامل",
|
||||
"Launch.Console": "≡ نافذة السجلات",
|
||||
"Launch.Launch": "▶ تشغيل",
|
||||
"Launch.CustomEnv": "تشغيل بمتغيرات بيئة مخصصة",
|
||||
"Launch.CustomEnv.Title": "تشغيل بمتغيرات بيئة مخصصة",
|
||||
"Launch.CustomEnv.Desc": "أدخل متغير بيئة واحدًا في كل سطر بصيغة NAME=VALUE. القيم المخصصة تتجاوز إعدادات الواجهة وإعدادات اللعبة التي تحمل الاسم نفسه.",
|
||||
"Launch.CustomEnv.Documentation": "عرض متغيرات البيئة غير الموثقة ↗",
|
||||
"Launch.CustomEnv.Placeholder": "SHARPEMU_EXAMPLE=1",
|
||||
"Launch.CustomEnv.SaveGame": "حفظ للعبة",
|
||||
"Launch.CustomEnv.SaveGlobal": "حفظ بشكل عام",
|
||||
"Launch.CustomEnv.Play": "تشغيل",
|
||||
"Launch.CustomEnv.Invalid": "متغير بيئة غير صالح: {0}",
|
||||
"Launch.CustomEnv.SavedGame": "تم الحفظ لهذه اللعبة.",
|
||||
"Launch.CustomEnv.SavedGlobal": "تم الحفظ بشكل عام.",
|
||||
"Launch.Stop": "■ إيقاف",
|
||||
"Launch.Running": "قيد التشغيل — {0}",
|
||||
"Launch.Stopping": "جارٍ الإيقاف...",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"Options.Env.BinkPlayback.Label": "Reprodução de vídeo Bink",
|
||||
"Options.Env.BinkPlayback.Desc": "Host reproduz vídeos Bink pela ponte FFmpeg, mas alguns jogos podem apresentar problemas.\nGuest usa o decodificador do próprio motor do jogo, que o SharpEmu atualmente suporta apenas parcialmente.\nSkip ignora os vídeos Bink, o que pode facilitar o desenvolvimento.",
|
||||
"Options.Env.BinkPlayback.Host": "Host (FFmpeg)",
|
||||
"Options.Env.BinkPlayback.Guest": "Guest",
|
||||
"Options.Env.BinkPlayback.Skip": "Ignorar",
|
||||
"_languageName": "Português (Brasil)",
|
||||
|
||||
"Page.Library": "Biblioteca",
|
||||
|
|
@ -104,6 +109,17 @@
|
|||
"Launch.Idle": "Ocioso",
|
||||
"Launch.Console": "≡ Console",
|
||||
"Launch.Launch": "▶ Iniciar",
|
||||
"Launch.CustomEnv": "Iniciar com variáveis de ambiente personalizadas",
|
||||
"Launch.CustomEnv.Title": "Iniciar com variáveis de ambiente personalizadas",
|
||||
"Launch.CustomEnv.Desc": "Digite uma variável de ambiente por linha no formato NOME=VALOR. Os valores personalizados substituem as configurações da GUI e específicas do jogo com o mesmo nome.",
|
||||
"Launch.CustomEnv.Documentation": "Ver variáveis de ambiente não documentadas ↗",
|
||||
"Launch.CustomEnv.Placeholder": "SHARPEMU_EXEMPLO=1",
|
||||
"Launch.CustomEnv.SaveGame": "Salvar para o jogo",
|
||||
"Launch.CustomEnv.SaveGlobal": "Salvar globalmente",
|
||||
"Launch.CustomEnv.Play": "Jogar",
|
||||
"Launch.CustomEnv.Invalid": "Variável de ambiente inválida: {0}",
|
||||
"Launch.CustomEnv.SavedGame": "Salvo para este jogo.",
|
||||
"Launch.CustomEnv.SavedGlobal": "Salvo globalmente.",
|
||||
"Launch.Stop": "■ Parar",
|
||||
"Launch.Running": "Em execução — {0}",
|
||||
"Launch.Stopping": "Encerrando…",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"Options.Env.BinkPlayback.Label": "Bink-Videowiedergabe",
|
||||
"Options.Env.BinkPlayback.Desc": "Host spielt Bink-Videos über die FFmpeg-Brücke ab, bei einigen Spielen können jedoch Probleme auftreten.\nGuest verwendet den spieleigenen Decoder, den SharpEmu derzeit nur teilweise unterstützt.\nSkip überspringt Bink-Videos, was die Entwicklung erleichtern kann.",
|
||||
"Options.Env.BinkPlayback.Host": "Host (FFmpeg)",
|
||||
"Options.Env.BinkPlayback.Guest": "Guest",
|
||||
"Options.Env.BinkPlayback.Skip": "Überspringen",
|
||||
"_languageName": "Deutsch",
|
||||
|
||||
"Page.Library": "Bibliothek",
|
||||
|
|
@ -90,6 +95,17 @@
|
|||
"Launch.Idle": "Bereit",
|
||||
"Launch.Console": "≡ Konsole",
|
||||
"Launch.Launch": "▶ Starten",
|
||||
"Launch.CustomEnv": "Mit benutzerdefinierten Umgebungsvariablen starten",
|
||||
"Launch.CustomEnv.Title": "Mit benutzerdefinierten Umgebungsvariablen starten",
|
||||
"Launch.CustomEnv.Desc": "Gib pro Zeile eine Umgebungsvariable im Format NAME=WERT ein. Benutzerdefinierte Werte überschreiben gleichnamige GUI- und spielspezifische Einstellungen.",
|
||||
"Launch.CustomEnv.Documentation": "Undokumentierte Umgebungsvariablen anzeigen ↗",
|
||||
"Launch.CustomEnv.Placeholder": "SHARPEMU_BEISPIEL=1",
|
||||
"Launch.CustomEnv.SaveGame": "Für Spiel speichern",
|
||||
"Launch.CustomEnv.SaveGlobal": "Global speichern",
|
||||
"Launch.CustomEnv.Play": "Spielen",
|
||||
"Launch.CustomEnv.Invalid": "Ungültige Umgebungsvariable: {0}",
|
||||
"Launch.CustomEnv.SavedGame": "Für dieses Spiel gespeichert.",
|
||||
"Launch.CustomEnv.SavedGlobal": "Global gespeichert.",
|
||||
"Launch.Stop": "■ Stoppen",
|
||||
"Launch.Running": "Läuft -- {0}",
|
||||
"Launch.Stopping": "Wird beendet…",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"Options.Env.BinkPlayback.Label": "Bink-videoafspilning",
|
||||
"Options.Env.BinkPlayback.Desc": "Host afspiller Bink-videoer via FFmpeg-broen, men nogle spil kan opleve problemer.\nGuest bruger spilmotorens egen dekoder, som SharpEmu i øjeblikket kun understøtter delvist.\nSkip springer Bink-videoer over, hvilket kan gøre udviklingen nemmere.",
|
||||
"Options.Env.BinkPlayback.Host": "Host (FFmpeg)",
|
||||
"Options.Env.BinkPlayback.Guest": "Guest",
|
||||
"Options.Env.BinkPlayback.Skip": "Spring over",
|
||||
"_languageName": "Dansk",
|
||||
|
||||
"Page.Library": "Bibliotek",
|
||||
|
|
@ -90,6 +95,17 @@
|
|||
"Launch.Idle": "Inaktiv",
|
||||
"Launch.Console": "≡ Konsol",
|
||||
"Launch.Launch": "▶ Start",
|
||||
"Launch.CustomEnv": "Start med brugerdefinerede miljøvariabler",
|
||||
"Launch.CustomEnv.Title": "Start med brugerdefinerede miljøvariabler",
|
||||
"Launch.CustomEnv.Desc": "Indtast én miljøvariabel pr. linje som NAVN=VÆRDI. Brugerdefinerede værdier tilsidesætter GUI- og spilspecifikke indstillinger med samme navn.",
|
||||
"Launch.CustomEnv.Documentation": "Vis udokumenterede miljøvariabler ↗",
|
||||
"Launch.CustomEnv.Placeholder": "SHARPEMU_EKSEMPEL=1",
|
||||
"Launch.CustomEnv.SaveGame": "Gem for spil",
|
||||
"Launch.CustomEnv.SaveGlobal": "Gem globalt",
|
||||
"Launch.CustomEnv.Play": "Spil",
|
||||
"Launch.CustomEnv.Invalid": "Ugyldig miljøvariabel: {0}",
|
||||
"Launch.CustomEnv.SavedGame": "Gemt for dette spil.",
|
||||
"Launch.CustomEnv.SavedGlobal": "Gemt globalt.",
|
||||
"Launch.Stop": "■ Stop",
|
||||
"Launch.Running": "Kører — {0}",
|
||||
"Launch.Stopping": "Stopper…",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"Options.Env.BinkPlayback.Label": "Bink-video taasesitus",
|
||||
"Options.Env.BinkPlayback.Desc": "Host esitab Bink-videoid FFmpegi silla kaudu, kuid mõnes mängus võib esineda probleeme.\nGuest kasutab mängumootori enda dekoodrit, mida SharpEmu praegu ainult osaliselt toetab.\nSkip jätab Bink-videod vahele, mis võib arendust lihtsustada.",
|
||||
"Options.Env.BinkPlayback.Host": "Host (FFmpeg)",
|
||||
"Options.Env.BinkPlayback.Guest": "Guest",
|
||||
"Options.Env.BinkPlayback.Skip": "Jäta vahele",
|
||||
"_languageName": "Eesti",
|
||||
|
||||
"Page.Library": "Teek",
|
||||
|
|
@ -142,6 +147,17 @@
|
|||
"Launch.Idle": "Ootel",
|
||||
"Launch.Console": "≡ Konsool",
|
||||
"Launch.Launch": "▶ Käivita",
|
||||
"Launch.CustomEnv": "Käivita kohandatud keskkonnamuutujatega",
|
||||
"Launch.CustomEnv.Title": "Käivita kohandatud keskkonnamuutujatega",
|
||||
"Launch.CustomEnv.Desc": "Sisesta üks keskkonnamuutuja rea kohta kujul NIMI=VÄÄRTUS. Kohandatud väärtused alistavad sama nimega GUI ja mängupõhised seaded.",
|
||||
"Launch.CustomEnv.Documentation": "Vaata dokumenteerimata keskkonnamuutujaid ↗",
|
||||
"Launch.CustomEnv.Placeholder": "SHARPEMU_NAIDE=1",
|
||||
"Launch.CustomEnv.SaveGame": "Salvesta mängule",
|
||||
"Launch.CustomEnv.SaveGlobal": "Salvesta globaalselt",
|
||||
"Launch.CustomEnv.Play": "Mängi",
|
||||
"Launch.CustomEnv.Invalid": "Vigane keskkonnamuutuja: {0}",
|
||||
"Launch.CustomEnv.SavedGame": "Selle mängu jaoks salvestatud.",
|
||||
"Launch.CustomEnv.SavedGlobal": "Globaalselt salvestatud.",
|
||||
"Launch.Stop": "■ Peata",
|
||||
"Launch.Running": "Käib — {0}",
|
||||
"Launch.Stopping": "Peatamine…",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"Options.Env.BinkPlayback.Label": "Bink video playback",
|
||||
"Options.Env.BinkPlayback.Desc": "Host plays Bink videos through the FFmpeg bridge, but some games may have issues.\nGuest uses the game engine's own decoder, which SharpEmu currently supports only partially.\nSkip skips Bink videos, which can make development easier.",
|
||||
"Options.Env.BinkPlayback.Host": "Host (FFmpeg)",
|
||||
"Options.Env.BinkPlayback.Guest": "Guest",
|
||||
"Options.Env.BinkPlayback.Skip": "Skip",
|
||||
"_languageName": "English",
|
||||
|
||||
"Page.Library": "Library",
|
||||
|
|
@ -142,6 +147,17 @@
|
|||
"Launch.Idle": "Idle",
|
||||
"Launch.Console": "≡ Console",
|
||||
"Launch.Launch": "▶ Launch",
|
||||
"Launch.CustomEnv": "Launch with custom env",
|
||||
"Launch.CustomEnv.Title": "Launch with custom env",
|
||||
"Launch.CustomEnv.Desc": "Enter environment variables one per line as NAME=VALUE. Custom values override matching GUI and per-game environment settings.",
|
||||
"Launch.CustomEnv.Documentation": "View undocumented environment variables ↗",
|
||||
"Launch.CustomEnv.Placeholder": "SHARPEMU_EXAMPLE=1",
|
||||
"Launch.CustomEnv.SaveGame": "Save for game",
|
||||
"Launch.CustomEnv.SaveGlobal": "Save globally",
|
||||
"Launch.CustomEnv.Play": "Play",
|
||||
"Launch.CustomEnv.Invalid": "Invalid environment variable: {0}",
|
||||
"Launch.CustomEnv.SavedGame": "Saved for this game.",
|
||||
"Launch.CustomEnv.SavedGlobal": "Saved globally.",
|
||||
"Launch.Stop": "■ Stop",
|
||||
"Launch.Running": "Running — {0}",
|
||||
"Launch.Stopping": "Stopping…",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"Options.Env.BinkPlayback.Label": "Reproducción de vídeo Bink",
|
||||
"Options.Env.BinkPlayback.Desc": "Host reproduce los vídeos Bink mediante el puente FFmpeg, aunque algunos juegos pueden presentar problemas.\nGuest usa el decodificador propio del motor del juego, que SharpEmu actualmente solo admite de forma parcial.\nSkip omite los vídeos Bink, lo que puede facilitar el desarrollo.",
|
||||
"Options.Env.BinkPlayback.Host": "Host (FFmpeg)",
|
||||
"Options.Env.BinkPlayback.Guest": "Guest",
|
||||
"Options.Env.BinkPlayback.Skip": "Omitir",
|
||||
"_languageName": "Español",
|
||||
|
||||
"Page.Library": "Biblioteca",
|
||||
|
|
@ -90,6 +95,17 @@
|
|||
"Launch.Idle": "Inactivo",
|
||||
"Launch.Console": "≡ Consola",
|
||||
"Launch.Launch": "▶ Iniciar",
|
||||
"Launch.CustomEnv": "Iniciar con variables de entorno personalizadas",
|
||||
"Launch.CustomEnv.Title": "Iniciar con variables de entorno personalizadas",
|
||||
"Launch.CustomEnv.Desc": "Introduce una variable de entorno por línea con el formato NOMBRE=VALOR. Los valores personalizados reemplazan los ajustes de la GUI y del juego con el mismo nombre.",
|
||||
"Launch.CustomEnv.Documentation": "Ver variables de entorno no documentadas ↗",
|
||||
"Launch.CustomEnv.Placeholder": "SHARPEMU_EJEMPLO=1",
|
||||
"Launch.CustomEnv.SaveGame": "Guardar para el juego",
|
||||
"Launch.CustomEnv.SaveGlobal": "Guardar globalmente",
|
||||
"Launch.CustomEnv.Play": "Jugar",
|
||||
"Launch.CustomEnv.Invalid": "Variable de entorno no válida: {0}",
|
||||
"Launch.CustomEnv.SavedGame": "Guardado para este juego.",
|
||||
"Launch.CustomEnv.SavedGlobal": "Guardado globalmente.",
|
||||
"Launch.Stop": "■ Detener",
|
||||
"Launch.Running": "En ejecución — {0}",
|
||||
"Launch.Stopping": "Deteniendo…",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"Options.Env.BinkPlayback.Label": "Lecture vidéo Bink",
|
||||
"Options.Env.BinkPlayback.Desc": "Host lit les vidéos Bink via le pont FFmpeg, mais certains jeux peuvent rencontrer des problèmes.\nGuest utilise le décodeur propre au moteur du jeu, que SharpEmu ne prend actuellement en charge que partiellement.\nSkip ignore les vidéos Bink, ce qui peut faciliter le développement.",
|
||||
"Options.Env.BinkPlayback.Host": "Host (FFmpeg)",
|
||||
"Options.Env.BinkPlayback.Guest": "Guest",
|
||||
"Options.Env.BinkPlayback.Skip": "Ignorer",
|
||||
"_languageName": "Français",
|
||||
|
||||
"Page.Library": "Bibliothèque",
|
||||
|
|
@ -104,6 +109,17 @@
|
|||
"Launch.Idle": "Inactif",
|
||||
"Launch.Console": "≡ Console",
|
||||
"Launch.Launch": "▶ Lancer",
|
||||
"Launch.CustomEnv": "Lancer avec des variables d'environnement personnalisées",
|
||||
"Launch.CustomEnv.Title": "Lancer avec des variables d'environnement personnalisées",
|
||||
"Launch.CustomEnv.Desc": "Saisissez une variable d'environnement par ligne au format NOM=VALEUR. Les valeurs personnalisées remplacent les réglages GUI et spécifiques au jeu portant le même nom.",
|
||||
"Launch.CustomEnv.Documentation": "Voir les variables d'environnement non documentées ↗",
|
||||
"Launch.CustomEnv.Placeholder": "SHARPEMU_EXEMPLE=1",
|
||||
"Launch.CustomEnv.SaveGame": "Enregistrer pour le jeu",
|
||||
"Launch.CustomEnv.SaveGlobal": "Enregistrer globalement",
|
||||
"Launch.CustomEnv.Play": "Jouer",
|
||||
"Launch.CustomEnv.Invalid": "Variable d'environnement invalide : {0}",
|
||||
"Launch.CustomEnv.SavedGame": "Enregistré pour ce jeu.",
|
||||
"Launch.CustomEnv.SavedGlobal": "Enregistré globalement.",
|
||||
"Launch.Stop": "■ Arrêter",
|
||||
"Launch.Running": "En cours d’exécution — {0}",
|
||||
"Launch.Stopping": "Arrêt en cours…",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"Options.Env.BinkPlayback.Label": "Bink videólejátszás",
|
||||
"Options.Env.BinkPlayback.Desc": "A Host az FFmpeg hídon keresztül játssza le a Bink videókat, de egyes játékoknál problémák jelentkezhetnek.\nA Guest a játékmotor saját dekóderét használja, amelyet a SharpEmu jelenleg csak részben támogat.\nA Skip kihagyja a Bink videókat, ami megkönnyítheti a fejlesztést.",
|
||||
"Options.Env.BinkPlayback.Host": "Host (FFmpeg)",
|
||||
"Options.Env.BinkPlayback.Guest": "Guest",
|
||||
"Options.Env.BinkPlayback.Skip": "Kihagyás",
|
||||
"_languageName": "Hungarian",
|
||||
|
||||
"Page.Library": "Könyvtár",
|
||||
|
|
@ -104,6 +109,17 @@
|
|||
"Launch.Idle": "Tétlen",
|
||||
"Launch.Console": "≡ Konzol",
|
||||
"Launch.Launch": "▶ Inditás",
|
||||
"Launch.CustomEnv": "Indítás egyéni környezeti változókkal",
|
||||
"Launch.CustomEnv.Title": "Indítás egyéni környezeti változókkal",
|
||||
"Launch.CustomEnv.Desc": "Soronként egy környezeti változót adj meg NÉV=ÉRTÉK formában. Az egyéni értékek felülírják az azonos nevű GUI- és játékspecifikus beállításokat.",
|
||||
"Launch.CustomEnv.Documentation": "Nem dokumentált környezeti változók megtekintése ↗",
|
||||
"Launch.CustomEnv.Placeholder": "SHARPEMU_PELDA=1",
|
||||
"Launch.CustomEnv.SaveGame": "Mentés a játékhoz",
|
||||
"Launch.CustomEnv.SaveGlobal": "Globális mentés",
|
||||
"Launch.CustomEnv.Play": "Játék",
|
||||
"Launch.CustomEnv.Invalid": "Érvénytelen környezeti változó: {0}",
|
||||
"Launch.CustomEnv.SavedGame": "Mentve ehhez a játékhoz.",
|
||||
"Launch.CustomEnv.SavedGlobal": "Globálisan mentve.",
|
||||
"Launch.Stop": "■ Leállítás",
|
||||
"Launch.Running": "Fut — {0}",
|
||||
"Launch.Stopping": "Leállítás…",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"Options.Env.BinkPlayback.Label": "Riproduzione video Bink",
|
||||
"Options.Env.BinkPlayback.Desc": "Host riproduce i video Bink tramite il bridge FFmpeg, ma alcuni giochi potrebbero avere problemi.\nGuest usa il decoder del motore di gioco, che SharpEmu attualmente supporta solo in parte.\nSkip salta i video Bink, facilitando lo sviluppo.",
|
||||
"Options.Env.BinkPlayback.Host": "Host (FFmpeg)",
|
||||
"Options.Env.BinkPlayback.Guest": "Guest",
|
||||
"Options.Env.BinkPlayback.Skip": "Salta",
|
||||
"_languageName": "Italiano",
|
||||
|
||||
"Page.Library": "Libreria",
|
||||
|
|
@ -93,6 +98,17 @@
|
|||
"Launch.Idle": "Inattivo",
|
||||
"Launch.Console": "≡ Console",
|
||||
"Launch.Launch": "▶ Avvia",
|
||||
"Launch.CustomEnv": "Avvia con variabili d'ambiente personalizzate",
|
||||
"Launch.CustomEnv.Title": "Avvia con variabili d'ambiente personalizzate",
|
||||
"Launch.CustomEnv.Desc": "Inserisci una variabile d'ambiente per riga nel formato NOME=VALORE. I valori personalizzati sostituiscono le impostazioni GUI e specifiche del gioco con lo stesso nome.",
|
||||
"Launch.CustomEnv.Documentation": "Visualizza le variabili d'ambiente non documentate ↗",
|
||||
"Launch.CustomEnv.Placeholder": "SHARPEMU_ESEMPIO=1",
|
||||
"Launch.CustomEnv.SaveGame": "Salva per il gioco",
|
||||
"Launch.CustomEnv.SaveGlobal": "Salva globalmente",
|
||||
"Launch.CustomEnv.Play": "Gioca",
|
||||
"Launch.CustomEnv.Invalid": "Variabile d'ambiente non valida: {0}",
|
||||
"Launch.CustomEnv.SavedGame": "Salvato per questo gioco.",
|
||||
"Launch.CustomEnv.SavedGlobal": "Salvato globalmente.",
|
||||
"Launch.Stop": "■ Ferma",
|
||||
"Launch.Running": "In esecuzione — {0}",
|
||||
"Launch.Stopping": "Arresto in corso…",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"Options.Env.BinkPlayback.Label": "Bink 動画再生",
|
||||
"Options.Env.BinkPlayback.Desc": "Host は FFmpeg ブリッジ経由で Bink 動画を再生しますが、一部のゲームで問題が発生する場合があります。\nGuest はゲームエンジン独自のデコーダーを使用しますが、SharpEmu は現在これを部分的にしかサポートしていません。\nSkip は Bink 動画をスキップし、開発を容易にする場合があります。",
|
||||
"Options.Env.BinkPlayback.Host": "Host (FFmpeg)",
|
||||
"Options.Env.BinkPlayback.Guest": "Guest",
|
||||
"Options.Env.BinkPlayback.Skip": "スキップ",
|
||||
"_languageName": "日本語",
|
||||
|
||||
"Page.Library": "ライブラリ",
|
||||
|
|
@ -90,6 +95,17 @@
|
|||
"Launch.Idle": "待機中",
|
||||
"Launch.Console": "≡ コンソール",
|
||||
"Launch.Launch": "▶ 起動",
|
||||
"Launch.CustomEnv": "カスタム環境変数で起動",
|
||||
"Launch.CustomEnv.Title": "カスタム環境変数で起動",
|
||||
"Launch.CustomEnv.Desc": "環境変数を 1 行に 1 つ、NAME=VALUE 形式で入力します。カスタム値は、同名の GUI およびゲーム固有の環境設定を上書きします。",
|
||||
"Launch.CustomEnv.Documentation": "未文書化の環境変数を表示 ↗",
|
||||
"Launch.CustomEnv.Placeholder": "SHARPEMU_EXAMPLE=1",
|
||||
"Launch.CustomEnv.SaveGame": "ゲーム用に保存",
|
||||
"Launch.CustomEnv.SaveGlobal": "全体設定として保存",
|
||||
"Launch.CustomEnv.Play": "プレイ",
|
||||
"Launch.CustomEnv.Invalid": "無効な環境変数: {0}",
|
||||
"Launch.CustomEnv.SavedGame": "このゲーム用に保存しました。",
|
||||
"Launch.CustomEnv.SavedGlobal": "全体設定として保存しました。",
|
||||
"Launch.Stop": "■ 停止",
|
||||
"Launch.Running": "実行中 — {0}",
|
||||
"Launch.Stopping": "停止中…",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"Options.Env.BinkPlayback.Label": "Bink 비디오 재생",
|
||||
"Options.Env.BinkPlayback.Desc": "Host는 FFmpeg 브리지를 통해 Bink 비디오를 재생하지만 일부 게임에서 문제가 발생할 수 있습니다.\nGuest는 게임 엔진 자체 디코더를 사용하며, SharpEmu는 현재 이를 부분적으로만 지원합니다.\nSkip은 Bink 비디오를 건너뛰어 개발을 더 쉽게 할 수 있습니다.",
|
||||
"Options.Env.BinkPlayback.Host": "Host (FFmpeg)",
|
||||
"Options.Env.BinkPlayback.Guest": "Guest",
|
||||
"Options.Env.BinkPlayback.Skip": "건너뛰기",
|
||||
"_languageName": "한국어",
|
||||
|
||||
"Page.Library": "라이브러리",
|
||||
|
|
@ -90,6 +95,17 @@
|
|||
"Launch.Idle": "대기 중",
|
||||
"Launch.Console": "≡ 콘솔",
|
||||
"Launch.Launch": "▶ 실행",
|
||||
"Launch.CustomEnv": "사용자 지정 환경 변수로 실행",
|
||||
"Launch.CustomEnv.Title": "사용자 지정 환경 변수로 실행",
|
||||
"Launch.CustomEnv.Desc": "환경 변수를 NAME=VALUE 형식으로 한 줄에 하나씩 입력하세요. 사용자 지정 값은 이름이 같은 GUI 및 게임별 환경 설정을 덮어씁니다.",
|
||||
"Launch.CustomEnv.Documentation": "문서화되지 않은 환경 변수 보기 ↗",
|
||||
"Launch.CustomEnv.Placeholder": "SHARPEMU_EXAMPLE=1",
|
||||
"Launch.CustomEnv.SaveGame": "게임용으로 저장",
|
||||
"Launch.CustomEnv.SaveGlobal": "전역으로 저장",
|
||||
"Launch.CustomEnv.Play": "플레이",
|
||||
"Launch.CustomEnv.Invalid": "잘못된 환경 변수: {0}",
|
||||
"Launch.CustomEnv.SavedGame": "이 게임용으로 저장했습니다.",
|
||||
"Launch.CustomEnv.SavedGlobal": "전역으로 저장했습니다.",
|
||||
"Launch.Stop": "■ 중지",
|
||||
"Launch.Running": "실행 중 — {0}",
|
||||
"Launch.Stopping": "중지 중…",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"Options.Env.BinkPlayback.Label": "Bink-video afspelen",
|
||||
"Options.Env.BinkPlayback.Desc": "Host speelt Bink-video's af via de FFmpeg-brug, maar sommige games kunnen problemen hebben.\nGuest gebruikt de eigen decoder van de game-engine, die SharpEmu momenteel slechts gedeeltelijk ondersteunt.\nSkip slaat Bink-video's over, wat de ontwikkeling kan vergemakkelijken.",
|
||||
"Options.Env.BinkPlayback.Host": "Host (FFmpeg)",
|
||||
"Options.Env.BinkPlayback.Guest": "Guest",
|
||||
"Options.Env.BinkPlayback.Skip": "Overslaan",
|
||||
"_languageName": "Nederlands",
|
||||
|
||||
"Page.Library": "Bibliotheek",
|
||||
|
|
@ -90,6 +95,17 @@
|
|||
"Launch.Idle": "Inactief",
|
||||
"Launch.Console": "≡ Console",
|
||||
"Launch.Launch": "▶ Starten",
|
||||
"Launch.CustomEnv": "Starten met aangepaste omgevingsvariabelen",
|
||||
"Launch.CustomEnv.Title": "Starten met aangepaste omgevingsvariabelen",
|
||||
"Launch.CustomEnv.Desc": "Voer per regel één omgevingsvariabele in als NAAM=WAARDE. Aangepaste waarden overschrijven GUI- en spelspecifieke instellingen met dezelfde naam.",
|
||||
"Launch.CustomEnv.Documentation": "Ongedocumenteerde omgevingsvariabelen bekijken ↗",
|
||||
"Launch.CustomEnv.Placeholder": "SHARPEMU_VOORBEELD=1",
|
||||
"Launch.CustomEnv.SaveGame": "Opslaan voor spel",
|
||||
"Launch.CustomEnv.SaveGlobal": "Globaal opslaan",
|
||||
"Launch.CustomEnv.Play": "Spelen",
|
||||
"Launch.CustomEnv.Invalid": "Ongeldige omgevingsvariabele: {0}",
|
||||
"Launch.CustomEnv.SavedGame": "Opgeslagen voor dit spel.",
|
||||
"Launch.CustomEnv.SavedGlobal": "Globaal opgeslagen.",
|
||||
"Launch.Stop": "■ Stoppen",
|
||||
"Launch.Running": "Actief — {0}",
|
||||
"Launch.Stopping": "Stoppen…",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"Options.Env.BinkPlayback.Label": "Odtwarzanie wideo Bink",
|
||||
"Options.Env.BinkPlayback.Desc": "Host odtwarza filmy Bink przez most FFmpeg, ale w niektórych grach mogą wystąpić problemy.\nGuest używa dekodera silnika gry, który SharpEmu obecnie obsługuje tylko częściowo.\nSkip pomija filmy Bink, co może ułatwić rozwój.",
|
||||
"Options.Env.BinkPlayback.Host": "Host (FFmpeg)",
|
||||
"Options.Env.BinkPlayback.Guest": "Guest",
|
||||
"Options.Env.BinkPlayback.Skip": "Pomiń",
|
||||
"_languageName": "Polski",
|
||||
|
||||
"Page.Library": "Biblioteka",
|
||||
|
|
@ -142,6 +147,17 @@
|
|||
"Launch.Idle": "Bezczynny",
|
||||
"Launch.Console": "≡ Konsola",
|
||||
"Launch.Launch": "▶ Uruchom",
|
||||
"Launch.CustomEnv": "Uruchom z własnymi zmiennymi środowiskowymi",
|
||||
"Launch.CustomEnv.Title": "Uruchom z własnymi zmiennymi środowiskowymi",
|
||||
"Launch.CustomEnv.Desc": "Wpisz po jednej zmiennej środowiskowej w wierszu w formacie NAZWA=WARTOŚĆ. Własne wartości zastępują ustawienia GUI i ustawienia gry o tej samej nazwie.",
|
||||
"Launch.CustomEnv.Documentation": "Wyświetl nieudokumentowane zmienne środowiskowe ↗",
|
||||
"Launch.CustomEnv.Placeholder": "SHARPEMU_PRZYKLAD=1",
|
||||
"Launch.CustomEnv.SaveGame": "Zapisz dla gry",
|
||||
"Launch.CustomEnv.SaveGlobal": "Zapisz globalnie",
|
||||
"Launch.CustomEnv.Play": "Graj",
|
||||
"Launch.CustomEnv.Invalid": "Nieprawidłowa zmienna środowiskowa: {0}",
|
||||
"Launch.CustomEnv.SavedGame": "Zapisano dla tej gry.",
|
||||
"Launch.CustomEnv.SavedGlobal": "Zapisano globalnie.",
|
||||
"Launch.Stop": "■ Zatrzymaj",
|
||||
"Launch.Running": "Działa — {0}",
|
||||
"Launch.Stopping": "Zatrzymywanie…",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"Options.Env.BinkPlayback.Label": "Reprodução de vídeo Bink",
|
||||
"Options.Env.BinkPlayback.Desc": "Host reproduz vídeos Bink pela ponte FFmpeg, mas alguns jogos podem apresentar problemas.\nGuest usa o descodificador do próprio motor do jogo, que o SharpEmu atualmente suporta apenas parcialmente.\nSkip ignora os vídeos Bink, o que pode facilitar o desenvolvimento.",
|
||||
"Options.Env.BinkPlayback.Host": "Host (FFmpeg)",
|
||||
"Options.Env.BinkPlayback.Guest": "Guest",
|
||||
"Options.Env.BinkPlayback.Skip": "Ignorar",
|
||||
"_languageName": "Português (Portugal)",
|
||||
|
||||
"Page.Library": "Biblioteca",
|
||||
|
|
@ -104,6 +109,17 @@
|
|||
"Launch.Idle": "Inativo",
|
||||
"Launch.Console": "≡ Consola",
|
||||
"Launch.Launch": "▶ Iniciar",
|
||||
"Launch.CustomEnv": "Iniciar com variáveis de ambiente personalizadas",
|
||||
"Launch.CustomEnv.Title": "Iniciar com variáveis de ambiente personalizadas",
|
||||
"Launch.CustomEnv.Desc": "Introduza uma variável de ambiente por linha no formato NOME=VALOR. Os valores personalizados substituem as definições da GUI e específicas do jogo com o mesmo nome.",
|
||||
"Launch.CustomEnv.Documentation": "Ver variáveis de ambiente não documentadas ↗",
|
||||
"Launch.CustomEnv.Placeholder": "SHARPEMU_EXEMPLO=1",
|
||||
"Launch.CustomEnv.SaveGame": "Guardar para o jogo",
|
||||
"Launch.CustomEnv.SaveGlobal": "Guardar globalmente",
|
||||
"Launch.CustomEnv.Play": "Jogar",
|
||||
"Launch.CustomEnv.Invalid": "Variável de ambiente inválida: {0}",
|
||||
"Launch.CustomEnv.SavedGame": "Guardado para este jogo.",
|
||||
"Launch.CustomEnv.SavedGlobal": "Guardado globalmente.",
|
||||
"Launch.Stop": "■ Parar",
|
||||
"Launch.Running": "Em execução — {0}",
|
||||
"Launch.Stopping": "A parar…",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"Options.Env.BinkPlayback.Label": "Воспроизведение видео Bink",
|
||||
"Options.Env.BinkPlayback.Desc": "Host воспроизводит видео Bink через мост FFmpeg, однако в некоторых играх могут возникать проблемы.\nGuest использует собственный декодер игрового движка, который SharpEmu сейчас поддерживает лишь частично.\nSkip пропускает видео Bink, что может упростить разработку.",
|
||||
"Options.Env.BinkPlayback.Host": "Host (FFmpeg)",
|
||||
"Options.Env.BinkPlayback.Guest": "Guest",
|
||||
"Options.Env.BinkPlayback.Skip": "Пропустить",
|
||||
"_languageName": "Русский",
|
||||
|
||||
"Page.Library": "Библиотека",
|
||||
|
|
@ -140,6 +145,17 @@
|
|||
"Launch.Idle": "Ожидание",
|
||||
"Launch.Console": "≡ Консоль",
|
||||
"Launch.Launch": "▶ Запустить",
|
||||
"Launch.CustomEnv": "Запустить с пользовательскими переменными среды",
|
||||
"Launch.CustomEnv.Title": "Запустить с пользовательскими переменными среды",
|
||||
"Launch.CustomEnv.Desc": "Введите по одной переменной среды на строку в формате ИМЯ=ЗНАЧЕНИЕ. Пользовательские значения переопределяют одноимённые настройки GUI и игры.",
|
||||
"Launch.CustomEnv.Documentation": "Показать недокументированные переменные среды ↗",
|
||||
"Launch.CustomEnv.Placeholder": "SHARPEMU_PRIMER=1",
|
||||
"Launch.CustomEnv.SaveGame": "Сохранить для игры",
|
||||
"Launch.CustomEnv.SaveGlobal": "Сохранить глобально",
|
||||
"Launch.CustomEnv.Play": "Играть",
|
||||
"Launch.CustomEnv.Invalid": "Недопустимая переменная среды: {0}",
|
||||
"Launch.CustomEnv.SavedGame": "Сохранено для этой игры.",
|
||||
"Launch.CustomEnv.SavedGlobal": "Сохранено глобально.",
|
||||
"Launch.Stop": "■ Остановить",
|
||||
"Launch.Running": "Запущено - {0}",
|
||||
"Launch.Stopping": "Остановка…",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"Options.Env.BinkPlayback.Label": "Bink video oynatma",
|
||||
"Options.Env.BinkPlayback.Desc": "Host, Bink videolarını FFmpeg köprüsüyle oynatır ancak bazı oyunlarda sorunlarla karşılaşabilir.\nGuest, oyun motorunun kendi kod çözücüsünü kullanır ancak SharpEmu bunu şu anda yalnızca kısmen desteklemektedir.\nSkip, Bink videolarını atlar; bu, geliştirmeyi kolaylaştırabilir.",
|
||||
"Options.Env.BinkPlayback.Host": "Host (FFmpeg)",
|
||||
"Options.Env.BinkPlayback.Guest": "Guest",
|
||||
"Options.Env.BinkPlayback.Skip": "Atla",
|
||||
"_languageName": "Türkçe",
|
||||
|
||||
"Page.Library": "Kütüphane",
|
||||
|
|
@ -108,6 +113,17 @@
|
|||
"Launch.Idle": "Boşta",
|
||||
"Launch.Console": "≡ Konsol",
|
||||
"Launch.Launch": "▶ Başlat",
|
||||
"Launch.CustomEnv": "Özel env ile başlat",
|
||||
"Launch.CustomEnv.Title": "Özel env ile başlat",
|
||||
"Launch.CustomEnv.Desc": "Ortam değişkenlerini NAME=VALUE biçiminde her satıra bir tane yazın. Özel değerler, aynı isimdeki GUI ve oyuna özel ortam ayarlarını geçersiz kılar.",
|
||||
"Launch.CustomEnv.Documentation": "Belgelenmemiş ortam değişkenlerini görüntüle ↗",
|
||||
"Launch.CustomEnv.Placeholder": "SHARPEMU_ORNEK=1",
|
||||
"Launch.CustomEnv.SaveGame": "Oyun için kaydet",
|
||||
"Launch.CustomEnv.SaveGlobal": "Genel olarak kaydet",
|
||||
"Launch.CustomEnv.Play": "Oyna",
|
||||
"Launch.CustomEnv.Invalid": "Geçersiz ortam değişkeni: {0}",
|
||||
"Launch.CustomEnv.SavedGame": "Bu oyun için kaydedildi.",
|
||||
"Launch.CustomEnv.SavedGlobal": "Genel olarak kaydedildi.",
|
||||
"Launch.Stop": "■ Durdur",
|
||||
"Launch.Running": "Çalışıyor — {0}",
|
||||
"Launch.Stopping": "Durduruluyor…",
|
||||
|
|
|
|||
|
|
@ -273,6 +273,7 @@ public partial class MainWindow
|
|||
VSync = GameVSyncToggle.IsChecked == true,
|
||||
HdrMode = SelectedComboText(GameHdrModeBox, "Auto"),
|
||||
EnvironmentToggles = BuildGameEnvironmentEntries(),
|
||||
CustomEnvironmentVariables = PerGameSettings.Load(_gameSettingsTitleId)?.CustomEnvironmentVariables,
|
||||
};
|
||||
settings.RemoveInheritedValues(_settings);
|
||||
settings.Save(_gameSettingsTitleId);
|
||||
|
|
|
|||
|
|
@ -339,6 +339,18 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
|||
Classes="playButton"
|
||||
Content="Launch"
|
||||
IsEnabled="False" />
|
||||
<TextBlock Text="|"
|
||||
Foreground="{StaticResource MutedBrush}"
|
||||
FontSize="22"
|
||||
VerticalAlignment="Center"
|
||||
Margin="-4,0" />
|
||||
<Button x:Name="LaunchCustomEnvButton"
|
||||
Classes="optionsCircle"
|
||||
ToolTip.Tip="{Binding [Launch.CustomEnv], Source={x:Static local:Localization.Instance}, x:CompileBindings=False}"
|
||||
AutomationProperties.Name="{Binding [Launch.CustomEnv], Source={x:Static local:Localization.Instance}, x:CompileBindings=False}">
|
||||
<TextBlock Classes="materialSymbol"
|
||||
Text="keyboard_arrow_down" />
|
||||
</Button>
|
||||
<Button x:Name="GameSettingsButton"
|
||||
Classes="optionsCircle"
|
||||
ToolTip.Tip="{Binding [Library.Context.GameSettings],
|
||||
|
|
@ -1481,6 +1493,16 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
|||
<Border Classes="optionsGroupDivider" />
|
||||
|
||||
<TextBlock Classes="optionsGroupHeader" Text="{Binding [Options.Env.Group.General], Source={x:Static local:Localization.Instance}}" />
|
||||
<local:SettingRow x:Name="BinkPlaybackRow"
|
||||
Classes="optionRow"
|
||||
Label="{Binding [Options.Env.BinkPlayback.Label], Source={x:Static local:Localization.Instance}}"
|
||||
Description="{Binding [Options.Env.BinkPlayback.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ComboBox x:Name="BinkPlaybackBox"
|
||||
Classes="optionValue"
|
||||
ToolTip.Tip="{Binding [Options.Env.BinkPlayback.Desc], Source={x:Static local:Localization.Instance}}"
|
||||
ItemTemplate="{StaticResource LocalizedChoiceTemplate}" />
|
||||
</local:SettingRow>
|
||||
|
||||
<local:SettingRow x:Name="EnvBthidRow" Classes="optionRow" LabelFontFamily="Consolas,monospace" Label="SHARPEMU_BTHID_UNAVAILABLE"
|
||||
Description="{Binding [Options.Env.Bthid.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ToggleSwitch x:Name="EnvBthidToggle" Classes="optionToggle" />
|
||||
|
|
|
|||
|
|
@ -83,6 +83,12 @@ public partial class MainWindow : Window
|
|||
LocalizedChoice.FromKey("On", "Common.On"),
|
||||
LocalizedChoice.FromKey("Off", "Common.Off"),
|
||||
];
|
||||
private readonly LocalizedChoice[] _binkPlaybackChoices =
|
||||
[
|
||||
LocalizedChoice.FromKey("Host", "Options.Env.BinkPlayback.Host"),
|
||||
LocalizedChoice.FromKey("Guest", "Options.Env.BinkPlayback.Guest"),
|
||||
LocalizedChoice.FromKey("Skip", "Options.Env.BinkPlayback.Skip"),
|
||||
];
|
||||
private readonly List<GameEntry> _allGames = new();
|
||||
private readonly ObservableCollection<GameEntry> _visibleGames = new();
|
||||
private readonly LibraryTileCollection _libraryTiles;
|
||||
|
|
@ -216,6 +222,7 @@ public partial class MainWindow : Window
|
|||
LaunchSelected();
|
||||
}
|
||||
};
|
||||
LaunchCustomEnvButton.Click += async (_, _) => await OpenCustomEnvironmentDialogAsync();
|
||||
ClearLogButton.Click += (_, _) => { _consoleLines.Clear(); _allConsoleLines.Clear(); };
|
||||
CopyLogButton.Click += async (_, _) => await CopyConsoleAsync();
|
||||
DetachConsoleButton.Click += (_, _) => ShowConsoleWindow();
|
||||
|
|
@ -276,6 +283,8 @@ public partial class MainWindow : Window
|
|||
SetEnvironmentToggle("SHARPEMU_DISABLE_IMPORT_LOOP_GUARD", EnvLoopGuardToggle.IsChecked == true);
|
||||
EnvWritableApp0Toggle.IsCheckedChanged += (_, _) =>
|
||||
SetEnvironmentToggle("SHARPEMU_WRITABLE_APP0", EnvWritableApp0Toggle.IsChecked == true);
|
||||
BinkPlaybackBox.SelectionChanged += (_, _) =>
|
||||
_settings.BinkPlaybackMode = SelectedComboText(BinkPlaybackBox, "Host");
|
||||
EnvVkValidationToggle.IsCheckedChanged += (_, _) =>
|
||||
SetEnvironmentToggle("SHARPEMU_VK_VALIDATION", EnvVkValidationToggle.IsChecked == true);
|
||||
EnvDumpSpirvToggle.IsCheckedChanged += (_, _) =>
|
||||
|
|
@ -355,7 +364,7 @@ public partial class MainWindow : Window
|
|||
{
|
||||
Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName = "https://github.com/sharpemu/sharpemu",
|
||||
FileName = ProjectLinks.RepositoryUrl,
|
||||
UseShellExecute = true
|
||||
});
|
||||
};
|
||||
|
|
@ -378,8 +387,7 @@ public partial class MainWindow : Window
|
|||
|
||||
Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName =
|
||||
$"https://github.com/sharpemu/sharpemu/commit/{_latestCommitSha}",
|
||||
FileName = ProjectLinks.CommitUrl(_latestCommitSha),
|
||||
UseShellExecute = true
|
||||
});
|
||||
};
|
||||
|
|
@ -658,16 +666,13 @@ public partial class MainWindow : Window
|
|||
}
|
||||
private async Task LoadLatestCommitAsync()
|
||||
{
|
||||
const string apiUrl =
|
||||
"https://api.github.com/repos/sharpemu/sharpemu/commits/main";
|
||||
|
||||
_latestCommitSha = null;
|
||||
LatestCommitHashText.Content = "Loading…";
|
||||
LatestCommitHashText.IsEnabled = false;
|
||||
|
||||
try
|
||||
{
|
||||
using var response = await GithubHttpClient.GetAsync(apiUrl);
|
||||
using var response = await GithubHttpClient.GetAsync(ProjectLinks.LatestCommitApiUrl);
|
||||
var responseBody =
|
||||
(await response.Content.ReadAsStringAsync()).Trim();
|
||||
|
||||
|
|
@ -1168,6 +1173,7 @@ public partial class MainWindow : Window
|
|||
WindowModeBox.ItemsSource = _windowModeChoices;
|
||||
ScalingModeBox.ItemsSource = _scalingModeChoices;
|
||||
HdrModeBox.ItemsSource = _hdrModeChoices;
|
||||
BinkPlaybackBox.ItemsSource = _binkPlaybackChoices;
|
||||
}
|
||||
|
||||
private void RefreshLocalizedChoices()
|
||||
|
|
@ -1178,6 +1184,7 @@ public partial class MainWindow : Window
|
|||
RefreshChoices(_windowModeChoices);
|
||||
RefreshChoices(_scalingModeChoices);
|
||||
RefreshChoices(_hdrModeChoices);
|
||||
RefreshChoices(_binkPlaybackChoices);
|
||||
}
|
||||
|
||||
private static void RefreshChoices(IEnumerable<LocalizedChoice> choices)
|
||||
|
|
@ -1219,6 +1226,7 @@ public partial class MainWindow : Window
|
|||
EnvBthidToggle.IsChecked = _settings.EnvironmentToggles.Contains("SHARPEMU_BTHID_UNAVAILABLE");
|
||||
EnvLoopGuardToggle.IsChecked = _settings.EnvironmentToggles.Contains("SHARPEMU_DISABLE_IMPORT_LOOP_GUARD");
|
||||
EnvWritableApp0Toggle.IsChecked = _settings.EnvironmentToggles.Contains("SHARPEMU_WRITABLE_APP0");
|
||||
BinkPlaybackBox.SelectedIndex = ChoiceIndex(_settings.BinkPlaybackMode, "Host", "Guest", "Skip");
|
||||
EnvVkValidationToggle.IsChecked = _settings.EnvironmentToggles.Contains("SHARPEMU_VK_VALIDATION");
|
||||
EnvDumpSpirvToggle.IsChecked = _settings.EnvironmentToggles.Contains("SHARPEMU_DUMP_SPIRV");
|
||||
EnvLogDirectMemoryToggle.IsChecked = _settings.EnvironmentToggles.Contains("SHARPEMU_LOG_DIRECT_MEMORY");
|
||||
|
|
@ -1458,6 +1466,7 @@ public partial class MainWindow : Window
|
|||
}
|
||||
|
||||
private const string DefaultProfileEnvironmentName = "SHARPEMU_DEFAULT_PROFILE";
|
||||
private const string BinkModeEnvironmentName = "SHARPEMU_BINK_MODE";
|
||||
|
||||
private string SelectedLogLevel()
|
||||
{
|
||||
|
|
@ -2330,6 +2339,34 @@ public partial class MainWindow : Window
|
|||
}
|
||||
}
|
||||
|
||||
private async Task OpenCustomEnvironmentDialogAsync()
|
||||
{
|
||||
if (_isRunning || GameList.SelectedItem is not GameEntry game)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var perGame = PerGameSettings.Load(game.TitleId);
|
||||
var initialEntries = CustomEnvironmentVariables.Merge(
|
||||
GlobalCustomEnvironmentSettings.Load(),
|
||||
perGame?.CustomEnvironmentVariables);
|
||||
var dialog = new CustomEnvironmentDialog(game.TitleId, initialEntries);
|
||||
dialog.SaveGlobalRequested += entries => GlobalCustomEnvironmentSettings.Save(entries);
|
||||
dialog.SaveGameRequested += (titleId, entries) =>
|
||||
{
|
||||
var settings = PerGameSettings.Load(titleId) ?? new PerGameSettings();
|
||||
settings.CustomEnvironmentVariables = entries.Count == 0 ? null : entries.ToList();
|
||||
settings.RemoveInheritedValues(_settings);
|
||||
settings.Save(titleId);
|
||||
};
|
||||
|
||||
var customEntries = await dialog.ShowDialog<IReadOnlyList<string>?>(this);
|
||||
if (customEntries is not null && !_isRunning)
|
||||
{
|
||||
Launch(game.Path, game.Name, game.TitleId, customEntries);
|
||||
}
|
||||
}
|
||||
|
||||
private void LaunchSelected()
|
||||
{
|
||||
if (GameList.SelectedItem is GameEntry game)
|
||||
|
|
@ -2338,7 +2375,11 @@ public partial class MainWindow : Window
|
|||
}
|
||||
}
|
||||
|
||||
private void Launch(string ebootPath, string displayName, string? titleId = null)
|
||||
private void Launch(
|
||||
string ebootPath,
|
||||
string displayName,
|
||||
string? titleId = null,
|
||||
IReadOnlyList<string>? oneShotCustomEnvironment = null)
|
||||
{
|
||||
if (_isRunning)
|
||||
{
|
||||
|
|
@ -2349,7 +2390,12 @@ public partial class MainWindow : Window
|
|||
? _allGames.FirstOrDefault(game =>
|
||||
game.Path.Equals(ebootPath, GameLibraryPath.Comparison))?.TitleId
|
||||
: titleId;
|
||||
var effective = EffectiveLaunchSettings.Resolve(_settings, PerGameSettings.Load(resolvedTitleId));
|
||||
var perGame = PerGameSettings.Load(resolvedTitleId);
|
||||
var effective = EffectiveLaunchSettings.Resolve(_settings, perGame);
|
||||
var customEnvironment = CustomEnvironmentVariables.Merge(
|
||||
GlobalCustomEnvironmentSettings.Load(),
|
||||
perGame?.CustomEnvironmentVariables,
|
||||
oneShotCustomEnvironment);
|
||||
|
||||
_sndPreview.Stop();
|
||||
_consoleLines.Clear();
|
||||
|
|
@ -2395,11 +2441,33 @@ public partial class MainWindow : Window
|
|||
GuiSettings.NormalizeDefaultProfile(_settings.DefaultProfile));
|
||||
_appliedEnvironmentVariables.Add(DefaultProfileEnvironmentName);
|
||||
|
||||
Environment.SetEnvironmentVariable(
|
||||
BinkModeEnvironmentName,
|
||||
_settings.BinkPlaybackMode switch
|
||||
{
|
||||
"Guest" => "guest",
|
||||
"Skip" => "skip",
|
||||
_ => "native",
|
||||
});
|
||||
_appliedEnvironmentVariables.Add(BinkModeEnvironmentName);
|
||||
|
||||
Environment.SetEnvironmentVariable(
|
||||
"SHARPEMU_RENDER_SCALE",
|
||||
_settings.RenderResolutionScale.ToString(
|
||||
"0.###",
|
||||
System.Globalization.CultureInfo.InvariantCulture));
|
||||
_appliedEnvironmentVariables.Add("SHARPEMU_RENDER_SCALE");
|
||||
|
||||
foreach (var entry in customEnvironment)
|
||||
{
|
||||
if (!CustomEnvironmentVariables.TryParseEntry(entry, out var name, out var value))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Environment.SetEnvironmentVariable(name, value);
|
||||
_appliedEnvironmentVariables.Add(name);
|
||||
}
|
||||
|
||||
if (SharpEmuLog.TryParseLevel(effective.LogLevel, out var logLevel))
|
||||
{
|
||||
|
|
@ -2688,6 +2756,8 @@ public partial class MainWindow : Window
|
|||
LaunchButton.IsEnabled = GameList.SelectedItem is GameEntry;
|
||||
}
|
||||
|
||||
LaunchCustomEnvButton.IsEnabled = !_isRunning && GameList.SelectedItem is GameEntry;
|
||||
|
||||
GameSettingsButton.IsEnabled =
|
||||
GameList.SelectedItem is GameEntry game &&
|
||||
!string.IsNullOrWhiteSpace(game.TitleId);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ public sealed class PerGameSettings
|
|||
|
||||
public List<string>? EnvironmentToggles { get; set; }
|
||||
|
||||
public List<string>? CustomEnvironmentVariables { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public bool IsEmpty =>
|
||||
LogLevel is null &&
|
||||
|
|
@ -50,7 +52,8 @@ public sealed class PerGameSettings
|
|||
ScalingMode is null &&
|
||||
VSync is null &&
|
||||
HdrMode is null &&
|
||||
EnvironmentToggles is null;
|
||||
EnvironmentToggles is null &&
|
||||
CustomEnvironmentVariables is null;
|
||||
|
||||
public static string DirectoryPath =>
|
||||
Path.Combine(AppContext.BaseDirectory, "user", "custom_configs");
|
||||
|
|
@ -88,6 +91,12 @@ public sealed class PerGameSettings
|
|||
{
|
||||
settings.EnvironmentToggles = toggles.Where(entry => !string.IsNullOrEmpty(entry)).ToList();
|
||||
}
|
||||
if (settings?.CustomEnvironmentVariables is { } customEnvironmentVariables)
|
||||
{
|
||||
settings.CustomEnvironmentVariables = customEnvironmentVariables
|
||||
.Where(entry => !string.IsNullOrWhiteSpace(entry))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
|
@ -158,6 +167,7 @@ public sealed class PerGameSettings
|
|||
{
|
||||
EnvironmentToggles = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void Save(string titleId)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (C) 2026 SharpEmu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
namespace SharpEmu.GUI;
|
||||
|
||||
internal static class ProjectLinks
|
||||
{
|
||||
private const string RepositorySlug = "sharpemu/sharpemu";
|
||||
|
||||
public static string RepositoryUrl => $"https://github.com/{RepositorySlug}";
|
||||
|
||||
public static string LatestCommitApiUrl =>
|
||||
$"https://api.github.com/repos/{RepositorySlug}/commits/main";
|
||||
|
||||
public static string CommitUrl(string sha) => $"{RepositoryUrl}/commit/{sha}";
|
||||
|
||||
public static string DocumentUrl(string path) =>
|
||||
$"{RepositoryUrl}/blob/main/{path.TrimStart('/')}";
|
||||
}
|
||||
Loading…
Reference in New Issue