mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	qt: Add 'Install to NAND' option to menu
Prompts for title type on NCA files.
This commit is contained in:
		
							parent
							
								
									b67e751ccb
								
							
						
					
					
						commit
						bfb945c243
					
				| @ -5,6 +5,7 @@ | |||||||
| #include <memory> | #include <memory> | ||||||
| #include <utility> | #include <utility> | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
|  | #include "common/string_util.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| #include "core/core_timing.h" | #include "core/core_timing.h" | ||||||
| #include "core/gdbstub/gdbstub.h" | #include "core/gdbstub/gdbstub.h" | ||||||
|  | |||||||
| @ -427,7 +427,7 @@ bool RegisteredCache::RawInstallYuzuMeta(const CNMT& cnmt) { | |||||||
|     } |     } | ||||||
|     Refresh(); |     Refresh(); | ||||||
|     return std::find_if(yuzu_meta.begin(), yuzu_meta.end(), |     return std::find_if(yuzu_meta.begin(), yuzu_meta.end(), | ||||||
|                         [&cnmt](const std::pair<const u64, CNMT>& kv) { |                         [&cnmt](const std::pair<u64, CNMT>& kv) { | ||||||
|                             return kv.second.GetType() == cnmt.GetType() && |                             return kv.second.GetType() == cnmt.GetType() && | ||||||
|                                    kv.second.GetTitleID() == cnmt.GetTitleID(); |                                    kv.second.GetTitleID() == cnmt.GetTitleID(); | ||||||
|                         }) != yuzu_meta.end(); |                         }) != yuzu_meta.end(); | ||||||
|  | |||||||
| @ -24,6 +24,7 @@ | |||||||
| #include "common/string_util.h" | #include "common/string_util.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| #include "core/crypto/key_manager.h" | #include "core/crypto/key_manager.h" | ||||||
|  | #include "core/file_sys/card_image.h" | ||||||
| #include "core/file_sys/vfs_real.h" | #include "core/file_sys/vfs_real.h" | ||||||
| #include "core/gdbstub/gdbstub.h" | #include "core/gdbstub/gdbstub.h" | ||||||
| #include "core/loader/loader.h" | #include "core/loader/loader.h" | ||||||
| @ -114,6 +115,9 @@ GMainWindow::GMainWindow() | |||||||
|                        .arg(Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc)); |                        .arg(Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc)); | ||||||
|     show(); |     show(); | ||||||
| 
 | 
 | ||||||
|  |     // Necessary to load titles from nand in gamelist.
 | ||||||
|  |     Service::FileSystem::RegisterBIS(std::make_unique<FileSys::BISFactory>(vfs->OpenDirectory( | ||||||
|  |         FileUtil::GetUserPath(FileUtil::UserPath::NANDDir), FileSys::Mode::ReadWrite))); | ||||||
|     game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan); |     game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan); | ||||||
| 
 | 
 | ||||||
|     // Show one-time "callout" messages to the user
 |     // Show one-time "callout" messages to the user
 | ||||||
| @ -309,6 +313,8 @@ void GMainWindow::ConnectMenuEvents() { | |||||||
|     // File
 |     // File
 | ||||||
|     connect(ui.action_Load_File, &QAction::triggered, this, &GMainWindow::OnMenuLoadFile); |     connect(ui.action_Load_File, &QAction::triggered, this, &GMainWindow::OnMenuLoadFile); | ||||||
|     connect(ui.action_Load_Folder, &QAction::triggered, this, &GMainWindow::OnMenuLoadFolder); |     connect(ui.action_Load_Folder, &QAction::triggered, this, &GMainWindow::OnMenuLoadFolder); | ||||||
|  |     connect(ui.action_Install_File_NAND, &QAction::triggered, this, | ||||||
|  |             &GMainWindow::OnMenuInstallToNAND); | ||||||
|     connect(ui.action_Select_Game_List_Root, &QAction::triggered, this, |     connect(ui.action_Select_Game_List_Root, &QAction::triggered, this, | ||||||
|             &GMainWindow::OnMenuSelectGameListRoot); |             &GMainWindow::OnMenuSelectGameListRoot); | ||||||
|     connect(ui.action_Exit, &QAction::triggered, this, &QMainWindow::close); |     connect(ui.action_Exit, &QAction::triggered, this, &QMainWindow::close); | ||||||
| @ -612,6 +618,89 @@ void GMainWindow::OnMenuLoadFolder() { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void GMainWindow::OnMenuInstallToNAND() { | ||||||
|  |     const static QString file_filter = | ||||||
|  |         tr("Installable Switch File (*.nca *.xci);;Nintendo Content Archive (*.nca);;NX Cartridge " | ||||||
|  |            "Image (*.xci)"); | ||||||
|  |     QString filename = QFileDialog::getOpenFileName(this, tr("Install File"), | ||||||
|  |                                                     UISettings::values.roms_path, file_filter); | ||||||
|  |     if (!filename.isEmpty()) { | ||||||
|  |         if (filename.endsWith("xci", Qt::CaseInsensitive)) { | ||||||
|  |             const auto xci = std::make_shared<FileSys::XCI>( | ||||||
|  |                 vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read)); | ||||||
|  |             if (xci->GetStatus() != Loader::ResultStatus::Success) { | ||||||
|  |                 QMessageBox::critical( | ||||||
|  |                     this, tr("Failed to Install XCI"), | ||||||
|  |                     tr("The XCI file you provided is invalid. Please double-check your encryption " | ||||||
|  |                        "keys and the file and try again.")); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             if (!Service::FileSystem::GetUserNANDContents()->InstallEntry(xci)) { | ||||||
|  |                 QMessageBox::critical( | ||||||
|  |                     this, tr("Failed to Install XCI"), | ||||||
|  |                     tr("There was an error while attempting to install the provided XCI file. It " | ||||||
|  |                        "could have an incorrect format or be missing a metadata entry. Please " | ||||||
|  |                        "double-check your file and try again.")); | ||||||
|  |             } else { | ||||||
|  |                 QMessageBox::information(this, tr("Successfully Installed XCI"), | ||||||
|  |                                          tr("The file was successfully installed.")); | ||||||
|  |                 game_list->PopulateAsync(UISettings::values.gamedir, | ||||||
|  |                                          UISettings::values.gamedir_deepscan); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             const auto nca = std::make_shared<FileSys::NCA>( | ||||||
|  |                 vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read)); | ||||||
|  |             if (nca->GetStatus() != Loader::ResultStatus::Success) { | ||||||
|  |                 QMessageBox::critical( | ||||||
|  |                     this, tr("Failed to Install NCA"), | ||||||
|  |                     tr("The NCA file you provided is invalid. Please double-check your encryption " | ||||||
|  |                        "keys and the file and try again.")); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             const static QStringList tt_options{"System Application", | ||||||
|  |                                                 "System Archive", | ||||||
|  |                                                 "System Application Update", | ||||||
|  |                                                 "Firmware Package (Type A)", | ||||||
|  |                                                 "Firmware Package (Type B)", | ||||||
|  |                                                 "Game", | ||||||
|  |                                                 "Game Update", | ||||||
|  |                                                 "Game DLC", | ||||||
|  |                                                 "Delta Title"}; | ||||||
|  |             bool ok; | ||||||
|  |             const auto item = QInputDialog::getItem( | ||||||
|  |                 this, tr("Select NCA Install Type..."), | ||||||
|  |                 tr("Please select the type of title you would like to install this NCA as:\n(In " | ||||||
|  |                    "most instances, the default 'Game' is fine.)"), | ||||||
|  |                 tt_options, 5, false, &ok); | ||||||
|  | 
 | ||||||
|  |             auto index = tt_options.indexOf(item); | ||||||
|  |             if (!ok || index == -1) { | ||||||
|  |                 QMessageBox::critical(this, tr("Failed to Install NCA"), | ||||||
|  |                                       tr("The title type you selected for the NCA is invalid.")); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (index >= 5) | ||||||
|  |                 index += 0x80; | ||||||
|  | 
 | ||||||
|  |             if (!Service::FileSystem::GetUserNANDContents()->InstallEntry( | ||||||
|  |                     nca, static_cast<FileSys::TitleType>(index))) { | ||||||
|  |                 QMessageBox::critical(this, tr("Failed to Install NCA"), | ||||||
|  |                                       tr("There was an error while attempting to install the " | ||||||
|  |                                          "provided NCA file. An error might have occured creating " | ||||||
|  |                                          "the metadata file or parsing the NCA. Please " | ||||||
|  |                                          "double-check your file and try again.")); | ||||||
|  |             } else { | ||||||
|  |                 QMessageBox::information(this, tr("Successfully Installed NCA"), | ||||||
|  |                                          tr("The file was successfully installed.")); | ||||||
|  |                 game_list->PopulateAsync(UISettings::values.gamedir, | ||||||
|  |                                          UISettings::values.gamedir_deepscan); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void GMainWindow::OnMenuSelectGameListRoot() { | void GMainWindow::OnMenuSelectGameListRoot() { | ||||||
|     QString dir_path = QFileDialog::getExistingDirectory(this, tr("Select Directory")); |     QString dir_path = QFileDialog::getExistingDirectory(this, tr("Select Directory")); | ||||||
|     if (!dir_path.isEmpty()) { |     if (!dir_path.isEmpty()) { | ||||||
|  | |||||||
| @ -125,6 +125,7 @@ private slots: | |||||||
|     void OnGameListOpenSaveFolder(u64 program_id); |     void OnGameListOpenSaveFolder(u64 program_id); | ||||||
|     void OnMenuLoadFile(); |     void OnMenuLoadFile(); | ||||||
|     void OnMenuLoadFolder(); |     void OnMenuLoadFolder(); | ||||||
|  |     void OnMenuInstallToNAND(); | ||||||
|     /// Called whenever a user selects the "File->Select Game List Root" menu item
 |     /// Called whenever a user selects the "File->Select Game List Root" menu item
 | ||||||
|     void OnMenuSelectGameListRoot(); |     void OnMenuSelectGameListRoot(); | ||||||
|     void OnMenuRecentFile(); |     void OnMenuRecentFile(); | ||||||
|  | |||||||
| @ -57,6 +57,8 @@ | |||||||
|       <string>Recent Files</string> |       <string>Recent Files</string> | ||||||
|      </property> |      </property> | ||||||
|     </widget> |     </widget> | ||||||
|  |      <addaction name="action_Install_File_NAND" /> | ||||||
|  |      <addaction name="separator"/> | ||||||
|     <addaction name="action_Load_File"/> |     <addaction name="action_Load_File"/> | ||||||
|     <addaction name="action_Load_Folder"/> |     <addaction name="action_Load_Folder"/> | ||||||
|     <addaction name="separator"/> |     <addaction name="separator"/> | ||||||
| @ -102,6 +104,11 @@ | |||||||
|    <addaction name="menu_View"/> |    <addaction name="menu_View"/> | ||||||
|    <addaction name="menu_Help"/> |    <addaction name="menu_Help"/> | ||||||
|   </widget> |   </widget> | ||||||
|  |    <action name="action_Install_File_NAND"> | ||||||
|  |      <property name="text"> | ||||||
|  |        <string>Install File to NAND...</string> | ||||||
|  |      </property> | ||||||
|  |    </action> | ||||||
|   <action name="action_Load_File"> |   <action name="action_Load_File"> | ||||||
|    <property name="text"> |    <property name="text"> | ||||||
|     <string>Load File...</string> |     <string>Load File...</string> | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Zach Hilman
						Zach Hilman