diff options
| author | 2018-08-09 21:33:13 -0400 | |
|---|---|---|
| committer | 2018-08-11 22:50:48 -0400 | |
| commit | bfb945c2431ca1ccf1c5c43d4e3c7eaedf0bed31 (patch) | |
| tree | 6ec1f2d655eae67b60341f7ac7b42c9feb134bd5 /src | |
| parent | game_list: Modify game list to scan installed titles (diff) | |
| download | yuzu-bfb945c2431ca1ccf1c5c43d4e3c7eaedf0bed31.tar.gz yuzu-bfb945c2431ca1ccf1c5c43d4e3c7eaedf0bed31.tar.xz yuzu-bfb945c2431ca1ccf1c5c43d4e3c7eaedf0bed31.zip | |
qt: Add 'Install to NAND' option to menu
Prompts for title type on NCA files.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/core.cpp | 1 | ||||
| -rw-r--r-- | src/core/file_sys/registered_cache.cpp | 2 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 89 | ||||
| -rw-r--r-- | src/yuzu/main.h | 1 | ||||
| -rw-r--r-- | src/yuzu/main.ui | 7 |
5 files changed, 99 insertions, 1 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index 05af68f22..28038ff6f 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include <memory> | 5 | #include <memory> |
| 6 | #include <utility> | 6 | #include <utility> |
| 7 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 8 | #include "common/string_util.h" | ||
| 8 | #include "core/core.h" | 9 | #include "core/core.h" |
| 9 | #include "core/core_timing.h" | 10 | #include "core/core_timing.h" |
| 10 | #include "core/gdbstub/gdbstub.h" | 11 | #include "core/gdbstub/gdbstub.h" |
diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp index 5440cdefb..766fef254 100644 --- a/src/core/file_sys/registered_cache.cpp +++ b/src/core/file_sys/registered_cache.cpp | |||
| @@ -427,7 +427,7 @@ bool RegisteredCache::RawInstallYuzuMeta(const CNMT& cnmt) { | |||
| 427 | } | 427 | } |
| 428 | Refresh(); | 428 | Refresh(); |
| 429 | return std::find_if(yuzu_meta.begin(), yuzu_meta.end(), | 429 | return std::find_if(yuzu_meta.begin(), yuzu_meta.end(), |
| 430 | [&cnmt](const std::pair<const u64, CNMT>& kv) { | 430 | [&cnmt](const std::pair<u64, CNMT>& kv) { |
| 431 | return kv.second.GetType() == cnmt.GetType() && | 431 | return kv.second.GetType() == cnmt.GetType() && |
| 432 | kv.second.GetTitleID() == cnmt.GetTitleID(); | 432 | kv.second.GetTitleID() == cnmt.GetTitleID(); |
| 433 | }) != yuzu_meta.end(); | 433 | }) != yuzu_meta.end(); |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 94fb8ae6a..c48191486 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include "common/string_util.h" | 24 | #include "common/string_util.h" |
| 25 | #include "core/core.h" | 25 | #include "core/core.h" |
| 26 | #include "core/crypto/key_manager.h" | 26 | #include "core/crypto/key_manager.h" |
| 27 | #include "core/file_sys/card_image.h" | ||
| 27 | #include "core/file_sys/vfs_real.h" | 28 | #include "core/file_sys/vfs_real.h" |
| 28 | #include "core/gdbstub/gdbstub.h" | 29 | #include "core/gdbstub/gdbstub.h" |
| 29 | #include "core/loader/loader.h" | 30 | #include "core/loader/loader.h" |
| @@ -114,6 +115,9 @@ GMainWindow::GMainWindow() | |||
| 114 | .arg(Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc)); | 115 | .arg(Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc)); |
| 115 | show(); | 116 | show(); |
| 116 | 117 | ||
| 118 | // Necessary to load titles from nand in gamelist. | ||
| 119 | Service::FileSystem::RegisterBIS(std::make_unique<FileSys::BISFactory>(vfs->OpenDirectory( | ||
| 120 | FileUtil::GetUserPath(FileUtil::UserPath::NANDDir), FileSys::Mode::ReadWrite))); | ||
| 117 | game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan); | 121 | game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan); |
| 118 | 122 | ||
| 119 | // Show one-time "callout" messages to the user | 123 | // Show one-time "callout" messages to the user |
| @@ -309,6 +313,8 @@ void GMainWindow::ConnectMenuEvents() { | |||
| 309 | // File | 313 | // File |
| 310 | connect(ui.action_Load_File, &QAction::triggered, this, &GMainWindow::OnMenuLoadFile); | 314 | connect(ui.action_Load_File, &QAction::triggered, this, &GMainWindow::OnMenuLoadFile); |
| 311 | connect(ui.action_Load_Folder, &QAction::triggered, this, &GMainWindow::OnMenuLoadFolder); | 315 | connect(ui.action_Load_Folder, &QAction::triggered, this, &GMainWindow::OnMenuLoadFolder); |
| 316 | connect(ui.action_Install_File_NAND, &QAction::triggered, this, | ||
| 317 | &GMainWindow::OnMenuInstallToNAND); | ||
| 312 | connect(ui.action_Select_Game_List_Root, &QAction::triggered, this, | 318 | connect(ui.action_Select_Game_List_Root, &QAction::triggered, this, |
| 313 | &GMainWindow::OnMenuSelectGameListRoot); | 319 | &GMainWindow::OnMenuSelectGameListRoot); |
| 314 | connect(ui.action_Exit, &QAction::triggered, this, &QMainWindow::close); | 320 | connect(ui.action_Exit, &QAction::triggered, this, &QMainWindow::close); |
| @@ -612,6 +618,89 @@ void GMainWindow::OnMenuLoadFolder() { | |||
| 612 | } | 618 | } |
| 613 | } | 619 | } |
| 614 | 620 | ||
| 621 | void GMainWindow::OnMenuInstallToNAND() { | ||
| 622 | const static QString file_filter = | ||
| 623 | tr("Installable Switch File (*.nca *.xci);;Nintendo Content Archive (*.nca);;NX Cartridge " | ||
| 624 | "Image (*.xci)"); | ||
| 625 | QString filename = QFileDialog::getOpenFileName(this, tr("Install File"), | ||
| 626 | UISettings::values.roms_path, file_filter); | ||
| 627 | if (!filename.isEmpty()) { | ||
| 628 | if (filename.endsWith("xci", Qt::CaseInsensitive)) { | ||
| 629 | const auto xci = std::make_shared<FileSys::XCI>( | ||
| 630 | vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read)); | ||
| 631 | if (xci->GetStatus() != Loader::ResultStatus::Success) { | ||
| 632 | QMessageBox::critical( | ||
| 633 | this, tr("Failed to Install XCI"), | ||
| 634 | tr("The XCI file you provided is invalid. Please double-check your encryption " | ||
| 635 | "keys and the file and try again.")); | ||
| 636 | return; | ||
| 637 | } | ||
| 638 | if (!Service::FileSystem::GetUserNANDContents()->InstallEntry(xci)) { | ||
| 639 | QMessageBox::critical( | ||
| 640 | this, tr("Failed to Install XCI"), | ||
| 641 | tr("There was an error while attempting to install the provided XCI file. It " | ||
| 642 | "could have an incorrect format or be missing a metadata entry. Please " | ||
| 643 | "double-check your file and try again.")); | ||
| 644 | } else { | ||
| 645 | QMessageBox::information(this, tr("Successfully Installed XCI"), | ||
| 646 | tr("The file was successfully installed.")); | ||
| 647 | game_list->PopulateAsync(UISettings::values.gamedir, | ||
| 648 | UISettings::values.gamedir_deepscan); | ||
| 649 | } | ||
| 650 | } else { | ||
| 651 | const auto nca = std::make_shared<FileSys::NCA>( | ||
| 652 | vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read)); | ||
| 653 | if (nca->GetStatus() != Loader::ResultStatus::Success) { | ||
| 654 | QMessageBox::critical( | ||
| 655 | this, tr("Failed to Install NCA"), | ||
| 656 | tr("The NCA file you provided is invalid. Please double-check your encryption " | ||
| 657 | "keys and the file and try again.")); | ||
| 658 | return; | ||
| 659 | } | ||
| 660 | |||
| 661 | const static QStringList tt_options{"System Application", | ||
| 662 | "System Archive", | ||
| 663 | "System Application Update", | ||
| 664 | "Firmware Package (Type A)", | ||
| 665 | "Firmware Package (Type B)", | ||
| 666 | "Game", | ||
| 667 | "Game Update", | ||
| 668 | "Game DLC", | ||
| 669 | "Delta Title"}; | ||
| 670 | bool ok; | ||
| 671 | const auto item = QInputDialog::getItem( | ||
| 672 | this, tr("Select NCA Install Type..."), | ||
| 673 | tr("Please select the type of title you would like to install this NCA as:\n(In " | ||
| 674 | "most instances, the default 'Game' is fine.)"), | ||
| 675 | tt_options, 5, false, &ok); | ||
| 676 | |||
| 677 | auto index = tt_options.indexOf(item); | ||
| 678 | if (!ok || index == -1) { | ||
| 679 | QMessageBox::critical(this, tr("Failed to Install NCA"), | ||
| 680 | tr("The title type you selected for the NCA is invalid.")); | ||
| 681 | return; | ||
| 682 | } | ||
| 683 | |||
| 684 | if (index >= 5) | ||
| 685 | index += 0x80; | ||
| 686 | |||
| 687 | if (!Service::FileSystem::GetUserNANDContents()->InstallEntry( | ||
| 688 | nca, static_cast<FileSys::TitleType>(index))) { | ||
| 689 | QMessageBox::critical(this, tr("Failed to Install NCA"), | ||
| 690 | tr("There was an error while attempting to install the " | ||
| 691 | "provided NCA file. An error might have occured creating " | ||
| 692 | "the metadata file or parsing the NCA. Please " | ||
| 693 | "double-check your file and try again.")); | ||
| 694 | } else { | ||
| 695 | QMessageBox::information(this, tr("Successfully Installed NCA"), | ||
| 696 | tr("The file was successfully installed.")); | ||
| 697 | game_list->PopulateAsync(UISettings::values.gamedir, | ||
| 698 | UISettings::values.gamedir_deepscan); | ||
| 699 | } | ||
| 700 | } | ||
| 701 | } | ||
| 702 | } | ||
| 703 | |||
| 615 | void GMainWindow::OnMenuSelectGameListRoot() { | 704 | void GMainWindow::OnMenuSelectGameListRoot() { |
| 616 | QString dir_path = QFileDialog::getExistingDirectory(this, tr("Select Directory")); | 705 | QString dir_path = QFileDialog::getExistingDirectory(this, tr("Select Directory")); |
| 617 | if (!dir_path.isEmpty()) { | 706 | if (!dir_path.isEmpty()) { |
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 74487c58c..5f4d2ab9a 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -125,6 +125,7 @@ private slots: | |||
| 125 | void OnGameListOpenSaveFolder(u64 program_id); | 125 | void OnGameListOpenSaveFolder(u64 program_id); |
| 126 | void OnMenuLoadFile(); | 126 | void OnMenuLoadFile(); |
| 127 | void OnMenuLoadFolder(); | 127 | void OnMenuLoadFolder(); |
| 128 | void OnMenuInstallToNAND(); | ||
| 128 | /// Called whenever a user selects the "File->Select Game List Root" menu item | 129 | /// Called whenever a user selects the "File->Select Game List Root" menu item |
| 129 | void OnMenuSelectGameListRoot(); | 130 | void OnMenuSelectGameListRoot(); |
| 130 | void OnMenuRecentFile(); | 131 | void OnMenuRecentFile(); |
diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui index 22c4cad08..a3bfb2af3 100644 --- a/src/yuzu/main.ui +++ b/src/yuzu/main.ui | |||
| @@ -57,6 +57,8 @@ | |||
| 57 | <string>Recent Files</string> | 57 | <string>Recent Files</string> |
| 58 | </property> | 58 | </property> |
| 59 | </widget> | 59 | </widget> |
| 60 | <addaction name="action_Install_File_NAND" /> | ||
| 61 | <addaction name="separator"/> | ||
| 60 | <addaction name="action_Load_File"/> | 62 | <addaction name="action_Load_File"/> |
| 61 | <addaction name="action_Load_Folder"/> | 63 | <addaction name="action_Load_Folder"/> |
| 62 | <addaction name="separator"/> | 64 | <addaction name="separator"/> |
| @@ -102,6 +104,11 @@ | |||
| 102 | <addaction name="menu_View"/> | 104 | <addaction name="menu_View"/> |
| 103 | <addaction name="menu_Help"/> | 105 | <addaction name="menu_Help"/> |
| 104 | </widget> | 106 | </widget> |
| 107 | <action name="action_Install_File_NAND"> | ||
| 108 | <property name="text"> | ||
| 109 | <string>Install File to NAND...</string> | ||
| 110 | </property> | ||
| 111 | </action> | ||
| 105 | <action name="action_Load_File"> | 112 | <action name="action_Load_File"> |
| 106 | <property name="text"> | 113 | <property name="text"> |
| 107 | <string>Load File...</string> | 114 | <string>Load File...</string> |