using ARMeilleure.Translation; using Ryujinx.Common.Logging; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace LibRyujinx { public static partial class LibRyujinx { [UnmanagedCallersOnly(EntryPoint = "device_initialize")] public static bool InitializeDeviceNative() { return InitializeDevice(true); } public static bool InitializeDevice(bool isHostMapped) { if (SwitchDevice == null) { return false; } return SwitchDevice.InitializeContext(isHostMapped); } [UnmanagedCallersOnly(EntryPoint = "device_load")] public static bool LoadApplicationNative(IntPtr pathPtr) { if(SwitchDevice?.EmulationContext == null) { return false; } var path = Marshal.PtrToStringAnsi(pathPtr); return LoadApplication(path); } public static bool LoadApplication(string path) { var emulationContext = SwitchDevice.EmulationContext; if (Directory.Exists(path)) { string[] romFsFiles = Directory.GetFiles(path, "*.istorage"); if (romFsFiles.Length == 0) { romFsFiles = Directory.GetFiles(path, "*.romfs"); } if (romFsFiles.Length > 0) { Logger.Info?.Print(LogClass.Application, "Loading as cart with RomFS."); if (!emulationContext.LoadCart(path, romFsFiles[0])) { SwitchDevice.DisposeContext(); return false; } } else { Logger.Info?.Print(LogClass.Application, "Loading as cart WITHOUT RomFS."); if (!emulationContext.LoadCart(path)) { SwitchDevice.DisposeContext(); return false; } } } else if (File.Exists(path)) { switch (Path.GetExtension(path).ToLowerInvariant()) { case ".xci": Logger.Info?.Print(LogClass.Application, "Loading as XCI."); if (!emulationContext.LoadXci(path)) { SwitchDevice.DisposeContext(); return false; } break; case ".nca": Logger.Info?.Print(LogClass.Application, "Loading as NCA."); if (!emulationContext.LoadNca(path)) { SwitchDevice.DisposeContext(); return false; } break; case ".nsp": case ".pfs0": Logger.Info?.Print(LogClass.Application, "Loading as NSP."); if (!emulationContext.LoadNsp(path)) { SwitchDevice.DisposeContext(); return false; } break; default: Logger.Info?.Print(LogClass.Application, "Loading as Homebrew."); try { if (!emulationContext.LoadProgram(path)) { SwitchDevice.DisposeContext(); return false; } } catch (ArgumentOutOfRangeException) { Logger.Error?.Print(LogClass.Application, "The specified file is not supported by Ryujinx."); SwitchDevice.DisposeContext(); return false; } break; } } else { Logger.Warning?.Print(LogClass.Application, $"Couldn't load '{path}'. Please specify a valid XCI/NCA/NSP/PFS0/NRO file."); SwitchDevice.DisposeContext(); return false; } Translator.IsReadyForTranslation.Reset(); return true; } } }