Merge branch 'master' into master

This commit is contained in:
Evan Husted 2025-02-10 15:48:40 -06:00 committed by GitHub
commit 7ea4d98a40
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 102 additions and 55 deletions

View File

@ -1,5 +1,4 @@
using Silk.NET.Vulkan; using Silk.NET.Vulkan;
using System.Text.RegularExpressions;
namespace Ryujinx.Graphics.Vulkan namespace Ryujinx.Graphics.Vulkan
{ {

View File

@ -15,7 +15,6 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
namespace Ryujinx.HLE.HOS.Applets.Error namespace Ryujinx.HLE.HOS.Applets.Error
{ {

View File

@ -1,4 +1,3 @@
using MsgPack;
using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Common;
using Ryujinx.Horizon.Prepo.Types; using Ryujinx.Horizon.Prepo.Types;
using Ryujinx.Memory; using Ryujinx.Memory;

View File

@ -5747,6 +5747,31 @@
"zh_TW": "啟用客體日誌" "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", "ID": "SettingsTabLoggingEnableFsAccessLogs",
"Translations": { "Translations": {
@ -16722,6 +16747,31 @@
"zh_TW": "謹慎使用" "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", "ID": "OpenGlLogLevel",
"Translations": { "Translations": {

View File

@ -1,6 +1,5 @@
using DiscordRPC; using DiscordRPC;
using Gommon; using Gommon;
using MsgPack;
using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Utilities.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Utilities.Configuration; using Ryujinx.Ava.Utilities.Configuration;
@ -11,7 +10,6 @@ using Ryujinx.HLE;
using Ryujinx.HLE.Loaders.Processes; using Ryujinx.HLE.Loaders.Processes;
using Ryujinx.Horizon; using Ryujinx.Horizon;
using Ryujinx.Horizon.Prepo.Types; using Ryujinx.Horizon.Prepo.Types;
using System.Linq;
using System.Text; using System.Text;
namespace Ryujinx.Ava namespace Ryujinx.Ava

View File

@ -387,7 +387,7 @@ namespace Ryujinx.Headless
[Option("graphics-shaders-dump-path", Required = false, HelpText = "Dumps shaders in this local directory. (Developer only)")] [Option("graphics-shaders-dump-path", Required = false, HelpText = "Dumps shaders in this local directory. (Developer only)")]
public string GraphicsShadersDumpPath { get; set; } 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; } 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.")] [Option("preferred-gpu-vendor", Required = false, Default = "", HelpText = "When using the Vulkan backend, prefer using the GPU from the specified vendor.")]

View File

@ -1,12 +1,9 @@
using Avalonia; using Avalonia.Controls;
using Avalonia.Controls;
using Avalonia.Input.Platform; using Avalonia.Input.Platform;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Styling; using Avalonia.Styling;
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;
using Ryujinx.Ava;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;

View File

@ -7,7 +7,6 @@ using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Utilities.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Utilities.Compat; using Ryujinx.Ava.Utilities.Compat;
using System; using System;
using System.Globalization;
using System.Linq; using System.Linq;
namespace Ryujinx.Ava.UI.Controls namespace Ryujinx.Ava.UI.Controls

View File

@ -1,6 +1,7 @@
using Avalonia.Logging; using Avalonia.Logging;
using Avalonia.Utilities; using Avalonia.Utilities;
using Gommon; using Gommon;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using System; using System;
using System.Text; using System.Text;
@ -14,13 +15,19 @@ namespace Ryujinx.Ava.UI.Helpers
internal class LoggerAdapter : ILogSink internal class LoggerAdapter : ILogSink
{ {
private static bool _avaloniaLogsEnabled = ConfigurationState.Instance.Logger.EnableAvaloniaLog;
public static void Register() public static void Register()
{ {
AvaLogger.Sink = new LoggerAdapter(); AvaLogger.Sink = new LoggerAdapter();
ConfigurationState.Instance.Logger.EnableAvaloniaLog.Event
+= (_, e) => _avaloniaLogsEnabled = e.NewValue;
} }
private static RyuLogger.Log? GetLog(AvaLogLevel level, string area) private static RyuLogger.Log? GetLog(AvaLogLevel level, string area)
{ {
if (!_avaloniaLogsEnabled) return null;
return level switch return level switch
{ {
AvaLogLevel.Verbose => RyuLogger.Debug, AvaLogLevel.Verbose => RyuLogger.Debug,

View File

@ -1147,10 +1147,10 @@ namespace Ryujinx.Ava.UI.ViewModels
List<string> dirs = result.Select(it => it.Path.LocalPath).ToList(); List<string> dirs = result.Select(it => it.Path.LocalPath).ToList();
int numAdded = onDirsSelected(dirs, out int numRemoved); 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[localeMessageRemovedKey], numRemoved),
string.Format(LocaleManager.Instance[localeMessageAddedKey], numAdded) string.Format(LocaleManager.Instance[localeMessageAddedKey], numAdded)
}); );
await Dispatcher.UIThread.InvokeAsync(async () => await Dispatcher.UIThread.InvokeAsync(async () =>
{ {

View File

@ -204,6 +204,7 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool EnableTrace { get; set; } public bool EnableTrace { get; set; }
public bool EnableGuest { get; set; } public bool EnableGuest { get; set; }
public bool EnableFsAccessLog { get; set; } public bool EnableFsAccessLog { get; set; }
public bool EnableAvaloniaLog { get; set; }
public bool EnableDebug { get; set; } public bool EnableDebug { get; set; }
public bool IsOpenAlEnabled { get; set; } public bool IsOpenAlEnabled { get; set; }
public bool IsSoundIoEnabled { get; set; } public bool IsSoundIoEnabled { get; set; }
@ -560,6 +561,7 @@ namespace Ryujinx.Ava.UI.ViewModels
EnableGuest = config.Logger.EnableGuest; EnableGuest = config.Logger.EnableGuest;
EnableDebug = config.Logger.EnableDebug; EnableDebug = config.Logger.EnableDebug;
EnableFsAccessLog = config.Logger.EnableFsAccessLog; EnableFsAccessLog = config.Logger.EnableFsAccessLog;
EnableAvaloniaLog = config.Logger.EnableAvaloniaLog;
FsGlobalAccessLogMode = config.System.FsGlobalAccessLogMode; FsGlobalAccessLogMode = config.System.FsGlobalAccessLogMode;
OpenglDebugLevel = (int)config.Logger.GraphicsDebugLevel.Value; OpenglDebugLevel = (int)config.Logger.GraphicsDebugLevel.Value;
@ -679,6 +681,7 @@ namespace Ryujinx.Ava.UI.ViewModels
config.Logger.EnableGuest.Value = EnableGuest; config.Logger.EnableGuest.Value = EnableGuest;
config.Logger.EnableDebug.Value = EnableDebug; config.Logger.EnableDebug.Value = EnableDebug;
config.Logger.EnableFsAccessLog.Value = EnableFsAccessLog; config.Logger.EnableFsAccessLog.Value = EnableFsAccessLog;
config.Logger.EnableAvaloniaLog.Value = EnableAvaloniaLog;
config.System.FsGlobalAccessLogMode.Value = FsGlobalAccessLogMode; config.System.FsGlobalAccessLogMode.Value = FsGlobalAccessLogMode;
config.Logger.GraphicsDebugLevel.Value = (GraphicsDebugLevel)OpenglDebugLevel; config.Logger.GraphicsDebugLevel.Value = (GraphicsDebugLevel)OpenglDebugLevel;

View File

@ -74,6 +74,10 @@
ToolTip.Tip="{ext:Locale DebugLogTooltip}"> ToolTip.Tip="{ext:Locale DebugLogTooltip}">
<TextBlock Text="{ext:Locale SettingsTabLoggingEnableDebugLogs}" /> <TextBlock Text="{ext:Locale SettingsTabLoggingEnableDebugLogs}" />
</CheckBox> </CheckBox>
<CheckBox IsChecked="{Binding EnableAvaloniaLog}"
ToolTip.Tip="{ext:Locale AvaloniaLogTooltip}">
<TextBlock Text="{ext:Locale SettingsTabLoggingEnableAvaloniaLogs}" />
</CheckBox>
<StackPanel Margin="0,10,0,0" Orientation="Horizontal" VerticalAlignment="Stretch"> <StackPanel Margin="0,10,0,0" Orientation="Horizontal" VerticalAlignment="Stretch">
<TextBlock VerticalAlignment="Center" <TextBlock VerticalAlignment="Center"
ToolTip.Tip="{ext:Locale FSAccessLogModeTooltip}" ToolTip.Tip="{ext:Locale FSAccessLogModeTooltip}"

View File

@ -1,5 +1,4 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Interactivity;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using TimeZone = Ryujinx.Ava.UI.Models.TimeZone; using TimeZone = Ryujinx.Ava.UI.Models.TimeZone;

View File

@ -59,7 +59,7 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
public string TimePlayedString => ValueFormatUtils.FormatTimeSpan(TimePlayed); public string TimePlayedString => ValueFormatUtils.FormatTimeSpan(TimePlayed);
public bool HasPlayedPreviously => TimePlayedString != string.Empty; public bool HasPlayedPreviously => TimePlayed.TotalSeconds > 1;
public string LastPlayedString => ValueFormatUtils.FormatDateTime(LastPlayed)?.Replace(" ", "\n"); 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 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 => public string LocalizedStatusTooltip =>
Compatibility.Convert(x => Compatibility.Convert(x =>
#pragma warning disable CS8509 It is exhaustive for all possible values this can contain. #pragma warning disable CS8509 It is exhaustive for all possible values this can contain.
@ -120,17 +101,17 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
public static string GetBuildId(VirtualFileSystem virtualFileSystem, IntegrityCheckLevel checkLevel, string titleFilePath) 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)) if (!System.IO.Path.Exists(titleFilePath))
{ {
Logger.Error?.Print(LogClass.Application, $"File \"{titleFilePath}\" does not exist."); Logger.Error?.Print(LogClass.Application, $"File \"{titleFilePath}\" does not exist.");
return string.Empty; 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(); string extension = System.IO.Path.GetExtension(titleFilePath).ToLower();
if (extension is ".nsp" or ".xci") if (extension is ".nsp" or ".xci")

View File

@ -15,7 +15,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
/// <summary> /// <summary>
/// The current version of the file format /// The current version of the file format
/// </summary> /// </summary>
public const int CurrentVersion = 63; public const int CurrentVersion = 64;
/// <summary> /// <summary>
/// Version of the configuration file format /// Version of the configuration file format
@ -112,6 +112,11 @@ namespace Ryujinx.Ava.Utilities.Configuration
/// </summary> /// </summary>
public bool LoggingEnableFsAccessLog { get; set; } public bool LoggingEnableFsAccessLog { get; set; }
/// <summary>
/// Enables log messages from Avalonia
/// </summary>
public bool LoggingEnableAvalonia { get; set; }
/// <summary> /// <summary>
/// Controls which log messages are written to the log targets /// Controls which log messages are written to the log targets
/// </summary> /// </summary>

View File

@ -430,7 +430,8 @@ namespace Ryujinx.Ava.Utilities.Configuration
} }
}), }),
(62, static cff => cff.RainbowSpeed = 1f), (62, static cff => cff.RainbowSpeed = 1f),
(63, static cff => cff.MatchSystemTime = false) (63, static cff => cff.MatchSystemTime = false),
(64, static cff => cff.LoggingEnableAvalonia = false)
); );
} }
} }

View File

@ -255,6 +255,11 @@ namespace Ryujinx.Ava.Utilities.Configuration
/// </summary> /// </summary>
public ReactiveObject<bool> EnableFsAccessLog { get; private set; } public ReactiveObject<bool> EnableFsAccessLog { get; private set; }
/// <summary>
/// Enables log messages from Avalonia
/// </summary>
public ReactiveObject<bool> EnableAvaloniaLog { get; private set; }
/// <summary> /// <summary>
/// Controls which log messages are written to the log targets /// Controls which log messages are written to the log targets
/// </summary> /// </summary>
@ -281,6 +286,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
EnableTrace = new ReactiveObject<bool>(); EnableTrace = new ReactiveObject<bool>();
EnableGuest = new ReactiveObject<bool>(); EnableGuest = new ReactiveObject<bool>();
EnableFsAccessLog = new ReactiveObject<bool>(); EnableFsAccessLog = new ReactiveObject<bool>();
EnableAvaloniaLog = new ReactiveObject<bool>();
FilteredClasses = new ReactiveObject<LogClass[]>(); FilteredClasses = new ReactiveObject<LogClass[]>();
EnableFileLog = new ReactiveObject<bool>(); EnableFileLog = new ReactiveObject<bool>();
EnableFileLog.LogChangesToValue(nameof(EnableFileLog)); EnableFileLog.LogChangesToValue(nameof(EnableFileLog));

View File

@ -46,6 +46,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
LoggingEnableTrace = Logger.EnableTrace, LoggingEnableTrace = Logger.EnableTrace,
LoggingEnableGuest = Logger.EnableGuest, LoggingEnableGuest = Logger.EnableGuest,
LoggingEnableFsAccessLog = Logger.EnableFsAccessLog, LoggingEnableFsAccessLog = Logger.EnableFsAccessLog,
LoggingEnableAvalonia = Logger.EnableAvaloniaLog,
LoggingFilteredClasses = Logger.FilteredClasses, LoggingFilteredClasses = Logger.FilteredClasses,
LoggingGraphicsDebugLevel = Logger.GraphicsDebugLevel, LoggingGraphicsDebugLevel = Logger.GraphicsDebugLevel,
SystemLanguage = System.Language, SystemLanguage = System.Language,
@ -165,6 +166,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
Logger.EnableTrace.Value = false; Logger.EnableTrace.Value = false;
Logger.EnableGuest.Value = true; Logger.EnableGuest.Value = true;
Logger.EnableFsAccessLog.Value = false; Logger.EnableFsAccessLog.Value = false;
Logger.EnableAvaloniaLog.Value = false;
Logger.FilteredClasses.Value = []; Logger.FilteredClasses.Value = [];
Logger.GraphicsDebugLevel.Value = GraphicsDebugLevel.None; Logger.GraphicsDebugLevel.Value = GraphicsDebugLevel.None;
System.Language.Value = Language.AmericanEnglish; System.Language.Value = Language.AmericanEnglish;

View File

@ -1,5 +1,4 @@
using Gommon; using Gommon;
using MsgPack;
using Ryujinx.Ava.Utilities.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;

View File

@ -1,7 +1,6 @@
using MsgPack; using MsgPack;
using Ryujinx.Ava.Utilities.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace Ryujinx.Ava.Utilities.PlayReport namespace Ryujinx.Ava.Utilities.PlayReport
{ {

View File

@ -1,4 +1,5 @@
using System; using Gommon;
using System;
using System.Buffers.Binary; using System.Buffers.Binary;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -281,9 +282,14 @@ namespace Ryujinx.Ava.Utilities.PlayReport
players = players.OrderBy(p => p.Rank ?? int.MaxValue).ToList(); players = players.OrderBy(p => p.Rank ?? int.MaxValue).ToList();
return players.Count > 4 return players.Count > 4
? $"{players.Count} Players - " + string.Join(", ", ? $"{players.Count} Players - {
players.Take(3).Select(p => $"{p.Character}({p.PlayerNumber}){RankMedal(p.Rank)}")) players.Take(3)
: string.Join(", ", players.Select(p => $"{p.Character}({p.PlayerNumber}){RankMedal(p.Rank)}")); .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 string RankMedal(int? rank) => rank switch
{ {

View File

@ -1,9 +1,4 @@
using System; namespace Ryujinx.Ava.Utilities.PlayReport
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Linq;
namespace Ryujinx.Ava.Utilities.PlayReport
{ {
public static partial class PlayReports public static partial class PlayReports
{ {

View File

@ -1,5 +1,4 @@
using FluentAvalonia.Core; using MsgPack;
using MsgPack;
using Ryujinx.Ava.Utilities.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;