diff --git a/Ryujinx.HLE/HOS/ApplicationLoader.cs b/Ryujinx.HLE/HOS/ApplicationLoader.cs index 65448d5dae..cf92abda26 100644 --- a/Ryujinx.HLE/HOS/ApplicationLoader.cs +++ b/Ryujinx.HLE/HOS/ApplicationLoader.cs @@ -481,14 +481,14 @@ namespace Ryujinx.HLE.HOS if (result.IsSuccess() && bytesRead == controlData.ByteSpan.Length) { - titleName = controlData.Value.Titles[(int)device.System.State.DesiredTitleLanguage].Name.ToString(); + titleName = controlData.Value.Title[(int)device.System.State.DesiredTitleLanguage].NameString.ToString(); if (string.IsNullOrWhiteSpace(titleName)) { - titleName = controlData.Value.Titles.ToArray().FirstOrDefault(x => x.Name[0] != 0).Name.ToString(); + titleName = controlData.Value.Title.ItemsRo.ToArray().FirstOrDefault(x => x.Name[0] != 0).NameString.ToString(); } - displayVersion = controlData.Value.DisplayVersion.ToString(); + displayVersion = controlData.Value.DisplayVersionString.ToString(); } } else @@ -615,20 +615,20 @@ namespace Ryujinx.HLE.HOS ref ApplicationControlProperty nacp = ref ControlData.Value; - programInfo.Name = nacp.Titles[(int)_device.System.State.DesiredTitleLanguage].Name.ToString(); + programInfo.Name = nacp.Title[(int)_device.System.State.DesiredTitleLanguage].NameString.ToString(); if (string.IsNullOrWhiteSpace(programInfo.Name)) { - programInfo.Name = nacp.Titles.ToArray().FirstOrDefault(x => x.Name[0] != 0).Name.ToString(); + programInfo.Name = nacp.Title.ItemsRo.ToArray().FirstOrDefault(x => x.Name[0] != 0).NameString.ToString(); } if (nacp.PresenceGroupId != 0) { programInfo.ProgramId = nacp.PresenceGroupId; } - else if (nacp.SaveDataOwnerId.Value != 0) + else if (nacp.SaveDataOwnerId != 0) { - programInfo.ProgramId = nacp.SaveDataOwnerId.Value; + programInfo.ProgramId = nacp.SaveDataOwnerId; } else if (nacp.AddOnContentBaseId != 0) { @@ -776,14 +776,14 @@ namespace Ryujinx.HLE.HOS // 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; - control.SaveDataOwnerId = applicationId; + control.SaveDataOwnerId = applicationId.Value; Logger.Warning?.Print(LogClass.Application, "No control file was found for this game. Using a dummy one instead. This may cause inaccuracies in some games."); } HorizonClient hos = _device.System.LibHacHorizonManager.RyujinxClient; - Result resultCode = hos.Fs.EnsureApplicationCacheStorage(out _, out _, applicationId, ref control); + Result resultCode = hos.Fs.EnsureApplicationCacheStorage(out _, out _, applicationId, in control); if (resultCode.IsFailure()) { @@ -792,7 +792,7 @@ namespace Ryujinx.HLE.HOS return resultCode; } - resultCode = EnsureApplicationSaveData(hos.Fs, out _, applicationId, ref control, ref user); + resultCode = hos.Fs.EnsureApplicationSaveData(out _, applicationId, in control, in user); if (resultCode.IsFailure()) { diff --git a/Ryujinx.HLE/HOS/Horizon.cs b/Ryujinx.HLE/HOS/Horizon.cs index 56c9985901..cadd43ffff 100644 --- a/Ryujinx.HLE/HOS/Horizon.cs +++ b/Ryujinx.HLE/HOS/Horizon.cs @@ -466,7 +466,7 @@ namespace Ryujinx.HLE.HOS AudioRendererManager.Dispose(); - LibHacHorizonManager.AmClient.Fs.UnregisterProgram(LibHacHorizonManager.ApplicationClient.Os.GetCurrentProcessId().Value); + LibHacHorizonManager.PmClient.Fs.UnregisterProgram(LibHacHorizonManager.ApplicationClient.Os.GetCurrentProcessId().Value).ThrowIfFailure(); KernelContext.Dispose(); } diff --git a/Ryujinx.HLE/HOS/LibHacHorizonManager.cs b/Ryujinx.HLE/HOS/LibHacHorizonManager.cs index 4ad8446eb5..35e5c6e910 100644 --- a/Ryujinx.HLE/HOS/LibHacHorizonManager.cs +++ b/Ryujinx.HLE/HOS/LibHacHorizonManager.cs @@ -24,6 +24,7 @@ namespace Ryujinx.HLE.HOS public HorizonClient BcatClient { get; private set; } public HorizonClient FsClient { get; private set; } public HorizonClient NsClient { get; private set; } + public HorizonClient PmClient { get; private set; } public HorizonClient SdbClient { get; private set; } private SharedRef _arpIReader; @@ -65,6 +66,7 @@ namespace Ryujinx.HLE.HOS public void InitializeSystemClients() { + PmClient = Server.CreatePrivilegedHorizonClient(); AccountClient = Server.CreateHorizonClient(new ProgramLocation(SystemProgramId.Account, StorageId.BuiltInSystem), AccountFsPermissions); AmClient = Server.CreateHorizonClient(new ProgramLocation(SystemProgramId.Am, StorageId.BuiltInSystem), AmFsPermissions); NsClient = Server.CreateHorizonClient(new ProgramLocation(SystemProgramId.Ns, StorageId.BuiltInSystem), NsFsPermissions); diff --git a/Ryujinx.HLE/HOS/ModLoader.cs b/Ryujinx.HLE/HOS/ModLoader.cs index e2037924bd..27c0022fa7 100644 --- a/Ryujinx.HLE/HOS/ModLoader.cs +++ b/Ryujinx.HLE/HOS/ModLoader.cs @@ -695,7 +695,7 @@ namespace Ryujinx.HLE.HOS var buildIds = programs.Select(p => p switch { - NsoExecutable nso => BitConverter.ToString(nso.BuildId.Bytes.ToArray()).Replace("-", "").TrimEnd('0'), + NsoExecutable nso => BitConverter.ToString(nso.BuildId.ItemsRo.ToArray()).Replace("-", "").TrimEnd('0'), NroExecutable nro => BitConverter.ToString(nro.Header.BuildId).Replace("-", "").TrimEnd('0'), _ => string.Empty }).ToList(); diff --git a/Ryujinx.HLE/HOS/ProgramLoader.cs b/Ryujinx.HLE/HOS/ProgramLoader.cs index 5605ab0114..403e0227c5 100644 --- a/Ryujinx.HLE/HOS/ProgramLoader.cs +++ b/Ryujinx.HLE/HOS/ProgramLoader.cs @@ -160,7 +160,7 @@ namespace Ryujinx.HLE.HOS var buildIds = executables.Select(e => (e switch { - NsoExecutable nso => BitConverter.ToString(nso.BuildId.Bytes.ToArray()), + NsoExecutable nso => BitConverter.ToString(nso.BuildId.ItemsRo.ToArray()), NroExecutable nro => BitConverter.ToString(nro.Header.BuildId), _ => "" }).Replace("-", "").ToUpper()); diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/AccountManager.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/AccountManager.cs index 3f504b2eaf..e28fe1061e 100644 --- a/Ryujinx.HLE/HOS/Services/Account/Acc/AccountManager.cs +++ b/Ryujinx.HLE/HOS/Services/Account/Acc/AccountManager.cs @@ -168,8 +168,8 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc private void DeleteSaveData(UserId userId) { - SaveDataFilter saveDataFilter = new SaveDataFilter(); - saveDataFilter.SetUserId(new LibHac.Fs.UserId((ulong)userId.High, (ulong)userId.Low)); + var saveDataFilter = SaveDataFilter.Make(programId: default, saveType: default, + new LibHac.Fs.UserId((ulong)userId.High, (ulong)userId.Low), saveDataId: default, index: default); using var saveDataIterator = new UniqueRef(); diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs index c29ed570c4..4de0b34bbb 100644 --- a/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs +++ b/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs @@ -169,7 +169,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc // TODO: Account actually calls nn::arp::detail::IReader::GetApplicationControlProperty() with the current Pid and store the result (NACP file) internally. // But since we use LibHac and we load one Application at a time, it's not necessary. - context.ResponseData.Write(context.Device.Application.ControlData.Value.UserAccountSwitchLock); + context.ResponseData.Write((byte)context.Device.Application.ControlData.Value.UserAccountSwitchLock); Logger.Stub?.PrintStub(LogClass.ServiceAcc); diff --git a/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs b/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs index 11b2f41ba2..efc1884f77 100644 --- a/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs +++ b/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs @@ -131,7 +131,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati } HorizonClient hos = context.Device.System.LibHacHorizonManager.AmClient; - Result result = EnsureApplicationSaveData(hos.Fs, out long requiredSize, applicationId, ref control, ref userId); + Result result = hos.Fs.EnsureApplicationSaveData(out long requiredSize, applicationId, in control, in userId); context.ResponseData.Write(requiredSize); @@ -148,7 +148,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati // TODO: When above calls are implemented, switch to using ns:am long desiredLanguageCode = context.Device.System.State.DesiredLanguageCode; - int supportedLanguages = (int)context.Device.Application.ControlData.Value.SupportedLanguages; + int supportedLanguages = (int)context.Device.Application.ControlData.Value.SupportedLanguageFlag; int firstSupported = BitOperations.TrailingZeroCount(supportedLanguages); if (firstSupported > (int)SystemState.TitleLanguage.BrazilianPortuguese) @@ -190,7 +190,6 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati // GetDisplayVersion() -> nn::oe::DisplayVersion public ResultCode GetDisplayVersion(ServiceCtx context) { - // This should work as DisplayVersion U8Span always gives a 0x10 size byte array. // If an NACP isn't found, the buffer will be all '\0' which seems to be the correct implementation. context.ResponseData.Write(context.Device.Application.ControlData.Value.DisplayVersion); @@ -252,7 +251,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati BlitStruct controlHolder = context.Device.Application.ControlData; Result result = _horizon.Fs.CreateApplicationCacheStorage(out long requiredSize, - out CacheStorageTargetMedia storageTarget, applicationId, ref controlHolder.Value, index, saveSize, + out CacheStorageTargetMedia storageTarget, applicationId, in controlHolder.Value, index, saveSize, journalSize); if (result.IsFailure()) return (ResultCode)result.Value; diff --git a/Ryujinx.HLE/HOS/Services/Arp/LibHacIReader.cs b/Ryujinx.HLE/HOS/Services/Arp/LibHacIReader.cs index 985dcdec4a..d7686871a8 100644 --- a/Ryujinx.HLE/HOS/Services/Arp/LibHacIReader.cs +++ b/Ryujinx.HLE/HOS/Services/Arp/LibHacIReader.cs @@ -16,7 +16,7 @@ namespace Ryujinx.HLE.HOS.Services.Arp { launchProperty = new LibHac.Arp.ApplicationLaunchProperty { - BaseStorageId = StorageId.BuiltInUser, + StorageId = StorageId.BuiltInUser, ApplicationId = ApplicationId }; @@ -29,7 +29,7 @@ namespace Ryujinx.HLE.HOS.Services.Arp { launchProperty = new LibHac.Arp.ApplicationLaunchProperty { - BaseStorageId = StorageId.BuiltInUser, + StorageId = StorageId.BuiltInUser, ApplicationId = applicationId }; diff --git a/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/FileSystemProxyHelper.cs b/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/FileSystemProxyHelper.cs index 6e9994867a..2afa348071 100644 --- a/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/FileSystemProxyHelper.cs +++ b/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/FileSystemProxyHelper.cs @@ -132,22 +132,10 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy } } - public static Result ReadFsPath(out FsPath path, ServiceCtx context, int index = 0) - { - ulong position = context.Request.PtrBuff[index].Position; - ulong size = context.Request.PtrBuff[index].Size; - - byte[] pathBytes = new byte[size]; - - context.Memory.Read(position, pathBytes); - - return FsPath.FromSpan(out path, pathBytes); - } - public static ref readonly FspPath GetFspPath(ServiceCtx context, int index = 0) { - ulong position = (ulong)context.Request.PtrBuff[index].Position; - ulong size = (ulong)context.Request.PtrBuff[index].Size; + ulong position = context.Request.PtrBuff[index].Position; + ulong size = context.Request.PtrBuff[index].Size; ReadOnlySpan buffer = context.Memory.GetSpan(position, (int)size); ReadOnlySpan fspBuffer = MemoryMarshal.Cast(buffer); @@ -157,8 +145,8 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy public static ref readonly LibHac.FsSrv.Sf.Path GetSfPath(ServiceCtx context, int index = 0) { - ulong position = (ulong)context.Request.PtrBuff[index].Position; - ulong size = (ulong)context.Request.PtrBuff[index].Size; + ulong position = context.Request.PtrBuff[index].Position; + ulong size = context.Request.PtrBuff[index].Size; ReadOnlySpan buffer = context.Memory.GetSpan(position, (int)size); ReadOnlySpan pathBuffer = MemoryMarshal.Cast(buffer); diff --git a/Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs b/Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs index 8be0bbcf70..07ade0c65b 100644 --- a/Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs +++ b/Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs @@ -1,6 +1,6 @@ using LibHac; using LibHac.Common; -using LibHac.FsSrv; +using LibHac.Fs; namespace Ryujinx.HLE.HOS.Services.Fs { diff --git a/Ryujinx.HLE/HOS/Services/Pctl/ParentalControlServiceFactory/IParentalControlService.cs b/Ryujinx.HLE/HOS/Services/Pctl/ParentalControlServiceFactory/IParentalControlService.cs index 15b998f2a7..1ccf0fb423 100644 --- a/Ryujinx.HLE/HOS/Services/Pctl/ParentalControlServiceFactory/IParentalControlService.cs +++ b/Ryujinx.HLE/HOS/Services/Pctl/ParentalControlServiceFactory/IParentalControlService.cs @@ -1,8 +1,9 @@ -using LibHac.Ns; using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Arp; using System; +using static LibHac.Ns.ApplicationControlProperty; + namespace Ryujinx.HLE.HOS.Services.Pctl.ParentalControlServiceFactory { class IParentalControlService : IpcService @@ -52,8 +53,8 @@ namespace Ryujinx.HLE.HOS.Services.Pctl.ParentalControlServiceFactory _titleId = titleId; // TODO: Call nn::arp::GetApplicationControlProperty here when implemented, if it return ResultCode.Success we assign fields. - _ratingAge = Array.ConvertAll(context.Device.Application.ControlData.Value.RatingAge.ToArray(), Convert.ToInt32); - _parentalControlFlag = context.Device.Application.ControlData.Value.ParentalControl; + _ratingAge = Array.ConvertAll(context.Device.Application.ControlData.Value.RatingAge.ItemsRo.ToArray(), Convert.ToInt32); + _parentalControlFlag = context.Device.Application.ControlData.Value.ParentalControlFlag; } } @@ -224,7 +225,7 @@ namespace Ryujinx.HLE.HOS.Services.Pctl.ParentalControlServiceFactory private ResultCode IsStereoVisionPermittedImpl() { /* - // TODO: Application Exemptions are readed from file "appExemptions.dat" in the service savedata. + // TODO: Application Exemptions are read from file "appExemptions.dat" in the service savedata. // Since we don't support the pctl savedata for now, this can be implemented later. if (appExemption) diff --git a/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs b/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs index 3449e1082c..fc6635fa75 100644 --- a/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs +++ b/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs @@ -15,6 +15,8 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService internal static ResultCode GetPlayStatistics(ServiceCtx context, bool byUserId = false) { + ref readonly var controlProperty = ref context.Device.Application.ControlData.Value; + ulong inputPosition = context.Request.SendBuff[0].Position; ulong inputSize = context.Request.SendBuff[0].Size; @@ -31,7 +33,7 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService } } - PlayLogQueryCapability queryCapability = (PlayLogQueryCapability)context.Device.Application.ControlData.Value.PlayLogQueryCapability; + PlayLogQueryCapability queryCapability = (PlayLogQueryCapability)controlProperty.PlayLogQueryCapability; List titleIds = new List(); @@ -45,7 +47,7 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService // Check if input title ids are in the whitelist. foreach (ulong titleId in titleIds) { - if (!context.Device.Application.ControlData.Value.PlayLogQueryableApplicationId.Contains(titleId)) + if (!controlProperty.PlayLogQueryableApplicationId.ItemsRo.Contains(titleId)) { return (ResultCode)Am.ResultCode.ObjectInvalid; } diff --git a/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs b/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs index f983536c7b..d3c0d1bf44 100644 --- a/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs +++ b/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs @@ -1,4 +1,4 @@ -using LibHac.Common; +using LibHac.Common.FixedArrays; using LibHac.Fs; using LibHac.Loader; using LibHac.Tools.FsSystem; @@ -26,8 +26,8 @@ namespace Ryujinx.HLE.Loaders.Executables public uint DataSize { get; } public uint BssSize { get; } - public string Name; - public Buffer32 BuildId; + public string Name; + public Array32 BuildId; public NsoExecutable(IStorage inStorage, string name = null) { diff --git a/Ryujinx.HLE/Ryujinx.HLE.csproj b/Ryujinx.HLE/Ryujinx.HLE.csproj index 0d7b577c65..cf1c734fc2 100644 --- a/Ryujinx.HLE/Ryujinx.HLE.csproj +++ b/Ryujinx.HLE/Ryujinx.HLE.csproj @@ -19,7 +19,7 @@ - + diff --git a/Ryujinx/Ui/App/ApplicationLibrary.cs b/Ryujinx/Ui/App/ApplicationLibrary.cs index 519dd72704..3658dfe28f 100644 --- a/Ryujinx/Ui/App/ApplicationLibrary.cs +++ b/Ryujinx/Ui/App/ApplicationLibrary.cs @@ -558,10 +558,10 @@ namespace Ryujinx.Ui.App { _ = Enum.TryParse(_desiredTitleLanguage.ToString(), out TitleLanguage desiredTitleLanguage); - if (controlData.Titles.Length > (int)desiredTitleLanguage) + if (controlData.Title.ItemsRo.Length > (int)desiredTitleLanguage) { - titleName = controlData.Titles[(int)desiredTitleLanguage].Name.ToString(); - publisher = controlData.Titles[(int)desiredTitleLanguage].Publisher.ToString(); + titleName = controlData.Title[(int)desiredTitleLanguage].NameString.ToString(); + publisher = controlData.Title[(int)desiredTitleLanguage].PublisherString.ToString(); } else { @@ -571,11 +571,11 @@ namespace Ryujinx.Ui.App if (string.IsNullOrWhiteSpace(titleName)) { - foreach (ApplicationControlTitle controlTitle in controlData.Titles) + foreach (ref readonly var controlTitle in controlData.Title.ItemsRo) { - if (!((U8Span)controlTitle.Name).IsEmpty()) + if (!controlTitle.NameString.IsEmpty()) { - titleName = controlTitle.Name.ToString(); + titleName = controlTitle.NameString.ToString(); break; } @@ -584,11 +584,11 @@ namespace Ryujinx.Ui.App if (string.IsNullOrWhiteSpace(publisher)) { - foreach (ApplicationControlTitle controlTitle in controlData.Titles) + foreach (ref readonly var controlTitle in controlData.Title.ItemsRo) { - if (!((U8Span)controlTitle.Publisher).IsEmpty()) + if (!controlTitle.PublisherString.IsEmpty()) { - publisher = controlTitle.Publisher.ToString(); + publisher = controlTitle.PublisherString.ToString(); break; } @@ -599,7 +599,7 @@ namespace Ryujinx.Ui.App { titleId = controlData.PresenceGroupId.ToString("x16"); } - else if (controlData.SaveDataOwnerId.Value != 0) + else if (controlData.SaveDataOwnerId != 0) { titleId = controlData.SaveDataOwnerId.ToString(); } @@ -612,7 +612,7 @@ namespace Ryujinx.Ui.App titleId = "0000000000000000"; } - version = controlData.DisplayVersion.ToString(); + version = controlData.DisplayVersionString.ToString(); } private bool IsUpdateApplied(string titleId, out IFileSystem updatedControlFs) diff --git a/Ryujinx/Ui/Widgets/GameTableContextMenu.cs b/Ryujinx/Ui/Widgets/GameTableContextMenu.cs index be9fc7b418..ef8fca341f 100644 --- a/Ryujinx/Ui/Widgets/GameTableContextMenu.cs +++ b/Ryujinx/Ui/Widgets/GameTableContextMenu.cs @@ -6,7 +6,6 @@ using LibHac.Fs; using LibHac.Fs.Fsa; using LibHac.Fs.Shim; using LibHac.FsSystem; -using LibHac.Ncm; using LibHac.Ns; using LibHac.Tools.Fs; using LibHac.Tools.FsSystem; @@ -26,8 +25,6 @@ using System.IO; using System.Reflection; using System.Threading; -using static LibHac.Fs.ApplicationSaveDataManagement; - namespace Ryujinx.Ui.Widgets { public partial class GameTableContextMenu : Menu @@ -81,7 +78,7 @@ namespace Ryujinx.Ui.Widgets PopupAtPointer(null); } - private bool TryFindSaveData(string titleName, ulong titleId, BlitStruct controlHolder, SaveDataFilter filter, out ulong saveDataId) + private bool TryFindSaveData(string titleName, ulong titleId, BlitStruct controlHolder, in SaveDataFilter filter, out ulong saveDataId) { saveDataId = default; @@ -121,7 +118,7 @@ namespace Ryujinx.Ui.Widgets Uid user = new Uid((ulong)_accountManager.LastOpenedUser.UserId.High, (ulong)_accountManager.LastOpenedUser.UserId.Low); - result = EnsureApplicationSaveData(_horizonClient.Fs, out _, new LibHac.Ncm.ApplicationId(titleId), ref control, ref user); + result = _horizonClient.Fs.EnsureApplicationSaveData(out _, new LibHac.Ncm.ApplicationId(titleId), in control, in user); if (result.IsFailure()) { @@ -146,11 +143,9 @@ namespace Ryujinx.Ui.Widgets return false; } - private void OpenSaveDir(SaveDataFilter saveDataFilter) + private void OpenSaveDir(in SaveDataFilter saveDataFilter) { - saveDataFilter.SetProgramId(new ProgramId(_titleId)); - - if (!TryFindSaveData(_titleName, _titleId, _controlData, saveDataFilter, out ulong saveDataId)) + if (!TryFindSaveData(_titleName, _titleId, _controlData, in saveDataFilter, out ulong saveDataId)) { return; } @@ -439,26 +434,24 @@ namespace Ryujinx.Ui.Widgets // private void OpenSaveUserDir_Clicked(object sender, EventArgs args) { - SaveDataFilter saveDataFilter = new SaveDataFilter(); - saveDataFilter.SetUserId(new LibHac.Fs.UserId((ulong)_accountManager.LastOpenedUser.UserId.High, (ulong)_accountManager.LastOpenedUser.UserId.Low)); + var userId = new LibHac.Fs.UserId((ulong)_accountManager.LastOpenedUser.UserId.High, (ulong)_accountManager.LastOpenedUser.UserId.Low); + var saveDataFilter = SaveDataFilter.Make(_titleId, saveType: default, userId, saveDataId: default, index: default); - OpenSaveDir(saveDataFilter); + OpenSaveDir(in saveDataFilter); } private void OpenSaveDeviceDir_Clicked(object sender, EventArgs args) { - SaveDataFilter saveDataFilter = new SaveDataFilter(); - saveDataFilter.SetSaveDataType(SaveDataType.Device); + var saveDataFilter = SaveDataFilter.Make(_titleId, SaveDataType.Device, userId: default, saveDataId: default, index: default); - OpenSaveDir(saveDataFilter); + OpenSaveDir(in saveDataFilter); } private void OpenSaveBcatDir_Clicked(object sender, EventArgs args) { - SaveDataFilter saveDataFilter = new SaveDataFilter(); - saveDataFilter.SetSaveDataType(SaveDataType.Bcat); + var saveDataFilter = SaveDataFilter.Make(_titleId, SaveDataType.Bcat, userId: default, saveDataId: default, index: default); - OpenSaveDir(saveDataFilter); + OpenSaveDir(in saveDataFilter); } private void ManageTitleUpdates_Clicked(object sender, EventArgs args) diff --git a/Ryujinx/Ui/Windows/TitleUpdateWindow.cs b/Ryujinx/Ui/Windows/TitleUpdateWindow.cs index f6dbff3073..94bf9e7093 100644 --- a/Ryujinx/Ui/Windows/TitleUpdateWindow.cs +++ b/Ryujinx/Ui/Windows/TitleUpdateWindow.cs @@ -105,7 +105,7 @@ namespace Ryujinx.Ui.Windows controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(ref nacpFile.Ref(), "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure(); nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure(); - RadioButton radioButton = new RadioButton($"Version {controlData.DisplayVersion.ToString()} - {path}"); + RadioButton radioButton = new RadioButton($"Version {controlData.DisplayVersionString.ToString()} - {path}"); radioButton.JoinGroup(_noUpdateRadioButton); _availableUpdatesBox.Add(radioButton);