gdkchan 8 anni fa
parent
commit
a8ba340dde
57 ha cambiato i file con 550 aggiunte e 865 eliminazioni
  1. 2 2
      ChocolArm64/Instruction/AInstEmitMemoryHelper.cs
  2. 7 2
      Ryujinx.Core/Hid/Hid.cs
  3. 0 296
      Ryujinx.Core/Logging.cs
  4. 5 5
      Ryujinx.Core/Logging/LogClass.cs
  5. 19 0
      Ryujinx.Core/Logging/LogEventArgs.cs
  6. 11 0
      Ryujinx.Core/Logging/LogLevel.cs
  7. 84 0
      Ryujinx.Core/Logging/Logger.cs
  8. 9 4
      Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs
  9. 3 3
      Ryujinx.Core/OsHle/Handles/KThread.cs
  10. 4 3
      Ryujinx.Core/OsHle/Horizon.cs
  11. 0 178
      Ryujinx.Core/OsHle/Ipc/IpcLog.cs
  12. 2 3
      Ryujinx.Core/OsHle/Ipc/IpcMessage.cs
  13. 2 3
      Ryujinx.Core/OsHle/Kernel/SvcHandler.cs
  14. 8 7
      Ryujinx.Core/OsHle/Kernel/SvcMemory.cs
  15. 6 5
      Ryujinx.Core/OsHle/Kernel/SvcSystem.cs
  16. 6 5
      Ryujinx.Core/OsHle/Kernel/SvcThread.cs
  17. 12 11
      Ryujinx.Core/OsHle/Kernel/SvcThreadSync.cs
  18. 7 10
      Ryujinx.Core/OsHle/Process.cs
  19. 7 6
      Ryujinx.Core/OsHle/Services/Acc/IAccountServiceForApplication.cs
  20. 3 2
      Ryujinx.Core/OsHle/Services/Acc/IManagerForApplication.cs
  21. 3 2
      Ryujinx.Core/OsHle/Services/Acc/IProfile.cs
  22. 14 6
      Ryujinx.Core/OsHle/Services/Am/IApplicationFunctions.cs
  23. 7 7
      Ryujinx.Core/OsHle/Services/Am/IApplicationProxy.cs
  24. 7 6
      Ryujinx.Core/OsHle/Services/Am/IAudioController.cs
  25. 2 1
      Ryujinx.Core/OsHle/Services/Am/ICommonStateGetter.cs
  26. 3 2
      Ryujinx.Core/OsHle/Services/Am/IHomeMenuFunctions.cs
  27. 8 7
      Ryujinx.Core/OsHle/Services/Am/ISelfController.cs
  28. 2 2
      Ryujinx.Core/OsHle/Services/Am/IStorageAccessor.cs
  29. 11 11
      Ryujinx.Core/OsHle/Services/Am/ISystemAppletProxy.cs
  30. 4 3
      Ryujinx.Core/OsHle/Services/Am/IWindowController.cs
  31. 2 2
      Ryujinx.Core/OsHle/Services/Apm/ISession.cs
  32. 4 3
      Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs
  33. 4 3
      Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs
  34. 3 2
      Ryujinx.Core/OsHle/Services/Aud/IAudioRenderer.cs
  35. 2 1
      Ryujinx.Core/OsHle/Services/Aud/IAudioRendererManager.cs
  36. 6 7
      Ryujinx.Core/OsHle/Services/Bsd/IClient.cs
  37. 10 10
      Ryujinx.Core/OsHle/Services/FspSrv/IFileSystem.cs
  38. 5 5
      Ryujinx.Core/OsHle/Services/FspSrv/IFileSystemProxy.cs
  39. 38 34
      Ryujinx.Core/OsHle/Services/Hid/IHidServer.cs
  40. 2 1
      Ryujinx.Core/OsHle/Services/IpcService.cs
  41. 44 99
      Ryujinx.Core/OsHle/Services/Lm/ILogger.cs
  42. 13 0
      Ryujinx.Core/OsHle/Services/Lm/LmLogField.cs
  43. 11 0
      Ryujinx.Core/OsHle/Services/Lm/LmLogLevel.cs
  44. 2 1
      Ryujinx.Core/OsHle/Services/Nifm/IGeneralService.cs
  45. 5 4
      Ryujinx.Core/OsHle/Services/Nifm/IRequest.cs
  46. 3 2
      Ryujinx.Core/OsHle/Services/Ns/IAddOnContentManager.cs
  47. 10 9
      Ryujinx.Core/OsHle/Services/Nv/INvDrvServices.cs
  48. 3 0
      Ryujinx.Core/OsHle/Services/ServiceFactory.cs
  49. 1 1
      Ryujinx.Core/OsHle/Services/Set/ISystemSettingsServer.cs
  50. 4 3
      Ryujinx.Core/OsHle/Services/Time/ITimeZoneService.cs
  51. 4 4
      Ryujinx.Core/OsHle/Services/Vi/IApplicationDisplayService.cs
  52. 2 5
      Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs
  53. 7 2
      Ryujinx.Core/Switch.cs
  54. 40 44
      Ryujinx/Config.cs
  55. 8 23
      Ryujinx/Ryujinx.conf
  56. 51 0
      Ryujinx/Ui/ConsoleLog.cs
  57. 8 8
      Ryujinx/Ui/Program.cs

+ 2 - 2
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));
             }
 

+ 7 - 2
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);
             }

+ 0 - 296
Ryujinx.Core/Logging.cs

@@ -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 "<null>";
-            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;
-        }
-    }
-}

+ 5 - 5
Ryujinx.Core/LogClass.cs → 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
     }
 }

+ 19 - 0
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;
+        }
+    }
+}

+ 11 - 0
Ryujinx.Core/Logging/LogLevel.cs

@@ -0,0 +1,11 @@
+namespace Ryujinx.Core.Logging
+{
+    public enum LogLevel
+    {
+        Debug,
+        Stub,
+        Info,
+        Warning,
+        Error
+    }
+}

+ 84 - 0
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<LogEventArgs> 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}";
+        }
+    }
+}

+ 9 - 4
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<KThread, SchedulerThread>();
 
             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 + ", " +

+ 3 - 3
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; }

+ 4 - 3
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<int, Process>();
 
@@ -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)
                 {

+ 0 - 178
Ryujinx.Core/OsHle/Ipc/IpcLog.cs

@@ -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;
-            }
-        }
-    }
-}

+ 2 - 3
Ryujinx.Core/OsHle/Ipc/IpcMessage.cs

@@ -15,7 +15,7 @@ namespace Ryujinx.Core.OsHle.Ipc
         public List<IpcBuffDesc>         ExchangeBuff { get; private set; }
         public List<IpcRecvListBuffDesc> RecvListBuff { get; private set; }
 
-        public List<int> ResponseObjIds { get; private set; }    
+        public List<int> 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);

+ 2 - 3
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
             {

+ 8 - 7
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);
 

+ 6 - 5
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;
         }

+ 6 - 5
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);
             }

+ 12 - 11
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;
             }

+ 7 - 10
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...");
             }
         }
     }

+ 7 - 6
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<int, ServiceProcessRequest>()
             {
-                {   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;
         }

+ 3 - 2
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);
 

+ 3 - 2
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;
         }
     }

+ 14 - 6
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<int, ServiceProcessRequest>()
             {
-                {  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.

+ 7 - 7
Ryujinx.Core/OsHle/Services/Am/IApplicationProxy.cs

@@ -13,13 +13,13 @@ namespace Ryujinx.Core.OsHle.Services.Am
         {
             m_Commands = new Dictionary<int, ServiceProcessRequest>()
             {
-                {    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       }
             };
         }

+ 7 - 6
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;
         }

+ 2 - 1
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;
         }

+ 3 - 2
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;
         }

+ 8 - 7
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;
         }

+ 2 - 2
Ryujinx.Core/OsHle/Services/Am/IStorageAccessor.cs

@@ -17,7 +17,7 @@ namespace Ryujinx.Core.OsHle.Services.Am
         {
             m_Commands = new Dictionary<int, ServiceProcessRequest>()
             {
-                {  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

+ 11 - 11
Ryujinx.Core/OsHle/Services/Am/ISystemAppletProxy.cs

@@ -13,15 +13,15 @@ namespace Ryujinx.Core.OsHle.Services.Am
         {
             m_Commands = new Dictionary<int, ServiceProcessRequest>()
             {
-                {    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());

+ 4 - 3
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<int, ServiceProcessRequest>()
             {
-                {  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;
         }

+ 2 - 2
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;
         }

+ 4 - 3
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;
         }

+ 4 - 3
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<AudioOutData>(
                 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;
         }

+ 3 - 2
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;
         }

+ 2 - 1
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);
 

+ 6 - 7
Ryujinx.Core/OsHle/Services/Bsd/IClient.cs

@@ -21,11 +21,11 @@ namespace Ryujinx.Core.OsHle.Services.Bsd
         {
             m_Commands = new Dictionary<int, ServiceProcessRequest>()
             {
-                {  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);
             }
         }

+ 10 - 10
Ryujinx.Core/OsHle/Services/FspSrv/IFileSystem.cs

@@ -22,16 +22,16 @@ namespace Ryujinx.Core.OsHle.Services.FspSrv
         {
             m_Commands = new Dictionary<int, ServiceProcessRequest>()
             {
-                {  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          },

+ 5 - 5
Ryujinx.Core/OsHle/Services/FspSrv/IFileSystemProxy.cs

@@ -13,11 +13,11 @@ namespace Ryujinx.Core.OsHle.Services.FspSrv
         {
             m_Commands = new Dictionary<int, ServiceProcessRequest>()
             {
-                {    1, SetCurrentProcess                    },
-                {   18, OpenSdCardFileSystem                 },
-                {   51, OpenSaveDataFileSystem               },
-                {  200, OpenDataStorageByCurrentProcess      },
-                {  203, OpenPatchDataStorageByCurrentProcess },
+                { 1,    SetCurrentProcess                    },
+                { 18,   OpenSdCardFileSystem                 },
+                { 51,   OpenSaveDataFileSystem               },
+                { 200,  OpenDataStorageByCurrentProcess      },
+                { 203,  OpenPatchDataStorageByCurrentProcess },
                 { 1005, GetGlobalAccessLogMode               }
             };
         }

+ 38 - 34
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<int, ServiceProcessRequest>()
             {
-                {   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();
+            long NpadJoyDeviceType    = Context.RequestData.ReadInt64();
 
-            Logging.Stub(LogClass.ServiceHid, "Stubbed");
+            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;
         }

+ 2 - 1
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);
 

+ 44 - 99
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, 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);
+            byte[] LogBuffer = AMemoryHelper.ReadBytes(
+                Context.Memory,
+                Context.Request.PtrBuff[0].Position,
+                Context.Request.PtrBuff[0].Size);
 
-            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}";
+            using (MemoryStream MS = new MemoryStream(LogBuffer))
+            {
+                BinaryReader Reader = new BinaryReader(MS);
 
-            LogString += Environment.NewLine + Environment.NewLine + "Message:" + Environment.NewLine;
+                long  Pid           = Reader.ReadInt64();
+                long  ThreadContext = Reader.ReadInt64();
+                short Flags         = Reader.ReadInt16();
+                byte  Level         = Reader.ReadByte();
+                byte  Verbosity     = Reader.ReadByte();
+                int   PayloadLength = Reader.ReadInt32();
 
-            string StrMessage = "", StrLine = "", StrFilename = "", StrFunction = "",
-                   StrModule = "", StrThread = "";
+                StringBuilder SB = new StringBuilder();
 
-            do
-            {
-                byte FieldType = bReader.ReadByte();
-                byte FieldSize = bReader.ReadByte();
+                SB.AppendLine("Guest log:");
 
-                if ((Field)FieldType != Field.Skip || FieldSize != 0)
+                while (MS.Position < MS.Length)
                 {
-                    byte[] Message = bReader.ReadBytes(FieldSize);
-                    switch ((Field)FieldType)
-                    {
-                        case Field.Message:
-                            StrMessage = Encoding.UTF8.GetString(Message);
-                            break;
-
-                        case Field.Line:
-                            StrLine = BitConverter.ToInt32(Message, 0).ToString();
-                            break;
+                    byte Type = Reader.ReadByte();
+                    byte Size = Reader.ReadByte();
 
-                        case Field.Filename:
-                            StrFilename = Encoding.UTF8.GetString(Message);
-                            break;
+                    LmLogField Field = (LmLogField)Type;
 
-                        case Field.Function:
-                            StrFunction = Encoding.UTF8.GetString(Message);
-                            break;
+                    string FieldStr = string.Empty;
 
-                        case Field.Module:
-                            StrModule = Encoding.UTF8.GetString(Message);
-                            break;
+                    if (Field == LmLogField.Skip)
+                    {
+                        Reader.ReadByte();
 
-                        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;
         }
     }
 }
- 

+ 13 - 0
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
+    }
+}

+ 11 - 0
Ryujinx.Core/OsHle/Services/Lm/LmLogLevel.cs

@@ -0,0 +1,11 @@
+namespace Ryujinx.Core.OsHle.Services.Lm
+{
+    enum LmLogLevel
+    {
+        Trace,
+        Info,
+        Warning,
+        Error,
+        Critical
+    }
+}

+ 2 - 1
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;
         }

+ 5 - 4
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;
         }

+ 3 - 2
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.

+ 10 - 9
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<NvMap>(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.
             }

+ 3 - 0
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();
 

+ 1 - 1
Ryujinx.Core/OsHle/Services/Set/ISystemSettingsServer.cs

@@ -17,7 +17,7 @@ namespace Ryujinx.Core.OsHle.Services.Set
         {
             m_Commands = new Dictionary<int, ServiceProcessRequest>()
             {
-                {  4, GetFirmwareVersion2 },
+                { 4,  GetFirmwareVersion2 },
                 { 23, GetColorSetId       },
                 { 24, SetColorSetId       }
             };

+ 4 - 3
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<int, ServiceProcessRequest>()
             {
-                {   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]);

+ 4 - 4
Ryujinx.Core/OsHle/Services/Vi/IApplicationDisplayService.cs

@@ -19,10 +19,10 @@ namespace Ryujinx.Core.OsHle.Services.Vi
         {
             m_Commands = new Dictionary<int, ServiceProcessRequest>()
             {
-                {  100, GetRelayService                      },
-                {  101, GetSystemDisplayService              },
-                {  102, GetManagerDisplayService             },
-                {  103, GetIndirectDisplayTransactionService },
+                { 100,  GetRelayService                      },
+                { 101,  GetSystemDisplayService              },
+                { 102,  GetManagerDisplayService             },
+                { 103,  GetIndirectDisplayTransactionService },
                 { 1010, OpenDisplay                          },
                 { 1020, CloseDisplay                         },
                 { 1102, GetDisplayResolution                 },

+ 2 - 5
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;
         }
 

+ 7 - 2
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;

+ 40 - 44
Ryujinx.Core/Config.cs → 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);
+
+            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"));
 
-            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[] 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);
         }
 
-        /// <summary>
-        /// Gets the setting value for the requested setting <see cref="Name"/>.
-        /// </summary>
-        /// <param name="Name">Setting Name</param>
-        /// <param name="defaultValue">Default value of the setting</param>
-        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;
         }
     }
 }

+ 8 - 23
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

+ 51 - 0
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<LogLevel, ConsoleColor> LogColors;
+
+        private static object ConsoleLock;
+
+        static ConsoleLog()
+        {
+            LogColors = new Dictionary<LogLevel, ConsoleColor>()
+            {
+                { 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);
+            }
+        }
+    }
+}

+ 8 - 8
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))