rjx-mirror/Ryujinx.HLE/HOS/Horizon.cs

950 lines
34 KiB
C#
Raw Normal View History

using LibHac;
using LibHac.Account;
using LibHac.Bcat;
using LibHac.Common;
using LibHac.Fs;
using LibHac.FsSystem;
using LibHac.FsSystem.NcaUtils;
using LibHac.Ncm;
using LibHac.Ns;
using LibHac.Spl;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Configuration;
using Ryujinx.HLE.FileSystem.Content;
using Ryujinx.HLE.HOS.Font;
using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Memory;
using Ryujinx.HLE.HOS.Kernel.Process;
using Ryujinx.HLE.HOS.Kernel.Threading;
using Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy;
using Ryujinx.HLE.HOS.Services.Arp;
using Ryujinx.HLE.HOS.Services.Mii;
using Ryujinx.HLE.HOS.Services.Nv;
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl;
using Ryujinx.HLE.HOS.Services.Pcv.Bpc;
using Ryujinx.HLE.HOS.Services.Settings;
using Ryujinx.HLE.HOS.Services.Sm;
using Ryujinx.HLE.HOS.Services.SurfaceFlinger;
using Ryujinx.HLE.HOS.Services.Time.Clock;
using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.HLE.Loaders.Executables;
2018-07-20 21:53:06 +00:00
using Ryujinx.HLE.Loaders.Npdm;
using Ryujinx.HLE.Utilities;
using System;
2018-02-04 23:08:20 +00:00
using System.Collections.Concurrent;
using System.Collections.Generic;
2018-02-04 23:08:20 +00:00
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using Utf8Json;
using Utf8Json.Resolvers;
using TimeServiceManager = Ryujinx.HLE.HOS.Services.Time.TimeManager;
using NsoExecutable = Ryujinx.HLE.Loaders.Executables.NsoExecutable;
2018-02-04 23:08:20 +00:00
using static LibHac.Fs.ApplicationSaveDataManagement;
namespace Ryujinx.HLE.HOS
2018-02-04 23:08:20 +00:00
{
public class Horizon : IDisposable
2018-02-04 23:08:20 +00:00
{
internal const int InitialKipId = 1;
internal const int InitialProcessId = 0x51;
2018-02-04 23:08:20 +00:00
internal const int HidSize = 0x40000;
internal const int FontSize = 0x1100000;
internal const int IirsSize = 0x8000;
internal const int TimeSize = 0x1000;
2018-02-04 23:08:20 +00:00
private const int MemoryBlockAllocatorSize = 0x2710;
private const ulong UserSlabHeapBase = DramMemoryMap.SlabHeapBase;
private const ulong UserSlabHeapItemSize = KMemoryManager.PageSize;
private const ulong UserSlabHeapSize = 0x3de000;
internal long PrivilegedProcessLowestId { get; set; } = 1;
internal long PrivilegedProcessHighestId { get; set; } = 8;
internal Switch Device { get; private set; }
2018-02-04 23:08:20 +00:00
internal SurfaceFlinger SurfaceFlinger { get; private set; }
public SystemStateMgr State { get; private set; }
internal bool KernelInitialized { get; private set; }
internal KResourceLimit ResourceLimit { get; private set; }
internal KMemoryRegionManager[] MemoryRegions { get; private set; }
internal KMemoryBlockAllocator LargeMemoryBlockAllocator { get; private set; }
internal KMemoryBlockAllocator SmallMemoryBlockAllocator { get; private set; }
internal KSlabHeap UserSlabHeapPages { get; private set; }
internal KCriticalSection CriticalSection { get; private set; }
internal KScheduler Scheduler { get; private set; }
internal KTimeManager TimeManager { get; private set; }
internal KSynchronization Synchronization { get; private set; }
internal KContextIdManager ContextIdManager { get; private set; }
private long _kipId;
private long _processId;
private long _threadUid;
internal CountdownEvent ThreadCounter;
internal SortedDictionary<long, KProcess> Processes;
internal ConcurrentDictionary<string, KAutoObject> AutoObjectNames;
internal bool EnableVersionChecks { get; private set; }
internal AppletStateMgr AppletState { get; private set; }
internal KSharedMemory HidSharedMem { get; private set; }
internal KSharedMemory FontSharedMem { get; private set; }
internal KSharedMemory IirsSharedMem { get; private set; }
internal SharedFontManager Font { get; private set; }
internal ContentManager ContentManager { get; private set; }
internal KEvent VsyncEvent { get; private set; }
internal KEvent DisplayResolutionChangeEvent { get; private set; }
public Keyset KeySet => Device.FileSystem.KeySet;
#pragma warning disable CS0649
private bool _hasStarted;
#pragma warning restore CS0649
private bool _isDisposed;
public BlitStruct<ApplicationControlProperty> ControlData { get; set; }
2019-05-30 20:27:43 +00:00
public string TitleName { get; private set; }
public ulong TitleId { get; private set; }
public string TitleIdText => TitleId.ToString("x16");
2019-05-30 20:27:43 +00:00
public string TitleVersionString { get; private set; }
public bool TitleIs64Bit { get; private set; }
public IntegrityCheckLevel FsIntegrityCheckLevel { get; set; }
public int GlobalAccessLogMode { get; set; }
internal long HidBaseAddress { get; private set; }
internal NvHostSyncpt HostSyncpoint { get; private set; }
internal LibHac.Horizon LibHacHorizonServer { get; private set; }
internal HorizonClient LibHacHorizonClient { get; private set; }
public Horizon(Switch device, ContentManager contentManager)
2018-02-04 23:08:20 +00:00
{
ControlData = new BlitStruct<ApplicationControlProperty>(1);
Device = device;
2018-02-04 23:08:20 +00:00
State = new SystemStateMgr();
ResourceLimit = new KResourceLimit(this);
KernelInit.InitializeResourceLimit(ResourceLimit);
MemoryRegions = KernelInit.GetMemoryRegions();
LargeMemoryBlockAllocator = new KMemoryBlockAllocator(MemoryBlockAllocatorSize * 2);
SmallMemoryBlockAllocator = new KMemoryBlockAllocator(MemoryBlockAllocatorSize);
UserSlabHeapPages = new KSlabHeap(
UserSlabHeapBase,
UserSlabHeapItemSize,
UserSlabHeapSize);
CriticalSection = new KCriticalSection(this);
Scheduler = new KScheduler(this);
TimeManager = new KTimeManager();
Synchronization = new KSynchronization(this);
ContextIdManager = new KContextIdManager();
_kipId = InitialKipId;
_processId = InitialProcessId;
Scheduler.StartAutoPreemptionThread();
KernelInitialized = true;
ThreadCounter = new CountdownEvent(1);
Processes = new SortedDictionary<long, KProcess>();
AutoObjectNames = new ConcurrentDictionary<string, KAutoObject>();
// Note: This is not really correct, but with HLE of services, the only memory
// region used that is used is Application, so we can use the other ones for anything.
KMemoryRegionManager region = MemoryRegions[(int)MemoryRegion.NvServices];
ulong hidPa = region.Address;
ulong fontPa = region.Address + HidSize;
ulong iirsPa = region.Address + HidSize + FontSize;
ulong timePa = region.Address + HidSize + FontSize + IirsSize;
HidBaseAddress = (long)(hidPa - DramMemoryMap.DramBase);
KPageList hidPageList = new KPageList();
KPageList fontPageList = new KPageList();
KPageList iirsPageList = new KPageList();
KPageList timePageList = new KPageList();
hidPageList .AddRange(hidPa, HidSize / KMemoryManager.PageSize);
fontPageList.AddRange(fontPa, FontSize / KMemoryManager.PageSize);
iirsPageList.AddRange(iirsPa, IirsSize / KMemoryManager.PageSize);
timePageList.AddRange(timePa, TimeSize / KMemoryManager.PageSize);
HidSharedMem = new KSharedMemory(this, hidPageList, 0, 0, MemoryPermission.Read);
FontSharedMem = new KSharedMemory(this, fontPageList, 0, 0, MemoryPermission.Read);
IirsSharedMem = new KSharedMemory(this, iirsPageList, 0, 0, MemoryPermission.Read);
KSharedMemory timeSharedMemory = new KSharedMemory(this, timePageList, 0, 0, MemoryPermission.Read);
TimeServiceManager.Instance.Initialize(device, this, timeSharedMemory, (long)(timePa - DramMemoryMap.DramBase), TimeSize);
AppletState = new AppletStateMgr(this);
AppletState.SetFocus(true);
Font = new SharedFontManager(device, (long)(fontPa - DramMemoryMap.DramBase));
IUserInterface.InitializePort(this);
VsyncEvent = new KEvent(this);
DisplayResolutionChangeEvent = new KEvent(this);
ContentManager = contentManager;
// TODO: use set:sys (and get external clock source id from settings)
// TODO: use "time!standard_steady_clock_rtc_update_interval_minutes" and implement a worker thread to be accurate.
UInt128 clockSourceId = new UInt128(Guid.NewGuid().ToByteArray());
IRtcManager.GetExternalRtcValue(out ulong rtcValue);
// We assume the rtc is system time.
TimeSpanType systemTime = TimeSpanType.FromSeconds((long)rtcValue);
// Configure and setup internal offset
TimeSpanType internalOffset = TimeSpanType.FromSeconds(ConfigurationState.Instance.System.SystemTimeOffset);
TimeSpanType systemTimeOffset = new TimeSpanType(systemTime.NanoSeconds + internalOffset.NanoSeconds);
if (systemTime.IsDaylightSavingTime() && !systemTimeOffset.IsDaylightSavingTime())
{
internalOffset = internalOffset.AddSeconds(3600L);
}
else if (!systemTime.IsDaylightSavingTime() && systemTimeOffset.IsDaylightSavingTime())
{
internalOffset = internalOffset.AddSeconds(-3600L);
}
internalOffset = new TimeSpanType(-internalOffset.NanoSeconds);
// First init the standard steady clock
TimeServiceManager.Instance.SetupStandardSteadyClock(null, clockSourceId, systemTime, internalOffset, TimeSpanType.Zero, false);
TimeServiceManager.Instance.SetupStandardLocalSystemClock(null, new SystemClockContext(), systemTime.ToSeconds());
if (NxSettings.Settings.TryGetValue("time!standard_network_clock_sufficient_accuracy_minutes", out object standardNetworkClockSufficientAccuracyMinutes))
{
TimeSpanType standardNetworkClockSufficientAccuracy = new TimeSpanType((int)standardNetworkClockSufficientAccuracyMinutes * 60000000000);
TimeServiceManager.Instance.SetupStandardNetworkSystemClock(new SystemClockContext(), standardNetworkClockSufficientAccuracy);
}
TimeServiceManager.Instance.SetupStandardUserSystemClock(null, false, SteadyClockTimePoint.GetRandom());
// FIXME: TimeZone shoud be init here but it's actually done in ContentManager
TimeServiceManager.Instance.SetupEphemeralNetworkSystemClock();
DatabaseImpl.Instance.InitializeDatabase(device);
HostSyncpoint = new NvHostSyncpt(device);
SurfaceFlinger = new SurfaceFlinger(device);
ConfigurationState.Instance.System.EnableDockedMode.Event += OnDockedModeChange;
InitLibHacHorizon();
}
private void InitLibHacHorizon()
{
LibHac.Horizon horizon = new LibHac.Horizon(null, Device.FileSystem.FsServer);
horizon.CreateHorizonClient(out HorizonClient ryujinxClient).ThrowIfFailure();
horizon.CreateHorizonClient(out HorizonClient bcatClient).ThrowIfFailure();
ryujinxClient.Sm.RegisterService(new LibHacIReader(this), "arp:r").ThrowIfFailure();
new BcatServer(bcatClient);
LibHacHorizonServer = horizon;
LibHacHorizonClient = ryujinxClient;
}
private void OnDockedModeChange(object sender, ReactiveEventArgs<bool> e)
{
if (e.NewValue != State.DockedMode)
{
State.DockedMode = e.NewValue;
AppletState.EnqueueMessage(MessageInfo.OperationModeChanged);
AppletState.EnqueueMessage(MessageInfo.PerformanceModeChanged);
SignalDisplayResolutionChange();
}
2018-02-04 23:08:20 +00:00
}
public void LoadCart(string exeFsDir, string romFsFile = null)
2018-02-04 23:08:20 +00:00
{
if (romFsFile != null)
2018-02-04 23:08:20 +00:00
{
Device.FileSystem.LoadRomFs(romFsFile);
2018-02-04 23:08:20 +00:00
}
LocalFileSystem codeFs = new LocalFileSystem(exeFsDir);
LoadExeFs(codeFs, out _);
if (TitleId != 0)
{
EnsureSaveData(new TitleId(TitleId));
}
2018-02-04 23:08:20 +00:00
}
public void LoadXci(string xciFile)
{
FileStream file = new FileStream(xciFile, FileMode.Open, FileAccess.Read);
Xci xci = new Xci(KeySet, file.AsStorage());
(Nca mainNca, Nca patchNca, Nca controlNca) = GetXciGameData(xci);
if (mainNca == null)
{
Logger.PrintError(LogClass.Loader, "Unable to load XCI");
return;
}
ContentManager.LoadEntries(Device);
LoadNca(mainNca, patchNca, controlNca);
}
public void LoadKip(string kipFile)
{
using (IStorage fs = new LocalStorage(kipFile, FileAccess.Read))
{
ProgramLoader.LoadKernelInitalProcess(this, new KipExecutable(fs));
}
}
private (Nca Main, Nca patch, Nca Control) GetXciGameData(Xci xci)
{
if (!xci.HasPartition(XciPartitionType.Secure))
{
throw new InvalidDataException("Could not find XCI secure partition");
}
Nca mainNca = null;
Nca patchNca = null;
Nca controlNca = null;
XciPartition securePartition = xci.OpenPartition(XciPartitionType.Secure);
foreach (DirectoryEntryEx ticketEntry in securePartition.EnumerateEntries("/", "*.tik"))
{
Result result = securePartition.OpenFile(out IFile ticketFile, ticketEntry.FullPath.ToU8Span(), OpenMode.Read);
if (result.IsSuccess())
{
Ticket ticket = new Ticket(ticketFile.AsStream());
KeySet.ExternalKeySet.Add(new RightsId(ticket.RightsId), new AccessKey(ticket.GetTitleKey(KeySet)));
}
}
foreach (DirectoryEntryEx fileEntry in securePartition.EnumerateEntries("/", "*.nca"))
{
Result result = securePartition.OpenFile(out IFile ncaFile, fileEntry.FullPath.ToU8Span(), OpenMode.Read);
if (result.IsFailure())
{
continue;
}
Nca nca = new Nca(KeySet, ncaFile.AsStorage());
if (nca.Header.ContentType == NcaContentType.Program)
{
int dataIndex = Nca.GetSectionIndexFromType(NcaSectionType.Data, NcaContentType.Program);
if (nca.Header.GetFsHeader(dataIndex).IsPatchSection())
{
patchNca = nca;
}
else
{
mainNca = nca;
}
}
else if (nca.Header.ContentType == NcaContentType.Control)
{
controlNca = nca;
}
}
if (mainNca == null)
{
Logger.PrintError(LogClass.Loader, "Could not find an Application NCA in the provided XCI file");
}
if (controlNca != null)
{
ReadControlData(controlNca);
}
else
{
ControlData.ByteSpan.Clear();
}
return (mainNca, patchNca, controlNca);
}
public void ReadControlData(Nca controlNca)
{
IFileSystem controlFs = controlNca.OpenFileSystem(NcaSectionType.Data, FsIntegrityCheckLevel);
Result result = controlFs.OpenFile(out IFile controlFile, "/control.nacp".ToU8Span(), OpenMode.Read);
if (result.IsSuccess())
{
result = controlFile.Read(out long bytesRead, 0, ControlData.ByteSpan, ReadOption.None);
if (result.IsSuccess() && bytesRead == ControlData.ByteSpan.Length)
{
TitleName = ControlData.Value
.Titles[(int) State.DesiredTitleLanguage].Name.ToString();
if (string.IsNullOrWhiteSpace(TitleName))
{
TitleName = ControlData.Value.Titles.ToArray()
.FirstOrDefault(x => x.Name[0] != 0).Name.ToString();
}
TitleVersionString = ControlData.Value.DisplayVersion.ToString();
}
}
else
{
ControlData.ByteSpan.Clear();
}
}
public void LoadNca(string ncaFile)
{
FileStream file = new FileStream(ncaFile, FileMode.Open, FileAccess.Read);
Nca nca = new Nca(KeySet, file.AsStorage(false));
LoadNca(nca, null, null);
}
public void LoadNsp(string nspFile)
{
FileStream file = new FileStream(nspFile, FileMode.Open, FileAccess.Read);
PartitionFileSystem nsp = new PartitionFileSystem(file.AsStorage());
foreach (DirectoryEntryEx ticketEntry in nsp.EnumerateEntries("/", "*.tik"))
{
Result result = nsp.OpenFile(out IFile ticketFile, ticketEntry.FullPath.ToU8Span(), OpenMode.Read);
if (result.IsSuccess())
{
Ticket ticket = new Ticket(ticketFile.AsStream());
KeySet.ExternalKeySet.Add(new RightsId(ticket.RightsId), new AccessKey(ticket.GetTitleKey(KeySet)));
}
}
Nca mainNca = null;
Nca patchNca = null;
Nca controlNca = null;
foreach (DirectoryEntryEx fileEntry in nsp.EnumerateEntries("/", "*.nca"))
{
nsp.OpenFile(out IFile ncaFile, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
Nca nca = new Nca(KeySet, ncaFile.AsStorage());
if (nca.Header.ContentType == NcaContentType.Program)
{
int dataIndex = Nca.GetSectionIndexFromType(NcaSectionType.Data, NcaContentType.Program);
if (nca.Header.GetFsHeader(dataIndex).IsPatchSection())
{
patchNca = nca;
}
else
{
mainNca = nca;
}
}
else if (nca.Header.ContentType == NcaContentType.Control)
{
controlNca = nca;
}
}
if (mainNca != null)
{
LoadNca(mainNca, patchNca, controlNca);
return;
}
// This is not a normal NSP, it's actually a ExeFS as a NSP
LoadExeFs(nsp, out _);
}
public void LoadNca(Nca mainNca, Nca patchNca, Nca controlNca)
{
if (mainNca.Header.ContentType != NcaContentType.Program)
{
Logger.PrintError(LogClass.Loader, "Selected NCA is not a \"Program\" NCA");
return;
}
IStorage dataStorage = null;
IFileSystem codeFs = null;
if (File.Exists(Path.Combine(Device.FileSystem.GetBasePath(), "games", mainNca.Header.TitleId.ToString("x16"), "updates.json")))
{
using (Stream stream = File.OpenRead(Path.Combine(Device.FileSystem.GetBasePath(), "games", mainNca.Header.TitleId.ToString("x16"), "updates.json")))
{
IJsonFormatterResolver resolver = CompositeResolver.Create(StandardResolver.AllowPrivateSnakeCase);
string updatePath = JsonSerializer.Deserialize<TitleUpdateMetadata>(stream, resolver).Selected;
if (File.Exists(updatePath))
{
FileStream file = new FileStream(updatePath, FileMode.Open, FileAccess.Read);
PartitionFileSystem nsp = new PartitionFileSystem(file.AsStorage());
foreach (DirectoryEntryEx ticketEntry in nsp.EnumerateEntries("/", "*.tik"))
{
Result result = nsp.OpenFile(out IFile ticketFile, ticketEntry.FullPath.ToU8Span(), OpenMode.Read);
if (result.IsSuccess())
{
Ticket ticket = new Ticket(ticketFile.AsStream());
KeySet.ExternalKeySet.Add(new RightsId(ticket.RightsId), new AccessKey(ticket.GetTitleKey(KeySet)));
}
}
foreach (DirectoryEntryEx fileEntry in nsp.EnumerateEntries("/", "*.nca"))
{
nsp.OpenFile(out IFile ncaFile, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
Nca nca = new Nca(KeySet, ncaFile.AsStorage());
if ($"{nca.Header.TitleId.ToString("x16")[..^3]}000" != mainNca.Header.TitleId.ToString("x16"))
{
break;
}
if (nca.Header.ContentType == NcaContentType.Program)
{
patchNca = nca;
}
else if (nca.Header.ContentType == NcaContentType.Control)
{
controlNca = nca;
}
}
}
}
}
if (patchNca == null)
{
if (mainNca.CanOpenSection(NcaSectionType.Data))
{
dataStorage = mainNca.OpenStorage(NcaSectionType.Data, FsIntegrityCheckLevel);
}
if (mainNca.CanOpenSection(NcaSectionType.Code))
{
codeFs = mainNca.OpenFileSystem(NcaSectionType.Code, FsIntegrityCheckLevel);
}
}
else
{
if (patchNca.CanOpenSection(NcaSectionType.Data))
{
dataStorage = mainNca.OpenStorageWithPatch(patchNca, NcaSectionType.Data, FsIntegrityCheckLevel);
}
if (patchNca.CanOpenSection(NcaSectionType.Code))
{
codeFs = mainNca.OpenFileSystemWithPatch(patchNca, NcaSectionType.Code, FsIntegrityCheckLevel);
}
}
if (codeFs == null)
{
Logger.PrintError(LogClass.Loader, "No ExeFS found in NCA");
return;
}
if (dataStorage == null)
{
Logger.PrintWarning(LogClass.Loader, "No RomFS found in NCA");
}
else
{
Device.FileSystem.SetRomFs(dataStorage.AsStream(FileAccess.Read));
}
LoadExeFs(codeFs, out Npdm metaData);
TitleId = metaData.Aci0.TitleId;
TitleIs64Bit = metaData.Is64Bit;
if (controlNca != null)
{
ReadControlData(controlNca);
}
else
{
ControlData.ByteSpan.Clear();
}
if (TitleId != 0)
{
EnsureSaveData(new TitleId(TitleId));
}
Logger.PrintInfo(LogClass.Loader, $"Application Loaded: {TitleName} v{TitleVersionString} [{TitleIdText}] [{(TitleIs64Bit ? "64-bit" : "32-bit")}]");
}
private void LoadExeFs(IFileSystem codeFs, out Npdm metaData)
{
Result result = codeFs.OpenFile(out IFile npdmFile, "/main.npdm".ToU8Span(), OpenMode.Read);
if (ResultFs.PathNotFound.Includes(result))
{
Logger.PrintWarning(LogClass.Loader, "NPDM file not found, using default values!");
metaData = GetDefaultNpdm();
}
else
{
metaData = new Npdm(npdmFile.AsStream());
}
List<IExecutable> staticObjects = new List<IExecutable>();
void LoadNso(string filename)
{
foreach (DirectoryEntryEx file in codeFs.EnumerateEntries("/", $"{filename}*"))
{
if (Path.GetExtension(file.Name) != string.Empty)
{
continue;
}
Logger.PrintInfo(LogClass.Loader, $"Loading {file.Name}...");
codeFs.OpenFile(out IFile nsoFile, file.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
NsoExecutable staticObject = new NsoExecutable(nsoFile.AsStorage());
staticObjects.Add(staticObject);
}
}
TitleId = metaData.Aci0.TitleId;
TitleIs64Bit = metaData.Is64Bit;
LoadNso("rtld");
LoadNso("main");
LoadNso("subsdk");
LoadNso("sdk");
ContentManager.LoadEntries(Device);
ProgramLoader.LoadStaticObjects(this, metaData, staticObjects.ToArray());
}
public void LoadProgram(string filePath)
2018-02-04 23:08:20 +00:00
{
Npdm metaData = GetDefaultNpdm();
bool isNro = Path.GetExtension(filePath).ToLower() == ".nro";
IExecutable staticObject;
if (isNro)
{
FileStream input = new FileStream(filePath, FileMode.Open);
NroExecutable obj = new NroExecutable(input);
staticObject = obj;
// homebrew NRO can actually have some data after the actual NRO
if (input.Length > obj.FileSize)
{
input.Position = obj.FileSize;
BinaryReader reader = new BinaryReader(input);
uint asetMagic = reader.ReadUInt32();
if (asetMagic == 0x54455341)
{
uint asetVersion = reader.ReadUInt32();
if (asetVersion == 0)
{
ulong iconOffset = reader.ReadUInt64();
Added GUI to Ryujinx (#695) * Added GUI to Ryujinx * Updated to use Glade Also added scrollbar and default dark theme * Added support for loading icon from .nro files and cleaned up the code a bit * Added General Settings Menu (read-only for now) and moved some functionality from MainMenu.cs to ApplicationLibrary.cs * Added custom GUI theme support and changed the defualt theme to one I just wrote * Added GTK to process path, fixed a bug and minor edits * some more edits and a bug fix * general settings menu is now fully functional. also fixed the bug where ryujinx crashes when it trys to load an invalid gamedir * big rewrite * aesthetic changes to General Settings menu * Added Control Settings one day done feature :P * minor changes * 1st wave of changes * 2nd wave of changes * 3rd wave of changes * Cleanup settings ui * minor edits * new about window added, still needs styling * added spin button for new option and tooltips to settings * Game icons and names are now shown in the games list * add nuget package which contains gtk dependencies * requested changes have been changed * put CreateGameWindow on a new thread and stopped destroying the main menu when a game loads * fixed bug that allowed a user to attempt to load multiple games at a time which causes a crash * Added LastPlayed and TimePlayed columns to the game list * Did some testing and fixed some bugs Im not happy with one of the fixes so i will do it properly an upcoming commit * did some more bug testing and fixed another 2 bugs * caught an exception when ryujinx tries to load non-homebrew as homebrew * Large changes Rewrote ApplicationLibrary.cs (added comments too) so any devs reading it wont get eye cancer, also its probably more efficient now. Added 2 new columns (Developer name and application version) to the game list and wrote the logic for it. Ryujinx now loads NRO's TitleName and TitleID from the NACP file instead of the default NPDM. I also killed a lot of bugs * Moved Files moved ApplicationLibrary.cs to Ryujinx.HLE as that is a better place for it. Moved contents of GUI folder to Ui folder and changed the namespaces of the gui files from Ryujinx to Ryujinx.Ui * Added 'Open Ryujinx Folder' button to the file menu and did some small fixes * New features * updated nuget package with missing dlls and changed emmauss' requested changes * fixed some minor issues * all requested changes marked as resolved have been changed * gdkchan's requested changes * fixed an issue with settings window getting chopped on small res * fixed 2 problems caused by rebase * changed the default theme * applied Thog's patch to fix issue on linux * fixed issue caused by rebase * added update check button that runs ryujinx-updater * reads version info from installer and displays it in about menu * changes completed * requested changes changed * fixed issue with default theme * fixed a bug and completed requested changes * added more tooltips and changed some text
2019-09-02 16:03:57 +00:00
ulong iconSize = reader.ReadUInt64();
ulong nacpOffset = reader.ReadUInt64();
Added GUI to Ryujinx (#695) * Added GUI to Ryujinx * Updated to use Glade Also added scrollbar and default dark theme * Added support for loading icon from .nro files and cleaned up the code a bit * Added General Settings Menu (read-only for now) and moved some functionality from MainMenu.cs to ApplicationLibrary.cs * Added custom GUI theme support and changed the defualt theme to one I just wrote * Added GTK to process path, fixed a bug and minor edits * some more edits and a bug fix * general settings menu is now fully functional. also fixed the bug where ryujinx crashes when it trys to load an invalid gamedir * big rewrite * aesthetic changes to General Settings menu * Added Control Settings one day done feature :P * minor changes * 1st wave of changes * 2nd wave of changes * 3rd wave of changes * Cleanup settings ui * minor edits * new about window added, still needs styling * added spin button for new option and tooltips to settings * Game icons and names are now shown in the games list * add nuget package which contains gtk dependencies * requested changes have been changed * put CreateGameWindow on a new thread and stopped destroying the main menu when a game loads * fixed bug that allowed a user to attempt to load multiple games at a time which causes a crash * Added LastPlayed and TimePlayed columns to the game list * Did some testing and fixed some bugs Im not happy with one of the fixes so i will do it properly an upcoming commit * did some more bug testing and fixed another 2 bugs * caught an exception when ryujinx tries to load non-homebrew as homebrew * Large changes Rewrote ApplicationLibrary.cs (added comments too) so any devs reading it wont get eye cancer, also its probably more efficient now. Added 2 new columns (Developer name and application version) to the game list and wrote the logic for it. Ryujinx now loads NRO's TitleName and TitleID from the NACP file instead of the default NPDM. I also killed a lot of bugs * Moved Files moved ApplicationLibrary.cs to Ryujinx.HLE as that is a better place for it. Moved contents of GUI folder to Ui folder and changed the namespaces of the gui files from Ryujinx to Ryujinx.Ui * Added 'Open Ryujinx Folder' button to the file menu and did some small fixes * New features * updated nuget package with missing dlls and changed emmauss' requested changes * fixed some minor issues * all requested changes marked as resolved have been changed * gdkchan's requested changes * fixed an issue with settings window getting chopped on small res * fixed 2 problems caused by rebase * changed the default theme * applied Thog's patch to fix issue on linux * fixed issue caused by rebase * added update check button that runs ryujinx-updater * reads version info from installer and displays it in about menu * changes completed * requested changes changed * fixed issue with default theme * fixed a bug and completed requested changes * added more tooltips and changed some text
2019-09-02 16:03:57 +00:00
ulong nacpSize = reader.ReadUInt64();
ulong romfsOffset = reader.ReadUInt64();
Added GUI to Ryujinx (#695) * Added GUI to Ryujinx * Updated to use Glade Also added scrollbar and default dark theme * Added support for loading icon from .nro files and cleaned up the code a bit * Added General Settings Menu (read-only for now) and moved some functionality from MainMenu.cs to ApplicationLibrary.cs * Added custom GUI theme support and changed the defualt theme to one I just wrote * Added GTK to process path, fixed a bug and minor edits * some more edits and a bug fix * general settings menu is now fully functional. also fixed the bug where ryujinx crashes when it trys to load an invalid gamedir * big rewrite * aesthetic changes to General Settings menu * Added Control Settings one day done feature :P * minor changes * 1st wave of changes * 2nd wave of changes * 3rd wave of changes * Cleanup settings ui * minor edits * new about window added, still needs styling * added spin button for new option and tooltips to settings * Game icons and names are now shown in the games list * add nuget package which contains gtk dependencies * requested changes have been changed * put CreateGameWindow on a new thread and stopped destroying the main menu when a game loads * fixed bug that allowed a user to attempt to load multiple games at a time which causes a crash * Added LastPlayed and TimePlayed columns to the game list * Did some testing and fixed some bugs Im not happy with one of the fixes so i will do it properly an upcoming commit * did some more bug testing and fixed another 2 bugs * caught an exception when ryujinx tries to load non-homebrew as homebrew * Large changes Rewrote ApplicationLibrary.cs (added comments too) so any devs reading it wont get eye cancer, also its probably more efficient now. Added 2 new columns (Developer name and application version) to the game list and wrote the logic for it. Ryujinx now loads NRO's TitleName and TitleID from the NACP file instead of the default NPDM. I also killed a lot of bugs * Moved Files moved ApplicationLibrary.cs to Ryujinx.HLE as that is a better place for it. Moved contents of GUI folder to Ui folder and changed the namespaces of the gui files from Ryujinx to Ryujinx.Ui * Added 'Open Ryujinx Folder' button to the file menu and did some small fixes * New features * updated nuget package with missing dlls and changed emmauss' requested changes * fixed some minor issues * all requested changes marked as resolved have been changed * gdkchan's requested changes * fixed an issue with settings window getting chopped on small res * fixed 2 problems caused by rebase * changed the default theme * applied Thog's patch to fix issue on linux * fixed issue caused by rebase * added update check button that runs ryujinx-updater * reads version info from installer and displays it in about menu * changes completed * requested changes changed * fixed issue with default theme * fixed a bug and completed requested changes * added more tooltips and changed some text
2019-09-02 16:03:57 +00:00
ulong romfsSize = reader.ReadUInt64();
if (romfsSize != 0)
{
Device.FileSystem.SetRomFs(new HomebrewRomFsStream(input, obj.FileSize + (long)romfsOffset));
}
Added GUI to Ryujinx (#695) * Added GUI to Ryujinx * Updated to use Glade Also added scrollbar and default dark theme * Added support for loading icon from .nro files and cleaned up the code a bit * Added General Settings Menu (read-only for now) and moved some functionality from MainMenu.cs to ApplicationLibrary.cs * Added custom GUI theme support and changed the defualt theme to one I just wrote * Added GTK to process path, fixed a bug and minor edits * some more edits and a bug fix * general settings menu is now fully functional. also fixed the bug where ryujinx crashes when it trys to load an invalid gamedir * big rewrite * aesthetic changes to General Settings menu * Added Control Settings one day done feature :P * minor changes * 1st wave of changes * 2nd wave of changes * 3rd wave of changes * Cleanup settings ui * minor edits * new about window added, still needs styling * added spin button for new option and tooltips to settings * Game icons and names are now shown in the games list * add nuget package which contains gtk dependencies * requested changes have been changed * put CreateGameWindow on a new thread and stopped destroying the main menu when a game loads * fixed bug that allowed a user to attempt to load multiple games at a time which causes a crash * Added LastPlayed and TimePlayed columns to the game list * Did some testing and fixed some bugs Im not happy with one of the fixes so i will do it properly an upcoming commit * did some more bug testing and fixed another 2 bugs * caught an exception when ryujinx tries to load non-homebrew as homebrew * Large changes Rewrote ApplicationLibrary.cs (added comments too) so any devs reading it wont get eye cancer, also its probably more efficient now. Added 2 new columns (Developer name and application version) to the game list and wrote the logic for it. Ryujinx now loads NRO's TitleName and TitleID from the NACP file instead of the default NPDM. I also killed a lot of bugs * Moved Files moved ApplicationLibrary.cs to Ryujinx.HLE as that is a better place for it. Moved contents of GUI folder to Ui folder and changed the namespaces of the gui files from Ryujinx to Ryujinx.Ui * Added 'Open Ryujinx Folder' button to the file menu and did some small fixes * New features * updated nuget package with missing dlls and changed emmauss' requested changes * fixed some minor issues * all requested changes marked as resolved have been changed * gdkchan's requested changes * fixed an issue with settings window getting chopped on small res * fixed 2 problems caused by rebase * changed the default theme * applied Thog's patch to fix issue on linux * fixed issue caused by rebase * added update check button that runs ryujinx-updater * reads version info from installer and displays it in about menu * changes completed * requested changes changed * fixed issue with default theme * fixed a bug and completed requested changes * added more tooltips and changed some text
2019-09-02 16:03:57 +00:00
if (nacpSize != 0)
{
input.Seek(obj.FileSize + (long)nacpOffset, SeekOrigin.Begin);
reader.Read(ControlData.ByteSpan);
ref ApplicationControlProperty nacp = ref ControlData.Value;
metaData.TitleName = nacp.Titles[(int)State.DesiredTitleLanguage].Name.ToString();
Added GUI to Ryujinx (#695) * Added GUI to Ryujinx * Updated to use Glade Also added scrollbar and default dark theme * Added support for loading icon from .nro files and cleaned up the code a bit * Added General Settings Menu (read-only for now) and moved some functionality from MainMenu.cs to ApplicationLibrary.cs * Added custom GUI theme support and changed the defualt theme to one I just wrote * Added GTK to process path, fixed a bug and minor edits * some more edits and a bug fix * general settings menu is now fully functional. also fixed the bug where ryujinx crashes when it trys to load an invalid gamedir * big rewrite * aesthetic changes to General Settings menu * Added Control Settings one day done feature :P * minor changes * 1st wave of changes * 2nd wave of changes * 3rd wave of changes * Cleanup settings ui * minor edits * new about window added, still needs styling * added spin button for new option and tooltips to settings * Game icons and names are now shown in the games list * add nuget package which contains gtk dependencies * requested changes have been changed * put CreateGameWindow on a new thread and stopped destroying the main menu when a game loads * fixed bug that allowed a user to attempt to load multiple games at a time which causes a crash * Added LastPlayed and TimePlayed columns to the game list * Did some testing and fixed some bugs Im not happy with one of the fixes so i will do it properly an upcoming commit * did some more bug testing and fixed another 2 bugs * caught an exception when ryujinx tries to load non-homebrew as homebrew * Large changes Rewrote ApplicationLibrary.cs (added comments too) so any devs reading it wont get eye cancer, also its probably more efficient now. Added 2 new columns (Developer name and application version) to the game list and wrote the logic for it. Ryujinx now loads NRO's TitleName and TitleID from the NACP file instead of the default NPDM. I also killed a lot of bugs * Moved Files moved ApplicationLibrary.cs to Ryujinx.HLE as that is a better place for it. Moved contents of GUI folder to Ui folder and changed the namespaces of the gui files from Ryujinx to Ryujinx.Ui * Added 'Open Ryujinx Folder' button to the file menu and did some small fixes * New features * updated nuget package with missing dlls and changed emmauss' requested changes * fixed some minor issues * all requested changes marked as resolved have been changed * gdkchan's requested changes * fixed an issue with settings window getting chopped on small res * fixed 2 problems caused by rebase * changed the default theme * applied Thog's patch to fix issue on linux * fixed issue caused by rebase * added update check button that runs ryujinx-updater * reads version info from installer and displays it in about menu * changes completed * requested changes changed * fixed issue with default theme * fixed a bug and completed requested changes * added more tooltips and changed some text
2019-09-02 16:03:57 +00:00
if (string.IsNullOrWhiteSpace(metaData.TitleName))
{
metaData.TitleName = nacp.Titles.ToArray().FirstOrDefault(x => x.Name[0] != 0).Name.ToString();
Added GUI to Ryujinx (#695) * Added GUI to Ryujinx * Updated to use Glade Also added scrollbar and default dark theme * Added support for loading icon from .nro files and cleaned up the code a bit * Added General Settings Menu (read-only for now) and moved some functionality from MainMenu.cs to ApplicationLibrary.cs * Added custom GUI theme support and changed the defualt theme to one I just wrote * Added GTK to process path, fixed a bug and minor edits * some more edits and a bug fix * general settings menu is now fully functional. also fixed the bug where ryujinx crashes when it trys to load an invalid gamedir * big rewrite * aesthetic changes to General Settings menu * Added Control Settings one day done feature :P * minor changes * 1st wave of changes * 2nd wave of changes * 3rd wave of changes * Cleanup settings ui * minor edits * new about window added, still needs styling * added spin button for new option and tooltips to settings * Game icons and names are now shown in the games list * add nuget package which contains gtk dependencies * requested changes have been changed * put CreateGameWindow on a new thread and stopped destroying the main menu when a game loads * fixed bug that allowed a user to attempt to load multiple games at a time which causes a crash * Added LastPlayed and TimePlayed columns to the game list * Did some testing and fixed some bugs Im not happy with one of the fixes so i will do it properly an upcoming commit * did some more bug testing and fixed another 2 bugs * caught an exception when ryujinx tries to load non-homebrew as homebrew * Large changes Rewrote ApplicationLibrary.cs (added comments too) so any devs reading it wont get eye cancer, also its probably more efficient now. Added 2 new columns (Developer name and application version) to the game list and wrote the logic for it. Ryujinx now loads NRO's TitleName and TitleID from the NACP file instead of the default NPDM. I also killed a lot of bugs * Moved Files moved ApplicationLibrary.cs to Ryujinx.HLE as that is a better place for it. Moved contents of GUI folder to Ui folder and changed the namespaces of the gui files from Ryujinx to Ryujinx.Ui * Added 'Open Ryujinx Folder' button to the file menu and did some small fixes * New features * updated nuget package with missing dlls and changed emmauss' requested changes * fixed some minor issues * all requested changes marked as resolved have been changed * gdkchan's requested changes * fixed an issue with settings window getting chopped on small res * fixed 2 problems caused by rebase * changed the default theme * applied Thog's patch to fix issue on linux * fixed issue caused by rebase * added update check button that runs ryujinx-updater * reads version info from installer and displays it in about menu * changes completed * requested changes changed * fixed issue with default theme * fixed a bug and completed requested changes * added more tooltips and changed some text
2019-09-02 16:03:57 +00:00
}
if (nacp.PresenceGroupId != 0)
{
metaData.Aci0.TitleId = nacp.PresenceGroupId;
}
else if (nacp.SaveDataOwnerId.Value != 0)
Added GUI to Ryujinx (#695) * Added GUI to Ryujinx * Updated to use Glade Also added scrollbar and default dark theme * Added support for loading icon from .nro files and cleaned up the code a bit * Added General Settings Menu (read-only for now) and moved some functionality from MainMenu.cs to ApplicationLibrary.cs * Added custom GUI theme support and changed the defualt theme to one I just wrote * Added GTK to process path, fixed a bug and minor edits * some more edits and a bug fix * general settings menu is now fully functional. also fixed the bug where ryujinx crashes when it trys to load an invalid gamedir * big rewrite * aesthetic changes to General Settings menu * Added Control Settings one day done feature :P * minor changes * 1st wave of changes * 2nd wave of changes * 3rd wave of changes * Cleanup settings ui * minor edits * new about window added, still needs styling * added spin button for new option and tooltips to settings * Game icons and names are now shown in the games list * add nuget package which contains gtk dependencies * requested changes have been changed * put CreateGameWindow on a new thread and stopped destroying the main menu when a game loads * fixed bug that allowed a user to attempt to load multiple games at a time which causes a crash * Added LastPlayed and TimePlayed columns to the game list * Did some testing and fixed some bugs Im not happy with one of the fixes so i will do it properly an upcoming commit * did some more bug testing and fixed another 2 bugs * caught an exception when ryujinx tries to load non-homebrew as homebrew * Large changes Rewrote ApplicationLibrary.cs (added comments too) so any devs reading it wont get eye cancer, also its probably more efficient now. Added 2 new columns (Developer name and application version) to the game list and wrote the logic for it. Ryujinx now loads NRO's TitleName and TitleID from the NACP file instead of the default NPDM. I also killed a lot of bugs * Moved Files moved ApplicationLibrary.cs to Ryujinx.HLE as that is a better place for it. Moved contents of GUI folder to Ui folder and changed the namespaces of the gui files from Ryujinx to Ryujinx.Ui * Added 'Open Ryujinx Folder' button to the file menu and did some small fixes * New features * updated nuget package with missing dlls and changed emmauss' requested changes * fixed some minor issues * all requested changes marked as resolved have been changed * gdkchan's requested changes * fixed an issue with settings window getting chopped on small res * fixed 2 problems caused by rebase * changed the default theme * applied Thog's patch to fix issue on linux * fixed issue caused by rebase * added update check button that runs ryujinx-updater * reads version info from installer and displays it in about menu * changes completed * requested changes changed * fixed issue with default theme * fixed a bug and completed requested changes * added more tooltips and changed some text
2019-09-02 16:03:57 +00:00
{
metaData.Aci0.TitleId = nacp.SaveDataOwnerId.Value;
Added GUI to Ryujinx (#695) * Added GUI to Ryujinx * Updated to use Glade Also added scrollbar and default dark theme * Added support for loading icon from .nro files and cleaned up the code a bit * Added General Settings Menu (read-only for now) and moved some functionality from MainMenu.cs to ApplicationLibrary.cs * Added custom GUI theme support and changed the defualt theme to one I just wrote * Added GTK to process path, fixed a bug and minor edits * some more edits and a bug fix * general settings menu is now fully functional. also fixed the bug where ryujinx crashes when it trys to load an invalid gamedir * big rewrite * aesthetic changes to General Settings menu * Added Control Settings one day done feature :P * minor changes * 1st wave of changes * 2nd wave of changes * 3rd wave of changes * Cleanup settings ui * minor edits * new about window added, still needs styling * added spin button for new option and tooltips to settings * Game icons and names are now shown in the games list * add nuget package which contains gtk dependencies * requested changes have been changed * put CreateGameWindow on a new thread and stopped destroying the main menu when a game loads * fixed bug that allowed a user to attempt to load multiple games at a time which causes a crash * Added LastPlayed and TimePlayed columns to the game list * Did some testing and fixed some bugs Im not happy with one of the fixes so i will do it properly an upcoming commit * did some more bug testing and fixed another 2 bugs * caught an exception when ryujinx tries to load non-homebrew as homebrew * Large changes Rewrote ApplicationLibrary.cs (added comments too) so any devs reading it wont get eye cancer, also its probably more efficient now. Added 2 new columns (Developer name and application version) to the game list and wrote the logic for it. Ryujinx now loads NRO's TitleName and TitleID from the NACP file instead of the default NPDM. I also killed a lot of bugs * Moved Files moved ApplicationLibrary.cs to Ryujinx.HLE as that is a better place for it. Moved contents of GUI folder to Ui folder and changed the namespaces of the gui files from Ryujinx to Ryujinx.Ui * Added 'Open Ryujinx Folder' button to the file menu and did some small fixes * New features * updated nuget package with missing dlls and changed emmauss' requested changes * fixed some minor issues * all requested changes marked as resolved have been changed * gdkchan's requested changes * fixed an issue with settings window getting chopped on small res * fixed 2 problems caused by rebase * changed the default theme * applied Thog's patch to fix issue on linux * fixed issue caused by rebase * added update check button that runs ryujinx-updater * reads version info from installer and displays it in about menu * changes completed * requested changes changed * fixed issue with default theme * fixed a bug and completed requested changes * added more tooltips and changed some text
2019-09-02 16:03:57 +00:00
}
else if (nacp.AddOnContentBaseId != 0)
Added GUI to Ryujinx (#695) * Added GUI to Ryujinx * Updated to use Glade Also added scrollbar and default dark theme * Added support for loading icon from .nro files and cleaned up the code a bit * Added General Settings Menu (read-only for now) and moved some functionality from MainMenu.cs to ApplicationLibrary.cs * Added custom GUI theme support and changed the defualt theme to one I just wrote * Added GTK to process path, fixed a bug and minor edits * some more edits and a bug fix * general settings menu is now fully functional. also fixed the bug where ryujinx crashes when it trys to load an invalid gamedir * big rewrite * aesthetic changes to General Settings menu * Added Control Settings one day done feature :P * minor changes * 1st wave of changes * 2nd wave of changes * 3rd wave of changes * Cleanup settings ui * minor edits * new about window added, still needs styling * added spin button for new option and tooltips to settings * Game icons and names are now shown in the games list * add nuget package which contains gtk dependencies * requested changes have been changed * put CreateGameWindow on a new thread and stopped destroying the main menu when a game loads * fixed bug that allowed a user to attempt to load multiple games at a time which causes a crash * Added LastPlayed and TimePlayed columns to the game list * Did some testing and fixed some bugs Im not happy with one of the fixes so i will do it properly an upcoming commit * did some more bug testing and fixed another 2 bugs * caught an exception when ryujinx tries to load non-homebrew as homebrew * Large changes Rewrote ApplicationLibrary.cs (added comments too) so any devs reading it wont get eye cancer, also its probably more efficient now. Added 2 new columns (Developer name and application version) to the game list and wrote the logic for it. Ryujinx now loads NRO's TitleName and TitleID from the NACP file instead of the default NPDM. I also killed a lot of bugs * Moved Files moved ApplicationLibrary.cs to Ryujinx.HLE as that is a better place for it. Moved contents of GUI folder to Ui folder and changed the namespaces of the gui files from Ryujinx to Ryujinx.Ui * Added 'Open Ryujinx Folder' button to the file menu and did some small fixes * New features * updated nuget package with missing dlls and changed emmauss' requested changes * fixed some minor issues * all requested changes marked as resolved have been changed * gdkchan's requested changes * fixed an issue with settings window getting chopped on small res * fixed 2 problems caused by rebase * changed the default theme * applied Thog's patch to fix issue on linux * fixed issue caused by rebase * added update check button that runs ryujinx-updater * reads version info from installer and displays it in about menu * changes completed * requested changes changed * fixed issue with default theme * fixed a bug and completed requested changes * added more tooltips and changed some text
2019-09-02 16:03:57 +00:00
{
metaData.Aci0.TitleId = nacp.AddOnContentBaseId - 0x1000;
Added GUI to Ryujinx (#695) * Added GUI to Ryujinx * Updated to use Glade Also added scrollbar and default dark theme * Added support for loading icon from .nro files and cleaned up the code a bit * Added General Settings Menu (read-only for now) and moved some functionality from MainMenu.cs to ApplicationLibrary.cs * Added custom GUI theme support and changed the defualt theme to one I just wrote * Added GTK to process path, fixed a bug and minor edits * some more edits and a bug fix * general settings menu is now fully functional. also fixed the bug where ryujinx crashes when it trys to load an invalid gamedir * big rewrite * aesthetic changes to General Settings menu * Added Control Settings one day done feature :P * minor changes * 1st wave of changes * 2nd wave of changes * 3rd wave of changes * Cleanup settings ui * minor edits * new about window added, still needs styling * added spin button for new option and tooltips to settings * Game icons and names are now shown in the games list * add nuget package which contains gtk dependencies * requested changes have been changed * put CreateGameWindow on a new thread and stopped destroying the main menu when a game loads * fixed bug that allowed a user to attempt to load multiple games at a time which causes a crash * Added LastPlayed and TimePlayed columns to the game list * Did some testing and fixed some bugs Im not happy with one of the fixes so i will do it properly an upcoming commit * did some more bug testing and fixed another 2 bugs * caught an exception when ryujinx tries to load non-homebrew as homebrew * Large changes Rewrote ApplicationLibrary.cs (added comments too) so any devs reading it wont get eye cancer, also its probably more efficient now. Added 2 new columns (Developer name and application version) to the game list and wrote the logic for it. Ryujinx now loads NRO's TitleName and TitleID from the NACP file instead of the default NPDM. I also killed a lot of bugs * Moved Files moved ApplicationLibrary.cs to Ryujinx.HLE as that is a better place for it. Moved contents of GUI folder to Ui folder and changed the namespaces of the gui files from Ryujinx to Ryujinx.Ui * Added 'Open Ryujinx Folder' button to the file menu and did some small fixes * New features * updated nuget package with missing dlls and changed emmauss' requested changes * fixed some minor issues * all requested changes marked as resolved have been changed * gdkchan's requested changes * fixed an issue with settings window getting chopped on small res * fixed 2 problems caused by rebase * changed the default theme * applied Thog's patch to fix issue on linux * fixed issue caused by rebase * added update check button that runs ryujinx-updater * reads version info from installer and displays it in about menu * changes completed * requested changes changed * fixed issue with default theme * fixed a bug and completed requested changes * added more tooltips and changed some text
2019-09-02 16:03:57 +00:00
}
else
Added GUI to Ryujinx (#695) * Added GUI to Ryujinx * Updated to use Glade Also added scrollbar and default dark theme * Added support for loading icon from .nro files and cleaned up the code a bit * Added General Settings Menu (read-only for now) and moved some functionality from MainMenu.cs to ApplicationLibrary.cs * Added custom GUI theme support and changed the defualt theme to one I just wrote * Added GTK to process path, fixed a bug and minor edits * some more edits and a bug fix * general settings menu is now fully functional. also fixed the bug where ryujinx crashes when it trys to load an invalid gamedir * big rewrite * aesthetic changes to General Settings menu * Added Control Settings one day done feature :P * minor changes * 1st wave of changes * 2nd wave of changes * 3rd wave of changes * Cleanup settings ui * minor edits * new about window added, still needs styling * added spin button for new option and tooltips to settings * Game icons and names are now shown in the games list * add nuget package which contains gtk dependencies * requested changes have been changed * put CreateGameWindow on a new thread and stopped destroying the main menu when a game loads * fixed bug that allowed a user to attempt to load multiple games at a time which causes a crash * Added LastPlayed and TimePlayed columns to the game list * Did some testing and fixed some bugs Im not happy with one of the fixes so i will do it properly an upcoming commit * did some more bug testing and fixed another 2 bugs * caught an exception when ryujinx tries to load non-homebrew as homebrew * Large changes Rewrote ApplicationLibrary.cs (added comments too) so any devs reading it wont get eye cancer, also its probably more efficient now. Added 2 new columns (Developer name and application version) to the game list and wrote the logic for it. Ryujinx now loads NRO's TitleName and TitleID from the NACP file instead of the default NPDM. I also killed a lot of bugs * Moved Files moved ApplicationLibrary.cs to Ryujinx.HLE as that is a better place for it. Moved contents of GUI folder to Ui folder and changed the namespaces of the gui files from Ryujinx to Ryujinx.Ui * Added 'Open Ryujinx Folder' button to the file menu and did some small fixes * New features * updated nuget package with missing dlls and changed emmauss' requested changes * fixed some minor issues * all requested changes marked as resolved have been changed * gdkchan's requested changes * fixed an issue with settings window getting chopped on small res * fixed 2 problems caused by rebase * changed the default theme * applied Thog's patch to fix issue on linux * fixed issue caused by rebase * added update check button that runs ryujinx-updater * reads version info from installer and displays it in about menu * changes completed * requested changes changed * fixed issue with default theme * fixed a bug and completed requested changes * added more tooltips and changed some text
2019-09-02 16:03:57 +00:00
{
metaData.Aci0.TitleId = 0000000000000000;
}
}
}
else
{
Logger.PrintWarning(LogClass.Loader, $"Unsupported ASET header version found \"{asetVersion}\"");
}
}
}
}
else
{
staticObject = new NsoExecutable(new LocalStorage(filePath, FileAccess.Read));
}
ContentManager.LoadEntries(Device);
TitleName = metaData.TitleName;
TitleId = metaData.Aci0.TitleId;
TitleIs64Bit = metaData.Is64Bit;
2019-05-30 20:27:43 +00:00
ProgramLoader.LoadStaticObjects(this, metaData, new IExecutable[] { staticObject });
}
private Npdm GetDefaultNpdm()
{
Assembly asm = Assembly.GetCallingAssembly();
2018-02-04 23:08:20 +00:00
using (Stream npdmStream = asm.GetManifestResourceStream("Ryujinx.HLE.Homebrew.npdm"))
2018-02-04 23:08:20 +00:00
{
return new Npdm(npdmStream);
2018-02-04 23:08:20 +00:00
}
}
private Result EnsureSaveData(TitleId titleId)
{
Logger.PrintInfo(LogClass.Application, "Ensuring required savedata exists.");
Uid user = State.Account.LastOpenedUser.UserId.ToLibHacUid();
ref ApplicationControlProperty control = ref ControlData.Value;
if (LibHac.Util.IsEmpty(ControlData.ByteSpan))
{
// If the current application doesn't have a loaded control property, create a dummy one
// and set the savedata sizes so a user savedata will be created.
control = ref new BlitStruct<ApplicationControlProperty>(1).Value;
// The set sizes don't actually matter as long as they're non-zero because we use directory savedata.
control.UserAccountSaveDataSize = 0x4000;
control.UserAccountSaveDataJournalSize = 0x4000;
Logger.PrintWarning(LogClass.Application,
"No control file was found for this game. Using a dummy one instead. This may cause inaccuracies in some games.");
}
FileSystemClient fs = Device.FileSystem.FsClient;
Result rc = fs.EnsureApplicationCacheStorage(out _, titleId, ref control);
if (rc.IsFailure())
{
Logger.PrintError(LogClass.Application, $"Error calling EnsureApplicationCacheStorage. Result code {rc.ToStringWithName()}");
}
rc = EnsureApplicationSaveData(fs, out _, titleId, ref control, ref user);
if (rc.IsFailure())
{
Logger.PrintError(LogClass.Application, $"Error calling EnsureApplicationSaveData. Result code {rc.ToStringWithName()}");
}
return rc;
}
public void SignalDisplayResolutionChange()
{
DisplayResolutionChangeEvent.ReadableEvent.Signal();
}
public void SignalVsync()
{
VsyncEvent.ReadableEvent.Signal();
}
internal long GetThreadUid()
2018-02-04 23:08:20 +00:00
{
return Interlocked.Increment(ref _threadUid) - 1;
2018-02-04 23:08:20 +00:00
}
internal long GetKipId()
{
return Interlocked.Increment(ref _kipId) - 1;
}
internal long GetProcessId()
{
return Interlocked.Increment(ref _processId) - 1;
}
public void EnableMultiCoreScheduling()
2018-02-04 23:08:20 +00:00
{
if (!_hasStarted)
{
Scheduler.MultiCoreScheduling = true;
}
}
public void DisableMultiCoreScheduling()
{
if (!_hasStarted)
{
Scheduler.MultiCoreScheduling = false;
}
2018-02-04 23:08:20 +00:00
}
public void Dispose()
2018-02-04 23:08:20 +00:00
{
Dispose(true);
}
2018-02-04 23:08:20 +00:00
protected virtual void Dispose(bool disposing)
{
if (!_isDisposed && disposing)
2018-02-04 23:08:20 +00:00
{
ConfigurationState.Instance.System.EnableDockedMode.Event -= OnDockedModeChange;
_isDisposed = true;
SurfaceFlinger.Dispose();
KProcess terminationProcess = new KProcess(this);
KThread terminationThread = new KThread(this);
terminationThread.Initialize(0, 0, 0, 3, 0, terminationProcess, ThreadType.Kernel, () =>
{
// Force all threads to exit.
lock (Processes)
{
foreach (KProcess process in Processes.Values)
{
process.Terminate();
}
}
// Exit ourself now!
Scheduler.ExitThread(terminationThread);
Scheduler.GetCurrentThread().Exit();
Scheduler.RemoveThread(terminationThread);
});
terminationThread.Start();
// Destroy nvservices channels as KThread could be waiting on some user events.
// This is safe as KThread that are likely to call ioctls are going to be terminated by the post handler hook on the SVC facade.
INvDrvServices.Destroy();
// This is needed as the IPC Dummy KThread is also counted in the ThreadCounter.
ThreadCounter.Signal();
// It's only safe to release resources once all threads
// have exited.
ThreadCounter.Signal();
ThreadCounter.Wait();
Scheduler.Dispose();
TimeManager.Dispose();
Device.Unload();
2018-02-04 23:08:20 +00:00
}
}
}
}