diff --git a/src/Ryujinx.Common/Configuration/DirtyHack.cs b/src/Ryujinx.Common/Configuration/DirtyHack.cs index 3959c0a99..71ac88f56 100644 --- a/src/Ryujinx.Common/Configuration/DirtyHack.cs +++ b/src/Ryujinx.Common/Configuration/DirtyHack.cs @@ -9,7 +9,8 @@ namespace Ryujinx.Common.Configuration public enum DirtyHack : byte { Xc2MenuSoftlockFix = 1, - ShaderTranslationDelay = 2 + // ShaderTranslationDelay = 2 + NifmServiceDisableIsAnyInternetRequestAccepted = 3 } public readonly struct EnabledDirtyHack(DirtyHack hack, int value) diff --git a/src/Ryujinx.Common/TitleIDs.cs b/src/Ryujinx.Common/TitleIDs.cs index 82be1572f..76a8a7126 100644 --- a/src/Ryujinx.Common/TitleIDs.cs +++ b/src/Ryujinx.Common/TitleIDs.cs @@ -1,7 +1,4 @@ using Gommon; -using Ryujinx.Common.Configuration; -using Ryujinx.Common.Helper; -using System; using System.Linq; namespace Ryujinx.Common diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/IStaticService.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/IStaticService.cs index 96e71cd07..d669caba1 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nifm/IStaticService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/IStaticService.cs @@ -13,7 +13,7 @@ namespace Ryujinx.HLE.HOS.Services.Nifm // CreateGeneralServiceOld() -> object public ResultCode CreateGeneralServiceOld(ServiceCtx context) { - MakeObject(context, new IGeneralService()); + MakeObject(context, new IGeneralService(context)); return ResultCode.Success; } @@ -22,7 +22,7 @@ namespace Ryujinx.HLE.HOS.Services.Nifm // CreateGeneralService(u64, pid) -> object public ResultCode CreateGeneralService(ServiceCtx context) { - MakeObject(context, new IGeneralService()); + MakeObject(context, new IGeneralService(context)); return ResultCode.Success; } diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs index a5a822db3..dd4efce6e 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs @@ -1,4 +1,5 @@ using Ryujinx.Common; +using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.Common.Utilities; using Ryujinx.HLE.HOS.Services.Nifm.StaticService.GeneralService; @@ -17,12 +18,12 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService private UnicastIPAddressInformation _targetAddressInfoCache = null; private string _cacheChosenInterface = null; - public IGeneralService() + public IGeneralService(ServiceCtx context) { _generalServiceDetail = new GeneralServiceDetail { ClientId = GeneralServiceManager.Count, - IsAnyInternetRequestAccepted = true, // NOTE: Why not accept any internet request? + IsAnyInternetRequestAccepted = !context.Device.DirtyHacks.IsEnabled(DirtyHack.NifmServiceDisableIsAnyInternetRequestAccepted), // NOTE: Why not accept any internet request? }; NetworkChange.NetworkAddressChanged += LocalInterfaceCacheHandler; diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Proxy/SocketHelpers.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Proxy/SocketHelpers.cs index b442cf802..660803714 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Proxy/SocketHelpers.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Proxy/SocketHelpers.cs @@ -1,6 +1,5 @@ using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnRyu.Proxy; -using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; using System; using System.Collections.Generic; using System.Linq; diff --git a/src/Ryujinx/Common/LocaleManager.cs b/src/Ryujinx/Common/LocaleManager.cs index 9aa82a4a5..d116fe709 100644 --- a/src/Ryujinx/Common/LocaleManager.cs +++ b/src/Ryujinx/Common/LocaleManager.cs @@ -38,8 +38,8 @@ namespace Ryujinx.Ava.Common.Locale { LocaleKeys.RyujinxConfirm, [RyujinxApp.FullAppName] }, { LocaleKeys.RyujinxUpdater, [RyujinxApp.FullAppName] }, { LocaleKeys.RyujinxRebooter, [RyujinxApp.FullAppName] }, - { LocaleKeys.CompatibilityListSearchBoxWatermarkWithCount, [CompatibilityCsv.Entries.Length] }, - { LocaleKeys.CompatibilityListTitle, [CompatibilityCsv.Entries.Length] } + { LocaleKeys.CompatibilityListSearchBoxWatermarkWithCount, [CompatibilityDatabase.Entries.Length] }, + { LocaleKeys.CompatibilityListTitle, [CompatibilityDatabase.Entries.Length] } }); Load(); diff --git a/src/Ryujinx/Common/Markup/MarkupExtensions.cs b/src/Ryujinx/Common/Markup/MarkupExtensions.cs index 26e9c3d3e..2c8290847 100644 --- a/src/Ryujinx/Common/Markup/MarkupExtensions.cs +++ b/src/Ryujinx/Common/Markup/MarkupExtensions.cs @@ -1,5 +1,4 @@ using Avalonia.Markup.Xaml.MarkupExtensions; -using Humanizer; using Projektanker.Icons.Avalonia; using Ryujinx.Ava.Common.Locale; diff --git a/src/Ryujinx/Common/XCITrimmerLog.cs b/src/Ryujinx/Common/XCITrimmerLog.cs index b661d918d..751831a66 100644 --- a/src/Ryujinx/Common/XCITrimmerLog.cs +++ b/src/Ryujinx/Common/XCITrimmerLog.cs @@ -26,9 +26,9 @@ namespace Ryujinx.Ava.Common internal class TrimmerWindow : Ryujinx.Common.Logging.XCIFileTrimmerLog { - private readonly XCITrimmerViewModel _viewModel; + private readonly XciTrimmerViewModel _viewModel; - public TrimmerWindow(XCITrimmerViewModel viewModel) + public TrimmerWindow(XciTrimmerViewModel viewModel) { _viewModel = viewModel; } diff --git a/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs b/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs index 7ff0a5259..751a86571 100644 --- a/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs +++ b/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs @@ -2,6 +2,7 @@ using DiscordRPC; using LibHac.Tools.FsSystem; using Ryujinx.Audio.Backends.SDL2; using Ryujinx.Ava; +using Ryujinx.Ava.Systems; using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration.Hid; @@ -11,7 +12,6 @@ using Ryujinx.Common.Configuration.Hid.Keyboard; using Ryujinx.Common.Logging; using Ryujinx.Common.Utilities; using Ryujinx.Graphics.GAL; -using Ryujinx.Graphics.GAL.Multithreading; using Ryujinx.Graphics.OpenGL; using Ryujinx.Graphics.Vulkan; using Ryujinx.HLE; diff --git a/src/Ryujinx/Program.cs b/src/Ryujinx/Program.cs index c24725b5c..016cc348a 100644 --- a/src/Ryujinx/Program.cs +++ b/src/Ryujinx/Program.cs @@ -5,6 +5,7 @@ using Gommon; using Projektanker.Icons.Avalonia; using Projektanker.Icons.Avalonia.FontAwesome; using Projektanker.Icons.Avalonia.MaterialDesign; +using Ryujinx.Ava.Systems; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.Utilities; diff --git a/src/Ryujinx/Ryujinx.csproj b/src/Ryujinx/Ryujinx.csproj index 698b392ee..1f9642466 100644 --- a/src/Ryujinx/Ryujinx.csproj +++ b/src/Ryujinx/Ryujinx.csproj @@ -91,10 +91,12 @@ Always THIRDPARTY.md + False Always LICENSE.txt + False diff --git a/src/Ryujinx/AppHost.cs b/src/Ryujinx/Systems/AppHost.cs similarity index 99% rename from src/Ryujinx/AppHost.cs rename to src/Ryujinx/Systems/AppHost.cs index 13f36d695..455afaf45 100644 --- a/src/Ryujinx/AppHost.cs +++ b/src/Ryujinx/Systems/AppHost.cs @@ -6,7 +6,6 @@ using Avalonia.Threading; using DiscordRPC; using LibHac.Common; using LibHac.Ns; -using LibHac.Tools.FsSystem; using Ryujinx.Audio.Backends.Dummy; using Ryujinx.Audio.Backends.OpenAL; using Ryujinx.Audio.Backends.SDL2; @@ -35,11 +34,9 @@ using Ryujinx.Graphics.GAL.Multithreading; using Ryujinx.Graphics.Gpu; using Ryujinx.Graphics.OpenGL; using Ryujinx.Graphics.Vulkan; -using Ryujinx.HLE; using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.HOS; using Ryujinx.HLE.HOS.Services.Account.Acc; -using Ryujinx.HLE.HOS.SystemState; using Ryujinx.Input; using Ryujinx.Input.HLE; using SkiaSharp; @@ -62,7 +59,7 @@ using Size = Avalonia.Size; using Switch = Ryujinx.HLE.Switch; using VSyncMode = Ryujinx.Common.Configuration.VSyncMode; -namespace Ryujinx.Ava +namespace Ryujinx.Ava.Systems { internal class AppHost { diff --git a/src/Ryujinx/Systems/AppLibrary/ApplicationData.cs b/src/Ryujinx/Systems/AppLibrary/ApplicationData.cs index e04ea454a..0819b86b8 100644 --- a/src/Ryujinx/Systems/AppLibrary/ApplicationData.cs +++ b/src/Ryujinx/Systems/AppLibrary/ApplicationData.cs @@ -36,7 +36,7 @@ namespace Ryujinx.Ava.Systems.AppLibrary { _id = value; - Compatibility = CompatibilityCsv.Find(value); + Compatibility = CompatibilityDatabase.Find(value); RichPresenceSpec = PlayReports.Analyzer.TryGetSpec(IdString, out GameSpec gameSpec) ? gameSpec : default(Optional); diff --git a/src/Ryujinx/Systems/AppLibrary/LdnGameDataReceivedEventArgs.cs b/src/Ryujinx/Systems/AppLibrary/LdnGameDataReceivedEventArgs.cs index 6c80c1924..21d24ff2d 100644 --- a/src/Ryujinx/Systems/AppLibrary/LdnGameDataReceivedEventArgs.cs +++ b/src/Ryujinx/Systems/AppLibrary/LdnGameDataReceivedEventArgs.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; namespace Ryujinx.Ava.Systems.AppLibrary { diff --git a/src/Ryujinx/Systems/CompatibilityCsv.cs b/src/Ryujinx/Systems/CompatibilityDatabase.cs similarity index 82% rename from src/Ryujinx/Systems/CompatibilityCsv.cs rename to src/Ryujinx/Systems/CompatibilityDatabase.cs index 9bab87d9f..bfc7ba903 100644 --- a/src/Ryujinx/Systems/CompatibilityCsv.cs +++ b/src/Ryujinx/Systems/CompatibilityDatabase.cs @@ -11,24 +11,9 @@ using System.Text; namespace Ryujinx.Ava.Systems { - public struct ColumnIndices(Func, int> getIndex) + public class CompatibilityDatabase { - public const string TitleIdCol = "\"title_id\""; - public const string GameNameCol = "\"game_name\""; - public const string LabelsCol = "\"labels\""; - public const string StatusCol = "\"status\""; - public const string LastUpdatedCol = "\"last_updated\""; - - public readonly int TitleId = getIndex(TitleIdCol); - public readonly int GameName = getIndex(GameNameCol); - public readonly int Labels = getIndex(LabelsCol); - public readonly int Status = getIndex(StatusCol); - public readonly int LastUpdated = getIndex(LastUpdatedCol); - } - - public class CompatibilityCsv - { - static CompatibilityCsv() => Load(); + static CompatibilityDatabase() => Load(); public static void Load() { @@ -65,16 +50,6 @@ namespace Ryujinx.Ava.Systems public static CompatibilityEntry Find(ulong titleId) => Find(titleId.ToString("X16")); - - public static LocaleKeys? GetStatus(string titleId) - => Find(titleId)?.Status; - - public static LocaleKeys? GetStatus(ulong titleId) => GetStatus(titleId.ToString("X16")); - - public static string GetLabels(string titleId) - => Find(titleId)?.FormattedIssueLabels; - - public static string GetLabels(ulong titleId) => GetLabels(titleId.ToString("X16")); } public class CompatibilityEntry @@ -135,6 +110,7 @@ namespace Ryujinx.Ava.Systems public string FormattedIssueLabels => Labels .Select(FormatLabelName) + .Where(x => x != null) .JoinToString(", "); public override string ToString() => @@ -158,7 +134,6 @@ namespace Ryujinx.Ava.Systems "gui" => "GUI", "help wanted" => "Help Wanted", "horizon" => "Horizon", - "infra" => "Project Infra", "invalid" => "Invalid", "kernel" => "Kernel", "ldn" => "LDN", @@ -172,9 +147,9 @@ namespace Ryujinx.Ava.Systems "ldn-untested" => "LDN Untested", "ldn-broken" => "LDN Broken", "ldn-partial" => "Partial LDN", - "nvdec" => "NVDEC", - "services" => "NX Services", - "services-horizon" => "Horizon OS Services", + "nvdec" => "GPU Video Decoding", + "services" => "HLE Services", + "services-horizon" => "New HLE Services", "slow" => "Runs Slow", "crash" => "Crashes", "deadlock" => "Deadlock", @@ -182,7 +157,7 @@ namespace Ryujinx.Ava.Systems "opengl" => "OpenGL", "opengl-backend-bug" => "OpenGL Backend Bug", "vulkan-backend-bug" => "Vulkan Backend Bug", - "mac-bug" => "Mac-specific Bug(s)", + "mac-bug" => "Mac-specific Problems", "amd-vendor-bug" => "AMD GPU Bug", "intel-vendor-bug" => "Intel GPU Bug", "loader-allocator" => "Loader Allocator", @@ -191,18 +166,22 @@ namespace Ryujinx.Ava.Systems "UE4" => "Unreal Engine 4", "homebrew" => "Homebrew Content", "online-broken" => "Online Broken", - _ => Capitalize(labelName) + _ => null }; + } + + public struct ColumnIndices(Func, int> getIndex) + { + private const string TitleIdCol = "\"title_id\""; + private const string GameNameCol = "\"game_name\""; + private const string LabelsCol = "\"labels\""; + private const string StatusCol = "\"status\""; + private const string LastUpdatedCol = "\"last_updated\""; - public static string Capitalize(string value) - { - if (value == string.Empty) - return string.Empty; - - char firstChar = value[0]; - string rest = value[1..]; - - return $"{char.ToUpper(firstChar)}{rest}"; - } + public readonly int TitleId = getIndex(TitleIdCol); + public readonly int GameName = getIndex(GameNameCol); + public readonly int Labels = getIndex(LabelsCol); + public readonly int Status = getIndex(StatusCol); + public readonly int LastUpdated = getIndex(LastUpdatedCol); } } diff --git a/src/Ryujinx/Systems/Configuration/ConfigurationFileFormat.cs b/src/Ryujinx/Systems/Configuration/ConfigurationFileFormat.cs index 042f95c46..c5315ab12 100644 --- a/src/Ryujinx/Systems/Configuration/ConfigurationFileFormat.cs +++ b/src/Ryujinx/Systems/Configuration/ConfigurationFileFormat.cs @@ -15,7 +15,7 @@ namespace Ryujinx.Ava.Systems.Configuration /// /// The current version of the file format /// - public const int CurrentVersion = 67; + public const int CurrentVersion = 68; /// /// Version of the configuration file format diff --git a/src/Ryujinx/Systems/Configuration/ConfigurationState.Migration.cs b/src/Ryujinx/Systems/Configuration/ConfigurationState.Migration.cs index 16a4fab10..b10cc3926 100644 --- a/src/Ryujinx/Systems/Configuration/ConfigurationState.Migration.cs +++ b/src/Ryujinx/Systems/Configuration/ConfigurationState.Migration.cs @@ -160,9 +160,7 @@ namespace Ryujinx.Ava.Systems.Configuration DirtyHacks hacks = new (cff.DirtyHacks ?? []); Hacks.Xc2MenuSoftlockFix.Value = hacks.IsEnabled(DirtyHack.Xc2MenuSoftlockFix); - - Hacks.EnableShaderTranslationDelay.Value = hacks.IsEnabled(DirtyHack.ShaderTranslationDelay); - Hacks.ShaderTranslationDelay.Value = hacks[DirtyHack.ShaderTranslationDelay].CoerceAtLeast(0); + } if (configurationFileUpdated) @@ -441,6 +439,8 @@ namespace Ryujinx.Ava.Systems.Configuration (65, static cff => cff.UpdateCheckerType = cff.CheckUpdatesOnStart ? UpdaterType.PromptAtStartup : UpdaterType.Off), (66, static cff => cff.DisableInputWhenOutOfFocus = false), (67, static cff => cff.FocusLostActionType = cff.DisableInputWhenOutOfFocus ? FocusLostType.BlockInput : FocusLostType.DoNothing) + // 68 was the version that added per-game configs; the file structure did not change + // the version was increased so external tools could know that your Ryujinx version has per-game config capabilities. ); } } diff --git a/src/Ryujinx/Systems/Configuration/ConfigurationState.Model.cs b/src/Ryujinx/Systems/Configuration/ConfigurationState.Model.cs index 24ee6ec66..b52c624e3 100644 --- a/src/Ryujinx/Systems/Configuration/ConfigurationState.Model.cs +++ b/src/Ryujinx/Systems/Configuration/ConfigurationState.Model.cs @@ -11,7 +11,6 @@ using Ryujinx.Common.Helper; using Ryujinx.Common.Logging; using Ryujinx.Common.Utilities; using Ryujinx.HLE; -using Ryujinx.HLE.HOS.SystemState; using System.Collections.Generic; using System.Linq; using RyuLogger = Ryujinx.Common.Logging.Logger; @@ -684,18 +683,15 @@ namespace Ryujinx.Ava.Systems.Configuration public ReactiveObject Xc2MenuSoftlockFix { get; private set; } - public ReactiveObject EnableShaderTranslationDelay { get; private set; } - - public ReactiveObject ShaderTranslationDelay { get; private set; } + public ReactiveObject DisableNifmIsAnyInternetRequestAccepted { get; private set; } public HacksSection() { ShowDirtyHacks = new ReactiveObject(); Xc2MenuSoftlockFix = new ReactiveObject(); Xc2MenuSoftlockFix.Event += HackChanged; - EnableShaderTranslationDelay = new ReactiveObject(); - EnableShaderTranslationDelay.Event += HackChanged; - ShaderTranslationDelay = new ReactiveObject(); + DisableNifmIsAnyInternetRequestAccepted = new ReactiveObject(); + DisableNifmIsAnyInternetRequestAccepted.Event += HackChanged; } private void HackChanged(object sender, ReactiveEventArgs rxe) @@ -726,8 +722,8 @@ namespace Ryujinx.Ava.Systems.Configuration if (Xc2MenuSoftlockFix) Apply(DirtyHack.Xc2MenuSoftlockFix); - if (EnableShaderTranslationDelay) - Apply(DirtyHack.ShaderTranslationDelay, ShaderTranslationDelay); + if (DisableNifmIsAnyInternetRequestAccepted) + Apply(DirtyHack.NifmServiceDisableIsAnyInternetRequestAccepted); return enabledHacks.ToArray(); diff --git a/src/Ryujinx/DiscordIntegrationModule.cs b/src/Ryujinx/Systems/DiscordIntegrationModule.cs similarity index 98% rename from src/Ryujinx/DiscordIntegrationModule.cs rename to src/Ryujinx/Systems/DiscordIntegrationModule.cs index 142261d72..8a3b42ac8 100644 --- a/src/Ryujinx/DiscordIntegrationModule.cs +++ b/src/Ryujinx/Systems/DiscordIntegrationModule.cs @@ -9,10 +9,9 @@ using Ryujinx.Common.Logging; using Ryujinx.HLE; using Ryujinx.HLE.Loaders.Processes; using Ryujinx.Horizon; -using Ryujinx.Horizon.Prepo.Types; using System.Text; -namespace Ryujinx.Ava +namespace Ryujinx.Ava.Systems { public static class DiscordIntegrationModule { @@ -124,7 +123,7 @@ namespace Ryujinx.Ava _currentApp = null; } - private static void HandlePlayReport(PlayReport playReport) + private static void HandlePlayReport(Horizon.Prepo.Types.PlayReport playReport) { if (_discordClient is null) return; if (!TitleIDs.CurrentApplication.Value.HasValue) return; diff --git a/src/Ryujinx/Rebooter.cs b/src/Ryujinx/Systems/Rebooter.cs similarity index 96% rename from src/Ryujinx/Rebooter.cs rename to src/Ryujinx/Systems/Rebooter.cs index 8c7755a4c..4b149e9e3 100644 --- a/src/Ryujinx/Rebooter.cs +++ b/src/Ryujinx/Systems/Rebooter.cs @@ -1,8 +1,6 @@ using FluentAvalonia.UI.Controls; using Ryujinx.Ava.Common.Locale; -using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.Utilities; -using SkiaSharp; using System; using System.Collections.Generic; using System.Diagnostics; @@ -10,7 +8,7 @@ using System.IO; using System.Linq; using System.Threading.Tasks; -namespace Ryujinx.Ava +namespace Ryujinx.Ava.Systems { internal static class Rebooter { diff --git a/src/Ryujinx/Updater.cs b/src/Ryujinx/Systems/Updater.cs similarity index 99% rename from src/Ryujinx/Updater.cs rename to src/Ryujinx/Systems/Updater.cs index 7ca5e885a..850bacc60 100644 --- a/src/Ryujinx/Updater.cs +++ b/src/Ryujinx/Systems/Updater.cs @@ -27,7 +27,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; -namespace Ryujinx.Ava +namespace Ryujinx.Ava.Systems { internal static class Updater { diff --git a/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs b/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs index 9635582c8..64377ba51 100644 --- a/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs +++ b/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs @@ -9,10 +9,10 @@ using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Models; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.ViewModels; -using Ryujinx.Ava.UI.Views.Misc; using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Systems.AppLibrary; +using Ryujinx.Ava.UI.Views.Dialog; using Ryujinx.Common.Configuration; using Ryujinx.Common.Helper; using Ryujinx.HLE.HOS; @@ -80,13 +80,13 @@ namespace Ryujinx.Ava.UI.Controls public async void OpenTitleUpdateManager_Click(object sender, RoutedEventArgs args) { if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel }) - await TitleUpdateWindow.Show(viewModel.ApplicationLibrary, viewModel.SelectedApplication); + await TitleUpdateManagerView.Show(viewModel.ApplicationLibrary, viewModel.SelectedApplication); } public async void OpenDownloadableContentManager_Click(object sender, RoutedEventArgs args) { if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel }) - await DownloadableContentManagerWindow.Show(viewModel.ApplicationLibrary, viewModel.SelectedApplication); + await DownloadableContentManagerView.Show(viewModel.ApplicationLibrary, viewModel.SelectedApplication); } public async void OpenCheatManager_Click(object sender, RoutedEventArgs args) @@ -127,7 +127,7 @@ namespace Ryujinx.Ava.UI.Controls public async void OpenModManager_Click(object sender, RoutedEventArgs args) { if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel }) - await ModManagerWindow.Show( + await ModManagerView.Show( viewModel.SelectedApplication.Id, viewModel.SelectedApplication.IdBase, viewModel.ApplicationLibrary, diff --git a/src/Ryujinx/UI/Controls/RyujinxLogo.cs b/src/Ryujinx/UI/Controls/RyujinxLogo.cs index 3b52ecf03..89b89f311 100644 --- a/src/Ryujinx/UI/Controls/RyujinxLogo.cs +++ b/src/Ryujinx/UI/Controls/RyujinxLogo.cs @@ -1,6 +1,5 @@ using Avalonia; using Avalonia.Controls; -using Avalonia.Layout; using Avalonia.Media.Imaging; using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.UI.ViewModels; diff --git a/src/Ryujinx/UI/Windows/IconColorPicker.cs b/src/Ryujinx/UI/Helpers/IconColorPicker.cs similarity index 98% rename from src/Ryujinx/UI/Windows/IconColorPicker.cs rename to src/Ryujinx/UI/Helpers/IconColorPicker.cs index ca9ac2c05..b6ee8bbbf 100644 --- a/src/Ryujinx/UI/Windows/IconColorPicker.cs +++ b/src/Ryujinx/UI/Helpers/IconColorPicker.cs @@ -2,9 +2,9 @@ using SkiaSharp; using System; using System.Collections.Generic; -namespace Ryujinx.Ava.UI.Windows +namespace Ryujinx.Ava.UI.Helpers { - static class IconColorPicker + public static class IconColorPicker { private const int ColorsPerLine = 64; private const int TotalColors = ColorsPerLine * ColorsPerLine; diff --git a/src/Ryujinx/RyujinxApp.axaml b/src/Ryujinx/UI/RyujinxApp.axaml similarity index 100% rename from src/Ryujinx/RyujinxApp.axaml rename to src/Ryujinx/UI/RyujinxApp.axaml diff --git a/src/Ryujinx/RyujinxApp.axaml.cs b/src/Ryujinx/UI/RyujinxApp.axaml.cs similarity index 98% rename from src/Ryujinx/RyujinxApp.axaml.cs rename to src/Ryujinx/UI/RyujinxApp.axaml.cs index 0a0f0a13c..2f460f2b3 100644 --- a/src/Ryujinx/RyujinxApp.axaml.cs +++ b/src/Ryujinx/UI/RyujinxApp.axaml.cs @@ -7,12 +7,12 @@ using Avalonia.Styling; using Avalonia.Threading; using FluentAvalonia.UI.Windowing; using Gommon; -using Ryujinx.Ava.Common; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Systems.Configuration; +using Ryujinx.Ava.UI.Views.Dialog; using Ryujinx.Common; using Ryujinx.Common.Logging; using System; @@ -150,7 +150,7 @@ namespace Ryujinx.Ava private async void AboutRyujinx_OnClick(object sender, EventArgs e) { - await AboutWindow.Show(); + await AboutView.Show(); } } } diff --git a/src/Ryujinx/UI/ViewModels/AboutWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/AboutWindowViewModel.cs index 07aa84c04..6e1bd7ce3 100644 --- a/src/Ryujinx/UI/ViewModels/AboutWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/AboutWindowViewModel.cs @@ -3,7 +3,6 @@ using Avalonia.Styling; using Avalonia.Threading; using CommunityToolkit.Mvvm.ComponentModel; using Gommon; -using Ryujinx.Ava.Common; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Systems.Configuration; using System; diff --git a/src/Ryujinx/UI/ViewModels/CompatibilityViewModel.cs b/src/Ryujinx/UI/ViewModels/CompatibilityViewModel.cs index d6c10044d..1965fee69 100644 --- a/src/Ryujinx/UI/ViewModels/CompatibilityViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/CompatibilityViewModel.cs @@ -1,17 +1,17 @@ using Gommon; using Ryujinx.Ava.Systems; using Ryujinx.Ava.Systems.AppLibrary; -using Ryujinx.Ava.UI.Windows; +using System; using System.Collections.Generic; using System.Linq; namespace Ryujinx.Ava.UI.ViewModels { - public class CompatibilityViewModel : BaseModel + public class CompatibilityViewModel : BaseModel, IDisposable { - private bool _onlyShowOwnedGames = true; + private readonly ApplicationLibrary _appLibrary; - private IEnumerable _currentEntries = CompatibilityCsv.Entries; + private IEnumerable _currentEntries = CompatibilityDatabase.Entries; private string[] _ownedGameTitleIds = []; public IEnumerable CurrentEntries => OnlyShowOwnedGames @@ -20,15 +20,27 @@ namespace Ryujinx.Ava.UI.ViewModels : _currentEntries; public CompatibilityViewModel() {} + + private void AppCountUpdated(object _, ApplicationCountUpdatedEventArgs __) + => _ownedGameTitleIds = _appLibrary.Applications.Keys.Select(x => x.ToString("X16")).ToArray(); public CompatibilityViewModel(ApplicationLibrary appLibrary) { - appLibrary.ApplicationCountUpdated += (_, _) - => _ownedGameTitleIds = appLibrary.Applications.Keys.Select(x => x.ToString("X16")).ToArray(); + _appLibrary = appLibrary; - _ownedGameTitleIds = appLibrary.Applications.Keys.Select(x => x.ToString("X16")).ToArray(); + AppCountUpdated(null, null); + + _appLibrary.ApplicationCountUpdated += AppCountUpdated; } + void IDisposable.Dispose() + { + GC.SuppressFinalize(this); + _appLibrary.ApplicationCountUpdated -= AppCountUpdated; + } + + private bool _onlyShowOwnedGames = true; + public bool OnlyShowOwnedGames { get => _onlyShowOwnedGames; @@ -46,11 +58,11 @@ namespace Ryujinx.Ava.UI.ViewModels { if (string.IsNullOrEmpty(searchTerm)) { - SetEntries(CompatibilityCsv.Entries); + SetEntries(CompatibilityDatabase.Entries); return; } - SetEntries(CompatibilityCsv.Entries.Where(x => + SetEntries(CompatibilityDatabase.Entries.Where(x => x.GameName.ContainsIgnoreCase(searchTerm) || x.TitleId.Check(tid => tid.ContainsIgnoreCase(searchTerm)))); } diff --git a/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs index 2aaddb6d7..84e4ba5d7 100644 --- a/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs @@ -1,9 +1,5 @@ using Avalonia.Svg.Skia; using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.Input; -using FluentAvalonia.UI.Controls; -using Ryujinx.Ava.Input; -using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Models.Input; using Ryujinx.Ava.UI.Views.Input; using Ryujinx.Common.Utilities; diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs index 9442c6338..b0cd6a556 100644 --- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs @@ -3,7 +3,6 @@ using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Input; using Avalonia.Media; -using Avalonia.Media.Imaging; using Avalonia.Platform.Storage; using Avalonia.Threading; using CommunityToolkit.Mvvm.ComponentModel; @@ -17,6 +16,7 @@ using LibHac.Ns; using Ryujinx.Ava.Common; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Input; +using Ryujinx.Ava.Systems; using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Models; @@ -46,7 +46,6 @@ using System.Collections.ObjectModel; using System.Globalization; using System.IO; using System.Linq; -using System.Reflection; using System.Threading; using System.Threading.Tasks; using Key = Ryujinx.Input.Key; diff --git a/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs index 816e85c98..022b7481e 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs @@ -16,11 +16,12 @@ namespace Ryujinx.Ava.UI.ViewModels } [ObservableProperty] private bool _xc2MenuSoftlockFix = ConfigurationState.Instance.Hacks.Xc2MenuSoftlockFix; + [ObservableProperty] private bool _nifmDisableIsAnyInternetRequestAccepted = ConfigurationState.Instance.Hacks.DisableNifmIsAnyInternetRequestAccepted; public static string Xc2MenuFixTooltip { get; } = Lambda.String(sb => { sb.AppendLine( - "This fix applies a 2ms delay (via 'Thread.Sleep(2)') every time the game tries to read data from the emulated Switch filesystem.") + "This hack applies a 2ms delay (via 'Thread.Sleep(2)') every time the game tries to read data from the emulated Switch filesystem.") .AppendLine(); sb.AppendLine("From the issue on GitHub:").AppendLine(); @@ -29,5 +30,14 @@ namespace Ryujinx.Ava.UI.ViewModels "there is a low chance that the game will softlock, " + "the submenu won't show up, while background music is still there."); }); + + public static string NifmDisableIsAnyInternetRequestAcceptedTooltip { get; } = Lambda.String(sb => + { + sb.AppendLine( + "This hack simply sets 'IsAnyInternetRequestAccepted' to 'false' when initializing the Nifm IGeneralService.") + .AppendLine(); + + sb.Append("Lets DOOM 2016 go in game."); + }); } } diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs index 5dc5b789f..a092e97f2 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs @@ -757,6 +757,8 @@ namespace Ryujinx.Ava.UI.ViewModels // Dirty Hacks config.Hacks.Xc2MenuSoftlockFix.Value = DirtyHacks.Xc2MenuSoftlockFix; + config.Hacks.DisableNifmIsAnyInternetRequestAccepted.Value = + DirtyHacks.NifmDisableIsAnyInternetRequestAccepted; config.ToFileFormat().SaveConfig(Program.ConfigurationPath); diff --git a/src/Ryujinx/UI/ViewModels/XCITrimmerViewModel.cs b/src/Ryujinx/UI/ViewModels/XciTrimmerViewModel.cs similarity index 98% rename from src/Ryujinx/UI/ViewModels/XCITrimmerViewModel.cs rename to src/Ryujinx/UI/ViewModels/XciTrimmerViewModel.cs index a48efcbd5..2085ffe26 100644 --- a/src/Ryujinx/UI/ViewModels/XCITrimmerViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/XciTrimmerViewModel.cs @@ -16,7 +16,7 @@ using static Ryujinx.Common.Utilities.XCIFileTrimmer; namespace Ryujinx.Ava.UI.ViewModels { - public class XCITrimmerViewModel : BaseModel + public class XciTrimmerViewModel : BaseModel { private const long _bytesPerMB = 1024 * 1024; private enum ProcessingMode @@ -46,7 +46,7 @@ namespace Ryujinx.Ava.UI.ViewModels private SortField _sortField = SortField.Name; private bool _sortAscending = true; - public XCITrimmerViewModel(MainWindowViewModel mainWindowViewModel) + public XciTrimmerViewModel(MainWindowViewModel mainWindowViewModel) { _logger = new XCITrimmerLog.TrimmerWindow(this); _mainWindowViewModel = mainWindowViewModel; @@ -254,9 +254,9 @@ namespace Ryujinx.Ava.UI.ViewModels private class CompareXCITrimmerFiles : IComparer { - private XCITrimmerViewModel _viewModel; + private XciTrimmerViewModel _viewModel; - public CompareXCITrimmerFiles(XCITrimmerViewModel ViewModel) + public CompareXCITrimmerFiles(XciTrimmerViewModel ViewModel) { _viewModel = ViewModel; } diff --git a/src/Ryujinx/UI/Windows/AboutWindow.axaml b/src/Ryujinx/UI/Views/Dialog/AboutView.axaml similarity index 99% rename from src/Ryujinx/UI/Windows/AboutWindow.axaml rename to src/Ryujinx/UI/Views/Dialog/AboutView.axaml index e215cf27e..4c3da21e4 100644 --- a/src/Ryujinx/UI/Windows/AboutWindow.axaml +++ b/src/Ryujinx/UI/Views/Dialog/AboutView.axaml @@ -1,5 +1,5 @@ + public partial class AboutView : RyujinxControl { - public AboutWindow() + public AboutView() { InitializeComponent(); @@ -34,7 +32,7 @@ namespace Ryujinx.Ava.UI.Windows PrimaryButtonText = string.Empty, SecondaryButtonText = string.Empty, CloseButtonText = LocaleManager.Instance[LocaleKeys.UserProfilesClose], - Content = new AboutWindow { ViewModel = viewModel } + Content = new AboutView { ViewModel = viewModel } }; await ContentDialogHelper.ShowAsync(contentDialog.ApplyStyles()); diff --git a/src/Ryujinx/UI/Views/Misc/ApplicationDataView.axaml b/src/Ryujinx/UI/Views/Dialog/ApplicationDataView.axaml similarity index 99% rename from src/Ryujinx/UI/Views/Misc/ApplicationDataView.axaml rename to src/Ryujinx/UI/Views/Dialog/ApplicationDataView.axaml index a36b637ec..7ba4ad784 100644 --- a/src/Ryujinx/UI/Views/Misc/ApplicationDataView.axaml +++ b/src/Ryujinx/UI/Views/Dialog/ApplicationDataView.axaml @@ -7,7 +7,7 @@ xmlns:ui="using:FluentAvalonia.UI.Controls" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" - x:Class="Ryujinx.Ava.UI.Views.Misc.ApplicationDataView" + x:Class="Ryujinx.Ava.UI.Views.Dialog.ApplicationDataView" x:DataType="viewModels:ApplicationDataViewModel"> { diff --git a/src/Ryujinx/UI/Views/Misc/DlcSelectView.axaml b/src/Ryujinx/UI/Views/Dialog/DlcSelectView.axaml similarity index 98% rename from src/Ryujinx/UI/Views/Misc/DlcSelectView.axaml rename to src/Ryujinx/UI/Views/Dialog/DlcSelectView.axaml index f44bc3261..05d1f7ae5 100644 --- a/src/Ryujinx/UI/Views/Misc/DlcSelectView.axaml +++ b/src/Ryujinx/UI/Views/Dialog/DlcSelectView.axaml @@ -7,7 +7,7 @@ xmlns:models="using:Ryujinx.Ava.Common.Models" xmlns:viewModels="using:Ryujinx.Ava.UI.ViewModels" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" - x:Class="Ryujinx.Ava.UI.Views.Misc.DlcSelectView" + x:Class="Ryujinx.Ava.UI.Views.Dialog.DlcSelectView" x:DataType="viewModels:DlcSelectViewModel"> { diff --git a/src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml b/src/Ryujinx/UI/Views/Dialog/DownloadableContentManagerView.axaml similarity index 99% rename from src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml rename to src/Ryujinx/UI/Views/Dialog/DownloadableContentManagerView.axaml index e2c4fe16e..8b97a4822 100644 --- a/src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml +++ b/src/Ryujinx/UI/Views/Dialog/DownloadableContentManagerView.axaml @@ -1,5 +1,5 @@ { - public DownloadableContentManagerViewModel ViewModel; - - public DownloadableContentManagerWindow() + public DownloadableContentManagerView() { - DataContext = this; - - InitializeComponent(); - } - - public DownloadableContentManagerWindow(ApplicationLibrary applicationLibrary, ApplicationData applicationData) - { - DataContext = ViewModel = new DownloadableContentManagerViewModel(applicationLibrary, applicationData); - InitializeComponent(); } @@ -36,8 +26,11 @@ namespace Ryujinx.Ava.UI.Windows PrimaryButtonText = string.Empty, SecondaryButtonText = string.Empty, CloseButtonText = string.Empty, - Content = new DownloadableContentManagerWindow(applicationLibrary, applicationData), Title = string.Format(LocaleManager.Instance[LocaleKeys.DlcWindowTitle], applicationData.Name, applicationData.IdBaseString), + Content = new DownloadableContentManagerView + { + ViewModel = new DownloadableContentManagerViewModel(applicationLibrary, applicationData) + } }; Style bottomBorder = new(x => x.OfType().Name("DialogSpace").Child().OfType()); diff --git a/src/Ryujinx/UI/Windows/ModManagerWindow.axaml b/src/Ryujinx/UI/Views/Dialog/ModManagerView.axaml similarity index 99% rename from src/Ryujinx/UI/Windows/ModManagerWindow.axaml rename to src/Ryujinx/UI/Views/Dialog/ModManagerView.axaml index 40ce6d6b5..ee913b56d 100644 --- a/src/Ryujinx/UI/Windows/ModManagerWindow.axaml +++ b/src/Ryujinx/UI/Views/Dialog/ModManagerView.axaml @@ -10,7 +10,7 @@ Width="500" Height="380" mc:Ignorable="d" - x:Class="Ryujinx.Ava.UI.Windows.ModManagerWindow" + x:Class="Ryujinx.Ava.UI.Views.Dialog.ModManagerView" x:CompileBindings="True" x:DataType="viewModels:ModManagerViewModel" Focusable="True"> diff --git a/src/Ryujinx/UI/Windows/ModManagerWindow.axaml.cs b/src/Ryujinx/UI/Views/Dialog/ModManagerView.axaml.cs similarity index 88% rename from src/Ryujinx/UI/Windows/ModManagerWindow.axaml.cs rename to src/Ryujinx/UI/Views/Dialog/ModManagerView.axaml.cs index e51d1ca4a..8735e2911 100644 --- a/src/Ryujinx/UI/Windows/ModManagerWindow.axaml.cs +++ b/src/Ryujinx/UI/Views/Dialog/ModManagerView.axaml.cs @@ -7,27 +7,17 @@ using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Models; using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.Systems.AppLibrary; +using Ryujinx.Ava.UI.Controls; using Ryujinx.Common.Helper; using System.Threading.Tasks; using Button = Avalonia.Controls.Button; -namespace Ryujinx.Ava.UI.Windows +namespace Ryujinx.Ava.UI.Views.Dialog { - public partial class ModManagerWindow : UserControl + public partial class ModManagerView : RyujinxControl { - public readonly ModManagerViewModel ViewModel; - - public ModManagerWindow() + public ModManagerView() { - DataContext = this; - - InitializeComponent(); - } - - public ModManagerWindow(ulong titleId, ulong titleIdBase, ApplicationLibrary applicationLibrary) - { - DataContext = ViewModel = new ModManagerViewModel(titleId, titleIdBase, applicationLibrary); - InitializeComponent(); } @@ -38,7 +28,10 @@ namespace Ryujinx.Ava.UI.Windows PrimaryButtonText = string.Empty, SecondaryButtonText = string.Empty, CloseButtonText = string.Empty, - Content = new ModManagerWindow(titleId, titleIdBase, appLibrary), + Content = new ModManagerView + { + ViewModel = new ModManagerViewModel(titleId, titleIdBase, appLibrary) + }, Title = string.Format(LocaleManager.Instance[LocaleKeys.ModWindowTitle], titleName, titleId.ToString("X16")), }; diff --git a/src/Ryujinx/UI/Windows/TitleUpdateWindow.axaml b/src/Ryujinx/UI/Views/Dialog/TitleUpdateManagerView.axaml similarity index 99% rename from src/Ryujinx/UI/Windows/TitleUpdateWindow.axaml rename to src/Ryujinx/UI/Views/Dialog/TitleUpdateManagerView.axaml index 4da727db5..ba3e85e8b 100644 --- a/src/Ryujinx/UI/Windows/TitleUpdateWindow.axaml +++ b/src/Ryujinx/UI/Views/Dialog/TitleUpdateManagerView.axaml @@ -1,5 +1,5 @@ { - public readonly TitleUpdateViewModel ViewModel; - - public TitleUpdateWindow() + public TitleUpdateManagerView() { - DataContext = this; - - InitializeComponent(); - } - - public TitleUpdateWindow(ApplicationLibrary applicationLibrary, ApplicationData applicationData) - { - DataContext = ViewModel = new TitleUpdateViewModel(applicationLibrary, applicationData); - InitializeComponent(); } @@ -36,8 +26,11 @@ namespace Ryujinx.Ava.UI.Windows PrimaryButtonText = string.Empty, SecondaryButtonText = string.Empty, CloseButtonText = string.Empty, - Content = new TitleUpdateWindow(applicationLibrary, applicationData), Title = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.GameUpdateWindowHeading, applicationData.Name, applicationData.IdBaseString), + Content = new TitleUpdateManagerView + { + ViewModel = new TitleUpdateViewModel(applicationLibrary, applicationData) + } }; Style bottomBorder = new(x => x.OfType().Name("DialogSpace").Child().OfType()); diff --git a/src/Ryujinx/UI/Windows/XCITrimmerWindow.axaml b/src/Ryujinx/UI/Views/Dialog/XciTrimmerView.axaml similarity index 98% rename from src/Ryujinx/UI/Windows/XCITrimmerWindow.axaml rename to src/Ryujinx/UI/Views/Dialog/XciTrimmerView.axaml index e3bdabbf5..d149d246c 100644 --- a/src/Ryujinx/UI/Windows/XCITrimmerWindow.axaml +++ b/src/Ryujinx/UI/Views/Dialog/XciTrimmerView.axaml @@ -1,5 +1,5 @@ @@ -151,7 +151,7 @@ HorizontalAlignment="Stretch" VerticalAlignment="Center" CornerRadius="5" - IsVisible="{Binding $parent[UserControl].((viewModels:XCITrimmerViewModel)DataContext).Processing}" + IsVisible="{Binding $parent[UserControl].((viewModels:XciTrimmerViewModel)DataContext).Processing}" Maximum="100" Minimum="0" Value="{Binding PercentageProgress}" /> diff --git a/src/Ryujinx/UI/Windows/XCITrimmerWindow.axaml.cs b/src/Ryujinx/UI/Views/Dialog/XciTrimmerView.axaml.cs similarity index 81% rename from src/Ryujinx/UI/Windows/XCITrimmerWindow.axaml.cs rename to src/Ryujinx/UI/Views/Dialog/XciTrimmerView.axaml.cs index e02ff6279..8fb8c151c 100644 --- a/src/Ryujinx/UI/Windows/XCITrimmerWindow.axaml.cs +++ b/src/Ryujinx/UI/Views/Dialog/XciTrimmerView.axaml.cs @@ -4,27 +4,17 @@ using Avalonia.Styling; using FluentAvalonia.UI.Controls; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Models; +using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.ViewModels; using System; using System.Threading.Tasks; -namespace Ryujinx.Ava.UI.Windows +namespace Ryujinx.Ava.UI.Views.Dialog { - public partial class XCITrimmerWindow : UserControl + public partial class XciTrimmerView : RyujinxControl { - public XCITrimmerViewModel ViewModel; - - public XCITrimmerWindow() + public XciTrimmerView() { - DataContext = this; - - InitializeComponent(); - } - - public XCITrimmerWindow(MainWindowViewModel mainWindowViewModel) - { - DataContext = ViewModel = new XCITrimmerViewModel(mainWindowViewModel); - InitializeComponent(); } @@ -35,7 +25,10 @@ namespace Ryujinx.Ava.UI.Windows PrimaryButtonText = string.Empty, SecondaryButtonText = string.Empty, CloseButtonText = string.Empty, - Content = new XCITrimmerWindow(RyujinxApp.MainWindow.ViewModel), + Content = new XciTrimmerView + { + ViewModel = new XciTrimmerViewModel(RyujinxApp.MainWindow.ViewModel) + }, Title = LocaleManager.Instance[LocaleKeys.XCITrimmerWindowTitle] }; @@ -70,7 +63,7 @@ namespace Ryujinx.Ava.UI.Windows public void Sort_Checked(object sender, RoutedEventArgs args) { if (sender is RadioButton { Tag: string sortField }) - ViewModel.SortingField = Enum.Parse(sortField); + ViewModel.SortingField = Enum.Parse(sortField); } public void Order_Checked(object sender, RoutedEventArgs args) diff --git a/src/Ryujinx/UI/Views/Input/LedInputView.axaml.cs b/src/Ryujinx/UI/Views/Input/LedInputView.axaml.cs index 3252ee7e2..916ada37e 100644 --- a/src/Ryujinx/UI/Views/Input/LedInputView.axaml.cs +++ b/src/Ryujinx/UI/Views/Input/LedInputView.axaml.cs @@ -1,5 +1,4 @@ using Avalonia; -using Avalonia.Controls; using FluentAvalonia.UI.Controls; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.UI.Controls; diff --git a/src/Ryujinx/UI/Views/Input/MotionInputView.axaml.cs b/src/Ryujinx/UI/Views/Input/MotionInputView.axaml.cs index 329b9128e..2a83d1008 100644 --- a/src/Ryujinx/UI/Views/Input/MotionInputView.axaml.cs +++ b/src/Ryujinx/UI/Views/Input/MotionInputView.axaml.cs @@ -1,4 +1,3 @@ -using Avalonia.Controls; using FluentAvalonia.UI.Controls; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.UI.Controls; diff --git a/src/Ryujinx/UI/Views/Input/RumbleInputView.axaml.cs b/src/Ryujinx/UI/Views/Input/RumbleInputView.axaml.cs index 2745ceac7..347d011d5 100644 --- a/src/Ryujinx/UI/Views/Input/RumbleInputView.axaml.cs +++ b/src/Ryujinx/UI/Views/Input/RumbleInputView.axaml.cs @@ -1,4 +1,3 @@ -using Avalonia.Controls; using FluentAvalonia.UI.Controls; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.UI.Controls; diff --git a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs index 871d724f0..e47adc575 100644 --- a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs +++ b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs @@ -13,7 +13,7 @@ using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Systems.Configuration; -using Ryujinx.Ava.UI.Views.Misc; +using Ryujinx.Ava.UI.Views.Dialog; using Ryujinx.Common; using Ryujinx.Common.Helper; using Ryujinx.Common.Utilities; @@ -46,8 +46,8 @@ namespace Ryujinx.Ava.UI.Views.Main CheatManagerMenuItem.Command = Commands.CreateSilentFail(OpenCheatManagerForCurrentApp); InstallFileTypesMenuItem.Command = Commands.Create(InstallFileTypes); UninstallFileTypesMenuItem.Command = Commands.Create(UninstallFileTypes); - XciTrimmerMenuItem.Command = Commands.Create(XCITrimmerWindow.Show); - AboutWindowMenuItem.Command = Commands.Create(AboutWindow.Show); + XciTrimmerMenuItem.Command = Commands.Create(XciTrimmerView.Show); + AboutWindowMenuItem.Command = Commands.Create(AboutView.Show); CompatibilityListMenuItem.Command = Commands.Create(() => CompatibilityListWindow.Show()); UpdateMenuItem.Command = MainWindowViewModel.UpdateCommand; diff --git a/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml.cs b/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml.cs index f8c4c48a2..8341dd92a 100644 --- a/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml.cs +++ b/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml.cs @@ -1,5 +1,4 @@ using Avalonia; -using Avalonia.Controls; using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.Threading; diff --git a/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml index 4cf96366a..229f9e866 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml +++ b/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml @@ -29,7 +29,7 @@ + Text="Highly specific hacks & tricks to alleviate performance issues, crashing, or freezing. Can cause issues." /> + + + + diff --git a/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml.cs b/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml.cs index 759c9014e..25a47954a 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml.cs +++ b/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml.cs @@ -3,7 +3,9 @@ using Avalonia.Controls.Primitives; using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.LogicalTree; +using Avalonia.Threading; using Ryujinx.Ava.Input; +using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Input; @@ -15,7 +17,7 @@ using Key = Ryujinx.Common.Configuration.Hid.Key; namespace Ryujinx.Ava.UI.Views.Settings { - public partial class SettingsHotkeysView : UserControl + public partial class SettingsHotkeysView : RyujinxControl { private ButtonKeyAssigner _currentAssigner; private readonly IGamepadDriver _avaloniaKeyboardDriver; @@ -115,45 +117,49 @@ namespace Ryujinx.Ava.UI.Views.Settings { if (e.ButtonValue.HasValue) { - SettingsViewModel viewModel = (DataContext) as SettingsViewModel; Button buttonValue = e.ButtonValue.Value; - switch (button.Name) + Dispatcher.UIThread.Post(() => { - case "ToggleVSyncMode": - viewModel.KeyboardHotkey.ToggleVSyncMode = buttonValue.AsHidType(); - break; - case "Screenshot": - viewModel.KeyboardHotkey.Screenshot = buttonValue.AsHidType(); - break; - case "ShowUI": - viewModel.KeyboardHotkey.ShowUI = buttonValue.AsHidType(); - break; - case "Pause": - viewModel.KeyboardHotkey.Pause = buttonValue.AsHidType(); - break; - case "ToggleMute": - viewModel.KeyboardHotkey.ToggleMute = buttonValue.AsHidType(); - break; - case "ResScaleUp": - viewModel.KeyboardHotkey.ResScaleUp = buttonValue.AsHidType(); - break; - case "ResScaleDown": - viewModel.KeyboardHotkey.ResScaleDown = buttonValue.AsHidType(); - break; - case "VolumeUp": - viewModel.KeyboardHotkey.VolumeUp = buttonValue.AsHidType(); - break; - case "VolumeDown": - viewModel.KeyboardHotkey.VolumeDown = buttonValue.AsHidType(); - break; - case "CustomVSyncIntervalIncrement": - viewModel.KeyboardHotkey.CustomVSyncIntervalIncrement = buttonValue.AsHidType(); - break; - case "CustomVSyncIntervalDecrement": - viewModel.KeyboardHotkey.CustomVSyncIntervalDecrement = buttonValue.AsHidType(); - break; - } + switch (button.Name) + { + case "ToggleVSyncMode": + ViewModel.KeyboardHotkey.ToggleVSyncMode = buttonValue.AsHidType(); + break; + case "Screenshot": + ViewModel.KeyboardHotkey.Screenshot = buttonValue.AsHidType(); + break; + case "ShowUI": + ViewModel.KeyboardHotkey.ShowUI = buttonValue.AsHidType(); + break; + case "Pause": + ViewModel.KeyboardHotkey.Pause = buttonValue.AsHidType(); + break; + case "ToggleMute": + ViewModel.KeyboardHotkey.ToggleMute = buttonValue.AsHidType(); + break; + case "ResScaleUp": + ViewModel.KeyboardHotkey.ResScaleUp = buttonValue.AsHidType(); + break; + case "ResScaleDown": + ViewModel.KeyboardHotkey.ResScaleDown = buttonValue.AsHidType(); + break; + case "VolumeUp": + ViewModel.KeyboardHotkey.VolumeUp = buttonValue.AsHidType(); + break; + case "VolumeDown": + ViewModel.KeyboardHotkey.VolumeDown = buttonValue.AsHidType(); + break; + case "CustomVSyncIntervalIncrement": + ViewModel.KeyboardHotkey.CustomVSyncIntervalIncrement = + buttonValue.AsHidType(); + break; + case "CustomVSyncIntervalDecrement": + ViewModel.KeyboardHotkey.CustomVSyncIntervalDecrement = + buttonValue.AsHidType(); + break; + } + }); } }; diff --git a/src/Ryujinx/UI/Views/Settings/SettingsNetworkView.axaml.cs b/src/Ryujinx/UI/Views/Settings/SettingsNetworkView.axaml.cs index c4987702c..934fcf142 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsNetworkView.axaml.cs +++ b/src/Ryujinx/UI/Views/Settings/SettingsNetworkView.axaml.cs @@ -1,15 +1,13 @@ -using Avalonia.Controls; using Avalonia.Interactivity; +using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.ViewModels; using System; namespace Ryujinx.Ava.UI.Views.Settings { - public partial class SettingsNetworkView : UserControl + public partial class SettingsNetworkView : RyujinxControl { private readonly Random _random; - - public SettingsViewModel ViewModel; public SettingsNetworkView() { diff --git a/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml.cs b/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml.cs index 2c9eac28c..a81e0fb75 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml.cs +++ b/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml.cs @@ -1,13 +1,12 @@ using Avalonia.Controls; +using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.ViewModels; using TimeZone = Ryujinx.Ava.UI.Models.TimeZone; namespace Ryujinx.Ava.UI.Views.Settings { - public partial class SettingsSystemView : UserControl + public partial class SettingsSystemView : RyujinxControl { - public SettingsViewModel ViewModel; - public SettingsSystemView() { InitializeComponent(); diff --git a/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml.cs b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml.cs index 2b0e57cb5..fb839a473 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml.cs +++ b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml.cs @@ -3,10 +3,10 @@ using Avalonia.Controls; using Avalonia.Interactivity; using Avalonia.Platform.Storage; using Gommon; +using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.Utilities; -using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -14,20 +14,18 @@ using System.Threading.Tasks; namespace Ryujinx.Ava.UI.Views.Settings { - public partial class SettingsUiView : UserControl + public partial class SettingsUiView : RyujinxControl { - public SettingsViewModel ViewModel; - public SettingsUiView() { InitializeComponent(); AddGameDirButton.Command = - Commands.Create(() => AddDirButton(GameDirPathBox, ViewModel.GameDirectories, true)); + Commands.Create(() => AddDirButton(GameDirPathBox, ViewModel.GameDirectories)); AddAutoloadDirButton.Command = - Commands.Create(() => AddDirButton(AutoloadDirPathBox, ViewModel.AutoloadDirectories, false)); + Commands.Create(() => AddDirButton(AutoloadDirPathBox, ViewModel.AutoloadDirectories)); } - private async Task AddDirButton(TextBox addDirBox, AvaloniaList directories, bool isGameList) + private async Task AddDirButton(TextBox addDirBox, AvaloniaList directories) { string path = addDirBox.Text; diff --git a/src/Ryujinx/UI/Views/User/UserEditorView.axaml.cs b/src/Ryujinx/UI/Views/User/UserEditorView.axaml.cs index afd102d07..eb1cf58bb 100644 --- a/src/Ryujinx/UI/Views/User/UserEditorView.axaml.cs +++ b/src/Ryujinx/UI/Views/User/UserEditorView.axaml.cs @@ -8,7 +8,6 @@ using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Models; using Ryujinx.HLE.HOS.Services.Account.Acc; -using System; using UserProfile = Ryujinx.Ava.UI.Models.UserProfile; namespace Ryujinx.Ava.UI.Views.User diff --git a/src/Ryujinx/UI/Views/User/UserRecovererView.axaml.cs b/src/Ryujinx/UI/Views/User/UserRecovererView.axaml.cs index 34dc3edab..d1fd70e9b 100644 --- a/src/Ryujinx/UI/Views/User/UserRecovererView.axaml.cs +++ b/src/Ryujinx/UI/Views/User/UserRecovererView.axaml.cs @@ -1,4 +1,3 @@ -using Avalonia.Controls; using Avalonia.Interactivity; using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Navigation; diff --git a/src/Ryujinx/UI/Views/User/UserSaveManagerView.axaml.cs b/src/Ryujinx/UI/Views/User/UserSaveManagerView.axaml.cs index 8aff9c5f9..edbbd595b 100644 --- a/src/Ryujinx/UI/Views/User/UserSaveManagerView.axaml.cs +++ b/src/Ryujinx/UI/Views/User/UserSaveManagerView.axaml.cs @@ -1,4 +1,3 @@ -using Avalonia.Controls; using Avalonia.Interactivity; using Avalonia.Threading; using FluentAvalonia.UI.Controls; diff --git a/src/Ryujinx/UI/Windows/CheatWindow.axaml.cs b/src/Ryujinx/UI/Windows/CheatWindow.axaml.cs index b4cb6ec37..a9b42be1f 100644 --- a/src/Ryujinx/UI/Windows/CheatWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/CheatWindow.axaml.cs @@ -1,10 +1,8 @@ using Avalonia.Collections; -using LibHac.Tools.FsSystem; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.UI.Models; using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Systems.Configuration; -using Ryujinx.Ava.UI.ViewModels; using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.HOS; using System.Collections.Generic; diff --git a/src/Ryujinx/UI/Windows/CompatibilityListWindow.axaml.cs b/src/Ryujinx/UI/Windows/CompatibilityListWindow.axaml.cs index 6728ff197..a2b98f8f8 100644 --- a/src/Ryujinx/UI/Windows/CompatibilityListWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/CompatibilityListWindow.axaml.cs @@ -1,25 +1,24 @@ using Avalonia.Controls; -using Avalonia.Styling; -using FluentAvalonia.UI.Controls; -using FluentAvalonia.UI.Windowing; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Systems.Configuration; -using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.ViewModels; -using Ryujinx.Ava.UI.Windows; using System.Threading.Tasks; namespace Ryujinx.Ava.UI.Windows { public partial class CompatibilityListWindow : StyleableAppWindow { - public static Task Show(string titleId = null) => - ShowAsync(new CompatibilityListWindow + public static async Task Show(string titleId = null) + { + using CompatibilityViewModel compatWindow = new(RyujinxApp.MainWindow.ViewModel.ApplicationLibrary); + + await ShowAsync(new CompatibilityListWindow { - DataContext = new CompatibilityViewModel(RyujinxApp.MainWindow.ViewModel.ApplicationLibrary), + DataContext = compatWindow, SearchBoxFlush = { Text = titleId ?? string.Empty }, SearchBoxNormal = { Text = titleId ?? string.Empty } }); + } public CompatibilityListWindow() : base(useCustomTitleBar: true, 37) { diff --git a/src/Ryujinx/UI/Windows/GameSpecificSettingsWindow.axaml.cs b/src/Ryujinx/UI/Windows/GameSpecificSettingsWindow.axaml.cs index 8e2761bff..0d172ff59 100644 --- a/src/Ryujinx/UI/Windows/GameSpecificSettingsWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/GameSpecificSettingsWindow.axaml.cs @@ -1,25 +1,9 @@ -using Avalonia; using Avalonia.Controls; -using Avalonia.Controls.Shapes; -using Avalonia.Input; -using Avalonia.Media.Imaging; -using FluentAvalonia.Core; using FluentAvalonia.UI.Controls; -using Projektanker.Icons.Avalonia; using Ryujinx.Ava.Common.Locale; -using Ryujinx.Ava.UI.Models; using Ryujinx.Ava.UI.ViewModels; -using Ryujinx.Ava.UI.ViewModels.Input; -using Ryujinx.Ava.Utilities; -using Ryujinx.Ava.Systems.Configuration; -using Ryujinx.Common.Configuration; -using Ryujinx.HLE.FileSystem; -using Ryujinx.HLE.HOS.SystemState; -using Ryujinx.Input; using System; -using System.IO; using System.Linq; -using Key = Avalonia.Input.Key; namespace Ryujinx.Ava.UI.Windows diff --git a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs index bee04c466..4f5cb13d3 100644 --- a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs @@ -7,13 +7,12 @@ using Avalonia.Platform; using Avalonia.Threading; using DynamicData; using FluentAvalonia.UI.Controls; -using FluentAvalonia.UI.Windowing; using Gommon; using LibHac.Ns; -using LibHac.Tools.FsSystem; using Ryujinx.Ava.Common; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Input; +using Ryujinx.Ava.Systems; using Ryujinx.Ava.UI.Applet; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.ViewModels; diff --git a/src/Ryujinx/UI/Windows/StyleableWindow.cs b/src/Ryujinx/UI/Windows/StyleableWindow.cs index d1e97e283..c5f753402 100644 --- a/src/Ryujinx/UI/Windows/StyleableWindow.cs +++ b/src/Ryujinx/UI/Windows/StyleableWindow.cs @@ -8,7 +8,6 @@ using FluentAvalonia.UI.Windowing; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.UI.Controls; -using Ryujinx.Ava.UI.ViewModels; using System.Threading.Tasks; namespace Ryujinx.Ava.UI.Windows