From f838f00c0469cd07e8867ea6ac4f067dc2c6f2de Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Sat, 7 Dec 2024 04:30:04 -0600 Subject: [PATCH] HLE: extract custom NACP data functionality into a static helper for generic reuse elsewhere, and clarify magic numbers. --- src/Ryujinx.HLE/StructHelpers.cs | 37 +++++++++++++++++++ .../UI/Views/Main/MainMenuBarView.axaml.cs | 31 ++++++---------- 2 files changed, 48 insertions(+), 20 deletions(-) create mode 100644 src/Ryujinx.HLE/StructHelpers.cs diff --git a/src/Ryujinx.HLE/StructHelpers.cs b/src/Ryujinx.HLE/StructHelpers.cs new file mode 100644 index 000000000..6e6af8cea --- /dev/null +++ b/src/Ryujinx.HLE/StructHelpers.cs @@ -0,0 +1,37 @@ +using LibHac.Common; +using LibHac.Ns; +using System; +using System.Text; + +namespace Ryujinx.HLE +{ + public static class StructHelpers + { + public static BlitStruct CreateCustomNacpData(string name, string version) + { + // https://switchbrew.org/wiki/NACP + const int OffsetOfDisplayVersion = 0x3060; + + // https://switchbrew.org/wiki/NACP#ApplicationTitle + const int TotalApplicationTitles = 0x10; + const int SizeOfApplicationTitle = 0x300; + const int OffsetOfApplicationPublisherStrings = 0x200; + + + var nacpData = new BlitStruct(1); + + // name and publisher buffer + // repeat once for each locale (the ApplicationControlProperty has 16 locales) + for (int i = 0; i < TotalApplicationTitles; i++) + { + Encoding.ASCII.GetBytes(name).AsSpan().CopyTo(nacpData.ByteSpan[(i * SizeOfApplicationTitle)..]); + "Ryujinx"u8.CopyTo(nacpData.ByteSpan[(i * SizeOfApplicationTitle + OffsetOfApplicationPublisherStrings)..]); + } + + // version buffer + Encoding.ASCII.GetBytes(version).AsSpan().CopyTo(nacpData.ByteSpan[OffsetOfDisplayVersion..]); + + return nacpData; + } + } +} diff --git a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs index 94f5cf9d3..ffe9b066c 100644 --- a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs +++ b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs @@ -13,6 +13,7 @@ using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.Windows; using Ryujinx.Common; using Ryujinx.Common.Utilities; +using Ryujinx.HLE; using Ryujinx.UI.App.Common; using Ryujinx.UI.Common; using Ryujinx.UI.Common.Configuration; @@ -126,32 +127,22 @@ namespace Ryujinx.Ava.UI.Views.Main public async void OpenMiiApplet(object sender, RoutedEventArgs e) { - const string name = "miiEdit"; - const ulong programId = 0x0100000000001009; - string contentPath = ViewModel.ContentManager.GetInstalledContentPath(programId, StorageId.BuiltInSystem, NcaContentType.Program); + const string AppletName = "miiEdit"; + const ulong AppletProgramId = 0x0100000000001009; + const string AppletVersion = "1.0.0"; + + string contentPath = ViewModel.ContentManager.GetInstalledContentPath(AppletProgramId, StorageId.BuiltInSystem, NcaContentType.Program); if (!string.IsNullOrEmpty(contentPath)) { ApplicationData applicationData = new() { - Name = name, - Id = programId, - Path = contentPath, + Name = AppletName, + Id = AppletProgramId, + Path = contentPath }; - - string version = "1.0.0"; - var nacpData = new BlitStruct(1); - - //version buffer - Encoding.ASCII.GetBytes(version).AsSpan().CopyTo(nacpData.ByteSpan.Slice(0x3060)); - - //name and distributor buffer - //repeat once for each locale (the ApplicationControlProperty has 16 locales) - for (int i = 0; i < 0x10; i++) - { - Encoding.ASCII.GetBytes(name).AsSpan().CopyTo(nacpData.ByteSpan.Slice(i * 0x300)); - "Ryujinx"u8.ToArray().AsSpan().CopyTo(nacpData.ByteSpan.Slice(i * 0x300 + 0x200)); - } + + var nacpData = StructHelpers.CreateCustomNacpData(AppletName, AppletVersion); await ViewModel.LoadApplication(applicationData, ViewModel.IsFullScreen || ViewModel.StartGamesInFullscreen, nacpData); }