From a8ba340ddef566517f197911863b127545685d5d Mon Sep 17 00:00:00 2001 From: gdkchan Date: Tue, 24 Apr 2018 15:57:39 -0300 Subject: [PATCH] Improved logging (#103) --- .../Instruction/AInstEmitMemoryHelper.cs | 4 +- Ryujinx.Core/Hid/Hid.cs | 9 +- Ryujinx.Core/Logging.cs | 296 ------------------ Ryujinx.Core/{ => Logging}/LogClass.cs | 10 +- Ryujinx.Core/Logging/LogEventArgs.cs | 19 ++ Ryujinx.Core/Logging/LogLevel.cs | 11 + Ryujinx.Core/Logging/Logger.cs | 84 +++++ .../OsHle/Handles/KProcessScheduler.cs | 13 +- Ryujinx.Core/OsHle/Handles/KThread.cs | 6 +- Ryujinx.Core/OsHle/Horizon.cs | 7 +- Ryujinx.Core/OsHle/Ipc/IpcLog.cs | 178 ----------- Ryujinx.Core/OsHle/Ipc/IpcMessage.cs | 5 +- Ryujinx.Core/OsHle/Kernel/SvcHandler.cs | 5 +- Ryujinx.Core/OsHle/Kernel/SvcMemory.cs | 15 +- Ryujinx.Core/OsHle/Kernel/SvcSystem.cs | 11 +- Ryujinx.Core/OsHle/Kernel/SvcThread.cs | 11 +- Ryujinx.Core/OsHle/Kernel/SvcThreadSync.cs | 23 +- Ryujinx.Core/OsHle/Process.cs | 17 +- .../Acc/IAccountServiceForApplication.cs | 13 +- .../Services/Acc/IManagerForApplication.cs | 5 +- Ryujinx.Core/OsHle/Services/Acc/IProfile.cs | 5 +- .../Services/Am/IApplicationFunctions.cs | 20 +- .../OsHle/Services/Am/IApplicationProxy.cs | 14 +- .../OsHle/Services/Am/IAudioController.cs | 13 +- .../OsHle/Services/Am/ICommonStateGetter.cs | 3 +- .../OsHle/Services/Am/IHomeMenuFunctions.cs | 5 +- .../OsHle/Services/Am/ISelfController.cs | 15 +- .../OsHle/Services/Am/IStorageAccessor.cs | 4 +- .../OsHle/Services/Am/ISystemAppletProxy.cs | 22 +- .../OsHle/Services/Am/IWindowController.cs | 7 +- Ryujinx.Core/OsHle/Services/Apm/ISession.cs | 4 +- .../OsHle/Services/Aud/IAudioDevice.cs | 7 +- Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs | 7 +- .../OsHle/Services/Aud/IAudioRenderer.cs | 5 +- .../Services/Aud/IAudioRendererManager.cs | 3 +- Ryujinx.Core/OsHle/Services/Bsd/IClient.cs | 13 +- .../OsHle/Services/FspSrv/IFileSystem.cs | 20 +- .../OsHle/Services/FspSrv/IFileSystemProxy.cs | 10 +- Ryujinx.Core/OsHle/Services/Hid/IHidServer.cs | 74 ++--- Ryujinx.Core/OsHle/Services/IpcService.cs | 3 +- Ryujinx.Core/OsHle/Services/Lm/ILogger.cs | 151 +++------ Ryujinx.Core/OsHle/Services/Lm/LmLogField.cs | 13 + Ryujinx.Core/OsHle/Services/Lm/LmLogLevel.cs | 11 + .../OsHle/Services/Nifm/IGeneralService.cs | 3 +- Ryujinx.Core/OsHle/Services/Nifm/IRequest.cs | 9 +- .../OsHle/Services/Ns/IAddOnContentManager.cs | 5 +- .../OsHle/Services/Nv/INvDrvServices.cs | 19 +- Ryujinx.Core/OsHle/Services/ServiceFactory.cs | 3 + .../Services/Set/ISystemSettingsServer.cs | 2 +- .../OsHle/Services/Time/ITimeZoneService.cs | 7 +- .../Services/Vi/IApplicationDisplayService.cs | 8 +- Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs | 7 +- Ryujinx.Core/Switch.cs | 9 +- {Ryujinx.Core => Ryujinx}/Config.cs | 84 +++-- Ryujinx/Ryujinx.conf | 31 +- Ryujinx/Ui/ConsoleLog.cs | 51 +++ Ryujinx/Ui/Program.cs | 16 +- 57 files changed, 555 insertions(+), 870 deletions(-) delete mode 100644 Ryujinx.Core/Logging.cs rename Ryujinx.Core/{ => Logging}/LogClass.cs (87%) create mode 100644 Ryujinx.Core/Logging/LogEventArgs.cs create mode 100644 Ryujinx.Core/Logging/LogLevel.cs create mode 100644 Ryujinx.Core/Logging/Logger.cs delete mode 100644 Ryujinx.Core/OsHle/Ipc/IpcLog.cs create mode 100644 Ryujinx.Core/OsHle/Services/Lm/LmLogField.cs create mode 100644 Ryujinx.Core/OsHle/Services/Lm/LmLogLevel.cs rename {Ryujinx.Core => Ryujinx}/Config.cs (53%) create mode 100644 Ryujinx/Ui/ConsoleLog.cs diff --git a/ChocolArm64/Instruction/AInstEmitMemoryHelper.cs b/ChocolArm64/Instruction/AInstEmitMemoryHelper.cs index 6ffcf2dc..df091bd5 100644 --- a/ChocolArm64/Instruction/AInstEmitMemoryHelper.cs +++ b/ChocolArm64/Instruction/AInstEmitMemoryHelper.cs @@ -87,7 +87,7 @@ namespace ChocolArm64.Instruction : nameof(AMemory.ReadUInt64); break; } } - + Context.EmitCall(typeof(AMemory), Name); if (!IsSimd) @@ -119,7 +119,7 @@ namespace ChocolArm64.Instruction string Name = null; if (Size < 0 || Size > (IsSimd ? 4 : 3)) - { + { throw new ArgumentOutOfRangeException(nameof(Size)); } diff --git a/Ryujinx.Core/Hid/Hid.cs b/Ryujinx.Core/Hid/Hid.cs index be122c60..6cda6399 100644 --- a/Ryujinx.Core/Hid/Hid.cs +++ b/Ryujinx.Core/Hid/Hid.cs @@ -1,4 +1,5 @@ using ChocolArm64.Memory; +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Handles; using System; @@ -61,12 +62,16 @@ namespace Ryujinx.Core.Input private const int HidEntryCount = 17; + private Logger Log; + private object ShMemLock; private (AMemory, long)[] ShMemPositions; - public Hid() + public Hid(Logger Log) { + this.Log = Log; + ShMemLock = new object(); ShMemPositions = new (AMemory, long)[0]; @@ -82,7 +87,7 @@ namespace Ryujinx.Core.Input (AMemory Memory, long Position) ShMem = ShMemPositions[ShMemPositions.Length - 1]; - Logging.Info(LogClass.ServiceHid, $"HID shared memory successfully mapped to 0x{ShMem.Position:x16}!"); + Log.PrintInfo(LogClass.Hid, $"HID shared memory successfully mapped to 0x{ShMem.Position:x16}!"); Init(ShMem.Memory, ShMem.Position); } diff --git a/Ryujinx.Core/Logging.cs b/Ryujinx.Core/Logging.cs deleted file mode 100644 index f6e2079a..00000000 --- a/Ryujinx.Core/Logging.cs +++ /dev/null @@ -1,296 +0,0 @@ -using Ryujinx.Core.OsHle.Ipc; -using System; -using System.Diagnostics; -using System.IO; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading; - -namespace Ryujinx.Core -{ - public static class Logging - { - private static Stopwatch ExecutionTime; - - private const string LogFileName = "Ryujinx.log"; - - private static bool EnableInfo = Config.LoggingEnableInfo; - private static bool EnableTrace = Config.LoggingEnableTrace; - private static bool EnableDebug = Config.LoggingEnableDebug; - private static bool EnableWarn = Config.LoggingEnableWarn; - private static bool EnableError = Config.LoggingEnableError; - private static bool EnableFatal = Config.LoggingEnableFatal; - private static bool EnableStub = Config.LoggingEnableStub; - private static bool EnableIpc = Config.LoggingEnableIpc; - private static bool EnableFilter = Config.LoggingEnableFilter; - private static bool EnableLogFile = Config.LoggingEnableLogFile; - private static bool[] FilteredLogClasses = Config.LoggingFilteredClasses; - - private enum LogLevel - { - Debug, - Error, - Fatal, - Info, - Stub, - Trace, - Warn - } - - static Logging() - { - if (File.Exists(LogFileName)) File.Delete(LogFileName); - - ExecutionTime = new Stopwatch(); - - ExecutionTime.Start(); - } - - public static string GetExecutionTime() => ExecutionTime.ElapsedMilliseconds.ToString().PadLeft(8, '0') + "ms"; - - private static void LogMessage(LogEntry LogEntry) - { - if (EnableFilter) - if (!FilteredLogClasses[(int)LogEntry.LogClass]) - return; - - ConsoleColor consoleColor = ConsoleColor.White; - - switch (LogEntry.LogLevel) - { - case LogLevel.Debug: - consoleColor = ConsoleColor.Gray; - break; - case LogLevel.Error: - consoleColor = ConsoleColor.Red; - break; - case LogLevel.Fatal: - consoleColor = ConsoleColor.Magenta; - break; - case LogLevel.Info: - consoleColor = ConsoleColor.White; - break; - case LogLevel.Stub: - consoleColor = ConsoleColor.DarkYellow; - break; - case LogLevel.Trace: - consoleColor = ConsoleColor.DarkGray; - break; - case LogLevel.Warn: - consoleColor = ConsoleColor.Yellow; - break; - } - - LogEntry.ManagedThreadId = Thread.CurrentThread.ManagedThreadId; - - string Text = $"{LogEntry.ExecutionTime} | {LogEntry.ManagedThreadId} > {LogEntry.LogClass} > " + - $"{LogEntry.LogLevel.ToString()} > {LogEntry.CallingMember} > {LogEntry.Message}"; - - Console.ForegroundColor = consoleColor; - Console.WriteLine(Text.PadLeft(Text.Length + 1, ' ')); - Console.ResetColor(); - - LogFile(Text); - } - - private static void LogFile(string Message) - { - if (EnableLogFile) - { - using (StreamWriter Writer = File.AppendText(LogFileName)) - { - Writer.WriteLine(Message); - } - } - } - - public static void Info(LogClass LogClass, string Message, [CallerMemberName] string CallingMember = "") - { - if (EnableInfo) - { - LogMessage(new LogEntry - { - CallingMember = CallingMember, - LogLevel = LogLevel.Info, - LogClass = LogClass, - Message = Message, - ExecutionTime = GetExecutionTime() - }); - } - } - - public static void Trace(LogClass LogClass, string Message, [CallerMemberName] string CallingMember = "") - { - if (EnableTrace) - { - LogMessage(new LogEntry - { - CallingMember = CallingMember, - LogLevel = LogLevel.Trace, - LogClass = LogClass, - Message = Message, - ExecutionTime = GetExecutionTime() - }); - } - } - - public static void Stub(LogClass LogClass, string Message, [CallerMemberName] string CallingMember = "") - { - if (EnableStub) - { - LogMessage(new LogEntry - { - CallingMember = CallingMember, - LogLevel = LogLevel.Stub, - LogClass = LogClass, - Message = Message, - ExecutionTime = GetExecutionTime() - }); - } - } - - public static void Debug(LogClass LogClass,string Message, [CallerMemberName] string CallingMember = "") - { - if (EnableDebug) - { - LogMessage(new LogEntry - { - CallingMember = CallingMember, - LogLevel = LogLevel.Debug, - LogClass = LogClass, - Message = Message, - ExecutionTime = GetExecutionTime() - }); - } - } - - public static void Warn(LogClass LogClass, string Message, [CallerMemberName] string CallingMember = "") - { - if (EnableWarn) - { - LogMessage(new LogEntry - { - CallingMember = CallingMember, - LogLevel = LogLevel.Warn, - LogClass = LogClass, - Message = Message, - ExecutionTime = GetExecutionTime() - }); - } - } - - public static void Error(LogClass LogClass, string Message, [CallerMemberName] string CallingMember = "") - { - if (EnableError) - { - LogMessage(new LogEntry - { - CallingMember = CallingMember, - LogLevel = LogLevel.Error, - LogClass = LogClass, - Message = Message, - ExecutionTime = GetExecutionTime() - }); - } - } - - public static void Fatal(LogClass LogClass, string Message, [CallerMemberName] string CallingMember = "") - { - if (EnableFatal) - { - LogMessage(new LogEntry - { - CallingMember = CallingMember, - LogLevel = LogLevel.Fatal, - LogClass = LogClass, - Message = Message, - ExecutionTime = GetExecutionTime() - }); - } - } - - public static void Ipc(byte[] Data, long CmdPtr, bool Domain) - { - if (EnableIpc) - { - Console.ForegroundColor = ConsoleColor.Cyan; - Console.WriteLine(IpcLog.Message(Data, CmdPtr, Domain)); - Console.ResetColor(); - } - } - - //https://www.codeproject.com/Articles/36747/Quick-and-Dirty-HexDump-of-a-Byte-Array - public static string HexDump(byte[] bytes, int bytesPerLine = 16) - { - if (bytes == null) return ""; - int bytesLength = bytes.Length; - - char[] HexChars = "0123456789ABCDEF".ToCharArray(); - - int firstHexColumn = - 8 // 8 characters for the address - + 3; // 3 spaces - - int firstCharColumn = firstHexColumn - + bytesPerLine * 3 // - 2 digit for the hexadecimal value and 1 space - + (bytesPerLine - 1) / 8 // - 1 extra space every 8 characters from the 9th - + 2; // 2 spaces - - int lineLength = firstCharColumn - + bytesPerLine // - characters to show the ascii value - + Environment.NewLine.Length; // Carriage return and line feed (should normally be 2) - - char[] line = (new String(' ', lineLength - Environment.NewLine.Length) + Environment.NewLine).ToCharArray(); - int expectedLines = (bytesLength + bytesPerLine - 1) / bytesPerLine; - StringBuilder result = new StringBuilder(expectedLines * lineLength); - - for (int i = 0; i < bytesLength; i += bytesPerLine) - { - line[0] = HexChars[(i >> 28) & 0xF]; - line[1] = HexChars[(i >> 24) & 0xF]; - line[2] = HexChars[(i >> 20) & 0xF]; - line[3] = HexChars[(i >> 16) & 0xF]; - line[4] = HexChars[(i >> 12) & 0xF]; - line[5] = HexChars[(i >> 8) & 0xF]; - line[6] = HexChars[(i >> 4) & 0xF]; - line[7] = HexChars[(i >> 0) & 0xF]; - - int hexColumn = firstHexColumn; - int charColumn = firstCharColumn; - - for (int j = 0; j < bytesPerLine; j++) - { - if (j > 0 && (j & 7) == 0) hexColumn++; - if (i + j >= bytesLength) - { - line[hexColumn] = ' '; - line[hexColumn + 1] = ' '; - line[charColumn] = ' '; - } - else - { - byte b = bytes[i + j]; - line[hexColumn] = HexChars[(b >> 4) & 0xF]; - line[hexColumn + 1] = HexChars[b & 0xF]; - line[charColumn] = (b < 32 ? '·' : (char)b); - } - hexColumn += 3; - charColumn++; - } - - result.Append(line); - } - return result.ToString(); - } - - private struct LogEntry - { - public string CallingMember; - public string ExecutionTime; - public string Message; - public int ManagedThreadId; - public LogClass LogClass; - public LogLevel LogLevel; - } - } -} diff --git a/Ryujinx.Core/LogClass.cs b/Ryujinx.Core/Logging/LogClass.cs similarity index 87% rename from Ryujinx.Core/LogClass.cs rename to Ryujinx.Core/Logging/LogClass.cs index 014b5732..2e6acd2e 100644 --- a/Ryujinx.Core/LogClass.cs +++ b/Ryujinx.Core/Logging/LogClass.cs @@ -1,10 +1,11 @@ -namespace Ryujinx.Core +namespace Ryujinx.Core.Logging { public enum LogClass { Audio, - CPU, - GPU, + Cpu, + Gpu, + Hid, Kernel, KernelIpc, KernelScheduler, @@ -32,7 +33,6 @@ ServiceSm, ServiceSss, ServiceTime, - ServiceVi, - Count, + ServiceVi } } diff --git a/Ryujinx.Core/Logging/LogEventArgs.cs b/Ryujinx.Core/Logging/LogEventArgs.cs new file mode 100644 index 00000000..15d5aefb --- /dev/null +++ b/Ryujinx.Core/Logging/LogEventArgs.cs @@ -0,0 +1,19 @@ +using System; + +namespace Ryujinx.Core.Logging +{ + public class LogEventArgs : EventArgs + { + public LogLevel Level { get; private set; } + public TimeSpan Time { get; private set; } + + public string Message { get; private set; } + + public LogEventArgs(LogLevel Level, TimeSpan Time, string Message) + { + this.Level = Level; + this.Time = Time; + this.Message = Message; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/Logging/LogLevel.cs b/Ryujinx.Core/Logging/LogLevel.cs new file mode 100644 index 00000000..be5b4ff2 --- /dev/null +++ b/Ryujinx.Core/Logging/LogLevel.cs @@ -0,0 +1,11 @@ +namespace Ryujinx.Core.Logging +{ + public enum LogLevel + { + Debug, + Stub, + Info, + Warning, + Error + } +} diff --git a/Ryujinx.Core/Logging/Logger.cs b/Ryujinx.Core/Logging/Logger.cs new file mode 100644 index 00000000..972d716c --- /dev/null +++ b/Ryujinx.Core/Logging/Logger.cs @@ -0,0 +1,84 @@ +using System; +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace Ryujinx.Core.Logging +{ + public class Logger + { + private bool[] EnabledLevels; + private bool[] EnabledClasses; + + public event EventHandler Updated; + + private Stopwatch Time; + + public Logger() + { + EnabledLevels = new bool[Enum.GetNames(typeof(LogLevel)).Length]; + EnabledClasses = new bool[Enum.GetNames(typeof(LogClass)).Length]; + + EnabledLevels[(int)LogLevel.Stub] = true; + EnabledLevels[(int)LogLevel.Info] = true; + EnabledLevels[(int)LogLevel.Warning] = true; + EnabledLevels[(int)LogLevel.Error] = true; + + for (int Index = 0; Index < EnabledClasses.Length; Index++) + { + EnabledClasses[Index] = true; + } + + Time = new Stopwatch(); + + Time.Start(); + } + + public void SetEnable(LogLevel Level, bool Enabled) + { + EnabledLevels[(int)Level] = Enabled; + } + + public void SetEnable(LogClass Class, bool Enabled) + { + EnabledClasses[(int)Class] = Enabled; + } + + internal void PrintDebug(LogClass Class, string Message, [CallerMemberName] string Caller = "") + { + Print(LogLevel.Debug, Class, GetFormattedMessage(Class, Message, Caller)); + } + + internal void PrintStub(LogClass Class, string Message, [CallerMemberName] string Caller = "") + { + Print(LogLevel.Stub, Class, GetFormattedMessage(Class, Message, Caller)); + } + + internal void PrintInfo(LogClass Class, string Message, [CallerMemberName] string Caller = "") + { + Print(LogLevel.Info, Class, GetFormattedMessage(Class, Message, Caller)); + } + + internal void PrintWarning(LogClass Class, string Message, [CallerMemberName] string Caller = "") + { + Print(LogLevel.Warning, Class, GetFormattedMessage(Class, Message, Caller)); + } + + internal void PrintError(LogClass Class, string Message, [CallerMemberName] string Caller = "") + { + Print(LogLevel.Error, Class, GetFormattedMessage(Class, Message, Caller)); + } + + private void Print(LogLevel Level, LogClass Class, string Message) + { + if (EnabledLevels[(int)Level] && EnabledClasses[(int)Class]) + { + Updated?.Invoke(this, new LogEventArgs(Level, Time.Elapsed, Message)); + } + } + + private string GetFormattedMessage(LogClass Class, string Message, string Caller) + { + return $"{Class} {Caller}: {Message}"; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs b/Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs index 81aa3fdd..c601d522 100644 --- a/Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs +++ b/Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs @@ -1,3 +1,4 @@ +using Ryujinx.Core.Logging; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -124,8 +125,12 @@ namespace Ryujinx.Core.OsHle.Handles private object SchedLock; - public KProcessScheduler() + private Logger Log; + + public KProcessScheduler(Logger Log) { + this.Log = Log; + AllThreads = new ConcurrentDictionary(); WaitingToRun = new ThreadQueue[4]; @@ -183,7 +188,7 @@ namespace Ryujinx.Core.OsHle.Handles if (NewThread == null) { - Logging.Debug(LogClass.KernelScheduler, $"Nothing to run on core {Thread.ProcessorId}!"); + Log.PrintDebug(LogClass.KernelScheduler, $"Nothing to run on core {Thread.ProcessorId}!"); ActiveProcessors.Remove(Thread.ProcessorId); @@ -276,7 +281,7 @@ namespace Ryujinx.Core.OsHle.Handles } else { - Logging.Debug(LogClass.KernelScheduler, $"Nothing to run on core {ProcessorId}!"); + Log.PrintDebug(LogClass.KernelScheduler, $"Nothing to run on core {ProcessorId}!"); ActiveProcessors.Remove(ProcessorId); } @@ -385,7 +390,7 @@ namespace Ryujinx.Core.OsHle.Handles private void PrintDbgThreadInfo(KThread Thread, string Message) { - Logging.Debug(LogClass.KernelScheduler, "(" + + Log.PrintDebug(LogClass.KernelScheduler, "(" + "ThreadId: " + Thread.ThreadId + ", " + "ProcessorId: " + Thread.ProcessorId + ", " + "ActualPriority: " + Thread.ActualPriority + ", " + diff --git a/Ryujinx.Core/OsHle/Handles/KThread.cs b/Ryujinx.Core/OsHle/Handles/KThread.cs index 4286984e..2084c2ba 100644 --- a/Ryujinx.Core/OsHle/Handles/KThread.cs +++ b/Ryujinx.Core/OsHle/Handles/KThread.cs @@ -7,13 +7,13 @@ namespace Ryujinx.Core.OsHle.Handles { public AThread Thread { get; private set; } - public KThread MutexOwner { get; set; } + public long MutexAddress { get; set; } + public long CondVarAddress { get; set; } public KThread NextMutexThread { get; set; } public KThread NextCondVarThread { get; set; } - public long MutexAddress { get; set; } - public long CondVarAddress { get; set; } + public KThread MutexOwner { get; set; } public int ActualPriority { get; private set; } public int WantedPriority { get; private set; } diff --git a/Ryujinx.Core/OsHle/Horizon.cs b/Ryujinx.Core/OsHle/Horizon.cs index 6c625b09..803d3d67 100644 --- a/Ryujinx.Core/OsHle/Horizon.cs +++ b/Ryujinx.Core/OsHle/Horizon.cs @@ -1,4 +1,5 @@ using Ryujinx.Core.Loaders.Executables; +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Handles; using System; using System.Collections.Concurrent; @@ -26,7 +27,7 @@ namespace Ryujinx.Core.OsHle { this.Ns = Ns; - Scheduler = new KProcessScheduler(); + Scheduler = new KProcessScheduler(Ns.Log); Processes = new ConcurrentDictionary(); @@ -54,7 +55,7 @@ namespace Ryujinx.Core.OsHle continue; } - Logging.Info(LogClass.Loader, $"Loading {Path.GetFileNameWithoutExtension(File)}..."); + Ns.Log.PrintInfo(LogClass.Loader, $"Loading {Path.GetFileNameWithoutExtension(File)}..."); using (FileStream Input = new FileStream(File, FileMode.Open)) { @@ -133,7 +134,7 @@ namespace Ryujinx.Core.OsHle { string NextNro = Homebrew.ReadHbAbiNextLoadPath(Process.Memory, Process.HbAbiDataPosition); - Logging.Info(LogClass.Loader, $"HbAbi NextLoadPath {NextNro}"); + Ns.Log.PrintInfo(LogClass.Loader, $"HbAbi NextLoadPath {NextNro}"); if (NextNro == string.Empty) { diff --git a/Ryujinx.Core/OsHle/Ipc/IpcLog.cs b/Ryujinx.Core/OsHle/Ipc/IpcLog.cs deleted file mode 100644 index 01915d91..00000000 --- a/Ryujinx.Core/OsHle/Ipc/IpcLog.cs +++ /dev/null @@ -1,178 +0,0 @@ -using System; -using System.IO; - -namespace Ryujinx.Core.OsHle.Ipc -{ - public static class IpcLog - { - public static string Message(byte[] Data, long CmdPtr, bool Domain) - { - string IpcMessage = ""; - - using (MemoryStream MS = new MemoryStream(Data)) - { - BinaryReader Reader = new BinaryReader(MS); - - int Word0 = Reader.ReadInt32(); - int Word1 = Reader.ReadInt32(); - - int Type = (Word0 & 0xffff); - - int PtrBuffCount = (Word0 >> 16) & 0xf; - int SendBuffCount = (Word0 >> 20) & 0xf; - int RecvBuffCount = (Word0 >> 24) & 0xf; - int XchgBuffCount = (Word0 >> 28) & 0xf; - - int RawDataSize = (Word1 >> 0) & 0x3ff; - int RecvListFlags = (Word1 >> 10) & 0xf; - bool HndDescEnable = ((Word1 >> 31) & 0x1) != 0; - - IpcMessage += Environment.NewLine + $" {Logging.GetExecutionTime()} | IpcMessage >" + Environment.NewLine + - $" Type: {Enum.GetName(typeof(IpcMessageType), Type)}" + Environment.NewLine + - - $" PtrBuffCount: {PtrBuffCount.ToString()}" + Environment.NewLine + - $" SendBuffCount: {SendBuffCount.ToString()}" + Environment.NewLine + - $" RecvBuffCount: {RecvBuffCount.ToString()}" + Environment.NewLine + - $" XchgBuffCount: {XchgBuffCount.ToString()}" + Environment.NewLine + - - $" RawDataSize: {RawDataSize.ToString()}" + Environment.NewLine + - $" RecvListFlags: {RecvListFlags.ToString()}" + Environment.NewLine + - $" HndDescEnable: {HndDescEnable.ToString()}" + Environment.NewLine; - - if (HndDescEnable) - { - int Word = Reader.ReadInt32(); - - bool HasPId = (Word & 1) != 0; - - int[] ToCopy = new int[(Word >> 1) & 0xf]; - int[] ToMove = new int[(Word >> 5) & 0xf]; - - long PId = HasPId ? Reader.ReadInt64() : 0; - - for (int Index = 0; Index < ToCopy.Length; Index++) - { - ToCopy[Index] = Reader.ReadInt32(); - } - - for (int Index = 0; Index < ToMove.Length; Index++) - { - ToMove[Index] = Reader.ReadInt32(); - } - - IpcMessage += Environment.NewLine + " HndDesc:" + Environment.NewLine + - $" PId: {PId.ToString()}" + Environment.NewLine + - $" ToCopy.Length: {ToCopy.Length.ToString()}" + Environment.NewLine + - $" ToMove.Length: {ToMove.Length.ToString()}" + Environment.NewLine; - } - - for (int Index = 0; Index < PtrBuffCount; Index++) - { - long IpcPtrBuffDescWord0 = Reader.ReadUInt32(); - long IpcPtrBuffDescWord1 = Reader.ReadUInt32(); - - long Position = IpcPtrBuffDescWord1; - Position |= (IpcPtrBuffDescWord0 << 20) & 0x0f00000000; - Position |= (IpcPtrBuffDescWord0 << 30) & 0x7000000000; - - int IpcPtrBuffDescIndex = ((int)IpcPtrBuffDescWord0 >> 0) & 0x03f; - IpcPtrBuffDescIndex |= ((int)IpcPtrBuffDescWord0 >> 3) & 0x1c0; - - short Size = (short)(IpcPtrBuffDescWord0 >> 16); - - IpcMessage += Environment.NewLine + $" PtrBuff[{Index}]:" + Environment.NewLine + - $" Position: {Position.ToString()}" + Environment.NewLine + - $" IpcPtrBuffDescIndex: {IpcPtrBuffDescIndex.ToString()}" + Environment.NewLine + - $" Size: {Size.ToString()}" + Environment.NewLine; - } - - ReadIpcBuffValues(Reader, SendBuffCount, IpcMessage, "SendBuff"); - ReadIpcBuffValues(Reader, RecvBuffCount, IpcMessage, "RecvBuff"); - ReadIpcBuffValues(Reader, XchgBuffCount, IpcMessage, "XchgBuff"); - - RawDataSize *= 4; - - long RecvListPos = Reader.BaseStream.Position + RawDataSize; - long Pad0 = 0; - - if ((Reader.BaseStream.Position + CmdPtr & 0xf) != 0) - { - Pad0 = 0x10 - (Reader.BaseStream.Position + CmdPtr & 0xf); - } - - Reader.BaseStream.Seek(Pad0, SeekOrigin.Current); - - int RecvListCount = RecvListFlags - 2; - - if (RecvListCount == 0) - { - RecvListCount = 1; - } - else if (RecvListCount < 0) - { - RecvListCount = 0; - } - - if (Domain && (IpcMessageType)Type == IpcMessageType.Request) - { - int DomWord0 = Reader.ReadInt32(); - - int DomCmd = (DomWord0 & 0xff); - - RawDataSize = (DomWord0 >> 16) & 0xffff; - - int DomObjId = Reader.ReadInt32(); - - Reader.ReadInt64(); //Padding - - IpcMessage += Environment.NewLine + $" Domain:" + Environment.NewLine + Environment.NewLine + - $" DomObjId: {DomObjId.ToString()}" + Environment.NewLine; - } - - byte[] RawData = Reader.ReadBytes(RawDataSize); - - IpcMessage += Environment.NewLine + $" RawData:" + Environment.NewLine + Logging.HexDump(RawData); - - Reader.BaseStream.Seek(RecvListPos, SeekOrigin.Begin); - - for (int Index = 0; Index < RecvListCount; Index++) - { - long RecvListBuffValue = Reader.ReadInt64(); - long RecvListBuffPosition = RecvListBuffValue & 0xffffffffffff; - long RecvListBuffSize = (short)(RecvListBuffValue >> 48); - - IpcMessage += Environment.NewLine + $" RecvList[{Index}]:" + Environment.NewLine + - $" Value: {RecvListBuffValue.ToString()}" + Environment.NewLine + - $" Position: {RecvListBuffPosition.ToString()}" + Environment.NewLine + - $" Size: {RecvListBuffSize.ToString()}" + Environment.NewLine; - } - } - - return IpcMessage; - } - - private static void ReadIpcBuffValues(BinaryReader Reader, int Count, string IpcMessage, string BufferName) - { - for (int Index = 0; Index < Count; Index++) - { - long Word0 = Reader.ReadUInt32(); - long Word1 = Reader.ReadUInt32(); - long Word2 = Reader.ReadUInt32(); - - long Position = Word1; - Position |= (Word2 << 4) & 0x0f00000000; - Position |= (Word2 << 34) & 0x7000000000; - - long Size = Word0; - Size |= (Word2 << 8) & 0xf00000000; - - int Flags = (int)Word2 & 3; - - IpcMessage += Environment.NewLine + $" {BufferName}[{Index}]:" + Environment.NewLine + - $" Position: {Position.ToString()}" + Environment.NewLine + - $" Flags: {Flags.ToString()}" + Environment.NewLine + - $" Size: {Size.ToString()}" + Environment.NewLine; - } - } - } -} diff --git a/Ryujinx.Core/OsHle/Ipc/IpcMessage.cs b/Ryujinx.Core/OsHle/Ipc/IpcMessage.cs index a9924246..4c4fa56e 100644 --- a/Ryujinx.Core/OsHle/Ipc/IpcMessage.cs +++ b/Ryujinx.Core/OsHle/Ipc/IpcMessage.cs @@ -15,7 +15,7 @@ namespace Ryujinx.Core.OsHle.Ipc public List ExchangeBuff { get; private set; } public List RecvListBuff { get; private set; } - public List ResponseObjIds { get; private set; } + public List ResponseObjIds { get; private set; } public byte[] RawData { get; set; } @@ -84,7 +84,7 @@ namespace Ryujinx.Core.OsHle.Ipc long Pad0 = GetPadSize16(Reader.BaseStream.Position + CmdPtr); - Reader.BaseStream.Seek(Pad0, SeekOrigin.Current); + Reader.BaseStream.Seek(Pad0, SeekOrigin.Current); int RecvListCount = RecvListFlags - 2; @@ -109,7 +109,6 @@ namespace Ryujinx.Core.OsHle.Ipc public byte[] GetBytes(long CmdPtr) { - //todo using (MemoryStream MS = new MemoryStream()) { BinaryWriter Writer = new BinaryWriter(MS); diff --git a/Ryujinx.Core/OsHle/Kernel/SvcHandler.cs b/Ryujinx.Core/OsHle/Kernel/SvcHandler.cs index 25d2767e..da7dce89 100644 --- a/Ryujinx.Core/OsHle/Kernel/SvcHandler.cs +++ b/Ryujinx.Core/OsHle/Kernel/SvcHandler.cs @@ -1,6 +1,7 @@ using ChocolArm64.Events; using ChocolArm64.Memory; using ChocolArm64.State; +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Handles; using System; using System.Collections.Generic; @@ -85,11 +86,9 @@ namespace Ryujinx.Core.OsHle.Kernel if (SvcFuncs.TryGetValue(e.Id, out SvcFunc Func)) { - Logging.Trace(LogClass.KernelSvc, $"(Thread {ThreadState.ThreadId}) {Func.Method.Name} called."); - Func(ThreadState); - Logging.Trace(LogClass.KernelSvc, $"(Thread {ThreadState.ThreadId}) {Func.Method.Name} ended."); + Ns.Log.PrintDebug(LogClass.KernelSvc, $"{Func.Method.Name} ended."); } else { diff --git a/Ryujinx.Core/OsHle/Kernel/SvcMemory.cs b/Ryujinx.Core/OsHle/Kernel/SvcMemory.cs index c8aedcff..6609d14a 100644 --- a/Ryujinx.Core/OsHle/Kernel/SvcMemory.cs +++ b/Ryujinx.Core/OsHle/Kernel/SvcMemory.cs @@ -1,5 +1,6 @@ using ChocolArm64.Memory; using ChocolArm64.State; +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Handles; using static Ryujinx.Core.OsHle.ErrorCode; @@ -57,7 +58,7 @@ namespace Ryujinx.Core.OsHle.Kernel if (!IsValidPosition(Src)) { - Logging.Warn(LogClass.KernelSvc, $"Tried to map Memory at invalid src address {Src:x16}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid src address {Src:x16}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange); @@ -66,7 +67,7 @@ namespace Ryujinx.Core.OsHle.Kernel if (!IsValidMapPosition(Dst)) { - Logging.Warn(LogClass.KernelSvc, $"Tried to map Memory at invalid dst address {Dst:x16}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid dst address {Dst:x16}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange); @@ -92,7 +93,7 @@ namespace Ryujinx.Core.OsHle.Kernel if (!IsValidPosition(Src)) { - Logging.Warn(LogClass.KernelSvc, $"Tried to unmap Memory at invalid src address {Src:x16}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid src address {Src:x16}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange); @@ -101,7 +102,7 @@ namespace Ryujinx.Core.OsHle.Kernel if (!IsValidMapPosition(Dst)) { - Logging.Warn(LogClass.KernelSvc, $"Tried to unmap Memory at invalid dst address {Dst:x16}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid dst address {Dst:x16}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange); @@ -158,7 +159,7 @@ namespace Ryujinx.Core.OsHle.Kernel if (!IsValidPosition(Src)) { - Logging.Warn(LogClass.KernelSvc, $"Tried to map SharedMemory at invalid address {Src:x16}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid address {Src:x16}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange); @@ -196,7 +197,7 @@ namespace Ryujinx.Core.OsHle.Kernel if (!IsValidPosition(Src)) { - Logging.Warn(LogClass.KernelSvc, $"Tried to unmap SharedMemory at invalid address {Src:x16}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid address {Src:x16}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange); @@ -230,7 +231,7 @@ namespace Ryujinx.Core.OsHle.Kernel if (!IsValidPosition(Src)) { - Logging.Warn(LogClass.KernelSvc, $"Tried to create TransferMemory at invalid address {Src:x16}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid address {Src:x16}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange); diff --git a/Ryujinx.Core/OsHle/Kernel/SvcSystem.cs b/Ryujinx.Core/OsHle/Kernel/SvcSystem.cs index 056b5059..601b211c 100644 --- a/Ryujinx.Core/OsHle/Kernel/SvcSystem.cs +++ b/Ryujinx.Core/OsHle/Kernel/SvcSystem.cs @@ -1,5 +1,6 @@ using ChocolArm64.Memory; using ChocolArm64.State; +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Exceptions; using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; @@ -39,7 +40,7 @@ namespace Ryujinx.Core.OsHle.Kernel if (Obj == null) { - Logging.Warn(LogClass.KernelSvc, $"Tried to CloseHandle on invalid handle 0x{Handle:x8}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Tried to CloseHandle on invalid handle 0x{Handle:x8}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle); @@ -75,7 +76,7 @@ namespace Ryujinx.Core.OsHle.Kernel } else { - Logging.Warn(LogClass.KernelSvc, $"Tried to ResetSignal on invalid event handle 0x{Handle:x8}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid event handle 0x{Handle:x8}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle); } @@ -99,7 +100,7 @@ namespace Ryujinx.Core.OsHle.Kernel if (SyncObj == null) { - Logging.Warn(LogClass.KernelSvc, $"Tried to WaitSynchronization on invalid handle 0x{Handle:x8}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid handle 0x{Handle:x8}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle); @@ -199,7 +200,7 @@ namespace Ryujinx.Core.OsHle.Kernel } else { - Logging.Warn(LogClass.KernelSvc, $"Tried to SendSyncRequest on invalid session handle 0x{Handle:x8}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid session handle 0x{Handle:x8}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle); } @@ -223,7 +224,7 @@ namespace Ryujinx.Core.OsHle.Kernel string Str = AMemoryHelper.ReadAsciiString(Memory, Position, Size); - Logging.Info(LogClass.KernelSvc, Str); + Ns.Log.PrintWarning(LogClass.KernelSvc, Str); ThreadState.X0 = 0; } diff --git a/Ryujinx.Core/OsHle/Kernel/SvcThread.cs b/Ryujinx.Core/OsHle/Kernel/SvcThread.cs index e1300b73..0d5f2f4f 100644 --- a/Ryujinx.Core/OsHle/Kernel/SvcThread.cs +++ b/Ryujinx.Core/OsHle/Kernel/SvcThread.cs @@ -1,4 +1,5 @@ using ChocolArm64.State; +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Handles; using System.Threading; @@ -49,7 +50,7 @@ namespace Ryujinx.Core.OsHle.Kernel } else { - Logging.Warn(LogClass.KernelSvc, $"Invalid thread handle 0x{Handle:x8}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid thread handle 0x{Handle:x8}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle); } @@ -95,7 +96,7 @@ namespace Ryujinx.Core.OsHle.Kernel } else { - Logging.Warn(LogClass.KernelSvc, $"Invalid thread handle 0x{Handle:x8}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid thread handle 0x{Handle:x8}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle); } @@ -116,7 +117,7 @@ namespace Ryujinx.Core.OsHle.Kernel } else { - Logging.Warn(LogClass.KernelSvc, $"Invalid thread handle 0x{Handle:x8}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid thread handle 0x{Handle:x8}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle); } @@ -147,7 +148,7 @@ namespace Ryujinx.Core.OsHle.Kernel } else { - Logging.Warn(LogClass.KernelSvc, $"Invalid thread handle 0x{Handle:x8}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid thread handle 0x{Handle:x8}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle); } @@ -168,7 +169,7 @@ namespace Ryujinx.Core.OsHle.Kernel } else { - Logging.Warn(LogClass.KernelSvc, $"Invalid thread handle 0x{Handle:x8}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid thread handle 0x{Handle:x8}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle); } diff --git a/Ryujinx.Core/OsHle/Kernel/SvcThreadSync.cs b/Ryujinx.Core/OsHle/Kernel/SvcThreadSync.cs index 6502e4c9..d5593e02 100644 --- a/Ryujinx.Core/OsHle/Kernel/SvcThreadSync.cs +++ b/Ryujinx.Core/OsHle/Kernel/SvcThreadSync.cs @@ -1,4 +1,5 @@ using ChocolArm64.State; +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Handles; using System; using System.Threading; @@ -19,7 +20,7 @@ namespace Ryujinx.Core.OsHle.Kernel if (IsPointingInsideKernel(MutexAddress)) { - Logging.Warn(LogClass.KernelSvc, $"Invalid mutex address 0x{MutexAddress:x16}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid mutex address 0x{MutexAddress:x16}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress); @@ -28,7 +29,7 @@ namespace Ryujinx.Core.OsHle.Kernel if (IsWordAddressUnaligned(MutexAddress)) { - Logging.Warn(LogClass.KernelSvc, $"Unaligned mutex address 0x{MutexAddress:x16}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Unaligned mutex address 0x{MutexAddress:x16}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAlignment); @@ -39,7 +40,7 @@ namespace Ryujinx.Core.OsHle.Kernel if (OwnerThread == null) { - Logging.Warn(LogClass.KernelSvc, $"Invalid owner thread handle 0x{OwnerThreadHandle:x8}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid owner thread handle 0x{OwnerThreadHandle:x8}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle); @@ -50,7 +51,7 @@ namespace Ryujinx.Core.OsHle.Kernel if (WaitThread == null) { - Logging.Warn(LogClass.KernelSvc, $"Invalid requesting thread handle 0x{WaitThreadHandle:x8}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid requesting thread handle 0x{WaitThreadHandle:x8}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle); @@ -70,7 +71,7 @@ namespace Ryujinx.Core.OsHle.Kernel if (IsPointingInsideKernel(MutexAddress)) { - Logging.Warn(LogClass.KernelSvc, $"Invalid mutex address 0x{MutexAddress:x16}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid mutex address 0x{MutexAddress:x16}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress); @@ -79,7 +80,7 @@ namespace Ryujinx.Core.OsHle.Kernel if (IsWordAddressUnaligned(MutexAddress)) { - Logging.Warn(LogClass.KernelSvc, $"Unaligned mutex address 0x{MutexAddress:x16}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Unaligned mutex address 0x{MutexAddress:x16}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAlignment); @@ -103,7 +104,7 @@ namespace Ryujinx.Core.OsHle.Kernel if (IsPointingInsideKernel(MutexAddress)) { - Logging.Warn(LogClass.KernelSvc, $"Invalid mutex address 0x{MutexAddress:x16}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid mutex address 0x{MutexAddress:x16}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress); @@ -112,7 +113,7 @@ namespace Ryujinx.Core.OsHle.Kernel if (IsWordAddressUnaligned(MutexAddress)) { - Logging.Warn(LogClass.KernelSvc, $"Unaligned mutex address 0x{MutexAddress:x16}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Unaligned mutex address 0x{MutexAddress:x16}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAlignment); @@ -123,7 +124,7 @@ namespace Ryujinx.Core.OsHle.Kernel if (Thread == null) { - Logging.Warn(LogClass.KernelSvc, $"Invalid thread handle 0x{ThreadHandle:x8}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid thread handle 0x{ThreadHandle:x8}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle); @@ -182,7 +183,7 @@ namespace Ryujinx.Core.OsHle.Kernel { if (CurrThread == null) { - Logging.Warn(LogClass.KernelSvc, $"Invalid mutex 0x{MutexAddress:x16}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid mutex 0x{MutexAddress:x16}!"); return false; } @@ -357,7 +358,7 @@ namespace Ryujinx.Core.OsHle.Kernel if (OwnerThread == null) { - Logging.Warn(LogClass.KernelSvc, $"Invalid thread handle 0x{OwnerThreadHandle:x8}!"); + Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid thread handle 0x{OwnerThreadHandle:x8}!"); return; } diff --git a/Ryujinx.Core/OsHle/Process.cs b/Ryujinx.Core/OsHle/Process.cs index 6591ed5a..c3f934af 100644 --- a/Ryujinx.Core/OsHle/Process.cs +++ b/Ryujinx.Core/OsHle/Process.cs @@ -4,6 +4,7 @@ using ChocolArm64.Memory; using ChocolArm64.State; using Ryujinx.Core.Loaders; using Ryujinx.Core.Loaders.Executables; +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Exceptions; using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Kernel; @@ -96,7 +97,7 @@ namespace Ryujinx.Core.OsHle throw new ObjectDisposedException(nameof(Process)); } - Logging.Info(LogClass.Loader, $"Image base at 0x{ImageBase:x16}."); + Ns.Log.PrintInfo(LogClass.Loader, $"Image base at 0x{ImageBase:x16}."); Executable Executable = new Executable(Program, Memory, ImageBase); @@ -282,7 +283,7 @@ namespace Ryujinx.Core.OsHle } } - Logging.Trace(LogClass.CPU, $"Executing at 0x{e.Position:x16} {e.SubName} {NsoName}"); + Ns.Log.PrintDebug(LogClass.Cpu, $"Executing at 0x{e.Position:x16} {e.SubName} {NsoName}"); } public void PrintStackTrace(AThreadState ThreadState) @@ -303,7 +304,7 @@ namespace Ryujinx.Core.OsHle Trace.AppendLine(" " + SubName + " (" + GetNsoNameAndAddress(Position) + ")"); } - Logging.Info(LogClass.CPU, Trace.ToString()); + Ns.Log.PrintInfo(LogClass.Cpu, Trace.ToString()); } private string GetNsoNameAndAddress(long Position) @@ -342,8 +343,6 @@ namespace Ryujinx.Core.OsHle { if (sender is AThread Thread) { - Logging.Info(LogClass.KernelScheduler, $"Thread {Thread.ThreadId} exiting..."); - TlsSlots.TryRemove(GetTlsSlot(Thread.ThreadState.Tpidr), out _); KThread KernelThread = GetThread(Thread.ThreadState.Tpidr); @@ -360,8 +359,6 @@ namespace Ryujinx.Core.OsHle Dispose(); } - Logging.Info(LogClass.KernelScheduler, $"No threads running, now exiting Process {ProcessId}..."); - Ns.Os.ExitProcess(ProcessId); } } @@ -375,7 +372,7 @@ namespace Ryujinx.Core.OsHle { if (!Threads.TryGetValue(Tpidr, out KThread Thread)) { - Logging.Error(LogClass.KernelScheduler, $"Thread with TPIDR 0x{Tpidr:x16} not found!"); + throw new InvalidOperationException(); } return Thread; @@ -398,7 +395,7 @@ namespace Ryujinx.Core.OsHle { ShouldDispose = true; - Logging.Info(LogClass.KernelScheduler, $"Process {ProcessId} waiting all threads terminate..."); + Ns.Log.PrintInfo(LogClass.Loader, $"Process {ProcessId} waiting all threads terminate..."); return; } @@ -425,7 +422,7 @@ namespace Ryujinx.Core.OsHle Memory.Dispose(); - Logging.Info(LogClass.KernelScheduler, $"Process {ProcessId} exiting..."); + Ns.Log.PrintInfo(LogClass.Loader, $"Process {ProcessId} exiting..."); } } } diff --git a/Ryujinx.Core/OsHle/Services/Acc/IAccountServiceForApplication.cs b/Ryujinx.Core/OsHle/Services/Acc/IAccountServiceForApplication.cs index 3ecdf15c..7b09b5f0 100644 --- a/Ryujinx.Core/OsHle/Services/Acc/IAccountServiceForApplication.cs +++ b/Ryujinx.Core/OsHle/Services/Acc/IAccountServiceForApplication.cs @@ -1,3 +1,4 @@ +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; @@ -13,9 +14,9 @@ namespace Ryujinx.Core.OsHle.Services.Acc { m_Commands = new Dictionary() { - { 0, GetUserCount }, - { 3, ListOpenUsers }, - { 5, GetProfile }, + { 0, GetUserCount }, + { 3, ListOpenUsers }, + { 5, GetProfile }, { 100, InitializeApplicationInfo }, { 101, GetBaasAccountManagerForApplication } }; @@ -25,14 +26,14 @@ namespace Ryujinx.Core.OsHle.Services.Acc { Context.ResponseData.Write(0); - Logging.Stub(LogClass.ServiceAcc, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceAcc, "Stubbed."); return 0; } public long ListOpenUsers(ServiceCtx Context) { - Logging.Stub(LogClass.ServiceAcc, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceAcc, "Stubbed."); return 0; } @@ -46,7 +47,7 @@ namespace Ryujinx.Core.OsHle.Services.Acc public long InitializeApplicationInfo(ServiceCtx Context) { - Logging.Stub(LogClass.ServiceAcc, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceAcc, "Stubbed."); return 0; } diff --git a/Ryujinx.Core/OsHle/Services/Acc/IManagerForApplication.cs b/Ryujinx.Core/OsHle/Services/Acc/IManagerForApplication.cs index cc72a64c..4dbbd8d1 100644 --- a/Ryujinx.Core/OsHle/Services/Acc/IManagerForApplication.cs +++ b/Ryujinx.Core/OsHle/Services/Acc/IManagerForApplication.cs @@ -1,3 +1,4 @@ +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; @@ -20,14 +21,14 @@ namespace Ryujinx.Core.OsHle.Services.Acc public long CheckAvailability(ServiceCtx Context) { - Logging.Stub(LogClass.ServiceAcc, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceAcc, "Stubbed."); return 0; } public long GetAccountId(ServiceCtx Context) { - Logging.Stub(LogClass.ServiceAcc, "AccountId = 0xcafeL"); + Context.Ns.Log.PrintStub(LogClass.ServiceAcc, "Stubbed."); Context.ResponseData.Write(0xcafeL); diff --git a/Ryujinx.Core/OsHle/Services/Acc/IProfile.cs b/Ryujinx.Core/OsHle/Services/Acc/IProfile.cs index 6f316b1c..98df3073 100644 --- a/Ryujinx.Core/OsHle/Services/Acc/IProfile.cs +++ b/Ryujinx.Core/OsHle/Services/Acc/IProfile.cs @@ -1,3 +1,4 @@ +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; @@ -19,7 +20,7 @@ namespace Ryujinx.Core.OsHle.Services.Acc public long GetBase(ServiceCtx Context) { - Logging.Stub(LogClass.ServiceAcc, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceAcc, "Stubbed."); Context.ResponseData.Write(0L); Context.ResponseData.Write(0L); @@ -28,7 +29,7 @@ namespace Ryujinx.Core.OsHle.Services.Acc Context.ResponseData.Write(0L); Context.ResponseData.Write(0L); Context.ResponseData.Write(0L); - + return 0; } } diff --git a/Ryujinx.Core/OsHle/Services/Am/IApplicationFunctions.cs b/Ryujinx.Core/OsHle/Services/Am/IApplicationFunctions.cs index f1c63fac..8433f9d5 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IApplicationFunctions.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IApplicationFunctions.cs @@ -1,3 +1,4 @@ +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; using System.IO; @@ -14,7 +15,7 @@ namespace Ryujinx.Core.OsHle.Services.Am { m_Commands = new Dictionary() { - { 1, PopLaunchParameter }, + { 1, PopLaunchParameter }, { 20, EnsureSaveData }, { 21, GetDesiredLanguage }, { 22, SetTerminateResult }, @@ -38,7 +39,7 @@ namespace Ryujinx.Core.OsHle.Services.Am long UIdLow = Context.RequestData.ReadInt64(); long UIdHigh = Context.RequestData.ReadInt64(); - Logging.Stub(LogClass.ServiceAm, $"UidLow = {UIdLow}, UidHigh = {UIdHigh}"); + Context.Ns.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); Context.ResponseData.Write(0L); @@ -47,7 +48,7 @@ namespace Ryujinx.Core.OsHle.Services.Am public long GetDesiredLanguage(ServiceCtx Context) { - Logging.Stub(LogClass.ServiceAm, "LanguageId = 1"); + Context.Ns.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); //This is an enumerator where each number is a differnet language. //0 is Japanese and 1 is English, need to figure out the other codes. @@ -60,14 +61,21 @@ namespace Ryujinx.Core.OsHle.Services.Am { int ErrorCode = Context.RequestData.ReadInt32(); - int Module = ErrorCode & 0xFF; - int Description = (ErrorCode >> 9) & 0xFFF; + string Result = GetFormattedErrorCode(ErrorCode); - Logging.Info(LogClass.ServiceAm, $"({(ErrorModule)Module}){2000 + Module}-{Description}"); + Context.Ns.Log.PrintInfo(LogClass.ServiceAm, $"Result = 0x{ErrorCode:x8} ({Result})."); return 0; } + private string GetFormattedErrorCode(int ErrorCode) + { + int Module = (ErrorCode >> 0) & 0x1ff; + int Description = (ErrorCode >> 9) & 0x1fff; + + return $"{(2000 + Module):d4}-{Description:d4}"; + } + public long GetDisplayVersion(ServiceCtx Context) { //FIXME: Need to check correct version on a switch. diff --git a/Ryujinx.Core/OsHle/Services/Am/IApplicationProxy.cs b/Ryujinx.Core/OsHle/Services/Am/IApplicationProxy.cs index d9d91600..f150f427 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IApplicationProxy.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IApplicationProxy.cs @@ -13,13 +13,13 @@ namespace Ryujinx.Core.OsHle.Services.Am { m_Commands = new Dictionary() { - { 0, GetCommonStateGetter }, - { 1, GetSelfController }, - { 2, GetWindowController }, - { 3, GetAudioController }, - { 4, GetDisplayController }, - { 11, GetLibraryAppletCreator }, - { 20, GetApplicationFunctions }, + { 0, GetCommonStateGetter }, + { 1, GetSelfController }, + { 2, GetWindowController }, + { 3, GetAudioController }, + { 4, GetDisplayController }, + { 11, GetLibraryAppletCreator }, + { 20, GetApplicationFunctions }, { 1000, GetDebugFunctions } }; } diff --git a/Ryujinx.Core/OsHle/Services/Am/IAudioController.cs b/Ryujinx.Core/OsHle/Services/Am/IAudioController.cs index 3b2a6951..7145434f 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IAudioController.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IAudioController.cs @@ -1,3 +1,4 @@ +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; @@ -16,7 +17,7 @@ namespace Ryujinx.Core.OsHle.Services.Am { 0, SetExpectedMasterVolume }, { 1, GetMainAppletExpectedMasterVolume }, { 2, GetLibraryAppletExpectedMasterVolume }, - { 3, ChangeMainAppletMasterVolume }, + { 3, ChangeMainAppletMasterVolume }, { 4, SetTransparentVolumeRate } }; } @@ -26,7 +27,7 @@ namespace Ryujinx.Core.OsHle.Services.Am float AppletVolume = Context.RequestData.ReadSingle(); float LibraryAppletVolume = Context.RequestData.ReadSingle(); - Logging.Stub(LogClass.ServiceAm, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); return 0; } @@ -35,7 +36,7 @@ namespace Ryujinx.Core.OsHle.Services.Am { Context.ResponseData.Write(1f); - Logging.Stub(LogClass.ServiceAm, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); return 0; } @@ -44,7 +45,7 @@ namespace Ryujinx.Core.OsHle.Services.Am { Context.ResponseData.Write(1f); - Logging.Stub(LogClass.ServiceAm, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); return 0; } @@ -54,7 +55,7 @@ namespace Ryujinx.Core.OsHle.Services.Am float Unknown0 = Context.RequestData.ReadSingle(); long Unknown1 = Context.RequestData.ReadInt64(); - Logging.Stub(LogClass.ServiceAm, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); return 0; } @@ -63,7 +64,7 @@ namespace Ryujinx.Core.OsHle.Services.Am { float Unknown0 = Context.RequestData.ReadSingle(); - Logging.Stub(LogClass.ServiceAm, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); return 0; } diff --git a/Ryujinx.Core/OsHle/Services/Am/ICommonStateGetter.cs b/Ryujinx.Core/OsHle/Services/Am/ICommonStateGetter.cs index c1b78e83..ba87cf32 100644 --- a/Ryujinx.Core/OsHle/Services/Am/ICommonStateGetter.cs +++ b/Ryujinx.Core/OsHle/Services/Am/ICommonStateGetter.cs @@ -1,3 +1,4 @@ +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; @@ -66,7 +67,7 @@ namespace Ryujinx.Core.OsHle.Services.Am { Context.ResponseData.Write((byte)0); //Unknown value. - Logging.Stub(LogClass.ServiceAm, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); return 0; } diff --git a/Ryujinx.Core/OsHle/Services/Am/IHomeMenuFunctions.cs b/Ryujinx.Core/OsHle/Services/Am/IHomeMenuFunctions.cs index 2b81eede..b516c0e3 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IHomeMenuFunctions.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IHomeMenuFunctions.cs @@ -1,3 +1,4 @@ +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; @@ -26,7 +27,7 @@ namespace Ryujinx.Core.OsHle.Services.Am public long RequestToGetForeground(ServiceCtx Context) { - Logging.Stub(LogClass.ServiceAm, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); return 0; } @@ -37,7 +38,7 @@ namespace Ryujinx.Core.OsHle.Services.Am Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle); - Logging.Stub(LogClass.ServiceAm, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); return 0; } diff --git a/Ryujinx.Core/OsHle/Services/Am/ISelfController.cs b/Ryujinx.Core/OsHle/Services/Am/ISelfController.cs index e508b5f6..41027df0 100644 --- a/Ryujinx.Core/OsHle/Services/Am/ISelfController.cs +++ b/Ryujinx.Core/OsHle/Services/Am/ISelfController.cs @@ -1,3 +1,4 @@ +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; @@ -33,7 +34,7 @@ namespace Ryujinx.Core.OsHle.Services.Am { bool Enable = Context.RequestData.ReadByte() != 0 ? true : false; - Logging.Stub(LogClass.ServiceAm, $"ScreenShot Allowed = {Enable}"); + Context.Ns.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); return 0; } @@ -42,7 +43,7 @@ namespace Ryujinx.Core.OsHle.Services.Am { bool Enable = Context.RequestData.ReadByte() != 0 ? true : false; - Logging.Stub(LogClass.ServiceAm, $"OperationMode Changed = {Enable}"); + Context.Ns.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); return 0; } @@ -51,7 +52,7 @@ namespace Ryujinx.Core.OsHle.Services.Am { bool Enable = Context.RequestData.ReadByte() != 0 ? true : false; - Logging.Stub(LogClass.ServiceAm, $"PerformanceMode Changed = {Enable}"); + Context.Ns.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); return 0; } @@ -62,7 +63,7 @@ namespace Ryujinx.Core.OsHle.Services.Am bool Flag2 = Context.RequestData.ReadByte() != 0 ? true : false; bool Flag3 = Context.RequestData.ReadByte() != 0 ? true : false; - Logging.Stub(LogClass.ServiceAm, $"Focus Handling Mode Flags = {{{Flag1}|{Flag2}|{Flag3}}}"); + Context.Ns.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); return 0; } @@ -71,7 +72,7 @@ namespace Ryujinx.Core.OsHle.Services.Am { bool Enable = Context.RequestData.ReadByte() != 0 ? true : false; - Logging.Stub(LogClass.ServiceAm, $"Restart Message Enabled = {Enable}"); + Context.Ns.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); return 0; } @@ -80,7 +81,7 @@ namespace Ryujinx.Core.OsHle.Services.Am { bool Enable = Context.RequestData.ReadByte() != 0 ? true : false; - Logging.Stub(LogClass.ServiceAm, $"Out Of Focus Suspending Enabled = {Enable}"); + Context.Ns.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); return 0; } @@ -89,7 +90,7 @@ namespace Ryujinx.Core.OsHle.Services.Am { bool Enable = Context.RequestData.ReadByte() != 0 ? true : false; - Logging.Stub(LogClass.ServiceAm, $"HandlesRequestToDisplay Allowed = {Enable}"); + Context.Ns.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); return 0; } diff --git a/Ryujinx.Core/OsHle/Services/Am/IStorageAccessor.cs b/Ryujinx.Core/OsHle/Services/Am/IStorageAccessor.cs index 1e17d9ba..12336df2 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IStorageAccessor.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IStorageAccessor.cs @@ -17,7 +17,7 @@ namespace Ryujinx.Core.OsHle.Services.Am { m_Commands = new Dictionary() { - { 0, GetSize }, + { 0, GetSize }, { 11, Read } }; @@ -45,7 +45,7 @@ namespace Ryujinx.Core.OsHle.Services.Am if (Storage.Data.Length > Size) { Data = new byte[Size]; - + Buffer.BlockCopy(Storage.Data, 0, Data, 0, Size); } else diff --git a/Ryujinx.Core/OsHle/Services/Am/ISystemAppletProxy.cs b/Ryujinx.Core/OsHle/Services/Am/ISystemAppletProxy.cs index 2d477b34..5a440659 100644 --- a/Ryujinx.Core/OsHle/Services/Am/ISystemAppletProxy.cs +++ b/Ryujinx.Core/OsHle/Services/Am/ISystemAppletProxy.cs @@ -13,15 +13,15 @@ namespace Ryujinx.Core.OsHle.Services.Am { m_Commands = new Dictionary() { - { 0, GetCommonStateGetter }, - { 1, GetSelfController }, - { 2, GetWindowController }, - { 3, GetAudioController }, - { 4, GetDisplayController }, - { 11, GetLibraryAppletCreator }, - { 20, GetHomeMenuFunctions }, - { 21, GetGlobalStateController }, - { 22, GetApplicationCreator }, + { 0, GetCommonStateGetter }, + { 1, GetSelfController }, + { 2, GetWindowController }, + { 3, GetAudioController }, + { 4, GetDisplayController }, + { 11, GetLibraryAppletCreator }, + { 20, GetHomeMenuFunctions }, + { 21, GetGlobalStateController }, + { 22, GetApplicationCreator }, { 1000, GetDebugFunctions } }; } @@ -45,8 +45,8 @@ namespace Ryujinx.Core.OsHle.Services.Am MakeObject(Context, new IWindowController()); return 0; - } - + } + public long GetAudioController(ServiceCtx Context) { MakeObject(Context, new IAudioController()); diff --git a/Ryujinx.Core/OsHle/Services/Am/IWindowController.cs b/Ryujinx.Core/OsHle/Services/Am/IWindowController.cs index b494a64b..554ac00a 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IWindowController.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IWindowController.cs @@ -1,3 +1,4 @@ +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; @@ -13,14 +14,14 @@ namespace Ryujinx.Core.OsHle.Services.Am { m_Commands = new Dictionary() { - { 1, GetAppletResourceUserId }, + { 1, GetAppletResourceUserId }, { 10, AcquireForegroundRights } }; } public long GetAppletResourceUserId(ServiceCtx Context) { - Logging.Stub(LogClass.ServiceAm, $"Applet Resource Id = 0"); + Context.Ns.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); Context.ResponseData.Write(0L); @@ -29,7 +30,7 @@ namespace Ryujinx.Core.OsHle.Services.Am public long AcquireForegroundRights(ServiceCtx Context) { - Logging.Stub(LogClass.ServiceAm, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceAm, "Stubbed."); return 0; } diff --git a/Ryujinx.Core/OsHle/Services/Apm/ISession.cs b/Ryujinx.Core/OsHle/Services/Apm/ISession.cs index bbef100c..3b3e98c9 100644 --- a/Ryujinx.Core/OsHle/Services/Apm/ISession.cs +++ b/Ryujinx.Core/OsHle/Services/Apm/ISession.cs @@ -1,3 +1,4 @@ +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; @@ -32,8 +33,7 @@ namespace Ryujinx.Core.OsHle.Services.Apm Context.ResponseData.Write((uint)PerformanceConfiguration.PerformanceConfiguration1); - Logging.Stub(LogClass.ServiceApm, $"PerformanceMode = {PerfMode}, PerformanceConfiguration =" + - $" {PerformanceConfiguration.PerformanceConfiguration1}"); + Context.Ns.Log.PrintStub(LogClass.ServiceApm, "Stubbed."); return 0; } diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs index 039a4413..3ccb8612 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs @@ -1,4 +1,5 @@ using ChocolArm64.Memory; +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; @@ -68,7 +69,7 @@ namespace Ryujinx.Core.OsHle.Services.Aud string Name = AMemoryHelper.ReadAsciiString(Context.Memory, Position, Size); - Logging.Stub(LogClass.ServiceAudio, $"Volume = {Volume}, Position = {Position}, Size = {Size}"); + Context.Ns.Log.PrintStub(LogClass.ServiceAudio, "Stubbed."); return 0; } @@ -93,7 +94,7 @@ namespace Ryujinx.Core.OsHle.Services.Aud Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle); - Logging.Stub(LogClass.ServiceAudio, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceAudio, "Stubbed."); return 0; } @@ -102,7 +103,7 @@ namespace Ryujinx.Core.OsHle.Services.Aud { Context.ResponseData.Write(2); - Logging.Stub(LogClass.ServiceAudio, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceAudio, "Stubbed."); return 0; } diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs index 3f7a18c4..09c5050f 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs @@ -1,5 +1,6 @@ using ChocolArm64.Memory; using Ryujinx.Audio; +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; using System; @@ -67,7 +68,7 @@ namespace Ryujinx.Core.OsHle.Services.Aud AudioOutData Data = AMemoryHelper.Read( Context.Memory, Context.Request.SendBuff[0].Position); - + byte[] Buffer = AMemoryHelper.ReadBytes( Context.Memory, Data.SampleBufferPtr, @@ -124,14 +125,14 @@ namespace Ryujinx.Core.OsHle.Services.Aud public long AppendAudioOutBufferEx(ServiceCtx Context) { - Logging.Stub(LogClass.ServiceAudio, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceAudio, "Stubbed."); return 0; } public long GetReleasedAudioOutBufferEx(ServiceCtx Context) { - Logging.Stub(LogClass.ServiceAudio, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceAudio, "Stubbed."); return 0; } diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioRenderer.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioRenderer.cs index d3795b53..4d06649f 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/IAudioRenderer.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioRenderer.cs @@ -1,3 +1,4 @@ +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; using System; @@ -54,14 +55,14 @@ namespace Ryujinx.Core.OsHle.Services.Aud public long StartAudioRenderer(ServiceCtx Context) { - Logging.Stub(LogClass.ServiceAudio, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceAudio, "Stubbed."); return 0; } public long StopAudioRenderer(ServiceCtx Context) { - Logging.Stub(LogClass.ServiceAudio, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceAudio, "Stubbed."); return 0; } diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioRendererManager.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioRendererManager.cs index dcf3c7b7..97dc074c 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/IAudioRendererManager.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioRendererManager.cs @@ -1,3 +1,4 @@ +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; @@ -42,7 +43,7 @@ namespace Ryujinx.Core.OsHle.Services.Aud int Unknown2c = Context.RequestData.ReadInt32(); int Rev1Magic = Context.RequestData.ReadInt32(); - Logging.Stub(LogClass.ServiceAudio, "BufferSize = 0x400L"); + Context.Ns.Log.PrintStub(LogClass.ServiceAudio, "Stubbed."); Context.ResponseData.Write(0x400L); diff --git a/Ryujinx.Core/OsHle/Services/Bsd/IClient.cs b/Ryujinx.Core/OsHle/Services/Bsd/IClient.cs index ccfb9147..f26e5ee3 100644 --- a/Ryujinx.Core/OsHle/Services/Bsd/IClient.cs +++ b/Ryujinx.Core/OsHle/Services/Bsd/IClient.cs @@ -21,11 +21,11 @@ namespace Ryujinx.Core.OsHle.Services.Bsd { m_Commands = new Dictionary() { - { 0, Initialize }, - { 1, StartMonitoring }, - { 2, Socket }, - { 6, Poll }, - { 8, Recv }, + { 0, Initialize }, + { 1, StartMonitoring }, + { 2, Socket }, + { 6, Poll }, + { 8, Recv }, { 10, Send }, { 11, SendTo }, { 12, Accept }, @@ -428,9 +428,8 @@ namespace Ryujinx.Core.OsHle.Services.Bsd Reader.ReadByte().ToString() + "." + Reader.ReadByte().ToString(); - Logging.Debug(LogClass.ServiceBsd, $"Try to connect to {IpAddress}:{Port}"); - Sockets[SocketId].IpAddress = IPAddress.Parse(IpAddress); + Sockets[SocketId].RemoteEP = new IPEndPoint(Sockets[SocketId].IpAddress, Port); } } diff --git a/Ryujinx.Core/OsHle/Services/FspSrv/IFileSystem.cs b/Ryujinx.Core/OsHle/Services/FspSrv/IFileSystem.cs index f65b89ef..23228db9 100644 --- a/Ryujinx.Core/OsHle/Services/FspSrv/IFileSystem.cs +++ b/Ryujinx.Core/OsHle/Services/FspSrv/IFileSystem.cs @@ -22,16 +22,16 @@ namespace Ryujinx.Core.OsHle.Services.FspSrv { m_Commands = new Dictionary() { - { 0, CreateFile }, - { 1, DeleteFile }, - { 2, CreateDirectory }, - { 3, DeleteDirectory }, - { 4, DeleteDirectoryRecursively }, - { 5, RenameFile }, - { 6, RenameDirectory }, - { 7, GetEntryType }, - { 8, OpenFile }, - { 9, OpenDirectory }, + { 0, CreateFile }, + { 1, DeleteFile }, + { 2, CreateDirectory }, + { 3, DeleteDirectory }, + { 4, DeleteDirectoryRecursively }, + { 5, RenameFile }, + { 6, RenameDirectory }, + { 7, GetEntryType }, + { 8, OpenFile }, + { 9, OpenDirectory }, { 10, Commit }, { 11, GetFreeSpaceSize }, { 12, GetTotalSpaceSize }, diff --git a/Ryujinx.Core/OsHle/Services/FspSrv/IFileSystemProxy.cs b/Ryujinx.Core/OsHle/Services/FspSrv/IFileSystemProxy.cs index 3afee1a1..29c5c68f 100644 --- a/Ryujinx.Core/OsHle/Services/FspSrv/IFileSystemProxy.cs +++ b/Ryujinx.Core/OsHle/Services/FspSrv/IFileSystemProxy.cs @@ -13,11 +13,11 @@ namespace Ryujinx.Core.OsHle.Services.FspSrv { m_Commands = new Dictionary() { - { 1, SetCurrentProcess }, - { 18, OpenSdCardFileSystem }, - { 51, OpenSaveDataFileSystem }, - { 200, OpenDataStorageByCurrentProcess }, - { 203, OpenPatchDataStorageByCurrentProcess }, + { 1, SetCurrentProcess }, + { 18, OpenSdCardFileSystem }, + { 51, OpenSaveDataFileSystem }, + { 200, OpenDataStorageByCurrentProcess }, + { 203, OpenPatchDataStorageByCurrentProcess }, { 1005, GetGlobalAccessLogMode } }; } diff --git a/Ryujinx.Core/OsHle/Services/Hid/IHidServer.cs b/Ryujinx.Core/OsHle/Services/Hid/IHidServer.cs index 0b401e20..b603d936 100644 --- a/Ryujinx.Core/OsHle/Services/Hid/IHidServer.cs +++ b/Ryujinx.Core/OsHle/Services/Hid/IHidServer.cs @@ -1,4 +1,5 @@ using Ryujinx.Core.Input; +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; @@ -14,13 +15,13 @@ namespace Ryujinx.Core.OsHle.Services.Hid { m_Commands = new Dictionary() { - { 0, CreateAppletResource }, - { 1, ActivateDebugPad }, - { 11, ActivateTouchScreen }, - { 21, ActivateMouse }, - { 31, ActivateKeyboard }, - { 66, StartSixAxisSensor }, - { 79, SetGyroscopeZeroDriftMode }, + { 0, CreateAppletResource }, + { 1, ActivateDebugPad }, + { 11, ActivateTouchScreen }, + { 21, ActivateMouse }, + { 31, ActivateKeyboard }, + { 66, StartSixAxisSensor }, + { 79, SetGyroscopeZeroDriftMode }, { 100, SetSupportedNpadStyleSet }, { 101, GetSupportedNpadStyleSet }, { 102, SetSupportedNpadIdType }, @@ -49,7 +50,7 @@ namespace Ryujinx.Core.OsHle.Services.Hid public long ActivateDebugPad(ServiceCtx Context) { - Logging.Stub(LogClass.ServiceHid, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceHid, "Stubbed."); return 0; } @@ -58,7 +59,7 @@ namespace Ryujinx.Core.OsHle.Services.Hid { long AppletResourceUserId = Context.RequestData.ReadInt64(); - Logging.Stub(LogClass.ServiceHid, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceHid, "Stubbed."); return 0; } @@ -67,7 +68,7 @@ namespace Ryujinx.Core.OsHle.Services.Hid { long AppletResourceUserId = Context.RequestData.ReadInt64(); - Logging.Stub(LogClass.ServiceHid, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceHid, "Stubbed."); return 0; } @@ -76,7 +77,7 @@ namespace Ryujinx.Core.OsHle.Services.Hid { long AppletResourceUserId = Context.RequestData.ReadInt64(); - Logging.Stub(LogClass.ServiceHid, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceHid, "Stubbed."); return 0; } @@ -87,18 +88,18 @@ namespace Ryujinx.Core.OsHle.Services.Hid long AppletResourceUserId = Context.RequestData.ReadInt64(); - Logging.Stub(LogClass.ServiceHid, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceHid, "Stubbed."); return 0; } public long SetGyroscopeZeroDriftMode(ServiceCtx Context) { - int Handle = Context.RequestData.ReadInt32(); - int Unknown = Context.RequestData.ReadInt32(); + int Handle = Context.RequestData.ReadInt32(); + int Unknown = Context.RequestData.ReadInt32(); long AppletResourceUserId = Context.RequestData.ReadInt64(); - Logging.Stub(LogClass.ServiceHid, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceHid, "Stubbed."); return 0; } @@ -107,7 +108,7 @@ namespace Ryujinx.Core.OsHle.Services.Hid { Context.ResponseData.Write(0); - Logging.Stub(LogClass.ServiceHid, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceHid, "Stubbed."); return 0; } @@ -117,7 +118,7 @@ namespace Ryujinx.Core.OsHle.Services.Hid long Unknown0 = Context.RequestData.ReadInt64(); long Unknown8 = Context.RequestData.ReadInt64(); - Logging.Stub(LogClass.ServiceHid, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceHid, "Stubbed."); return 0; } @@ -126,7 +127,7 @@ namespace Ryujinx.Core.OsHle.Services.Hid { long Unknown = Context.RequestData.ReadInt64(); - Logging.Stub(LogClass.ServiceHid, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceHid, "Stubbed."); return 0; } @@ -135,7 +136,7 @@ namespace Ryujinx.Core.OsHle.Services.Hid { long Unknown = Context.RequestData.ReadInt64(); - Logging.Stub(LogClass.ServiceHid, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceHid, "Stubbed."); return 0; } @@ -146,7 +147,7 @@ namespace Ryujinx.Core.OsHle.Services.Hid Context.ResponseData.Write(0L); - Logging.Stub(LogClass.ServiceHid, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceHid, "Stubbed."); return 0; } @@ -156,7 +157,7 @@ namespace Ryujinx.Core.OsHle.Services.Hid long Unknown0 = Context.RequestData.ReadInt64(); long Unknown8 = Context.RequestData.ReadInt64(); - Logging.Stub(LogClass.ServiceHid, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceHid, "Stubbed."); return 0; } @@ -165,7 +166,7 @@ namespace Ryujinx.Core.OsHle.Services.Hid { Context.ResponseData.Write(0L); - Logging.Stub(LogClass.ServiceHid, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceHid, "Stubbed."); return 0; } @@ -173,9 +174,10 @@ namespace Ryujinx.Core.OsHle.Services.Hid public long SetNpadJoyAssignmentModeSingleByDefault(ServiceCtx Context) { HidControllerId HidControllerId = (HidControllerId)Context.RequestData.ReadInt32(); + long AppletUserResourceId = Context.RequestData.ReadInt64(); - Logging.Stub(LogClass.ServiceHid, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceHid, "Stubbed."); return 0; } @@ -183,10 +185,11 @@ namespace Ryujinx.Core.OsHle.Services.Hid public long SetNpadJoyAssignmentModeSingle(ServiceCtx Context) { HidControllerId HidControllerId = (HidControllerId)Context.RequestData.ReadInt32(); - long AppletUserResourceId = Context.RequestData.ReadInt64(); - long NpadJoyDeviceType = Context.RequestData.ReadInt64(); - Logging.Stub(LogClass.ServiceHid, "Stubbed"); + long AppletUserResourceId = Context.RequestData.ReadInt64(); + long NpadJoyDeviceType = Context.RequestData.ReadInt64(); + + Context.Ns.Log.PrintStub(LogClass.ServiceHid, "Stubbed."); return 0; } @@ -194,20 +197,21 @@ namespace Ryujinx.Core.OsHle.Services.Hid public long SetNpadJoyAssignmentModeDual(ServiceCtx Context) { HidControllerId HidControllerId = (HidControllerId)Context.RequestData.ReadInt32(); + long AppletUserResourceId = Context.RequestData.ReadInt64(); - Logging.Stub(LogClass.ServiceHid, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceHid, "Stubbed."); return 0; } public long MergeSingleJoyAsDualJoy(ServiceCtx Context) { - long Unknown0 = Context.RequestData.ReadInt32(); - long Unknown8 = Context.RequestData.ReadInt32(); + long Unknown0 = Context.RequestData.ReadInt32(); + long Unknown8 = Context.RequestData.ReadInt32(); long AppletUserResourceId = Context.RequestData.ReadInt64(); - Logging.Stub(LogClass.ServiceHid, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceHid, "Stubbed."); return 0; } @@ -215,9 +219,9 @@ namespace Ryujinx.Core.OsHle.Services.Hid public long SetNpadHandheldActivationMode(ServiceCtx Context) { long AppletUserResourceId = Context.RequestData.ReadInt64(); - long Unknown = Context.RequestData.ReadInt64(); + long Unknown = Context.RequestData.ReadInt64(); - Logging.Stub(LogClass.ServiceHid, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceHid, "Stubbed."); return 0; } @@ -226,7 +230,7 @@ namespace Ryujinx.Core.OsHle.Services.Hid { int VibrationDeviceHandle = Context.RequestData.ReadInt32(); - Logging.Stub(LogClass.ServiceHid, $"VibrationDeviceHandle = {VibrationDeviceHandle}, VibrationDeviceInfo = 0"); + Context.Ns.Log.PrintStub(LogClass.ServiceHid, "Stubbed."); Context.ResponseData.Write(0L); //VibrationDeviceInfoForIpc @@ -244,7 +248,7 @@ namespace Ryujinx.Core.OsHle.Services.Hid long AppletUserResourceId = Context.RequestData.ReadInt64(); - Logging.Stub(LogClass.ServiceHid, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceHid, "Stubbed."); return 0; } @@ -258,7 +262,7 @@ namespace Ryujinx.Core.OsHle.Services.Hid public long SendVibrationValues(ServiceCtx Context) { - Logging.Stub(LogClass.ServiceHid, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceHid, "Stubbed."); return 0; } diff --git a/Ryujinx.Core/OsHle/Services/IpcService.cs b/Ryujinx.Core/OsHle/Services/IpcService.cs index f39adb7a..d2eadd27 100644 --- a/Ryujinx.Core/OsHle/Services/IpcService.cs +++ b/Ryujinx.Core/OsHle/Services/IpcService.cs @@ -1,3 +1,4 @@ +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; using System; @@ -81,7 +82,7 @@ namespace Ryujinx.Core.OsHle.Services { Context.ResponseData.BaseStream.Seek(IsDomain ? 0x20 : 0x10, SeekOrigin.Begin); - Logging.Trace(LogClass.KernelIpc, $"{Service.GetType().Name}: {ProcessRequest.Method.Name}"); + Context.Ns.Log.PrintDebug(LogClass.KernelIpc, $"{Service.GetType().Name}: {ProcessRequest.Method.Name}"); long Result = ProcessRequest(Context); diff --git a/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs b/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs index 6d3de79b..c5b6c931 100644 --- a/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs +++ b/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs @@ -1,6 +1,6 @@ using ChocolArm64.Memory; +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Ipc; -using System; using System.Collections.Generic; using System.IO; using System.Text; @@ -21,123 +21,68 @@ namespace Ryujinx.Core.OsHle.Services.Lm }; } - enum Flags - { - Padding, - IsHead, - IsTail - } - - enum Severity - { - Trace, - Info, - Warning, - Error, - Critical - } - - enum Field - { - Padding, - Skip, - Message, - Line, - Filename, - Function, - Module, - Thread - } - public long Log(ServiceCtx Context) { - long BufferPosition = Context.Request.PtrBuff[0].Position; - long BufferLen = Context.Request.PtrBuff[0].Size; + byte[] LogBuffer = AMemoryHelper.ReadBytes( + Context.Memory, + Context.Request.PtrBuff[0].Position, + Context.Request.PtrBuff[0].Size); - byte[] LogBuffer = AMemoryHelper.ReadBytes(Context.Memory, BufferPosition, BufferLen); - - MemoryStream LogMessage = new MemoryStream(LogBuffer); - BinaryReader bReader = new BinaryReader(LogMessage); - - //Header reading. - long Pid = bReader.ReadInt64(); - long ThreadCxt = bReader.ReadInt64(); - int Infos = bReader.ReadInt32(); - int PayloadLen = bReader.ReadInt32(); - - int iFlags = Infos & 0xFFFF; - int iSeverity = (Infos >> 17) & 0x7F; - int iVerbosity = (Infos >> 25) & 0x7F; - - //ToDo: For now we don't care about Head or Tail Log. - bool IsHeadLog = Convert.ToBoolean(iFlags & (int)Flags.IsHead); - bool IsTailLog = Convert.ToBoolean(iFlags & (int)Flags.IsTail); - - string LogString = "nn::diag::detail::LogImpl()" + Environment.NewLine + Environment.NewLine + - "Header:" + Environment.NewLine + - $" Pid: {Pid}" + Environment.NewLine + - $" ThreadContext: {ThreadCxt}" + Environment.NewLine + - $" Flags: {IsHeadLog}/{IsTailLog}" + Environment.NewLine + - $" Severity: {Enum.GetName(typeof(Severity), iSeverity)}" + Environment.NewLine + - $" Verbosity: {iVerbosity}"; - - LogString += Environment.NewLine + Environment.NewLine + "Message:" + Environment.NewLine; - - string StrMessage = "", StrLine = "", StrFilename = "", StrFunction = "", - StrModule = "", StrThread = ""; - - do + using (MemoryStream MS = new MemoryStream(LogBuffer)) { - byte FieldType = bReader.ReadByte(); - byte FieldSize = bReader.ReadByte(); + BinaryReader Reader = new BinaryReader(MS); - if ((Field)FieldType != Field.Skip || FieldSize != 0) + long Pid = Reader.ReadInt64(); + long ThreadContext = Reader.ReadInt64(); + short Flags = Reader.ReadInt16(); + byte Level = Reader.ReadByte(); + byte Verbosity = Reader.ReadByte(); + int PayloadLength = Reader.ReadInt32(); + + StringBuilder SB = new StringBuilder(); + + SB.AppendLine("Guest log:"); + + while (MS.Position < MS.Length) { - byte[] Message = bReader.ReadBytes(FieldSize); - switch ((Field)FieldType) + byte Type = Reader.ReadByte(); + byte Size = Reader.ReadByte(); + + LmLogField Field = (LmLogField)Type; + + string FieldStr = string.Empty; + + if (Field == LmLogField.Skip) { - case Field.Message: - StrMessage = Encoding.UTF8.GetString(Message); - break; + Reader.ReadByte(); - case Field.Line: - StrLine = BitConverter.ToInt32(Message, 0).ToString(); - break; - - case Field.Filename: - StrFilename = Encoding.UTF8.GetString(Message); - break; - - case Field.Function: - StrFunction = Encoding.UTF8.GetString(Message); - break; - - case Field.Module: - StrModule = Encoding.UTF8.GetString(Message); - break; - - case Field.Thread: - StrThread = Encoding.UTF8.GetString(Message); - break; + continue; } + else if (Field == LmLogField.Line) + { + FieldStr = Field + ": " + Reader.ReadInt32(); + } + else + { + FieldStr = Field + ": \"" + Encoding.UTF8.GetString(Reader.ReadBytes(Size)) + "\""; + } + + SB.AppendLine(" " + FieldStr); } - - } - while (LogMessage.Position != PayloadLen + 0x18); // 0x18 - Size of Header LogMessage. - LogString += StrModule + " > " + StrThread + ": " + StrFilename + "@" + StrFunction + "(" + StrLine + ") '" + StrMessage + "'" + Environment.NewLine; + string Text = SB.ToString(); - switch((Severity)iSeverity) - { - case Severity.Trace: Logging.Trace(LogClass.ServiceLm, LogString); break; - case Severity.Info: Logging.Info(LogClass.ServiceLm, LogString); break; - case Severity.Warning: Logging.Warn(LogClass.ServiceLm, LogString); break; - case Severity.Error: Logging.Error(LogClass.ServiceLm, LogString); break; - case Severity.Critical: Logging.Fatal(LogClass.ServiceLm, LogString); break; + switch((LmLogLevel)Level) + { + case LmLogLevel.Trace: Context.Ns.Log.PrintDebug (LogClass.ServiceLm, Text); break; + case LmLogLevel.Info: Context.Ns.Log.PrintInfo (LogClass.ServiceLm, Text); break; + case LmLogLevel.Warning: Context.Ns.Log.PrintWarning(LogClass.ServiceLm, Text); break; + case LmLogLevel.Error: Context.Ns.Log.PrintError (LogClass.ServiceLm, Text); break; + case LmLogLevel.Critical: Context.Ns.Log.PrintError (LogClass.ServiceLm, Text); break; + } } return 0; } } } - \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Lm/LmLogField.cs b/Ryujinx.Core/OsHle/Services/Lm/LmLogField.cs new file mode 100644 index 00000000..2906c7c3 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Lm/LmLogField.cs @@ -0,0 +1,13 @@ +namespace Ryujinx.Core.OsHle.Services.Lm +{ + enum LmLogField + { + Skip = 1, + Message = 2, + Line = 3, + Filename = 4, + Function = 5, + Module = 6, + Thread = 7 + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Lm/LmLogLevel.cs b/Ryujinx.Core/OsHle/Services/Lm/LmLogLevel.cs new file mode 100644 index 00000000..f5c66233 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Lm/LmLogLevel.cs @@ -0,0 +1,11 @@ +namespace Ryujinx.Core.OsHle.Services.Lm +{ + enum LmLogLevel + { + Trace, + Info, + Warning, + Error, + Critical + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Nifm/IGeneralService.cs b/Ryujinx.Core/OsHle/Services/Nifm/IGeneralService.cs index e40ad9f0..2e008339 100644 --- a/Ryujinx.Core/OsHle/Services/Nifm/IGeneralService.cs +++ b/Ryujinx.Core/OsHle/Services/Nifm/IGeneralService.cs @@ -1,3 +1,4 @@ +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; @@ -24,7 +25,7 @@ namespace Ryujinx.Core.OsHle.Services.Nifm MakeObject(Context, new IRequest()); - Logging.Stub(LogClass.ServiceNifm, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceNifm, "Stubbed."); return 0; } diff --git a/Ryujinx.Core/OsHle/Services/Nifm/IRequest.cs b/Ryujinx.Core/OsHle/Services/Nifm/IRequest.cs index 276183cd..7de5a4d9 100644 --- a/Ryujinx.Core/OsHle/Services/Nifm/IRequest.cs +++ b/Ryujinx.Core/OsHle/Services/Nifm/IRequest.cs @@ -1,3 +1,4 @@ +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; using System; @@ -31,14 +32,14 @@ namespace Ryujinx.Core.OsHle.Services.Nifm { Context.ResponseData.Write(0); - Logging.Stub(LogClass.ServiceNifm, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceNifm, "Stubbed."); return 0; } public long GetResult(ServiceCtx Context) { - Logging.Stub(LogClass.ServiceNifm, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceNifm, "Stubbed."); return 0; } @@ -56,14 +57,14 @@ namespace Ryujinx.Core.OsHle.Services.Nifm public long Cancel(ServiceCtx Context) { - Logging.Stub(LogClass.ServiceNifm, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceNifm, "Stubbed."); return 0; } public long Submit(ServiceCtx Context) { - Logging.Stub(LogClass.ServiceNifm, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceNifm, "Stubbed."); return 0; } diff --git a/Ryujinx.Core/OsHle/Services/Ns/IAddOnContentManager.cs b/Ryujinx.Core/OsHle/Services/Ns/IAddOnContentManager.cs index 5c08cd62..5163b3e1 100644 --- a/Ryujinx.Core/OsHle/Services/Ns/IAddOnContentManager.cs +++ b/Ryujinx.Core/OsHle/Services/Ns/IAddOnContentManager.cs @@ -1,3 +1,4 @@ +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; @@ -22,14 +23,14 @@ namespace Ryujinx.Core.OsHle.Services.Ns { Context.ResponseData.Write(0); - Logging.Stub(LogClass.ServiceNs, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceNs, "Stubbed."); return 0; } public static long ListAddOnContent(ServiceCtx Context) { - Logging.Stub(LogClass.ServiceNs, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceNs, "Stubbed."); //TODO: This is supposed to write a u32 array aswell. //It's unknown what it contains. diff --git a/Ryujinx.Core/OsHle/Services/Nv/INvDrvServices.cs b/Ryujinx.Core/OsHle/Services/Nv/INvDrvServices.cs index cc5f95cd..10d63894 100644 --- a/Ryujinx.Core/OsHle/Services/Nv/INvDrvServices.cs +++ b/Ryujinx.Core/OsHle/Services/Nv/INvDrvServices.cs @@ -1,4 +1,5 @@ using ChocolArm64.Memory; +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; using Ryujinx.Core.OsHle.Utilities; @@ -228,7 +229,7 @@ namespace Ryujinx.Core.OsHle.Services.Nv if (Map == null) { - Logging.Warn(LogClass.ServiceNv, $"Trying to use invalid NvMap Handle {Handle}!"); + Context.Ns.Log.PrintWarning(LogClass.ServiceNv, $"invalid NvMap Handle {Handle}!"); return -1; //TODO: Corrent error code. } @@ -634,7 +635,7 @@ namespace Ryujinx.Core.OsHle.Services.Nv Context.Memory.WriteInt32(Position + 4, Map.Handle); - Logging.Info(LogClass.ServiceNv, $"NvMap {Map.Id} created with size {Size:x8}!"); + Context.Ns.Log.PrintInfo(LogClass.ServiceNv, $"NvMap {Map.Id} created with size {Size:x8}!"); return 0; } @@ -649,7 +650,7 @@ namespace Ryujinx.Core.OsHle.Services.Nv if (Map == null) { - Logging.Warn(LogClass.ServiceNv, $"Trying to use invalid NvMap Id {Id}!"); + Context.Ns.Log.PrintWarning(LogClass.ServiceNv, $"Invalid NvMap Id {Id}!"); return -1; //TODO: Corrent error code. } @@ -676,7 +677,7 @@ namespace Ryujinx.Core.OsHle.Services.Nv if (Map == null) { - Logging.Warn(LogClass.ServiceNv, $"Trying to use invalid NvMap Handle {Handle}!"); + Context.Ns.Log.PrintWarning(LogClass.ServiceNv, $"Invalid NvMap Handle {Handle}!"); return -1; //TODO: Corrent error code. } @@ -695,14 +696,14 @@ namespace Ryujinx.Core.OsHle.Services.Nv MemReader Reader = new MemReader(Context.Memory, Position); MemWriter Writer = new MemWriter(Context.Memory, Position + 8); - int Handle = Reader.ReadInt32(); - int Padding = Reader.ReadInt32(); + int Handle = Reader.ReadInt32(); + int Padding = Reader.ReadInt32(); NvMap Map = NvMaps.GetData(Context.Process, Handle); if (Map == null) { - Logging.Warn(LogClass.ServiceNv, $"Trying to use invalid NvMap Handle {Handle}!"); + Context.Ns.Log.PrintWarning(LogClass.ServiceNv, $"Invalid NvMap Handle {Handle}!"); return -1; //TODO: Corrent error code. } @@ -727,7 +728,7 @@ namespace Ryujinx.Core.OsHle.Services.Nv if (Map == null) { - Logging.Warn(LogClass.ServiceNv, $"Trying to use invalid NvMap Handle {Handle}!"); + Context.Ns.Log.PrintWarning(LogClass.ServiceNv, $"Invalid NvMap Handle {Handle}!"); return -1; //TODO: Corrent error code. } @@ -757,7 +758,7 @@ namespace Ryujinx.Core.OsHle.Services.Nv if (Map == null) { - Logging.Warn(LogClass.ServiceNv, $"Trying to use invalid NvMap Handle {Handle}!"); + Context.Ns.Log.PrintWarning(LogClass.ServiceNv, $"Invalid NvMap Handle {Handle}!"); return -1; //TODO: Corrent error code. } diff --git a/Ryujinx.Core/OsHle/Services/ServiceFactory.cs b/Ryujinx.Core/OsHle/Services/ServiceFactory.cs index 8e639b94..6b636e0f 100644 --- a/Ryujinx.Core/OsHle/Services/ServiceFactory.cs +++ b/Ryujinx.Core/OsHle/Services/ServiceFactory.cs @@ -103,6 +103,9 @@ namespace Ryujinx.Core.OsHle.Services case "pl:u": return new ISharedFontManager(); + case "prepo:a": + return new IPrepoService(); + case "prepo:u": return new IPrepoService(); diff --git a/Ryujinx.Core/OsHle/Services/Set/ISystemSettingsServer.cs b/Ryujinx.Core/OsHle/Services/Set/ISystemSettingsServer.cs index bdf5c7b4..173e78c8 100644 --- a/Ryujinx.Core/OsHle/Services/Set/ISystemSettingsServer.cs +++ b/Ryujinx.Core/OsHle/Services/Set/ISystemSettingsServer.cs @@ -17,7 +17,7 @@ namespace Ryujinx.Core.OsHle.Services.Set { m_Commands = new Dictionary() { - { 4, GetFirmwareVersion2 }, + { 4, GetFirmwareVersion2 }, { 23, GetColorSetId }, { 24, SetColorSetId } }; diff --git a/Ryujinx.Core/OsHle/Services/Time/ITimeZoneService.cs b/Ryujinx.Core/OsHle/Services/Time/ITimeZoneService.cs index ec50c82f..c9c2c94a 100644 --- a/Ryujinx.Core/OsHle/Services/Time/ITimeZoneService.cs +++ b/Ryujinx.Core/OsHle/Services/Time/ITimeZoneService.cs @@ -1,3 +1,4 @@ +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Ipc; using System; using System.Collections.Generic; @@ -16,14 +17,14 @@ namespace Ryujinx.Core.OsHle.Services.Time { m_Commands = new Dictionary() { - { 0, GetDeviceLocationName }, + { 0, GetDeviceLocationName }, { 101, ToCalendarTimeWithMyRule } }; } public long GetDeviceLocationName(ServiceCtx Context) { - Logging.Stub(LogClass.ServiceTime, "Stubbed"); + Context.Ns.Log.PrintStub(LogClass.ServiceTime, "Stubbed."); for (int Index = 0; Index < 0x24; Index++) { @@ -60,7 +61,7 @@ namespace Ryujinx.Core.OsHle.Services.Time */ Context.ResponseData.Write((int)CurrentTime.DayOfWeek); - Context.ResponseData.Write(CurrentTime.DayOfYear); + Context.ResponseData.Write(CurrentTime.DayOfYear - 1); //TODO: Find out the names used. Context.ResponseData.Write(new byte[8]); diff --git a/Ryujinx.Core/OsHle/Services/Vi/IApplicationDisplayService.cs b/Ryujinx.Core/OsHle/Services/Vi/IApplicationDisplayService.cs index b92dc16c..84c869d5 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/IApplicationDisplayService.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/IApplicationDisplayService.cs @@ -19,10 +19,10 @@ namespace Ryujinx.Core.OsHle.Services.Vi { m_Commands = new Dictionary() { - { 100, GetRelayService }, - { 101, GetSystemDisplayService }, - { 102, GetManagerDisplayService }, - { 103, GetIndirectDisplayTransactionService }, + { 100, GetRelayService }, + { 101, GetSystemDisplayService }, + { 102, GetManagerDisplayService }, + { 103, GetIndirectDisplayTransactionService }, { 1010, OpenDisplay }, { 1020, CloseDisplay }, { 1102, GetDisplayResolution }, diff --git a/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs b/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs index 4dc01997..5aa3c3d5 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs @@ -1,4 +1,5 @@ using ChocolArm64.Memory; +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Services.Nv; using Ryujinx.Graphics.Gal; @@ -112,7 +113,7 @@ namespace Ryujinx.Core.OsHle.Services.Android if (Commands.TryGetValue((InterfaceName, Code), out ServiceProcessParcel ProcReq)) { - Logging.Debug(LogClass.ServiceNv, $"{InterfaceName} {ProcReq.Method.Name}"); + Context.Ns.Log.PrintDebug(LogClass.ServiceVi, $"{InterfaceName} {ProcReq.Method.Name}"); return ProcReq(Context, Reader); } @@ -412,8 +413,6 @@ namespace Ryujinx.Core.OsHle.Services.Android break; } - Logging.Debug(LogClass.ServiceNv, "Waiting for a free BufferQueue slot..."); - if (Disposed) { break; @@ -426,8 +425,6 @@ namespace Ryujinx.Core.OsHle.Services.Android } while (!Disposed); - Logging.Debug(LogClass.ServiceNv, $"Found free BufferQueue slot {Slot}!"); - return Slot; } diff --git a/Ryujinx.Core/Switch.cs b/Ryujinx.Core/Switch.cs index 0df8b126..02fdc8b6 100644 --- a/Ryujinx.Core/Switch.cs +++ b/Ryujinx.Core/Switch.cs @@ -1,5 +1,6 @@ using Ryujinx.Audio; using Ryujinx.Core.Input; +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle; using Ryujinx.Core.Settings; using Ryujinx.Graphics.Gal; @@ -12,6 +13,8 @@ namespace Ryujinx.Core { internal IAalOutput AudioOut { get; private set; } + public Logger Log { get; private set; } + internal NsGpu Gpu { get; private set; } internal VirtualFileSystem VFs { get; private set; } @@ -40,7 +43,9 @@ namespace Ryujinx.Core this.AudioOut = AudioOut; - Gpu = new NsGpu(Renderer); + Log = new Logger(); + + Gpu = new NsGpu(Renderer); VFs = new VirtualFileSystem(); @@ -50,7 +55,7 @@ namespace Ryujinx.Core Statistics = new PerformanceStatistics(); - Hid = new Hid(); + Hid = new Hid(Log); Os.HidSharedMem.MemoryMapped += Hid.ShMemMap; Os.HidSharedMem.MemoryUnmapped += Hid.ShMemUnmap; diff --git a/Ryujinx.Core/Config.cs b/Ryujinx/Config.cs similarity index 53% rename from Ryujinx.Core/Config.cs rename to Ryujinx/Config.cs index 11eb1c1d..d5364edc 100644 --- a/Ryujinx.Core/Config.cs +++ b/Ryujinx/Config.cs @@ -1,58 +1,59 @@ using Ryujinx.Core.Input; +using Ryujinx.Core.Logging; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; -namespace Ryujinx.Core +namespace Ryujinx { public static class Config { - public static bool EnableMemoryChecks { get; private set; } - public static bool LoggingEnableInfo { get; private set; } - public static bool LoggingEnableTrace { get; private set; } - public static bool LoggingEnableDebug { get; private set; } - public static bool LoggingEnableWarn { get; private set; } - public static bool LoggingEnableError { get; private set; } - public static bool LoggingEnableFatal { get; private set; } - public static bool LoggingEnableIpc { get; private set; } - public static bool LoggingEnableStub { get; private set; } - public static bool LoggingEnableLogFile { get; private set; } - public static bool LoggingEnableFilter { get; private set; } - public static bool[] LoggingFilteredClasses { get; private set; } - public static JoyCon FakeJoyCon { get; private set; } - public static void Read() + public static void Read(Logger Log) { - var iniFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); - var iniPath = Path.Combine(iniFolder, "Ryujinx.conf"); - IniParser Parser = new IniParser(iniPath); + string IniFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); - EnableMemoryChecks = Convert.ToBoolean(Parser.Value("Enable_Memory_Checks")); - LoggingEnableInfo = Convert.ToBoolean(Parser.Value("Logging_Enable_Info")); - LoggingEnableTrace = Convert.ToBoolean(Parser.Value("Logging_Enable_Trace")); - LoggingEnableDebug = Convert.ToBoolean(Parser.Value("Logging_Enable_Debug")); - LoggingEnableWarn = Convert.ToBoolean(Parser.Value("Logging_Enable_Warn")); - LoggingEnableError = Convert.ToBoolean(Parser.Value("Logging_Enable_Error")); - LoggingEnableFatal = Convert.ToBoolean(Parser.Value("Logging_Enable_Fatal")); - LoggingEnableIpc = Convert.ToBoolean(Parser.Value("Logging_Enable_Ipc")); - LoggingEnableStub = Convert.ToBoolean(Parser.Value("Logging_Enable_Stub")); - LoggingEnableLogFile = Convert.ToBoolean(Parser.Value("Logging_Enable_LogFile")); - LoggingEnableFilter = Convert.ToBoolean(Parser.Value("Logging_Enable_Filter")); - LoggingFilteredClasses = new bool[(int)LogClass.Count]; + string IniPath = Path.Combine(IniFolder, "Ryujinx.conf"); + + IniParser Parser = new IniParser(IniPath); + + AOptimizations.DisableMemoryChecks = !Convert.ToBoolean(Parser.Value("Enable_Memory_Checks")); + + Console.WriteLine(Parser.Value("Logging_Enable_Warn")); + + bool LoggingEnableDebug = Convert.ToBoolean(Parser.Value("Logging_Enable_Debug")); + bool LoggingEnableStub = Convert.ToBoolean(Parser.Value("Logging_Enable_Stub")); + bool LoggingEnableInfo = Convert.ToBoolean(Parser.Value("Logging_Enable_Info")); + bool LoggingEnableTrace = Convert.ToBoolean(Parser.Value("Logging_Enable_Trace")); + bool LoggingEnableWarn = Convert.ToBoolean(Parser.Value("Logging_Enable_Warn")); + bool LoggingEnableError = Convert.ToBoolean(Parser.Value("Logging_Enable_Error")); + + string[] FilteredLogClasses = Parser.Value("Logging_Filtered_Classes").Split(',', StringSplitOptions.RemoveEmptyEntries); + + //When the classes are specified on the list, we only + //enable the classes that are on the list. + //So, first disable everything, then enable + //the classes that the user added to the list. + if (FilteredLogClasses.Length > 0) + { + foreach (LogClass Class in Enum.GetValues(typeof(LogClass))) + { + Log.SetEnable(Class, false); + } + } - string[] FilteredLogClasses = Parser.Value("Logging_Filtered_Classes", string.Empty).Split(','); foreach (string LogClass in FilteredLogClasses) { if (!string.IsNullOrEmpty(LogClass.Trim())) { - foreach (LogClass EnumItemName in Enum.GetValues(typeof(LogClass))) + foreach (LogClass Class in Enum.GetValues(typeof(LogClass))) { - if (EnumItemName.ToString().ToLower().Contains(LogClass.Trim().ToLower())) + if (Class.ToString().ToLower().Contains(LogClass.Trim().ToLower())) { - LoggingFilteredClasses[(int)EnumItemName] = true; + Log.SetEnable(Class, true); } } } @@ -103,19 +104,14 @@ namespace Ryujinx.Core public IniParser(string Path) { Values = File.ReadLines(Path) - .Where(Line => !string.IsNullOrWhiteSpace(Line) && !Line.StartsWith('#')) - .Select(Line => Line.Split('=', 2)) - .ToDictionary(Parts => Parts[0].Trim(), Parts => Parts.Length > 1 ? Parts[1].Trim() : null); + .Where(Line => !string.IsNullOrWhiteSpace(Line) && !Line.StartsWith('#')) + .Select(Line => Line.Split('=', 2)) + .ToDictionary(Parts => Parts[0].Trim(), Parts => Parts.Length > 1 ? Parts[1].Trim() : null); } - /// - /// Gets the setting value for the requested setting . - /// - /// Setting Name - /// Default value of the setting - public string Value(string Name, string defaultValue = null) + public string Value(string Name) { - return Values.TryGetValue(Name, out var value) ? value : defaultValue; + return Values.TryGetValue(Name, out string Value) ? Value : null; } } } diff --git a/Ryujinx/Ryujinx.conf b/Ryujinx/Ryujinx.conf index 0c88b34b..611f3207 100644 --- a/Ryujinx/Ryujinx.conf +++ b/Ryujinx/Ryujinx.conf @@ -1,39 +1,24 @@ #Enable cpu memory checks (slow) Enable_Memory_Checks = false -#Enable print informations logs -Logging_Enable_Info = true - -#Enable print trace logs -Logging_Enable_Trace = false - #Enable print debug logs Logging_Enable_Debug = false +#Enable print stubbed calls logs +Logging_Enable_Stub = true + +#Enable print informations logs +Logging_Enable_Info = true + #Enable print warning logs Logging_Enable_Warn = true #Enable print error logs Logging_Enable_Error = true -#Enable print fatal logs -Logging_Enable_Fatal = true - -#Enable print stubbed calls logs -Logging_Enable_Stub = false - -#Enable print Ipc logs -Logging_Enable_Ipc = false - -#Enable log filter -Logging_Enable_Filter = false - -#Filtered log classes, seperated by ',', eg. `Logging_Filtered_Classes = Loader,ServiceFS` +#Filtered log classes, seperated by ", ", eg. `Logging_Filtered_Classes = Loader, ServiceFS` Logging_Filtered_Classes = -#Save logs into Ryujinx.log -Logging_Enable_LogFile = false - #https://github.com/opentk/opentk/blob/develop/src/OpenTK/Input/Key.cs Controls_Left_FakeJoycon_Stick_Up = 105 Controls_Left_FakeJoycon_Stick_Down = 101 @@ -59,4 +44,4 @@ Controls_Right_FakeJoycon_Button_X = 85 Controls_Right_FakeJoycon_Button_Y = 104 Controls_Right_FakeJoycon_Button_Plus = 121 Controls_Right_FakeJoycon_Button_R = 103 -Controls_Right_FakeJoycon_Button_ZR = 97 +Controls_Right_FakeJoycon_Button_ZR = 97 \ No newline at end of file diff --git a/Ryujinx/Ui/ConsoleLog.cs b/Ryujinx/Ui/ConsoleLog.cs new file mode 100644 index 00000000..b9707357 --- /dev/null +++ b/Ryujinx/Ui/ConsoleLog.cs @@ -0,0 +1,51 @@ +using Ryujinx.Core.Logging; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Ryujinx +{ + static class ConsoleLog + { + private static Dictionary LogColors; + + private static object ConsoleLock; + + static ConsoleLog() + { + LogColors = new Dictionary() + { + { LogLevel.Stub, ConsoleColor.DarkGray }, + { LogLevel.Info, ConsoleColor.White }, + { LogLevel.Warning, ConsoleColor.Yellow }, + { LogLevel.Error, ConsoleColor.Red } + }; + + ConsoleLock = new object(); + } + + public static void PrintLog(object sender, LogEventArgs e) + { + string FormattedTime = e.Time.ToString(@"hh\:mm\:ss\.fff"); + + string CurrentThread = Thread.CurrentThread.ManagedThreadId.ToString("d4"); + + string Message = FormattedTime + " | " + CurrentThread + " " + e.Message; + + if (LogColors.TryGetValue(e.Level, out ConsoleColor Color)) + { + lock (ConsoleLock) + { + Console.ForegroundColor = Color; + + Console.WriteLine(Message); + Console.ResetColor(); + } + } + else + { + Console.WriteLine(Message); + } + } + } +} \ No newline at end of file diff --git a/Ryujinx/Ui/Program.cs b/Ryujinx/Ui/Program.cs index f9d40eb5..77322d08 100644 --- a/Ryujinx/Ui/Program.cs +++ b/Ryujinx/Ui/Program.cs @@ -12,10 +12,6 @@ namespace Ryujinx { static void Main(string[] args) { - Config.Read(); - - AOptimizations.DisableMemoryChecks = !Config.EnableMemoryChecks; - Console.Title = "Ryujinx Console"; IGalRenderer Renderer = new OpenGLRenderer(); @@ -24,6 +20,10 @@ namespace Ryujinx Switch Ns = new Switch(Renderer, AudioOut); + Config.Read(Ns.Log); + + Ns.Log.Updated += ConsoleLog.PrintLog; + if (args.Length == 1) { if (Directory.Exists(args[0])) @@ -37,27 +37,27 @@ namespace Ryujinx if (RomFsFiles.Length > 0) { - Logging.Info(LogClass.Loader, "Loading as cart with RomFS."); + Console.WriteLine("Loading as cart with RomFS."); Ns.LoadCart(args[0], RomFsFiles[0]); } else { - Logging.Info(LogClass.Loader, "Loading as cart WITHOUT RomFS."); + Console.WriteLine("Loading as cart WITHOUT RomFS."); Ns.LoadCart(args[0]); } } else if (File.Exists(args[0])) { - Logging.Info(LogClass.Loader, "Loading as homebrew."); + Console.WriteLine("Loading as homebrew."); Ns.LoadProgram(args[0]); } } else { - Logging.Error(LogClass.Loader, "Please specify the folder with the NSOs/IStorage or a NSO/NRO."); + Console.WriteLine("Please specify the folder with the NSOs/IStorage or a NSO/NRO."); } using (GLScreen Screen = new GLScreen(Ns, Renderer))