diff --git a/Ryujinx.Graphics.Gpu/NvGpuFifo.cs b/Ryujinx.Graphics.Gpu/NvGpuFifo.cs index e1b9a61bc1..36a275e291 100644 --- a/Ryujinx.Graphics.Gpu/NvGpuFifo.cs +++ b/Ryujinx.Graphics.Gpu/NvGpuFifo.cs @@ -82,9 +82,6 @@ namespace Ryujinx.Graphics.Gpu } } - private int _currMacroPosition; - private int _currMacroBindIndex; - private ShadowRamControl _shadowCtrl; private CachedMacro[] _macros; diff --git a/Ryujinx.HLE/HOS/ApplicationLoader.cs b/Ryujinx.HLE/HOS/ApplicationLoader.cs index f6ab5ba99a..bc7016bda2 100644 --- a/Ryujinx.HLE/HOS/ApplicationLoader.cs +++ b/Ryujinx.HLE/HOS/ApplicationLoader.cs @@ -415,13 +415,13 @@ namespace Ryujinx.HLE.HOS bool isNro = Path.GetExtension(filePath).ToLower() == ".nro"; - IExecutable nro; + IExecutable executable; if (isNro) { FileStream input = new FileStream(filePath, FileMode.Open); NroExecutable obj = new NroExecutable(input); - nro = obj; + executable = obj; // homebrew NRO can actually have some data after the actual NRO if (input.Length > obj.FileSize) @@ -493,7 +493,7 @@ namespace Ryujinx.HLE.HOS } else { - nro = new NsoExecutable(new LocalStorage(filePath, FileAccess.Read)); + executable = new NsoExecutable(new LocalStorage(filePath, FileAccess.Read)); } _contentManager.LoadEntries(_device); @@ -502,7 +502,7 @@ namespace Ryujinx.HLE.HOS TitleId = metaData.Aci0.TitleId; TitleIs64Bit = metaData.Is64Bit; - ProgramLoader.LoadNsos(_device.System.KernelContext, metaData, executables: nro); + ProgramLoader.LoadNsos(_device.System.KernelContext, metaData, executables: executable); } private Npdm GetDefaultNpdm() diff --git a/Ryujinx.HLE/HOS/ProgramLoader.cs b/Ryujinx.HLE/HOS/ProgramLoader.cs index 1158925ab7..cf5b15bac4 100644 --- a/Ryujinx.HLE/HOS/ProgramLoader.cs +++ b/Ryujinx.HLE/HOS/ProgramLoader.cs @@ -32,7 +32,7 @@ namespace Ryujinx.HLE.HOS int codePagesCount = codeSize / KMemoryManager.PageSize; - ulong codeBaseAddress = (kip.Header.Flags & 0x10) != 0 ? 0x8000000UL : 0x200000UL; + ulong codeBaseAddress = kip.Is64BitAddressSpace ? 0x8000000UL : 0x200000UL; ulong codeAddress = codeBaseAddress + (ulong)kip.TextOffset; @@ -45,27 +45,27 @@ namespace Ryujinx.HLE.HOS mmuFlags |= 0x20; } - if ((kip.Header.Flags & 0x10) != 0) + if (kip.Is64BitAddressSpace) { mmuFlags |= (int)AddressSpaceType.Addr39Bits << 1; } - if ((kip.Header.Flags & 0x08) != 0) + if (kip.Is64Bit) { mmuFlags |= 1; } ProcessCreationInfo creationInfo = new ProcessCreationInfo( - kip.Header.Name, - kip.Header.ProcessCategory, - kip.Header.TitleId, + kip.Name, + kip.Version, + kip.ProgramId, codeAddress, codePagesCount, mmuFlags, 0, 0); - MemoryRegion memoryRegion = (kip.Header.Flags & 0x20) != 0 + MemoryRegion memoryRegion = kip.UsesSecureMemory ? MemoryRegion.Service : MemoryRegion.Application; @@ -105,9 +105,9 @@ namespace Ryujinx.HLE.HOS return false; } - process.DefaultCpuCore = kip.Header.DefaultCore; + process.DefaultCpuCore = kip.IdealCoreId; - result = process.Start(kip.Header.MainThreadPriority, (ulong)kip.Header.Sections[1].Attribute); + result = process.Start(kip.Priority, (ulong)kip.StackSize); if (result != KernelResult.Success) { diff --git a/Ryujinx.HLE/HOS/Services/Bluetooth/IBluetoothDriver.cs b/Ryujinx.HLE/HOS/Services/Bluetooth/IBluetoothDriver.cs index 8bbf26b26b..d94030fab4 100644 --- a/Ryujinx.HLE/HOS/Services/Bluetooth/IBluetoothDriver.cs +++ b/Ryujinx.HLE/HOS/Services/Bluetooth/IBluetoothDriver.cs @@ -9,9 +9,9 @@ namespace Ryujinx.HLE.HOS.Services.Bluetooth [Service("btdrv")] class IBluetoothDriver : IpcService { -#pragma warning disable CS0169 +#pragma warning disable CS0414 private string _unknownLowEnergy; -#pragma warning restore CS0169 +#pragma warning restore CS0414 public IBluetoothDriver(ServiceCtx context) { } diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs index 246c92bdef..3bdf15a1af 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs @@ -32,7 +32,9 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager return ResultCode.Success; } +#pragma warning disable CS0162 return ResultCode.NullOutputObject; +#pragma warning restore CS0162 } } diff --git a/Ryujinx.HLE/Loaders/Executables/KipExecutable.cs b/Ryujinx.HLE/Loaders/Executables/KipExecutable.cs index 9f04cf4e43..0f1309c028 100644 --- a/Ryujinx.HLE/Loaders/Executables/KipExecutable.cs +++ b/Ryujinx.HLE/Loaders/Executables/KipExecutable.cs @@ -1,35 +1,76 @@ -using LibHac; using LibHac.Fs; -using System.IO; +using LibHac.Loader; namespace Ryujinx.HLE.Loaders.Executables { - class KipExecutable : Kip, IExecutable + class KipExecutable : IExecutable { public byte[] Text { get; } public byte[] Ro { get; } public byte[] Data { get; } - public int TextOffset => Header.Sections[0].OutOffset; - public int RoOffset => Header.Sections[1].OutOffset; - public int DataOffset => Header.Sections[2].OutOffset; - public int BssOffset => Header.Sections[3].OutOffset; - public int BssSize => Header.Sections[3].DecompressedSize; + public int TextOffset { get; } + public int RoOffset { get; } + public int DataOffset { get; } + public int BssOffset { get; } + public int BssSize { 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 KipExecutable(IStorage inStorage) : base(inStorage) + public KipExecutable(IStorage inStorage) { + KipReader reader = new KipReader(); + + reader.Initialize(inStorage).ThrowIfFailure(); + + TextOffset = reader.Segments[0].MemoryOffset; + RoOffset = reader.Segments[1].MemoryOffset; + DataOffset = reader.Segments[2].MemoryOffset; + BssOffset = reader.Segments[3].MemoryOffset; + BssSize = reader.Segments[3].Size; + + StackSize = reader.StackSize; + + UsesSecureMemory = reader.UsesSecureMemory; + Is64BitAddressSpace = reader.Is64BitAddressSpace; + Is64Bit = reader.Is64Bit; + + ProgramId = reader.ProgramId; + Priority = reader.Priority; + IdealCoreId = reader.IdealCoreId; + Version = reader.Version; + Name = reader.Name.ToString(); + Capabilities = new int[32]; for (int index = 0; index < Capabilities.Length; index++) { - Capabilities[index] = System.BitConverter.ToInt32(Header.Capabilities, index * 4); + Capabilities[index] = (int)reader.Capabilities[index]; } - Text = DecompressSection(0); - Ro = DecompressSection(1); - Data = DecompressSection(2); + Text = DecompressSection(reader, KipReader.SegmentType.Text); + Ro = DecompressSection(reader, KipReader.SegmentType.Ro); + Data = DecompressSection(reader, KipReader.SegmentType.Data); + } + + private static byte[] DecompressSection(KipReader reader, KipReader.SegmentType segmentType) + { + reader.GetSegmentSize(segmentType, out int uncompressedSize).ThrowIfFailure(); + + byte[] result = new byte[uncompressedSize]; + + reader.ReadSegment(segmentType, result).ThrowIfFailure(); + + return result; } } } \ No newline at end of file diff --git a/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs b/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs index 6050432d0e..bbe2c87fe2 100644 --- a/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs +++ b/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs @@ -1,28 +1,47 @@ -using LibHac; using LibHac.Fs; -using System; -using System.IO; +using LibHac.FsSystem; +using LibHac.Loader; namespace Ryujinx.HLE.Loaders.Executables { - class NsoExecutable : Nso, IExecutable + class NsoExecutable : IExecutable { public byte[] Text { get; } public byte[] Ro { get; } public byte[] Data { get; } - public int TextOffset => (int)Sections[0].MemoryOffset; - public int RoOffset => (int)Sections[1].MemoryOffset; - public int DataOffset => (int)Sections[2].MemoryOffset; + public int TextOffset { get; } + public int RoOffset { get; } + public int DataOffset { get; } public int BssOffset => DataOffset + Data.Length; - public new int BssSize => (int)base.BssSize; + public int BssSize { get; } - public NsoExecutable(IStorage inStorage) : base(inStorage) + public NsoExecutable(IStorage inStorage) { - Text = Sections[0].DecompressSection(); - Ro = Sections[1].DecompressSection(); - Data = Sections[2].DecompressSection(); + NsoReader reader = new NsoReader(); + + reader.Initialize(inStorage.AsFile(OpenMode.Read)).ThrowIfFailure(); + + TextOffset = (int)reader.Header.Segments[0].MemoryOffset; + RoOffset = (int)reader.Header.Segments[1].MemoryOffset; + DataOffset = (int)reader.Header.Segments[2].MemoryOffset; + BssSize = (int)reader.Header.BssSize; + + Text = DecompressSection(reader, NsoReader.SegmentType.Text); + Ro = DecompressSection(reader, NsoReader.SegmentType.Ro); + Data = DecompressSection(reader, NsoReader.SegmentType.Data); + } + + private static byte[] DecompressSection(NsoReader reader, NsoReader.SegmentType segmentType) + { + reader.GetSegmentSize(segmentType, out uint uncompressedSize).ThrowIfFailure(); + + byte[] result = new byte[uncompressedSize]; + + reader.ReadSegment(segmentType, result).ThrowIfFailure(); + + return result; } } } \ No newline at end of file