Reuse the IOS code for WAD installation
* Less code and logic duplication. * Fixes a bug with the data dir not being created, steps being done in the wrong order.
This commit is contained in:
parent
afcda22da9
commit
c8bffb0153
|
@ -246,74 +246,6 @@ void CNANDContentManager::ClearCache()
|
|||
m_map.clear();
|
||||
}
|
||||
|
||||
u64 CNANDContentManager::Install_WiiWAD(const std::string& filename)
|
||||
{
|
||||
if (filename.find(".wad") == std::string::npos)
|
||||
return 0;
|
||||
const CNANDContentLoader& content_loader = GetNANDLoader(filename);
|
||||
if (content_loader.IsValid() == false)
|
||||
return 0;
|
||||
|
||||
const u64 title_id = content_loader.GetTMD().GetTitleId();
|
||||
|
||||
// copy WAD's TMD header and contents to content directory
|
||||
|
||||
std::string content_path(Common::GetTitleContentPath(title_id, Common::FROM_CONFIGURED_ROOT));
|
||||
std::string tmd_filename(Common::GetTMDFileName(title_id, Common::FROM_CONFIGURED_ROOT));
|
||||
File::CreateFullPath(tmd_filename);
|
||||
|
||||
File::IOFile tmd_file(tmd_filename, "wb");
|
||||
if (!tmd_file)
|
||||
{
|
||||
PanicAlertT("WAD installation failed: error creating %s", tmd_filename.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto& raw_tmd = content_loader.GetTMD().GetRawTMD();
|
||||
tmd_file.WriteBytes(raw_tmd.data(), raw_tmd.size());
|
||||
|
||||
IOS::ES::SharedContentMap shared_content{Common::FromWhichRoot::FROM_CONFIGURED_ROOT};
|
||||
for (const auto& content : content_loader.GetContent())
|
||||
{
|
||||
std::string app_filename;
|
||||
if (content.m_metadata.IsShared())
|
||||
app_filename = shared_content.AddSharedContent(content.m_metadata.sha1);
|
||||
else
|
||||
app_filename = StringFromFormat("%s%08x.app", content_path.c_str(), content.m_metadata.id);
|
||||
|
||||
if (!File::Exists(app_filename))
|
||||
{
|
||||
File::CreateFullPath(app_filename);
|
||||
File::IOFile app_file(app_filename, "wb");
|
||||
if (!app_file)
|
||||
{
|
||||
PanicAlertT("WAD installation failed: error creating %s", app_filename.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
app_file.WriteBytes(content.m_Data->Get().data(), content.m_metadata.size);
|
||||
}
|
||||
else
|
||||
{
|
||||
INFO_LOG(DISCIO, "Content %s already exists.", app_filename.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Extract and copy WAD's ticket to ticket directory
|
||||
if (!AddTicket(content_loader.GetTicket()))
|
||||
{
|
||||
PanicAlertT("WAD installation failed: error creating ticket");
|
||||
return 0;
|
||||
}
|
||||
|
||||
IOS::ES::UIDSys uid_sys{Common::FromWhichRoot::FROM_CONFIGURED_ROOT};
|
||||
uid_sys.GetOrInsertUIDForTitle(title_id);
|
||||
|
||||
ClearCache();
|
||||
|
||||
return title_id;
|
||||
}
|
||||
|
||||
bool AddTicket(const IOS::ES::TicketReader& signed_ticket)
|
||||
{
|
||||
if (!signed_ticket.IsValid())
|
||||
|
|
|
@ -106,7 +106,6 @@ public:
|
|||
static CNANDContentManager instance;
|
||||
return instance;
|
||||
}
|
||||
u64 Install_WiiWAD(const std::string& fileName);
|
||||
|
||||
const CNANDContentLoader& GetNANDLoader(const std::string& content_path);
|
||||
const CNANDContentLoader& GetNANDLoader(u64 title_id, Common::FromWhichRoot from);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "DolphinQt2/GameList/GameFile.h"
|
||||
#include "DolphinQt2/Resources.h"
|
||||
#include "DolphinQt2/Settings.h"
|
||||
#include "UICommon/WiiUtils.h"
|
||||
|
||||
static const int CACHE_VERSION = 13; // Last changed in PR #3261
|
||||
static const int DATASTREAM_VERSION = QDataStream::Qt_5_5;
|
||||
|
@ -331,7 +332,7 @@ bool GameFile::Install()
|
|||
{
|
||||
_assert_(m_platform == DiscIO::Platform::WII_WAD);
|
||||
|
||||
return DiscIO::CNANDContentManager::Access().Install_WiiWAD(m_path.toStdString());
|
||||
return WiiUtils::InstallWAD(m_path.toStdString());
|
||||
}
|
||||
|
||||
bool GameFile::Uninstall()
|
||||
|
|
|
@ -83,6 +83,8 @@
|
|||
|
||||
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
||||
|
||||
#include "UICommon/WiiUtils.h"
|
||||
|
||||
#include "VideoCommon/RenderBase.h"
|
||||
#include "VideoCommon/VideoBackendBase.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
@ -1209,11 +1211,8 @@ void CFrame::OnInstallWAD(wxCommandEvent& event)
|
|||
wxPD_APP_MODAL | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
|
||||
wxPD_REMAINING_TIME | wxPD_SMOOTH);
|
||||
|
||||
u64 titleID = DiscIO::CNANDContentManager::Access().Install_WiiWAD(fileName);
|
||||
if (titleID == TITLEID_SYSMENU)
|
||||
{
|
||||
if (WiiUtils::InstallWAD(fileName))
|
||||
UpdateLoadWiiMenuItem();
|
||||
}
|
||||
}
|
||||
|
||||
void CFrame::OnUninstallWAD(wxCommandEvent&)
|
||||
|
|
|
@ -3,6 +3,7 @@ set(SRCS
|
|||
Disassembler.cpp
|
||||
UICommon.cpp
|
||||
USBUtils.cpp
|
||||
WiiUtils.cpp
|
||||
)
|
||||
|
||||
if(USE_X11)
|
||||
|
|
|
@ -59,12 +59,14 @@
|
|||
<ClCompile Include="USBUtils.cpp">
|
||||
<DisableSpecificWarnings>4200;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<ClCompile Include="WiiUtils.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="CommandLineParse.h" />
|
||||
<ClInclude Include="UICommon.h" />
|
||||
<ClInclude Include="Disassembler.h" />
|
||||
<ClInclude Include="USBUtils.h" />
|
||||
<ClInclude Include="WiiUtils.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="$(ExternalsDir)cpp-optparse\cpp-optparse.vcxproj">
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "UICommon/WiiUtils.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
#include "Core/IOS/ES/ES.h"
|
||||
#include "Core/IOS/ES/Formats.h"
|
||||
#include "Core/IOS/IOS.h"
|
||||
#include "DiscIO/NANDContentLoader.h"
|
||||
#include "DiscIO/WiiWad.h"
|
||||
|
||||
namespace WiiUtils
|
||||
{
|
||||
bool InstallWAD(const std::string& wad_path)
|
||||
{
|
||||
const DiscIO::WiiWAD wad{wad_path};
|
||||
if (!wad.IsValid())
|
||||
{
|
||||
PanicAlertT("WAD installation failed: The selected file is not a valid WAD.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto tmd = wad.GetTMD();
|
||||
IOS::HLE::Kernel ios;
|
||||
const auto es = ios.GetES();
|
||||
|
||||
IOS::HLE::Device::ES::Context context;
|
||||
if (es->ImportTicket(wad.GetTicket().GetRawTicket()) < 0 ||
|
||||
es->ImportTitleInit(context, tmd.GetRawTMD()) < 0)
|
||||
{
|
||||
PanicAlertT("WAD installation failed: Could not initialise title import.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool contents_imported = [&]() {
|
||||
const u64 title_id = tmd.GetTitleId();
|
||||
for (const IOS::ES::Content& content : tmd.GetContents())
|
||||
{
|
||||
const std::vector<u8> data = wad.GetContent(content.index);
|
||||
|
||||
if (es->ImportContentBegin(context, title_id, content.id) < 0 ||
|
||||
es->ImportContentData(context, 0, data.data(), static_cast<u32>(data.size())) < 0 ||
|
||||
es->ImportContentEnd(context, 0) < 0)
|
||||
{
|
||||
PanicAlertT("WAD installation failed: Could not import content %08x.", content.id);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}();
|
||||
|
||||
if ((contents_imported && es->ImportTitleDone(context) < 0) ||
|
||||
(!contents_imported && es->ImportTitleCancel(context) < 0))
|
||||
{
|
||||
PanicAlertT("WAD installation failed: Could not finalise title import.");
|
||||
return false;
|
||||
}
|
||||
|
||||
DiscIO::CNANDContentManager::Access().ClearCache();
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
// Small utility functions for common Wii related tasks.
|
||||
|
||||
namespace WiiUtils
|
||||
{
|
||||
bool InstallWAD(const std::string& wad_path);
|
||||
}
|
Loading…
Reference in New Issue