Compare commits
8 Commits
Canary-1.2
...
Canary-1.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
88d11d3d8d | ||
|
|
391f57bdd2 | ||
|
|
fd2b5a7fc1 | ||
|
|
37c165e9fc | ||
|
|
003a6d322b | ||
|
|
978d2c132b | ||
|
|
5d63706cea | ||
|
|
732aafd3bb |
@@ -53,6 +53,9 @@ namespace Ryujinx.Common
|
|||||||
{
|
{
|
||||||
public static void LogValueChange<T>(LogClass logClass, ReactiveEventArgs<T> eventArgs, string valueName)
|
public static void LogValueChange<T>(LogClass logClass, ReactiveEventArgs<T> eventArgs, string valueName)
|
||||||
{
|
{
|
||||||
|
if (eventArgs.AreValuesEqual)
|
||||||
|
return;
|
||||||
|
|
||||||
string message = string.Create(CultureInfo.InvariantCulture, $"{valueName} set to: {eventArgs.NewValue}");
|
string message = string.Create(CultureInfo.InvariantCulture, $"{valueName} set to: {eventArgs.NewValue}");
|
||||||
|
|
||||||
Logger.Info?.Print(logClass, message);
|
Logger.Info?.Print(logClass, message);
|
||||||
@@ -65,5 +68,22 @@ namespace Ryujinx.Common
|
|||||||
{
|
{
|
||||||
public T OldValue { get; } = oldValue;
|
public T OldValue { get; } = oldValue;
|
||||||
public T NewValue { get; } = newValue;
|
public T NewValue { get; } = newValue;
|
||||||
|
|
||||||
|
public bool AreValuesEqual
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (OldValue == null && NewValue == null)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (OldValue == null && NewValue != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (OldValue != null && NewValue == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return OldValue!.Equals(NewValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -367,7 +367,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_context.DirtyHacks.IsEnabled(DirtyHack.ShaderTranslationDelay))
|
if (_context.Capabilities.Api == TargetApi.Metal && _context.DirtyHacks.IsEnabled(DirtyHack.ShaderTranslationDelay))
|
||||||
Thread.Sleep(_context.DirtyHacks[DirtyHack.ShaderTranslationDelay]);
|
Thread.Sleep(_context.DirtyHacks[DirtyHack.ShaderTranslationDelay]);
|
||||||
|
|
||||||
AsyncProgramTranslation asyncTranslation = new(guestShaders, specState, programIndex, isCompute);
|
AsyncProgramTranslation asyncTranslation = new(guestShaders, specState, programIndex, isCompute);
|
||||||
|
|||||||
@@ -1235,7 +1235,7 @@
|
|||||||
"it_IT": "",
|
"it_IT": "",
|
||||||
"ja_JP": "",
|
"ja_JP": "",
|
||||||
"ko_KR": "자주 묻는 질문(FAQ) 및 안내",
|
"ko_KR": "자주 묻는 질문(FAQ) 및 안내",
|
||||||
"no_NO": "",
|
"no_NO": "Vanlige spørsmål og veiledninger",
|
||||||
"pl_PL": "",
|
"pl_PL": "",
|
||||||
"pt_BR": "",
|
"pt_BR": "",
|
||||||
"ru_RU": "FAQ и Руководства",
|
"ru_RU": "FAQ и Руководства",
|
||||||
@@ -1460,7 +1460,7 @@
|
|||||||
"it_IT": "Preferito",
|
"it_IT": "Preferito",
|
||||||
"ja_JP": "お気に入り",
|
"ja_JP": "お気に入り",
|
||||||
"ko_KR": "즐겨찾기",
|
"ko_KR": "즐겨찾기",
|
||||||
"no_NO": "",
|
"no_NO": "Favoritter",
|
||||||
"pl_PL": "Ulubione",
|
"pl_PL": "Ulubione",
|
||||||
"pt_BR": "Favorito",
|
"pt_BR": "Favorito",
|
||||||
"ru_RU": "Избранное",
|
"ru_RU": "Избранное",
|
||||||
@@ -2610,7 +2610,7 @@
|
|||||||
"it_IT": "",
|
"it_IT": "",
|
||||||
"ja_JP": "",
|
"ja_JP": "",
|
||||||
"ko_KR": "펌웨어 버전 : {0}",
|
"ko_KR": "펌웨어 버전 : {0}",
|
||||||
"no_NO": "",
|
"no_NO": "Fastvareversjon: {0}",
|
||||||
"pl_PL": "",
|
"pl_PL": "",
|
||||||
"pt_BR": "Versão do firmware: {0}",
|
"pt_BR": "Versão do firmware: {0}",
|
||||||
"ru_RU": "Версия прошивки: {0}",
|
"ru_RU": "Версия прошивки: {0}",
|
||||||
@@ -3460,7 +3460,7 @@
|
|||||||
"it_IT": "Corea",
|
"it_IT": "Corea",
|
||||||
"ja_JP": "韓国",
|
"ja_JP": "韓国",
|
||||||
"ko_KR": "한국",
|
"ko_KR": "한국",
|
||||||
"no_NO": "",
|
"no_NO": "Koreansk",
|
||||||
"pl_PL": "",
|
"pl_PL": "",
|
||||||
"pt_BR": "Coreia",
|
"pt_BR": "Coreia",
|
||||||
"ru_RU": "Корея",
|
"ru_RU": "Корея",
|
||||||
@@ -4010,7 +4010,7 @@
|
|||||||
"it_IT": "",
|
"it_IT": "",
|
||||||
"ja_JP": "",
|
"ja_JP": "",
|
||||||
"ko_KR": "PC 날짜와 시간에 동기화",
|
"ko_KR": "PC 날짜와 시간에 동기화",
|
||||||
"no_NO": "",
|
"no_NO": "Resynkroniser til PC-dato og -klokkeslett",
|
||||||
"pl_PL": "",
|
"pl_PL": "",
|
||||||
"pt_BR": "",
|
"pt_BR": "",
|
||||||
"ru_RU": "Повторная синхронизация с датой и временем на компьютере",
|
"ru_RU": "Повторная синхронизация с датой и временем на компьютере",
|
||||||
@@ -15260,7 +15260,7 @@
|
|||||||
"it_IT": "",
|
"it_IT": "",
|
||||||
"ja_JP": "",
|
"ja_JP": "",
|
||||||
"ko_KR": "시스템 시간을 PC의 현재 날짜 및 시간과 일치하도록 다시 동기화합니다.\n\n이 설정은 활성 설정이 아니므로 여전히 동기화되지 않을 수 있으며, 이 경우 이 버튼을 다시 클릭하면 됩니다.",
|
"ko_KR": "시스템 시간을 PC의 현재 날짜 및 시간과 일치하도록 다시 동기화합니다.\n\n이 설정은 활성 설정이 아니므로 여전히 동기화되지 않을 수 있으며, 이 경우 이 버튼을 다시 클릭하면 됩니다.",
|
||||||
"no_NO": "",
|
"no_NO": "Resynkroniser systemtiden slik at den samsvarer med PC-ens gjeldende dato og klokkeslett. \\Dette er ikke en aktiv innstilling, men den kan likevel komme ut av synkronisering; i så fall er det bare å klikke på denne knappen igjen.",
|
||||||
"pl_PL": "",
|
"pl_PL": "",
|
||||||
"pt_BR": "",
|
"pt_BR": "",
|
||||||
"ru_RU": "Повторно синхронизирует системное время, чтобы оно соответствовало текущей дате и времени вашего компьютера.\n\nЭто не активная настройка, она все еще может рассинхронизироваться; в этом случае просто нажмите эту кнопку еще раз.",
|
"ru_RU": "Повторно синхронизирует системное время, чтобы оно соответствовало текущей дате и времени вашего компьютера.\n\nЭто не активная настройка, она все еще может рассинхронизироваться; в этом случае просто нажмите эту кнопку еще раз.",
|
||||||
@@ -20535,7 +20535,7 @@
|
|||||||
"it_IT": "",
|
"it_IT": "",
|
||||||
"ja_JP": "",
|
"ja_JP": "",
|
||||||
"ko_KR": "Vulkan을 사용합니다.\nARM 맥에서 해당 플랫폼에서 잘 실행되는 게임을 플레이하는 경우 Metal 후단부를 사용합니다.",
|
"ko_KR": "Vulkan을 사용합니다.\nARM 맥에서 해당 플랫폼에서 잘 실행되는 게임을 플레이하는 경우 Metal 후단부를 사용합니다.",
|
||||||
"no_NO": "",
|
"no_NO": "Bruker Vulkan \nPå en ARM Mac, og når du spiller et spill som kjører bra under den, bruker du Metal-backend.",
|
||||||
"pl_PL": "",
|
"pl_PL": "",
|
||||||
"pt_BR": "",
|
"pt_BR": "",
|
||||||
"ru_RU": "Использует Vulkan.\nНа Mac с ARM процессорами используется Metal, если игра с ним совместима и хорошо работает.",
|
"ru_RU": "Использует Vulkan.\nНа Mac с ARM процессорами используется Metal, если игра с ним совместима и хорошо работает.",
|
||||||
@@ -22598,4 +22598,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ namespace Ryujinx.Headless
|
|||||||
// Make process DPI aware for proper window sizing on high-res screens.
|
// Make process DPI aware for proper window sizing on high-res screens.
|
||||||
ForceDpiAware.Windows();
|
ForceDpiAware.Windows();
|
||||||
|
|
||||||
Console.Title = $"Ryujinx Console {Program.Version} (Headless)";
|
Console.Title = $"HeadlessRyujinx Console {Program.Version}";
|
||||||
|
|
||||||
if (OperatingSystem.IsMacOS() || OperatingSystem.IsLinux())
|
if (OperatingSystem.IsMacOS() || OperatingSystem.IsLinux())
|
||||||
{
|
{
|
||||||
@@ -162,6 +162,11 @@ namespace Ryujinx.Headless
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReloadConfig();
|
ReloadConfig();
|
||||||
|
|
||||||
|
if (option.InheritConfig)
|
||||||
|
{
|
||||||
|
option.InheritMainConfigInput(originalArgs, ConfigurationState.Instance);
|
||||||
|
}
|
||||||
|
|
||||||
_virtualFileSystem = VirtualFileSystem.CreateInstance();
|
_virtualFileSystem = VirtualFileSystem.CreateInstance();
|
||||||
_libHacHorizonManager = new LibHacHorizonManager();
|
_libHacHorizonManager = new LibHacHorizonManager();
|
||||||
@@ -224,15 +229,7 @@ namespace Ryujinx.Headless
|
|||||||
_enableKeyboard = option.EnableKeyboard;
|
_enableKeyboard = option.EnableKeyboard;
|
||||||
_enableMouse = option.EnableMouse;
|
_enableMouse = option.EnableMouse;
|
||||||
|
|
||||||
static void LoadPlayerConfiguration(string inputProfileName, string inputId, PlayerIndex index)
|
|
||||||
{
|
|
||||||
InputConfig inputConfig = HandlePlayerConfiguration(inputProfileName, inputId, index);
|
|
||||||
|
|
||||||
if (inputConfig != null)
|
|
||||||
{
|
|
||||||
_inputConfiguration.Add(inputConfig);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadPlayerConfiguration(option.InputProfile1Name, option.InputId1, PlayerIndex.Player1);
|
LoadPlayerConfiguration(option.InputProfile1Name, option.InputId1, PlayerIndex.Player1);
|
||||||
LoadPlayerConfiguration(option.InputProfile2Name, option.InputId2, PlayerIndex.Player2);
|
LoadPlayerConfiguration(option.InputProfile2Name, option.InputId2, PlayerIndex.Player2);
|
||||||
@@ -244,7 +241,6 @@ namespace Ryujinx.Headless
|
|||||||
LoadPlayerConfiguration(option.InputProfile8Name, option.InputId8, PlayerIndex.Player8);
|
LoadPlayerConfiguration(option.InputProfile8Name, option.InputId8, PlayerIndex.Player8);
|
||||||
LoadPlayerConfiguration(option.InputProfileHandheldName, option.InputIdHandheld, PlayerIndex.Handheld);
|
LoadPlayerConfiguration(option.InputProfileHandheldName, option.InputIdHandheld, PlayerIndex.Handheld);
|
||||||
|
|
||||||
|
|
||||||
if (_inputConfiguration.Count == 0)
|
if (_inputConfiguration.Count == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -306,6 +302,24 @@ namespace Ryujinx.Headless
|
|||||||
}
|
}
|
||||||
|
|
||||||
_inputManager.Dispose();
|
_inputManager.Dispose();
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
void LoadPlayerConfiguration(string inputProfileName, string inputId, PlayerIndex index)
|
||||||
|
{
|
||||||
|
if (index == PlayerIndex.Handheld && _inputConfiguration.Count > 0)
|
||||||
|
{
|
||||||
|
Logger.Info?.Print(LogClass.Configuration, "Skipping handheld configuration as there are already other players configured.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputConfig inputConfig = option.InheritedInputConfigs[index] ?? HandlePlayerConfiguration(inputProfileName, inputId, index);
|
||||||
|
|
||||||
|
if (inputConfig != null)
|
||||||
|
{
|
||||||
|
_inputConfiguration.Add(inputConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SetupProgressHandler()
|
private static void SetupProgressHandler()
|
||||||
|
|||||||
@@ -154,10 +154,37 @@ namespace Ryujinx.Headless
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
bool NeedsOverride(string argKey) => originalArgs.None(arg => arg.TrimStart('-').EqualsIgnoreCase(OptionName(argKey)));
|
bool NeedsOverride(string argKey) => originalArgs.None(arg => arg.TrimStart('-').EqualsIgnoreCase(OptionName(argKey)));
|
||||||
|
|
||||||
string OptionName(string propertyName) =>
|
|
||||||
typeof(Options)!.GetProperty(propertyName)!.GetCustomAttribute<OptionAttribute>()!.LongName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void InheritMainConfigInput(string[] originalArgs, ConfigurationState configurationState)
|
||||||
|
{
|
||||||
|
Dictionary<PlayerIndex, (string InputId, string InputProfileName)> indicesToProperties = new()
|
||||||
|
{
|
||||||
|
{ PlayerIndex.Handheld, (nameof(InputIdHandheld), nameof(InputProfileHandheldName)) },
|
||||||
|
{ PlayerIndex.Player1, (nameof(InputId1), nameof(InputProfile1Name)) },
|
||||||
|
{ PlayerIndex.Player2, (nameof(InputId2), nameof(InputProfile2Name)) },
|
||||||
|
{ PlayerIndex.Player3, (nameof(InputId3), nameof(InputProfile3Name)) },
|
||||||
|
{ PlayerIndex.Player4, (nameof(InputId4), nameof(InputProfile4Name)) },
|
||||||
|
{ PlayerIndex.Player5, (nameof(InputId5), nameof(InputProfile5Name)) },
|
||||||
|
{ PlayerIndex.Player6, (nameof(InputId6), nameof(InputProfile6Name)) },
|
||||||
|
{ PlayerIndex.Player7, (nameof(InputId7), nameof(InputProfile7Name)) },
|
||||||
|
{ PlayerIndex.Player8, (nameof(InputId8), nameof(InputProfile8Name)) }
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach ((PlayerIndex playerIndex, _) in indicesToProperties
|
||||||
|
.Where(it => NeedsOverride(it.Value.InputId) && NeedsOverride(it.Value.InputProfileName)))
|
||||||
|
{
|
||||||
|
configurationState.Hid.InputConfig.Value.FindFirst(x => x.PlayerIndex == playerIndex)
|
||||||
|
.IfPresent(ic => InheritedInputConfigs[playerIndex] = ic);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool NeedsOverride(string argKey) => originalArgs.None(arg => arg.TrimStart('-').EqualsIgnoreCase(OptionName(argKey)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string OptionName(string propertyName) =>
|
||||||
|
typeof(Options)!.GetProperty(propertyName)!.GetCustomAttribute<OptionAttribute>()!.LongName;
|
||||||
|
|
||||||
// General
|
// General
|
||||||
|
|
||||||
@@ -391,5 +418,7 @@ namespace Ryujinx.Headless
|
|||||||
|
|
||||||
[Value(0, MetaName = "input", HelpText = "Input to load.", Required = true)]
|
[Value(0, MetaName = "input", HelpText = "Input to load.", Required = true)]
|
||||||
public string InputPath { get; set; }
|
public string InputPath { get; set; }
|
||||||
|
|
||||||
|
public SafeDictionary<PlayerIndex, InputConfig> InheritedInputConfigs = new();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
<UserControl
|
|
||||||
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"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
d:DesignWidth="800"
|
|
||||||
d:DesignHeight="450"
|
|
||||||
x:Class="Ryujinx.Ava.UI.Renderer.RendererHost"
|
|
||||||
FlowDirection="LeftToRight"
|
|
||||||
Focusable="True">
|
|
||||||
</UserControl>
|
|
||||||
@@ -1,16 +1,15 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Gommon;
|
using Avalonia.Media;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Utilities.Configuration;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Renderer
|
namespace Ryujinx.Ava.UI.Renderer
|
||||||
{
|
{
|
||||||
public partial class RendererHost : UserControl, IDisposable
|
public class RendererHost : UserControl, IDisposable
|
||||||
{
|
{
|
||||||
public readonly EmbeddedWindow EmbeddedWindow;
|
public readonly EmbeddedWindow EmbeddedWindow;
|
||||||
|
|
||||||
@@ -19,7 +18,8 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||||||
|
|
||||||
public RendererHost()
|
public RendererHost()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
Focusable = true;
|
||||||
|
FlowDirection = FlowDirection.LeftToRight;
|
||||||
|
|
||||||
EmbeddedWindow = ConfigurationState.Instance.Graphics.GraphicsBackend.Value switch
|
EmbeddedWindow = ConfigurationState.Instance.Graphics.GraphicsBackend.Value switch
|
||||||
{
|
{
|
||||||
@@ -43,8 +43,6 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||||||
|
|
||||||
public RendererHost(string titleId)
|
public RendererHost(string titleId)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
|
||||||
|
|
||||||
switch (TitleIDs.SelectGraphicsBackend(titleId, ConfigurationState.Instance.Graphics.GraphicsBackend))
|
switch (TitleIDs.SelectGraphicsBackend(titleId, ConfigurationState.Instance.Graphics.GraphicsBackend))
|
||||||
{
|
{
|
||||||
case GraphicsBackend.OpenGl:
|
case GraphicsBackend.OpenGl:
|
||||||
@@ -109,3 +107,4 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,9 +106,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
// NOTE(jpr): this works around a bug where calling _views.Clear also clears SelectedDownloadableContents for
|
// NOTE(jpr): this works around a bug where calling _views.Clear also clears SelectedDownloadableContents for
|
||||||
// some reason. so we save the items here and add them back after
|
// some reason. so we save the items here and add them back after
|
||||||
var items = SelectedDownloadableContents.ToArray();
|
var items = SelectedDownloadableContents.ToArray();
|
||||||
|
|
||||||
_views.Clear();
|
Views.Clear();
|
||||||
_views.AddRange(view);
|
Views.AddRange(view);
|
||||||
|
|
||||||
foreach (DownloadableContentModel item in items)
|
foreach (DownloadableContentModel item in items)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -182,7 +182,11 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
Applications.ToObservableChangeSet()
|
Applications.ToObservableChangeSet()
|
||||||
.Filter(Filter)
|
.Filter(Filter)
|
||||||
.Sort(GetComparer())
|
.Sort(GetComparer())
|
||||||
|
.OnItemAdded(_ => OnPropertyChanged(nameof(AppsObservableList)))
|
||||||
|
.OnItemRemoved(_ => OnPropertyChanged(nameof(AppsObservableList)))
|
||||||
|
#pragma warning disable MVVMTK0034 // Event to update is fired below
|
||||||
.Bind(out _appsObservableList)
|
.Bind(out _appsObservableList)
|
||||||
|
#pragma warning restore MVVMTK0034
|
||||||
.AsObservableList();
|
.AsObservableList();
|
||||||
|
|
||||||
_rendererWaitEvent = new AutoResetEvent(false);
|
_rendererWaitEvent = new AutoResetEvent(false);
|
||||||
@@ -192,8 +196,8 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
LoadConfigurableHotKeys();
|
LoadConfigurableHotKeys();
|
||||||
|
|
||||||
Volume = ConfigurationState.Instance.System.AudioVolume;
|
Volume = ConfigurationState.Instance.System.AudioVolume;
|
||||||
|
CustomVSyncInterval = ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value;
|
||||||
}
|
}
|
||||||
CustomVSyncInterval = ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(
|
public void Initialize(
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Avalonia.Collections;
|
using Avalonia.Collections;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using LibHac.Tools.FsSystem;
|
using LibHac.Tools.FsSystem;
|
||||||
using Ryujinx.Audio.Backends.OpenAL;
|
using Ryujinx.Audio.Backends.OpenAL;
|
||||||
@@ -46,9 +47,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
private int _resolutionScale;
|
private int _resolutionScale;
|
||||||
private int _graphicsBackendMultithreadingIndex;
|
private int _graphicsBackendMultithreadingIndex;
|
||||||
private float _volume;
|
private float _volume;
|
||||||
private bool _isVulkanAvailable = true;
|
[ObservableProperty] private bool _isVulkanAvailable = true;
|
||||||
private bool _gameDirectoryChanged;
|
[ObservableProperty] private bool _gameDirectoryChanged;
|
||||||
private bool _autoloadDirectoryChanged;
|
[ObservableProperty] private bool _autoloadDirectoryChanged;
|
||||||
private readonly List<string> _gpuIds = new();
|
private readonly List<string> _gpuIds = new();
|
||||||
private int _graphicsBackendIndex;
|
private int _graphicsBackendIndex;
|
||||||
private int _scalingFilter;
|
private int _scalingFilter;
|
||||||
@@ -63,7 +64,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
private int _networkInterfaceIndex;
|
private int _networkInterfaceIndex;
|
||||||
private int _multiplayerModeIndex;
|
private int _multiplayerModeIndex;
|
||||||
private string _ldnPassphrase;
|
private string _ldnPassphrase;
|
||||||
private string _ldnServer;
|
[ObservableProperty] private string _ldnServer;
|
||||||
|
|
||||||
public SettingsHacksViewModel DirtyHacks { get; }
|
public SettingsHacksViewModel DirtyHacks { get; }
|
||||||
|
|
||||||
@@ -111,43 +112,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsVulkanAvailable
|
|
||||||
{
|
|
||||||
get => _isVulkanAvailable;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_isVulkanAvailable = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsOpenGLAvailable => !OperatingSystem.IsMacOS();
|
public bool IsOpenGLAvailable => !OperatingSystem.IsMacOS();
|
||||||
|
|
||||||
public bool IsAppleSiliconMac => OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64;
|
public bool IsAppleSiliconMac => OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64;
|
||||||
|
|
||||||
public bool GameDirectoryChanged
|
|
||||||
{
|
|
||||||
get => _gameDirectoryChanged;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_gameDirectoryChanged = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AutoloadDirectoryChanged
|
|
||||||
{
|
|
||||||
get => _autoloadDirectoryChanged;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_autoloadDirectoryChanged = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsMacOS => OperatingSystem.IsMacOS();
|
public bool IsMacOS => OperatingSystem.IsMacOS();
|
||||||
|
|
||||||
public bool EnableDiscordIntegration { get; set; }
|
public bool EnableDiscordIntegration { get; set; }
|
||||||
@@ -182,19 +150,12 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
_customVSyncInterval = newInterval;
|
_customVSyncInterval = newInterval;
|
||||||
_customVSyncIntervalPercentageProxy = value;
|
_customVSyncIntervalPercentageProxy = value;
|
||||||
OnPropertiesChanged(
|
OnPropertiesChanged(
|
||||||
nameof(CustomVSyncInterval),
|
nameof(CustomVSyncInterval),
|
||||||
nameof(CustomVSyncIntervalPercentageText));
|
nameof(CustomVSyncIntervalPercentageText));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string CustomVSyncIntervalPercentageText
|
public string CustomVSyncIntervalPercentageText => CustomVSyncIntervalPercentageProxy + "%";
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
string text = CustomVSyncIntervalPercentageProxy + "%";
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool EnableCustomVSyncInterval
|
public bool EnableCustomVSyncInterval
|
||||||
{
|
{
|
||||||
@@ -356,7 +317,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
_networkInterfaceIndex = value != -1 ? value : 0;
|
_networkInterfaceIndex = value != -1 ? value : 0;
|
||||||
ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value = _networkInterfaces[NetworkInterfaceList[_networkInterfaceIndex]];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,7 +326,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
_multiplayerModeIndex = value;
|
_multiplayerModeIndex = value;
|
||||||
ConfigurationState.Instance.Multiplayer.Mode.Value = (MultiplayerMode)_multiplayerModeIndex;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,16 +334,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
public bool IsInvalidLdnPassphraseVisible { get; set; }
|
public bool IsInvalidLdnPassphraseVisible { get; set; }
|
||||||
|
|
||||||
public string LdnServer
|
|
||||||
{
|
|
||||||
get => _ldnServer;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_ldnServer = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public SettingsViewModel(VirtualFileSystem virtualFileSystem, ContentManager contentManager) : this()
|
public SettingsViewModel(VirtualFileSystem virtualFileSystem, ContentManager contentManager) : this()
|
||||||
{
|
{
|
||||||
_virtualFileSystem = virtualFileSystem;
|
_virtualFileSystem = virtualFileSystem;
|
||||||
@@ -647,16 +596,14 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
config.ShowTitleBar.Value = ShowTitleBar;
|
config.ShowTitleBar.Value = ShowTitleBar;
|
||||||
config.HideCursor.Value = (HideCursorMode)HideCursor;
|
config.HideCursor.Value = (HideCursorMode)HideCursor;
|
||||||
|
|
||||||
if (_gameDirectoryChanged)
|
if (GameDirectoryChanged)
|
||||||
{
|
{
|
||||||
List<string> gameDirs = new(GameDirectories);
|
config.UI.GameDirs.Value = [..GameDirectories];
|
||||||
config.UI.GameDirs.Value = gameDirs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_autoloadDirectoryChanged)
|
if (AutoloadDirectoryChanged)
|
||||||
{
|
{
|
||||||
List<string> autoloadDirs = new(AutoloadDirectories);
|
config.UI.AutoloadDirs.Value = [..AutoloadDirectories];
|
||||||
config.UI.AutoloadDirs.Value = autoloadDirs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
config.UI.BaseStyle.Value = BaseStyleIndex switch
|
config.UI.BaseStyle.Value = BaseStyleIndex switch
|
||||||
@@ -766,8 +713,8 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
SaveSettingsEvent?.Invoke();
|
SaveSettingsEvent?.Invoke();
|
||||||
|
|
||||||
_gameDirectoryChanged = false;
|
GameDirectoryChanged = false;
|
||||||
_autoloadDirectoryChanged = false;
|
AutoloadDirectoryChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RevertIfNotSaved()
|
private static void RevertIfNotSaved()
|
||||||
|
|||||||
@@ -247,6 +247,7 @@
|
|||||||
Header="{ext:Locale MenuBarActionsScanAmiiboBin}"
|
Header="{ext:Locale MenuBarActionsScanAmiiboBin}"
|
||||||
Icon="{ext:Icon mdi-cube-scan}"
|
Icon="{ext:Icon mdi-cube-scan}"
|
||||||
IsVisible="{Binding CanScanAmiiboBinaries}"
|
IsVisible="{Binding CanScanAmiiboBinaries}"
|
||||||
|
InputGesture="Ctrl + B"
|
||||||
IsEnabled="{Binding IsAmiiboBinRequested}" />
|
IsEnabled="{Binding IsAmiiboBinRequested}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding TakeScreenshot}"
|
Command="{Binding TakeScreenshot}"
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
<KeyBinding Gesture="F9" Command="{Binding ToggleDockMode}" />
|
<KeyBinding Gesture="F9" Command="{Binding ToggleDockMode}" />
|
||||||
<KeyBinding Gesture="Escape" Command="{Binding ExitCurrentState}" />
|
<KeyBinding Gesture="Escape" Command="{Binding ExitCurrentState}" />
|
||||||
<KeyBinding Gesture="Ctrl+A" Command="{Binding OpenAmiiboWindow}" />
|
<KeyBinding Gesture="Ctrl+A" Command="{Binding OpenAmiiboWindow}" />
|
||||||
|
<KeyBinding Gesture="Ctrl+B" Command="{Binding OpenBinFile}" />
|
||||||
</Window.KeyBindings>
|
</Window.KeyBindings>
|
||||||
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RowDefinitions="*">
|
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RowDefinitions="*">
|
||||||
<helpers:OffscreenTextBox IsEnabled="False" Opacity="0" Name="HiddenTextBox" IsHitTestVisible="False" IsTabStop="False" />
|
<helpers:OffscreenTextBox IsEnabled="False" Opacity="0" Name="HiddenTextBox" IsHitTestVisible="False" IsTabStop="False" />
|
||||||
|
|||||||
Reference in New Issue
Block a user