From 2471bb8ede39355fb0285b6fad47fd9e028d9023 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Mon, 20 Jan 2025 14:30:28 -0600 Subject: [PATCH] UI: Move DLC RomFS dumping under normal RomFS dumping. Also removed it from DLC manager. --- .../Models/DownloadableContentModel.cs | 2 +- src/Ryujinx/Assets/Locales/en_US.json | 5 +- src/Ryujinx/Assets/Locales/fr_FR.json | 5 +- src/Ryujinx/Common/ApplicationHelper.cs | 13 ++-- .../UI/Controls/ApplicationContextMenu.axaml | 4 ++ .../Controls/ApplicationContextMenu.axaml.cs | 17 +++++ .../UI/Controls/ApplicationListView.axaml | 2 +- src/Ryujinx/UI/Controls/DlcSelectView.axaml | 67 +++++++++++++++++++ .../UI/Controls/DlcSelectView.axaml.cs | 50 ++++++++++++++ .../UI/Controls/NavigationDialogHost.axaml.cs | 2 +- .../UI/ViewModels/DlcSelectViewModel.cs | 45 +++++++++++++ .../DownloadableContentManagerWindow.axaml | 16 +---- .../DownloadableContentManagerWindow.axaml.cs | 13 ---- 13 files changed, 202 insertions(+), 39 deletions(-) create mode 100644 src/Ryujinx/UI/Controls/DlcSelectView.axaml create mode 100644 src/Ryujinx/UI/Controls/DlcSelectView.axaml.cs create mode 100644 src/Ryujinx/UI/ViewModels/DlcSelectViewModel.cs diff --git a/src/Ryujinx.UI.Common/Models/DownloadableContentModel.cs b/src/Ryujinx.UI.Common/Models/DownloadableContentModel.cs index 95c64f078..d0b711857 100644 --- a/src/Ryujinx.UI.Common/Models/DownloadableContentModel.cs +++ b/src/Ryujinx.UI.Common/Models/DownloadableContentModel.cs @@ -6,7 +6,7 @@ namespace Ryujinx.UI.Common.Models public bool IsBundled { get; } = System.IO.Path.GetExtension(ContainerPath)?.ToLower() == ".xci"; public string FileName => System.IO.Path.GetFileName(ContainerPath); - public string TitleIdStr => TitleId.ToString("x16"); + public string TitleIdStr => TitleId.ToString("x16").ToUpper(); public ulong TitleIdBase => TitleId & ~0x1FFFUL; } } diff --git a/src/Ryujinx/Assets/Locales/en_US.json b/src/Ryujinx/Assets/Locales/en_US.json index e0b042bb1..188ce1a93 100644 --- a/src/Ryujinx/Assets/Locales/en_US.json +++ b/src/Ryujinx/Assets/Locales/en_US.json @@ -913,5 +913,8 @@ "FpsTurboStatusBarText": "{0} FPS ({1}ms), Turbo ({2}%)", "SettingsTabHotkeysTurboMode": "Turbo mode:", "SettingsTabHotkeysTurboModeToolTip": "The Turbo mode hotkey.\\nConfigure the behavior of Turbo mode in Ryujinx CPU settings.\\n\\nLeave Unbound if unsure.", - "SettingsTabHotkeysOnlyWhilePressed": "Only while pressed" + "SettingsTabHotkeysOnlyWhilePressed": "Only while pressed", + "GameListContextMenuExtractDataAocRomFS": "DLC RomFS", + "GameListContextMenuExtractDataAocRomFSToolTip": "Extract the RomFS from a selected DLC file", + "ExtractAocListHeader": "Select a DLC to Extract" } diff --git a/src/Ryujinx/Assets/Locales/fr_FR.json b/src/Ryujinx/Assets/Locales/fr_FR.json index 64fcbd93e..335035e5e 100644 --- a/src/Ryujinx/Assets/Locales/fr_FR.json +++ b/src/Ryujinx/Assets/Locales/fr_FR.json @@ -821,5 +821,8 @@ "FpsStatusBarText": "{0} FPS ({1}ms)", "SettingsTabHotkeysTurboMode": "Mode Turbo :", "SettingsTabHotkeysTurboModeToolTip": "Le raccourci clavier Mode Turbo.\\nConfigurez le comportement du Mode Turbo dans les paramètres de CPU de Ryujinx.\\n\\nLaisser Non Attribuée si incertain.", - "SettingsTabHotkeysOnlyWhilePressed": "Seulement quand le raccourci est maintenu" + "SettingsTabHotkeysOnlyWhilePressed": "Seulement quand le raccourci est maintenu", + "GameListContextMenuExtractDataAocRomFS": "RomFS de DLC", + "GameListContextMenuExtractDataAocRomFSToolTip": "Extraire les RomFS d'un fichier DLC choisi", + "ExtractAocListHeader": "Choisissez un DLC à extraire" } diff --git a/src/Ryujinx/Common/ApplicationHelper.cs b/src/Ryujinx/Common/ApplicationHelper.cs index 80309515b..75eb03c1e 100644 --- a/src/Ryujinx/Common/ApplicationHelper.cs +++ b/src/Ryujinx/Common/ApplicationHelper.cs @@ -297,13 +297,13 @@ namespace Ryujinx.Ava.Common extractorThread.Start(); } - public static void ExtractAoc(string destination, NcaSectionType ncaSectionType, string updateFilePath, string updateName) + public static void ExtractAoc(string destination, string updateFilePath, string updateName) { var cancellationToken = new CancellationTokenSource(); UpdateWaitWindow waitingDialog = new( $"Ryujinx {Program.Version} - {LocaleManager.Instance[LocaleKeys.DialogNcaExtractionTitle]}", - LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogNcaExtractionMessage, ncaSectionType, Path.GetFileName(updateFilePath)), + LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogNcaExtractionMessage, NcaSectionType.Data, Path.GetFileName(updateFilePath)), cancellationToken); Thread extractorThread = new(() => @@ -353,7 +353,7 @@ namespace Ryujinx.Ava.Common ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None; - int index = Nca.GetSectionIndexFromType(ncaSectionType, publicDataNca.Header.ContentType); + int index = Nca.GetSectionIndexFromType(NcaSectionType.Data, publicDataNca.Header.ContentType); try { @@ -411,14 +411,13 @@ namespace Ryujinx.Ava.Common } }) { - Name = "GUI.NcaSectionExtractorThread", + Name = "GUI.AocExtractorThread", IsBackground = true, }; extractorThread.Start(); } - public static async Task ExtractAoc(IStorageProvider storageProvider, NcaSectionType ncaSectionType, - string updateFilePath, string updateName) + public static async Task ExtractAoc(IStorageProvider storageProvider, string updateFilePath, string updateName) { var result = await storageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions { @@ -431,7 +430,7 @@ namespace Ryujinx.Ava.Common return; } - ExtractAoc(result[0].Path.LocalPath, ncaSectionType, updateFilePath, updateName); + ExtractAoc(result[0].Path.LocalPath, updateFilePath, updateName); } diff --git a/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml b/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml index 23718ed25..05fef6cc8 100644 --- a/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml +++ b/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml @@ -97,6 +97,10 @@ Click="ExtractApplicationRomFs_Click" Header="{locale:Locale GameListContextMenuExtractDataRomFS}" ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataRomFSToolTip}" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Ryujinx/UI/Controls/DlcSelectView.axaml.cs b/src/Ryujinx/UI/Controls/DlcSelectView.axaml.cs new file mode 100644 index 000000000..6b90f59d9 --- /dev/null +++ b/src/Ryujinx/UI/Controls/DlcSelectView.axaml.cs @@ -0,0 +1,50 @@ +using Avalonia.Controls; +using Avalonia.Styling; +using FluentAvalonia.UI.Controls; +using Ryujinx.Ava.Common.Locale; +using Ryujinx.Ava.UI.Helpers; +using Ryujinx.Ava.UI.ViewModels; +using Ryujinx.UI.App.Common; +using Ryujinx.UI.Common.Models; +using System.Threading.Tasks; + +namespace Ryujinx.Ava.UI.Controls +{ + public partial class DlcSelectView : UserControl + { + public DlcSelectView() + { + InitializeComponent(); + } + + #nullable enable + public static async Task Show(ulong selectedTitleId, ApplicationLibrary appLibrary) + #nullable disable + { + DlcSelectViewModel viewModel = new(selectedTitleId, appLibrary); + + ContentDialog contentDialog = new() + { + PrimaryButtonText = LocaleManager.Instance[LocaleKeys.Continue], + SecondaryButtonText = string.Empty, + CloseButtonText = string.Empty, + Content = new DlcSelectView { DataContext = viewModel } + }; + + Style closeButton = new(x => x.Name("CloseButton")); + closeButton.Setters.Add(new Setter(WidthProperty, 80d)); + + Style closeButtonParent = new(x => x.Name("CommandSpace")); + closeButtonParent.Setters.Add(new Setter(HorizontalAlignmentProperty, + Avalonia.Layout.HorizontalAlignment.Right)); + + contentDialog.Styles.Add(closeButton); + contentDialog.Styles.Add(closeButtonParent); + + await ContentDialogHelper.ShowAsync(contentDialog); + + return viewModel.SelectedDlc; + } + } +} + diff --git a/src/Ryujinx/UI/Controls/NavigationDialogHost.axaml.cs b/src/Ryujinx/UI/Controls/NavigationDialogHost.axaml.cs index 1ca1615d5..4d20d9a54 100644 --- a/src/Ryujinx/UI/Controls/NavigationDialogHost.axaml.cs +++ b/src/Ryujinx/UI/Controls/NavigationDialogHost.axaml.cs @@ -73,7 +73,7 @@ namespace Ryujinx.Ava.UI.Controls public static async Task Show(AccountManager ownerAccountManager, ContentManager ownerContentManager, VirtualFileSystem ownerVirtualFileSystem, HorizonClient ownerHorizonClient) { - var content = new NavigationDialogHost(ownerAccountManager, ownerContentManager, ownerVirtualFileSystem, ownerHorizonClient); + NavigationDialogHost content = new(ownerAccountManager, ownerContentManager, ownerVirtualFileSystem, ownerHorizonClient); ContentDialog contentDialog = new() { Title = LocaleManager.Instance[LocaleKeys.UserProfileWindowTitle], diff --git a/src/Ryujinx/UI/ViewModels/DlcSelectViewModel.cs b/src/Ryujinx/UI/ViewModels/DlcSelectViewModel.cs new file mode 100644 index 000000000..50e00ff06 --- /dev/null +++ b/src/Ryujinx/UI/ViewModels/DlcSelectViewModel.cs @@ -0,0 +1,45 @@ +using Ryujinx.UI.App.Common; +using Ryujinx.UI.Common.Models; +using System.Linq; + +namespace Ryujinx.Ava.UI.ViewModels +{ + public partial class DlcSelectViewModel : BaseModel + { + private DownloadableContentModel[] _dlcs; + private DownloadableContentModel _selectedDlc; + + public DownloadableContentModel[] Dlcs + { + get => _dlcs; + set + { + _dlcs = value; + + OnPropertyChanged(); + } + } + #nullable enable + public DownloadableContentModel? SelectedDlc + { + get => _selectedDlc; + set + { + _selectedDlc = value; + + OnPropertyChanged(); + } + } + #nullable disable + + public DlcSelectViewModel(ulong titleId, ApplicationLibrary appLibrary) + { + _dlcs = appLibrary.DownloadableContents.Items + .Where(x => x.Dlc.TitleIdBase == titleId) + .Select(x => x.Dlc) + .OrderBy(it => it.IsBundled ? 0 : 1) + .ThenBy(it => it.TitleId) + .ToArray(); + } + } +} diff --git a/src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml b/src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml index 2d39161fb..54e4dd10a 100644 --- a/src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml +++ b/src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml @@ -14,9 +14,6 @@ mc:Ignorable="d" x:DataType="viewModels:DownloadableContentManagerViewModel" Focusable="True"> - - - - + @@ -113,22 +110,13 @@ Margin="10 0" HorizontalAlignment="Left" VerticalAlignment="Center" - Text="{Binding TitleId}" /> + Text="{Binding TitleIdStr}" /> -