From 9469fc3d6fef425fced1c9e0c05c50dddb3b1966 Mon Sep 17 00:00:00 2001 From: spycrab Date: Thu, 24 Aug 2017 15:11:04 +0200 Subject: [PATCH 1/5] Qt: Implement "Import Wii Save" --- Source/Core/DolphinQt2/MenuBar.cpp | 16 ++++++++++++++++ Source/Core/DolphinQt2/MenuBar.h | 1 + 2 files changed, 17 insertions(+) diff --git a/Source/Core/DolphinQt2/MenuBar.cpp b/Source/Core/DolphinQt2/MenuBar.cpp index b599c99f53..56c5ff480e 100644 --- a/Source/Core/DolphinQt2/MenuBar.cpp +++ b/Source/Core/DolphinQt2/MenuBar.cpp @@ -11,6 +11,7 @@ #include "Core/CommonTitles.h" #include "Core/ConfigManager.h" +#include "Core/HW/WiiSaveCrypted.h" #include "Core/IOS/ES/ES.h" #include "Core/IOS/IOS.h" #include "Core/State.h" @@ -86,6 +87,11 @@ void MenuBar::AddFileMenu() void MenuBar::AddToolsMenu() { QMenu* tools_menu = addMenu(tr("&Tools")); + + tools_menu->addAction(tr("Import Wii Save..."), this, &MenuBar::ImportWiiSave); + + tools_menu->addSeparator(); + m_wad_install_action = tools_menu->addAction(tr("Install WAD..."), this, &MenuBar::InstallWAD); tools_menu->addAction(tr("Start &NetPlay..."), this, &MenuBar::StartNetPlay); @@ -411,3 +417,13 @@ void MenuBar::InstallWAD() result_dialog.exec(); } + +void MenuBar::ImportWiiSave() +{ + QString file = QFileDialog::getOpenFileName(this, tr("Select the save file"), QDir::currentPath(), + tr("Wii save files (*.bin);;" + "All Files (*)")); + + if (!file.isEmpty()) + CWiiSaveCrypted::ImportWiiSave(file.toStdString()); +} diff --git a/Source/Core/DolphinQt2/MenuBar.h b/Source/Core/DolphinQt2/MenuBar.h index db490271ea..59dbf6db1f 100644 --- a/Source/Core/DolphinQt2/MenuBar.h +++ b/Source/Core/DolphinQt2/MenuBar.h @@ -24,6 +24,7 @@ public: // Tools void InstallWAD(); + void ImportWiiSave(); signals: // File From 0dfde1d34e7f4f068aad1461619691b8eea8d84d Mon Sep 17 00:00:00 2001 From: spycrab Date: Thu, 24 Aug 2017 15:21:21 +0200 Subject: [PATCH 2/5] Qt: Implement "Export All Wii Saves" --- Source/Core/DolphinQt2/MenuBar.cpp | 6 ++++++ Source/Core/DolphinQt2/MenuBar.h | 1 + 2 files changed, 7 insertions(+) diff --git a/Source/Core/DolphinQt2/MenuBar.cpp b/Source/Core/DolphinQt2/MenuBar.cpp index 56c5ff480e..38aace538c 100644 --- a/Source/Core/DolphinQt2/MenuBar.cpp +++ b/Source/Core/DolphinQt2/MenuBar.cpp @@ -89,6 +89,7 @@ void MenuBar::AddToolsMenu() QMenu* tools_menu = addMenu(tr("&Tools")); tools_menu->addAction(tr("Import Wii Save..."), this, &MenuBar::ImportWiiSave); + tools_menu->addAction(tr("Export All Wii Saves"), this, &MenuBar::ExportWiiSaves); tools_menu->addSeparator(); @@ -427,3 +428,8 @@ void MenuBar::ImportWiiSave() if (!file.isEmpty()) CWiiSaveCrypted::ImportWiiSave(file.toStdString()); } + +void MenuBar::ExportWiiSaves() +{ + CWiiSaveCrypted::ExportAllSaves(); +} diff --git a/Source/Core/DolphinQt2/MenuBar.h b/Source/Core/DolphinQt2/MenuBar.h index 59dbf6db1f..1a7347fa03 100644 --- a/Source/Core/DolphinQt2/MenuBar.h +++ b/Source/Core/DolphinQt2/MenuBar.h @@ -25,6 +25,7 @@ public: // Tools void InstallWAD(); void ImportWiiSave(); + void ExportWiiSaves(); signals: // File From a2b7632850015efde794f4cac0b1a80d0cd752a7 Mon Sep 17 00:00:00 2001 From: spycrab Date: Thu, 24 Aug 2017 16:35:47 +0200 Subject: [PATCH 3/5] Qt: Implement "Load GameCube Main Menu" --- Source/Core/DolphinQt2/MainWindow.cpp | 25 +++++++++++++++++++------ Source/Core/DolphinQt2/MainWindow.h | 7 ++++++- Source/Core/DolphinQt2/MenuBar.cpp | 18 ++++++++++++++++++ Source/Core/DolphinQt2/MenuBar.h | 6 ++++++ 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/Source/Core/DolphinQt2/MainWindow.cpp b/Source/Core/DolphinQt2/MainWindow.cpp index 6dc3ff4ec9..2723ca6431 100644 --- a/Source/Core/DolphinQt2/MainWindow.cpp +++ b/Source/Core/DolphinQt2/MainWindow.cpp @@ -14,6 +14,7 @@ #include #include "Common/Common.h" +#include "Common/Compat/optional" #include "Core/Boot/Boot.h" #include "Core/BootManager.h" @@ -199,6 +200,7 @@ void MainWindow::ConnectMenuBar() connect(m_menu_bar, &MenuBar::ConfigureHotkeys, this, &MainWindow::ShowHotkeyDialog); // Tools + connect(m_menu_bar, &MenuBar::BootGameCubeIPL, this, &MainWindow::OnBootGameCubeIPL); connect(m_menu_bar, &MenuBar::PerformOnlineUpdate, this, &MainWindow::PerformOnlineUpdate); connect(m_menu_bar, &MenuBar::BootWiiSystemMenu, this, &MainWindow::BootWiiSystemMenu); connect(m_menu_bar, &MenuBar::StartNetPlay, this, &MainWindow::ShowNetPlaySetupDialog); @@ -345,10 +347,10 @@ void MainWindow::OnStopComplete() QGuiApplication::instance()->quit(); // If the current emulation prevented the booting of another, do that now - if (!m_pending_boot.isEmpty()) + if (m_pending_boot != nullptr) { - StartGame(m_pending_boot); - m_pending_boot.clear(); + StartGame(std::move(m_pending_boot)); + m_pending_boot.reset(); } } @@ -446,6 +448,11 @@ void MainWindow::ScreenShot() } void MainWindow::StartGame(const QString& path) +{ + StartGame(BootParameters::GenerateFromFile(path.toStdString())); +} + +void MainWindow::StartGame(std::unique_ptr&& parameters) { // If we're running, only start a new game once we've stopped the last. if (Core::GetState() != Core::State::Uninitialized) @@ -454,11 +461,11 @@ void MainWindow::StartGame(const QString& path) return; // As long as the shutdown isn't complete, we can't boot, so let's boot later - m_pending_boot = path; + m_pending_boot = std::move(parameters); return; } // Boot up, show an error if it fails to load the game. - if (!BootManager::BootCore(BootParameters::GenerateFromFile(path.toStdString()))) + if (!BootManager::BootCore(std::move(parameters))) { QMessageBox::critical(this, tr("Error"), tr("Failed to init core"), QMessageBox::Ok); return; @@ -637,7 +644,8 @@ void MainWindow::NetPlayInit() m_netplay_setup_dialog = new NetPlaySetupDialog(this); m_netplay_dialog = new NetPlayDialog(this); - connect(m_netplay_dialog, &NetPlayDialog::Boot, this, &MainWindow::StartGame); + connect(m_netplay_dialog, &NetPlayDialog::Boot, this, + static_cast(&MainWindow::StartGame)); connect(m_netplay_dialog, &NetPlayDialog::Stop, this, &MainWindow::RequestStop); connect(m_netplay_dialog, &NetPlayDialog::rejected, this, &MainWindow::NetPlayQuit); connect(this, &MainWindow::EmulationStopped, m_netplay_dialog, &NetPlayDialog::EmulationStopped); @@ -819,3 +827,8 @@ QSize MainWindow::sizeHint() const { return QSize(800, 600); } + +void MainWindow::OnBootGameCubeIPL(DiscIO::Region region) +{ + StartGame(std::make_unique(BootParameters::IPL{region})); +} diff --git a/Source/Core/DolphinQt2/MainWindow.h b/Source/Core/DolphinQt2/MainWindow.h index c9804d940d..1d55b39289 100644 --- a/Source/Core/DolphinQt2/MainWindow.h +++ b/Source/Core/DolphinQt2/MainWindow.h @@ -9,11 +9,14 @@ #include #include +#include + #include "DolphinQt2/GameList/GameList.h" #include "DolphinQt2/MenuBar.h" #include "DolphinQt2/RenderWidget.h" #include "DolphinQt2/ToolBar.h" +struct BootParameters; class HotkeyScheduler; class LoggerWidget; class MappingWindow; @@ -83,6 +86,7 @@ private: void InitCoreCallbacks(); void StartGame(const QString& path); + void StartGame(std::unique_ptr&& parameters); void ShowRenderWidget(); void HideRenderWidget(); @@ -99,6 +103,7 @@ private: bool NetPlayHost(const QString& game_id); void NetPlayQuit(); + void OnBootGameCubeIPL(DiscIO::Region region); void OnStopComplete(); void dragEnterEvent(QDragEnterEvent* event) override; void dropEvent(QDropEvent* event) override; @@ -113,7 +118,7 @@ private: bool m_stop_requested = false; bool m_exit_requested = false; int m_state_slot = 1; - QString m_pending_boot; + std::unique_ptr m_pending_boot; HotkeyScheduler* m_hotkey_scheduler; ControllersWindow* m_controllers_window; diff --git a/Source/Core/DolphinQt2/MenuBar.cpp b/Source/Core/DolphinQt2/MenuBar.cpp index 38aace538c..c235125317 100644 --- a/Source/Core/DolphinQt2/MenuBar.cpp +++ b/Source/Core/DolphinQt2/MenuBar.cpp @@ -9,6 +9,8 @@ #include #include +#include "Common/CommonPaths.h" +#include "Common/FileUtil.h" #include "Core/CommonTitles.h" #include "Core/ConfigManager.h" #include "Core/HW/WiiSaveCrypted.h" @@ -95,6 +97,16 @@ void MenuBar::AddToolsMenu() m_wad_install_action = tools_menu->addAction(tr("Install WAD..."), this, &MenuBar::InstallWAD); + tools_menu->addSeparator(); + QMenu* gc_ipl = tools_menu->addMenu(tr("Load GameCube Main Menu")); + + m_ntscj_ipl = gc_ipl->addAction(tr("NTSC-J"), this, + [this] { emit BootGameCubeIPL(DiscIO::Region::NTSC_J); }); + m_ntscu_ipl = gc_ipl->addAction(tr("NTSC-U"), this, + [this] { emit BootGameCubeIPL(DiscIO::Region::NTSC_U); }); + m_pal_ipl = + gc_ipl->addAction(tr("PAL"), this, [this] { emit BootGameCubeIPL(DiscIO::Region::PAL); }); + tools_menu->addAction(tr("Start &NetPlay..."), this, &MenuBar::StartNetPlay); tools_menu->addSeparator(); @@ -375,6 +387,12 @@ void MenuBar::UpdateToolsMenu(bool emulation_started) { m_boot_sysmenu->setEnabled(!emulation_started); m_perform_online_update_menu->setEnabled(!emulation_started); + m_ntscj_ipl->setEnabled(!emulation_started && + File::Exists(SConfig::GetInstance().GetBootROMPath(JAP_DIR))); + m_ntscu_ipl->setEnabled(!emulation_started && + File::Exists(SConfig::GetInstance().GetBootROMPath(USA_DIR))); + m_pal_ipl->setEnabled(!emulation_started && + File::Exists(SConfig::GetInstance().GetBootROMPath(EUR_DIR))); if (!emulation_started) { diff --git a/Source/Core/DolphinQt2/MenuBar.h b/Source/Core/DolphinQt2/MenuBar.h index 1a7347fa03..28bb00a7e1 100644 --- a/Source/Core/DolphinQt2/MenuBar.h +++ b/Source/Core/DolphinQt2/MenuBar.h @@ -55,6 +55,9 @@ signals: void PerformOnlineUpdate(const std::string& region); + // Tools + void BootGameCubeIPL(DiscIO::Region region); + // Options void Configure(); void ConfigureGraphics(); @@ -97,6 +100,9 @@ private: QAction* m_wad_install_action; QMenu* m_perform_online_update_menu; QAction* m_perform_online_update_for_current_region; + QAction* m_ntscj_ipl; + QAction* m_ntscu_ipl; + QAction* m_pal_ipl; // Emulation QAction* m_play_action; From 561d31f88755f1f6157fcd78a08c06ab45751bf2 Mon Sep 17 00:00:00 2001 From: spycrab Date: Thu, 24 Aug 2017 17:38:31 +0200 Subject: [PATCH 4/5] Qt: Implement "Import BootMii NAND Backup" --- Source/Core/DolphinQt2/MainWindow.cpp | 52 ++++++++++++++++++++++++++- Source/Core/DolphinQt2/MainWindow.h | 1 + Source/Core/DolphinQt2/MenuBar.cpp | 9 ++++- Source/Core/DolphinQt2/MenuBar.h | 16 ++++++--- 4 files changed, 71 insertions(+), 7 deletions(-) diff --git a/Source/Core/DolphinQt2/MainWindow.cpp b/Source/Core/DolphinQt2/MainWindow.cpp index 2723ca6431..e5004f4eb2 100644 --- a/Source/Core/DolphinQt2/MainWindow.cpp +++ b/Source/Core/DolphinQt2/MainWindow.cpp @@ -12,9 +12,11 @@ #include #include #include +#include + +#include #include "Common/Common.h" -#include "Common/Compat/optional" #include "Core/Boot/Boot.h" #include "Core/BootManager.h" @@ -34,6 +36,8 @@ #include "Core/NetPlayServer.h" #include "Core/State.h" +#include "DiscIO/NANDImporter.h" + #include "DolphinQt2/AboutDialog.h" #include "DolphinQt2/Config/ControllersWindow.h" #include "DolphinQt2/Config/Graphics/GraphicsWindow.h" @@ -45,6 +49,7 @@ #include "DolphinQt2/MainWindow.h" #include "DolphinQt2/NetPlay/NetPlayDialog.h" #include "DolphinQt2/NetPlay/NetPlaySetupDialog.h" +#include "DolphinQt2/QtUtils/QueueOnObject.h" #include "DolphinQt2/QtUtils/WindowActivationEventFilter.h" #include "DolphinQt2/Resources.h" #include "DolphinQt2/Settings.h" @@ -201,6 +206,7 @@ void MainWindow::ConnectMenuBar() // Tools connect(m_menu_bar, &MenuBar::BootGameCubeIPL, this, &MainWindow::OnBootGameCubeIPL); + connect(m_menu_bar, &MenuBar::ImportNANDBackup, this, &MainWindow::OnImportNANDBackup); connect(m_menu_bar, &MenuBar::PerformOnlineUpdate, this, &MainWindow::PerformOnlineUpdate); connect(m_menu_bar, &MenuBar::BootWiiSystemMenu, this, &MainWindow::BootWiiSystemMenu); connect(m_menu_bar, &MenuBar::StartNetPlay, this, &MainWindow::ShowNetPlaySetupDialog); @@ -832,3 +838,47 @@ void MainWindow::OnBootGameCubeIPL(DiscIO::Region region) { StartGame(std::make_unique(BootParameters::IPL{region})); } + +void MainWindow::OnImportNANDBackup() +{ + auto response = QMessageBox::question( + this, tr("Question"), + tr("Merging a new NAND over your currently selected NAND will overwrite any channels " + "and savegames that already exist. This process is not reversible, so it is " + "recommended that you keep backups of both NANDs. Are you sure you want to " + "continue?")); + + if (response == QMessageBox::No) + return; + + QString file = QFileDialog::getOpenFileName(this, tr("Select the save file"), QDir::currentPath(), + tr("BootMii NAND backup file (*.bin);;" + "All Files (*)")); + + if (file.isEmpty()) + return; + + QProgressDialog* dialog = new QProgressDialog(this); + dialog->setMinimum(0); + dialog->setMaximum(0); + dialog->setLabelText(tr("Importing NAND backup")); + dialog->setCancelButton(nullptr); + + auto beginning = QDateTime::currentDateTime().toSecsSinceEpoch(); + + auto result = std::async(std::launch::async, [&] { + DiscIO::NANDImporter().ImportNANDBin(file.toStdString(), [&dialog, beginning] { + QueueOnObject(dialog, [&dialog, beginning] { + dialog->setLabelText(tr("Importing NAND backup\n Time elapsed: %1s") + .arg(QDateTime::currentDateTime().toSecsSinceEpoch() - beginning)); + }); + }); + QueueOnObject(dialog, [dialog] { dialog->close(); }); + }); + + dialog->exec(); + + result.wait(); + + m_menu_bar->UpdateToolsMenu(Core::IsRunning()); +} diff --git a/Source/Core/DolphinQt2/MainWindow.h b/Source/Core/DolphinQt2/MainWindow.h index 1d55b39289..96efeef45b 100644 --- a/Source/Core/DolphinQt2/MainWindow.h +++ b/Source/Core/DolphinQt2/MainWindow.h @@ -104,6 +104,7 @@ private: void NetPlayQuit(); void OnBootGameCubeIPL(DiscIO::Region region); + void OnImportNANDBackup(); void OnStopComplete(); void dragEnterEvent(QDragEnterEvent* event) override; void dropEvent(QDropEvent* event) override; diff --git a/Source/Core/DolphinQt2/MenuBar.cpp b/Source/Core/DolphinQt2/MenuBar.cpp index c235125317..99e9544302 100644 --- a/Source/Core/DolphinQt2/MenuBar.cpp +++ b/Source/Core/DolphinQt2/MenuBar.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +#include "DolphinQt2/MenuBar.h" + #include #include #include @@ -17,9 +19,9 @@ #include "Core/IOS/ES/ES.h" #include "Core/IOS/IOS.h" #include "Core/State.h" +#include "DiscIO/NANDImporter.h" #include "DolphinQt2/AboutDialog.h" #include "DolphinQt2/GameList/GameFile.h" -#include "DolphinQt2/MenuBar.h" #include "DolphinQt2/Settings.h" MenuBar::MenuBar(QWidget* parent) : QMenuBar(parent) @@ -112,6 +114,9 @@ void MenuBar::AddToolsMenu() // Label will be set by a NANDRefresh later m_boot_sysmenu = tools_menu->addAction(QStringLiteral(""), [this] { emit BootWiiSystemMenu(); }); + m_import_backup = tools_menu->addAction(tr("Import BootMii NAND Backup..."), + [this] { emit ImportNANDBackup(); }); + m_boot_sysmenu->setEnabled(false); connect(&Settings::Instance(), &Settings::NANDRefresh, [this] { UpdateToolsMenu(false); }); @@ -393,6 +398,7 @@ void MenuBar::UpdateToolsMenu(bool emulation_started) File::Exists(SConfig::GetInstance().GetBootROMPath(USA_DIR))); m_pal_ipl->setEnabled(!emulation_started && File::Exists(SConfig::GetInstance().GetBootROMPath(EUR_DIR))); + m_import_backup->setEnabled(!emulation_started); if (!emulation_started) { @@ -451,3 +457,4 @@ void MenuBar::ExportWiiSaves() { CWiiSaveCrypted::ExportAllSaves(); } + diff --git a/Source/Core/DolphinQt2/MenuBar.h b/Source/Core/DolphinQt2/MenuBar.h index 28bb00a7e1..2a34f47e50 100644 --- a/Source/Core/DolphinQt2/MenuBar.h +++ b/Source/Core/DolphinQt2/MenuBar.h @@ -9,6 +9,11 @@ #include #include +namespace DiscIO +{ +enum class Region; +}; + class MenuBar final : public QMenuBar { Q_OBJECT @@ -22,11 +27,6 @@ public: void UpdateStateSlotMenu(); void UpdateToolsMenu(bool emulation_started); - // Tools - void InstallWAD(); - void ImportWiiSave(); - void ExportWiiSaves(); - signals: // File void Open(); @@ -52,6 +52,7 @@ signals: void StateSaveOldest(); void SetStateSlot(int slot); void BootWiiSystemMenu(); + void ImportNANDBackup(); void PerformOnlineUpdate(const std::string& region); @@ -92,6 +93,10 @@ private: void AddToolsMenu(); void AddHelpMenu(); + void InstallWAD(); + void ImportWiiSave(); + void ExportWiiSaves(); + // File QAction* m_open_action; QAction* m_exit_action; @@ -103,6 +108,7 @@ private: QAction* m_ntscj_ipl; QAction* m_ntscu_ipl; QAction* m_pal_ipl; + QAction* m_import_backup; // Emulation QAction* m_play_action; From 1173c2f790d0c47eaba081209baa602f4b530685 Mon Sep 17 00:00:00 2001 From: spycrab Date: Sat, 26 Aug 2017 14:41:53 +0200 Subject: [PATCH 5/5] Qt: Implement "Extract Certificates from NAND" --- Source/Core/DolphinQt2/MenuBar.cpp | 15 +++++++++++++++ Source/Core/DolphinQt2/MenuBar.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/Source/Core/DolphinQt2/MenuBar.cpp b/Source/Core/DolphinQt2/MenuBar.cpp index 99e9544302..8a1c6ec509 100644 --- a/Source/Core/DolphinQt2/MenuBar.cpp +++ b/Source/Core/DolphinQt2/MenuBar.cpp @@ -117,6 +117,9 @@ void MenuBar::AddToolsMenu() m_import_backup = tools_menu->addAction(tr("Import BootMii NAND Backup..."), [this] { emit ImportNANDBackup(); }); + m_extract_certificates = tools_menu->addAction(tr("Extract Certificates from NAND"), this, + &MenuBar::NANDExtractCertificates); + m_boot_sysmenu->setEnabled(false); connect(&Settings::Instance(), &Settings::NANDRefresh, [this] { UpdateToolsMenu(false); }); @@ -458,3 +461,15 @@ void MenuBar::ExportWiiSaves() CWiiSaveCrypted::ExportAllSaves(); } +void MenuBar::NANDExtractCertificates() +{ + if (DiscIO::NANDImporter().ExtractCertificates(File::GetUserPath(D_WIIROOT_IDX))) + { + QMessageBox::information(this, tr("Success"), + tr("Successfully extracted certificates from NAND")); + } + else + { + QMessageBox::critical(this, tr("Error"), tr("Failed to extract certificates from NAND")); + } +} diff --git a/Source/Core/DolphinQt2/MenuBar.h b/Source/Core/DolphinQt2/MenuBar.h index 2a34f47e50..a170441d19 100644 --- a/Source/Core/DolphinQt2/MenuBar.h +++ b/Source/Core/DolphinQt2/MenuBar.h @@ -96,6 +96,7 @@ private: void InstallWAD(); void ImportWiiSave(); void ExportWiiSaves(); + void NANDExtractCertificates(); // File QAction* m_open_action; @@ -109,6 +110,7 @@ private: QAction* m_ntscu_ipl; QAction* m_pal_ipl; QAction* m_import_backup; + QAction* m_extract_certificates; // Emulation QAction* m_play_action;