diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp index 157ce8c123..819bcba3e5 100644 --- a/Source/Android/jni/MainAndroid.cpp +++ b/Source/Android/jni/MainAndroid.cpp @@ -794,7 +794,7 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv* // No use running the loop when booting fails s_have_wm_user_stop = false; - if (BootManager::BootCore(s_filename.c_str())) + if (BootManager::BootCore(s_filename.c_str(), SConfig::BOOT_DEFAULT)) { static constexpr int TIMEOUT = 10000; static constexpr int WAIT_STEP = 25; diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp index daf9472763..6febdd28a3 100644 --- a/Source/Core/Core/Boot/Boot.cpp +++ b/Source/Core/Core/Boot/Boot.cpp @@ -276,7 +276,10 @@ bool CBoot::BootUp() { SConfig& _StartupPara = SConfig::GetInstance(); - NOTICE_LOG(BOOT, "Booting %s", _StartupPara.m_strFilename.c_str()); + if (_StartupPara.m_BootType == SConfig::BOOT_BS2) + NOTICE_LOG(BOOT, "Booting %s", _StartupPara.m_strBootROM.c_str()); + else + NOTICE_LOG(BOOT, "Booting %s", _StartupPara.m_strFilename.c_str()); g_symbolDB.Clear(); diff --git a/Source/Core/Core/BootManager.cpp b/Source/Core/Core/BootManager.cpp index febea2441e..295ac883de 100644 --- a/Source/Core/Core/BootManager.cpp +++ b/Source/Core/Core/BootManager.cpp @@ -218,13 +218,13 @@ static GPUDeterminismMode ParseGPUDeterminismMode(const std::string& mode) } // Boot the ISO or file -bool BootCore(const std::string& _rFilename) +bool BootCore(const std::string& filename, SConfig::EBootBS2 type) { SConfig& StartUp = SConfig::GetInstance(); StartUp.m_BootType = SConfig::BOOT_ISO; - StartUp.m_strFilename = _rFilename; - StartUp.m_LastFilename = _rFilename; + StartUp.m_strFilename = filename; + StartUp.m_LastFilename = filename; StartUp.SaveSettings(); StartUp.bRunCompareClient = false; StartUp.bRunCompareServer = false; @@ -232,10 +232,11 @@ bool BootCore(const std::string& _rFilename) config_cache.SaveConfig(StartUp); // If for example the ISO file is bad we return here - if (!StartUp.AutoSetup(SConfig::BOOT_DEFAULT)) + if (!StartUp.AutoSetup(type)) return false; // Load game specific settings + if (type == SConfig::BOOT_DEFAULT) { IniFile game_ini = StartUp.LoadGameIni(); diff --git a/Source/Core/Core/BootManager.h b/Source/Core/Core/BootManager.h index 42dd9d7b49..bb7b7cae99 100644 --- a/Source/Core/Core/BootManager.h +++ b/Source/Core/Core/BootManager.h @@ -6,9 +6,11 @@ #include +#include "Core/ConfigManager.h" + namespace BootManager { -bool BootCore(const std::string& _rFilename); +bool BootCore(const std::string& filename, SConfig::EBootBS2 type); // Stop the emulation core and restore the configuration. void Stop(); diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp index c71b56e822..0a1917791d 100644 --- a/Source/Core/Core/ConfigManager.cpp +++ b/Source/Core/Core/ConfigManager.cpp @@ -870,6 +870,15 @@ const char* SConfig::GetDirectoryForRegion(DiscIO::Region region) } } +std::string SConfig::GetBootROMPath(const std::string& region_directory) const +{ + const std::string path = + File::GetUserPath(D_GCUSER_IDX) + DIR_SEP + region_directory + DIR_SEP GC_IPL; + if (!File::Exists(path)) + return File::GetSysDirectory() + GC_SYS_DIR + DIR_SEP + region_directory + DIR_SEP GC_IPL; + return path; +} + // Sets m_region to the region parameter, or to PAL if the region parameter // is invalid. Set directory_name to the value returned by GetDirectoryForRegion // for m_region. Returns false if the region parameter is invalid. @@ -991,16 +1000,19 @@ bool SConfig::AutoSetup(EBootBS2 _BootBS2) case BOOT_BS2_USA: SetRegion(DiscIO::Region::NTSC_U, &set_region_dir); m_strFilename.clear(); + m_BootType = SConfig::BOOT_BS2; break; case BOOT_BS2_JAP: SetRegion(DiscIO::Region::NTSC_J, &set_region_dir); m_strFilename.clear(); + m_BootType = SConfig::BOOT_BS2; break; case BOOT_BS2_EUR: SetRegion(DiscIO::Region::PAL, &set_region_dir); m_strFilename.clear(); + m_BootType = SConfig::BOOT_BS2; break; } @@ -1012,10 +1024,7 @@ bool SConfig::AutoSetup(EBootBS2 _BootBS2) { if (!bHLE_BS2) { - m_strBootROM = File::GetUserPath(D_GCUSER_IDX) + DIR_SEP + set_region_dir + DIR_SEP GC_IPL; - if (!File::Exists(m_strBootROM)) - m_strBootROM = - File::GetSysDirectory() + GC_SYS_DIR + DIR_SEP + set_region_dir + DIR_SEP GC_IPL; + m_strBootROM = GetBootROMPath(set_region_dir); if (!File::Exists(m_strBootROM)) { diff --git a/Source/Core/Core/ConfigManager.h b/Source/Core/Core/ConfigManager.h index 15c1570cc8..be35ea8e7e 100644 --- a/Source/Core/Core/ConfigManager.h +++ b/Source/Core/Core/ConfigManager.h @@ -231,6 +231,7 @@ struct SConfig : NonCopyable void LoadDefaults(); static const char* GetDirectoryForRegion(DiscIO::Region region); + std::string GetBootROMPath(const std::string& region_directory) const; bool AutoSetup(EBootBS2 _BootBS2); void CheckMemcardPath(std::string& memcardPath, const std::string& gameRegion, bool isSlotA); DiscIO::Language GetCurrentLanguage(bool wii) const; diff --git a/Source/Core/DolphinNoGUI/MainNoGUI.cpp b/Source/Core/DolphinNoGUI/MainNoGUI.cpp index ce296251ed..9e4eb3e433 100644 --- a/Source/Core/DolphinNoGUI/MainNoGUI.cpp +++ b/Source/Core/DolphinNoGUI/MainNoGUI.cpp @@ -422,7 +422,7 @@ int main(int argc, char* argv[]) DolphinAnalytics::Instance()->ReportDolphinStart("nogui"); - if (!BootManager::BootCore(boot_filename)) + if (!BootManager::BootCore(boot_filename, SConfig::BOOT_DEFAULT)) { fprintf(stderr, "Could not boot %s\n", boot_filename.c_str()); return 1; diff --git a/Source/Core/DolphinQt2/MainWindow.cpp b/Source/Core/DolphinQt2/MainWindow.cpp index 90eef84439..d60c0ac415 100644 --- a/Source/Core/DolphinQt2/MainWindow.cpp +++ b/Source/Core/DolphinQt2/MainWindow.cpp @@ -289,7 +289,7 @@ void MainWindow::StartGame(const QString& path) return; } // Boot up, show an error if it fails to load the game. - if (!BootManager::BootCore(path.toStdString())) + if (!BootManager::BootCore(path.toStdString(), SConfig::BOOT_DEFAULT)) { QMessageBox::critical(this, tr("Error"), tr("Failed to init core"), QMessageBox::Ok); return; diff --git a/Source/Core/DolphinWX/Frame.h b/Source/Core/DolphinWX/Frame.h index b31a211152..aadba9d5df 100644 --- a/Source/Core/DolphinWX/Frame.h +++ b/Source/Core/DolphinWX/Frame.h @@ -17,6 +17,7 @@ #include "Common/CommonTypes.h" #include "Common/Event.h" +#include "Core/ConfigManager.h" #include "DolphinWX/Globals.h" #if defined(HAVE_X11) && HAVE_X11 @@ -183,7 +184,7 @@ private: void InitializeTASDialogs(); void InitializeCoreCallbacks(); - void StartGame(const std::string& filename); + void StartGame(const std::string& filename, SConfig::EBootBS2 type = SConfig::BOOT_DEFAULT); void SetDebuggerStartupParameters() const; // Utility @@ -327,6 +328,10 @@ private: void OnImportSave(wxCommandEvent& event); void OnExportAllSaves(wxCommandEvent& event); + void OnLoadGameCubeBIOSJAP(wxCommandEvent& event); + void OnLoadGameCubeBIOSUSA(wxCommandEvent& event); + void OnLoadGameCubeBIOSEUR(wxCommandEvent& event); + void OnNetPlay(wxCommandEvent& event); void OnShowCheatsWindow(wxCommandEvent& event); diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp index c7682c9fac..27c3f80ca8 100644 --- a/Source/Core/DolphinWX/FrameTools.cpp +++ b/Source/Core/DolphinWX/FrameTools.cpp @@ -23,6 +23,7 @@ #include #include "Common/CDUtils.h" +#include "Common/CommonPaths.h" #include "Common/CommonTypes.h" #include "Common/FileSearch.h" #include "Common/FileUtil.h" @@ -168,6 +169,9 @@ void CFrame::BindMenuBarEvents() Bind(wxEVT_MENU, &CFrame::OnMemcard, this, IDM_MEMCARD); Bind(wxEVT_MENU, &CFrame::OnImportSave, this, IDM_IMPORT_SAVE); Bind(wxEVT_MENU, &CFrame::OnExportAllSaves, this, IDM_EXPORT_ALL_SAVE); + Bind(wxEVT_MENU, &CFrame::OnLoadGameCubeBIOSJAP, this, IDM_LOAD_GC_BIOS_JAP); + Bind(wxEVT_MENU, &CFrame::OnLoadGameCubeBIOSUSA, this, IDM_LOAD_GC_BIOS_USA); + Bind(wxEVT_MENU, &CFrame::OnLoadGameCubeBIOSEUR, this, IDM_LOAD_GC_BIOS_EUR); Bind(wxEVT_MENU, &CFrame::OnShowCheatsWindow, this, IDM_CHEATS); Bind(wxEVT_MENU, &CFrame::OnNetPlay, this, IDM_NETPLAY); Bind(wxEVT_MENU, &CFrame::OnInstallWAD, this, IDM_MENU_INSTALL_WAD); @@ -632,7 +636,7 @@ void CFrame::ToggleDisplayMode(bool bFullscreen) } // Prepare the GUI to start the game. -void CFrame::StartGame(const std::string& filename) +void CFrame::StartGame(const std::string& filename, SConfig::EBootBS2 type) { if (m_is_game_loading) return; @@ -710,7 +714,7 @@ void CFrame::StartGame(const std::string& filename) SetDebuggerStartupParameters(); - if (!BootManager::BootCore(filename)) + if (!BootManager::BootCore(filename, type)) { DoFullscreen(false); @@ -1172,6 +1176,21 @@ void CFrame::OnMemcard(wxCommandEvent& WXUNUSED(event)) HotkeyManagerEmu::Enable(true); } +void CFrame::OnLoadGameCubeBIOSJAP(wxCommandEvent&) +{ + StartGame("", SConfig::BOOT_BS2_JAP); +} + +void CFrame::OnLoadGameCubeBIOSUSA(wxCommandEvent&) +{ + StartGame("", SConfig::BOOT_BS2_USA); +} + +void CFrame::OnLoadGameCubeBIOSEUR(wxCommandEvent&) +{ + StartGame("", SConfig::BOOT_BS2_EUR); +} + void CFrame::OnExportAllSaves(wxCommandEvent& WXUNUSED(event)) { CWiiSaveCrypted::ExportAllSaves(); @@ -1478,6 +1497,15 @@ void CFrame::UpdateGUI() GetMenuBar()->FindItem(IDM_SAVE_STATE)->Enable(Initialized); // Misc GetMenuBar()->FindItem(IDM_CHANGE_DISC)->Enable(Initialized); + GetMenuBar() + ->FindItem(IDM_LOAD_GC_BIOS_JAP) + ->Enable(!Initialized && File::Exists(SConfig::GetInstance().GetBootROMPath(JAP_DIR))); + GetMenuBar() + ->FindItem(IDM_LOAD_GC_BIOS_USA) + ->Enable(!Initialized && File::Exists(SConfig::GetInstance().GetBootROMPath(USA_DIR))); + GetMenuBar() + ->FindItem(IDM_LOAD_GC_BIOS_EUR) + ->Enable(!Initialized && File::Exists(SConfig::GetInstance().GetBootROMPath(EUR_DIR))); if (DiscIO::CNANDContentManager::Access() .GetNANDLoader(TITLEID_SYSMENU, Common::FROM_CONFIGURED_ROOT) .IsValid()) diff --git a/Source/Core/DolphinWX/Globals.h b/Source/Core/DolphinWX/Globals.h index 0af8dc1886..4abebdbcfa 100644 --- a/Source/Core/DolphinWX/Globals.h +++ b/Source/Core/DolphinWX/Globals.h @@ -105,6 +105,9 @@ enum IDM_IMPORT_NAND, IDM_EXTRACT_CERTIFICATES, IDM_FIFOPLAYER, + IDM_LOAD_GC_BIOS_JAP, + IDM_LOAD_GC_BIOS_USA, + IDM_LOAD_GC_BIOS_EUR, IDM_CONNECT_WIIMOTE1, IDM_CONNECT_WIIMOTE2, IDM_CONNECT_WIIMOTE3, diff --git a/Source/Core/DolphinWX/MainMenuBar.cpp b/Source/Core/DolphinWX/MainMenuBar.cpp index c29cbbbef4..eb977ccf0e 100644 --- a/Source/Core/DolphinWX/MainMenuBar.cpp +++ b/Source/Core/DolphinWX/MainMenuBar.cpp @@ -216,6 +216,16 @@ wxMenu* MainMenuBar::CreateToolsMenu() const tools_menu->Append(IDM_IMPORT_SAVE, _("Import Wii Save...")); tools_menu->Append(IDM_EXPORT_ALL_SAVE, _("Export All Wii Saves")); tools_menu->AppendSeparator(); + auto* const gc_bios_menu = new wxMenu; + gc_bios_menu->Append(IDM_LOAD_GC_BIOS_JAP, _("NTSC-J"), + _("Load NTSC-J GameCube BIOS from the JAP folder.")); + gc_bios_menu->Append(IDM_LOAD_GC_BIOS_USA, _("NTSC-U"), + _("Load NTSC-U GameCube BIOS from the USA folder.")); + gc_bios_menu->Append(IDM_LOAD_GC_BIOS_EUR, _("PAL"), + _("Load PAL GameCube BIOS from the EUR folder.")); + tools_menu->AppendSubMenu(gc_bios_menu, _("Load GameCube BIOS"), + _("Load a GameCube BIOS located under Dolphin's GC folder.")); + tools_menu->AppendSeparator(); tools_menu->Append(IDM_CHEATS, _("&Cheat Manager")); tools_menu->Append(IDM_NETPLAY, _("Start &NetPlay...")); tools_menu->Append(IDM_FIFOPLAYER, _("FIFO Player"));