mirror of
https://git.ryujinx.app/projects/Kenji-NX.git
synced 2026-10-06 00:58:58 +02:00
Add custom audio settings
This commit is contained in:
@@ -78,6 +78,8 @@ namespace Ryujinx.UI.Common.Helper
|
|||||||
ConfigurationState.Instance.System.EnableLowPowerPptc.Value = customSettingsModel.EnableLowPowerPptc;
|
ConfigurationState.Instance.System.EnableLowPowerPptc.Value = customSettingsModel.EnableLowPowerPptc;
|
||||||
ConfigurationState.Instance.System.MemoryManagerMode.Value = (MemoryManagerMode)customSettingsModel.MemoryManagerMode;
|
ConfigurationState.Instance.System.MemoryManagerMode.Value = (MemoryManagerMode)customSettingsModel.MemoryManagerMode;
|
||||||
ConfigurationState.Instance.System.UseHypervisor.Value = customSettingsModel.UseHypervisor;
|
ConfigurationState.Instance.System.UseHypervisor.Value = customSettingsModel.UseHypervisor;
|
||||||
|
ConfigurationState.Instance.System.AudioBackend.Value = customSettingsModel.AudioBackend;
|
||||||
|
ConfigurationState.Instance.System.AudioVolume.Value = customSettingsModel.AudioVolume;
|
||||||
ConfigurationState.Instance.Graphics.GraphicsBackend.Value = (GraphicsBackend)customSettingsModel.GraphicsBackend;
|
ConfigurationState.Instance.Graphics.GraphicsBackend.Value = (GraphicsBackend)customSettingsModel.GraphicsBackend;
|
||||||
ConfigurationState.Instance.Graphics.PreferredGpu.Value = customSettingsModel.PreferredGpu;
|
ConfigurationState.Instance.Graphics.PreferredGpu.Value = customSettingsModel.PreferredGpu;
|
||||||
ConfigurationState.Instance.Graphics.EnableShaderCache.Value = customSettingsModel.EnableShaderCache;
|
ConfigurationState.Instance.Graphics.EnableShaderCache.Value = customSettingsModel.EnableShaderCache;
|
||||||
|
|||||||
@@ -28,5 +28,10 @@ namespace Ryujinx.UI.Common.Models
|
|||||||
public float ResScale { get; set; }
|
public float ResScale { get; set; }
|
||||||
public float MaxAnisotropy { get; set; }
|
public float MaxAnisotropy { get; set; }
|
||||||
public int BackendThreading { get; set; }
|
public int BackendThreading { get; set; }
|
||||||
|
public int IsOpenAlEnabled { get; set; }
|
||||||
|
public int IsSDL2Enabled { get; set; }
|
||||||
|
public int IsSoundIoEnabled { get; set; }
|
||||||
|
public AudioBackend AudioBackend { get; set; }
|
||||||
|
public float AudioVolume { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -178,5 +178,8 @@
|
|||||||
<Compile Update="UI\Windows\CustomSettingsWindow.axaml.cs">
|
<Compile Update="UI\Windows\CustomSettingsWindow.axaml.cs">
|
||||||
<DependentUpon>CustomSettingsWindow.axaml</DependentUpon>
|
<DependentUpon>CustomSettingsWindow.axaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Update="UI\Views\Settings\CustomSettingsAudioView.axaml.cs">
|
||||||
|
<DependentUpon>CustomSettingsAudioView.axaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ using Avalonia.Controls;
|
|||||||
using Avalonia.Media.Imaging;
|
using Avalonia.Media.Imaging;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using Ryujinx.Audio.Backends.OpenAL;
|
||||||
|
using Ryujinx.Audio.Backends.SDL2;
|
||||||
|
using Ryujinx.Audio.Backends.SoundIo;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Graphics.Vulkan;
|
using Ryujinx.Graphics.Vulkan;
|
||||||
@@ -131,12 +134,33 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
public int MaxAnisotropyIndex { get; set; }
|
public int MaxAnisotropyIndex { get; set; }
|
||||||
public int BackendThreading { get; set; }
|
public int BackendThreading { get; set; }
|
||||||
|
|
||||||
|
// Audio settings
|
||||||
|
public bool IsOpenAlEnabled { get; set; }
|
||||||
|
public bool IsSoundIoEnabled { get; set; }
|
||||||
|
public bool IsSDL2Enabled { get; set; }
|
||||||
|
public AudioBackend AudioBackend { get; set; }
|
||||||
|
|
||||||
|
public float Volume
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
field = value;
|
||||||
|
|
||||||
|
ConfigurationState.Instance.System.AudioVolume.Value = field / 100;
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public CustomSettingsViewModel(string titleId, byte[] icon, string titleName)
|
public CustomSettingsViewModel(string titleId, byte[] icon, string titleName)
|
||||||
{
|
{
|
||||||
AvailableGpus = [];
|
AvailableGpus = [];
|
||||||
ApplicationIdBase = ulong.Parse(titleId, NumberStyles.HexNumber);
|
ApplicationIdBase = ulong.Parse(titleId, NumberStyles.HexNumber);
|
||||||
CustomSettingsModel = CustomSettingsHelper.LoadCustomSettingsJson(CustomSettingsHelper.PathToGameSettingsJson(ApplicationIdBase));
|
CustomSettingsModel = CustomSettingsHelper.LoadCustomSettingsJson(CustomSettingsHelper.PathToGameSettingsJson(ApplicationIdBase));
|
||||||
|
|
||||||
|
Task.Run(CheckSoundBackends);
|
||||||
|
|
||||||
if (icon is { Length: > 0 })
|
if (icon is { Length: > 0 })
|
||||||
{
|
{
|
||||||
using MemoryStream ms = new(icon);
|
using MemoryStream ms = new(icon);
|
||||||
@@ -150,6 +174,20 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task CheckSoundBackends()
|
||||||
|
{
|
||||||
|
IsOpenAlEnabled = OpenALHardwareDeviceDriver.IsSupported;
|
||||||
|
IsSoundIoEnabled = SoundIoHardwareDeviceDriver.IsSupported;
|
||||||
|
IsSDL2Enabled = SDL2HardwareDeviceDriver.IsSupported;
|
||||||
|
|
||||||
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
||||||
|
{
|
||||||
|
OnPropertyChanged(nameof(IsOpenAlEnabled));
|
||||||
|
OnPropertyChanged(nameof(IsSoundIoEnabled));
|
||||||
|
OnPropertyChanged(nameof(IsSDL2Enabled));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private async Task LoadAvailableGpus()
|
private async Task LoadAvailableGpus()
|
||||||
{
|
{
|
||||||
AvailableGpus.Clear();
|
AvailableGpus.Clear();
|
||||||
@@ -206,6 +244,8 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
ResScaleIndex = ComputeResScaleIndex(config.Graphics.ResScale);
|
ResScaleIndex = ComputeResScaleIndex(config.Graphics.ResScale);
|
||||||
MaxAnisotropyIndex = ComputeMaxAnisotropyIndex(config.Graphics.MaxAnisotropy);
|
MaxAnisotropyIndex = ComputeMaxAnisotropyIndex(config.Graphics.MaxAnisotropy);
|
||||||
BackendThreading = (int)config.Graphics.BackendThreading.Value;
|
BackendThreading = (int)config.Graphics.BackendThreading.Value;
|
||||||
|
AudioBackend = config.System.AudioBackend.Value;
|
||||||
|
Volume = config.System.AudioVolume * 100;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -230,6 +270,8 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
ResScaleIndex = ComputeResScaleIndex(CustomSettingsModel.ResScale);
|
ResScaleIndex = ComputeResScaleIndex(CustomSettingsModel.ResScale);
|
||||||
MaxAnisotropyIndex = ComputeMaxAnisotropyIndex(CustomSettingsModel.MaxAnisotropy);
|
MaxAnisotropyIndex = ComputeMaxAnisotropyIndex(CustomSettingsModel.MaxAnisotropy);
|
||||||
BackendThreading = CustomSettingsModel.BackendThreading;
|
BackendThreading = CustomSettingsModel.BackendThreading;
|
||||||
|
AudioBackend = CustomSettingsModel.AudioBackend;
|
||||||
|
Volume = CustomSettingsModel.AudioVolume * 100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,6 +305,8 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
CustomSettingsModel.ResScale = ComputeResScale(ResScaleIndex);
|
CustomSettingsModel.ResScale = ComputeResScale(ResScaleIndex);
|
||||||
CustomSettingsModel.MaxAnisotropy = ComputeMaxAnisotropy(MaxAnisotropyIndex);
|
CustomSettingsModel.MaxAnisotropy = ComputeMaxAnisotropy(MaxAnisotropyIndex);
|
||||||
CustomSettingsModel.BackendThreading = BackendThreading;
|
CustomSettingsModel.BackendThreading = BackendThreading;
|
||||||
|
CustomSettingsModel.AudioBackend = AudioBackend;
|
||||||
|
CustomSettingsModel.AudioVolume = Volume / 100;
|
||||||
CustomSettingsHelper.SaveCustomSettingsJson(CustomSettingsHelper.PathToGameSettingsJson(ApplicationIdBase), CustomSettingsModel);
|
CustomSettingsHelper.SaveCustomSettingsJson(CustomSettingsHelper.PathToGameSettingsJson(ApplicationIdBase), CustomSettingsModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
<UserControl
|
||||||
|
x:Class="Ryujinx.Ava.UI.Views.Settings.CustomSettingsAudioView"
|
||||||
|
xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
|
||||||
|
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||||
|
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
||||||
|
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
x:DataType="viewModels:CustomSettingsViewModel">
|
||||||
|
<Design.DataContext>
|
||||||
|
<viewModels:SettingsViewModel />
|
||||||
|
</Design.DataContext>
|
||||||
|
<ScrollViewer
|
||||||
|
Name="AudioPage"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
HorizontalScrollBarVisibility="Disabled"
|
||||||
|
VerticalScrollBarVisibility="Auto">
|
||||||
|
<Border Classes="settings">
|
||||||
|
<StackPanel
|
||||||
|
Margin="10"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
Orientation="Vertical"
|
||||||
|
Spacing="10">
|
||||||
|
<TextBlock Classes="h1" Text="{locale:Locale SettingsTabAudio}" />
|
||||||
|
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
||||||
|
<TextBlock VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale SettingsTabSystemAudioBackend}"
|
||||||
|
ToolTip.Tip="{locale:Locale AudioBackendTooltip}"
|
||||||
|
Width="250" />
|
||||||
|
<ComboBox SelectedIndex="{Binding AudioBackend}"
|
||||||
|
Width="350"
|
||||||
|
HorizontalContentAlignment="Left">
|
||||||
|
<ComboBoxItem
|
||||||
|
Content="{locale:Locale SettingsTabSystemAudioBackendDummy}" />
|
||||||
|
<ComboBoxItem
|
||||||
|
IsEnabled="{Binding IsOpenAlEnabled}"
|
||||||
|
Content="{locale:Locale SettingsTabSystemAudioBackendOpenAL}" />
|
||||||
|
<ComboBoxItem
|
||||||
|
IsEnabled="{Binding IsSoundIoEnabled}"
|
||||||
|
Content="{locale:Locale SettingsTabSystemAudioBackendSoundIO}" />
|
||||||
|
<ComboBoxItem
|
||||||
|
IsEnabled="{Binding IsSDL2Enabled}"
|
||||||
|
Content="{locale:Locale SettingsTabSystemAudioBackendSDL2}" />
|
||||||
|
</ComboBox>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
||||||
|
<TextBlock VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale SettingsTabSystemAudioVolume}"
|
||||||
|
ToolTip.Tip="{locale:Locale AudioVolumeTooltip}"
|
||||||
|
Width="250" />
|
||||||
|
<ui:NumberBox Value="{Binding Volume}"
|
||||||
|
ToolTip.Tip="{locale:Locale AudioVolumeTooltip}"
|
||||||
|
Width="350"
|
||||||
|
SmallChange="1"
|
||||||
|
LargeChange="10"
|
||||||
|
SimpleNumberFormat="F0"
|
||||||
|
SpinButtonPlacementMode="Inline"
|
||||||
|
Minimum="0"
|
||||||
|
Maximum="100" />
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
||||||
|
<controls:SliderScroll Value="{Binding Volume}"
|
||||||
|
Margin="250,0,0,0"
|
||||||
|
ToolTip.Tip="{locale:Locale AudioVolumeTooltip}"
|
||||||
|
Minimum="0"
|
||||||
|
Maximum="100"
|
||||||
|
SmallChange="1"
|
||||||
|
TickFrequency="1"
|
||||||
|
IsSnapToTickEnabled="True"
|
||||||
|
LargeChange="10"
|
||||||
|
Width="350" />
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
</ScrollViewer>
|
||||||
|
</UserControl>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using Avalonia.Controls;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.UI.Views.Settings
|
||||||
|
{
|
||||||
|
public partial class CustomSettingsAudioView : UserControl
|
||||||
|
{
|
||||||
|
public CustomSettingsAudioView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,6 +32,7 @@
|
|||||||
<settings:CustomSettingsSystemView Name="SystemPage" />
|
<settings:CustomSettingsSystemView Name="SystemPage" />
|
||||||
<settings:CustomSettingsCPUView Name="CpuPage" />
|
<settings:CustomSettingsCPUView Name="CpuPage" />
|
||||||
<settings:CustomSettingsGraphicsView Name="GraphicsPage" />
|
<settings:CustomSettingsGraphicsView Name="GraphicsPage" />
|
||||||
|
<settings:CustomSettingsAudioView Name="AudioPage" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<ui:NavigationView
|
<ui:NavigationView
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
@@ -82,6 +83,10 @@
|
|||||||
Content="{locale:Locale SettingsTabGraphics}"
|
Content="{locale:Locale SettingsTabGraphics}"
|
||||||
Tag="GraphicsPage"
|
Tag="GraphicsPage"
|
||||||
IconSource="Image" />
|
IconSource="Image" />
|
||||||
|
<ui:NavigationViewItem
|
||||||
|
Content="{locale:Locale SettingsTabAudio}"
|
||||||
|
IconSource="Audio"
|
||||||
|
Tag="AudioPage" />
|
||||||
</ui:NavigationView.MenuItems>
|
</ui:NavigationView.MenuItems>
|
||||||
<ui:NavigationView.Styles>
|
<ui:NavigationView.Styles>
|
||||||
<Style Selector="Grid#PlaceholderGrid">
|
<Style Selector="Grid#PlaceholderGrid">
|
||||||
|
|||||||
@@ -94,6 +94,9 @@ namespace Ryujinx.Ava.UI.Windows
|
|||||||
case "GraphicsPage":
|
case "GraphicsPage":
|
||||||
NavPanel.Content = GraphicsPage;
|
NavPanel.Content = GraphicsPage;
|
||||||
break;
|
break;
|
||||||
|
case "AudioPage":
|
||||||
|
NavPanel.Content = AudioPage;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user