diff --git a/Ryujinx.HLE/FileSystem/Content/ContentManager.cs b/Ryujinx.HLE/FileSystem/Content/ContentManager.cs index 1c061dffbb..98ac3738e9 100644 --- a/Ryujinx.HLE/FileSystem/Content/ContentManager.cs +++ b/Ryujinx.HLE/FileSystem/Content/ContentManager.cs @@ -746,11 +746,20 @@ namespace Ryujinx.HLE.FileSystem.Content { if (updateNcas.TryGetValue(metaEntry.TitleId, out var ncaEntry)) { - var metaNcaEntry = ncaEntry.Find(x => x.Item1 == NcaContentType.Meta); - var contentNcaEntry = ncaEntry.Find(x => x.Item1 != NcaContentType.Meta); + var metaNcaEntry = ncaEntry.Find(x => x.Item1 == NcaContentType.Meta); + string contentPath = ncaEntry.Find(x => x.Item1 != NcaContentType.Meta).Item2; + + + // Nintendo in 9.0.0, removed PPC and only kept the meta nca of it. + // This is a perfect valid case, so we should just ignore the missing content nca and continue. + if (contentPath == null) + { + updateNcas.Remove(metaEntry.TitleId); + continue; + } IStorage metaStorage = OpenPossibleFragmentedFile(filesystem, metaNcaEntry.Item2, OpenMode.Read).AsStorage(); - IStorage contentStorage = OpenPossibleFragmentedFile(filesystem, contentNcaEntry.Item2, OpenMode.Read).AsStorage(); + IStorage contentStorage = OpenPossibleFragmentedFile(filesystem, contentPath, OpenMode.Read).AsStorage(); Nca metaNca = new Nca(_device.System.KeySet, metaStorage); diff --git a/Ryujinx/Ui/MainWindow.cs b/Ryujinx/Ui/MainWindow.cs index 8eb41461f8..9a29579f5b 100644 --- a/Ryujinx/Ui/MainWindow.cs +++ b/Ryujinx/Ui/MainWindow.cs @@ -45,7 +45,8 @@ namespace Ryujinx.Ui [GUI] CheckMenuItem _fullScreen; [GUI] MenuItem _stopEmulation; [GUI] CheckMenuItem _favToggle; - [GUI] MenuItem _firmwareInstall; + [GUI] MenuItem _firmwareInstallFile; + [GUI] MenuItem _firmwareInstallDirectory; [GUI] CheckMenuItem _iconToggle; [GUI] CheckMenuItem _appToggle; [GUI] CheckMenuItem _developerToggle; @@ -298,7 +299,9 @@ namespace Ryujinx.Ui _gameLoaded = true; _stopEmulation.Sensitive = true; - _firmwareInstall.Sensitive = false; + + _firmwareInstallFile.Sensitive = false; + _firmwareInstallDirectory.Sensitive = false; DiscordIntegrationModule.SwitchToPlayingState(_device.System.TitleId, _device.System.TitleName); @@ -558,18 +561,40 @@ namespace Ryujinx.Ui _gameLoaded = false; } - - private void Installer_Pressed(object o, EventArgs args) + + private void Installer_File_Pressed(object o, EventArgs args) { - FileChooserDialog fileChooser = new FileChooserDialog("Choose the folder to open", - this, + FileChooserDialog fileChooser = new FileChooserDialog("Choose the firmware file to open", + this, FileChooserAction.Open, "Cancel", - ResponseType.Cancel, + ResponseType.Cancel, "Open", ResponseType.Accept); - - if(fileChooser.Run() == (int)ResponseType.Accept) + + fileChooser.Filter = new FileFilter(); + fileChooser.Filter.AddPattern("*.zip"); + fileChooser.Filter.AddPattern("*.xci"); + + HandleInstallerDialog(fileChooser); + } + + private void Installer_Directory_Pressed(object o, EventArgs args) + { + FileChooserDialog directoryChooser = new FileChooserDialog("Choose the firmware directory to open", + this, + FileChooserAction.SelectFolder, + "Cancel", + ResponseType.Cancel, + "Open", + ResponseType.Accept); + + HandleInstallerDialog(directoryChooser); + } + + private void HandleInstallerDialog(FileChooserDialog fileChooser) + { + if (fileChooser.Run() == (int)ResponseType.Accept) { MessageDialog dialog = null; @@ -581,7 +606,7 @@ namespace Ryujinx.Ui var firmwareVersion = _device.System.VerifyFirmwarePackage(filename); - if(firmwareVersion== null) + if(firmwareVersion == null) { dialog = new MessageDialog(this, DialogFlags.Modal, diff --git a/Ryujinx/Ui/MainWindow.glade b/Ryujinx/Ui/MainWindow.glade index 633154ec1d..ef29582835 100644 --- a/Ryujinx/Ui/MainWindow.glade +++ b/Ryujinx/Ui/MainWindow.glade @@ -268,12 +268,35 @@ True False - + True False Install Firmware True - + + + True + False + + + True + False + Install a firmware from XCI or ZIP + True + + + + + + True + False + Install a firmware from a directory + True + + + + +