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:
Ac_K 2021-09-15 01:24:49 +02:00 committed by GitHub
parent 3f2486342b
commit 5d08e9b495
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 261 additions and 382 deletions

View 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();
}
}
}
}

View File

@ -7,9 +7,9 @@ namespace Ryujinx.HLE.Exceptions
{
static readonly Type _structType = typeof(T);
public InvalidStructLayoutException(string message) : base(message) {}
public InvalidStructLayoutException(string message) : base(message) { }
public InvalidStructLayoutException(int expectedSize) :
base($"Type {_structType.Name} has the wrong size. Expected: {expectedSize} bytes, Got: {Unsafe.SizeOf<T>()} bytes") {}
public InvalidStructLayoutException(int expectedSize)
: base($"Type {_structType.Name} has the wrong size. Expected: {expectedSize} bytes, got: {Unsafe.SizeOf<T>()} bytes") { }
}
}

View File

@ -19,37 +19,29 @@ namespace Ryujinx.HLE.Exceptions
public IpcMessage Request { get; }
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)
: base(message)
public ServiceNotImplementedException(IpcService service, ServiceCtx context, string message) : base(message)
{
Service = service;
Context = context;
Request = context.Request;
}
public ServiceNotImplementedException(IpcService service, ServiceCtx context, string message, Exception inner)
: base(message, inner)
public ServiceNotImplementedException(IpcService service, ServiceCtx context, string message, Exception inner) : base(message, inner)
{
Service = service;
Context = context;
Request = context.Request;
}
protected ServiceNotImplementedException(SerializationInfo info, StreamingContext context)
: base(info, context)
{ }
protected ServiceNotImplementedException(SerializationInfo info, StreamingContext context) : base(info, context) { }
public override string Message
{
get
{
return base.Message +
Environment.NewLine +
Environment.NewLine +
BuildMessage();
return base.Message + Environment.NewLine + Environment.NewLine + BuildMessage();
}
}
@ -63,8 +55,7 @@ namespace Ryujinx.HLE.Exceptions
if (callingType != null && callingMethod != null)
{
// If the type is past 0xF, we are using TIPC
var ipcCommands = Request.Type > IpcMessageType.TipcCloseSession ?
Service.TipcCommands : Service.HipcCommands;
var ipcCommands = Request.Type > IpcMessageType.TipcCloseSession ? Service.TipcCommands : Service.HipcCommands;
// Find the handler for the method called
var ipcHandler = ipcCommands.FirstOrDefault(x => x.Value == callingMethod);
@ -82,9 +73,9 @@ namespace Ryujinx.HLE.Exceptions
sb.AppendLine(Context.Thread.GetGuestStackTrace());
// Print buffer information
if (Request.PtrBuff.Count > 0 ||
Request.SendBuff.Count > 0 ||
Request.ReceiveBuff.Count > 0 ||
if (Request.PtrBuff.Count > 0 ||
Request.SendBuff.Count > 0 ||
Request.ReceiveBuff.Count > 0 ||
Request.ExchangeBuff.Count > 0 ||
Request.RecvListBuff.Count > 0)
{
@ -149,11 +140,12 @@ namespace Ryujinx.HLE.Exceptions
return sb.ToString();
}
private (Type, MethodBase) WalkStackTrace(StackTrace trace)
private static (Type, MethodBase) WalkStackTrace(StackTrace trace)
{
int i = 0;
StackFrame frame;
// Find the IIpcService method that threw this exception
while ((frame = trace.GetFrame(i++)) != null)
{

View File

@ -191,7 +191,7 @@ namespace Ryujinx.HLE.FileSystem.Content
if (device != null)
{
TimeManager.Instance.InitializeTimeZone(device);
device.System.Font.Initialize(this);
device.System.SharedFontManager.Initialize();
}
}
}

View File

@ -143,49 +143,49 @@ namespace Ryujinx.HLE
/// </summary>
public Action RefreshInputConfig { internal get; set; }
public HLEConfiguration(VirtualFileSystem virtualFileSystem,
LibHacHorizonManager libHacHorizonManager,
ContentManager contentManager,
AccountManager accountManager,
public HLEConfiguration(VirtualFileSystem virtualFileSystem,
LibHacHorizonManager libHacHorizonManager,
ContentManager contentManager,
AccountManager accountManager,
UserChannelPersistence userChannelPersistence,
IRenderer gpuRenderer,
IHardwareDeviceDriver audioDeviceDriver,
MemoryConfiguration memoryConfiguration,
IHostUiHandler hostUiHandler,
SystemLanguage systemLanguage,
RegionCode region,
bool enableVsync,
bool enableDockedMode,
bool enablePtc,
IntegrityCheckLevel fsIntegrityCheckLevel,
int fsGlobalAccessLogMode,
long systemTimeOffset,
string timeZone,
MemoryManagerMode memoryManagerMode,
bool ignoreMissingServices,
AspectRatio aspectRatio)
IRenderer gpuRenderer,
IHardwareDeviceDriver audioDeviceDriver,
MemoryConfiguration memoryConfiguration,
IHostUiHandler hostUiHandler,
SystemLanguage systemLanguage,
RegionCode region,
bool enableVsync,
bool enableDockedMode,
bool enablePtc,
IntegrityCheckLevel fsIntegrityCheckLevel,
int fsGlobalAccessLogMode,
long systemTimeOffset,
string timeZone,
MemoryManagerMode memoryManagerMode,
bool ignoreMissingServices,
AspectRatio aspectRatio)
{
VirtualFileSystem = virtualFileSystem;
LibHacHorizonManager = libHacHorizonManager;
AccountManager = accountManager;
ContentManager = contentManager;
VirtualFileSystem = virtualFileSystem;
LibHacHorizonManager = libHacHorizonManager;
AccountManager = accountManager;
ContentManager = contentManager;
UserChannelPersistence = userChannelPersistence;
GpuRenderer = gpuRenderer;
AudioDeviceDriver = audioDeviceDriver;
MemoryConfiguration = memoryConfiguration;
HostUiHandler = hostUiHandler;
SystemLanguage = systemLanguage;
Region = region;
EnableVsync = enableVsync;
EnableDockedMode = enableDockedMode;
EnablePtc = enablePtc;
FsIntegrityCheckLevel = fsIntegrityCheckLevel;
FsGlobalAccessLogMode = fsGlobalAccessLogMode;
SystemTimeOffset = systemTimeOffset;
TimeZone = timeZone;
MemoryManagerMode = memoryManagerMode;
IgnoreMissingServices = ignoreMissingServices;
AspectRatio = aspectRatio;
GpuRenderer = gpuRenderer;
AudioDeviceDriver = audioDeviceDriver;
MemoryConfiguration = memoryConfiguration;
HostUiHandler = hostUiHandler;
SystemLanguage = systemLanguage;
Region = region;
EnableVsync = enableVsync;
EnableDockedMode = enableDockedMode;
EnablePtc = enablePtc;
FsIntegrityCheckLevel = fsIntegrityCheckLevel;
FsGlobalAccessLogMode = fsGlobalAccessLogMode;
SystemTimeOffset = systemTimeOffset;
TimeZone = timeZone;
MemoryManagerMode = memoryManagerMode;
IgnoreMissingServices = ignoreMissingServices;
AspectRatio = aspectRatio;
}
}
}

View File

@ -9,7 +9,6 @@ using Ryujinx.Audio.Output;
using Ryujinx.Audio.Renderer.Device;
using Ryujinx.Audio.Renderer.Server;
using Ryujinx.HLE.FileSystem.Content;
using Ryujinx.HLE.HOS.Font;
using Ryujinx.HLE.HOS.Kernel;
using Ryujinx.HLE.HOS.Kernel.Memory;
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.NvDrvServices.NvHostCtrl;
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.Sm;
using Ryujinx.HLE.HOS.Services.SurfaceFlinger;
@ -87,11 +87,10 @@ namespace Ryujinx.HLE.HOS
internal KTransferMemory AppletCaptureBufferTransfer { get; private set; }
internal SharedFontManager Font { get; private set; }
internal AccountManager AccountManager { get; private set; }
internal ContentManager ContentManager { get; private set; }
internal CaptureManager CaptureManager { get; private set; }
internal SharedFontManager SharedFontManager { get; private set; }
internal AccountManager AccountManager { get; private set; }
internal ContentManager ContentManager { get; private set; }
internal CaptureManager CaptureManager { get; private set; }
internal KEvent VsyncEvent { get; private set; }
@ -175,15 +174,14 @@ namespace Ryujinx.HLE.HOS
AppletState.SetFocus(true);
Font = new SharedFontManager(device, fontStorage);
VsyncEvent = new KEvent(KernelContext);
DisplayResolutionChangeEvent = new KEvent(KernelContext);
AccountManager = device.Configuration.AccountManager;
ContentManager = device.Configuration.ContentManager;
CaptureManager = new CaptureManager(device);
SharedFontManager = new SharedFontManager(device, fontStorage);
AccountManager = device.Configuration.AccountManager;
ContentManager = device.Configuration.ContentManager;
CaptureManager = new CaptureManager(device);
LibHacHorizonManager = device.Configuration.LibHacHorizonManager;

View File

@ -16,16 +16,15 @@ namespace Ryujinx.HLE.HOS
public class LibHacHorizonManager
{
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 AccountClient { get; private set; }
public HorizonClient AmClient { get; private set; }
public HorizonClient BcatClient { get; private set; }
public HorizonClient FsClient { get; private set; }
public HorizonClient NsClient { get; private set; }
public HorizonClient SdbClient { get; private set; }
public HorizonClient AccountClient { get; private set; }
public HorizonClient AmClient { get; private set; }
public HorizonClient BcatClient { get; private set; }
public HorizonClient FsClient { get; private set; }
public HorizonClient NsClient { get; private set; }
public HorizonClient SdbClient { get; private set; }
internal LibHacIReader ArpIReader { get; private set; }
@ -49,8 +48,7 @@ namespace Ryujinx.HLE.HOS
public void InitializeBcatServer()
{
BcatClient = Server.CreateHorizonClient(new ProgramLocation(SystemProgramId.Bcat, StorageId.BuiltInSystem),
BcatFsPermissions);
BcatClient = Server.CreateHorizonClient(new ProgramLocation(SystemProgramId.Bcat, StorageId.BuiltInSystem), BcatFsPermissions);
_ = new BcatServer(BcatClient);
}
@ -66,23 +64,15 @@ namespace Ryujinx.HLE.HOS
public void InitializeSystemClients()
{
AccountClient = Server.CreateHorizonClient(new ProgramLocation(SystemProgramId.Account, StorageId.BuiltInSystem),
AccountFsPermissions);
AmClient = Server.CreateHorizonClient(new ProgramLocation(SystemProgramId.Am, StorageId.BuiltInSystem),
AmFsPermissions);
NsClient = Server.CreateHorizonClient(new ProgramLocation(SystemProgramId.Ns, StorageId.BuiltInSystem),
NsFsPermissions);
SdbClient = Server.CreateHorizonClient(new ProgramLocation(SystemProgramId.Sdb, StorageId.BuiltInSystem),
SdbFacData, SdbFacDescriptor);
AccountClient = Server.CreateHorizonClient(new ProgramLocation(SystemProgramId.Account, StorageId.BuiltInSystem), AccountFsPermissions);
AmClient = Server.CreateHorizonClient(new ProgramLocation(SystemProgramId.Am, StorageId.BuiltInSystem), 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)
{
ApplicationClient = Server.CreateHorizonClient(new ProgramLocation(programId, StorageId.BuiltInUser),
npdm.FsAccessControlData, npdm.FsAccessControlDescriptor);
ApplicationClient = Server.CreateHorizonClient(new ProgramLocation(programId, StorageId.BuiltInUser), npdm.FsAccessControlData, npdm.FsAccessControlDescriptor);
}
// This function was added to avoid errors that come from a user's keys or SD encryption seed changing.

View File

@ -8,32 +8,32 @@ namespace Ryujinx.HLE.HOS
{
class ServiceCtx
{
public Switch Device { get; }
public KProcess Process { get; }
public IVirtualMemoryManager Memory { get; }
public KThread Thread { get; }
public IpcMessage Request { get; }
public IpcMessage Response { get; }
public BinaryReader RequestData { get; }
public BinaryWriter ResponseData { get; }
public Switch Device { get; }
public KProcess Process { get; }
public IVirtualMemoryManager Memory { get; }
public KThread Thread { get; }
public IpcMessage Request { get; }
public IpcMessage Response { get; }
public BinaryReader RequestData { get; }
public BinaryWriter ResponseData { get; }
public ServiceCtx(
Switch device,
KProcess process,
Switch device,
KProcess process,
IVirtualMemoryManager memory,
KThread thread,
IpcMessage request,
IpcMessage response,
BinaryReader requestData,
BinaryWriter responseData)
KThread thread,
IpcMessage request,
IpcMessage response,
BinaryReader requestData,
BinaryWriter responseData)
{
Device = device;
Process = process;
Memory = memory;
Thread = thread;
Request = request;
Response = response;
RequestData = requestData;
Device = device;
Process = process;
Memory = memory;
Thread = thread;
Request = request;
Response = response;
RequestData = requestData;
ResponseData = responseData;
}
}

View File

@ -53,8 +53,7 @@ namespace Ryujinx.HLE.HOS.Services.Ro
return ResultCode.InvalidAddress;
}
StructReader reader = new StructReader(_owner.CpuMemory, nrrAddress);
NrrHeader header = reader.Read<NrrHeader>();
NrrHeader header = _owner.CpuMemory.Read<NrrHeader>(nrrAddress);
if (header.Magic != NrrMagic)
{

View File

@ -1,6 +1,6 @@
using Ryujinx.HLE.HOS.Font;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Services.Sdb.Pl.Types;
using System;
namespace Ryujinx.HLE.HOS.Services.Sdb.Pl
@ -43,7 +43,7 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pl
{
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;
}
@ -54,7 +54,7 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pl
{
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;
}
@ -63,7 +63,7 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pl
// GetSharedMemoryNativeHandle() -> handle<copy>
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)
{
@ -131,8 +131,8 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pl
}
context.Memory.Write(typesPosition + offset, (int)fontType);
context.Memory.Write(offsetsPosition + offset, context.Device.System.Font.GetSharedMemoryAddressOffset(fontType));
context.Memory.Write(fontSizeBufferPosition + offset, context.Device.System.Font.GetFontSize(fontType));
context.Memory.Write(offsetsPosition + offset, context.Device.System.SharedFontManager.GetSharedMemoryAddressOffset(fontType));
context.Memory.Write(fontSizeBufferPosition + offset, context.Device.System.SharedFontManager.GetFontSize(fontType));
return true;
}

View File

@ -7,19 +7,20 @@ using Ryujinx.HLE.Exceptions;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.FileSystem.Content;
using Ryujinx.HLE.HOS.Kernel.Memory;
using Ryujinx.HLE.HOS.Services.Sdb.Pl.Types;
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
using static Ryujinx.HLE.Utilities.FontUtils;
namespace Ryujinx.HLE.HOS.Font
namespace Ryujinx.HLE.HOS.Services.Sdb.Pl
{
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 struct FontInfo
@ -42,7 +43,7 @@ namespace Ryujinx.HLE.HOS.Font
_storage = storage;
}
public void Initialize(ContentManager contentManager)
public void Initialize()
{
_fontData?.Clear();
_fontData = null;
@ -59,8 +60,7 @@ namespace Ryujinx.HLE.HOS.Font
FontInfo CreateFont(string name)
{
if (contentManager.TryGetFontTitle(name, out ulong fontTitle) &&
contentManager.TryGetFontFilename(name, out string fontFilename))
if (contentManager.TryGetFontTitle(name, out ulong fontTitle) && contentManager.TryGetFontFilename(name, out string fontFilename))
{
string contentPath = contentManager.GetInstalledContentPath(fontTitle, StorageId.NandSystem, NcaContentType.Data);
string fontPath = _device.FileSystem.SwitchPathToSystemPath(contentPath);
@ -71,8 +71,8 @@ namespace Ryujinx.HLE.HOS.Font
using (IStorage ncaFileStream = new LocalStorage(fontPath, FileAccess.Read, FileMode.Open))
{
Nca nca = new Nca(_device.System.KeySet, ncaFileStream);
IFileSystem romfs = nca.OpenFileSystem(NcaSectionType.Data, _device.System.FsIntegrityCheckLevel);
Nca nca = new Nca(_device.System.KeySet, ncaFileStream);
IFileSystem romfs = nca.OpenFileSystem(NcaSectionType.Data, _device.System.FsIntegrityCheckLevel);
romfs.OpenFile(out IFile fontFile, ("/" + fontFilename).ToU8Span(), OpenMode.Read).ThrowIfFailure();
@ -122,22 +122,19 @@ namespace Ryujinx.HLE.HOS.Font
if (fontOffset > Horizon.FontSize)
{
throw new InvalidSystemResourceException(
$"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).");
throw new InvalidSystemResourceException("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).");
}
}
}
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);
_storage.GetRef<int>(offset + 0) = decMagic;
_storage.GetRef<int>(offset + 0) = (int)BFTTFMagic;
_storage.GetRef<int>(offset + 4) = encryptedSize;
}
@ -154,5 +151,29 @@ namespace Ryujinx.HLE.HOS.Font
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();
}
}
}
}

View File

@ -1,4 +1,4 @@
namespace Ryujinx.HLE.HOS.Font
namespace Ryujinx.HLE.HOS.Services.Sdb.Pl.Types
{
public enum SharedFontType
{

View File

@ -1,5 +1,4 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.Utilities;
using System;
using System.Buffers.Binary;
using System.Collections.Generic;

View File

@ -1,6 +1,6 @@
using System.Diagnostics.CodeAnalysis;
namespace Ryujinx.HLE.Utilities
namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
{
[SuppressMessage("ReSharper", "InconsistentNaming")]
enum LinuxError

View File

@ -1,6 +1,6 @@
using System.Diagnostics.CodeAnalysis;
namespace Ryujinx.HLE.Utilities
namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
{
[SuppressMessage("ReSharper", "InconsistentNaming")]
enum WsaError

View File

@ -1,4 +1,5 @@
using Ryujinx.Common;
using Ryujinx.Common.Utilities;
using Ryujinx.HLE.Utilities;
using System;
using System.IO;

View File

@ -8,13 +8,8 @@ namespace Ryujinx.HLE.Loaders.Elf
public ElfSymbolBinding Binding { get; private set; }
public ElfSymbolVisibility Visibility { get; private set; }
public bool IsFuncOrObject =>
Type == ElfSymbolType.SttFunc ||
Type == ElfSymbolType.SttObject;
public bool IsGlobalOrWeak =>
Binding == ElfSymbolBinding.StbGlobal ||
Binding == ElfSymbolBinding.StbWeak;
public bool IsFuncOrObject => Type == ElfSymbolType.SttFunc || Type == ElfSymbolType.SttObject;
public bool IsGlobalOrWeak => Binding == ElfSymbolBinding.StbGlobal || Binding == ElfSymbolBinding.StbWeak;
public int ShIdx { get; private set; }
public ulong Value { get; private set; }

View File

@ -12,25 +12,25 @@ namespace Ryujinx.HLE.Loaders.Executables
public Span<byte> Data => Program.AsSpan().Slice((int)DataOffset, (int)DataSize);
public uint TextOffset { get; }
public uint RoOffset { get; }
public uint RoOffset { get; }
public uint DataOffset { get; }
public uint BssOffset { get; }
public uint BssOffset { get; }
public uint TextSize { get; }
public uint RoSize { get; }
public uint RoSize { get; }
public uint DataSize { get; }
public uint BssSize { get; }
public uint BssSize { get; }
public int[] Capabilities { get; }
public bool UsesSecureMemory { get; }
public int[] Capabilities { get; }
public bool UsesSecureMemory { get; }
public bool Is64BitAddressSpace { get; }
public bool Is64Bit { get; }
public ulong ProgramId { get; }
public byte Priority { get; }
public int StackSize { get; }
public byte IdealCoreId { get; }
public int Version { get; }
public string Name { get; }
public bool Is64Bit { get; }
public ulong ProgramId { get; }
public byte Priority { get; }
public int StackSize { get; }
public byte IdealCoreId { get; }
public int Version { get; }
public string Name { get; }
public KipExecutable(IStorage inStorage)
{
@ -39,22 +39,22 @@ namespace Ryujinx.HLE.Loaders.Executables
reader.Initialize(inStorage).ThrowIfFailure();
TextOffset = (uint)reader.Segments[0].MemoryOffset;
RoOffset = (uint)reader.Segments[1].MemoryOffset;
RoOffset = (uint)reader.Segments[1].MemoryOffset;
DataOffset = (uint)reader.Segments[2].MemoryOffset;
BssOffset = (uint)reader.Segments[3].MemoryOffset;
BssSize = (uint)reader.Segments[3].Size;
BssOffset = (uint)reader.Segments[3].MemoryOffset;
BssSize = (uint)reader.Segments[3].Size;
StackSize = reader.StackSize;
UsesSecureMemory = reader.UsesSecureMemory;
UsesSecureMemory = reader.UsesSecureMemory;
Is64BitAddressSpace = reader.Is64BitAddressSpace;
Is64Bit = reader.Is64Bit;
Is64Bit = reader.Is64Bit;
ProgramId = reader.ProgramId;
Priority = reader.Priority;
ProgramId = reader.ProgramId;
Priority = reader.Priority;
IdealCoreId = reader.IdealCoreId;
Version = reader.Version;
Name = reader.Name.ToString();
Version = reader.Version;
Name = reader.Name.ToString();
Capabilities = new int[32];

View File

@ -17,14 +17,14 @@ namespace Ryujinx.HLE.Loaders.Executables
public Span<byte> Data => Program.AsSpan().Slice((int)DataOffset, (int)DataSize);
public uint TextOffset { get; }
public uint RoOffset { get; }
public uint RoOffset { get; }
public uint DataOffset { get; }
public uint BssOffset => DataOffset + (uint)Data.Length;
public uint TextSize { get; }
public uint RoSize { get; }
public uint RoSize { get; }
public uint DataSize { get; }
public uint BssSize { get; }
public uint BssSize { get; }
public string Name;
public Buffer32 BuildId;

View File

@ -20,10 +20,10 @@ namespace Ryujinx.HLE.Loaders.Mods
private static MemPatch ParseIps(BinaryReader reader)
{
Span<byte> IpsHeaderMagic = Encoding.ASCII.GetBytes("PATCH").AsSpan();
Span<byte> IpsTailMagic = Encoding.ASCII.GetBytes("EOF").AsSpan();
Span<byte> IpsHeaderMagic = Encoding.ASCII.GetBytes("PATCH").AsSpan();
Span<byte> IpsTailMagic = Encoding.ASCII.GetBytes("EOF").AsSpan();
Span<byte> Ips32HeaderMagic = Encoding.ASCII.GetBytes("IPS32").AsSpan();
Span<byte> Ips32TailMagic = Encoding.ASCII.GetBytes("EEOF").AsSpan();
Span<byte> Ips32TailMagic = Encoding.ASCII.GetBytes("EEOF").AsSpan();
MemPatch patches = new MemPatch();
var header = reader.ReadBytes(IpsHeaderMagic.Length).AsSpan();
@ -68,7 +68,7 @@ namespace Ryujinx.HLE.Loaders.Mods
}
int patchOffset = is32 ? buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]
: buf[0] << 16 | buf[1] << 8 | buf[2];
: buf[0] << 16 | buf[1] << 8 | buf[2];
if (ReadNext(2))
{

View File

@ -7,11 +7,19 @@ namespace Ryujinx.HLE.Loaders.Mods
{
class IPSwitchPatcher
{
readonly StreamReader _reader;
public string BuildId { get; }
const string BidHeader = "@nsobid-";
private enum Token
{
Normal,
String,
EscapeChar,
Comment
}
private readonly StreamReader _reader;
public string BuildId { get; }
public IPSwitchPatcher(StreamReader reader)
{
string header = reader.ReadLine();
@ -26,14 +34,6 @@ namespace Ryujinx.HLE.Loaders.Mods
BuildId = header.Substring(BidHeader.Length).TrimEnd().TrimEnd('0');
}
private enum Token
{
Normal,
String,
EscapeChar,
Comment
}
// Uncomments line and unescapes C style strings within
private static string PreprocessLine(string line)
{
@ -56,24 +56,24 @@ namespace Ryujinx.HLE.Loaders.Mods
case Token.String:
state = c switch
{
'"' => Token.Normal,
'"' => Token.Normal,
'\\' => Token.EscapeChar,
_ => Token.String
_ => Token.String
};
break;
case Token.EscapeChar:
state = Token.String;
c = c switch
{
'a' => '\a',
'b' => '\b',
'f' => '\f',
'n' => '\n',
'r' => '\r',
't' => '\t',
'v' => '\v',
'a' => '\a',
'b' => '\b',
'f' => '\f',
'n' => '\n',
'r' => '\r',
't' => '\t',
'v' => '\v',
'\\' => '\\',
_ => '?'
_ => '?'
};
break;
}
@ -119,7 +119,8 @@ namespace Ryujinx.HLE.Loaders.Mods
for (int i = 0; i < hexstr.Length; i += 2)
{
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);
}
@ -131,11 +132,11 @@ namespace Ryujinx.HLE.Loaders.Mods
{
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
{
return Int32.TryParse(str, System.Globalization.NumberStyles.Integer, null, out value);
return int.TryParse(str, System.Globalization.NumberStyles.Integer, null, out value);
}
}
@ -148,7 +149,7 @@ namespace Ryujinx.HLE.Loaders.Mods
MemPatch patches = new MemPatch();
bool enabled = false;
bool enabled = false;
bool printValues = false;
int offset_shift = 0;
@ -236,7 +237,7 @@ namespace Ryujinx.HLE.Loaders.Mods
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();

View File

@ -1,10 +1,8 @@
using Ryujinx.Cpu;
using Ryujinx.Common.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using Ryujinx.Common.Logging;
namespace Ryujinx.HLE.Loaders.Mods
{
public class MemPatch
@ -71,7 +69,7 @@ namespace Ryujinx.HLE.Loaders.Mods
foreach (var (offset, patch) in _patches.OrderBy(item => item.Key))
{
int patchOffset = (int)offset;
int patchSize = patch.Length;
int patchSize = patch.Length;
if (patchOffset < protectedOffset || patchOffset > memory.Length)
{
@ -82,7 +80,7 @@ namespace Ryujinx.HLE.Loaders.Mods
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}");

View File

@ -5,12 +5,12 @@ namespace Ryujinx.HLE
{
public enum MemoryConfiguration
{
MemoryConfiguration4GB = 0,
MemoryConfiguration4GB = 0,
MemoryConfiguration4GBAppletDev = 1,
MemoryConfiguration4GBSystemDev = 2,
MemoryConfiguration6GB = 3,
MemoryConfiguration6GB = 3,
MemoryConfiguration6GBAppletDev = 4,
MemoryConfiguration8GB = 5
MemoryConfiguration8GB = 5
}
static class MemoryConfigurationExtensions
@ -21,12 +21,12 @@ namespace Ryujinx.HLE
{
return configuration switch
{
MemoryConfiguration.MemoryConfiguration4GB => MemoryArrange.MemoryArrange4GB,
MemoryConfiguration.MemoryConfiguration4GB => MemoryArrange.MemoryArrange4GB,
MemoryConfiguration.MemoryConfiguration4GBAppletDev => MemoryArrange.MemoryArrange4GBAppletDev,
MemoryConfiguration.MemoryConfiguration4GBSystemDev => MemoryArrange.MemoryArrange4GBSystemDev,
MemoryConfiguration.MemoryConfiguration6GB => MemoryArrange.MemoryArrange6GB,
MemoryConfiguration.MemoryConfiguration6GB => MemoryArrange.MemoryArrange6GB,
MemoryConfiguration.MemoryConfiguration6GBAppletDev => MemoryArrange.MemoryArrange6GBAppletDev,
MemoryConfiguration.MemoryConfiguration8GB => MemoryArrange.MemoryArrange8GB,
MemoryConfiguration.MemoryConfiguration8GB => MemoryArrange.MemoryArrange8GB,
_ => throw new AggregateException($"Invalid memory configuration \"{configuration}\".")
};
}
@ -40,7 +40,7 @@ namespace Ryujinx.HLE
MemoryConfiguration.MemoryConfiguration4GBSystemDev => MemorySize.MemorySize4GB,
MemoryConfiguration.MemoryConfiguration6GB or
MemoryConfiguration.MemoryConfiguration6GBAppletDev => MemorySize.MemorySize6GB,
MemoryConfiguration.MemoryConfiguration8GB => MemorySize.MemorySize8GB,
MemoryConfiguration.MemoryConfiguration8GB => MemorySize.MemorySize8GB,
_ => throw new AggregateException($"Invalid memory configuration \"{configuration}\".")
};
}
@ -54,7 +54,7 @@ namespace Ryujinx.HLE
MemoryConfiguration.MemoryConfiguration4GBSystemDev => 4 * Gb,
MemoryConfiguration.MemoryConfiguration6GB or
MemoryConfiguration.MemoryConfiguration6GBAppletDev => 6 * Gb,
MemoryConfiguration.MemoryConfiguration8GB => 8 * Gb,
MemoryConfiguration.MemoryConfiguration8GB => 8 * Gb,
_ => throw new AggregateException($"Invalid memory configuration \"{configuration}\".")
};
}

View File

@ -1,5 +1,4 @@
using Ryujinx.Common;
using System.Diagnostics;
using System.Timers;
namespace Ryujinx.HLE
@ -7,9 +6,8 @@ namespace Ryujinx.HLE
public class PerformanceStatistics
{
private const double FrameRateWeight = 0.5;
private const int FrameTypeGame = 0;
private const int PercentTypeFifo = 0;
private const int FrameTypeGame = 0;
private const int PercentTypeFifo = 0;
private double[] _averageFrameRate;
private double[] _accumulatedFrameTime;
@ -50,7 +48,6 @@ namespace Ryujinx.HLE
_resetTimer = new Timer(1000);
_resetTimer.Elapsed += ResetTimerElapsed;
_resetTimer.AutoReset = true;
_resetTimer.Start();
@ -75,10 +72,8 @@ namespace Ryujinx.HLE
frameRate = _framesRendered[frameType] / _accumulatedFrameTime[frameType];
}
_averageFrameRate[frameType] = LinearInterpolate(_averageFrameRate[frameType], frameRate);
_framesRendered[frameType] = 0;
_averageFrameRate[frameType] = LinearInterpolate(_averageFrameRate[frameType], frameRate);
_framesRendered[frameType] = 0;
_accumulatedFrameTime[frameType] = 0;
}
}
@ -96,15 +91,13 @@ namespace Ryujinx.HLE
percent = (_accumulatedActiveTime[percentType] / _percentTime[percentType]) * 100;
}
_averagePercent[percentType] = percent;
_percentTime[percentType] = 0;
_averagePercent[percentType] = percent;
_percentTime[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;
}
@ -133,26 +126,23 @@ namespace Ryujinx.HLE
private void EndPercentTime(int percentType)
{
double currentTime = PerformanceCounter.ElapsedTicks * _ticksToSeconds;
double elapsedTime = currentTime - _percentLastEndTime[percentType];
double currentTime = PerformanceCounter.ElapsedTicks * _ticksToSeconds;
double elapsedTime = currentTime - _percentLastEndTime[percentType];
double elapsedActiveTime = currentTime - _percentStartTime[percentType];
lock (_percentLock[percentType])
{
_accumulatedActiveTime[percentType] += elapsedActiveTime;
_percentTime[percentType] += elapsedTime;
_percentTime[percentType] += elapsedTime;
}
_percentLastEndTime[percentType] = currentTime;
_percentStartTime[percentType] = 0;
_percentStartTime[percentType] = 0;
}
private void RecordFrameTime(int frameType)
{
double currentFrameTime = PerformanceCounter.ElapsedTicks * _ticksToSeconds;
double elapsedFrameTime = currentFrameTime - _previousFrameTime[frameType];
_previousFrameTime[frameType] = currentFrameTime;

View File

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

View File

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

View File

@ -12,7 +12,7 @@ namespace Ryujinx.HLE.Utilities
{
public static byte[] GetFixedLengthBytes(string inputString, int size, Encoding encoding)
{
inputString = inputString + "\0";
inputString += "\0";
int bytesCount = encoding.GetByteCount(inputString);
@ -76,8 +76,8 @@ namespace Ryujinx.HLE.Utilities
public static U8Span ReadUtf8Span(ServiceCtx context, int index = 0)
{
ulong position = (ulong)context.Request.PtrBuff[index].Position;
ulong size = (ulong)context.Request.PtrBuff[index].Size;
ulong position = context.Request.PtrBuff[index].Position;
ulong size = context.Request.PtrBuff[index].Size;
ReadOnlySpan<byte> buffer = context.Memory.GetSpan(position, (int)size);
@ -93,7 +93,7 @@ namespace Ryujinx.HLE.Utilities
{
while (size-- > 0)
{
byte value = context.Memory.Read<byte>((ulong)position++);
byte value = context.Memory.Read<byte>(position++);
if (value == 0)
{

View File

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

View File

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