diff --git a/Source/Core/DiscIO/NANDContentLoader.cpp b/Source/Core/DiscIO/NANDContentLoader.cpp
index 4e7f6f12ba..e6aca0ce79 100644
--- a/Source/Core/DiscIO/NANDContentLoader.cpp
+++ b/Source/Core/DiscIO/NANDContentLoader.cpp
@@ -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())
diff --git a/Source/Core/DiscIO/NANDContentLoader.h b/Source/Core/DiscIO/NANDContentLoader.h
index 3b16b82bda..af4ff4909c 100644
--- a/Source/Core/DiscIO/NANDContentLoader.h
+++ b/Source/Core/DiscIO/NANDContentLoader.h
@@ -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);
diff --git a/Source/Core/DolphinQt2/GameList/GameFile.cpp b/Source/Core/DolphinQt2/GameList/GameFile.cpp
index b81d491aff..f3a644934d 100644
--- a/Source/Core/DolphinQt2/GameList/GameFile.cpp
+++ b/Source/Core/DolphinQt2/GameList/GameFile.cpp
@@ -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()
diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp
index f8f99cdd81..1098852605 100644
--- a/Source/Core/DolphinWX/FrameTools.cpp
+++ b/Source/Core/DolphinWX/FrameTools.cpp
@@ -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&)
diff --git a/Source/Core/UICommon/CMakeLists.txt b/Source/Core/UICommon/CMakeLists.txt
index 36648bbe7c..df1f3fd157 100644
--- a/Source/Core/UICommon/CMakeLists.txt
+++ b/Source/Core/UICommon/CMakeLists.txt
@@ -3,6 +3,7 @@ set(SRCS
Disassembler.cpp
UICommon.cpp
USBUtils.cpp
+ WiiUtils.cpp
)
if(USE_X11)
diff --git a/Source/Core/UICommon/UICommon.vcxproj b/Source/Core/UICommon/UICommon.vcxproj
index 18d1ee0966..d5982fc1b3 100644
--- a/Source/Core/UICommon/UICommon.vcxproj
+++ b/Source/Core/UICommon/UICommon.vcxproj
@@ -59,12 +59,14 @@
4200;%(DisableSpecificWarnings)
+
+
@@ -74,4 +76,4 @@
-
\ No newline at end of file
+
diff --git a/Source/Core/UICommon/WiiUtils.cpp b/Source/Core/UICommon/WiiUtils.cpp
new file mode 100644
index 0000000000..1575f272f7
--- /dev/null
+++ b/Source/Core/UICommon/WiiUtils.cpp
@@ -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 data = wad.GetContent(content.index);
+
+ if (es->ImportContentBegin(context, title_id, content.id) < 0 ||
+ es->ImportContentData(context, 0, data.data(), static_cast(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;
+}
+}
diff --git a/Source/Core/UICommon/WiiUtils.h b/Source/Core/UICommon/WiiUtils.h
new file mode 100644
index 0000000000..8419e01b9b
--- /dev/null
+++ b/Source/Core/UICommon/WiiUtils.h
@@ -0,0 +1,14 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include
+
+// Small utility functions for common Wii related tasks.
+
+namespace WiiUtils
+{
+bool InstallWAD(const std::string& wad_path);
+}