diff --git a/src/Ryujinx.Graphics.Vulkan/Vendor.cs b/src/Ryujinx.Graphics.Vulkan/Vendor.cs index 87c6407cd..550ba0221 100644 --- a/src/Ryujinx.Graphics.Vulkan/Vendor.cs +++ b/src/Ryujinx.Graphics.Vulkan/Vendor.cs @@ -1,5 +1,4 @@ using Silk.NET.Vulkan; -using System.Text.RegularExpressions; namespace Ryujinx.Graphics.Vulkan { diff --git a/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs b/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs index b41bc60b1..2faff6e61 100644 --- a/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs +++ b/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs @@ -15,7 +15,6 @@ using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; -using System.Text.RegularExpressions; namespace Ryujinx.HLE.HOS.Applets.Error { diff --git a/src/Ryujinx.Horizon/HorizonStatic.cs b/src/Ryujinx.Horizon/HorizonStatic.cs index eb9dd4e31..a936a5a2d 100644 --- a/src/Ryujinx.Horizon/HorizonStatic.cs +++ b/src/Ryujinx.Horizon/HorizonStatic.cs @@ -1,4 +1,3 @@ -using MsgPack; using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Prepo.Types; using Ryujinx.Memory; diff --git a/src/Ryujinx/Assets/locales.json b/src/Ryujinx/Assets/locales.json index 04ecfe8da..ab114a893 100644 --- a/src/Ryujinx/Assets/locales.json +++ b/src/Ryujinx/Assets/locales.json @@ -5747,6 +5747,31 @@ "zh_TW": "啟用客體日誌" } }, + { + "ID": "SettingsTabLoggingEnableAvaloniaLogs", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Enable UI Logs", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" + } + }, { "ID": "SettingsTabLoggingEnableFsAccessLogs", "Translations": { @@ -16722,6 +16747,31 @@ "zh_TW": "謹慎使用" } }, + { + "ID": "AvaloniaLogTooltip", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Prints Avalonia (UI) log messages in the console.", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" + } + }, { "ID": "OpenGlLogLevel", "Translations": { diff --git a/src/Ryujinx/DiscordIntegrationModule.cs b/src/Ryujinx/DiscordIntegrationModule.cs index 1f820a223..47fc8ad69 100644 --- a/src/Ryujinx/DiscordIntegrationModule.cs +++ b/src/Ryujinx/DiscordIntegrationModule.cs @@ -1,6 +1,5 @@ using DiscordRPC; using Gommon; -using MsgPack; using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities.AppLibrary; using Ryujinx.Ava.Utilities.Configuration; @@ -11,7 +10,6 @@ using Ryujinx.HLE; using Ryujinx.HLE.Loaders.Processes; using Ryujinx.Horizon; using Ryujinx.Horizon.Prepo.Types; -using System.Linq; using System.Text; namespace Ryujinx.Ava diff --git a/src/Ryujinx/Headless/Options.cs b/src/Ryujinx/Headless/Options.cs index 1b10145fe..a57863d5d 100644 --- a/src/Ryujinx/Headless/Options.cs +++ b/src/Ryujinx/Headless/Options.cs @@ -387,7 +387,7 @@ namespace Ryujinx.Headless [Option("graphics-shaders-dump-path", Required = false, HelpText = "Dumps shaders in this local directory. (Developer only)")] public string GraphicsShadersDumpPath { get; set; } - [Option("graphics-backend", Required = false, Default = GraphicsBackend.OpenGl, HelpText = "Change Graphics Backend to use.")] + [Option("graphics-backend", Required = false, Default = GraphicsBackend.Vulkan, HelpText = "Change Graphics Backend to use.")] public GraphicsBackend GraphicsBackend { get; set; } [Option("preferred-gpu-vendor", Required = false, Default = "", HelpText = "When using the Vulkan backend, prefer using the GPU from the specified vendor.")] diff --git a/src/Ryujinx/UI/Controls/ApplicationDataView.axaml.cs b/src/Ryujinx/UI/Controls/ApplicationDataView.axaml.cs index e85e1188e..57dba3228 100644 --- a/src/Ryujinx/UI/Controls/ApplicationDataView.axaml.cs +++ b/src/Ryujinx/UI/Controls/ApplicationDataView.axaml.cs @@ -1,12 +1,9 @@ -using Avalonia; -using Avalonia.Controls; +using Avalonia.Controls; using Avalonia.Input.Platform; using Avalonia.Interactivity; using Avalonia.Styling; using FluentAvalonia.UI.Controls; -using Ryujinx.Ava; using Ryujinx.Ava.Common.Locale; -using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.Windows; diff --git a/src/Ryujinx/UI/Controls/ApplicationListView.axaml.cs b/src/Ryujinx/UI/Controls/ApplicationListView.axaml.cs index 7c6b0cf15..fb38fdb72 100644 --- a/src/Ryujinx/UI/Controls/ApplicationListView.axaml.cs +++ b/src/Ryujinx/UI/Controls/ApplicationListView.axaml.cs @@ -7,7 +7,6 @@ using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.Utilities.AppLibrary; using Ryujinx.Ava.Utilities.Compat; using System; -using System.Globalization; using System.Linq; namespace Ryujinx.Ava.UI.Controls diff --git a/src/Ryujinx/UI/Helpers/LoggerAdapter.cs b/src/Ryujinx/UI/Helpers/LoggerAdapter.cs index 928d1fc31..ba317e74a 100644 --- a/src/Ryujinx/UI/Helpers/LoggerAdapter.cs +++ b/src/Ryujinx/UI/Helpers/LoggerAdapter.cs @@ -1,6 +1,7 @@ using Avalonia.Logging; using Avalonia.Utilities; using Gommon; +using Ryujinx.Ava.Utilities.Configuration; using Ryujinx.Common.Logging; using System; using System.Text; @@ -14,13 +15,19 @@ namespace Ryujinx.Ava.UI.Helpers internal class LoggerAdapter : ILogSink { + private static bool _avaloniaLogsEnabled = ConfigurationState.Instance.Logger.EnableAvaloniaLog; + public static void Register() { AvaLogger.Sink = new LoggerAdapter(); + ConfigurationState.Instance.Logger.EnableAvaloniaLog.Event + += (_, e) => _avaloniaLogsEnabled = e.NewValue; } private static RyuLogger.Log? GetLog(AvaLogLevel level, string area) { + if (!_avaloniaLogsEnabled) return null; + return level switch { AvaLogLevel.Verbose => RyuLogger.Debug, diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs index 499eedc8d..113c00a5a 100644 --- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs @@ -1147,10 +1147,10 @@ namespace Ryujinx.Ava.UI.ViewModels List dirs = result.Select(it => it.Path.LocalPath).ToList(); int numAdded = onDirsSelected(dirs, out int numRemoved); - string msg = String.Join("\r\n", new string[] { + string msg = string.Join("\n", string.Format(LocaleManager.Instance[localeMessageRemovedKey], numRemoved), string.Format(LocaleManager.Instance[localeMessageAddedKey], numAdded) - }); + ); await Dispatcher.UIThread.InvokeAsync(async () => { diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs index bd649602c..0b3f8dcc6 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs @@ -204,6 +204,7 @@ namespace Ryujinx.Ava.UI.ViewModels public bool EnableTrace { get; set; } public bool EnableGuest { get; set; } public bool EnableFsAccessLog { get; set; } + public bool EnableAvaloniaLog { get; set; } public bool EnableDebug { get; set; } public bool IsOpenAlEnabled { get; set; } public bool IsSoundIoEnabled { get; set; } @@ -560,6 +561,7 @@ namespace Ryujinx.Ava.UI.ViewModels EnableGuest = config.Logger.EnableGuest; EnableDebug = config.Logger.EnableDebug; EnableFsAccessLog = config.Logger.EnableFsAccessLog; + EnableAvaloniaLog = config.Logger.EnableAvaloniaLog; FsGlobalAccessLogMode = config.System.FsGlobalAccessLogMode; OpenglDebugLevel = (int)config.Logger.GraphicsDebugLevel.Value; @@ -679,6 +681,7 @@ namespace Ryujinx.Ava.UI.ViewModels config.Logger.EnableGuest.Value = EnableGuest; config.Logger.EnableDebug.Value = EnableDebug; config.Logger.EnableFsAccessLog.Value = EnableFsAccessLog; + config.Logger.EnableAvaloniaLog.Value = EnableAvaloniaLog; config.System.FsGlobalAccessLogMode.Value = FsGlobalAccessLogMode; config.Logger.GraphicsDebugLevel.Value = (GraphicsDebugLevel)OpenglDebugLevel; diff --git a/src/Ryujinx/UI/Views/Settings/SettingsLoggingView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsLoggingView.axaml index 7ab49c0ae..d28f0ffa7 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsLoggingView.axaml +++ b/src/Ryujinx/UI/Views/Settings/SettingsLoggingView.axaml @@ -74,6 +74,10 @@ ToolTip.Tip="{ext:Locale DebugLogTooltip}"> + + + ValueFormatUtils.FormatTimeSpan(TimePlayed); - public bool HasPlayedPreviously => TimePlayedString != string.Empty; + public bool HasPlayedPreviously => TimePlayed.TotalSeconds > 1; public string LastPlayedString => ValueFormatUtils.FormatDateTime(LastPlayed)?.Replace(" ", "\n"); @@ -78,25 +78,6 @@ namespace Ryujinx.Ava.Utilities.AppLibrary public LocaleKeys? PlayabilityStatus => Compatibility.Convert(x => x.Status).OrElse(null); - public string CompatibilityToolTip - { - get - { - StringBuilder sb = new(LocalizedStatusTooltip); - - string formattedCompatibilityLabels = FormattedCompatibilityLabels; - if (!string.IsNullOrEmpty(formattedCompatibilityLabels)) - { - sb.AppendLine() - .AppendLine() - .Append(formattedCompatibilityLabels); - } - - return sb.ToString(); - } - } - - public string LocalizedStatusTooltip => Compatibility.Convert(x => #pragma warning disable CS8509 It is exhaustive for all possible values this can contain. @@ -120,16 +101,16 @@ namespace Ryujinx.Ava.Utilities.AppLibrary public static string GetBuildId(VirtualFileSystem virtualFileSystem, IntegrityCheckLevel checkLevel, string titleFilePath) { - using FileStream file = new(titleFilePath, FileMode.Open, FileAccess.Read); - - Nca mainNca = null; - Nca patchNca = null; - if (!System.IO.Path.Exists(titleFilePath)) { Logger.Error?.Print(LogClass.Application, $"File \"{titleFilePath}\" does not exist."); return string.Empty; } + + using FileStream file = new(titleFilePath, FileMode.Open, FileAccess.Read); + + Nca mainNca = null; + Nca patchNca = null; string extension = System.IO.Path.GetExtension(titleFilePath).ToLower(); diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationFileFormat.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationFileFormat.cs index 805a171be..95364873b 100644 --- a/src/Ryujinx/Utilities/Configuration/ConfigurationFileFormat.cs +++ b/src/Ryujinx/Utilities/Configuration/ConfigurationFileFormat.cs @@ -15,7 +15,7 @@ namespace Ryujinx.Ava.Utilities.Configuration /// /// The current version of the file format /// - public const int CurrentVersion = 63; + public const int CurrentVersion = 64; /// /// Version of the configuration file format @@ -111,6 +111,11 @@ namespace Ryujinx.Ava.Utilities.Configuration /// Enables printing FS access log messages /// public bool LoggingEnableFsAccessLog { get; set; } + + /// + /// Enables log messages from Avalonia + /// + public bool LoggingEnableAvalonia { get; set; } /// /// Controls which log messages are written to the log targets diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs index 0fb3fb754..36f42d8b3 100644 --- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs +++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs @@ -430,7 +430,8 @@ namespace Ryujinx.Ava.Utilities.Configuration } }), (62, static cff => cff.RainbowSpeed = 1f), - (63, static cff => cff.MatchSystemTime = false) + (63, static cff => cff.MatchSystemTime = false), + (64, static cff => cff.LoggingEnableAvalonia = false) ); } } diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs index 2d6e2aa7f..8fbe20e05 100644 --- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs +++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs @@ -254,6 +254,11 @@ namespace Ryujinx.Ava.Utilities.Configuration /// Enables printing FS access log messages /// public ReactiveObject EnableFsAccessLog { get; private set; } + + /// + /// Enables log messages from Avalonia + /// + public ReactiveObject EnableAvaloniaLog { get; private set; } /// /// Controls which log messages are written to the log targets @@ -281,6 +286,7 @@ namespace Ryujinx.Ava.Utilities.Configuration EnableTrace = new ReactiveObject(); EnableGuest = new ReactiveObject(); EnableFsAccessLog = new ReactiveObject(); + EnableAvaloniaLog = new ReactiveObject(); FilteredClasses = new ReactiveObject(); EnableFileLog = new ReactiveObject(); EnableFileLog.LogChangesToValue(nameof(EnableFileLog)); diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs index 4ab77a60f..f8fbc90d8 100644 --- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs +++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs @@ -46,6 +46,7 @@ namespace Ryujinx.Ava.Utilities.Configuration LoggingEnableTrace = Logger.EnableTrace, LoggingEnableGuest = Logger.EnableGuest, LoggingEnableFsAccessLog = Logger.EnableFsAccessLog, + LoggingEnableAvalonia = Logger.EnableAvaloniaLog, LoggingFilteredClasses = Logger.FilteredClasses, LoggingGraphicsDebugLevel = Logger.GraphicsDebugLevel, SystemLanguage = System.Language, @@ -165,6 +166,7 @@ namespace Ryujinx.Ava.Utilities.Configuration Logger.EnableTrace.Value = false; Logger.EnableGuest.Value = true; Logger.EnableFsAccessLog.Value = false; + Logger.EnableAvaloniaLog.Value = false; Logger.FilteredClasses.Value = []; Logger.GraphicsDebugLevel.Value = GraphicsDebugLevel.None; System.Language.Value = Language.AmericanEnglish; diff --git a/src/Ryujinx/Utilities/PlayReport/Analyzer.cs b/src/Ryujinx/Utilities/PlayReport/Analyzer.cs index 0b5284673..51047cc32 100644 --- a/src/Ryujinx/Utilities/PlayReport/Analyzer.cs +++ b/src/Ryujinx/Utilities/PlayReport/Analyzer.cs @@ -1,5 +1,4 @@ using Gommon; -using MsgPack; using Ryujinx.Ava.Utilities.AppLibrary; using System; using System.Collections.Generic; diff --git a/src/Ryujinx/Utilities/PlayReport/MatchedValues.cs b/src/Ryujinx/Utilities/PlayReport/MatchedValues.cs index 3086a9d65..46cae678a 100644 --- a/src/Ryujinx/Utilities/PlayReport/MatchedValues.cs +++ b/src/Ryujinx/Utilities/PlayReport/MatchedValues.cs @@ -1,7 +1,6 @@ using MsgPack; using Ryujinx.Ava.Utilities.AppLibrary; using System.Collections.Generic; -using System.Linq; namespace Ryujinx.Ava.Utilities.PlayReport { diff --git a/src/Ryujinx/Utilities/PlayReport/PlayReports.Formatters.cs b/src/Ryujinx/Utilities/PlayReport/PlayReports.Formatters.cs index f0d7f87ba..cabace6bb 100644 --- a/src/Ryujinx/Utilities/PlayReport/PlayReports.Formatters.cs +++ b/src/Ryujinx/Utilities/PlayReport/PlayReports.Formatters.cs @@ -1,4 +1,5 @@ -using System; +using Gommon; +using System; using System.Buffers.Binary; using System.Collections.Generic; using System.Linq; @@ -281,9 +282,14 @@ namespace Ryujinx.Ava.Utilities.PlayReport players = players.OrderBy(p => p.Rank ?? int.MaxValue).ToList(); return players.Count > 4 - ? $"{players.Count} Players - " + string.Join(", ", - players.Take(3).Select(p => $"{p.Character}({p.PlayerNumber}){RankMedal(p.Rank)}")) - : string.Join(", ", players.Select(p => $"{p.Character}({p.PlayerNumber}){RankMedal(p.Rank)}")); + ? $"{players.Count} Players - { + players.Take(3) + .Select(p => $"{p.Character}({p.PlayerNumber}){RankMedal(p.Rank)}") + .JoinToString(", ") + }" + : players + .Select(p => $"{p.Character}({p.PlayerNumber}){RankMedal(p.Rank)}") + .JoinToString(", "); string RankMedal(int? rank) => rank switch { diff --git a/src/Ryujinx/Utilities/PlayReport/PlayReports.cs b/src/Ryujinx/Utilities/PlayReport/PlayReports.cs index 5f6ba3446..d5568962e 100644 --- a/src/Ryujinx/Utilities/PlayReport/PlayReports.cs +++ b/src/Ryujinx/Utilities/PlayReport/PlayReports.cs @@ -1,9 +1,4 @@ -using System; -using System.Buffers.Binary; -using System.Collections.Generic; -using System.Linq; - -namespace Ryujinx.Ava.Utilities.PlayReport +namespace Ryujinx.Ava.Utilities.PlayReport { public static partial class PlayReports { diff --git a/src/Ryujinx/Utilities/PlayReport/Specs.cs b/src/Ryujinx/Utilities/PlayReport/Specs.cs index b81a599a2..5c8126a99 100644 --- a/src/Ryujinx/Utilities/PlayReport/Specs.cs +++ b/src/Ryujinx/Utilities/PlayReport/Specs.cs @@ -1,5 +1,4 @@ -using FluentAvalonia.Core; -using MsgPack; +using MsgPack; using Ryujinx.Ava.Utilities.AppLibrary; using System; using System.Collections.Generic;