aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx.HLE/Loaders/Executable.cs6
-rw-r--r--Ryujinx.HLE/Loaders/Executables/IExecutable.cs2
-rw-r--r--Ryujinx.HLE/Loaders/Executables/Nro.cs6
-rw-r--r--Ryujinx.HLE/Loaders/Executables/Nso.cs4
-rw-r--r--Ryujinx.HLE/OsHle/Homebrew.cs10
-rw-r--r--Ryujinx.HLE/OsHle/Horizon.cs29
-rw-r--r--Ryujinx.HLE/OsHle/Process.cs10
-rw-r--r--Ryujinx.HLE/Switch.cs3
-rw-r--r--Ryujinx.HLE/VirtualFileSystem.cs29
-rw-r--r--Ryujinx/Ui/Program.cs1
10 files changed, 84 insertions, 16 deletions
diff --git a/Ryujinx.HLE/Loaders/Executable.cs b/Ryujinx.HLE/Loaders/Executable.cs
index 618ee241..43193245 100644
--- a/Ryujinx.HLE/Loaders/Executable.cs
+++ b/Ryujinx.HLE/Loaders/Executable.cs
@@ -2,6 +2,7 @@ using ChocolArm64.Memory;
using Ryujinx.HLE.Loaders.Executables;
using Ryujinx.HLE.OsHle;
using System.Collections.Generic;
+using System.IO;
namespace Ryujinx.HLE.Loaders
{
@@ -15,6 +16,8 @@ namespace Ryujinx.HLE.Loaders
public string Name { get; private set; }
+ public string FilePath { get; private set; }
+
private AMemory Memory;
public long ImageBase { get; private set; }
@@ -26,8 +29,9 @@ namespace Ryujinx.HLE.Loaders
m_SymbolTable = new Dictionary<long, string>();
- Name = Exe.Name;
+ FilePath = Exe.FilePath;
+ Name = Path.GetFileNameWithoutExtension(FilePath.Replace(Homebrew.TemporaryNroSuffix, ""));
this.Memory = Memory;
this.ImageBase = ImageBase;
this.ImageEnd = ImageBase;
diff --git a/Ryujinx.HLE/Loaders/Executables/IExecutable.cs b/Ryujinx.HLE/Loaders/Executables/IExecutable.cs
index 1e8e569a..44bad614 100644
--- a/Ryujinx.HLE/Loaders/Executables/IExecutable.cs
+++ b/Ryujinx.HLE/Loaders/Executables/IExecutable.cs
@@ -2,7 +2,7 @@ namespace Ryujinx.HLE.Loaders.Executables
{
public interface IExecutable
{
- string Name { get; }
+ string FilePath { get; }
byte[] Text { get; }
byte[] RO { get; }
diff --git a/Ryujinx.HLE/Loaders/Executables/Nro.cs b/Ryujinx.HLE/Loaders/Executables/Nro.cs
index 9e2b7e90..0b5068d7 100644
--- a/Ryujinx.HLE/Loaders/Executables/Nro.cs
+++ b/Ryujinx.HLE/Loaders/Executables/Nro.cs
@@ -4,7 +4,7 @@ namespace Ryujinx.HLE.Loaders.Executables
{
class Nro : IExecutable
{
- public string Name { get; private set; }
+ public string FilePath { get; private set; }
public byte[] Text { get; private set; }
public byte[] RO { get; private set; }
@@ -16,9 +16,9 @@ namespace Ryujinx.HLE.Loaders.Executables
public int DataOffset { get; private set; }
public int BssSize { get; private set; }
- public Nro(Stream Input, string Name)
+ public Nro(Stream Input, string FilePath)
{
- this.Name = Name;
+ this.FilePath = FilePath;
BinaryReader Reader = new BinaryReader(Input);
diff --git a/Ryujinx.HLE/Loaders/Executables/Nso.cs b/Ryujinx.HLE/Loaders/Executables/Nso.cs
index a5e1a361..6a55c755 100644
--- a/Ryujinx.HLE/Loaders/Executables/Nso.cs
+++ b/Ryujinx.HLE/Loaders/Executables/Nso.cs
@@ -6,7 +6,7 @@ namespace Ryujinx.HLE.Loaders.Executables
{
class Nso : IExecutable
{
- public string Name { get; private set; }
+ public string FilePath { get; private set; }
public byte[] Text { get; private set; }
public byte[] RO { get; private set; }
@@ -31,7 +31,7 @@ namespace Ryujinx.HLE.Loaders.Executables
public Nso(Stream Input, string Name)
{
- this.Name = Name;
+ this.FilePath = FilePath;
BinaryReader Reader = new BinaryReader(Input);
diff --git a/Ryujinx.HLE/OsHle/Homebrew.cs b/Ryujinx.HLE/OsHle/Homebrew.cs
index 4266c8db..778e52fe 100644
--- a/Ryujinx.HLE/OsHle/Homebrew.cs
+++ b/Ryujinx.HLE/OsHle/Homebrew.cs
@@ -1,11 +1,14 @@
using ChocolArm64.Memory;
+using System.Text;
namespace Ryujinx.HLE.OsHle
{
static class Homebrew
{
+ public const string TemporaryNroSuffix = ".ryu_tmp.nro";
+
//http://switchbrew.org/index.php?title=Homebrew_ABI
- public static void WriteHbAbiData(AMemory Memory, long Position, int MainThreadHandle)
+ public static void WriteHbAbiData(AMemory Memory, long Position, int MainThreadHandle, string SwitchPath)
{
Memory.Manager.Map(Position, AMemoryMgr.PageSize, (int)MemoryType.Normal, AMemoryPerm.RW);
@@ -15,6 +18,11 @@ namespace Ryujinx.HLE.OsHle
//NextLoadPath
WriteConfigEntry(Memory, ref Position, 2, 0, Position + 0x200, Position + 0x400);
+ // Argv
+ long ArgvPosition = Position + 0xC00;
+ WriteConfigEntry(Memory, ref Position, 5, 0, 0, ArgvPosition);
+ Memory.WriteBytes(ArgvPosition, Encoding.ASCII.GetBytes(SwitchPath + "\0"));
+
//AppletType
WriteConfigEntry(Memory, ref Position, 7);
diff --git a/Ryujinx.HLE/OsHle/Horizon.cs b/Ryujinx.HLE/OsHle/Horizon.cs
index a5bf0616..9d8a937f 100644
--- a/Ryujinx.HLE/OsHle/Horizon.cs
+++ b/Ryujinx.HLE/OsHle/Horizon.cs
@@ -87,19 +87,36 @@ namespace Ryujinx.HLE.OsHle
MainProcess.Run();
}
- public void LoadProgram(string FileName)
+ public void LoadProgram(string FilePath)
{
- bool IsNro = Path.GetExtension(FileName).ToLower() == ".nro";
+ bool IsNro = Path.GetExtension(FilePath).ToLower() == ".nro";
- string Name = Path.GetFileNameWithoutExtension(FileName);
+ string Name = Path.GetFileNameWithoutExtension(FilePath);
+ string SwitchFilePath = Ns.VFs.SystemPathToSwitchPath(FilePath);
+
+ if (IsNro && (SwitchFilePath == null || !SwitchFilePath.StartsWith("sdmc:/")))
+ {
+ // TODO: avoid copying the file if we are already inside a sdmc directory
+ string SwitchPath = $"sdmc:/switch/{Name}{Homebrew.TemporaryNroSuffix}";
+ string TempPath = Ns.VFs.SwitchPathToSystemPath(SwitchPath);
+
+ string SwitchDir = Path.GetDirectoryName(TempPath);
+ if (!Directory.Exists(SwitchDir))
+ {
+ Directory.CreateDirectory(SwitchDir);
+ }
+ File.Copy(FilePath, TempPath, true);
+
+ FilePath = TempPath;
+ }
Process MainProcess = MakeProcess();
- using (FileStream Input = new FileStream(FileName, FileMode.Open))
+ using (FileStream Input = new FileStream(FilePath, FileMode.Open))
{
MainProcess.LoadProgram(IsNro
- ? (IExecutable)new Nro(Input, Name)
- : (IExecutable)new Nso(Input, Name));
+ ? (IExecutable)new Nro(Input, FilePath)
+ : (IExecutable)new Nso(Input, FilePath));
}
MainProcess.SetEmptyArgs();
diff --git a/Ryujinx.HLE/OsHle/Process.cs b/Ryujinx.HLE/OsHle/Process.cs
index 53e357ab..be27dcc2 100644
--- a/Ryujinx.HLE/OsHle/Process.cs
+++ b/Ryujinx.HLE/OsHle/Process.cs
@@ -13,6 +13,7 @@ using Ryujinx.HLE.OsHle.Services.Nv;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.IO;
using System.Text;
namespace Ryujinx.HLE.OsHle
@@ -155,7 +156,9 @@ namespace Ryujinx.HLE.OsHle
{
HbAbiDataPosition = AMemoryHelper.PageRoundUp(Executables[0].ImageEnd);
- Homebrew.WriteHbAbiData(Memory, HbAbiDataPosition, Handle);
+ string SwitchPath = Ns.VFs.SystemPathToSwitchPath(Executables[0].FilePath);
+
+ Homebrew.WriteHbAbiData(Memory, HbAbiDataPosition, Handle, SwitchPath);
MainThread.Thread.ThreadState.X0 = (ulong)HbAbiDataPosition;
MainThread.Thread.ThreadState.X1 = ulong.MaxValue;
@@ -400,6 +403,11 @@ namespace Ryujinx.HLE.OsHle
{
if (Disposing && !Disposed)
{
+ if (NeedsHbAbi && Executables[0].FilePath.EndsWith(Homebrew.TemporaryNroSuffix))
+ {
+ File.Delete(Executables[0].FilePath);
+ }
+
//If there is still some thread running, disposing the objects is not
//safe as the thread may try to access those resources. Instead, we set
//the flag to have the Process disposed when all threads finishes.
diff --git a/Ryujinx.HLE/Switch.cs b/Ryujinx.HLE/Switch.cs
index 1946b187..74c0564a 100644
--- a/Ryujinx.HLE/Switch.cs
+++ b/Ryujinx.HLE/Switch.cs
@@ -81,8 +81,9 @@ namespace Ryujinx.HLE
Gpu.Fifo.DispatchCalls();
}
- internal virtual void OnFinish(EventArgs e)
+ public virtual void OnFinish(EventArgs e)
{
+ Os.Dispose();
Finish?.Invoke(this, e);
}
diff --git a/Ryujinx.HLE/VirtualFileSystem.cs b/Ryujinx.HLE/VirtualFileSystem.cs
index 8b71caa9..38df81f8 100644
--- a/Ryujinx.HLE/VirtualFileSystem.cs
+++ b/Ryujinx.HLE/VirtualFileSystem.cs
@@ -45,6 +45,35 @@ namespace Ryujinx.HLE
public string GetGameSavesPath() => MakeDirAndGetFullPath(NandPath);
+ public string SwitchPathToSystemPath(string SwitchPath)
+ {
+ string[] Parts = SwitchPath.Split(":");
+ if (Parts.Length != 2)
+ {
+ return null;
+ }
+ return GetFullPath(MakeDirAndGetFullPath(Parts[0]), Parts[1]);
+ }
+
+ public string SystemPathToSwitchPath(string SystemPath)
+ {
+ string BaseSystemPath = GetBasePath() + "/";
+ if (SystemPath.StartsWith(BaseSystemPath))
+ {
+ string RawPath = SystemPath.Replace(BaseSystemPath, "");
+ int FirstSeparatorOffset = RawPath.IndexOf('/');
+ if (FirstSeparatorOffset == -1)
+ {
+ return $"{RawPath}:/";
+ }
+
+ string BasePath = RawPath.Substring(0, FirstSeparatorOffset);
+ string FileName = RawPath.Substring(FirstSeparatorOffset + 1);
+ return $"{BasePath}:/{FileName}";
+ }
+ return null;
+ }
+
private string MakeDirAndGetFullPath(string Dir)
{
string FullPath = Path.Combine(GetBasePath(), Dir);
diff --git a/Ryujinx/Ui/Program.cs b/Ryujinx/Ui/Program.cs
index 5cacc622..879b9c20 100644
--- a/Ryujinx/Ui/Program.cs
+++ b/Ryujinx/Ui/Program.cs
@@ -68,6 +68,7 @@ namespace Ryujinx
};
Screen.MainLoop();
+ Ns.OnFinish(EventArgs.Empty);
}
Environment.Exit(0);