Drop the direct WAD launch hack
This removes the hack that enables directly booting from WADs without installing them first for the following reasons: 1. It makes the NAND content handling much more complicated than what it should be and makes future changes like permissions or booting NAND titles without a WAD more annoying to implement. Because of this hack, we needed an extra level of abstraction (NANDContent*) which has to read tons of things from the NAND, even most of the time it's useless. This in turn forces us to have caching, which is known to break titles and requires manual cache invalidations. Annoying and error prone. 2. It prevents the WAD boot code from being easily accurate. With this change, we can simply reuse the existing launch code, and ask IOS to launch the title from the NAND. 3. The hack did not work that well since it did not cover a lot of ES commands. And it works even less since the ES accuracy fixes. This results in Dolphin returning inconsistent results: a lot of the ES "DI" commands will just fail because the active title is not installed on the NAND. uid.sys is not changed, etc. And I'm not even talking about FS stuff -- where this would still totally fail, unless we add even more unnecessary hacks. This is not just theoretical -- the system menu and the Wii Shop are known to behave strangely because the hack damages the NAND structure, and we've already had several users report issues. This commit makes it so WADs are always installed prior to launching. A future commit will remove any code that was there only for the hack.
This commit is contained in:
parent
60ba382799
commit
9000a042e4
|
@ -100,8 +100,8 @@ std::unique_ptr<BootParameters> BootParameters::GenerateFromFile(const std::stri
|
||||||
if (extension == ".dff")
|
if (extension == ".dff")
|
||||||
return std::make_unique<BootParameters>(DFF{path});
|
return std::make_unique<BootParameters>(DFF{path});
|
||||||
|
|
||||||
if (DiscIO::NANDContentManager::Access().GetNANDLoader(path).IsValid())
|
if (extension == ".wad")
|
||||||
return std::make_unique<BootParameters>(NAND{path});
|
return std::make_unique<BootParameters>(DiscIO::WiiWAD{path});
|
||||||
|
|
||||||
PanicAlertT("Could not recognize file %s", path.c_str());
|
PanicAlertT("Could not recognize file %s", path.c_str());
|
||||||
return {};
|
return {};
|
||||||
|
@ -357,11 +357,10 @@ bool CBoot::BootUp(std::unique_ptr<BootParameters> boot)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(const BootParameters::NAND& nand) const
|
bool operator()(const DiscIO::WiiWAD& wad) const
|
||||||
{
|
{
|
||||||
NOTICE_LOG(BOOT, "Booting from NAND: %s", nand.content_path.c_str());
|
|
||||||
SetDefaultDisc();
|
SetDefaultDisc();
|
||||||
return Boot_WiiWAD(nand.content_path);
|
return Boot_WiiWAD(wad);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(const BootParameters::NANDTitle& nand_title) const
|
bool operator()(const BootParameters::NANDTitle& nand_title) const
|
||||||
|
|
|
@ -13,8 +13,10 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
#include "DiscIO/Blob.h"
|
||||||
#include "DiscIO/Enums.h"
|
#include "DiscIO/Enums.h"
|
||||||
#include "DiscIO/Volume.h"
|
#include "DiscIO/Volume.h"
|
||||||
|
#include "DiscIO/WiiWad.h"
|
||||||
|
|
||||||
namespace File
|
namespace File
|
||||||
{
|
{
|
||||||
|
@ -45,11 +47,6 @@ struct BootParameters
|
||||||
std::unique_ptr<BootExecutableReader> reader;
|
std::unique_ptr<BootExecutableReader> reader;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NAND
|
|
||||||
{
|
|
||||||
std::string content_path;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct NANDTitle
|
struct NANDTitle
|
||||||
{
|
{
|
||||||
u64 id;
|
u64 id;
|
||||||
|
@ -72,7 +69,7 @@ struct BootParameters
|
||||||
|
|
||||||
static std::unique_ptr<BootParameters> GenerateFromFile(const std::string& path);
|
static std::unique_ptr<BootParameters> GenerateFromFile(const std::string& path);
|
||||||
|
|
||||||
using Parameters = std::variant<Disc, Executable, NAND, NANDTitle, IPL, DFF>;
|
using Parameters = std::variant<Disc, Executable, DiscIO::WiiWAD, NANDTitle, IPL, DFF>;
|
||||||
BootParameters(Parameters&& parameters_);
|
BootParameters(Parameters&& parameters_);
|
||||||
|
|
||||||
Parameters parameters;
|
Parameters parameters;
|
||||||
|
@ -103,7 +100,7 @@ private:
|
||||||
|
|
||||||
static void UpdateDebugger_MapLoaded();
|
static void UpdateDebugger_MapLoaded();
|
||||||
|
|
||||||
static bool Boot_WiiWAD(const std::string& filename);
|
static bool Boot_WiiWAD(const DiscIO::WiiWAD& wad);
|
||||||
static bool BootNANDTitle(u64 title_id);
|
static bool BootNANDTitle(u64 title_id);
|
||||||
|
|
||||||
static void SetupMSR();
|
static void SetupMSR();
|
||||||
|
|
|
@ -18,8 +18,10 @@
|
||||||
#include "Core/IOS/ES/Formats.h"
|
#include "Core/IOS/ES/Formats.h"
|
||||||
#include "Core/IOS/FS/FileIO.h"
|
#include "Core/IOS/FS/FileIO.h"
|
||||||
#include "Core/IOS/IOS.h"
|
#include "Core/IOS/IOS.h"
|
||||||
|
#include "Core/WiiUtils.h"
|
||||||
|
|
||||||
#include "DiscIO/NANDContentLoader.h"
|
#include "DiscIO/NANDContentLoader.h"
|
||||||
|
#include "DiscIO/WiiWad.h"
|
||||||
|
|
||||||
bool CBoot::BootNANDTitle(const u64 title_id)
|
bool CBoot::BootNANDTitle(const u64 title_id)
|
||||||
{
|
{
|
||||||
|
@ -35,46 +37,12 @@ bool CBoot::BootNANDTitle(const u64 title_id)
|
||||||
return ios->GetES()->LaunchTitle(title_id);
|
return ios->GetES()->LaunchTitle(title_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBoot::Boot_WiiWAD(const std::string& _pFilename)
|
bool CBoot::Boot_WiiWAD(const DiscIO::WiiWAD& wad)
|
||||||
{
|
{
|
||||||
UpdateStateFlags([](StateFlags* state) {
|
if (!WiiUtils::InstallWAD(*IOS::HLE::GetIOS(), wad))
|
||||||
state->type = 0x03; // TYPE_RETURN
|
|
||||||
});
|
|
||||||
|
|
||||||
const DiscIO::NANDContentLoader& ContentLoader =
|
|
||||||
DiscIO::NANDContentManager::Access().GetNANDLoader(_pFilename);
|
|
||||||
if (!ContentLoader.IsValid())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
u64 titleID = ContentLoader.GetTMD().GetTitleId();
|
|
||||||
|
|
||||||
if (!IOS::ES::IsChannel(titleID))
|
|
||||||
{
|
{
|
||||||
PanicAlertT("This WAD is not bootable.");
|
PanicAlertT("Cannot boot this WAD because it could not be installed to the NAND.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return BootNANDTitle(wad.GetTMD().GetTitleId());
|
||||||
// create data directory
|
|
||||||
File::CreateFullPath(Common::GetTitleDataPath(titleID, Common::FROM_SESSION_ROOT));
|
|
||||||
|
|
||||||
if (titleID == Titles::SYSTEM_MENU)
|
|
||||||
IOS::HLE::CreateVirtualFATFilesystem();
|
|
||||||
// setup Wii memory
|
|
||||||
|
|
||||||
if (!SetupWiiMemory(ContentLoader.GetTMD().GetIOSId()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
IOS::HLE::Device::ES::LoadWAD(_pFilename);
|
|
||||||
|
|
||||||
// TODO: kill these manual calls and just use ES_Launch here, as soon as the direct WAD
|
|
||||||
// launch hack is dropped.
|
|
||||||
auto* ios = IOS::HLE::GetIOS();
|
|
||||||
IOS::ES::UIDSys uid_map{Common::FROM_SESSION_ROOT};
|
|
||||||
ios->SetUidForPPC(uid_map.GetOrInsertUIDForTitle(titleID));
|
|
||||||
ios->SetGidForPPC(ContentLoader.GetTMD().GetGroupId());
|
|
||||||
|
|
||||||
if (!ios->BootstrapPPC(ContentLoader))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "DiscIO/Enums.h"
|
#include "DiscIO/Enums.h"
|
||||||
#include "DiscIO/NANDContentLoader.h"
|
#include "DiscIO/NANDContentLoader.h"
|
||||||
#include "DiscIO/Volume.h"
|
#include "DiscIO/Volume.h"
|
||||||
|
#include "DiscIO/WiiWad.h"
|
||||||
|
|
||||||
SConfig* SConfig::m_Instance;
|
SConfig* SConfig::m_Instance;
|
||||||
|
|
||||||
|
@ -888,14 +889,20 @@ struct SetGameMetadata
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(const BootParameters::NAND& nand) const
|
bool operator()(const DiscIO::WiiWAD& wad) const
|
||||||
{
|
{
|
||||||
const auto& loader = DiscIO::NANDContentManager::Access().GetNANDLoader(nand.content_path);
|
if (!wad.IsValid() || !wad.GetTMD().IsValid())
|
||||||
if (!loader.IsValid())
|
{
|
||||||
|
PanicAlertT("This WAD is not valid.");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
if (!IOS::ES::IsChannel(wad.GetTMD().GetTitleId()))
|
||||||
|
{
|
||||||
|
PanicAlertT("This WAD is not bootable.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const IOS::ES::TMDReader& tmd = loader.GetTMD();
|
const IOS::ES::TMDReader& tmd = wad.GetTMD();
|
||||||
|
|
||||||
config->SetRunningGameMetadata(tmd);
|
config->SetRunningGameMetadata(tmd);
|
||||||
config->bWii = true;
|
config->bWii = true;
|
||||||
*region = tmd.GetRegion();
|
*region = tmd.GetRegion();
|
||||||
|
|
|
@ -20,6 +20,8 @@ class WiiWAD
|
||||||
public:
|
public:
|
||||||
explicit WiiWAD(const std::string& name);
|
explicit WiiWAD(const std::string& name);
|
||||||
explicit WiiWAD(std::unique_ptr<BlobReader> blob_reader);
|
explicit WiiWAD(std::unique_ptr<BlobReader> blob_reader);
|
||||||
|
WiiWAD(WiiWAD&&) = default;
|
||||||
|
WiiWAD& operator=(WiiWAD&&) = default;
|
||||||
~WiiWAD();
|
~WiiWAD();
|
||||||
|
|
||||||
bool IsValid() const { return m_valid; }
|
bool IsValid() const { return m_valid; }
|
||||||
|
|
Loading…
Reference in New Issue