diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp index a93ba7b577..94bd4ef2b8 100644 --- a/Source/Core/Core/Boot/Boot.cpp +++ b/Source/Core/Core/Boot/Boot.cpp @@ -339,7 +339,8 @@ bool CBoot::BootUp(std::unique_ptr boot) HID4.SBE = 1; // Because there is no TMD to get the requested system (IOS) version from, // we default to IOS58, which is the version used by the Homebrew Channel. - SetupWiiMemory(0x000000010000003a); + SetupWiiMemory(); + IOS::HLE::GetIOS()->BootIOS(0x000000010000003a); } else { @@ -363,6 +364,12 @@ bool CBoot::BootUp(std::unique_ptr boot) return Boot_WiiWAD(nand.content_path); } + bool operator()(const BootParameters::NANDTitle& nand_title) const + { + SetDefaultDisc(); + return BootNANDTitle(nand_title.id); + } + bool operator()(const BootParameters::IPL& ipl) const { NOTICE_LOG(BOOT, "Booting GC IPL: %s", ipl.path.c_str()); diff --git a/Source/Core/Core/Boot/Boot.h b/Source/Core/Core/Boot/Boot.h index 96dd2002e4..b3bc5fab36 100644 --- a/Source/Core/Core/Boot/Boot.h +++ b/Source/Core/Core/Boot/Boot.h @@ -50,6 +50,11 @@ struct BootParameters std::string content_path; }; + struct NANDTitle + { + u64 id; + }; + struct IPL { explicit IPL(DiscIO::Region region_); @@ -67,7 +72,7 @@ struct BootParameters static std::unique_ptr GenerateFromFile(const std::string& path); - using Parameters = std::variant; + using Parameters = std::variant; BootParameters(Parameters&& parameters_); Parameters parameters; @@ -99,6 +104,7 @@ private: static void UpdateDebugger_MapLoaded(); static bool Boot_WiiWAD(const std::string& filename); + static bool BootNANDTitle(u64 title_id); static void SetupMSR(); static void SetupBAT(bool is_wii); @@ -109,7 +115,7 @@ private: static bool Load_BS2(const std::string& boot_rom_filename); static void SetupGCMemory(); - static bool SetupWiiMemory(u64 ios_title_id); + static bool SetupWiiMemory(); }; class BootExecutableReader diff --git a/Source/Core/Core/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Boot/Boot_BS2Emu.cpp index 794e979aa1..ac7d691fce 100644 --- a/Source/Core/Core/Boot/Boot_BS2Emu.cpp +++ b/Source/Core/Core/Boot/Boot_BS2Emu.cpp @@ -213,7 +213,7 @@ bool CBoot::EmulatedBS2_GC(const DiscIO::Volume& volume) return RunApploader(/*is_wii*/ false, volume); } -bool CBoot::SetupWiiMemory(u64 ios_title_id) +bool CBoot::SetupWiiMemory() { static const std::map region_settings = { {DiscIO::Region::NTSC_J, {"JPN", "NTSC", "JP", "LJ"}}, @@ -308,9 +308,6 @@ bool CBoot::SetupWiiMemory(u64 ios_title_id) // It is fine to always use the latest value as apploaders work with all versions. Memory::Write_U16(0x0113, 0x0000315e); - if (!IOS::HLE::GetIOS()->BootIOS(ios_title_id)) - return false; - Memory::Write_U8(0x80, 0x0000315c); // OSInit Memory::Write_U16(0x0000, 0x000030e0); // PADInit Memory::Write_U32(0x80000000, 0x00003184); // GameID Address @@ -367,7 +364,7 @@ bool CBoot::EmulatedBS2_Wii(const DiscIO::Volume& volume) Memory::Write_U32(0, 0x3194); Memory::Write_U32(static_cast(data_partition.offset >> 2), 0x3198); - if (!SetupWiiMemory(tmd.GetIOSId())) + if (!SetupWiiMemory() || !IOS::HLE::GetIOS()->BootIOS(tmd.GetIOSId())) return false; DVDRead(volume, 0x00000000, 0x00000000, 0x20, DiscIO::PARTITION_NONE); // Game Code diff --git a/Source/Core/Core/Boot/Boot_WiiWAD.cpp b/Source/Core/Core/Boot/Boot_WiiWAD.cpp index 44d2b64262..de4275c14a 100644 --- a/Source/Core/Core/Boot/Boot_WiiWAD.cpp +++ b/Source/Core/Core/Boot/Boot_WiiWAD.cpp @@ -21,6 +21,20 @@ #include "DiscIO/NANDContentLoader.h" +bool CBoot::BootNANDTitle(const u64 title_id) +{ + UpdateStateFlags([](StateFlags* state) { + state->type = 0x03; // TYPE_RETURN + }); + + if (title_id == Titles::SYSTEM_MENU) + IOS::HLE::CreateVirtualFATFilesystem(); + + SetupWiiMemory(); + auto* ios = IOS::HLE::GetIOS(); + return ios->GetES()->LaunchTitle(title_id); +} + bool CBoot::Boot_WiiWAD(const std::string& _pFilename) { UpdateStateFlags([](StateFlags* state) { diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp index 2341fdfba3..c5d39b5530 100644 --- a/Source/Core/Core/ConfigManager.cpp +++ b/Source/Core/Core/ConfigManager.cpp @@ -902,6 +902,21 @@ struct SetGameMetadata return true; } + bool operator()(const BootParameters::NANDTitle& nand_title) const + { + IOS::HLE::Kernel ios; + const IOS::ES::TMDReader tmd = ios.GetES()->FindInstalledTMD(nand_title.id); + if (!tmd.IsValid() || !IOS::ES::IsChannel(nand_title.id)) + { + PanicAlertT("This title cannot be booted."); + return false; + } + config->SetRunningGameMetadata(tmd); + config->bWii = true; + *region = tmd.GetRegion(); + return true; + } + bool operator()(const BootParameters::IPL& ipl) const { config->bWii = false; diff --git a/Source/Core/DolphinQt2/MainWindow.cpp b/Source/Core/DolphinQt2/MainWindow.cpp index fbb508f195..7ebc6e9546 100644 --- a/Source/Core/DolphinQt2/MainWindow.cpp +++ b/Source/Core/DolphinQt2/MainWindow.cpp @@ -652,8 +652,7 @@ void MainWindow::PerformOnlineUpdate(const std::string& region) void MainWindow::BootWiiSystemMenu() { - StartGame(QString::fromStdString( - Common::GetTitleContentPath(Titles::SYSTEM_MENU, Common::FROM_CONFIGURED_ROOT))); + StartGame(std::make_unique(BootParameters::NANDTitle{Titles::SYSTEM_MENU})); } void MainWindow::NetPlayInit() diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp index 592f338cd2..7ec4cb0da1 100644 --- a/Source/Core/DolphinWX/FrameTools.cpp +++ b/Source/Core/DolphinWX/FrameTools.cpp @@ -1225,7 +1225,7 @@ void CFrame::OnShowCheatsWindow(wxCommandEvent& WXUNUSED(event)) void CFrame::OnLoadWiiMenu(wxCommandEvent& WXUNUSED(event)) { - BootGame(Common::GetTitleContentPath(Titles::SYSTEM_MENU, Common::FROM_CONFIGURED_ROOT)); + StartGame(std::make_unique(BootParameters::NANDTitle{Titles::SYSTEM_MENU})); } void CFrame::OnInstallWAD(wxCommandEvent& event)