Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f449895e6d | ||
|
410be95ab6 | ||
|
cff9046fc7 |
@@ -462,7 +462,7 @@ namespace Ryujinx.Cpu
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_privateMemoryAllocator.Dispose();
|
_privateMemoryAllocator?.Dispose();
|
||||||
Base.Dispose();
|
Base.Dispose();
|
||||||
Mirror.Dispose();
|
Mirror.Dispose();
|
||||||
}
|
}
|
||||||
|
@@ -16,6 +16,7 @@ using Ryujinx.Common.Logging;
|
|||||||
using Ryujinx.HLE.HOS;
|
using Ryujinx.HLE.HOS;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers.Text;
|
using System.Buffers.Text;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
@@ -35,7 +36,8 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
public EmulatedGameCard GameCard { get; private set; }
|
public EmulatedGameCard GameCard { get; private set; }
|
||||||
public EmulatedSdCard SdCard { get; private set; }
|
public EmulatedSdCard SdCard { get; private set; }
|
||||||
public ModLoader ModLoader { get; private set; }
|
public ModLoader ModLoader { get; private set; }
|
||||||
public Stream RomFs { get; private set; }
|
|
||||||
|
private readonly ConcurrentDictionary<ulong, Stream> _romFsByPid;
|
||||||
|
|
||||||
private static bool _isInitialized = false;
|
private static bool _isInitialized = false;
|
||||||
|
|
||||||
@@ -55,17 +57,34 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
{
|
{
|
||||||
ReloadKeySet();
|
ReloadKeySet();
|
||||||
ModLoader = new ModLoader(); // Should only be created once
|
ModLoader = new ModLoader(); // Should only be created once
|
||||||
|
_romFsByPid = new ConcurrentDictionary<ulong, Stream>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadRomFs(string fileName)
|
public void LoadRomFs(ulong pid, string fileName)
|
||||||
{
|
{
|
||||||
RomFs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
|
var romfsStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
|
||||||
|
|
||||||
|
_romFsByPid.AddOrUpdate(pid, romfsStream, (pid, oldStream) =>
|
||||||
|
{
|
||||||
|
oldStream.Close();
|
||||||
|
|
||||||
|
return romfsStream;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetRomFs(Stream romfsStream)
|
public void SetRomFs(ulong pid, Stream romfsStream)
|
||||||
{
|
{
|
||||||
RomFs?.Close();
|
_romFsByPid.AddOrUpdate(pid, romfsStream, (pid, oldStream) =>
|
||||||
RomFs = romfsStream;
|
{
|
||||||
|
oldStream.Close();
|
||||||
|
|
||||||
|
return romfsStream;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stream GetRomFs(ulong pid)
|
||||||
|
{
|
||||||
|
return _romFsByPid[pid];
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetFullPath(string basePath, string fileName)
|
public string GetFullPath(string basePath, string fileName)
|
||||||
@@ -583,7 +602,12 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
RomFs?.Dispose();
|
foreach (var stream in _romFsByPid.Values)
|
||||||
|
{
|
||||||
|
stream.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
_romFsByPid.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -76,11 +76,6 @@ namespace Ryujinx.HLE.HOS
|
|||||||
|
|
||||||
public void LoadCart(string exeFsDir, string romFsFile = null)
|
public void LoadCart(string exeFsDir, string romFsFile = null)
|
||||||
{
|
{
|
||||||
if (romFsFile != null)
|
|
||||||
{
|
|
||||||
_device.Configuration.VirtualFileSystem.LoadRomFs(romFsFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalFileSystem codeFs = new LocalFileSystem(exeFsDir);
|
LocalFileSystem codeFs = new LocalFileSystem(exeFsDir);
|
||||||
|
|
||||||
MetaLoader metaData = ReadNpdm(codeFs);
|
MetaLoader metaData = ReadNpdm(codeFs);
|
||||||
@@ -95,7 +90,12 @@ namespace Ryujinx.HLE.HOS
|
|||||||
EnsureSaveData(new ApplicationId(TitleId));
|
EnsureSaveData(new ApplicationId(TitleId));
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadExeFs(codeFs, string.Empty, metaData);
|
ulong pid = LoadExeFs(codeFs, string.Empty, metaData);
|
||||||
|
|
||||||
|
if (romFsFile != null)
|
||||||
|
{
|
||||||
|
_device.Configuration.VirtualFileSystem.LoadRomFs(pid, romFsFile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (Nca main, Nca patch, Nca control) GetGameData(VirtualFileSystem fileSystem, PartitionFileSystem pfs, int programIndex)
|
public static (Nca main, Nca patch, Nca control) GetGameData(VirtualFileSystem fileSystem, PartitionFileSystem pfs, int programIndex)
|
||||||
@@ -491,6 +491,8 @@ namespace Ryujinx.HLE.HOS
|
|||||||
|
|
||||||
_displayVersion = displayVersion;
|
_displayVersion = displayVersion;
|
||||||
|
|
||||||
|
ulong pid = LoadExeFs(codeFs, displayVersion, metaData);
|
||||||
|
|
||||||
if (dataStorage == null)
|
if (dataStorage == null)
|
||||||
{
|
{
|
||||||
Logger.Warning?.Print(LogClass.Loader, "No RomFS found in NCA");
|
Logger.Warning?.Print(LogClass.Loader, "No RomFS found in NCA");
|
||||||
@@ -499,7 +501,7 @@ namespace Ryujinx.HLE.HOS
|
|||||||
{
|
{
|
||||||
IStorage newStorage = _device.Configuration.VirtualFileSystem.ModLoader.ApplyRomFsMods(TitleId, dataStorage);
|
IStorage newStorage = _device.Configuration.VirtualFileSystem.ModLoader.ApplyRomFsMods(TitleId, dataStorage);
|
||||||
|
|
||||||
_device.Configuration.VirtualFileSystem.SetRomFs(newStorage.AsStream(FileAccess.Read));
|
_device.Configuration.VirtualFileSystem.SetRomFs(pid, newStorage.AsStream(FileAccess.Read));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't create save data for system programs.
|
// Don't create save data for system programs.
|
||||||
@@ -510,8 +512,6 @@ namespace Ryujinx.HLE.HOS
|
|||||||
EnsureSaveData(new ApplicationId(TitleId & ~0xFul));
|
EnsureSaveData(new ApplicationId(TitleId & ~0xFul));
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadExeFs(codeFs, displayVersion, metaData);
|
|
||||||
|
|
||||||
Logger.Info?.Print(LogClass.Loader, $"Application Loaded: {TitleName} v{DisplayVersion} [{TitleIdText}] [{(TitleIs64Bit ? "64-bit" : "32-bit")}]");
|
Logger.Info?.Print(LogClass.Loader, $"Application Loaded: {TitleName} v{DisplayVersion} [{TitleIdText}] [{(TitleIs64Bit ? "64-bit" : "32-bit")}]");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -579,7 +579,7 @@ namespace Ryujinx.HLE.HOS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadExeFs(IFileSystem codeFs, string displayVersion, MetaLoader metaData = null, bool isHomebrew = false)
|
private ulong LoadExeFs(IFileSystem codeFs, string displayVersion, MetaLoader metaData = null, bool isHomebrew = false)
|
||||||
{
|
{
|
||||||
if (_device.Configuration.VirtualFileSystem.ModLoader.ReplaceExefsPartition(TitleId, ref codeFs))
|
if (_device.Configuration.VirtualFileSystem.ModLoader.ReplaceExefsPartition(TitleId, ref codeFs))
|
||||||
{
|
{
|
||||||
@@ -654,6 +654,8 @@ namespace Ryujinx.HLE.HOS
|
|||||||
DiskCacheLoadState = result.DiskCacheLoadState;
|
DiskCacheLoadState = result.DiskCacheLoadState;
|
||||||
|
|
||||||
_device.Configuration.VirtualFileSystem.ModLoader.LoadCheats(TitleId, result.TamperInfo, _device.TamperMachine);
|
_device.Configuration.VirtualFileSystem.ModLoader.LoadCheats(TitleId, result.TamperInfo, _device.TamperMachine);
|
||||||
|
|
||||||
|
return result.ProcessId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadProgram(string filePath)
|
public void LoadProgram(string filePath)
|
||||||
@@ -665,6 +667,7 @@ namespace Ryujinx.HLE.HOS
|
|||||||
bool isNro = Path.GetExtension(filePath).ToLower() == ".nro";
|
bool isNro = Path.GetExtension(filePath).ToLower() == ".nro";
|
||||||
|
|
||||||
IExecutable executable;
|
IExecutable executable;
|
||||||
|
Stream romfsStream = null;
|
||||||
|
|
||||||
if (isNro)
|
if (isNro)
|
||||||
{
|
{
|
||||||
@@ -697,7 +700,7 @@ namespace Ryujinx.HLE.HOS
|
|||||||
|
|
||||||
if (romfsSize != 0)
|
if (romfsSize != 0)
|
||||||
{
|
{
|
||||||
_device.Configuration.VirtualFileSystem.SetRomFs(new HomebrewRomFsStream(input, obj.FileSize + (long)romfsOffset));
|
romfsStream = new HomebrewRomFsStream(input, obj.FileSize + (long)romfsOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nacpSize != 0)
|
if (nacpSize != 0)
|
||||||
@@ -758,6 +761,11 @@ namespace Ryujinx.HLE.HOS
|
|||||||
|
|
||||||
ProgramLoadResult result = ProgramLoader.LoadNsos(_device.System.KernelContext, metaData, programInfo, executables: executable);
|
ProgramLoadResult result = ProgramLoader.LoadNsos(_device.System.KernelContext, metaData, programInfo, executables: executable);
|
||||||
|
|
||||||
|
if (romfsStream != null)
|
||||||
|
{
|
||||||
|
_device.Configuration.VirtualFileSystem.SetRomFs(result.ProcessId, romfsStream);
|
||||||
|
}
|
||||||
|
|
||||||
DiskCacheLoadState = result.DiskCacheLoadState;
|
DiskCacheLoadState = result.DiskCacheLoadState;
|
||||||
|
|
||||||
_device.Configuration.VirtualFileSystem.ModLoader.LoadCheats(TitleId, result.TamperInfo, _device.TamperMachine);
|
_device.Configuration.VirtualFileSystem.ModLoader.LoadCheats(TitleId, result.TamperInfo, _device.TamperMachine);
|
||||||
|
@@ -41,17 +41,19 @@ namespace Ryujinx.HLE.HOS
|
|||||||
|
|
||||||
struct ProgramLoadResult
|
struct ProgramLoadResult
|
||||||
{
|
{
|
||||||
public static ProgramLoadResult Failed => new ProgramLoadResult(false, null, null);
|
public static ProgramLoadResult Failed => new ProgramLoadResult(false, null, null, 0);
|
||||||
|
|
||||||
public readonly bool Success;
|
public readonly bool Success;
|
||||||
public readonly ProcessTamperInfo TamperInfo;
|
public readonly ProcessTamperInfo TamperInfo;
|
||||||
public readonly IDiskCacheLoadState DiskCacheLoadState;
|
public readonly IDiskCacheLoadState DiskCacheLoadState;
|
||||||
|
public readonly ulong ProcessId;
|
||||||
|
|
||||||
public ProgramLoadResult(bool success, ProcessTamperInfo tamperInfo, IDiskCacheLoadState diskCacheLoadState)
|
public ProgramLoadResult(bool success, ProcessTamperInfo tamperInfo, IDiskCacheLoadState diskCacheLoadState, ulong pid)
|
||||||
{
|
{
|
||||||
Success = success;
|
Success = success;
|
||||||
TamperInfo = tamperInfo;
|
TamperInfo = tamperInfo;
|
||||||
DiskCacheLoadState = diskCacheLoadState;
|
DiskCacheLoadState = diskCacheLoadState;
|
||||||
|
ProcessId = pid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,7 +368,7 @@ namespace Ryujinx.HLE.HOS
|
|||||||
process.MemoryManager.AliasRegionStart,
|
process.MemoryManager.AliasRegionStart,
|
||||||
process.MemoryManager.CodeRegionStart);
|
process.MemoryManager.CodeRegionStart);
|
||||||
|
|
||||||
return new ProgramLoadResult(true, tamperInfo, processContextFactory.DiskCacheLoadState);
|
return new ProgramLoadResult(true, tamperInfo, processContextFactory.DiskCacheLoadState, process.Pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Result LoadIntoMemory(KProcess process, IExecutable image, ulong baseAddress)
|
private static Result LoadIntoMemory(KProcess process, IExecutable image, ulong baseAddress)
|
||||||
|
@@ -27,6 +27,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs
|
|||||||
class IFileSystemProxy : DisposableIpcService
|
class IFileSystemProxy : DisposableIpcService
|
||||||
{
|
{
|
||||||
private SharedRef<LibHac.FsSrv.Sf.IFileSystemProxy> _baseFileSystemProxy;
|
private SharedRef<LibHac.FsSrv.Sf.IFileSystemProxy> _baseFileSystemProxy;
|
||||||
|
private ulong _pid;
|
||||||
|
|
||||||
public IFileSystemProxy(ServiceCtx context) : base(context.Device.System.FsServer)
|
public IFileSystemProxy(ServiceCtx context) : base(context.Device.System.FsServer)
|
||||||
{
|
{
|
||||||
@@ -38,6 +39,8 @@ namespace Ryujinx.HLE.HOS.Services.Fs
|
|||||||
// SetCurrentProcess(u64, pid)
|
// SetCurrentProcess(u64, pid)
|
||||||
public ResultCode SetCurrentProcess(ServiceCtx context)
|
public ResultCode SetCurrentProcess(ServiceCtx context)
|
||||||
{
|
{
|
||||||
|
_pid = context.Request.HandleDesc.PId;
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -702,7 +705,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs
|
|||||||
// OpenDataStorageByCurrentProcess() -> object<nn::fssrv::sf::IStorage> dataStorage
|
// OpenDataStorageByCurrentProcess() -> object<nn::fssrv::sf::IStorage> dataStorage
|
||||||
public ResultCode OpenDataStorageByCurrentProcess(ServiceCtx context)
|
public ResultCode OpenDataStorageByCurrentProcess(ServiceCtx context)
|
||||||
{
|
{
|
||||||
var storage = context.Device.FileSystem.RomFs.AsStorage(true);
|
var storage = context.Device.FileSystem.GetRomFs(_pid).AsStorage(true);
|
||||||
using var sharedStorage = new SharedRef<LibHac.Fs.IStorage>(storage);
|
using var sharedStorage = new SharedRef<LibHac.Fs.IStorage>(storage);
|
||||||
using var sfStorage = new SharedRef<IStorage>(new StorageInterfaceAdapter(ref sharedStorage.Ref()));
|
using var sfStorage = new SharedRef<IStorage>(new StorageInterfaceAdapter(ref sharedStorage.Ref()));
|
||||||
|
|
||||||
@@ -791,7 +794,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs
|
|||||||
// OpenPatchDataStorageByCurrentProcess() -> object<nn::fssrv::sf::IStorage>
|
// OpenPatchDataStorageByCurrentProcess() -> object<nn::fssrv::sf::IStorage>
|
||||||
public ResultCode OpenPatchDataStorageByCurrentProcess(ServiceCtx context)
|
public ResultCode OpenPatchDataStorageByCurrentProcess(ServiceCtx context)
|
||||||
{
|
{
|
||||||
var storage = context.Device.FileSystem.RomFs.AsStorage(true);
|
var storage = context.Device.FileSystem.GetRomFs(_pid).AsStorage(true);
|
||||||
using var sharedStorage = new SharedRef<LibHac.Fs.IStorage>(storage);
|
using var sharedStorage = new SharedRef<LibHac.Fs.IStorage>(storage);
|
||||||
using var sfStorage = new SharedRef<IStorage>(new StorageInterfaceAdapter(ref sharedStorage.Ref()));
|
using var sfStorage = new SharedRef<IStorage>(new StorageInterfaceAdapter(ref sharedStorage.Ref()));
|
||||||
|
|
||||||
@@ -811,7 +814,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs
|
|||||||
throw new NotImplementedException($"Accessing storage from other programs is not supported (program index = {programIndex}).");
|
throw new NotImplementedException($"Accessing storage from other programs is not supported (program index = {programIndex}).");
|
||||||
}
|
}
|
||||||
|
|
||||||
var storage = context.Device.FileSystem.RomFs.AsStorage(true);
|
var storage = context.Device.FileSystem.GetRomFs(_pid).AsStorage(true);
|
||||||
using var sharedStorage = new SharedRef<LibHac.Fs.IStorage>(storage);
|
using var sharedStorage = new SharedRef<LibHac.Fs.IStorage>(storage);
|
||||||
using var sfStorage = new SharedRef<IStorage>(new StorageInterfaceAdapter(ref sharedStorage.Ref()));
|
using var sfStorage = new SharedRef<IStorage>(new StorageInterfaceAdapter(ref sharedStorage.Ref()));
|
||||||
|
|
||||||
|
@@ -617,7 +617,7 @@ namespace Ryujinx.Ui.Common.Configuration
|
|||||||
Graphics.ResScaleCustom.Value = 1.0f;
|
Graphics.ResScaleCustom.Value = 1.0f;
|
||||||
Graphics.MaxAnisotropy.Value = -1.0f;
|
Graphics.MaxAnisotropy.Value = -1.0f;
|
||||||
Graphics.AspectRatio.Value = AspectRatio.Fixed16x9;
|
Graphics.AspectRatio.Value = AspectRatio.Fixed16x9;
|
||||||
Graphics.GraphicsBackend.Value = GraphicsBackend.OpenGl;
|
Graphics.GraphicsBackend.Value = OperatingSystem.IsMacOS() ? GraphicsBackend.Vulkan : GraphicsBackend.OpenGl;
|
||||||
Graphics.PreferredGpu.Value = "";
|
Graphics.PreferredGpu.Value = "";
|
||||||
Graphics.ShadersDumpPath.Value = "";
|
Graphics.ShadersDumpPath.Value = "";
|
||||||
Logger.EnableDebug.Value = false;
|
Logger.EnableDebug.Value = false;
|
||||||
|
Reference in New Issue
Block a user