Compare commits

..

8 Commits

Author SHA1 Message Date
e3b36db71c hle: Some cleanup (#3210)
* hle: Some cleanup

This PR cleaned up a bit the HLE folder and the VirtualFileSystem one, since we use LibHac, we can use some class of it directly instead of duplicate things. The "Content" of VFS folder is removed since it should be handled in the NCM service directly.
A larger cleanup should be done later since there is still be duplicated code here and there.

* Fix Headless.SDL2

* Addresses gdkchan feedback
2022-03-22 20:46:16 +01:00
ba0171d054 Memory.Tests: Make Multithreading test explicit (#3220) 2022-03-21 09:21:05 +01:00
d1146a5af2 Don't restore Viewport 0 if it hasn't been set yet. (#3219)
Fixes a driver crash when starting some games caused by #3217
2022-03-20 14:48:43 -03:00
79408b68c3 De-tile GOB when DMA copying from block linear to pitch kind memory regions (#3207)
* De-tile GOB when DMA copying from block linear to pitch kind memory regions

* XML docs + nits

* Remove using

* No flush for regular buffer copies

* Add back ulong casts, fix regression due to oversight
2022-03-20 13:55:07 -03:00
d461d4f68b Fix OpenGL issues with RTSS overlays and OBS Game Capture (#3217)
OpenGL game overlays and hooks tend to make a lot of assumptions about how games present frames to the screen, since presentation in OpenGL kind of sucks and they would like to have info such as the size of the screen, or if the contents are SRGB rather than linear.

There are two ways of getting this. OBS hooks swap buffers to get a frame for video capture, but it actually checks the bound framebuffer at the time. I made sure that this matches the output framebuffer (the window) so that the output matches the size. RTSS checks the viewport size by default, but this was actually set to the last used viewport by the game, causing the OSD to fly all across the screen depending on how it was used (or res scale). The viewport is now manually set to match the output framebuffer size.

In the case of RTSS, it also loads its resources by destructively setting a pixel pack parameter without regard to what it was set to by the guest application. OpenGL state can be set for a long period of time and is not expected to be set before each call to a method, so randomly changing it isn't great practice. To fix this, I've added a line to set the pixel unpack alignment back to 4 after presentation, which should cover RTSS loading its incredibly ugly font.

- RTSS and overlays that use it should no longer cause certain textures to load incorrectly. (mario kart 8, pokemon legends arceus)
- OBS Game Capture should no longer crop the game output incorrectly, flicker randomly, or capture with incorrect gamma.

This doesn't fix issues with how RTSS reports our frame timings.
2022-03-20 13:37:45 -03:00
b45d30acf8 oslc: Fix condition in GetSaveDataBackupSetting (#3208)
* oslc: Fix condition in GetSaveDataBackupSetting

This PR fixes a condition previously implemented in #3190 where ACNH can't be booted without an existing savedata.
Closes #3206

* Addresses gdkchan feedback
2022-03-20 13:25:29 -03:00
df70442c46 InstEmitMemoryEx: Barrier after write on ordered store (#3193)
* InstEmitMemoryEx: Barrier after write on ordered store

* increment ptc version

* 32
2022-03-19 10:32:35 -03:00
e2ffa5a125 ntc: Implement IEnsureNetworkClockAvailabilityService (#3192)
* ntc: Implement IEnsureNetworkClockAvailabilityService

This PR implement a basic `IEnsureNetworkClockAvailabilityService` checked by RE. It's needed by Splatoon 2 with Guest Internet Access enabled. Game is now playable with this setting.

* Update Ryujinx.HLE/HOS/Services/Nim/Ntc/StaticService/IEnsureNetworkClockAvailabilityService.cs

Co-authored-by: gdkchan <gab.dark.100@gmail.com>

Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2022-03-15 04:07:07 +01:00
54 changed files with 775 additions and 435 deletions

View File

@ -130,11 +130,6 @@ namespace ARMeilleure.Instructions
bool ordered = (accType & AccessType.Ordered) != 0;
bool exclusive = (accType & AccessType.Exclusive) != 0;
if (ordered)
{
EmitBarrier(context);
}
Operand address = context.Copy(GetIntOrSP(context, op.Rn));
Operand t = GetIntOrZR(context, op.Rt);
@ -163,6 +158,11 @@ namespace ARMeilleure.Instructions
{
EmitStoreExclusive(context, address, t, exclusive, op.Size, op.Rs, a32: false);
}
if (ordered)
{
EmitBarrier(context);
}
}
private static void EmitBarrier(ArmEmitterContext context)

View File

@ -146,13 +146,13 @@ namespace ARMeilleure.Instructions
var exclusive = (accType & AccessType.Exclusive) != 0;
var ordered = (accType & AccessType.Ordered) != 0;
if (ordered)
{
EmitBarrier(context);
}
if ((accType & AccessType.Load) != 0)
{
if (ordered)
{
EmitBarrier(context);
}
if (size == DWordSizeLog2)
{
// Keep loads atomic - make the call to get the whole region and then decompose it into parts
@ -219,6 +219,11 @@ namespace ARMeilleure.Instructions
Operand value = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rt));
EmitStoreExclusive(context, address, value, exclusive, size, op.Rd, a32: true);
}
if (ordered)
{
EmitBarrier(context);
}
}
}

View File

@ -27,7 +27,7 @@ namespace ARMeilleure.Translation.PTC
private const string OuterHeaderMagicString = "PTCohd\0\0";
private const string InnerHeaderMagicString = "PTCihd\0\0";
private const uint InternalVersion = 3179; //! To be incremented manually for each change to the ARMeilleure project.
private const uint InternalVersion = 3193; //! To be incremented manually for each change to the ARMeilleure project.
private const string ActualDir = "0";
private const string BackupDir = "1";

View File

@ -47,6 +47,7 @@ namespace Ryujinx.Common.Logging
ServiceNim,
ServiceNs,
ServiceNsd,
ServiceNtc,
ServiceNv,
ServiceOlsc,
ServicePctl,

View File

@ -1,7 +1,7 @@
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Device;
using Ryujinx.Graphics.Gpu.Engine.Threed;
using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.Graphics.Texture;
using System;
using System.Collections.Generic;
@ -330,11 +330,95 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
{
// TODO: Implement remap functionality.
// Buffer to buffer copy.
memoryManager.Physical.BufferCache.CopyBuffer(memoryManager, srcGpuVa, dstGpuVa, size);
bool srcIsPitchKind = memoryManager.GetKind(srcGpuVa).IsPitch();
bool dstIsPitchKind = memoryManager.GetKind(dstGpuVa).IsPitch();
if (!srcIsPitchKind && dstIsPitchKind)
{
CopyGobBlockLinearToLinear(memoryManager, srcGpuVa, dstGpuVa, size);
}
else if (srcIsPitchKind && !dstIsPitchKind)
{
CopyGobLinearToBlockLinear(memoryManager, srcGpuVa, dstGpuVa, size);
}
else
{
memoryManager.Physical.BufferCache.CopyBuffer(memoryManager, srcGpuVa, dstGpuVa, size);
}
}
}
}
/// <summary>
/// Copies block linear data with block linear GOBs to a block linear destination with linear GOBs.
/// </summary>
/// <param name="memoryManager">GPU memory manager</param>
/// <param name="srcGpuVa">Source GPU virtual address</param>
/// <param name="dstGpuVa">Destination GPU virtual address</param>
/// <param name="size">Size in bytes of the copy</param>
private static void CopyGobBlockLinearToLinear(MemoryManager memoryManager, ulong srcGpuVa, ulong dstGpuVa, ulong size)
{
if (((srcGpuVa | dstGpuVa | size) & 0xf) == 0)
{
for (ulong offset = 0; offset < size; offset += 16)
{
Vector128<byte> data = memoryManager.Read<Vector128<byte>>(ConvertGobLinearToBlockLinearAddress(srcGpuVa + offset), true);
memoryManager.Write(dstGpuVa + offset, data);
}
}
else
{
for (ulong offset = 0; offset < size; offset++)
{
byte data = memoryManager.Read<byte>(ConvertGobLinearToBlockLinearAddress(srcGpuVa + offset), true);
memoryManager.Write(dstGpuVa + offset, data);
}
}
}
/// <summary>
/// Copies block linear data with linear GOBs to a block linear destination with block linear GOBs.
/// </summary>
/// <param name="memoryManager">GPU memory manager</param>
/// <param name="srcGpuVa">Source GPU virtual address</param>
/// <param name="dstGpuVa">Destination GPU virtual address</param>
/// <param name="size">Size in bytes of the copy</param>
private static void CopyGobLinearToBlockLinear(MemoryManager memoryManager, ulong srcGpuVa, ulong dstGpuVa, ulong size)
{
if (((srcGpuVa | dstGpuVa | size) & 0xf) == 0)
{
for (ulong offset = 0; offset < size; offset += 16)
{
Vector128<byte> data = memoryManager.Read<Vector128<byte>>(srcGpuVa + offset, true);
memoryManager.Write(ConvertGobLinearToBlockLinearAddress(dstGpuVa + offset), data);
}
}
else
{
for (ulong offset = 0; offset < size; offset++)
{
byte data = memoryManager.Read<byte>(srcGpuVa + offset, true);
memoryManager.Write(ConvertGobLinearToBlockLinearAddress(dstGpuVa + offset), data);
}
}
}
/// <summary>
/// Calculates the GOB block linear address from a linear address.
/// </summary>
/// <param name="address">Linear address</param>
/// <returns>Block linear address</returns>
private static ulong ConvertGobLinearToBlockLinearAddress(ulong address)
{
// y2 y1 y0 x5 x4 x3 x2 x1 x0 -> x5 y2 y1 x4 y0 x3 x2 x1 x0
return (address & ~0x1f0UL) |
((address & 0x40) >> 2) |
((address & 0x10) << 1) |
((address & 0x180) >> 1) |
((address & 0x20) << 3);
}
/// <summary>
/// Performs a buffer to buffer, or buffer to texture copy, then optionally releases a semaphore.
/// </summary>

View File

@ -7,7 +7,6 @@ using Ryujinx.Graphics.Gpu.Engine.Types;
using Ryujinx.Graphics.Gpu.Image;
using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.Graphics.Texture;
using Ryujinx.Memory;
using Ryujinx.Memory.Range;
using System;
using System.Collections.Generic;

View File

@ -264,7 +264,8 @@ namespace Ryujinx.Graphics.Gpu.Memory
/// <param name="pa">CPU virtual address to map into</param>
/// <param name="va">GPU virtual address to be mapped</param>
/// <param name="size">Size in bytes of the mapping</param>
public void Map(ulong pa, ulong va, ulong size)
/// <param name="kind">Kind of the resource located at the mapping</param>
public void Map(ulong pa, ulong va, ulong size, PteKind kind)
{
lock (_pageTable)
{
@ -272,7 +273,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
for (ulong offset = 0; offset < size; offset += PageSize)
{
SetPte(va + offset, pa + offset);
SetPte(va + offset, PackPte(pa + offset, kind));
}
}
}
@ -462,14 +463,37 @@ namespace Ryujinx.Graphics.Gpu.Memory
return PteUnmapped;
}
ulong baseAddress = GetPte(va);
ulong pte = GetPte(va);
if (baseAddress == PteUnmapped)
if (pte == PteUnmapped)
{
return PteUnmapped;
}
return baseAddress + (va & PageMask);
return UnpackPaFromPte(pte) + (va & PageMask);
}
/// <summary>
/// Gets the kind of a given memory page.
/// This might indicate the type of resource that can be allocated on the page, and also texture tiling.
/// </summary>
/// <param name="va">GPU virtual address</param>
/// <returns>Kind of the memory page</returns>
public PteKind GetKind(ulong va)
{
if (!ValidateAddress(va))
{
return PteKind.Invalid;
}
ulong pte = GetPte(va);
if (pte == PteUnmapped)
{
return PteKind.Invalid;
}
return UnpackKindFromPte(pte);
}
/// <summary>
@ -512,5 +536,36 @@ namespace Ryujinx.Graphics.Gpu.Memory
_pageTable[l0][l1] = pte;
}
/// <summary>
/// Creates a page table entry from a physical address and kind.
/// </summary>
/// <param name="pa">Physical address</param>
/// <param name="kind">Kind</param>
/// <returns>Page table entry</returns>
private static ulong PackPte(ulong pa, PteKind kind)
{
return pa | ((ulong)kind << 56);
}
/// <summary>
/// Unpacks kind from a page table entry.
/// </summary>
/// <param name="pte">Page table entry</param>
/// <returns>Kind</returns>
private static PteKind UnpackKindFromPte(ulong pte)
{
return (PteKind)(pte >> 56);
}
/// <summary>
/// Unpacks physical address from a page table entry.
/// </summary>
/// <param name="pte">Page table entry</param>
/// <returns>Physical address</returns>
private static ulong UnpackPaFromPte(ulong pte)
{
return pte & 0xffffffffffffffUL;
}
}
}

View File

@ -0,0 +1,268 @@
namespace Ryujinx.Graphics.Gpu.Memory
{
/// <summary>
/// Kind of the resource at the given memory mapping.
/// </summary>
public enum PteKind : byte
{
Invalid = 0xff,
Pitch = 0x00,
Z16 = 0x01,
Z162C = 0x02,
Z16MS22C = 0x03,
Z16MS42C = 0x04,
Z16MS82C = 0x05,
Z16MS162C = 0x06,
Z162Z = 0x07,
Z16MS22Z = 0x08,
Z16MS42Z = 0x09,
Z16MS82Z = 0x0a,
Z16MS162Z = 0x0b,
Z162CZ = 0x36,
Z16MS22CZ = 0x37,
Z16MS42CZ = 0x38,
Z16MS82CZ = 0x39,
Z16MS162CZ = 0x5f,
Z164CZ = 0x0c,
Z16MS24CZ = 0x0d,
Z16MS44CZ = 0x0e,
Z16MS84CZ = 0x0f,
Z16MS164CZ = 0x10,
S8Z24 = 0x11,
S8Z241Z = 0x12,
S8Z24MS21Z = 0x13,
S8Z24MS41Z = 0x14,
S8Z24MS81Z = 0x15,
S8Z24MS161Z = 0x16,
S8Z242CZ = 0x17,
S8Z24MS22CZ = 0x18,
S8Z24MS42CZ = 0x19,
S8Z24MS82CZ = 0x1a,
S8Z24MS162CZ = 0x1b,
S8Z242CS = 0x1c,
S8Z24MS22CS = 0x1d,
S8Z24MS42CS = 0x1e,
S8Z24MS82CS = 0x1f,
S8Z24MS162CS = 0x20,
S8Z244CSZV = 0x21,
S8Z24MS24CSZV = 0x22,
S8Z24MS44CSZV = 0x23,
S8Z24MS84CSZV = 0x24,
S8Z24MS164CSZV = 0x25,
V8Z24MS4VC12 = 0x26,
V8Z24MS4VC4 = 0x27,
V8Z24MS8VC8 = 0x28,
V8Z24MS8VC24 = 0x29,
V8Z24MS4VC121ZV = 0x2e,
V8Z24MS4VC41ZV = 0x2f,
V8Z24MS8VC81ZV = 0x30,
V8Z24MS8VC241ZV = 0x31,
V8Z24MS4VC122CS = 0x32,
V8Z24MS4VC42CS = 0x33,
V8Z24MS8VC82CS = 0x34,
V8Z24MS8VC242CS = 0x35,
V8Z24MS4VC122CZV = 0x3a,
V8Z24MS4VC42CZV = 0x3b,
V8Z24MS8VC82CZV = 0x3c,
V8Z24MS8VC242CZV = 0x3d,
V8Z24MS4VC122ZV = 0x3e,
V8Z24MS4VC42ZV = 0x3f,
V8Z24MS8VC82ZV = 0x40,
V8Z24MS8VC242ZV = 0x41,
V8Z24MS4VC124CSZV = 0x42,
V8Z24MS4VC44CSZV = 0x43,
V8Z24MS8VC84CSZV = 0x44,
V8Z24MS8VC244CSZV = 0x45,
Z24S8 = 0x46,
Z24S81Z = 0x47,
Z24S8MS21Z = 0x48,
Z24S8MS41Z = 0x49,
Z24S8MS81Z = 0x4a,
Z24S8MS161Z = 0x4b,
Z24S82CS = 0x4c,
Z24S8MS22CS = 0x4d,
Z24S8MS42CS = 0x4e,
Z24S8MS82CS = 0x4f,
Z24S8MS162CS = 0x50,
Z24S82CZ = 0x51,
Z24S8MS22CZ = 0x52,
Z24S8MS42CZ = 0x53,
Z24S8MS82CZ = 0x54,
Z24S8MS162CZ = 0x55,
Z24S84CSZV = 0x56,
Z24S8MS24CSZV = 0x57,
Z24S8MS44CSZV = 0x58,
Z24S8MS84CSZV = 0x59,
Z24S8MS164CSZV = 0x5a,
Z24V8MS4VC12 = 0x5b,
Z24V8MS4VC4 = 0x5c,
Z24V8MS8VC8 = 0x5d,
Z24V8MS8VC24 = 0x5e,
YUVB8C12Y = 0x60,
YUVB8C22Y = 0x61,
YUVB10C12Y = 0x62,
YUVB10C22Y = 0x6b,
YUVB12C12Y = 0x6c,
YUVB12C22Y = 0x6d,
Z24V8MS4VC121ZV = 0x63,
Z24V8MS4VC41ZV = 0x64,
Z24V8MS8VC81ZV = 0x65,
Z24V8MS8VC241ZV = 0x66,
Z24V8MS4VC122CS = 0x67,
Z24V8MS4VC42CS = 0x68,
Z24V8MS8VC82CS = 0x69,
Z24V8MS8VC242CS = 0x6a,
Z24V8MS4VC122CZV = 0x6f,
Z24V8MS4VC42CZV = 0x70,
Z24V8MS8VC82CZV = 0x71,
Z24V8MS8VC242CZV = 0x72,
Z24V8MS4VC122ZV = 0x73,
Z24V8MS4VC42ZV = 0x74,
Z24V8MS8VC82ZV = 0x75,
Z24V8MS8VC242ZV = 0x76,
Z24V8MS4VC124CSZV = 0x77,
Z24V8MS4VC44CSZV = 0x78,
Z24V8MS8VC84CSZV = 0x79,
Z24V8MS8VC244CSZV = 0x7a,
ZF32 = 0x7b,
ZF321Z = 0x7c,
ZF32MS21Z = 0x7d,
ZF32MS41Z = 0x7e,
ZF32MS81Z = 0x7f,
ZF32MS161Z = 0x80,
ZF322CS = 0x81,
ZF32MS22CS = 0x82,
ZF32MS42CS = 0x83,
ZF32MS82CS = 0x84,
ZF32MS162CS = 0x85,
ZF322CZ = 0x86,
ZF32MS22CZ = 0x87,
ZF32MS42CZ = 0x88,
ZF32MS82CZ = 0x89,
ZF32MS162CZ = 0x8a,
X8Z24X16V8S8MS4VC12 = 0x8b,
X8Z24X16V8S8MS4VC4 = 0x8c,
X8Z24X16V8S8MS8VC8 = 0x8d,
X8Z24X16V8S8MS8VC24 = 0x8e,
X8Z24X16V8S8MS4VC121CS = 0x8f,
X8Z24X16V8S8MS4VC41CS = 0x90,
X8Z24X16V8S8MS8VC81CS = 0x91,
X8Z24X16V8S8MS8VC241CS = 0x92,
X8Z24X16V8S8MS4VC121ZV = 0x97,
X8Z24X16V8S8MS4VC41ZV = 0x98,
X8Z24X16V8S8MS8VC81ZV = 0x99,
X8Z24X16V8S8MS8VC241ZV = 0x9a,
X8Z24X16V8S8MS4VC121CZV = 0x9b,
X8Z24X16V8S8MS4VC41CZV = 0x9c,
X8Z24X16V8S8MS8VC81CZV = 0x9d,
X8Z24X16V8S8MS8VC241CZV = 0x9e,
X8Z24X16V8S8MS4VC122CS = 0x9f,
X8Z24X16V8S8MS4VC42CS = 0xa0,
X8Z24X16V8S8MS8VC82CS = 0xa1,
X8Z24X16V8S8MS8VC242CS = 0xa2,
X8Z24X16V8S8MS4VC122CSZV = 0xa3,
X8Z24X16V8S8MS4VC42CSZV = 0xa4,
X8Z24X16V8S8MS8VC82CSZV = 0xa5,
X8Z24X16V8S8MS8VC242CSZV = 0xa6,
ZF32X16V8S8MS4VC12 = 0xa7,
ZF32X16V8S8MS4VC4 = 0xa8,
ZF32X16V8S8MS8VC8 = 0xa9,
ZF32X16V8S8MS8VC24 = 0xaa,
ZF32X16V8S8MS4VC121CS = 0xab,
ZF32X16V8S8MS4VC41CS = 0xac,
ZF32X16V8S8MS8VC81CS = 0xad,
ZF32X16V8S8MS8VC241CS = 0xae,
ZF32X16V8S8MS4VC121ZV = 0xb3,
ZF32X16V8S8MS4VC41ZV = 0xb4,
ZF32X16V8S8MS8VC81ZV = 0xb5,
ZF32X16V8S8MS8VC241ZV = 0xb6,
ZF32X16V8S8MS4VC121CZV = 0xb7,
ZF32X16V8S8MS4VC41CZV = 0xb8,
ZF32X16V8S8MS8VC81CZV = 0xb9,
ZF32X16V8S8MS8VC241CZV = 0xba,
ZF32X16V8S8MS4VC122CS = 0xbb,
ZF32X16V8S8MS4VC42CS = 0xbc,
ZF32X16V8S8MS8VC82CS = 0xbd,
ZF32X16V8S8MS8VC242CS = 0xbe,
ZF32X16V8S8MS4VC122CSZV = 0xbf,
ZF32X16V8S8MS4VC42CSZV = 0xc0,
ZF32X16V8S8MS8VC82CSZV = 0xc1,
ZF32X16V8S8MS8VC242CSZV = 0xc2,
ZF32X24S8 = 0xc3,
ZF32X24S81CS = 0xc4,
ZF32X24S8MS21CS = 0xc5,
ZF32X24S8MS41CS = 0xc6,
ZF32X24S8MS81CS = 0xc7,
ZF32X24S8MS161CS = 0xc8,
ZF32X24S82CSZV = 0xce,
ZF32X24S8MS22CSZV = 0xcf,
ZF32X24S8MS42CSZV = 0xd0,
ZF32X24S8MS82CSZV = 0xd1,
ZF32X24S8MS162CSZV = 0xd2,
ZF32X24S82CS = 0xd3,
ZF32X24S8MS22CS = 0xd4,
ZF32X24S8MS42CS = 0xd5,
ZF32X24S8MS82CS = 0xd6,
ZF32X24S8MS162CS = 0xd7,
S8 = 0x2a,
S82S = 0x2b,
Generic16Bx2 = 0xfe,
C322C = 0xd8,
C322CBR = 0xd9,
C322CBA = 0xda,
C322CRA = 0xdb,
C322BRA = 0xdc,
C32MS22C = 0xdd,
C32MS22CBR = 0xde,
C32MS24CBRA = 0xcc,
C32MS42C = 0xdf,
C32MS42CBR = 0xe0,
C32MS42CBA = 0xe1,
C32MS42CRA = 0xe2,
C32MS42BRA = 0xe3,
C32MS44CBRA = 0x2c,
C32MS8MS162C = 0xe4,
C32MS8MS162CRA = 0xe5,
C642C = 0xe6,
C642CBR = 0xe7,
C642CBA = 0xe8,
C642CRA = 0xe9,
C642BRA = 0xea,
C64MS22C = 0xeb,
C64MS22CBR = 0xec,
C64MS24CBRA = 0xcd,
C64MS42C = 0xed,
C64MS42CBR = 0xee,
C64MS42CBA = 0xef,
C64MS42CRA = 0xf0,
C64MS42BRA = 0xf1,
C64MS44CBRA = 0x2d,
C64MS8MS162C = 0xf2,
C64MS8MS162CRA = 0xf3,
C1282C = 0xf4,
C1282CR = 0xf5,
C128MS22C = 0xf6,
C128MS22CR = 0xf7,
C128MS42C = 0xf8,
C128MS42CR = 0xf9,
C128MS8MS162C = 0xfa,
C128MS8MS162CR = 0xfb,
X8C24 = 0xfc,
PitchNoSwizzle = 0xfd,
SmSkedMessage = 0xca,
SmHostMessage = 0xcb
}
static class PteKindExtensions
{
/// <summary>
/// Checks if the kind is pitch.
/// </summary>
/// <param name="kind">Kind to check</param>
/// <returns>True if pitch, false otherwise</returns>
public static bool IsPitch(this PteKind kind)
{
return kind == PteKind.Pitch || kind == PteKind.PitchNoSwizzle;
}
}
}

View File

@ -1,13 +0,0 @@
namespace Ryujinx.Graphics.Gpu.Memory
{
/// <summary>
/// Name of a GPU resource.
/// </summary>
public enum ResourceName
{
Buffer,
Texture,
TexturePool,
SamplerPool
}
}

View File

@ -16,7 +16,7 @@ namespace Ryujinx.Graphics.Nvdec.Image
int width = surface.Width;
int height = surface.Height;
int stride = surface.Stride;
ReadOnlySpan<byte> luma = gmm.DeviceGetSpan(lumaOffset, GetBlockLinearSize(width, height, 1));
ReadLuma(surface.YPlane.AsSpan(), luma, stride, width, height);

View File

@ -612,7 +612,7 @@ namespace Ryujinx.Graphics.OpenGL
_program?.Bind();
_unit0Sampler?.Bind(0);
GL.ViewportArray(0, 1, _viewportArray);
RestoreViewport0();
Enable(EnableCap.CullFace, _cullEnable);
Enable(EnableCap.StencilTest, _stencilTestEnable);
@ -1478,6 +1478,11 @@ namespace Ryujinx.Graphics.OpenGL
_currentComponentMasks |= componentMaskAtIndex;
}
public void RestoreClipControl()
{
GL.ClipControl(_clipOrigin, _clipDepthMode);
}
public void RestoreScissor0Enable()
{
if ((_scissorEnables & 1u) != 0)
@ -1494,6 +1499,14 @@ namespace Ryujinx.Graphics.OpenGL
}
}
public void RestoreViewport0()
{
if (_viewportArray.Length > 0)
{
GL.ViewportArray(0, 1, _viewportArray);
}
}
public bool TryHostConditionalRendering(ICounterEvent value, ulong compare, bool isEqual)
{
if (value is CounterQueueEvent)

View File

@ -27,11 +27,12 @@ namespace Ryujinx.Graphics.OpenGL
{
GL.Disable(EnableCap.FramebufferSrgb);
CopyTextureToFrameBufferRGB(0, GetCopyFramebufferHandleLazy(), (TextureView)texture, crop);
CopyTextureToFrameBufferRGB(0, GetCopyFramebufferHandleLazy(), (TextureView)texture, crop, swapBuffersCallback);
GL.Enable(EnableCap.FramebufferSrgb);
swapBuffersCallback();
// Restore unpack alignment to 4, as performance overlays such as RTSS may change this to load their resources.
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4);
}
public void SetSize(int width, int height)
@ -40,7 +41,7 @@ namespace Ryujinx.Graphics.OpenGL
_height = height;
}
private void CopyTextureToFrameBufferRGB(int drawFramebuffer, int readFramebuffer, TextureView view, ImageCrop crop)
private void CopyTextureToFrameBufferRGB(int drawFramebuffer, int readFramebuffer, TextureView view, ImageCrop crop, Action swapBuffersCallback)
{
(int oldDrawFramebufferHandle, int oldReadFramebufferHandle) = ((Pipeline)_renderer.Pipeline).GetBoundFramebuffers();
@ -139,11 +140,20 @@ namespace Ryujinx.Graphics.OpenGL
((Pipeline)_renderer.Pipeline).RestoreComponentMask(i);
}
// Set clip control, viewport and the framebuffer to the output to placate overlays and OBS capture.
GL.ClipControl(ClipOrigin.LowerLeft, ClipDepthMode.NegativeOneToOne);
GL.Viewport(0, 0, _width, _height);
GL.BindFramebuffer(FramebufferTarget.Framebuffer, drawFramebuffer);
swapBuffersCallback();
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle);
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, oldDrawFramebufferHandle);
((Pipeline)_renderer.Pipeline).RestoreClipControl();
((Pipeline)_renderer.Pipeline).RestoreScissor0Enable();
((Pipeline)_renderer.Pipeline).RestoreRasterizerDiscard();
((Pipeline)_renderer.Pipeline).RestoreViewport0();
if (viewConverted != view)
{

View File

@ -1,19 +0,0 @@
namespace Ryujinx.HLE.FileSystem.Content
{
static class ContentPath
{
public const string SystemContent = "@SystemContent";
public const string UserContent = "@UserContent";
public const string SdCardContent = "@SdCardContent";
public const string SdCard = "@SdCard";
public const string CalibFile = "@CalibFile";
public const string Safe = "@Safe";
public const string User = "@User";
public const string System = "@System";
public const string Host = "@Host";
public const string GamecardApp = "@GcApp";
public const string GamecardContents = "@GcS00000001";
public const string GamecardUpdate = "@upp";
public const string RegisteredUpdate = "@RegUpdate";
}
}

View File

@ -1,91 +0,0 @@
using System;
using System.IO;
using static Ryujinx.HLE.FileSystem.VirtualFileSystem;
namespace Ryujinx.HLE.FileSystem.Content
{
internal static class LocationHelper
{
public static string GetRealPath(VirtualFileSystem fileSystem, string switchContentPath)
{
string basePath = fileSystem.GetBasePath();
switch (switchContentPath)
{
case ContentPath.SystemContent:
return Path.Combine(basePath, SystemNandPath, "Contents");
case ContentPath.UserContent:
return Path.Combine(basePath, UserNandPath, "Contents");
case ContentPath.SdCardContent:
return Path.Combine(fileSystem.GetSdCardPath(), "Nintendo", "Contents");
case ContentPath.System:
return Path.Combine(basePath, SystemNandPath);
case ContentPath.User:
return Path.Combine(basePath, UserNandPath);
default:
throw new NotSupportedException($"Content Path `{switchContentPath}` is not supported.");
}
}
public static string GetContentPath(ContentStorageId contentStorageId)
{
switch (contentStorageId)
{
case ContentStorageId.NandSystem:
return ContentPath.SystemContent;
case ContentStorageId.NandUser:
return ContentPath.UserContent;
case ContentStorageId.SdCard:
return ContentPath.SdCardContent;
default:
throw new NotSupportedException($"Content Storage `{contentStorageId}` is not supported.");
}
}
public static string GetContentRoot(StorageId storageId)
{
switch (storageId)
{
case StorageId.NandSystem:
return ContentPath.SystemContent;
case StorageId.NandUser:
return ContentPath.UserContent;
case StorageId.SdCard:
return ContentPath.SdCardContent;
default:
throw new NotSupportedException($"Storage Id `{storageId}` is not supported.");
}
}
public static StorageId GetStorageId(string contentPathString)
{
string cleanedPath = contentPathString.Split(':')[0];
switch (cleanedPath)
{
case ContentPath.SystemContent:
case ContentPath.System:
return StorageId.NandSystem;
case ContentPath.UserContent:
case ContentPath.User:
return StorageId.NandUser;
case ContentPath.SdCardContent:
return StorageId.SdCard;
case ContentPath.Host:
return StorageId.Host;
case ContentPath.GamecardApp:
case ContentPath.GamecardContents:
case ContentPath.GamecardUpdate:
return StorageId.GameCard;
default:
return StorageId.None;
}
}
}
}

View File

@ -1,9 +0,0 @@
namespace Ryujinx.HLE.FileSystem.Content
{
public enum ContentStorageId
{
NandSystem,
NandUser,
SdCard
}
}

View File

@ -1,15 +0,0 @@
namespace Ryujinx.HLE.FileSystem.Content
{
enum TitleType
{
SystemPrograms = 0x01,
SystemDataArchive = 0x02,
SystemUpdate = 0x03,
FirmwarePackageA = 0x04,
FirmwarePackageB = 0x05,
RegularApplication = 0x80,
Update = 0x81,
AddOnContent = 0x82,
DeltaTitle = 0x83
}
}

View File

@ -20,7 +20,7 @@ using System.IO.Compression;
using System.Linq;
using Path = System.IO.Path;
namespace Ryujinx.HLE.FileSystem.Content
namespace Ryujinx.HLE.FileSystem
{
public class ContentManager
{
@ -110,8 +110,8 @@ namespace Ryujinx.HLE.FileSystem.Content
try
{
contentPathString = LocationHelper.GetContentRoot(storageId);
contentDirectory = LocationHelper.GetRealPath(_virtualFileSystem, contentPathString);
contentPathString = ContentPath.GetContentPath(storageId);
contentDirectory = ContentPath.GetRealPath(_virtualFileSystem, contentPathString);
registeredDirectory = Path.Combine(contentDirectory, "registered");
}
catch (NotSupportedException)
@ -367,8 +367,7 @@ namespace Ryujinx.HLE.FileSystem.Content
{
LocationEntry locationEntry = GetLocation(titleId, contentType, storageId);
return locationEntry.ContentPath != null ?
LocationHelper.GetStorageId(locationEntry.ContentPath) : StorageId.None;
return locationEntry.ContentPath != null ? ContentPath.GetStorageId(locationEntry.ContentPath) : StorageId.None;
}
}
@ -493,8 +492,8 @@ namespace Ryujinx.HLE.FileSystem.Content
public void InstallFirmware(string firmwareSource)
{
string contentPathString = LocationHelper.GetContentRoot(StorageId.NandSystem);
string contentDirectory = LocationHelper.GetRealPath(_virtualFileSystem, contentPathString);
string contentPathString = ContentPath.GetContentPath(StorageId.BuiltInSystem);
string contentDirectory = ContentPath.GetRealPath(_virtualFileSystem, contentPathString);
string registeredDirectory = Path.Combine(contentDirectory, "registered");
string temporaryDirectory = Path.Combine(contentDirectory, "temp");
@ -998,9 +997,9 @@ namespace Ryujinx.HLE.FileSystem.Content
foreach (var entry in updateNcas)
{
foreach (var nca in entry.Value)
foreach (var (type, path) in entry.Value)
{
extraNcas += nca.path + Environment.NewLine;
extraNcas += path + Environment.NewLine;
}
}
@ -1019,7 +1018,7 @@ namespace Ryujinx.HLE.FileSystem.Content
lock (_lock)
{
var locationEnties = _locationEntries[StorageId.NandSystem];
var locationEnties = _locationEntries[StorageId.BuiltInSystem];
foreach (var entry in locationEnties)
{

View File

@ -0,0 +1,82 @@
using LibHac.Fs;
using LibHac.Ncm;
using Ryujinx.Common.Configuration;
using System;
using static Ryujinx.HLE.FileSystem.VirtualFileSystem;
using Path = System.IO.Path;
namespace Ryujinx.HLE.FileSystem
{
internal static class ContentPath
{
public const string SystemContent = "@SystemContent";
public const string UserContent = "@UserContent";
public const string SdCardContent = "@SdCardContent";
public const string SdCard = "@Sdcard";
public const string CalibFile = "@CalibFile";
public const string Safe = "@Safe";
public const string User = "@User";
public const string System = "@System";
public const string Host = "@Host";
public const string GamecardApp = "@GcApp";
public const string GamecardContents = "@GcS00000001";
public const string GamecardUpdate = "@upp";
public const string RegisteredUpdate = "@RegUpdate";
public const string Nintendo = "Nintendo";
public const string Contents = "Contents";
public static string GetRealPath(VirtualFileSystem fileSystem, string switchContentPath)
{
return switchContentPath switch
{
SystemContent => Path.Combine(AppDataManager.BaseDirPath, SystemNandPath, Contents),
UserContent => Path.Combine(AppDataManager.BaseDirPath, UserNandPath, Contents),
SdCardContent => Path.Combine(fileSystem.GetSdCardPath(), Nintendo, Contents),
System => Path.Combine(AppDataManager.BaseDirPath, SystemNandPath),
User => Path.Combine(AppDataManager.BaseDirPath, UserNandPath),
_ => throw new NotSupportedException($"Content Path \"`{switchContentPath}`\" is not supported.")
};
}
public static string GetContentPath(ContentStorageId contentStorageId)
{
return contentStorageId switch
{
ContentStorageId.System => SystemContent,
ContentStorageId.User => UserContent,
ContentStorageId.SdCard => SdCardContent,
_ => throw new NotSupportedException($"Content Storage Id \"`{contentStorageId}`\" is not supported.")
};
}
public static string GetContentPath(StorageId storageId)
{
return storageId switch
{
StorageId.BuiltInSystem => SystemContent,
StorageId.BuiltInUser => UserContent,
StorageId.SdCard => SdCardContent,
_ => throw new NotSupportedException($"Storage Id \"`{storageId}`\" is not supported.")
};
}
public static StorageId GetStorageId(string contentPathString)
{
return contentPathString.Split(':')[0] switch
{
SystemContent or
System => StorageId.BuiltInSystem,
UserContent or
User => StorageId.BuiltInUser,
SdCardContent => StorageId.SdCard,
Host => StorageId.Host,
GamecardApp or
GamecardContents or
GamecardUpdate => StorageId.GameCard,
_ => StorageId.None
};
}
}
}

View File

@ -8,7 +8,6 @@ namespace Ryujinx.HLE.FileSystem
{
public class EncryptedFileSystemCreator : IEncryptedFileSystemCreator
{
public Result Create(ref SharedRef<IFileSystem> outEncryptedFileSystem,
ref SharedRef<IFileSystem> baseFileSystem, IEncryptedFileSystemCreator.KeyId idIndex,
in EncryptionSeed encryptionSeed)
@ -18,10 +17,10 @@ namespace Ryujinx.HLE.FileSystem
return ResultFs.InvalidArgument.Log();
}
// Todo: Reenable when AesXtsFileSystem is fixed
// TODO: Reenable when AesXtsFileSystem is fixed.
outEncryptedFileSystem = SharedRef<IFileSystem>.CreateMove(ref baseFileSystem);
return Result.Success;
}
}
}
}

View File

@ -1,6 +1,6 @@
using LibHac.FsSystem;
namespace Ryujinx.HLE.FileSystem.Content
namespace Ryujinx.HLE.FileSystem
{
public struct LocationEntry
{

View File

@ -1,12 +0,0 @@
namespace Ryujinx.HLE.FileSystem
{
enum SaveDataType : byte
{
SystemSaveData,
SaveData,
BcatDeliveryCacheStorage,
DeviceSaveData,
TemporaryStorage,
CacheStorage
}
}

View File

@ -1,27 +0,0 @@
using Ryujinx.HLE.HOS.Services.Account.Acc;
namespace Ryujinx.HLE.FileSystem
{
struct SaveInfo
{
public ulong TitleId { get; private set; }
public long SaveId { get; private set; }
public SaveDataType SaveDataType { get; private set; }
public SaveSpaceId SaveSpaceId { get; private set; }
public UserId UserId { get; private set; }
public SaveInfo(
ulong titleId,
long saveId,
SaveDataType saveDataType,
SaveSpaceId saveSpaceId,
UserId userId = new UserId())
{
TitleId = titleId;
SaveId = saveId;
SaveDataType = saveDataType;
SaveSpaceId = saveSpaceId;
UserId = userId;
}
}
}

View File

@ -1,10 +0,0 @@
namespace Ryujinx.HLE.FileSystem
{
enum SaveSpaceId
{
NandSystem,
NandUser,
SdCard,
TemporaryStorage
}
}

View File

@ -1,12 +0,0 @@
namespace Ryujinx.HLE.FileSystem
{
public enum StorageId
{
None,
Host,
GameCard,
NandSystem,
NandUser,
SdCard
}
}

View File

@ -1,8 +1,7 @@
using Ryujinx.HLE.Utilities;
using System.IO;
using System.Text;
namespace Ryujinx.HLE.FileSystem.Content
namespace Ryujinx.HLE.FileSystem
{
public class SystemVersion
{

View File

@ -13,7 +13,6 @@ using LibHac.Tools.Fs;
using LibHac.Tools.FsSystem;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem.Content;
using Ryujinx.HLE.HOS;
using System;
using System.Buffers.Text;
@ -28,20 +27,29 @@ namespace Ryujinx.HLE.FileSystem
{
public class VirtualFileSystem : IDisposable
{
public const string NandPath = AppDataManager.DefaultNandDir;
public const string SdCardPath = AppDataManager.DefaultSdcardDir;
public static string SafeNandPath = Path.Combine(AppDataManager.DefaultNandDir, "safe");
public static string SystemNandPath = Path.Combine(AppDataManager.DefaultNandDir, "system");
public static string UserNandPath = Path.Combine(AppDataManager.DefaultNandDir, "user");
public static string SafeNandPath = Path.Combine(NandPath, "safe");
public static string SystemNandPath = Path.Combine(NandPath, "system");
public static string UserNandPath = Path.Combine(NandPath, "user");
public KeySet KeySet { get; private set; }
public EmulatedGameCard GameCard { get; private set; }
public EmulatedSdCard SdCard { get; private set; }
public ModLoader ModLoader { get; private set; }
public Stream RomFs { get; private set; }
private static bool _isInitialized = false;
public KeySet KeySet { get; private set; }
public EmulatedGameCard GameCard { get; private set; }
public EmulatedSdCard SdCard { get; private set; }
public static VirtualFileSystem CreateInstance()
{
if (_isInitialized)
{
throw new InvalidOperationException("VirtualFileSystem can only be instantiated once!");
}
public ModLoader ModLoader { get; private set; }
_isInitialized = true;
return new VirtualFileSystem();
}
private VirtualFileSystem()
{
@ -49,8 +57,6 @@ namespace Ryujinx.HLE.FileSystem
ModLoader = new ModLoader(); // Should only be created once
}
public Stream RomFs { get; private set; }
public void LoadRomFs(string fileName)
{
RomFs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
@ -79,7 +85,7 @@ namespace Ryujinx.HLE.FileSystem
string fullPath = Path.GetFullPath(Path.Combine(basePath, fileName));
if (!fullPath.StartsWith(GetBasePath()))
if (!fullPath.StartsWith(AppDataManager.BaseDirPath))
{
return null;
}
@ -87,14 +93,8 @@ namespace Ryujinx.HLE.FileSystem
return fullPath;
}
internal string GetBasePath() => AppDataManager.BaseDirPath;
internal string GetSdCardPath() => MakeFullPath(SdCardPath);
public string GetNandPath() => MakeFullPath(NandPath);
public string GetFullPartitionPath(string partitionPath)
{
return MakeFullPath(partitionPath);
}
internal string GetSdCardPath() => MakeFullPath(AppDataManager.DefaultSdcardDir);
public string GetNandPath() => MakeFullPath(AppDataManager.DefaultNandDir);
public string SwitchPathToSystemPath(string switchPath)
{
@ -110,7 +110,7 @@ namespace Ryujinx.HLE.FileSystem
public string SystemPathToSwitchPath(string systemPath)
{
string baseSystemPath = GetBasePath() + Path.DirectorySeparatorChar;
string baseSystemPath = AppDataManager.BaseDirPath + Path.DirectorySeparatorChar;
if (systemPath.StartsWith(baseSystemPath))
{
@ -136,8 +136,7 @@ namespace Ryujinx.HLE.FileSystem
switch (path)
{
case ContentPath.SdCard:
case "@Sdcard":
path = SdCardPath;
path = AppDataManager.DefaultSdcardDir;
break;
case ContentPath.User:
path = UserNandPath;
@ -146,7 +145,7 @@ namespace Ryujinx.HLE.FileSystem
path = SystemNandPath;
break;
case ContentPath.SdCardContent:
path = Path.Combine(SdCardPath, "Nintendo", "Contents");
path = Path.Combine(AppDataManager.DefaultSdcardDir, "Nintendo", "Contents");
break;
case ContentPath.UserContent:
path = Path.Combine(UserNandPath, "Contents");
@ -156,27 +155,19 @@ namespace Ryujinx.HLE.FileSystem
break;
}
string fullPath = Path.Combine(GetBasePath(), path);
string fullPath = Path.Combine(AppDataManager.BaseDirPath, path);
if (isDirectory)
if (isDirectory && !Directory.Exists(fullPath))
{
if (!Directory.Exists(fullPath))
{
Directory.CreateDirectory(fullPath);
}
Directory.CreateDirectory(fullPath);
}
return fullPath;
}
public DriveInfo GetDrive()
{
return new DriveInfo(Path.GetPathRoot(GetBasePath()));
}
public void InitializeFsServer(LibHac.Horizon horizon, out HorizonClient fsServerClient)
{
LocalFileSystem serverBaseFs = new LocalFileSystem(GetBasePath());
LocalFileSystem serverBaseFs = new LocalFileSystem(AppDataManager.BaseDirPath);
fsServerClient = horizon.CreatePrivilegedHorizonClient();
var fsServer = new FileSystemServer(fsServerClient);
@ -505,7 +496,7 @@ namespace Ryujinx.HLE.FileSystem
bool canFixBySaveDataId = extraData.Attribute.StaticSaveDataId == 0 && info.StaticSaveDataId != 0;
bool hasEmptyOwnerId = extraData.OwnerId == 0 && info.Type != LibHac.Fs.SaveDataType.System;
bool hasEmptyOwnerId = extraData.OwnerId == 0 && info.Type != SaveDataType.System;
if (!canFixByProgramId && !canFixBySaveDataId && !hasEmptyOwnerId)
{
@ -523,7 +514,7 @@ namespace Ryujinx.HLE.FileSystem
// The rest of the extra data can't be created from the save data info.
// On user saves the owner ID will almost certainly be the same as the program ID.
if (info.Type != LibHac.Fs.SaveDataType.System)
if (info.Type != SaveDataType.System)
{
extraData.OwnerId = info.ProgramId.Value;
}
@ -580,11 +571,6 @@ namespace Ryujinx.HLE.FileSystem
}
};
public void Unload()
{
RomFs?.Dispose();
}
public void Dispose()
{
Dispose(true);
@ -594,20 +580,8 @@ namespace Ryujinx.HLE.FileSystem
{
if (disposing)
{
Unload();
RomFs?.Dispose();
}
}
public static VirtualFileSystem CreateInstance()
{
if (_isInitialized)
{
throw new InvalidOperationException("VirtualFileSystem can only be instantiated once!");
}
_isInitialized = true;
return new VirtualFileSystem();
}
}
}

View File

@ -3,7 +3,6 @@ using Ryujinx.Audio.Integration;
using Ryujinx.Common.Configuration;
using Ryujinx.Graphics.GAL;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.FileSystem.Content;
using Ryujinx.HLE.HOS;
using Ryujinx.HLE.HOS.Services.Account.Acc;
using Ryujinx.HLE.HOS.SystemState;

View File

@ -2,10 +2,10 @@
using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.FsSystem;
using LibHac.Ncm;
using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.Services.Am.AppletAE;
using Ryujinx.HLE.HOS.SystemState;
using System;
@ -106,7 +106,7 @@ namespace Ryujinx.HLE.HOS.Applets.Error
private string GetMessageText(uint module, uint description, string key)
{
string binaryTitleContentPath = _horizon.ContentManager.GetInstalledContentPath(ErrorMessageBinaryTitleId, StorageId.NandSystem, NcaContentType.Data);
string binaryTitleContentPath = _horizon.ContentManager.GetInstalledContentPath(ErrorMessageBinaryTitleId, StorageId.BuiltInSystem, NcaContentType.Data);
using (LibHac.Fs.IStorage ncaFileStream = new LocalStorage(_horizon.Device.FileSystem.SwitchPathToSystemPath(binaryTitleContentPath), FileAccess.Read, FileMode.Open))
{

View File

@ -10,7 +10,7 @@ using Ryujinx.Audio.Integration;
using Ryujinx.Audio.Output;
using Ryujinx.Audio.Renderer.Device;
using Ryujinx.Audio.Renderer.Server;
using Ryujinx.HLE.FileSystem.Content;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.Kernel;
using Ryujinx.HLE.HOS.Kernel.Memory;
using Ryujinx.HLE.HOS.Kernel.Process;
@ -238,6 +238,7 @@ namespace Ryujinx.HLE.HOS
SurfaceFlinger = new SurfaceFlinger(device);
InitializeAudioRenderer();
InitializeServices();
}
private void InitializeAudioRenderer()
@ -288,7 +289,7 @@ namespace Ryujinx.HLE.HOS
AudioManager.Start();
}
public void InitializeServices()
private void InitializeServices()
{
SmServer = new ServerBase(KernelContext, "SmServer", () => new IUserInterface(KernelContext));

View File

@ -1,4 +1,4 @@
using Ryujinx.HLE.FileSystem;
using LibHac.Ncm;
namespace Ryujinx.HLE.HOS.Services.Arp
{
@ -20,7 +20,7 @@ namespace Ryujinx.HLE.HOS.Services.Arp
{
TitleId = 0x00,
Version = 0x00,
BaseGameStorageId = (byte)StorageId.NandSystem,
BaseGameStorageId = (byte)StorageId.BuiltInSystem,
UpdateGameStorageId = (byte)StorageId.None
};
}
@ -35,7 +35,7 @@ namespace Ryujinx.HLE.HOS.Services.Arp
{
TitleId = context.Device.Application.TitleId,
Version = 0x00,
BaseGameStorageId = (byte)StorageId.NandSystem,
BaseGameStorageId = (byte)StorageId.BuiltInSystem,
UpdateGameStorageId = (byte)StorageId.None
};
}

View File

@ -2,7 +2,6 @@ using LibHac;
using LibHac.Common;
using LibHac.Fs;
using LibHac.Fs.Shim;
using LibHac.FsSrv;
using LibHac.FsSrv.Impl;
using LibHac.FsSystem;
using LibHac.Ncm;
@ -19,7 +18,6 @@ using static Ryujinx.HLE.Utilities.StringUtils;
using IFileSystem = LibHac.FsSrv.Sf.IFileSystem;
using IStorage = LibHac.FsSrv.Sf.IStorage;
using RightsId = LibHac.Fs.RightsId;
using StorageId = Ryujinx.HLE.FileSystem.StorageId;
namespace Ryujinx.HLE.HOS.Services.Fs
{

View File

@ -55,9 +55,11 @@ namespace Ryujinx.HLE.HOS.Services.Hid
_storage = storage;
SharedMemory = SharedMemory.Create();
InitDevices();
}
public void InitDevices()
private void InitDevices()
{
DebugPad = new DebugPadDevice(_device, true);
Touchscreen = new TouchDevice(_device, true);

View File

@ -1,4 +1,4 @@
using Ryujinx.HLE.FileSystem;
using LibHac.Ncm;
using Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager;
namespace Ryujinx.HLE.HOS.Services.Ncm.Lr

View File

@ -1,6 +1,6 @@
using LibHac.FsSystem;
using LibHac.Ncm;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.FileSystem.Content;
using System.Text;
using static Ryujinx.HLE.Utilities.StringUtils;

View File

@ -1,5 +1,5 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem;
using LibHac.Ncm;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Services.Arp;
using Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface;

View File

@ -1,8 +1,24 @@
namespace Ryujinx.HLE.HOS.Services.Nim.Ntc
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Services.Nim.Ntc.StaticService;
namespace Ryujinx.HLE.HOS.Services.Nim.Ntc
{
[Service("ntc")]
class IStaticService : IpcService
{
public IStaticService(ServiceCtx context) { }
[CommandHipc(0)]
// OpenEnsureNetworkClockAvailabilityService(u64) -> object<nn::ntc::detail::service::IEnsureNetworkClockAvailabilityService>
public ResultCode CreateAsyncInterface(ServiceCtx context)
{
ulong unknown = context.RequestData.ReadUInt64();
MakeObject(context, new IEnsureNetworkClockAvailabilityService(context));
Logger.Stub?.PrintStub(LogClass.ServiceNtc, new { unknown });
return ResultCode.Success;
}
}
}

View File

@ -0,0 +1,77 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Threading;
using System;
namespace Ryujinx.HLE.HOS.Services.Nim.Ntc.StaticService
{
class IEnsureNetworkClockAvailabilityService : IpcService
{
private KEvent _finishNotificationEvent;
private ResultCode _taskResultCode;
public IEnsureNetworkClockAvailabilityService(ServiceCtx context)
{
_finishNotificationEvent = new KEvent(context.Device.System.KernelContext);
_taskResultCode = ResultCode.Success;
// NOTE: The service starts a thread that polls Nintendo NTP server and syncs the time with it.
// Additionnally it gets and uses some settings too:
// autonomic_correction_interval_seconds, autonomic_correction_failed_retry_interval_seconds,
// autonomic_correction_immediate_try_count_max, autonomic_correction_immediate_try_interval_milliseconds
}
[CommandHipc(0)]
// StartTask()
public ResultCode StartTask(ServiceCtx context)
{
if (!context.Device.Configuration.EnableInternetAccess)
{
return (ResultCode)Time.ResultCode.NetworkTimeNotAvailable;
}
// NOTE: Since we don't support the Nintendo NTP server, we can signal the event now to confirm the update task is done.
_finishNotificationEvent.ReadableEvent.Signal();
Logger.Stub?.PrintStub(LogClass.ServiceNtc);
return ResultCode.Success;
}
[CommandHipc(1)]
// GetFinishNotificationEvent() -> handle<copy>
public ResultCode GetFinishNotificationEvent(ServiceCtx context)
{
if (context.Process.HandleTable.GenerateHandle(_finishNotificationEvent.ReadableEvent, out int finishNotificationEventHandle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(finishNotificationEventHandle);
return ResultCode.Success;
}
[CommandHipc(2)]
// GetResult()
public ResultCode GetResult(ServiceCtx context)
{
return _taskResultCode;
}
[CommandHipc(3)]
// Cancel()
public ResultCode Cancel(ServiceCtx context)
{
// NOTE: The update task should be canceled here.
_finishNotificationEvent.ReadableEvent.Signal();
_taskResultCode = (ResultCode)Time.ResultCode.NetworkTimeTaskCanceled;
Logger.Stub?.PrintStub(LogClass.ServiceNtc);
return ResultCode.Success;
}
}
}

View File

@ -232,7 +232,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
ulong virtualAddress = arguments.Offset + arguments.BufferOffset;
physicalAddress += arguments.BufferOffset;
_asContext.Gmm.Map(physicalAddress, virtualAddress, arguments.MappingSize);
_asContext.Gmm.Map(physicalAddress, virtualAddress, arguments.MappingSize, (PteKind)arguments.Kind);
return NvInternalResult.Success;
}
@ -282,7 +282,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
{
if (_asContext.ValidateFixedBuffer(arguments.Offset, size, pageSize))
{
_asContext.Gmm.Map(physicalAddress, arguments.Offset, size);
_asContext.Gmm.Map(physicalAddress, arguments.Offset, size, (PteKind)arguments.Kind);
}
else
{
@ -301,7 +301,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
_memoryAllocator.AllocateRange(va, size, freeAddressStartPosition);
}
_asContext.Gmm.Map(physicalAddress, va, size);
_asContext.Gmm.Map(physicalAddress, va, size, (PteKind)arguments.Kind);
arguments.Offset = va;
}
@ -366,26 +366,30 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
for (int index = 0; index < arguments.Length; index++)
{
ulong mapOffs = (ulong)arguments[index].MapOffset << 16;
ulong gpuVa = (ulong)arguments[index].GpuOffset << 16;
ulong size = (ulong)arguments[index].Pages << 16;
ref RemapArguments argument = ref arguments[index];
ulong gpuVa = (ulong)argument.GpuOffset << 16;
ulong size = (ulong)argument.Pages << 16;
int nvmapHandle = argument.NvMapHandle;
if (arguments[index].NvMapHandle == 0)
if (nvmapHandle == 0)
{
gmm.Unmap(gpuVa, size);
}
else
{
NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, arguments[index].NvMapHandle);
ulong mapOffs = (ulong)argument.MapOffset << 16;
PteKind kind = (PteKind)argument.Kind;
NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, nvmapHandle);
if (map == null)
{
Logger.Warning?.Print(LogClass.ServiceNv, $"Invalid NvMap handle 0x{arguments[index].NvMapHandle:x8}!");
Logger.Warning?.Print(LogClass.ServiceNv, $"Invalid NvMap handle 0x{nvmapHandle:x8}!");
return NvInternalResult.InvalidInput;
}
gmm.Map(mapOffs + map.Address, gpuVa, size);
gmm.Map(mapOffs + map.Address, gpuVa, size, kind);
}
}

View File

@ -251,7 +251,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
if (va != NvMemoryAllocator.PteUnmapped && va <= uint.MaxValue && (va + (uint)map.Size) <= uint.MaxValue)
{
_host1xContext.MemoryAllocator.AllocateRange(va, (uint)map.Size, freeAddressStartPosition);
_host1xContext.Smmu.Map(map.Address, va, (uint)map.Size);
_host1xContext.Smmu.Map(map.Address, va, (uint)map.Size, PteKind.Pitch); // FIXME: This should not use the GMMU.
map.DmaMapAddress = va;
}
else

View File

@ -45,7 +45,7 @@ namespace Ryujinx.HLE.HOS.Services.Olsc
return ResultCode.NullArgument;
}
if (_saveDataBackupSettingDatabase[userId])
if (_saveDataBackupSettingDatabase.TryGetValue(userId, out bool enabled) && enabled)
{
context.ResponseData.Write((byte)1); // TODO: Determine value.
}

View File

@ -2,11 +2,11 @@ using LibHac.Common;
using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.FsSystem;
using LibHac.Ncm;
using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils;
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;
@ -63,7 +63,7 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pl
{
if (contentManager.TryGetFontTitle(name, out ulong fontTitle) && contentManager.TryGetFontFilename(name, out string fontFilename))
{
string contentPath = contentManager.GetInstalledContentPath(fontTitle, StorageId.NandSystem, NcaContentType.Data);
string contentPath = contentManager.GetInstalledContentPath(fontTitle, StorageId.BuiltInSystem, NcaContentType.Data);
string fontPath = _device.FileSystem.SwitchPathToSystemPath(contentPath);
if (!string.IsNullOrWhiteSpace(fontPath))

View File

@ -3,9 +3,9 @@ using LibHac.Common;
using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.FsSystem;
using LibHac.Ncm;
using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.HLE.Utilities;
using System;
@ -290,7 +290,7 @@ namespace Ryujinx.HLE.HOS.Services.Settings
{
const ulong SystemVersionTitleId = 0x0100000000000809;
string contentPath = device.System.ContentManager.GetInstalledContentPath(SystemVersionTitleId, StorageId.NandSystem, NcaContentType.Data);
string contentPath = device.System.ContentManager.GetInstalledContentPath(SystemVersionTitleId, StorageId.BuiltInSystem, NcaContentType.Data);
if (string.IsNullOrWhiteSpace(contentPath))
{

View File

@ -1,5 +1,4 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem.Content;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Services.Spl.Types;

View File

@ -3,13 +3,13 @@ using LibHac.Common;
using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.FsSystem;
using LibHac.Ncm;
using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.Exceptions;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.FileSystem.Content;
using Ryujinx.HLE.HOS.Services.Ssl.Types;
using System;
using System.Collections.Generic;
@ -82,7 +82,7 @@ namespace Ryujinx.HLE.HOS.Services.Ssl
public string GetCertStoreTitleContentPath()
{
return _contentManager.GetInstalledContentPath(CertStoreTitleId, StorageId.NandSystem, NcaContentType.Data);
return _contentManager.GetInstalledContentPath(CertStoreTitleId, StorageId.BuiltInSystem, NcaContentType.Data);
}
public bool HasCertStoreTitle()

View File

@ -7,16 +7,18 @@
Success = 0,
TimeServiceNotInitialized = (0 << ErrorCodeShift) | ModuleId,
PermissionDenied = (1 << ErrorCodeShift) | ModuleId,
TimeMismatch = (102 << ErrorCodeShift) | ModuleId,
UninitializedClock = (103 << ErrorCodeShift) | ModuleId,
TimeNotFound = (200 << ErrorCodeShift) | ModuleId,
Overflow = (201 << ErrorCodeShift) | ModuleId,
LocationNameTooLong = (801 << ErrorCodeShift) | ModuleId,
OutOfRange = (902 << ErrorCodeShift) | ModuleId,
TimeZoneConversionFailed = (903 << ErrorCodeShift) | ModuleId,
TimeZoneNotFound = (989 << ErrorCodeShift) | ModuleId,
NotImplemented = (990 << ErrorCodeShift) | ModuleId,
TimeServiceNotInitialized = (0 << ErrorCodeShift) | ModuleId,
PermissionDenied = (1 << ErrorCodeShift) | ModuleId,
TimeMismatch = (102 << ErrorCodeShift) | ModuleId,
UninitializedClock = (103 << ErrorCodeShift) | ModuleId,
TimeNotFound = (200 << ErrorCodeShift) | ModuleId,
Overflow = (201 << ErrorCodeShift) | ModuleId,
LocationNameTooLong = (801 << ErrorCodeShift) | ModuleId,
OutOfRange = (902 << ErrorCodeShift) | ModuleId,
TimeZoneConversionFailed = (903 << ErrorCodeShift) | ModuleId,
TimeZoneNotFound = (989 << ErrorCodeShift) | ModuleId,
NotImplemented = (990 << ErrorCodeShift) | ModuleId,
NetworkTimeNotAvailable = (1000 << ErrorCodeShift) | ModuleId,
NetworkTimeTaskCanceled = (1003 << ErrorCodeShift) | ModuleId,
}
}

View File

@ -3,12 +3,12 @@ using LibHac.Common;
using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.FsSystem;
using LibHac.Ncm;
using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.Exceptions;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.FileSystem.Content;
using Ryujinx.HLE.HOS.Services.Time.Clock;
using Ryujinx.HLE.Utilities;
using System;
@ -241,7 +241,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
public string GetTimeZoneBinaryTitleContentPath()
{
return _contentManager.GetInstalledContentPath(TimeZoneBinaryTitleId, StorageId.NandSystem, NcaContentType.Data);
return _contentManager.GetInstalledContentPath(TimeZoneBinaryTitleId, StorageId.BuiltInSystem, NcaContentType.Data);
}
public bool HasTimeZoneBinaryTitle()

View File

@ -13,27 +13,17 @@ namespace Ryujinx.HLE
{
public class Switch : IDisposable
{
public HLEConfiguration Configuration { get; }
public HLEConfiguration Configuration { get; }
public IHardwareDeviceDriver AudioDeviceDriver { get; }
internal MemoryBlock Memory { get; }
public GpuContext Gpu { get; }
public VirtualFileSystem FileSystem => Configuration.VirtualFileSystem;
public Horizon System { get; }
public ApplicationLoader Application { get; }
public PerformanceStatistics Statistics { get; }
public Hid Hid { get; }
public TamperMachine TamperMachine { get; }
public IHostUiHandler UiHandler { get; }
public MemoryBlock Memory { get; }
public GpuContext Gpu { get; }
public VirtualFileSystem FileSystem { get; }
public Horizon System { get; }
public ApplicationLoader Application { get; }
public PerformanceStatistics Statistics { get; }
public Hid Hid { get; }
public TamperMachine TamperMachine { get; }
public IHostUiHandler UiHandler { get; }
public bool EnableDeviceVsync { get; set; } = true;
@ -55,47 +45,27 @@ namespace Ryujinx.HLE
}
Configuration = configuration;
FileSystem = Configuration.VirtualFileSystem;
UiHandler = Configuration.HostUiHandler;
UiHandler = configuration.HostUiHandler;
AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(Configuration.AudioDeviceDriver);
Memory = new MemoryBlock(Configuration.MemoryConfiguration.ToDramSize(), MemoryAllocationFlags.Reserve);
Gpu = new GpuContext(Configuration.GpuRenderer);
System = new Horizon(this);
Statistics = new PerformanceStatistics();
Hid = new Hid(this, System.HidStorage);
Application = new ApplicationLoader(this);
TamperMachine = new TamperMachine();
AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(configuration.AudioDeviceDriver);
Memory = new MemoryBlock(configuration.MemoryConfiguration.ToDramSize(), MemoryAllocationFlags.Reserve);
Gpu = new GpuContext(configuration.GpuRenderer);
System = new Horizon(this);
System.InitializeServices();
Statistics = new PerformanceStatistics();
Hid = new Hid(this, System.HidStorage);
Hid.InitDevices();
Application = new ApplicationLoader(this);
TamperMachine = new TamperMachine();
Initialize();
}
private void Initialize()
{
System.State.SetLanguage(Configuration.SystemLanguage);
System.State.SetRegion(Configuration.Region);
EnableDeviceVsync = Configuration.EnableVsync;
System.State.DockedMode = Configuration.EnableDockedMode;
EnableDeviceVsync = Configuration.EnableVsync;
System.State.DockedMode = Configuration.EnableDockedMode;
System.PerformanceState.PerformanceMode = System.State.DockedMode ? PerformanceMode.Boost : PerformanceMode.Default;
System.EnablePtc = Configuration.EnablePtc;
System.FsIntegrityCheckLevel = Configuration.FsIntegrityCheckLevel;
System.GlobalAccessLogMode = Configuration.FsGlobalAccessLogMode;
System.EnablePtc = Configuration.EnablePtc;
System.FsIntegrityCheckLevel = Configuration.FsIntegrityCheckLevel;
System.GlobalAccessLogMode = Configuration.FsGlobalAccessLogMode;
}
public void LoadCart(string exeFsDir, string romFsFile = null)
@ -132,7 +102,6 @@ namespace Ryujinx.HLE
{
Gpu.ProcessShaderCacheQueue();
Gpu.Renderer.PreFrame();
Gpu.GPFifo.DispatchCalls();
}
@ -182,9 +151,9 @@ namespace Ryujinx.HLE
{
System.Dispose();
AudioDeviceDriver.Dispose();
FileSystem.Unload();
FileSystem.Dispose();
Memory.Dispose();
}
}
}
}
}

View File

@ -20,7 +20,6 @@ using Ryujinx.Graphics.OpenGL;
using Ryujinx.Headless.SDL2.OpenGL;
using Ryujinx.HLE;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.FileSystem.Content;
using Ryujinx.HLE.HOS;
using Ryujinx.HLE.HOS.Services.Account.Acc;
using Ryujinx.Input;
@ -29,7 +28,6 @@ using Ryujinx.Input.SDL2;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text.Json;
using System.Threading;

View File

@ -188,7 +188,7 @@ namespace Ryujinx.Memory.Tests
Assert.False(alignedAfterTriggers);
}
[Test, Timeout(1000)]
[Test, Explicit, Timeout(1000)]
public void Multithreading()
{
// Multithreading sanity test

View File

@ -1,5 +1,5 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem.Content;
using Ryujinx.HLE.FileSystem;
using Ryujinx.Ui.Widgets;
using System;
using System.IO;

View File

@ -1,18 +1,10 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using ARMeilleure.Translation;
using ARMeilleure.Translation;
using ARMeilleure.Translation.PTC;
using Gtk;
using LibHac.Common;
using LibHac.Common.Keys;
using LibHac.FsSystem;
using LibHac.Ncm;
using LibHac.Ns;
using LibHac.Tools.FsSystem;
using Ryujinx.Audio.Backends.Dummy;
@ -29,7 +21,6 @@ using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.GAL.Multithreading;
using Ryujinx.Graphics.OpenGL;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.FileSystem.Content;
using Ryujinx.HLE.HOS;
using Ryujinx.HLE.HOS.Services.Account.Acc;
using Ryujinx.HLE.HOS.SystemState;
@ -42,9 +33,14 @@ using Ryujinx.Ui.Applet;
using Ryujinx.Ui.Helper;
using Ryujinx.Ui.Widgets;
using Ryujinx.Ui.Windows;
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using GUI = Gtk.Builder.ObjectAttribute;
using PtcLoadingState = ARMeilleure.Translation.PTC.PtcLoadingState;
using ShaderCacheLoadingState = Ryujinx.Graphics.Gpu.Shader.ShaderCacheState;
@ -1283,7 +1279,7 @@ namespace Ryujinx.Ui
private void Load_Mii_Edit_Applet(object sender, EventArgs args)
{
string contentPath = _contentManager.GetInstalledContentPath(0x0100000000001009, StorageId.NandSystem, NcaContentType.Program);
string contentPath = _contentManager.GetInstalledContentPath(0x0100000000001009, StorageId.BuiltInSystem, NcaContentType.Program);
LoadApplication(contentPath);
}

View File

@ -3,10 +3,10 @@ using LibHac.Common;
using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.FsSystem;
using LibHac.Ncm;
using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.FileSystem.Content;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats;
@ -115,7 +115,7 @@ namespace Ryujinx.Ui.Windows
return;
}
string contentPath = contentManager.GetInstalledContentPath(0x010000000000080A, StorageId.NandSystem, NcaContentType.Data);
string contentPath = contentManager.GetInstalledContentPath(0x010000000000080A, StorageId.BuiltInSystem, NcaContentType.Data);
string avatarPath = virtualFileSystem.SwitchPathToSystemPath(contentPath);
if (!string.IsNullOrWhiteSpace(avatarPath))

View File

@ -105,9 +105,9 @@ namespace Ryujinx.Ui.Windows
#pragma warning restore CS0649, IDE0044
public SettingsWindow(MainWindow parent, VirtualFileSystem virtualFileSystem, HLE.FileSystem.Content.ContentManager contentManager) : this(parent, new Builder("Ryujinx.Ui.Windows.SettingsWindow.glade"), virtualFileSystem, contentManager) { }
public SettingsWindow(MainWindow parent, VirtualFileSystem virtualFileSystem, ContentManager contentManager) : this(parent, new Builder("Ryujinx.Ui.Windows.SettingsWindow.glade"), virtualFileSystem, contentManager) { }
private SettingsWindow(MainWindow parent, Builder builder, VirtualFileSystem virtualFileSystem, HLE.FileSystem.Content.ContentManager contentManager) : base(builder.GetObject("_settingsWin").Handle)
private SettingsWindow(MainWindow parent, Builder builder, VirtualFileSystem virtualFileSystem, ContentManager contentManager) : base(builder.GetObject("_settingsWin").Handle)
{
Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Logo_Ryujinx.png");

View File

@ -1,6 +1,5 @@
using Gtk;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.FileSystem.Content;
using Ryujinx.HLE.HOS.Services.Account.Acc;
using Ryujinx.Ui.Widgets;
using SixLabors.ImageSharp;
@ -12,7 +11,7 @@ using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Image = SixLabors.ImageSharp.Image;
using Image = SixLabors.ImageSharp.Image;
using UserId = Ryujinx.HLE.HOS.Services.Account.Acc.UserId;
namespace Ryujinx.Ui.Windows