diff options
Diffstat (limited to 'Ryujinx.Core')
| -rw-r--r-- | Ryujinx.Core/Loaders/Executable.cs | 4 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Handles/HSharedMem.cs | 2 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Homebrew.cs | 2 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Horizon.cs | 23 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/MemoryInfo.cs | 28 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/MemoryRegions.cs | 21 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Process.cs | 52 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Svc/SvcHandler.cs | 3 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Svc/SvcMemory.cs | 65 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Svc/SvcSystem.cs | 128 | ||||
| -rw-r--r-- | Ryujinx.Core/VirtualFs.cs | 12 |
11 files changed, 175 insertions, 165 deletions
diff --git a/Ryujinx.Core/Loaders/Executable.cs b/Ryujinx.Core/Loaders/Executable.cs index 95cb7d6f..fa204460 100644 --- a/Ryujinx.Core/Loaders/Executable.cs +++ b/Ryujinx.Core/Loaders/Executable.cs @@ -96,7 +96,7 @@ namespace Ryujinx.Core.Loaders MemoryType Type, AMemoryPerm Perm) { - Memory.Manager.MapPhys(Position, Data.Count, (int)Type, AMemoryPerm.Write); + Memory.Manager.Map(Position, Data.Count, (int)Type, AMemoryPerm.Write); for (int Index = 0; Index < Data.Count; Index++) { @@ -108,7 +108,7 @@ namespace Ryujinx.Core.Loaders private void MapBss(long Position, long Size) { - Memory.Manager.MapPhys(Position, Size, (int)MemoryType.Normal, AMemoryPerm.RW); + Memory.Manager.Map(Position, Size, (int)MemoryType.Normal, AMemoryPerm.RW); } private ElfRel GetRelocation(long Position) diff --git a/Ryujinx.Core/OsHle/Handles/HSharedMem.cs b/Ryujinx.Core/OsHle/Handles/HSharedMem.cs index 3d56ff92..9cd0a0d4 100644 --- a/Ryujinx.Core/OsHle/Handles/HSharedMem.cs +++ b/Ryujinx.Core/OsHle/Handles/HSharedMem.cs @@ -12,7 +12,7 @@ namespace Ryujinx.Core.OsHle.Handles public EventHandler<EventArgs> MemoryMapped; public EventHandler<EventArgs> MemoryUnmapped; - public HSharedMem(long PhysPos) + public HSharedMem() { Positions = new List<long>(); } diff --git a/Ryujinx.Core/OsHle/Homebrew.cs b/Ryujinx.Core/OsHle/Homebrew.cs index f177b37e..e2e95e4d 100644 --- a/Ryujinx.Core/OsHle/Homebrew.cs +++ b/Ryujinx.Core/OsHle/Homebrew.cs @@ -7,7 +7,7 @@ namespace Ryujinx.Core.OsHle //http://switchbrew.org/index.php?title=Homebrew_ABI public static void WriteHbAbiData(AMemory Memory, long Position, int MainThreadHandle) { - Memory.Manager.MapPhys(Position, AMemoryMgr.PageSize, (int)MemoryType.Normal, AMemoryPerm.RW); + Memory.Manager.Map(Position, AMemoryMgr.PageSize, (int)MemoryType.Normal, AMemoryPerm.RW); //MainThreadHandle WriteConfigEntry(Memory, ref Position, 1, 0, MainThreadHandle); diff --git a/Ryujinx.Core/OsHle/Horizon.cs b/Ryujinx.Core/OsHle/Horizon.cs index 9929102d..c2389143 100644 --- a/Ryujinx.Core/OsHle/Horizon.cs +++ b/Ryujinx.Core/OsHle/Horizon.cs @@ -1,4 +1,3 @@ -using ChocolArm64.Memory; using Ryujinx.Core.Loaders.Executables; using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Utilities; @@ -16,9 +15,6 @@ namespace Ryujinx.Core.OsHle internal int HidHandle { get; private set; } internal int FontHandle { get; private set; } - public long HidOffset { get; private set; } - public long FontOffset { get; private set; } - internal IdPool IdGen { get; private set; } internal IdPool NvMapIds { get; private set; } @@ -33,8 +29,6 @@ namespace Ryujinx.Core.OsHle private HSharedMem HidSharedMem; - private AMemoryAlloc Allocator; - private Switch Ns; public Horizon(Switch Ns) @@ -53,18 +47,13 @@ namespace Ryujinx.Core.OsHle Processes = new ConcurrentDictionary<int, Process>(); - Allocator = new AMemoryAlloc(); - - HidOffset = Allocator.Alloc(HidSize); - FontOffset = Allocator.Alloc(FontSize); - - HidSharedMem = new HSharedMem(HidOffset); + HidSharedMem = new HSharedMem(); HidSharedMem.MemoryMapped += HidInit; HidHandle = Handles.GenerateId(HidSharedMem); - FontHandle = Handles.GenerateId(new HSharedMem(FontOffset)); + FontHandle = Handles.GenerateId(new HSharedMem()); } public void LoadCart(string ExeFsDir, string RomFsFile = null) @@ -76,7 +65,7 @@ namespace Ryujinx.Core.OsHle int ProcessId = IdGen.GenerateId(); - Process MainProcess = new Process(Ns, Allocator, ProcessId); + Process MainProcess = new Process(Ns, ProcessId); void LoadNso(string FileName) { @@ -106,7 +95,6 @@ namespace Ryujinx.Core.OsHle LoadNso("subsdk*"); LoadNso("sdk"); - MainProcess.InitializeHeap(); MainProcess.Run(); Processes.TryAdd(ProcessId, MainProcess); @@ -118,7 +106,7 @@ namespace Ryujinx.Core.OsHle int ProcessId = IdGen.GenerateId(); - Process MainProcess = new Process(Ns, Allocator, ProcessId); + Process MainProcess = new Process(Ns, ProcessId); using (FileStream Input = new FileStream(FileName, FileMode.Open)) { @@ -128,7 +116,6 @@ namespace Ryujinx.Core.OsHle } MainProcess.SetEmptyArgs(); - MainProcess.InitializeHeap(); MainProcess.Run(IsNro); Processes.TryAdd(ProcessId, MainProcess); @@ -186,7 +173,7 @@ namespace Ryujinx.Core.OsHle if (SharedMem.TryGetLastVirtualPosition(out long Position)) { - Logging.Info($"HID shared memory successfully mapped to {Position:x16}!"); + Logging.Info($"HID shared memory successfully mapped to 0x{Position:x16}!"); Ns.Hid.Init(Position); } diff --git a/Ryujinx.Core/OsHle/MemoryInfo.cs b/Ryujinx.Core/OsHle/MemoryInfo.cs deleted file mode 100644 index 76a4bef3..00000000 --- a/Ryujinx.Core/OsHle/MemoryInfo.cs +++ /dev/null @@ -1,28 +0,0 @@ -using ChocolArm64.Memory; - -namespace Ryujinx.Core.OsHle -{ - struct MemoryInfo - { - public long BaseAddress; - public long Size; - public int MemType; - public int MemAttr; - public int MemPerm; - public int IpcRefCount; - public int DeviceRefCount; - public int Padding; //SBZ - - public MemoryInfo(AMemoryMapInfo MapInfo) - { - BaseAddress = MapInfo.Position; - Size = MapInfo.Size; - MemType = MapInfo.Type; - MemAttr = MapInfo.Attr; - MemPerm = (int)MapInfo.Perm; - IpcRefCount = 0; - DeviceRefCount = 0; - Padding = 0; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Core/OsHle/MemoryRegions.cs b/Ryujinx.Core/OsHle/MemoryRegions.cs index 86d266f6..3b690426 100644 --- a/Ryujinx.Core/OsHle/MemoryRegions.cs +++ b/Ryujinx.Core/OsHle/MemoryRegions.cs @@ -1,11 +1,28 @@ +using ChocolArm64.Memory; + namespace Ryujinx.Core.OsHle { static class MemoryRegions { - public const long MapRegionAddress = 0x80000000; + public const long AddrSpaceStart = 0x08000000; + + public const long MapRegionAddress = 0x10000000; public const long MapRegionSize = 0x40000000; + public const long MainStackSize = 0x100000; + + public const long MainStackAddress = AMemoryMgr.AddrSize - MainStackSize; + + public const long TlsPagesSize = 0x4000; + + public const long TlsPagesAddress = MainStackAddress - TlsPagesSize; + public const long HeapRegionAddress = MapRegionAddress + MapRegionSize; - public const long HeapRegionSize = 0x40000000; + + public const long TotalMemoryUsed = HeapRegionAddress + TlsPagesSize + MainStackSize; + + public const long TotalMemoryAvailable = AMemoryMgr.RamSize - AddrSpaceStart; + + public const long AddrSpaceSize = AMemoryMgr.AddrSize - AddrSpaceStart; } }
\ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Process.cs b/Ryujinx.Core/OsHle/Process.cs index 9ca9a2bd..f0b568c8 100644 --- a/Ryujinx.Core/OsHle/Process.cs +++ b/Ryujinx.Core/OsHle/Process.cs @@ -15,19 +15,15 @@ namespace Ryujinx.Core.OsHle { public class Process : IDisposable { - private const int MaxStackSize = 8 * 1024 * 1024; - private const int TlsSize = 0x200; private const int TotalTlsSlots = 32; - private const int TlsTotalSize = TotalTlsSlots * TlsSize; - private const long TlsPageAddr = (AMemoryMgr.AddrSize - TlsTotalSize) & ~AMemoryMgr.PageMask; private Switch Ns; - private ATranslator Translator; - public int ProcessId { get; private set; } + private ATranslator Translator; + public AMemory Memory { get; private set; } public KProcessScheduler Scheduler { get; private set; } @@ -44,12 +40,12 @@ namespace Ryujinx.Core.OsHle private long ImageBase; - public Process(Switch Ns, AMemoryAlloc Allocator, int ProcessId) + public Process(Switch Ns, int ProcessId) { this.Ns = Ns; this.ProcessId = ProcessId; - Memory = new AMemory(Ns.Ram, Allocator); + Memory = new AMemory(Ns.Ram); Scheduler = new KProcessScheduler(); @@ -61,13 +57,12 @@ namespace Ryujinx.Core.OsHle Executables = new List<Executable>(); - ImageBase = 0x8000000; + ImageBase = MemoryRegions.AddrSpaceStart; - Memory.Manager.MapPhys( - TlsPageAddr, - TlsTotalSize, - (int)MemoryType.ThreadLocal, - AMemoryPerm.RW); + MapRWMemRegion( + MemoryRegions.TlsPagesAddress, + MemoryRegions.TlsPagesSize, + MemoryType.ThreadLocal); } public void LoadProgram(IExecutable Program) @@ -86,11 +81,6 @@ namespace Ryujinx.Core.OsHle ImageBase += AMemoryMgr.PageSize; } - public void InitializeHeap() - { - Memory.Manager.SetHeapAddr(MemoryRegions.HeapRegionAddress); - } - public bool Run(bool UseHbAbi = false) { if (Executables.Count == 0) @@ -98,11 +88,14 @@ namespace Ryujinx.Core.OsHle return false; } - long StackBot = TlsPageAddr - MaxStackSize; - - Memory.Manager.MapPhys(StackBot, MaxStackSize, (int)MemoryType.Normal, AMemoryPerm.RW); + MapRWMemRegion( + MemoryRegions.MainStackAddress, + MemoryRegions.MainStackSize, + MemoryType.Normal); + + long StackTop = MemoryRegions.MainStackAddress + MemoryRegions.MainStackSize; - int Handle = MakeThread(Executables[0].ImageBase, TlsPageAddr, 0, 0, 0); + int Handle = MakeThread(Executables[0].ImageBase, StackTop, 0, 0, 0); if (Handle == -1) { @@ -113,7 +106,7 @@ namespace Ryujinx.Core.OsHle if (UseHbAbi) { - long HbAbiDataPosition = (Executables[0].ImageEnd + 0xfff) & ~0xfff; + long HbAbiDataPosition = AMemoryHelper.PageRoundUp(Executables[0].ImageEnd); Homebrew.WriteHbAbiData(Memory, HbAbiDataPosition, Handle); @@ -126,6 +119,11 @@ namespace Ryujinx.Core.OsHle return true; } + private void MapRWMemRegion(long Position, long Size, MemoryType Type) + { + Memory.Manager.Map(Position, Size, (int)Type, AMemoryPerm.RW); + } + public void StopAllThreads() { if (MainThread != null) @@ -188,12 +186,14 @@ namespace Ryujinx.Core.OsHle return -1; } + long Tpidr = MemoryRegions.TlsPagesAddress + TlsSlot * TlsSize; + Thread.ThreadState.Break += BreakHandler; Thread.ThreadState.SvcCall += SvcHandler.SvcCall; Thread.ThreadState.Undefined += UndefinedHandler; Thread.ThreadState.ProcessId = ProcessId; Thread.ThreadState.ThreadId = Ns.Os.IdGen.GenerateId(); - Thread.ThreadState.Tpidr = TlsPageAddr + TlsSlot * TlsSize; + Thread.ThreadState.Tpidr = Tpidr; Thread.ThreadState.X0 = (ulong)ArgsPtr; Thread.ThreadState.X1 = (ulong)Handle; Thread.ThreadState.X31 = (ulong)StackTop; @@ -267,7 +267,7 @@ namespace Ryujinx.Core.OsHle private int GetTlsSlot(long Position) { - return (int)((Position - TlsPageAddr) / TlsSize); + return (int)((Position - MemoryRegions.TlsPagesAddress) / TlsSize); } public HThread GetThread(long Tpidr) diff --git a/Ryujinx.Core/OsHle/Svc/SvcHandler.cs b/Ryujinx.Core/OsHle/Svc/SvcHandler.cs index ec53f47f..212d30a6 100644 --- a/Ryujinx.Core/OsHle/Svc/SvcHandler.cs +++ b/Ryujinx.Core/OsHle/Svc/SvcHandler.cs @@ -17,6 +17,8 @@ namespace Ryujinx.Core.OsHle.Svc private AMemory Memory; private static Random Rng; + + private ulong CurrentHeapSize; public SvcHandler(Switch Ns, Process Process) { @@ -25,6 +27,7 @@ namespace Ryujinx.Core.OsHle.Svc { 0x01, SvcSetHeapSize }, { 0x03, SvcSetMemoryAttribute }, { 0x04, SvcMapMemory }, + { 0x05, SvcUnmapMemory }, { 0x06, SvcQueryMemory }, { 0x07, SvcExitProcess }, { 0x08, SvcCreateThread }, diff --git a/Ryujinx.Core/OsHle/Svc/SvcMemory.cs b/Ryujinx.Core/OsHle/Svc/SvcMemory.cs index 6ca27f16..e7559a14 100644 --- a/Ryujinx.Core/OsHle/Svc/SvcMemory.cs +++ b/Ryujinx.Core/OsHle/Svc/SvcMemory.cs @@ -10,10 +10,21 @@ namespace Ryujinx.Core.OsHle.Svc { uint Size = (uint)ThreadState.X1; - Memory.Manager.SetHeapSize(Size, (int)MemoryType.Heap); + long Position = MemoryRegions.HeapRegionAddress; + + if (Size > CurrentHeapSize) + { + Memory.Manager.Map(Position, Size, (int)MemoryType.Heap, AMemoryPerm.RW); + } + else + { + Memory.Manager.Unmap(Position + Size, (long)CurrentHeapSize - Size); + } + + CurrentHeapSize = Size; ThreadState.X0 = (int)SvcResult.Success; - ThreadState.X1 = (ulong)Memory.Manager.HeapAddr; + ThreadState.X1 = (ulong)Position; } private void SvcSetMemoryAttribute(AThreadState ThreadState) @@ -42,7 +53,30 @@ namespace Ryujinx.Core.OsHle.Svc long Src = (long)ThreadState.X1; long Size = (long)ThreadState.X2; - Memory.Manager.MapMirror(Src, Dst, Size, (int)MemoryType.MappedMemory); + AMemoryMapInfo SrcInfo = Memory.Manager.GetMapInfo(Src); + + Memory.Manager.Map(Dst, Size, (int)MemoryType.MappedMemory, SrcInfo.Perm); + + Memory.Manager.Reprotect(Src, Size, AMemoryPerm.None); + + Memory.Manager.SetAttrBit(Src, Size, 0); + + ThreadState.X0 = (int)SvcResult.Success; + } + + private void SvcUnmapMemory(AThreadState ThreadState) + { + long Dst = (long)ThreadState.X0; + long Src = (long)ThreadState.X1; + long Size = (long)ThreadState.X2; + + AMemoryMapInfo DstInfo = Memory.Manager.GetMapInfo(Dst); + + Memory.Manager.Unmap(Dst, Size, (int)MemoryType.MappedMemory); + + Memory.Manager.Reprotect(Src, Size, DstInfo.Perm); + + Memory.Manager.ClearAttrBit(Src, Size, 0); ThreadState.X0 = (int)SvcResult.Success; } @@ -54,17 +88,22 @@ namespace Ryujinx.Core.OsHle.Svc AMemoryMapInfo MapInfo = Memory.Manager.GetMapInfo(Position); - MemoryInfo Info = new MemoryInfo(MapInfo); + if (MapInfo == null) + { + //TODO: Correct error code. + ThreadState.X0 = ulong.MaxValue; - Memory.WriteInt64(InfoPtr + 0x00, Info.BaseAddress); - Memory.WriteInt64(InfoPtr + 0x08, Info.Size); - Memory.WriteInt32(InfoPtr + 0x10, Info.MemType); - Memory.WriteInt32(InfoPtr + 0x14, Info.MemAttr); - Memory.WriteInt32(InfoPtr + 0x18, Info.MemPerm); - Memory.WriteInt32(InfoPtr + 0x1c, Info.IpcRefCount); - Memory.WriteInt32(InfoPtr + 0x20, Info.DeviceRefCount); - Memory.WriteInt32(InfoPtr + 0x24, Info.Padding); + return; + } + Memory.WriteInt64(InfoPtr + 0x00, MapInfo.Position); + Memory.WriteInt64(InfoPtr + 0x08, MapInfo.Size); + Memory.WriteInt32(InfoPtr + 0x10, MapInfo.Type); + Memory.WriteInt32(InfoPtr + 0x14, MapInfo.Attr); + Memory.WriteInt32(InfoPtr + 0x18, (int)MapInfo.Perm); + Memory.WriteInt32(InfoPtr + 0x1c, 0); + Memory.WriteInt32(InfoPtr + 0x20, 0); + Memory.WriteInt32(InfoPtr + 0x24, 0); //TODO: X1. ThreadState.X0 = (int)SvcResult.Success; @@ -84,7 +123,7 @@ namespace Ryujinx.Core.OsHle.Svc { SharedMem.AddVirtualPosition(Src); - Memory.Manager.MapPhys(Src, Size, (int)MemoryType.SharedMemory, (AMemoryPerm)Perm); + Memory.Manager.Map(Src, Size, (int)MemoryType.SharedMemory, (AMemoryPerm)Perm); ThreadState.X0 = (int)SvcResult.Success; } diff --git a/Ryujinx.Core/OsHle/Svc/SvcSystem.cs b/Ryujinx.Core/OsHle/Svc/SvcSystem.cs index 3b9142c7..51b2e26c 100644 --- a/Ryujinx.Core/OsHle/Svc/SvcSystem.cs +++ b/Ryujinx.Core/OsHle/Svc/SvcSystem.cs @@ -11,7 +11,14 @@ namespace Ryujinx.Core.OsHle.Svc { partial class SvcHandler { - private void SvcExitProcess(AThreadState ThreadState) => Ns.Os.ExitProcess(ThreadState.ProcessId); + private const int AllowedCpuIdBitmask = 0b1111; + + private const bool EnableProcessDebugging = false; + + private void SvcExitProcess(AThreadState ThreadState) + { + Ns.Os.ExitProcess(ThreadState.ProcessId); + } private void SvcCloseHandle(AThreadState ThreadState) { @@ -162,79 +169,62 @@ namespace Ryujinx.Core.OsHle.Svc switch (InfoType) { - case 0: ThreadState.X1 = AllowedCpuIdBitmask(); break; - case 2: ThreadState.X1 = GetMapRegionBaseAddr(); break; - case 3: ThreadState.X1 = GetMapRegionSize(); break; - case 4: ThreadState.X1 = GetHeapRegionBaseAddr(); break; - case 5: ThreadState.X1 = GetHeapRegionSize(); break; - case 6: ThreadState.X1 = GetTotalMem(); break; - case 7: ThreadState.X1 = GetUsedMem(); break; - case 8: ThreadState.X1 = IsCurrentProcessBeingDebugged(); break; - case 11: ThreadState.X1 = GetRnd64(); break; - case 12: ThreadState.X1 = GetAddrSpaceBaseAddr(); break; - case 13: ThreadState.X1 = GetAddrSpaceSize(); break; - case 14: ThreadState.X1 = GetMapRegionBaseAddr(); break; - case 15: ThreadState.X1 = GetMapRegionSize(); break; + case 0: + ThreadState.X1 = AllowedCpuIdBitmask; + break; + + case 2: + ThreadState.X1 = MemoryRegions.MapRegionAddress; + break; + + case 3: + ThreadState.X1 = MemoryRegions.MapRegionSize; + break; + + case 4: + ThreadState.X1 = MemoryRegions.HeapRegionAddress; + break; + + case 5: + ThreadState.X1 = CurrentHeapSize; + break; + + case 6: + ThreadState.X1 = MemoryRegions.TotalMemoryAvailable; + break; + + case 7: + ThreadState.X1 = MemoryRegions.TotalMemoryUsed + CurrentHeapSize; + break; + + case 8: + ThreadState.X1 = EnableProcessDebugging ? 1 : 0; + break; + + case 11: + ThreadState.X1 = (ulong)Rng.Next() + ((ulong)Rng.Next() << 32); + break; + + case 12: + ThreadState.X1 = MemoryRegions.AddrSpaceStart; + break; + + case 13: + ThreadState.X1 = MemoryRegions.AddrSpaceSize; + break; + + case 14: + ThreadState.X1 = MemoryRegions.MapRegionAddress; + break; + + case 15: + ThreadState.X1 = MemoryRegions.MapRegionSize; + break; default: throw new NotImplementedException($"SvcGetInfo: {InfoType} {Handle} {InfoId}"); } ThreadState.X0 = (int)SvcResult.Success; } - - private ulong AllowedCpuIdBitmask() - { - return 0xF; //Mephisto value. - } - - private ulong GetMapRegionBaseAddr() - { - return MemoryRegions.MapRegionAddress; - } - - private ulong GetMapRegionSize() - { - return MemoryRegions.MapRegionSize; - } - - private ulong GetHeapRegionBaseAddr() - { - return MemoryRegions.HeapRegionAddress; - } - - private ulong GetHeapRegionSize() - { - return MemoryRegions.HeapRegionSize; - } - - private ulong GetTotalMem() - { - return (ulong)Memory.Manager.GetTotalMemorySize(); - } - - private ulong GetUsedMem() - { - return (ulong)Memory.Manager.GetUsedMemorySize(); - } - - private ulong IsCurrentProcessBeingDebugged() - { - return (ulong)0; - } - - private ulong GetRnd64() - { - return (ulong)Rng.Next() + ((ulong)Rng.Next() << 32); - } - - private ulong GetAddrSpaceBaseAddr() - { - return 0x08000000; - } - - private ulong GetAddrSpaceSize() - { - return AMemoryMgr.AddrSize - GetAddrSpaceBaseAddr(); - } } } diff --git a/Ryujinx.Core/VirtualFs.cs b/Ryujinx.Core/VirtualFs.cs index 0c911116..195fb6a3 100644 --- a/Ryujinx.Core/VirtualFs.cs +++ b/Ryujinx.Core/VirtualFs.cs @@ -5,9 +5,9 @@ namespace Ryujinx.Core { class VirtualFs : IDisposable { - private const string BasePath = "Fs"; - private const string SavesPath = "Saves"; - private const string SdCardPath = "SdCard"; + private const string BasePath = "RyuFs"; + private const string NandPath = "nand"; + private const string SdCardPath = "sdmc"; public Stream RomFs { get; private set; } @@ -35,7 +35,7 @@ namespace Ryujinx.Core public string GetSdCardPath() => MakeDirAndGetFullPath(SdCardPath); - public string GetGameSavesPath() => MakeDirAndGetFullPath(SavesPath); + public string GetGameSavesPath() => MakeDirAndGetFullPath(NandPath); private string MakeDirAndGetFullPath(string Dir) { @@ -56,7 +56,9 @@ namespace Ryujinx.Core public string GetBasePath() { - return Path.Combine(Directory.GetCurrentDirectory(), BasePath); + string AppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + + return Path.Combine(AppDataPath, BasePath); } public void Dispose() |
