hos: Cleanup the project (#2634)
* hos: Cleanup the project Since a lot of changes has been done on the HOS project, there are some leftover here and there, or class just used in one service, things at wrong places, and more. This PR fixes that, additionnally to that, I've realigned some vars because I though it make the code more readable. * Address gdkchan feedback * addresses Thog feedback * Revert ElfSymbol
This commit is contained in:
parent
3f2486342b
commit
5d08e9b495
36 changed files with 261 additions and 382 deletions
17
Ryujinx.Common/Utilities/StreamUtils.cs
Normal file
17
Ryujinx.Common/Utilities/StreamUtils.cs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Ryujinx.Common.Utilities
|
||||||
|
{
|
||||||
|
public static class StreamUtils
|
||||||
|
{
|
||||||
|
public static byte[] StreamToBytes(Stream input)
|
||||||
|
{
|
||||||
|
using (MemoryStream stream = new MemoryStream())
|
||||||
|
{
|
||||||
|
input.CopyTo(stream);
|
||||||
|
|
||||||
|
return stream.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,9 +7,9 @@ namespace Ryujinx.HLE.Exceptions
|
||||||
{
|
{
|
||||||
static readonly Type _structType = typeof(T);
|
static readonly Type _structType = typeof(T);
|
||||||
|
|
||||||
public InvalidStructLayoutException(string message) : base(message) {}
|
public InvalidStructLayoutException(string message) : base(message) { }
|
||||||
|
|
||||||
public InvalidStructLayoutException(int expectedSize) :
|
public InvalidStructLayoutException(int expectedSize)
|
||||||
base($"Type {_structType.Name} has the wrong size. Expected: {expectedSize} bytes, Got: {Unsafe.SizeOf<T>()} bytes") {}
|
: base($"Type {_structType.Name} has the wrong size. Expected: {expectedSize} bytes, got: {Unsafe.SizeOf<T>()} bytes") { }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,37 +19,29 @@ namespace Ryujinx.HLE.Exceptions
|
||||||
public IpcMessage Request { get; }
|
public IpcMessage Request { get; }
|
||||||
|
|
||||||
public ServiceNotImplementedException(IpcService service, ServiceCtx context)
|
public ServiceNotImplementedException(IpcService service, ServiceCtx context)
|
||||||
: this(service, context, "The service call is not implemented.")
|
: this(service, context, "The service call is not implemented.") { }
|
||||||
{ }
|
|
||||||
|
|
||||||
public ServiceNotImplementedException(IpcService service, ServiceCtx context, string message)
|
public ServiceNotImplementedException(IpcService service, ServiceCtx context, string message) : base(message)
|
||||||
: base(message)
|
|
||||||
{
|
{
|
||||||
Service = service;
|
Service = service;
|
||||||
Context = context;
|
Context = context;
|
||||||
Request = context.Request;
|
Request = context.Request;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServiceNotImplementedException(IpcService service, ServiceCtx context, string message, Exception inner)
|
public ServiceNotImplementedException(IpcService service, ServiceCtx context, string message, Exception inner) : base(message, inner)
|
||||||
: base(message, inner)
|
|
||||||
{
|
{
|
||||||
Service = service;
|
Service = service;
|
||||||
Context = context;
|
Context = context;
|
||||||
Request = context.Request;
|
Request = context.Request;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ServiceNotImplementedException(SerializationInfo info, StreamingContext context)
|
protected ServiceNotImplementedException(SerializationInfo info, StreamingContext context) : base(info, context) { }
|
||||||
: base(info, context)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
public override string Message
|
public override string Message
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return base.Message +
|
return base.Message + Environment.NewLine + Environment.NewLine + BuildMessage();
|
||||||
Environment.NewLine +
|
|
||||||
Environment.NewLine +
|
|
||||||
BuildMessage();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,8 +55,7 @@ namespace Ryujinx.HLE.Exceptions
|
||||||
if (callingType != null && callingMethod != null)
|
if (callingType != null && callingMethod != null)
|
||||||
{
|
{
|
||||||
// If the type is past 0xF, we are using TIPC
|
// If the type is past 0xF, we are using TIPC
|
||||||
var ipcCommands = Request.Type > IpcMessageType.TipcCloseSession ?
|
var ipcCommands = Request.Type > IpcMessageType.TipcCloseSession ? Service.TipcCommands : Service.HipcCommands;
|
||||||
Service.TipcCommands : Service.HipcCommands;
|
|
||||||
|
|
||||||
// Find the handler for the method called
|
// Find the handler for the method called
|
||||||
var ipcHandler = ipcCommands.FirstOrDefault(x => x.Value == callingMethod);
|
var ipcHandler = ipcCommands.FirstOrDefault(x => x.Value == callingMethod);
|
||||||
|
@ -149,11 +140,12 @@ namespace Ryujinx.HLE.Exceptions
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private (Type, MethodBase) WalkStackTrace(StackTrace trace)
|
private static (Type, MethodBase) WalkStackTrace(StackTrace trace)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
StackFrame frame;
|
StackFrame frame;
|
||||||
|
|
||||||
// Find the IIpcService method that threw this exception
|
// Find the IIpcService method that threw this exception
|
||||||
while ((frame = trace.GetFrame(i++)) != null)
|
while ((frame = trace.GetFrame(i++)) != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -191,7 +191,7 @@ namespace Ryujinx.HLE.FileSystem.Content
|
||||||
if (device != null)
|
if (device != null)
|
||||||
{
|
{
|
||||||
TimeManager.Instance.InitializeTimeZone(device);
|
TimeManager.Instance.InitializeTimeZone(device);
|
||||||
device.System.Font.Initialize(this);
|
device.System.SharedFontManager.Initialize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ using Ryujinx.Audio.Output;
|
||||||
using Ryujinx.Audio.Renderer.Device;
|
using Ryujinx.Audio.Renderer.Device;
|
||||||
using Ryujinx.Audio.Renderer.Server;
|
using Ryujinx.Audio.Renderer.Server;
|
||||||
using Ryujinx.HLE.FileSystem.Content;
|
using Ryujinx.HLE.FileSystem.Content;
|
||||||
using Ryujinx.HLE.HOS.Font;
|
|
||||||
using Ryujinx.HLE.HOS.Kernel;
|
using Ryujinx.HLE.HOS.Kernel;
|
||||||
using Ryujinx.HLE.HOS.Kernel.Memory;
|
using Ryujinx.HLE.HOS.Kernel.Memory;
|
||||||
using Ryujinx.HLE.HOS.Kernel.Process;
|
using Ryujinx.HLE.HOS.Kernel.Process;
|
||||||
|
@ -25,6 +24,7 @@ using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager;
|
||||||
using Ryujinx.HLE.HOS.Services.Nv;
|
using Ryujinx.HLE.HOS.Services.Nv;
|
||||||
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl;
|
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl;
|
||||||
using Ryujinx.HLE.HOS.Services.Pcv.Bpc;
|
using Ryujinx.HLE.HOS.Services.Pcv.Bpc;
|
||||||
|
using Ryujinx.HLE.HOS.Services.Sdb.Pl;
|
||||||
using Ryujinx.HLE.HOS.Services.Settings;
|
using Ryujinx.HLE.HOS.Services.Settings;
|
||||||
using Ryujinx.HLE.HOS.Services.Sm;
|
using Ryujinx.HLE.HOS.Services.Sm;
|
||||||
using Ryujinx.HLE.HOS.Services.SurfaceFlinger;
|
using Ryujinx.HLE.HOS.Services.SurfaceFlinger;
|
||||||
|
@ -87,8 +87,7 @@ namespace Ryujinx.HLE.HOS
|
||||||
|
|
||||||
internal KTransferMemory AppletCaptureBufferTransfer { get; private set; }
|
internal KTransferMemory AppletCaptureBufferTransfer { get; private set; }
|
||||||
|
|
||||||
internal SharedFontManager Font { get; private set; }
|
internal SharedFontManager SharedFontManager { get; private set; }
|
||||||
|
|
||||||
internal AccountManager AccountManager { get; private set; }
|
internal AccountManager AccountManager { get; private set; }
|
||||||
internal ContentManager ContentManager { get; private set; }
|
internal ContentManager ContentManager { get; private set; }
|
||||||
internal CaptureManager CaptureManager { get; private set; }
|
internal CaptureManager CaptureManager { get; private set; }
|
||||||
|
@ -175,12 +174,11 @@ namespace Ryujinx.HLE.HOS
|
||||||
|
|
||||||
AppletState.SetFocus(true);
|
AppletState.SetFocus(true);
|
||||||
|
|
||||||
Font = new SharedFontManager(device, fontStorage);
|
|
||||||
|
|
||||||
VsyncEvent = new KEvent(KernelContext);
|
VsyncEvent = new KEvent(KernelContext);
|
||||||
|
|
||||||
DisplayResolutionChangeEvent = new KEvent(KernelContext);
|
DisplayResolutionChangeEvent = new KEvent(KernelContext);
|
||||||
|
|
||||||
|
SharedFontManager = new SharedFontManager(device, fontStorage);
|
||||||
AccountManager = device.Configuration.AccountManager;
|
AccountManager = device.Configuration.AccountManager;
|
||||||
ContentManager = device.Configuration.ContentManager;
|
ContentManager = device.Configuration.ContentManager;
|
||||||
CaptureManager = new CaptureManager(device);
|
CaptureManager = new CaptureManager(device);
|
||||||
|
|
|
@ -16,10 +16,9 @@ namespace Ryujinx.HLE.HOS
|
||||||
public class LibHacHorizonManager
|
public class LibHacHorizonManager
|
||||||
{
|
{
|
||||||
private LibHac.Horizon Server { get; set; }
|
private LibHac.Horizon Server { get; set; }
|
||||||
|
|
||||||
public HorizonClient RyujinxClient { get; private set; }
|
public HorizonClient RyujinxClient { get; private set; }
|
||||||
|
|
||||||
public HorizonClient ApplicationClient { get; private set; }
|
public HorizonClient ApplicationClient { get; private set; }
|
||||||
|
|
||||||
public HorizonClient AccountClient { get; private set; }
|
public HorizonClient AccountClient { get; private set; }
|
||||||
public HorizonClient AmClient { get; private set; }
|
public HorizonClient AmClient { get; private set; }
|
||||||
public HorizonClient BcatClient { get; private set; }
|
public HorizonClient BcatClient { get; private set; }
|
||||||
|
@ -49,8 +48,7 @@ namespace Ryujinx.HLE.HOS
|
||||||
|
|
||||||
public void InitializeBcatServer()
|
public void InitializeBcatServer()
|
||||||
{
|
{
|
||||||
BcatClient = Server.CreateHorizonClient(new ProgramLocation(SystemProgramId.Bcat, StorageId.BuiltInSystem),
|
BcatClient = Server.CreateHorizonClient(new ProgramLocation(SystemProgramId.Bcat, StorageId.BuiltInSystem), BcatFsPermissions);
|
||||||
BcatFsPermissions);
|
|
||||||
|
|
||||||
_ = new BcatServer(BcatClient);
|
_ = new BcatServer(BcatClient);
|
||||||
}
|
}
|
||||||
|
@ -66,23 +64,15 @@ namespace Ryujinx.HLE.HOS
|
||||||
|
|
||||||
public void InitializeSystemClients()
|
public void InitializeSystemClients()
|
||||||
{
|
{
|
||||||
AccountClient = Server.CreateHorizonClient(new ProgramLocation(SystemProgramId.Account, StorageId.BuiltInSystem),
|
AccountClient = Server.CreateHorizonClient(new ProgramLocation(SystemProgramId.Account, StorageId.BuiltInSystem), AccountFsPermissions);
|
||||||
AccountFsPermissions);
|
AmClient = Server.CreateHorizonClient(new ProgramLocation(SystemProgramId.Am, StorageId.BuiltInSystem), AmFsPermissions);
|
||||||
|
NsClient = Server.CreateHorizonClient(new ProgramLocation(SystemProgramId.Ns, StorageId.BuiltInSystem), NsFsPermissions);
|
||||||
AmClient = Server.CreateHorizonClient(new ProgramLocation(SystemProgramId.Am, StorageId.BuiltInSystem),
|
SdbClient = Server.CreateHorizonClient(new ProgramLocation(SystemProgramId.Sdb, StorageId.BuiltInSystem), SdbFacData, SdbFacDescriptor);
|
||||||
AmFsPermissions);
|
|
||||||
|
|
||||||
NsClient = Server.CreateHorizonClient(new ProgramLocation(SystemProgramId.Ns, StorageId.BuiltInSystem),
|
|
||||||
NsFsPermissions);
|
|
||||||
|
|
||||||
SdbClient = Server.CreateHorizonClient(new ProgramLocation(SystemProgramId.Sdb, StorageId.BuiltInSystem),
|
|
||||||
SdbFacData, SdbFacDescriptor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InitializeApplicationClient(ProgramId programId, in Npdm npdm)
|
public void InitializeApplicationClient(ProgramId programId, in Npdm npdm)
|
||||||
{
|
{
|
||||||
ApplicationClient = Server.CreateHorizonClient(new ProgramLocation(programId, StorageId.BuiltInUser),
|
ApplicationClient = Server.CreateHorizonClient(new ProgramLocation(programId, StorageId.BuiltInUser), npdm.FsAccessControlData, npdm.FsAccessControlDescriptor);
|
||||||
npdm.FsAccessControlData, npdm.FsAccessControlDescriptor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function was added to avoid errors that come from a user's keys or SD encryption seed changing.
|
// This function was added to avoid errors that come from a user's keys or SD encryption seed changing.
|
||||||
|
|
|
@ -53,8 +53,7 @@ namespace Ryujinx.HLE.HOS.Services.Ro
|
||||||
return ResultCode.InvalidAddress;
|
return ResultCode.InvalidAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
StructReader reader = new StructReader(_owner.CpuMemory, nrrAddress);
|
NrrHeader header = _owner.CpuMemory.Read<NrrHeader>(nrrAddress);
|
||||||
NrrHeader header = reader.Read<NrrHeader>();
|
|
||||||
|
|
||||||
if (header.Magic != NrrMagic)
|
if (header.Magic != NrrMagic)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using Ryujinx.HLE.HOS.Font;
|
|
||||||
using Ryujinx.HLE.HOS.Ipc;
|
using Ryujinx.HLE.HOS.Ipc;
|
||||||
using Ryujinx.HLE.HOS.Kernel.Common;
|
using Ryujinx.HLE.HOS.Kernel.Common;
|
||||||
|
using Ryujinx.HLE.HOS.Services.Sdb.Pl.Types;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Sdb.Pl
|
namespace Ryujinx.HLE.HOS.Services.Sdb.Pl
|
||||||
|
@ -43,7 +43,7 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pl
|
||||||
{
|
{
|
||||||
SharedFontType fontType = (SharedFontType)context.RequestData.ReadInt32();
|
SharedFontType fontType = (SharedFontType)context.RequestData.ReadInt32();
|
||||||
|
|
||||||
context.ResponseData.Write(context.Device.System.Font.GetFontSize(fontType));
|
context.ResponseData.Write(context.Device.System.SharedFontManager.GetFontSize(fontType));
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pl
|
||||||
{
|
{
|
||||||
SharedFontType fontType = (SharedFontType)context.RequestData.ReadInt32();
|
SharedFontType fontType = (SharedFontType)context.RequestData.ReadInt32();
|
||||||
|
|
||||||
context.ResponseData.Write(context.Device.System.Font.GetSharedMemoryAddressOffset(fontType));
|
context.ResponseData.Write(context.Device.System.SharedFontManager.GetSharedMemoryAddressOffset(fontType));
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pl
|
||||||
// GetSharedMemoryNativeHandle() -> handle<copy>
|
// GetSharedMemoryNativeHandle() -> handle<copy>
|
||||||
public ResultCode GetSharedMemoryNativeHandle(ServiceCtx context)
|
public ResultCode GetSharedMemoryNativeHandle(ServiceCtx context)
|
||||||
{
|
{
|
||||||
context.Device.System.Font.EnsureInitialized(context.Device.System.ContentManager);
|
context.Device.System.SharedFontManager.EnsureInitialized(context.Device.System.ContentManager);
|
||||||
|
|
||||||
if (_fontSharedMemHandle == 0)
|
if (_fontSharedMemHandle == 0)
|
||||||
{
|
{
|
||||||
|
@ -131,8 +131,8 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pl
|
||||||
}
|
}
|
||||||
|
|
||||||
context.Memory.Write(typesPosition + offset, (int)fontType);
|
context.Memory.Write(typesPosition + offset, (int)fontType);
|
||||||
context.Memory.Write(offsetsPosition + offset, context.Device.System.Font.GetSharedMemoryAddressOffset(fontType));
|
context.Memory.Write(offsetsPosition + offset, context.Device.System.SharedFontManager.GetSharedMemoryAddressOffset(fontType));
|
||||||
context.Memory.Write(fontSizeBufferPosition + offset, context.Device.System.Font.GetFontSize(fontType));
|
context.Memory.Write(fontSizeBufferPosition + offset, context.Device.System.SharedFontManager.GetFontSize(fontType));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,19 +7,20 @@ using Ryujinx.HLE.Exceptions;
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
using Ryujinx.HLE.FileSystem.Content;
|
using Ryujinx.HLE.FileSystem.Content;
|
||||||
using Ryujinx.HLE.HOS.Kernel.Memory;
|
using Ryujinx.HLE.HOS.Kernel.Memory;
|
||||||
|
using Ryujinx.HLE.HOS.Services.Sdb.Pl.Types;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers.Binary;
|
using System.Buffers.Binary;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
using static Ryujinx.HLE.Utilities.FontUtils;
|
namespace Ryujinx.HLE.HOS.Services.Sdb.Pl
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Font
|
|
||||||
{
|
{
|
||||||
class SharedFontManager
|
class SharedFontManager
|
||||||
{
|
{
|
||||||
private readonly Switch _device;
|
private static readonly uint FontKey = 0x06186249;
|
||||||
|
private static readonly uint BFTTFMagic = 0x18029a7f;
|
||||||
|
|
||||||
|
private readonly Switch _device;
|
||||||
private readonly SharedMemoryStorage _storage;
|
private readonly SharedMemoryStorage _storage;
|
||||||
|
|
||||||
private struct FontInfo
|
private struct FontInfo
|
||||||
|
@ -42,7 +43,7 @@ namespace Ryujinx.HLE.HOS.Font
|
||||||
_storage = storage;
|
_storage = storage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(ContentManager contentManager)
|
public void Initialize()
|
||||||
{
|
{
|
||||||
_fontData?.Clear();
|
_fontData?.Clear();
|
||||||
_fontData = null;
|
_fontData = null;
|
||||||
|
@ -59,8 +60,7 @@ namespace Ryujinx.HLE.HOS.Font
|
||||||
|
|
||||||
FontInfo CreateFont(string name)
|
FontInfo CreateFont(string name)
|
||||||
{
|
{
|
||||||
if (contentManager.TryGetFontTitle(name, out ulong fontTitle) &&
|
if (contentManager.TryGetFontTitle(name, out ulong fontTitle) && contentManager.TryGetFontFilename(name, out string fontFilename))
|
||||||
contentManager.TryGetFontFilename(name, out string fontFilename))
|
|
||||||
{
|
{
|
||||||
string contentPath = contentManager.GetInstalledContentPath(fontTitle, StorageId.NandSystem, NcaContentType.Data);
|
string contentPath = contentManager.GetInstalledContentPath(fontTitle, StorageId.NandSystem, NcaContentType.Data);
|
||||||
string fontPath = _device.FileSystem.SwitchPathToSystemPath(contentPath);
|
string fontPath = _device.FileSystem.SwitchPathToSystemPath(contentPath);
|
||||||
|
@ -122,22 +122,19 @@ namespace Ryujinx.HLE.HOS.Font
|
||||||
|
|
||||||
if (fontOffset > Horizon.FontSize)
|
if (fontOffset > Horizon.FontSize)
|
||||||
{
|
{
|
||||||
throw new InvalidSystemResourceException(
|
throw new InvalidSystemResourceException("The sum of all fonts size exceed the shared memory size. " +
|
||||||
$"The sum of all fonts size exceed the shared memory size. " +
|
$"Please make sure that the fonts don't exceed {Horizon.FontSize} bytes in total. (actual size: {fontOffset} bytes).");
|
||||||
$"Please make sure that the fonts don't exceed {Horizon.FontSize} bytes in total. " +
|
|
||||||
$"(actual size: {fontOffset} bytes).");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteMagicAndSize(ulong offset, int size)
|
private void WriteMagicAndSize(ulong offset, int size)
|
||||||
{
|
{
|
||||||
const int decMagic = 0x18029a7f;
|
|
||||||
const int key = 0x49621806;
|
const int key = 0x49621806;
|
||||||
|
|
||||||
int encryptedSize = BinaryPrimitives.ReverseEndianness(size ^ key);
|
int encryptedSize = BinaryPrimitives.ReverseEndianness(size ^ key);
|
||||||
|
|
||||||
_storage.GetRef<int>(offset + 0) = decMagic;
|
_storage.GetRef<int>(offset + 0) = (int)BFTTFMagic;
|
||||||
_storage.GetRef<int>(offset + 4) = encryptedSize;
|
_storage.GetRef<int>(offset + 4) = encryptedSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,5 +151,29 @@ namespace Ryujinx.HLE.HOS.Font
|
||||||
|
|
||||||
return _fontData[fontType].Offset + 8;
|
return _fontData[fontType].Offset + 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static byte[] DecryptFont(Stream bfttfStream)
|
||||||
|
{
|
||||||
|
static uint KXor(uint data) => data ^ FontKey;
|
||||||
|
|
||||||
|
using (BinaryReader reader = new BinaryReader(bfttfStream))
|
||||||
|
using (MemoryStream ttfStream = new MemoryStream())
|
||||||
|
using (BinaryWriter output = new BinaryWriter(ttfStream))
|
||||||
|
{
|
||||||
|
if (KXor(reader.ReadUInt32()) != BFTTFMagic)
|
||||||
|
{
|
||||||
|
throw new InvalidDataException("Error: Input file is not in BFTTF format!");
|
||||||
|
}
|
||||||
|
|
||||||
|
bfttfStream.Position += 4;
|
||||||
|
|
||||||
|
for (int i = 0; i < (bfttfStream.Length - 8) / 4; i++)
|
||||||
|
{
|
||||||
|
output.Write(KXor(reader.ReadUInt32()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ttfStream.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Ryujinx.HLE.HOS.Font
|
namespace Ryujinx.HLE.HOS.Services.Sdb.Pl.Types
|
||||||
{
|
{
|
||||||
public enum SharedFontType
|
public enum SharedFontType
|
||||||
{
|
{
|
|
@ -1,5 +1,4 @@
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.HLE.Utilities;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers.Binary;
|
using System.Buffers.Binary;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.Utilities
|
namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||||
{
|
{
|
||||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||||
enum LinuxError
|
enum LinuxError
|
|
@ -1,6 +1,6 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.Utilities
|
namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||||
{
|
{
|
||||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||||
enum WsaError
|
enum WsaError
|
|
@ -1,4 +1,5 @@
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.HLE.Utilities;
|
using Ryujinx.HLE.Utilities;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
|
@ -8,13 +8,8 @@ namespace Ryujinx.HLE.Loaders.Elf
|
||||||
public ElfSymbolBinding Binding { get; private set; }
|
public ElfSymbolBinding Binding { get; private set; }
|
||||||
public ElfSymbolVisibility Visibility { get; private set; }
|
public ElfSymbolVisibility Visibility { get; private set; }
|
||||||
|
|
||||||
public bool IsFuncOrObject =>
|
public bool IsFuncOrObject => Type == ElfSymbolType.SttFunc || Type == ElfSymbolType.SttObject;
|
||||||
Type == ElfSymbolType.SttFunc ||
|
public bool IsGlobalOrWeak => Binding == ElfSymbolBinding.StbGlobal || Binding == ElfSymbolBinding.StbWeak;
|
||||||
Type == ElfSymbolType.SttObject;
|
|
||||||
|
|
||||||
public bool IsGlobalOrWeak =>
|
|
||||||
Binding == ElfSymbolBinding.StbGlobal ||
|
|
||||||
Binding == ElfSymbolBinding.StbWeak;
|
|
||||||
|
|
||||||
public int ShIdx { get; private set; }
|
public int ShIdx { get; private set; }
|
||||||
public ulong Value { get; private set; }
|
public ulong Value { get; private set; }
|
||||||
|
|
|
@ -7,11 +7,19 @@ namespace Ryujinx.HLE.Loaders.Mods
|
||||||
{
|
{
|
||||||
class IPSwitchPatcher
|
class IPSwitchPatcher
|
||||||
{
|
{
|
||||||
readonly StreamReader _reader;
|
|
||||||
public string BuildId { get; }
|
|
||||||
|
|
||||||
const string BidHeader = "@nsobid-";
|
const string BidHeader = "@nsobid-";
|
||||||
|
|
||||||
|
private enum Token
|
||||||
|
{
|
||||||
|
Normal,
|
||||||
|
String,
|
||||||
|
EscapeChar,
|
||||||
|
Comment
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly StreamReader _reader;
|
||||||
|
public string BuildId { get; }
|
||||||
|
|
||||||
public IPSwitchPatcher(StreamReader reader)
|
public IPSwitchPatcher(StreamReader reader)
|
||||||
{
|
{
|
||||||
string header = reader.ReadLine();
|
string header = reader.ReadLine();
|
||||||
|
@ -26,14 +34,6 @@ namespace Ryujinx.HLE.Loaders.Mods
|
||||||
BuildId = header.Substring(BidHeader.Length).TrimEnd().TrimEnd('0');
|
BuildId = header.Substring(BidHeader.Length).TrimEnd().TrimEnd('0');
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum Token
|
|
||||||
{
|
|
||||||
Normal,
|
|
||||||
String,
|
|
||||||
EscapeChar,
|
|
||||||
Comment
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uncomments line and unescapes C style strings within
|
// Uncomments line and unescapes C style strings within
|
||||||
private static string PreprocessLine(string line)
|
private static string PreprocessLine(string line)
|
||||||
{
|
{
|
||||||
|
@ -120,6 +120,7 @@ namespace Ryujinx.HLE.Loaders.Mods
|
||||||
{
|
{
|
||||||
int high = ParseHexByte((byte)hexstr[i]);
|
int high = ParseHexByte((byte)hexstr[i]);
|
||||||
int low = ParseHexByte((byte)hexstr[i + 1]);
|
int low = ParseHexByte((byte)hexstr[i + 1]);
|
||||||
|
|
||||||
bytes[i >> 1] = (byte)((high << 4) | low);
|
bytes[i >> 1] = (byte)((high << 4) | low);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,11 +132,11 @@ namespace Ryujinx.HLE.Loaders.Mods
|
||||||
{
|
{
|
||||||
if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
|
if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
|
||||||
{
|
{
|
||||||
return Int32.TryParse(str.Substring(2), System.Globalization.NumberStyles.HexNumber, null, out value);
|
return int.TryParse(str.Substring(2), System.Globalization.NumberStyles.HexNumber, null, out value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return Int32.TryParse(str, System.Globalization.NumberStyles.Integer, null, out value);
|
return int.TryParse(str, System.Globalization.NumberStyles.Integer, null, out value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +237,7 @@ namespace Ryujinx.HLE.Loaders.Mods
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Int32.TryParse(tokens[0], System.Globalization.NumberStyles.HexNumber, null, out int offset))
|
if (!int.TryParse(tokens[0], System.Globalization.NumberStyles.HexNumber, null, out int offset))
|
||||||
{
|
{
|
||||||
ParseWarn();
|
ParseWarn();
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
using Ryujinx.Cpu;
|
using Ryujinx.Common.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
using Ryujinx.Common.Logging;
|
|
||||||
|
|
||||||
namespace Ryujinx.HLE.Loaders.Mods
|
namespace Ryujinx.HLE.Loaders.Mods
|
||||||
{
|
{
|
||||||
public class MemPatch
|
public class MemPatch
|
||||||
|
@ -82,7 +80,7 @@ namespace Ryujinx.HLE.Loaders.Mods
|
||||||
|
|
||||||
if (patchOffset + patchSize > memory.Length)
|
if (patchOffset + patchSize > memory.Length)
|
||||||
{
|
{
|
||||||
patchSize = memory.Length - (int)patchOffset; // Add warning?
|
patchSize = memory.Length - patchOffset; // Add warning?
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Info?.Print(LogClass.ModLoader, $"Patching address offset {patchOffset:x} <= {BitConverter.ToString(patch).Replace('-', ' ')} len={patchSize}");
|
Logger.Info?.Print(LogClass.ModLoader, $"Patching address offset {patchOffset:x} <= {BitConverter.ToString(patch).Replace('-', ' ')} len={patchSize}");
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
|
|
||||||
namespace Ryujinx.HLE
|
namespace Ryujinx.HLE
|
||||||
|
@ -7,7 +6,6 @@ namespace Ryujinx.HLE
|
||||||
public class PerformanceStatistics
|
public class PerformanceStatistics
|
||||||
{
|
{
|
||||||
private const double FrameRateWeight = 0.5;
|
private const double FrameRateWeight = 0.5;
|
||||||
|
|
||||||
private const int FrameTypeGame = 0;
|
private const int FrameTypeGame = 0;
|
||||||
private const int PercentTypeFifo = 0;
|
private const int PercentTypeFifo = 0;
|
||||||
|
|
||||||
|
@ -50,7 +48,6 @@ namespace Ryujinx.HLE
|
||||||
_resetTimer = new Timer(1000);
|
_resetTimer = new Timer(1000);
|
||||||
|
|
||||||
_resetTimer.Elapsed += ResetTimerElapsed;
|
_resetTimer.Elapsed += ResetTimerElapsed;
|
||||||
|
|
||||||
_resetTimer.AutoReset = true;
|
_resetTimer.AutoReset = true;
|
||||||
|
|
||||||
_resetTimer.Start();
|
_resetTimer.Start();
|
||||||
|
@ -76,9 +73,7 @@ namespace Ryujinx.HLE
|
||||||
}
|
}
|
||||||
|
|
||||||
_averageFrameRate[frameType] = LinearInterpolate(_averageFrameRate[frameType], frameRate);
|
_averageFrameRate[frameType] = LinearInterpolate(_averageFrameRate[frameType], frameRate);
|
||||||
|
|
||||||
_framesRendered[frameType] = 0;
|
_framesRendered[frameType] = 0;
|
||||||
|
|
||||||
_accumulatedFrameTime[frameType] = 0;
|
_accumulatedFrameTime[frameType] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,14 +92,12 @@ namespace Ryujinx.HLE
|
||||||
}
|
}
|
||||||
|
|
||||||
_averagePercent[percentType] = percent;
|
_averagePercent[percentType] = percent;
|
||||||
|
|
||||||
_percentTime[percentType] = 0;
|
_percentTime[percentType] = 0;
|
||||||
|
|
||||||
_accumulatedActiveTime[percentType] = 0;
|
_accumulatedActiveTime[percentType] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private double LinearInterpolate(double lhs, double rhs)
|
private static double LinearInterpolate(double lhs, double rhs)
|
||||||
{
|
{
|
||||||
return lhs * (1.0 - FrameRateWeight) + rhs * FrameRateWeight;
|
return lhs * (1.0 - FrameRateWeight) + rhs * FrameRateWeight;
|
||||||
}
|
}
|
||||||
|
@ -134,14 +127,12 @@ namespace Ryujinx.HLE
|
||||||
private void EndPercentTime(int percentType)
|
private void EndPercentTime(int percentType)
|
||||||
{
|
{
|
||||||
double currentTime = PerformanceCounter.ElapsedTicks * _ticksToSeconds;
|
double currentTime = PerformanceCounter.ElapsedTicks * _ticksToSeconds;
|
||||||
|
|
||||||
double elapsedTime = currentTime - _percentLastEndTime[percentType];
|
double elapsedTime = currentTime - _percentLastEndTime[percentType];
|
||||||
double elapsedActiveTime = currentTime - _percentStartTime[percentType];
|
double elapsedActiveTime = currentTime - _percentStartTime[percentType];
|
||||||
|
|
||||||
lock (_percentLock[percentType])
|
lock (_percentLock[percentType])
|
||||||
{
|
{
|
||||||
_accumulatedActiveTime[percentType] += elapsedActiveTime;
|
_accumulatedActiveTime[percentType] += elapsedActiveTime;
|
||||||
|
|
||||||
_percentTime[percentType] += elapsedTime;
|
_percentTime[percentType] += elapsedTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +143,6 @@ namespace Ryujinx.HLE
|
||||||
private void RecordFrameTime(int frameType)
|
private void RecordFrameTime(int frameType)
|
||||||
{
|
{
|
||||||
double currentFrameTime = PerformanceCounter.ElapsedTicks * _ticksToSeconds;
|
double currentFrameTime = PerformanceCounter.ElapsedTicks * _ticksToSeconds;
|
||||||
|
|
||||||
double elapsedFrameTime = currentFrameTime - _previousFrameTime[frameType];
|
double elapsedFrameTime = currentFrameTime - _previousFrameTime[frameType];
|
||||||
|
|
||||||
_previousFrameTime[frameType] = currentFrameTime;
|
_previousFrameTime[frameType] = currentFrameTime;
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Ryujinx.HLE.Utilities
|
|
||||||
{
|
|
||||||
public static class FontUtils
|
|
||||||
{
|
|
||||||
private static readonly uint FontKey = 0x06186249;
|
|
||||||
|
|
||||||
public static byte[] DecryptFont(Stream bfttfStream)
|
|
||||||
{
|
|
||||||
uint KXor(uint In) => In ^ FontKey;
|
|
||||||
|
|
||||||
using (BinaryReader reader = new BinaryReader(bfttfStream))
|
|
||||||
{
|
|
||||||
using (MemoryStream ttfStream = new MemoryStream())
|
|
||||||
{
|
|
||||||
using (BinaryWriter output = new BinaryWriter(ttfStream))
|
|
||||||
{
|
|
||||||
if (KXor(reader.ReadUInt32()) != 0x18029a7f)
|
|
||||||
{
|
|
||||||
throw new InvalidDataException("Error: Input file is not in BFTTF format!");
|
|
||||||
}
|
|
||||||
|
|
||||||
bfttfStream.Position += 4;
|
|
||||||
|
|
||||||
for (int i = 0; i < (bfttfStream.Length - 8) / 4; i++)
|
|
||||||
{
|
|
||||||
output.Write(KXor(reader.ReadUInt32()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ttfStream.ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Ryujinx.HLE.Utilities
|
|
||||||
{
|
|
||||||
static class StreamUtils
|
|
||||||
{
|
|
||||||
public static byte[] StreamToBytes(Stream input)
|
|
||||||
{
|
|
||||||
using (MemoryStream ms = new MemoryStream())
|
|
||||||
{
|
|
||||||
input.CopyTo(ms);
|
|
||||||
return ms.ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -12,7 +12,7 @@ namespace Ryujinx.HLE.Utilities
|
||||||
{
|
{
|
||||||
public static byte[] GetFixedLengthBytes(string inputString, int size, Encoding encoding)
|
public static byte[] GetFixedLengthBytes(string inputString, int size, Encoding encoding)
|
||||||
{
|
{
|
||||||
inputString = inputString + "\0";
|
inputString += "\0";
|
||||||
|
|
||||||
int bytesCount = encoding.GetByteCount(inputString);
|
int bytesCount = encoding.GetByteCount(inputString);
|
||||||
|
|
||||||
|
@ -76,8 +76,8 @@ namespace Ryujinx.HLE.Utilities
|
||||||
|
|
||||||
public static U8Span ReadUtf8Span(ServiceCtx context, int index = 0)
|
public static U8Span ReadUtf8Span(ServiceCtx context, int index = 0)
|
||||||
{
|
{
|
||||||
ulong position = (ulong)context.Request.PtrBuff[index].Position;
|
ulong position = context.Request.PtrBuff[index].Position;
|
||||||
ulong size = (ulong)context.Request.PtrBuff[index].Size;
|
ulong size = context.Request.PtrBuff[index].Size;
|
||||||
|
|
||||||
ReadOnlySpan<byte> buffer = context.Memory.GetSpan(position, (int)size);
|
ReadOnlySpan<byte> buffer = context.Memory.GetSpan(position, (int)size);
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ namespace Ryujinx.HLE.Utilities
|
||||||
{
|
{
|
||||||
while (size-- > 0)
|
while (size-- > 0)
|
||||||
{
|
{
|
||||||
byte value = context.Memory.Read<byte>((ulong)position++);
|
byte value = context.Memory.Read<byte>(position++);
|
||||||
|
|
||||||
if (value == 0)
|
if (value == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
using Ryujinx.Cpu;
|
|
||||||
using Ryujinx.Memory;
|
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Ryujinx.HLE.Utilities
|
|
||||||
{
|
|
||||||
class StructReader
|
|
||||||
{
|
|
||||||
private IVirtualMemoryManager _memory;
|
|
||||||
|
|
||||||
public ulong Position { get; private set; }
|
|
||||||
|
|
||||||
public StructReader(IVirtualMemoryManager memory, ulong position)
|
|
||||||
{
|
|
||||||
_memory = memory;
|
|
||||||
Position = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public T Read<T>() where T : unmanaged
|
|
||||||
{
|
|
||||||
T value = MemoryHelper.Read<T>(_memory, Position);
|
|
||||||
|
|
||||||
Position += (uint)Marshal.SizeOf<T>();
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ReadOnlySpan<T> Read<T>(int size) where T : unmanaged
|
|
||||||
{
|
|
||||||
ReadOnlySpan<byte> data = _memory.GetSpan(Position, size);
|
|
||||||
|
|
||||||
Position += (uint)size;
|
|
||||||
|
|
||||||
return MemoryMarshal.Cast<byte, T>(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
using Ryujinx.Cpu;
|
|
||||||
using Ryujinx.Memory;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Ryujinx.HLE.Utilities
|
|
||||||
{
|
|
||||||
class StructWriter
|
|
||||||
{
|
|
||||||
private IVirtualMemoryManager _memory;
|
|
||||||
|
|
||||||
public ulong Position { get; private set; }
|
|
||||||
|
|
||||||
public StructWriter(IVirtualMemoryManager memory, ulong position)
|
|
||||||
{
|
|
||||||
_memory = memory;
|
|
||||||
Position = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Write<T>(T value) where T : struct
|
|
||||||
{
|
|
||||||
MemoryHelper.Write(_memory, Position, value);
|
|
||||||
|
|
||||||
Position += (ulong)Marshal.SizeOf<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SkipBytes(ulong count)
|
|
||||||
{
|
|
||||||
Position += count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Reference in a new issue