|
|
|
@@ -1,7 +1,6 @@
|
|
|
|
|
using Avalonia.Collections;
|
|
|
|
|
using Avalonia.Controls;
|
|
|
|
|
using Avalonia.Threading;
|
|
|
|
|
using DynamicData;
|
|
|
|
|
using LibHac.Tools.FsSystem;
|
|
|
|
|
using Ryujinx.Audio.Backends.OpenAL;
|
|
|
|
|
using Ryujinx.Audio.Backends.SDL2;
|
|
|
|
@@ -24,6 +23,7 @@ using System.Collections.ObjectModel;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Net.NetworkInformation;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using TimeZone = Ryujinx.Ava.UI.Models.TimeZone;
|
|
|
|
|
|
|
|
|
|
namespace Ryujinx.Ava.UI.ViewModels
|
|
|
|
@@ -44,7 +44,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|
|
|
|
private float _volume;
|
|
|
|
|
private bool _isVulkanAvailable = true;
|
|
|
|
|
private bool _directoryChanged;
|
|
|
|
|
private List<string> _gpuIds = new();
|
|
|
|
|
private readonly List<string> _gpuIds = new();
|
|
|
|
|
private KeyboardHotkeys _keyboardHotkeys;
|
|
|
|
|
private int _graphicsBackendIndex;
|
|
|
|
|
private string _customThemePath;
|
|
|
|
@@ -278,7 +278,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|
|
|
|
_contentManager = contentManager;
|
|
|
|
|
if (Program.PreviewerDetached)
|
|
|
|
|
{
|
|
|
|
|
LoadTimeZones();
|
|
|
|
|
Task.Run(LoadTimeZones);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -290,27 +290,34 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|
|
|
|
_validTzRegions = new List<string>();
|
|
|
|
|
_networkInterfaces = new Dictionary<string, string>();
|
|
|
|
|
|
|
|
|
|
CheckSoundBackends();
|
|
|
|
|
PopulateNetworkInterfaces();
|
|
|
|
|
Task.Run(CheckSoundBackends);
|
|
|
|
|
Task.Run(PopulateNetworkInterfaces);
|
|
|
|
|
|
|
|
|
|
if (Program.PreviewerDetached)
|
|
|
|
|
{
|
|
|
|
|
LoadAvailableGpus();
|
|
|
|
|
Task.Run(LoadAvailableGpus);
|
|
|
|
|
LoadCurrentConfiguration();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void CheckSoundBackends()
|
|
|
|
|
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 void LoadAvailableGpus()
|
|
|
|
|
private async Task LoadAvailableGpus()
|
|
|
|
|
{
|
|
|
|
|
_gpuIds = new List<string>();
|
|
|
|
|
List<string> names = new();
|
|
|
|
|
AvailableGpus.Clear();
|
|
|
|
|
|
|
|
|
|
var devices = VulkanRenderer.GetPhysicalDevices();
|
|
|
|
|
|
|
|
|
|
if (devices.Length == 0)
|
|
|
|
@@ -322,16 +329,23 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|
|
|
|
{
|
|
|
|
|
foreach (var device in devices)
|
|
|
|
|
{
|
|
|
|
|
_gpuIds.Add(device.Id);
|
|
|
|
|
names.Add($"{device.Name} {(device.IsDiscrete ? "(dGPU)" : "")}");
|
|
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
|
|
|
|
_gpuIds.Add(device.Id);
|
|
|
|
|
|
|
|
|
|
AvailableGpus.Add(new ComboBoxItem { Content = $"{device.Name} {(device.IsDiscrete ? "(dGPU)" : "")}" });
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AvailableGpus.Clear();
|
|
|
|
|
AvailableGpus.AddRange(names.Select(x => new ComboBoxItem { Content = x }));
|
|
|
|
|
// GPU configuration needs to be loaded during the async method or it will always return 0.
|
|
|
|
|
PreferredGpuIndex = _gpuIds.Contains(ConfigurationState.Instance.Graphics.PreferredGpu) ?
|
|
|
|
|
_gpuIds.IndexOf(ConfigurationState.Instance.Graphics.PreferredGpu) : 0;
|
|
|
|
|
|
|
|
|
|
Dispatcher.UIThread.Post(() => OnPropertyChanged(nameof(PreferredGpuIndex)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void LoadTimeZones()
|
|
|
|
|
public async Task LoadTimeZones()
|
|
|
|
|
{
|
|
|
|
|
_timeZoneContentManager = new TimeZoneContentManager();
|
|
|
|
|
|
|
|
|
@@ -344,21 +358,34 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|
|
|
|
|
|
|
|
|
string abbr2 = abbr.StartsWith('+') || abbr.StartsWith('-') ? string.Empty : abbr;
|
|
|
|
|
|
|
|
|
|
TimeZones.Add(new TimeZone($"UTC{hours:+0#;-0#;+00}:{minutes:D2}", location, abbr2));
|
|
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
|
|
|
|
TimeZones.Add(new TimeZone($"UTC{hours:+0#;-0#;+00}:{minutes:D2}", location, abbr2));
|
|
|
|
|
|
|
|
|
|
_validTzRegions.Add(location);
|
|
|
|
|
_validTzRegions.Add(location);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Dispatcher.UIThread.Post(() => OnPropertyChanged(nameof(TimeZone)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void PopulateNetworkInterfaces()
|
|
|
|
|
private async Task PopulateNetworkInterfaces()
|
|
|
|
|
{
|
|
|
|
|
_networkInterfaces.Clear();
|
|
|
|
|
_networkInterfaces.Add(LocaleManager.Instance[LocaleKeys.NetworkInterfaceDefault], "0");
|
|
|
|
|
|
|
|
|
|
foreach (NetworkInterface networkInterface in NetworkInterface.GetAllNetworkInterfaces())
|
|
|
|
|
{
|
|
|
|
|
_networkInterfaces.Add(networkInterface.Name, networkInterface.Id);
|
|
|
|
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
|
|
|
|
_networkInterfaces.Add(networkInterface.Name, networkInterface.Id);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Network interface index needs to be loaded during the async method or it will always return 0.
|
|
|
|
|
NetworkInterfaceIndex = _networkInterfaces.Values.ToList().IndexOf(ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value);
|
|
|
|
|
|
|
|
|
|
Dispatcher.UIThread.Post(() => OnPropertyChanged(nameof(NetworkInterfaceIndex)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ValidateAndSetTimeZone(string location)
|
|
|
|
@@ -416,7 +443,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|
|
|
|
|
|
|
|
|
// Graphics
|
|
|
|
|
GraphicsBackendIndex = (int)config.Graphics.GraphicsBackend.Value;
|
|
|
|
|
PreferredGpuIndex = _gpuIds.Contains(config.Graphics.PreferredGpu) ? _gpuIds.IndexOf(config.Graphics.PreferredGpu) : 0;
|
|
|
|
|
// Physical devices are queried asynchronously hence the prefered index config value is loaded in LoadAvailableGpus().
|
|
|
|
|
EnableShaderCache = config.Graphics.EnableShaderCache;
|
|
|
|
|
EnableTextureRecompression = config.Graphics.EnableTextureRecompression;
|
|
|
|
|
EnableMacroHLE = config.Graphics.EnableMacroHLE;
|
|
|
|
@@ -437,6 +464,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|
|
|
|
|
|
|
|
|
// Network
|
|
|
|
|
EnableInternetAccess = config.System.EnableInternetAccess;
|
|
|
|
|
// LAN interface index is loaded asynchronously in PopulateNetworkInterfaces()
|
|
|
|
|
|
|
|
|
|
// Logging
|
|
|
|
|
EnableFileLog = config.Logger.EnableFileLog;
|
|
|
|
@@ -450,8 +478,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|
|
|
|
EnableFsAccessLog = config.Logger.EnableFsAccessLog;
|
|
|
|
|
FsGlobalAccessLogMode = config.System.FsGlobalAccessLogMode;
|
|
|
|
|
OpenglDebugLevel = (int)config.Logger.GraphicsDebugLevel.Value;
|
|
|
|
|
|
|
|
|
|
NetworkInterfaceIndex = _networkInterfaces.Values.ToList().IndexOf(config.Multiplayer.LanInterfaceId.Value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SaveSettings()
|
|
|
|
|