mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-30 14:39:42 +08:00
[GUI] Add live localization bindings and fill missing locales (#685)
This commit is contained in:
+246
-134
@@ -18,6 +18,14 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
Icon="avares://SharpEmu.GUI/Assets/SharpEmu.ico"
|
||||
KeyDown="OnKeyDown">
|
||||
|
||||
<Window.Resources>
|
||||
<DataTemplate x:Key="LocalizedChoiceTemplate" x:DataType="local:LocalizedChoice">
|
||||
<TextBlock Text="{Binding Label}"
|
||||
HorizontalAlignment="Left"
|
||||
TextAlignment="Left" />
|
||||
</DataTemplate>
|
||||
</Window.Resources>
|
||||
|
||||
<Grid x:Name="RootLayout" RowDefinitions="Auto,*,Auto">
|
||||
|
||||
<!-- Selected-game backdrop: key art behind the main content, dimmed by
|
||||
@@ -94,8 +102,12 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
<Border Classes="padHint" VerticalAlignment="Center">
|
||||
<TextBlock Text="LB" FontSize="11" FontWeight="Bold" Foreground="{StaticResource MutedBrush}" />
|
||||
</Border>
|
||||
<Button x:Name="LibraryTabButton" Classes="segment active" Content="Library" />
|
||||
<Button x:Name="OptionsTabButton" Classes="segment" Content="Options" />
|
||||
<Button x:Name="LibraryTabButton"
|
||||
Classes="segment active"
|
||||
Content="{Binding [Page.Library], Source={x:Static local:Localization.Instance}}" />
|
||||
<Button x:Name="OptionsTabButton"
|
||||
Classes="segment"
|
||||
Content="{Binding [Page.Options], Source={x:Static local:Localization.Instance}}" />
|
||||
<Border Classes="padHint" VerticalAlignment="Center">
|
||||
<TextBlock Text="RB" FontSize="11" FontWeight="Bold" Foreground="{StaticResource MutedBrush}" />
|
||||
</Border>
|
||||
@@ -103,9 +115,18 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
<StackPanel Grid.Column="2" x:Name="LibraryToolbar" Orientation="Horizontal" Spacing="8"
|
||||
VerticalAlignment="Center">
|
||||
<TextBox x:Name="SearchBox" PlaceholderText="Search library…" Width="240" VerticalAlignment="Center" />
|
||||
<Button x:Name="AddFolderButton" Classes="ghost" Content="+ Add folder" VerticalAlignment="Center" />
|
||||
<Button x:Name="OpenFileButton" Classes="ghost" Content="Open file…" VerticalAlignment="Center" />
|
||||
<TextBox x:Name="SearchBox"
|
||||
PlaceholderText="{Binding [Library.SearchWatermark], Source={x:Static local:Localization.Instance}}"
|
||||
Width="240"
|
||||
VerticalAlignment="Center" />
|
||||
<Button x:Name="AddFolderButton"
|
||||
Classes="ghost"
|
||||
Content="{Binding [Library.AddFolder], Source={x:Static local:Localization.Instance}}"
|
||||
VerticalAlignment="Center" />
|
||||
<Button x:Name="OpenFileButton"
|
||||
Classes="ghost"
|
||||
Content="{Binding [Library.OpenFile], Source={x:Static local:Localization.Instance}}"
|
||||
VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
@@ -119,39 +140,46 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
SelectionMode="Single" Padding="0">
|
||||
<ListBox.ContextMenu>
|
||||
<ContextMenu x:Name="GameContextMenu" Placement="Pointer">
|
||||
<MenuItem x:Name="CtxLaunch" Header="Launch" FontWeight="SemiBold">
|
||||
<MenuItem x:Name="CtxLaunch"
|
||||
Header="{Binding [Library.Context.Launch], Source={x:Static local:Localization.Instance}}"
|
||||
FontWeight="SemiBold">
|
||||
<MenuItem.Icon>
|
||||
<TextBlock Text="▶" FontSize="11" Foreground="{StaticResource AccentHoverBrush}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem x:Name="CtxOpenFolder" Header="Open game folder">
|
||||
<MenuItem x:Name="CtxOpenFolder"
|
||||
Header="{Binding [Library.Context.OpenFolder], Source={x:Static local:Localization.Instance}}">
|
||||
<MenuItem.Icon>
|
||||
<TextBlock Text="📂" FontSize="12" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem x:Name="CtxCopyPath" Header="Copy path">
|
||||
<MenuItem x:Name="CtxCopyPath"
|
||||
Header="{Binding [Library.Context.CopyPath], Source={x:Static local:Localization.Instance}}">
|
||||
<MenuItem.Icon>
|
||||
<TextBlock Text="⧉" FontSize="13" Foreground="{StaticResource MutedBrush}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem x:Name="CtxCopyTitleId" Header="Copy title ID">
|
||||
<MenuItem x:Name="CtxCopyTitleId"
|
||||
Header="{Binding [Library.Context.CopyTitleId], Source={x:Static local:Localization.Instance}}">
|
||||
<MenuItem.Icon>
|
||||
<TextBlock Text="⧉" FontSize="13" Foreground="{StaticResource MutedBrush}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem x:Name="CtxGameSettings" Header="Game settings…">
|
||||
<MenuItem x:Name="CtxGameSettings"
|
||||
Header="{Binding [Library.Context.GameSettings], Source={x:Static local:Localization.Instance}}">
|
||||
<MenuItem.Icon>
|
||||
<TextBlock Text="⚙" FontSize="13" Foreground="{StaticResource MutedBrush}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem x:Name="CtxRemove" Header="Remove from library"
|
||||
<MenuItem x:Name="CtxRemove"
|
||||
Header="{Binding [Library.Context.Remove], Source={x:Static local:Localization.Instance}}"
|
||||
Foreground="{StaticResource DangerHoverBrush}">
|
||||
<MenuItem.Icon>
|
||||
<TextBlock Text="✕" FontSize="12" Foreground="{StaticResource DangerHoverBrush}"
|
||||
@@ -196,7 +224,8 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
HorizontalAlignment="Center" />
|
||||
<TextBlock x:Name="EmptyStateHint" Text="Add a folder containing your games to get started."
|
||||
FontSize="13" Foreground="{StaticResource MutedBrush}" HorizontalAlignment="Center" />
|
||||
<Button x:Name="EmptyAddFolderButton" Classes="accent" Content="+ Add game folder"
|
||||
<Button x:Name="EmptyAddFolderButton" Classes="accent"
|
||||
Content="{Binding [Library.Empty.AddFolder], Source={x:Static local:Localization.Instance}}"
|
||||
HorizontalAlignment="Center" Margin="0,8,0,0" />
|
||||
</StackPanel>
|
||||
|
||||
@@ -206,7 +235,9 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
<StackPanel x:Name="LoadingState" Spacing="14" HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
IsVisible="False">
|
||||
<ProgressBar IsIndeterminate="True" Width="180" Height="3" />
|
||||
<TextBlock x:Name="LoadingStateText" Text="Loading library…" FontSize="13"
|
||||
<TextBlock x:Name="LoadingStateText"
|
||||
Text="{Binding [Library.Loading], Source={x:Static local:Localization.Instance}}"
|
||||
FontSize="13"
|
||||
Foreground="{StaticResource MutedBrush}" HorizontalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</Panel>
|
||||
@@ -216,25 +247,32 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
language used by the console panel and launch bar below. -->
|
||||
<Grid x:Name="OptionsPage" IsVisible="False">
|
||||
<TabControl>
|
||||
<TabItem x:Name="GeneralTabItem" Header="General" FontSize="15">
|
||||
<TabItem x:Name="GeneralTabItem"
|
||||
Header="{Binding [Options.General], Source={x:Static local:Localization.Instance}}"
|
||||
FontSize="15">
|
||||
<ScrollViewer>
|
||||
<StackPanel Margin="0,14,0,16" Spacing="16" MaxWidth="1280" HorizontalAlignment="Left">
|
||||
|
||||
<Border Classes="card">
|
||||
<StackPanel Spacing="14">
|
||||
<TextBlock x:Name="EmulationSectionTitle" Classes="sectionTitle" Text="EMULATION" />
|
||||
<TextBlock x:Name="EmulationSectionTitle" Classes="sectionTitle"
|
||||
Text="{Binding [Options.Section.Emulation], Source={x:Static local:Localization.Instance}}" />
|
||||
|
||||
<local:SettingRow x:Name="CpuEngineRow" Label="CPU engine"
|
||||
Description="Execution engine used to run game code.">
|
||||
<ComboBox x:Name="CpuEngineBox" Width="160" SelectedIndex="0"
|
||||
VerticalAlignment="Center" CornerRadius="8">
|
||||
<ComboBoxItem x:Name="CpuEngineNativeItem" Content="Native" />
|
||||
</ComboBox>
|
||||
<local:SettingRow x:Name="CpuEngineRow"
|
||||
Label="{Binding [Options.CpuEngine.Label], Source={x:Static local:Localization.Instance}}"
|
||||
Description="{Binding [Options.CpuEngine.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ComboBox x:Name="CpuEngineBox" Width="160"
|
||||
ItemTemplate="{StaticResource LocalizedChoiceTemplate}"
|
||||
HorizontalContentAlignment="Left"
|
||||
VerticalAlignment="Center" CornerRadius="8" />
|
||||
</local:SettingRow>
|
||||
|
||||
<local:SettingRow x:Name="StrictRow" Label="Strict dynlib resolution"
|
||||
Description="Fail the launch when an imported symbol cannot be resolved.">
|
||||
<ToggleSwitch x:Name="StrictToggle" OnContent="On" OffContent="Off"
|
||||
<local:SettingRow x:Name="StrictRow"
|
||||
Label="{Binding [Options.Strict.Label], Source={x:Static local:Localization.Instance}}"
|
||||
Description="{Binding [Options.Strict.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ToggleSwitch x:Name="StrictToggle"
|
||||
OnContent="{Binding [Common.On], Source={x:Static local:Localization.Instance}}"
|
||||
OffContent="{Binding [Common.Off], Source={x:Static local:Localization.Instance}}"
|
||||
VerticalAlignment="Center" />
|
||||
</local:SettingRow>
|
||||
</StackPanel>
|
||||
@@ -242,43 +280,49 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
<Border Classes="card">
|
||||
<StackPanel Spacing="14">
|
||||
<TextBlock x:Name="LoggingSectionTitle" Classes="sectionTitle" Text="LOGGING" />
|
||||
<TextBlock x:Name="LoggingSectionTitle" Classes="sectionTitle"
|
||||
Text="{Binding [Options.Section.Logging], Source={x:Static local:Localization.Instance}}" />
|
||||
|
||||
<local:SettingRow x:Name="LogLevelRow" Label="Log level"
|
||||
Description="Verbosity of the emulator console output.">
|
||||
<ComboBox x:Name="LogLevelBox" Width="160" SelectedIndex="2"
|
||||
VerticalAlignment="Center" CornerRadius="8">
|
||||
<ComboBoxItem x:Name="LogLevelTraceItem" Content="Trace" />
|
||||
<ComboBoxItem x:Name="LogLevelDebugItem" Content="Debug" />
|
||||
<ComboBoxItem x:Name="LogLevelInfoItem" Content="Info" />
|
||||
<ComboBoxItem x:Name="LogLevelWarningItem" Content="Warning" />
|
||||
<ComboBoxItem x:Name="LogLevelErrorItem" Content="Error" />
|
||||
<ComboBoxItem x:Name="LogLevelCriticalItem" Content="Critical" />
|
||||
</ComboBox>
|
||||
<local:SettingRow x:Name="LogLevelRow"
|
||||
Label="{Binding [Options.LogLevel.Label], Source={x:Static local:Localization.Instance}}"
|
||||
Description="{Binding [Options.LogLevel.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ComboBox x:Name="LogLevelBox" Width="160"
|
||||
ItemTemplate="{StaticResource LocalizedChoiceTemplate}"
|
||||
HorizontalContentAlignment="Left"
|
||||
VerticalAlignment="Center" CornerRadius="8" />
|
||||
</local:SettingRow>
|
||||
|
||||
<local:SettingRow x:Name="TraceImportsRow" Label="Import trace limit"
|
||||
Description="Trace the first N imports per module (0 = off).">
|
||||
<local:SettingRow x:Name="TraceImportsRow"
|
||||
Label="{Binding [Options.TraceImports.Label], Source={x:Static local:Localization.Instance}}"
|
||||
Description="{Binding [Options.TraceImports.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<NumericUpDown x:Name="TraceImportsBox" Width="160" Minimum="0"
|
||||
Maximum="4096" Increment="16" Value="0" FormatString="0"
|
||||
VerticalAlignment="Center" CornerRadius="8" />
|
||||
</local:SettingRow>
|
||||
|
||||
<local:SettingRow x:Name="LogToFileRow" Label="Log to file"
|
||||
Description="Mirror emulator output to a log file.">
|
||||
<ToggleSwitch x:Name="LogToFileToggle" OnContent="On" OffContent="Off"
|
||||
<local:SettingRow x:Name="LogToFileRow"
|
||||
Label="{Binding [Options.LogToFile.Label], Source={x:Static local:Localization.Instance}}"
|
||||
Description="{Binding [Options.LogToFile.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ToggleSwitch x:Name="LogToFileToggle"
|
||||
OnContent="{Binding [Common.On], Source={x:Static local:Localization.Instance}}"
|
||||
OffContent="{Binding [Common.Off], Source={x:Static local:Localization.Instance}}"
|
||||
VerticalAlignment="Center" />
|
||||
</local:SettingRow>
|
||||
|
||||
<local:SettingRow x:Name="LogFilePathRow" Label="Log file path"
|
||||
<local:SettingRow x:Name="LogFilePathRow"
|
||||
Label="{Binding [Options.LogFilePath.Label], Source={x:Static local:Localization.Instance}}"
|
||||
Description="No custom path">
|
||||
<Button x:Name="SelectLogFilePathButton" Classes="ghost" Content="Select…"
|
||||
<Button x:Name="SelectLogFilePathButton" Classes="ghost"
|
||||
Content="{Binding [Options.LogFilePath.Select], Source={x:Static local:Localization.Instance}}"
|
||||
VerticalAlignment="Center" />
|
||||
</local:SettingRow>
|
||||
|
||||
<local:SettingRow x:Name="OverrideLogFileRow" Label="Override log file"
|
||||
Description="Use the exact file path instead of appending title ID and timestamp.">
|
||||
<ToggleSwitch x:Name="OverrideLogFileToggle" OnContent="On" OffContent="Off"
|
||||
<local:SettingRow x:Name="OverrideLogFileRow"
|
||||
Label="{Binding [Options.OverrideLogFile.Label], Source={x:Static local:Localization.Instance}}"
|
||||
Description="{Binding [Options.OverrideLogFile.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ToggleSwitch x:Name="OverrideLogFileToggle"
|
||||
OnContent="{Binding [Common.On], Source={x:Static local:Localization.Instance}}"
|
||||
OffContent="{Binding [Common.Off], Source={x:Static local:Localization.Instance}}"
|
||||
VerticalAlignment="Center" />
|
||||
</local:SettingRow>
|
||||
</StackPanel>
|
||||
@@ -286,10 +330,12 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
<Border Classes="card">
|
||||
<StackPanel Spacing="14">
|
||||
<TextBlock x:Name="LauncherSectionTitle" Classes="sectionTitle" Text="LAUNCHER" />
|
||||
<TextBlock x:Name="LauncherSectionTitle" Classes="sectionTitle"
|
||||
Text="{Binding [Options.Section.Launcher], Source={x:Static local:Localization.Instance}}" />
|
||||
|
||||
<local:SettingRow x:Name="LanguageRow" Label="Emulator language"
|
||||
Description="Language used throughout the launcher. Applies immediately.">
|
||||
<local:SettingRow x:Name="LanguageRow"
|
||||
Label="{Binding [Options.Language.Label], Source={x:Static local:Localization.Instance}}"
|
||||
Description="{Binding [Options.Language.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ComboBox x:Name="LanguageBox" Width="160"
|
||||
VerticalAlignment="Center" CornerRadius="8">
|
||||
<ComboBox.ItemTemplate>
|
||||
@@ -300,21 +346,30 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
</ComboBox>
|
||||
</local:SettingRow>
|
||||
|
||||
<local:SettingRow x:Name="TitleMusicRow" Label="Title music"
|
||||
Description="Loop the selected game's preview music in the library.">
|
||||
<ToggleSwitch x:Name="TitleMusicToggle" OnContent="On" OffContent="Off"
|
||||
<local:SettingRow x:Name="TitleMusicRow"
|
||||
Label="{Binding [Options.TitleMusic.Label], Source={x:Static local:Localization.Instance}}"
|
||||
Description="{Binding [Options.TitleMusic.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ToggleSwitch x:Name="TitleMusicToggle"
|
||||
OnContent="{Binding [Common.On], Source={x:Static local:Localization.Instance}}"
|
||||
OffContent="{Binding [Common.Off], Source={x:Static local:Localization.Instance}}"
|
||||
IsChecked="True" VerticalAlignment="Center" />
|
||||
</local:SettingRow>
|
||||
|
||||
<local:SettingRow x:Name="DiscordRow" Label="Discord presence"
|
||||
Description="Show the running game on your Discord profile.">
|
||||
<ToggleSwitch x:Name="DiscordToggle" OnContent="On" OffContent="Off"
|
||||
<local:SettingRow x:Name="DiscordRow"
|
||||
Label="{Binding [Options.Discord.Label], Source={x:Static local:Localization.Instance}}"
|
||||
Description="{Binding [Options.Discord.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ToggleSwitch x:Name="DiscordToggle"
|
||||
OnContent="{Binding [Common.On], Source={x:Static local:Localization.Instance}}"
|
||||
OffContent="{Binding [Common.Off], Source={x:Static local:Localization.Instance}}"
|
||||
VerticalAlignment="Center" />
|
||||
</local:SettingRow>
|
||||
|
||||
<local:SettingRow x:Name="AutoUpdateRow" Label="Check for updates on startup"
|
||||
Description="Checks GitHub without delaying startup.">
|
||||
<ToggleSwitch x:Name="AutoUpdateToggle" OnContent="On" OffContent="Off"
|
||||
<local:SettingRow x:Name="AutoUpdateRow"
|
||||
Label="{Binding [Updater.Auto.Label], Source={x:Static local:Localization.Instance}}"
|
||||
Description="{Binding [Updater.Auto.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ToggleSwitch x:Name="AutoUpdateToggle"
|
||||
OnContent="{Binding [Common.On], Source={x:Static local:Localization.Instance}}"
|
||||
OffContent="{Binding [Common.Off], Source={x:Static local:Localization.Instance}}"
|
||||
IsChecked="True" VerticalAlignment="Center" />
|
||||
</local:SettingRow>
|
||||
</StackPanel>
|
||||
@@ -323,7 +378,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
<StackPanel Spacing="14">
|
||||
<TextBlock x:Name="AboutSectionTitle"
|
||||
Classes="sectionTitle"
|
||||
Text="ABOUT" />
|
||||
Text="{Binding [Options.About], Source={x:Static local:Localization.Instance}}" />
|
||||
|
||||
<!--Latest commit info-->
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
@@ -331,8 +386,12 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
<Image Source="avares://SharpEmu.GUI/Assets/commit-icon.png"
|
||||
Width="24" Height="24" VerticalAlignment="Center" />
|
||||
<StackPanel Spacing="2" VerticalAlignment="Center">
|
||||
<TextBlock x:Name="LatestCommitLabel" Text="Latest commit" FontSize="13"/>
|
||||
<TextBlock x:Name="LatestCommitDescription" Text="Latest commit on the main branch" FontSize="11" Foreground="{StaticResource MutedBrush}"/>
|
||||
<TextBlock x:Name="LatestCommitLabel"
|
||||
Text="{Binding [About.Github.LatestCommitLabel], Source={x:Static local:Localization.Instance}}"
|
||||
FontSize="13"/>
|
||||
<TextBlock x:Name="LatestCommitDescription"
|
||||
Text="{Binding [About.Github.LatestCommitDescription], Source={x:Static local:Localization.Instance}}"
|
||||
FontSize="11" Foreground="{StaticResource MutedBrush}"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
@@ -350,7 +409,9 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
Height="24"
|
||||
VerticalAlignment="Center" />
|
||||
<StackPanel Spacing="2" VerticalAlignment="Center">
|
||||
<TextBlock x:Name="UpdateLabel" Text="Updates" FontSize="13" />
|
||||
<TextBlock x:Name="UpdateLabel"
|
||||
Text="{Binding [Updater.Label], Source={x:Static local:Localization.Instance}}"
|
||||
FontSize="13" />
|
||||
<TextBlock x:Name="UpdateStatusText" Text="Current build: dev" FontSize="11"
|
||||
Foreground="{StaticResource MutedBrush}" TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
@@ -372,10 +433,10 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
<StackPanel VerticalAlignment="Center"
|
||||
Spacing="2">
|
||||
<TextBlock x:Name="GithubLabel"
|
||||
Text="GitHub"
|
||||
Text="{Binding [About.Github.Label], Source={x:Static local:Localization.Instance}}"
|
||||
FontSize="13" />
|
||||
<TextBlock x:Name="GithubDesc"
|
||||
Text="Source code, issues and project development."
|
||||
Text="{Binding [About.Github.Desc], Source={x:Static local:Localization.Instance}}"
|
||||
FontSize="11"
|
||||
Foreground="{StaticResource MutedBrush}"
|
||||
TextWrapping="Wrap" />
|
||||
@@ -385,7 +446,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
<Button Grid.Column="1"
|
||||
x:Name="GithubButton"
|
||||
Classes="ghost"
|
||||
Content="Open"
|
||||
Content="{Binding [About.GithubButton], Source={x:Static local:Localization.Instance}}"
|
||||
VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
|
||||
@@ -402,10 +463,10 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
<StackPanel VerticalAlignment="Center"
|
||||
Spacing="2">
|
||||
<TextBlock x:Name="DiscordServerLabel"
|
||||
Text="Discord"
|
||||
Text="{Binding [About.Discord.Label], Source={x:Static local:Localization.Instance}}"
|
||||
FontSize="13" />
|
||||
<TextBlock x:Name="DiscordServerDesc"
|
||||
Text="Join the community, get support and follow development."
|
||||
Text="{Binding [About.Discord.Desc], Source={x:Static local:Localization.Instance}}"
|
||||
FontSize="11"
|
||||
Foreground="{StaticResource MutedBrush}"
|
||||
TextWrapping="Wrap" />
|
||||
@@ -415,7 +476,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
<Button Grid.Column="1"
|
||||
x:Name="DiscordButton"
|
||||
Classes="ghost"
|
||||
Content="Join"
|
||||
Content="{Binding [About.DiscordButton], Source={x:Static local:Localization.Instance}}"
|
||||
VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
@@ -423,130 +484,165 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
<TabItem x:Name="GraphicsTabItem" Header="Graphics" FontSize="15">
|
||||
<TabItem x:Name="GraphicsTabItem"
|
||||
Header="{Binding [Options.Graphics], Source={x:Static local:Localization.Instance}}"
|
||||
FontSize="15">
|
||||
<ScrollViewer>
|
||||
<StackPanel Margin="0,14,0,16" Spacing="16" MaxWidth="1280" HorizontalAlignment="Left">
|
||||
<Border Classes="card">
|
||||
<StackPanel Spacing="14">
|
||||
<TextBlock x:Name="RenderingSectionTitle" Classes="sectionTitle" Text="RENDERING" />
|
||||
<TextBlock x:Name="RenderingSectionTitle" Classes="sectionTitle"
|
||||
Text="{Binding [Options.Section.Rendering], Source={x:Static local:Localization.Instance}}" />
|
||||
|
||||
<local:SettingRow x:Name="RenderResolutionRow" Label="Internal resolution"
|
||||
Description="Render offscreen targets below native resolution and upscale on present. Lower values trade image quality for GPU headroom; takes effect on next launch.">
|
||||
<ComboBox x:Name="RenderResolutionBox" Width="160" SelectedIndex="0"
|
||||
VerticalAlignment="Center" CornerRadius="8">
|
||||
<ComboBoxItem x:Name="RenderResolution100Item" Content="100% (native)" Tag="1.0" />
|
||||
<ComboBoxItem x:Name="RenderResolution75Item" Content="75%" Tag="0.75" />
|
||||
<ComboBoxItem x:Name="RenderResolution50Item" Content="50%" Tag="0.5" />
|
||||
<ComboBoxItem x:Name="RenderResolution25Item" Content="25%" Tag="0.25" />
|
||||
</ComboBox>
|
||||
<local:SettingRow x:Name="RenderResolutionRow"
|
||||
Label="{Binding [Options.RenderResolution.Label], Source={x:Static local:Localization.Instance}}"
|
||||
Description="{Binding [Options.RenderResolution.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ComboBox x:Name="RenderResolutionBox" Width="160"
|
||||
ItemTemplate="{StaticResource LocalizedChoiceTemplate}"
|
||||
HorizontalContentAlignment="Left"
|
||||
VerticalAlignment="Center" CornerRadius="8" />
|
||||
</local:SettingRow>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<Border Classes="card">
|
||||
<StackPanel Spacing="14">
|
||||
<TextBlock x:Name="DisplaySectionTitle" Classes="sectionTitle" Text="DISPLAY" />
|
||||
<local:SettingRow x:Name="WindowModeRow" Label="Window mode" Description="Regular window, desktop borderless, or exclusive fullscreen.">
|
||||
<ComboBox x:Name="WindowModeBox" Width="180" SelectedIndex="0" CornerRadius="8">
|
||||
<ComboBoxItem Content="Windowed" />
|
||||
<ComboBoxItem Content="Borderless" />
|
||||
<ComboBoxItem Content="Exclusive" />
|
||||
</ComboBox>
|
||||
<TextBlock x:Name="DisplaySectionTitle" Classes="sectionTitle"
|
||||
Text="{Binding [Options.Section.Display], Source={x:Static local:Localization.Instance}}" />
|
||||
<local:SettingRow x:Name="WindowModeRow"
|
||||
Label="{Binding [Options.WindowMode.Label], Source={x:Static local:Localization.Instance}}"
|
||||
Description="{Binding [Options.WindowMode.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ComboBox x:Name="WindowModeBox" Width="180"
|
||||
ItemTemplate="{StaticResource LocalizedChoiceTemplate}"
|
||||
HorizontalContentAlignment="Left"
|
||||
CornerRadius="8" />
|
||||
</local:SettingRow>
|
||||
<local:SettingRow x:Name="ResolutionRow" Label="Resolution" Description="Initial window size or exclusive fullscreen resolution.">
|
||||
<local:SettingRow x:Name="ResolutionRow"
|
||||
Label="{Binding [Options.Resolution.Label], Source={x:Static local:Localization.Instance}}"
|
||||
Description="{Binding [Options.Resolution.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ComboBox x:Name="ResolutionBox" Width="180" CornerRadius="8" />
|
||||
</local:SettingRow>
|
||||
<local:SettingRow x:Name="DisplayRow" Label="Display" Description="Monitor used for centering and fullscreen.">
|
||||
<local:SettingRow x:Name="DisplayRow"
|
||||
Label="{Binding [Options.Display.Label], Source={x:Static local:Localization.Instance}}"
|
||||
Description="{Binding [Options.Display.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ComboBox x:Name="DisplayBox" Width="260" CornerRadius="8" />
|
||||
</local:SettingRow>
|
||||
<local:SettingRow x:Name="RefreshRateRow" Label="Refresh rate" Description="Exclusive fullscreen refresh rate. Automatic selects the closest mode.">
|
||||
<local:SettingRow x:Name="RefreshRateRow"
|
||||
Label="{Binding [Options.RefreshRate.Label], Source={x:Static local:Localization.Instance}}"
|
||||
Description="{Binding [Options.RefreshRate.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ComboBox x:Name="RefreshRateBox" Width="180" CornerRadius="8" />
|
||||
</local:SettingRow>
|
||||
<local:SettingRow x:Name="ScalingRow" Label="Scaling" Description="Scale the native guest image without changing its internal resolution.">
|
||||
<ComboBox x:Name="ScalingModeBox" Width="180" SelectedIndex="0" CornerRadius="8">
|
||||
<ComboBoxItem Content="Fit" />
|
||||
<ComboBoxItem Content="Cover" />
|
||||
<ComboBoxItem Content="Stretch" />
|
||||
<ComboBoxItem Content="Integer" />
|
||||
</ComboBox>
|
||||
<local:SettingRow x:Name="ScalingRow"
|
||||
Label="{Binding [Options.Scaling.Label], Source={x:Static local:Localization.Instance}}"
|
||||
Description="{Binding [Options.Scaling.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ComboBox x:Name="ScalingModeBox" Width="180"
|
||||
ItemTemplate="{StaticResource LocalizedChoiceTemplate}"
|
||||
HorizontalContentAlignment="Left"
|
||||
CornerRadius="8" />
|
||||
</local:SettingRow>
|
||||
<local:SettingRow x:Name="VSyncRow" Label="VSync" Description="Use FIFO presentation for tear-free output.">
|
||||
<ToggleSwitch x:Name="VSyncToggle" IsChecked="True" OnContent="On" OffContent="Off" />
|
||||
<local:SettingRow x:Name="VSyncRow"
|
||||
Label="{Binding [Options.VSync.Label], Source={x:Static local:Localization.Instance}}"
|
||||
Description="{Binding [Options.VSync.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ToggleSwitch x:Name="VSyncToggle" IsChecked="True"
|
||||
OnContent="{Binding [Common.On], Source={x:Static local:Localization.Instance}}"
|
||||
OffContent="{Binding [Common.Off], Source={x:Static local:Localization.Instance}}" />
|
||||
</local:SettingRow>
|
||||
<local:SettingRow x:Name="HdrRow" Label="HDR" Description="Use HDR output when the selected display and graphics backend support it.">
|
||||
<ComboBox x:Name="HdrModeBox" Width="180" SelectedIndex="0" CornerRadius="8">
|
||||
<ComboBoxItem Content="Auto" />
|
||||
<ComboBoxItem Content="On" />
|
||||
<ComboBoxItem Content="Off" />
|
||||
</ComboBox>
|
||||
<local:SettingRow x:Name="HdrRow"
|
||||
Label="{Binding [Options.Hdr.Label], Source={x:Static local:Localization.Instance}}"
|
||||
Description="{Binding [Options.Hdr.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ComboBox x:Name="HdrModeBox" Width="180"
|
||||
ItemTemplate="{StaticResource LocalizedChoiceTemplate}"
|
||||
HorizontalContentAlignment="Left"
|
||||
CornerRadius="8" />
|
||||
</local:SettingRow>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
<TabItem x:Name="EnvTabItem" Header="Environment" FontSize="15">
|
||||
<TabItem x:Name="EnvTabItem"
|
||||
Header="{Binding [Options.Env.Tab], Source={x:Static local:Localization.Instance}}"
|
||||
FontSize="15">
|
||||
<ScrollViewer>
|
||||
<StackPanel Margin="0,14,0,16" Spacing="16" MaxWidth="1280" HorizontalAlignment="Left">
|
||||
|
||||
<Border Classes="card">
|
||||
<StackPanel Spacing="14">
|
||||
<TextBlock x:Name="EnvSectionTitle" Classes="sectionTitle" Text="ENVIRONMENT VARIABLES" />
|
||||
<TextBlock x:Name="EnvSectionTitle" Classes="sectionTitle"
|
||||
Text="{Binding [Options.Section.Environment], Source={x:Static local:Localization.Instance}}" />
|
||||
<TextBlock x:Name="EnvDesc"
|
||||
Text="Switches passed to the emulator as environment variables at launch."
|
||||
Text="{Binding [Options.Env.Desc], Source={x:Static local:Localization.Instance}}"
|
||||
FontSize="11" Foreground="{StaticResource MutedBrush}" TextWrapping="Wrap" />
|
||||
|
||||
<local:SettingRow x:Name="EnvBthidRow" LabelFontFamily="Consolas,monospace" Label="SHARPEMU_BTHID_UNAVAILABLE"
|
||||
Description="Report Bluetooth HID as unavailable for titles whose wheel/FFB middleware polls forever. Leave off normally. Some titles freeze when init fails.">
|
||||
<ToggleSwitch x:Name="EnvBthidToggle" OnContent="On" OffContent="Off"
|
||||
Description="{Binding [Options.Env.Bthid.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ToggleSwitch x:Name="EnvBthidToggle"
|
||||
OnContent="{Binding [Common.On], Source={x:Static local:Localization.Instance}}"
|
||||
OffContent="{Binding [Common.Off], Source={x:Static local:Localization.Instance}}"
|
||||
VerticalAlignment="Center" />
|
||||
</local:SettingRow>
|
||||
|
||||
<local:SettingRow x:Name="EnvLoopGuardRow" LabelFontFamily="Consolas,monospace" Label="SHARPEMU_DISABLE_IMPORT_LOOP_GUARD"
|
||||
Description="Do not force quit titles that repeat the same call for too long. Try this when a game exits on its own while loading.">
|
||||
<ToggleSwitch x:Name="EnvLoopGuardToggle" OnContent="On" OffContent="Off"
|
||||
Description="{Binding [Options.Env.LoopGuard.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ToggleSwitch x:Name="EnvLoopGuardToggle"
|
||||
OnContent="{Binding [Common.On], Source={x:Static local:Localization.Instance}}"
|
||||
OffContent="{Binding [Common.Off], Source={x:Static local:Localization.Instance}}"
|
||||
VerticalAlignment="Center" />
|
||||
</local:SettingRow>
|
||||
|
||||
<local:SettingRow x:Name="EnvWritableApp0Row" LabelFontFamily="Consolas,monospace" Label="SHARPEMU_WRITABLE_APP0"
|
||||
Description="Allow titles to create and write files inside their install folder. Needed by unpackaged dumps that write their save or config data under /app0.">
|
||||
<ToggleSwitch x:Name="EnvWritableApp0Toggle" OnContent="On" OffContent="Off"
|
||||
Description="{Binding [Options.Env.WritableApp0.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ToggleSwitch x:Name="EnvWritableApp0Toggle"
|
||||
OnContent="{Binding [Common.On], Source={x:Static local:Localization.Instance}}"
|
||||
OffContent="{Binding [Common.Off], Source={x:Static local:Localization.Instance}}"
|
||||
VerticalAlignment="Center" />
|
||||
</local:SettingRow>
|
||||
|
||||
<local:SettingRow x:Name="EnvVkValidationRow" LabelFontFamily="Consolas,monospace" Label="SHARPEMU_VK_VALIDATION"
|
||||
Description="Enable Vulkan validation layers for GPU debugging. Slow. Requires the Vulkan SDK to be installed.">
|
||||
<ToggleSwitch x:Name="EnvVkValidationToggle" OnContent="On" OffContent="Off"
|
||||
Description="{Binding [Options.Env.VkValidation.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ToggleSwitch x:Name="EnvVkValidationToggle"
|
||||
OnContent="{Binding [Common.On], Source={x:Static local:Localization.Instance}}"
|
||||
OffContent="{Binding [Common.Off], Source={x:Static local:Localization.Instance}}"
|
||||
VerticalAlignment="Center" />
|
||||
</local:SettingRow>
|
||||
|
||||
<local:SettingRow x:Name="EnvDumpSpirvRow" LabelFontFamily="Consolas,monospace" Label="SHARPEMU_DUMP_SPIRV"
|
||||
Description="Dump AGC shaders and their SPIR-V translations to the shader-dumps folder. Use when reporting shader or rendering bugs.">
|
||||
<ToggleSwitch x:Name="EnvDumpSpirvToggle" OnContent="On" OffContent="Off"
|
||||
Description="{Binding [Options.Env.DumpSpirv.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ToggleSwitch x:Name="EnvDumpSpirvToggle"
|
||||
OnContent="{Binding [Common.On], Source={x:Static local:Localization.Instance}}"
|
||||
OffContent="{Binding [Common.Off], Source={x:Static local:Localization.Instance}}"
|
||||
VerticalAlignment="Center" />
|
||||
</local:SettingRow>
|
||||
|
||||
<local:SettingRow x:Name="EnvLogDirectMemoryRow" LabelFontFamily="Consolas,monospace" Label="SHARPEMU_LOG_DIRECT_MEMORY"
|
||||
Description="Log direct memory allocations and failures to the console. Use when a game aborts or exits during boot.">
|
||||
<ToggleSwitch x:Name="EnvLogDirectMemoryToggle" OnContent="On" OffContent="Off"
|
||||
Description="{Binding [Options.Env.LogDirectMemory.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ToggleSwitch x:Name="EnvLogDirectMemoryToggle"
|
||||
OnContent="{Binding [Common.On], Source={x:Static local:Localization.Instance}}"
|
||||
OffContent="{Binding [Common.Off], Source={x:Static local:Localization.Instance}}"
|
||||
VerticalAlignment="Center" />
|
||||
</local:SettingRow>
|
||||
|
||||
<local:SettingRow x:Name="EnvLogIoRow" LabelFontFamily="Consolas,monospace" Label="SHARPEMU_LOG_IO"
|
||||
Description="Log file open, read, and path-resolve activity to the console. Use when a game cannot find its data files during boot.">
|
||||
<ToggleSwitch x:Name="EnvLogIoToggle" OnContent="On" OffContent="Off"
|
||||
Description="{Binding [Options.Env.LogIo.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ToggleSwitch x:Name="EnvLogIoToggle"
|
||||
OnContent="{Binding [Common.On], Source={x:Static local:Localization.Instance}}"
|
||||
OffContent="{Binding [Common.Off], Source={x:Static local:Localization.Instance}}"
|
||||
VerticalAlignment="Center" />
|
||||
</local:SettingRow>
|
||||
|
||||
<local:SettingRow x:Name="EnvLogNpRow" LabelFontFamily="Consolas,monospace" Label="SHARPEMU_LOG_NP"
|
||||
Description="Log NP (PlayStation Network) library calls to the console.">
|
||||
<ToggleSwitch x:Name="EnvLogNpToggle" OnContent="On" OffContent="Off"
|
||||
Description="{Binding [Options.Env.LogNp.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ToggleSwitch x:Name="EnvLogNpToggle"
|
||||
OnContent="{Binding [Common.On], Source={x:Static local:Localization.Instance}}"
|
||||
OffContent="{Binding [Common.Off], Source={x:Static local:Localization.Instance}}"
|
||||
VerticalAlignment="Center" />
|
||||
</local:SettingRow>
|
||||
|
||||
<local:SettingRow x:Name="EnvGuestImageCpuSyncRow" LabelFontFamily="Consolas,monospace" Label="SHARPEMU_GUEST_IMAGE_CPU_SYNC"
|
||||
Description="Re-upload guest surfaces the game's own CPU code rewrites. Leave off normally. Turn on for titles whose CPU-drawn surfaces never reach the screen. Costs performance and regresses some titles, such as GTA V.">
|
||||
<ToggleSwitch x:Name="EnvGuestImageCpuSyncToggle" OnContent="On" OffContent="Off"
|
||||
Description="{Binding [Options.Env.GuestImageCpuSync.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ToggleSwitch x:Name="EnvGuestImageCpuSyncToggle"
|
||||
OnContent="{Binding [Common.On], Source={x:Static local:Localization.Instance}}"
|
||||
OffContent="{Binding [Common.Off], Source={x:Static local:Localization.Instance}}"
|
||||
VerticalAlignment="Center" />
|
||||
</local:SettingRow>
|
||||
</StackPanel>
|
||||
@@ -564,16 +660,27 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
Margin="0,12,0,0" IsVisible="False">
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
<Grid Grid.Row="0" ColumnDefinitions="*,Auto,Auto,Auto,Auto,Auto" Margin="16,12,16,8">
|
||||
<TextBlock x:Name="ConsoleSectionTitle" Classes="sectionTitle" Text="CONSOLE" VerticalAlignment="Center" />
|
||||
<TextBlock x:Name="ConsoleSectionTitle" Classes="sectionTitle"
|
||||
Text="{Binding [Console.Title], Source={x:Static local:Localization.Instance}}"
|
||||
VerticalAlignment="Center" />
|
||||
<TextBox Grid.Column="1" FontSize="12" Margin="0,0,12,0" x:Name="ConsoleSearchBox"
|
||||
PlaceholderText="Search..." Width="320" />
|
||||
<CheckBox Grid.Column="2" x:Name="AutoScrollCheck" Content="Auto-scroll" IsChecked="True"
|
||||
PlaceholderText="{Binding [Console.SearchWatermark], Source={x:Static local:Localization.Instance}}"
|
||||
Width="320" />
|
||||
<CheckBox Grid.Column="2" x:Name="AutoScrollCheck"
|
||||
Content="{Binding [Console.AutoScroll], Source={x:Static local:Localization.Instance}}"
|
||||
IsChecked="True"
|
||||
FontSize="12" Margin="0,0,12,0" />
|
||||
<Button Grid.Column="3" x:Name="DetachConsoleButton" Classes="ghost" Content="Split" FontSize="12"
|
||||
<Button Grid.Column="3" x:Name="DetachConsoleButton" Classes="ghost"
|
||||
Content="{Binding [Console.Split], Source={x:Static local:Localization.Instance}}"
|
||||
FontSize="12"
|
||||
Padding="10,4" Margin="0,0,8,0" />
|
||||
<Button Grid.Column="4" x:Name="CopyLogButton" Classes="ghost" Content="Copy" FontSize="12"
|
||||
<Button Grid.Column="4" x:Name="CopyLogButton" Classes="ghost"
|
||||
Content="{Binding [Console.Copy], Source={x:Static local:Localization.Instance}}"
|
||||
FontSize="12"
|
||||
Padding="10,4" Margin="0,0,8,0" />
|
||||
<Button Grid.Column="5" x:Name="ClearLogButton" Classes="ghost" Content="Clear" FontSize="12"
|
||||
<Button Grid.Column="5" x:Name="ClearLogButton" Classes="ghost"
|
||||
Content="{Binding [Console.Clear], Source={x:Static local:Localization.Instance}}"
|
||||
FontSize="12"
|
||||
Padding="10,4" />
|
||||
</Grid>
|
||||
<ListBox Grid.Row="1" x:Name="ConsoleList" Classes="console" BorderThickness="0,1,0,0"
|
||||
@@ -649,9 +756,14 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Column="2" Orientation="Horizontal" Spacing="8" VerticalAlignment="Center">
|
||||
<ToggleButton x:Name="ConsoleToggle" Classes="ghost" Content="≡ Console" />
|
||||
<Button x:Name="LaunchButton" Classes="accent" Content="▶ Launch" IsEnabled="False" />
|
||||
<Button x:Name="StopButton" Classes="danger" Content="■ Stop" IsEnabled="False" />
|
||||
<ToggleButton x:Name="ConsoleToggle" Classes="ghost"
|
||||
Content="{Binding [Launch.Console], Source={x:Static local:Localization.Instance}}" />
|
||||
<Button x:Name="LaunchButton" Classes="accent"
|
||||
Content="{Binding [Launch.Launch], Source={x:Static local:Localization.Instance}}"
|
||||
IsEnabled="False" />
|
||||
<Button x:Name="StopButton" Classes="danger"
|
||||
Content="{Binding [Launch.Stop], Source={x:Static local:Localization.Instance}}"
|
||||
IsEnabled="False" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
|
||||
Reference in New Issue
Block a user