Added support for exporting Trilogy and Wii de Asobu builds
This commit is contained in:
parent
305fbbdeed
commit
e4d7c37541
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -17,12 +17,14 @@
|
||||||
#define USE_ASSET_NAME_MAP 1
|
#define USE_ASSET_NAME_MAP 1
|
||||||
#define EXPORT_COOKED 1
|
#define EXPORT_COOKED 1
|
||||||
|
|
||||||
CGameExporter::CGameExporter(EGame Game, ERegion Region, const TString& rkGameName, const TString& rkGameID, float BuildVersion)
|
CGameExporter::CGameExporter(EDiscType DiscType, EGame Game, bool FrontEnd, ERegion Region, const TString& rkGameName, const TString& rkGameID, float BuildVersion)
|
||||||
: mGame(Game)
|
: mGame(Game)
|
||||||
, mRegion(Region)
|
, mRegion(Region)
|
||||||
, mGameName(rkGameName)
|
, mGameName(rkGameName)
|
||||||
, mGameID(rkGameID)
|
, mGameID(rkGameID)
|
||||||
, mBuildVersion(BuildVersion)
|
, mBuildVersion(BuildVersion)
|
||||||
|
, mDiscType(DiscType)
|
||||||
|
, mFrontEnd(FrontEnd)
|
||||||
, mpProgress(nullptr)
|
, mpProgress(nullptr)
|
||||||
{
|
{
|
||||||
ASSERT(mGame != eUnknownGame);
|
ASSERT(mGame != eUnknownGame);
|
||||||
|
@ -96,6 +98,70 @@ void CGameExporter::LoadResource(const CAssetID& rkID, std::vector<u8>& rBuffer)
|
||||||
if (pInst) LoadResource(*pInst, rBuffer);
|
if (pInst) LoadResource(*pInst, rBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CGameExporter::ShouldExportDiscNode(const nod::Node *pkNode, bool IsInRoot)
|
||||||
|
{
|
||||||
|
if (IsInRoot && mDiscType != eDT_Normal)
|
||||||
|
{
|
||||||
|
// Directories - exclude the filesystem for other games
|
||||||
|
if (pkNode->getKind() == nod::Node::Kind::Directory)
|
||||||
|
{
|
||||||
|
// Frontend is always included; this is for compatibility with Dolphin
|
||||||
|
if (pkNode->getName() == "fe")
|
||||||
|
return true;
|
||||||
|
|
||||||
|
else if (mFrontEnd)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (mGame)
|
||||||
|
{
|
||||||
|
case ePrime:
|
||||||
|
return ( (mDiscType == eDT_WiiDeAsobu && pkNode->getName() == "MP1JPN") ||
|
||||||
|
(mDiscType == eDT_Trilogy && pkNode->getName() == "MP1") );
|
||||||
|
|
||||||
|
case eEchoes:
|
||||||
|
return ( (mDiscType == eDT_WiiDeAsobu && pkNode->getName() == "MP2JPN") ||
|
||||||
|
(mDiscType == eDT_Trilogy && pkNode->getName() == "MP2") );
|
||||||
|
|
||||||
|
case eCorruption:
|
||||||
|
return (mDiscType == eDT_Trilogy && pkNode->getName() == "MP3");
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Files - exclude the DOLs for other games
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Again - always include frontend. Always include opening.bnr as well.
|
||||||
|
if (pkNode->getName() == "rs5fe_p.dol" || pkNode->getName() == "opening.bnr")
|
||||||
|
return true;
|
||||||
|
|
||||||
|
else if (mFrontEnd)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (mGame)
|
||||||
|
{
|
||||||
|
case ePrime:
|
||||||
|
return ( (mDiscType == eDT_WiiDeAsobu && pkNode->getName() == "rs5mp1jpn_p.dol") ||
|
||||||
|
(mDiscType == eDT_Trilogy && pkNode->getName() == "rs5mp1_p.dol") );
|
||||||
|
|
||||||
|
case eEchoes:
|
||||||
|
return ( (mDiscType == eDT_WiiDeAsobu && pkNode->getName() == "rs5mp2jpn_p.dol") ||
|
||||||
|
(mDiscType == eDT_Trilogy && pkNode->getName() == "rs5mp2_p.dol") );
|
||||||
|
|
||||||
|
case eCorruption:
|
||||||
|
return (mDiscType == eDT_Trilogy && pkNode->getName() == "rs5mp3_p.dol");
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// ************ PROTECTED ************
|
// ************ PROTECTED ************
|
||||||
bool CGameExporter::ExtractDiscData()
|
bool CGameExporter::ExtractDiscData()
|
||||||
{
|
{
|
||||||
|
@ -122,7 +188,7 @@ bool CGameExporter::ExtractDiscData()
|
||||||
TString FilesDir = AbsDiscDir + "files/";
|
TString FilesDir = AbsDiscDir + "files/";
|
||||||
FileUtil::MakeDirectory(FilesDir);
|
FileUtil::MakeDirectory(FilesDir);
|
||||||
|
|
||||||
bool Success = ExtractDiscNodeRecursive(&pDataPartition->getFSTRoot(), FilesDir, Context);
|
bool Success = ExtractDiscNodeRecursive(&pDataPartition->getFSTRoot(), FilesDir, true, Context);
|
||||||
if (!Success) return false;
|
if (!Success) return false;
|
||||||
|
|
||||||
if (!mpProgress->ShouldCancel())
|
if (!mpProgress->ShouldCancel())
|
||||||
|
@ -150,18 +216,25 @@ bool CGameExporter::ExtractDiscData()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGameExporter::ExtractDiscNodeRecursive(const nod::Node *pkNode, const TString& rkDir, const nod::ExtractionContext& rkContext)
|
bool CGameExporter::ExtractDiscNodeRecursive(const nod::Node *pkNode, const TString& rkDir, bool RootNode, const nod::ExtractionContext& rkContext)
|
||||||
{
|
{
|
||||||
for (nod::Node::DirectoryIterator Iter = pkNode->begin(); Iter != pkNode->end(); ++Iter)
|
for (nod::Node::DirectoryIterator Iter = pkNode->begin(); Iter != pkNode->end(); ++Iter)
|
||||||
{
|
{
|
||||||
|
if (!ShouldExportDiscNode(&*Iter, RootNode))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (Iter->getKind() == nod::Node::Kind::File)
|
if (Iter->getKind() == nod::Node::Kind::File)
|
||||||
{
|
{
|
||||||
TString FilePath = rkDir + Iter->getName();
|
TString FilePath = rkDir + Iter->getName();
|
||||||
bool Success = Iter->extractToDirectory(*rkDir.ToUTF16(), rkContext);
|
bool Success = Iter->extractToDirectory(*rkDir.ToUTF16(), rkContext);
|
||||||
if (!Success) return false;
|
if (!Success) return false;
|
||||||
|
|
||||||
if (FilePath.GetFileExtension() == "pak")
|
if (FilePath.GetFileExtension().CaseInsensitiveCompare("pak"))
|
||||||
mPaks.push_back(FilePath);
|
{
|
||||||
|
// For multi-game Wii discs, don't track packages for frontend unless we're exporting frontend
|
||||||
|
if (mDiscType == eDT_Normal || mFrontEnd || pkNode->getName() != "fe")
|
||||||
|
mPaks.push_back(FilePath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -170,7 +243,7 @@ bool CGameExporter::ExtractDiscNodeRecursive(const nod::Node *pkNode, const TStr
|
||||||
bool Success = FileUtil::MakeDirectory(Subdir);
|
bool Success = FileUtil::MakeDirectory(Subdir);
|
||||||
if (!Success) return false;
|
if (!Success) return false;
|
||||||
|
|
||||||
Success = ExtractDiscNodeRecursive(&*Iter, Subdir, rkContext);
|
Success = ExtractDiscNodeRecursive(&*Iter, Subdir, false, rkContext);
|
||||||
if (!Success) return false;
|
if (!Success) return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,13 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <nod/nod.hpp>
|
#include <nod/nod.hpp>
|
||||||
|
|
||||||
|
enum EDiscType
|
||||||
|
{
|
||||||
|
eDT_Normal,
|
||||||
|
eDT_WiiDeAsobu,
|
||||||
|
eDT_Trilogy
|
||||||
|
};
|
||||||
|
|
||||||
class CGameExporter
|
class CGameExporter
|
||||||
{
|
{
|
||||||
// Project Data
|
// Project Data
|
||||||
|
@ -33,6 +40,8 @@ class CGameExporter
|
||||||
|
|
||||||
// Files
|
// Files
|
||||||
nod::DiscBase *mpDisc;
|
nod::DiscBase *mpDisc;
|
||||||
|
EDiscType mDiscType;
|
||||||
|
bool mFrontEnd;
|
||||||
|
|
||||||
// Resources
|
// Resources
|
||||||
TStringList mPaks;
|
TStringList mPaks;
|
||||||
|
@ -65,15 +74,16 @@ class CGameExporter
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CGameExporter(EGame Game, ERegion Region, const TString& rkGameName, const TString& rkGameID, float BuildVersion);
|
CGameExporter(EDiscType DiscType, EGame Game, bool FrontEnd, ERegion Region, const TString& rkGameName, const TString& rkGameID, float BuildVersion);
|
||||||
bool Export(nod::DiscBase *pDisc, const TString& rkOutputDir, CAssetNameMap *pNameMap, CGameInfo *pGameInfo, IProgressNotifier *pProgress);
|
bool Export(nod::DiscBase *pDisc, const TString& rkOutputDir, CAssetNameMap *pNameMap, CGameInfo *pGameInfo, IProgressNotifier *pProgress);
|
||||||
void LoadResource(const CAssetID& rkID, std::vector<u8>& rBuffer);
|
void LoadResource(const CAssetID& rkID, std::vector<u8>& rBuffer);
|
||||||
|
bool ShouldExportDiscNode(const nod::Node *pkNode, bool IsInRoot);
|
||||||
|
|
||||||
inline TString ProjectPath() const { return mProjectPath; }
|
inline TString ProjectPath() const { return mProjectPath; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool ExtractDiscData();
|
bool ExtractDiscData();
|
||||||
bool ExtractDiscNodeRecursive(const nod::Node *pkNode, const TString& rkDir, const nod::ExtractionContext& rkContext);
|
bool ExtractDiscNodeRecursive(const nod::Node *pkNode, const TString& rkDir, bool RootNode, const nod::ExtractionContext& rkContext);
|
||||||
void LoadPaks();
|
void LoadPaks();
|
||||||
void LoadResource(const SResourceInstance& rkResource, std::vector<u8>& rBuffer);
|
void LoadResource(const SResourceInstance& rkResource, std::vector<u8>& rBuffer);
|
||||||
void ExportCookedResources();
|
void ExportCookedResources();
|
||||||
|
|
|
@ -100,6 +100,7 @@ public:
|
||||||
inline float BuildVersion() const { return mBuildVersion; }
|
inline float BuildVersion() const { return mBuildVersion; }
|
||||||
inline bool IsWiiBuild() const { return mBuildVersion >= 3.f; }
|
inline bool IsWiiBuild() const { return mBuildVersion >= 3.f; }
|
||||||
inline bool IsTrilogy() const { return mGame <= eCorruption && mBuildVersion >= 3.593f; }
|
inline bool IsTrilogy() const { return mGame <= eCorruption && mBuildVersion >= 3.593f; }
|
||||||
|
inline bool IsWiiDeAsobu() const { return mGame < eCorruption && mBuildVersion >= 3.f && mBuildVersion < 3.593f; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CGAMEPROJECT_H
|
#endif // CGAMEPROJECT_H
|
||||||
|
|
|
@ -170,9 +170,14 @@ bool CVirtualDirectory::AddChild(const TString &rkPath, CResourceEntry *pEntry)
|
||||||
{
|
{
|
||||||
// Create new subdirectory
|
// Create new subdirectory
|
||||||
pSubdir = new CVirtualDirectory(this, DirName, mpStore);
|
pSubdir = new CVirtualDirectory(this, DirName, mpStore);
|
||||||
FileUtil::MakeDirectory(mpStore->ResourcesDir() + pSubdir->FullPath());
|
|
||||||
mSubdirectories.push_back(pSubdir);
|
|
||||||
|
|
||||||
|
if (!pSubdir->CreateFilesystemDirectory())
|
||||||
|
{
|
||||||
|
delete pSubdir;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mSubdirectories.push_back(pSubdir);
|
||||||
std::sort(mSubdirectories.begin(), mSubdirectories.end(), [](CVirtualDirectory *pLeft, CVirtualDirectory *pRight) -> bool {
|
std::sort(mSubdirectories.begin(), mSubdirectories.end(), [](CVirtualDirectory *pLeft, CVirtualDirectory *pRight) -> bool {
|
||||||
return (pLeft->Name().ToUpper() < pRight->Name().ToUpper());
|
return (pLeft->Name().ToUpper() < pRight->Name().ToUpper());
|
||||||
});
|
});
|
||||||
|
@ -184,6 +189,13 @@ bool CVirtualDirectory::AddChild(const TString &rkPath, CResourceEntry *pEntry)
|
||||||
for (auto Iter = Components.begin(); Iter != Components.end(); Iter++)
|
for (auto Iter = Components.begin(); Iter != Components.end(); Iter++)
|
||||||
{
|
{
|
||||||
pSubdir = new CVirtualDirectory(pSubdir, *Iter, mpStore);
|
pSubdir = new CVirtualDirectory(pSubdir, *Iter, mpStore);
|
||||||
|
|
||||||
|
if (!pSubdir->CreateFilesystemDirectory())
|
||||||
|
{
|
||||||
|
delete pSubdir;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
pSubdir->Parent()->mSubdirectories.push_back(pSubdir);
|
pSubdir->Parent()->mSubdirectories.push_back(pSubdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,6 +319,23 @@ void CVirtualDirectory::DeleteEmptySubdirectories()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CVirtualDirectory::CreateFilesystemDirectory()
|
||||||
|
{
|
||||||
|
TString AbsPath = AbsolutePath();
|
||||||
|
|
||||||
|
if (!FileUtil::Exists(AbsPath))
|
||||||
|
{
|
||||||
|
bool CreateSuccess = FileUtil::MakeDirectory(AbsPath);
|
||||||
|
|
||||||
|
if (!CreateSuccess)
|
||||||
|
Log::Error("FAILED to create filesystem directory: " + AbsPath);
|
||||||
|
|
||||||
|
return CreateSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool CVirtualDirectory::SetParent(CVirtualDirectory *pParent)
|
bool CVirtualDirectory::SetParent(CVirtualDirectory *pParent)
|
||||||
{
|
{
|
||||||
ASSERT(!pParent->IsDescendantOf(this));
|
ASSERT(!pParent->IsDescendantOf(this));
|
||||||
|
|
|
@ -39,6 +39,7 @@ public:
|
||||||
bool Rename(const TString& rkNewName);
|
bool Rename(const TString& rkNewName);
|
||||||
bool Delete();
|
bool Delete();
|
||||||
void DeleteEmptySubdirectories();
|
void DeleteEmptySubdirectories();
|
||||||
|
bool CreateFilesystemDirectory();
|
||||||
bool SetParent(CVirtualDirectory *pParent);
|
bool SetParent(CVirtualDirectory *pParent);
|
||||||
|
|
||||||
static bool IsValidDirectoryName(const TString& rkName);
|
static bool IsValidDirectoryName(const TString& rkName);
|
||||||
|
|
|
@ -21,9 +21,13 @@
|
||||||
CExportGameDialog::CExportGameDialog(const QString& rkIsoPath, const QString& rkExportDir, QWidget *pParent /*= 0*/)
|
CExportGameDialog::CExportGameDialog(const QString& rkIsoPath, const QString& rkExportDir, QWidget *pParent /*= 0*/)
|
||||||
: QDialog(pParent)
|
: QDialog(pParent)
|
||||||
, mpUI(new Ui::CExportGameDialog)
|
, mpUI(new Ui::CExportGameDialog)
|
||||||
|
, mpDisc(nullptr)
|
||||||
|
, mpExporter(nullptr)
|
||||||
|
, mDiscType(eDT_Normal)
|
||||||
, mGame(eUnknownGame)
|
, mGame(eUnknownGame)
|
||||||
, mRegion(eRegion_Unknown)
|
, mRegion(eRegion_Unknown)
|
||||||
, mTrilogy(false)
|
, mBuildVer(0.f)
|
||||||
|
, mWiiFrontend(false)
|
||||||
, mExportSuccess(false)
|
, mExportSuccess(false)
|
||||||
{
|
{
|
||||||
mpUI->setupUi(this);
|
mpUI->setupUi(this);
|
||||||
|
@ -35,25 +39,19 @@ CExportGameDialog::CExportGameDialog(const QString& rkIsoPath, const QString& rk
|
||||||
if (ValidateGame())
|
if (ValidateGame())
|
||||||
{
|
{
|
||||||
mBuildVer = FindBuildVersion();
|
mBuildVer = FindBuildVersion();
|
||||||
|
mpExporter = new CGameExporter(mDiscType, mGame, mWiiFrontend, mRegion, mGameTitle, mGameID, mBuildVer);
|
||||||
InitUI(rkExportDir);
|
InitUI(rkExportDir);
|
||||||
|
|
||||||
TString IsoName = TO_TSTRING(rkIsoPath).GetFileName();
|
TString IsoName = TO_TSTRING(rkIsoPath).GetFileName();
|
||||||
setWindowTitle(QString("Export Settings - %1").arg( TO_QSTRING(IsoName) ));
|
setWindowTitle(QString("Export Settings - %1").arg( TO_QSTRING(IsoName) ));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!mTrilogy)
|
|
||||||
UICommon::ErrorMsg(this, "Invalid ISO!");
|
|
||||||
|
|
||||||
delete mpDisc;
|
|
||||||
mpDisc = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CExportGameDialog::~CExportGameDialog()
|
CExportGameDialog::~CExportGameDialog()
|
||||||
{
|
{
|
||||||
delete mpUI;
|
delete mpUI;
|
||||||
delete mpDisc;
|
delete mpDisc;
|
||||||
|
delete mpExporter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecursiveAddToTree(const nod::Node *pkNode, QTreeWidgetItem *pParent);
|
void RecursiveAddToTree(const nod::Node *pkNode, QTreeWidgetItem *pParent);
|
||||||
|
@ -89,13 +87,12 @@ void CExportGameDialog::InitUI(QString ExportDir)
|
||||||
nod::Partition *pPartition = mpDisc->getDataPartition();
|
nod::Partition *pPartition = mpDisc->getDataPartition();
|
||||||
ASSERT(pPartition);
|
ASSERT(pPartition);
|
||||||
|
|
||||||
const nod::Node *pkDiscRoot = &pPartition->getFSTRoot();
|
|
||||||
if (mTrilogy)
|
|
||||||
pkDiscRoot = &*pkDiscRoot->find( GetGameShortName(mGame).ToStdString() );
|
|
||||||
|
|
||||||
QTreeWidgetItem *pTreeRoot = new QTreeWidgetItem((QTreeWidgetItem*) nullptr, QStringList(QString("Disc")));
|
QTreeWidgetItem *pTreeRoot = new QTreeWidgetItem((QTreeWidgetItem*) nullptr, QStringList(QString("Disc")));
|
||||||
mpUI->DiscFstTreeWidget->addTopLevelItem(pTreeRoot);
|
mpUI->DiscFstTreeWidget->addTopLevelItem(pTreeRoot);
|
||||||
|
|
||||||
|
const nod::Node *pkDiscRoot = &pPartition->getFSTRoot();
|
||||||
RecursiveAddToTree(pkDiscRoot, pTreeRoot);
|
RecursiveAddToTree(pkDiscRoot, pTreeRoot);
|
||||||
|
|
||||||
pTreeRoot->setIcon(0, QIcon(":/icons/Disc_16px.png"));
|
pTreeRoot->setIcon(0, QIcon(":/icons/Disc_16px.png"));
|
||||||
pTreeRoot->setExpanded(true);
|
pTreeRoot->setExpanded(true);
|
||||||
|
|
||||||
|
@ -175,14 +172,28 @@ bool CExportGameDialog::ValidateGame()
|
||||||
|
|
||||||
case FOURCC('R3MX'):
|
case FOURCC('R3MX'):
|
||||||
// Trilogy
|
// Trilogy
|
||||||
mTrilogy = true;
|
mDiscType = eDT_Trilogy;
|
||||||
if (!RequestTrilogyGame()) return false;
|
if (!RequestWiiPortGame()) return false;
|
||||||
|
|
||||||
|
// Force change game name so it isn't "Metroid Prime Trilogy"
|
||||||
|
if (!mWiiFrontend)
|
||||||
|
mGameTitle = GetGameName(mGame);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FOURCC('R3IX'):
|
case FOURCC('R3IX'):
|
||||||
// MP1 Wii de Asobu
|
// MP1 Wii de Asobu
|
||||||
|
mGame = ePrime;
|
||||||
|
mDiscType = eDT_WiiDeAsobu;
|
||||||
|
if (!RequestWiiPortGame()) return false;
|
||||||
|
break;
|
||||||
|
|
||||||
case FOURCC('R32X'):
|
case FOURCC('R32X'):
|
||||||
// MP2 Wii de Asobu
|
mGame = eEchoes;
|
||||||
|
mDiscType = eDT_WiiDeAsobu;
|
||||||
|
if (!RequestWiiPortGame()) return false;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Unrecognized game ID
|
// Unrecognized game ID
|
||||||
return false;
|
return false;
|
||||||
|
@ -191,16 +202,25 @@ bool CExportGameDialog::ValidateGame()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CExportGameDialog::RequestTrilogyGame()
|
bool CExportGameDialog::RequestWiiPortGame()
|
||||||
{
|
{
|
||||||
QDialog Dialog;
|
QDialog Dialog;
|
||||||
Dialog.setWindowTitle("Select Trilogy Game");
|
Dialog.setWindowTitle("Select Game");
|
||||||
|
|
||||||
|
bool IsTrilogy = (mGame == eUnknownGame);
|
||||||
|
bool HasMP1 = (IsTrilogy || mGame == ePrime);
|
||||||
|
bool HasMP2 = (IsTrilogy || mGame == eEchoes);
|
||||||
|
bool HasMP3 = IsTrilogy;
|
||||||
|
|
||||||
|
QString GameName = (IsTrilogy ? "Metroid Prime: Trilogy" : "Wii de Asobu");
|
||||||
|
QString LabelText = QString("You have selected a %1 ISO. Please pick a game to export:").arg(GameName);
|
||||||
|
QLabel Label(LabelText, &Dialog);
|
||||||
|
|
||||||
QLabel Label("You have selected a Metroid Prime: Trilogy ISO. Please pick a game to export:", &Dialog);
|
|
||||||
QComboBox ComboBox(&Dialog);
|
QComboBox ComboBox(&Dialog);
|
||||||
ComboBox.addItem("Metroid Prime");
|
ComboBox.addItem("Front End");
|
||||||
ComboBox.addItem("Metroid Prime 2: Echoes");
|
if (HasMP1) ComboBox.addItem("Metroid Prime");
|
||||||
ComboBox.addItem("Metroid Prime 3: Corruption");
|
if (HasMP2) ComboBox.addItem("Metroid Prime 2: Echoes");
|
||||||
|
if (HasMP3) ComboBox.addItem("Metroid Prime 3: Corruption");
|
||||||
QDialogButtonBox ButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &Dialog);
|
QDialogButtonBox ButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &Dialog);
|
||||||
connect(&ButtonBox, SIGNAL(accepted()), &Dialog, SLOT(accept()));
|
connect(&ButtonBox, SIGNAL(accepted()), &Dialog, SLOT(accept()));
|
||||||
connect(&ButtonBox, SIGNAL(rejected()), &Dialog, SLOT(reject()));
|
connect(&ButtonBox, SIGNAL(rejected()), &Dialog, SLOT(reject()));
|
||||||
|
@ -217,10 +237,24 @@ bool CExportGameDialog::RequestTrilogyGame()
|
||||||
{
|
{
|
||||||
switch (ComboBox.currentIndex())
|
switch (ComboBox.currentIndex())
|
||||||
{
|
{
|
||||||
case 0: mGame = ePrime; break;
|
case 0:
|
||||||
case 1: mGame = eEchoes; break;
|
mGame = eCorruption;
|
||||||
case 2: mGame = eCorruption; break;
|
mWiiFrontend = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
mGame = (HasMP1 ? ePrime : eEchoes);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
mGame = eEchoes;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
mGame = eCorruption;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else return false;
|
else return false;
|
||||||
|
@ -263,7 +297,7 @@ float CExportGameDialog::FindBuildVersion()
|
||||||
return 0.f;
|
return 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecursiveAddToTree(const nod::Node *pkNode, QTreeWidgetItem *pParent)
|
void CExportGameDialog::RecursiveAddToTree(const nod::Node *pkNode, QTreeWidgetItem *pParent)
|
||||||
{
|
{
|
||||||
// Get sorted list of nodes
|
// Get sorted list of nodes
|
||||||
std::list<const nod::Node*> NodeList;
|
std::list<const nod::Node*> NodeList;
|
||||||
|
@ -285,6 +319,10 @@ void RecursiveAddToTree(const nod::Node *pkNode, QTreeWidgetItem *pParent)
|
||||||
for (auto Iter = NodeList.begin(); Iter != NodeList.end(); Iter++)
|
for (auto Iter = NodeList.begin(); Iter != NodeList.end(); Iter++)
|
||||||
{
|
{
|
||||||
const nod::Node *pkNode = *Iter;
|
const nod::Node *pkNode = *Iter;
|
||||||
|
|
||||||
|
if (!mpExporter->ShouldExportDiscNode(pkNode, pParent->parent() == nullptr))
|
||||||
|
continue;
|
||||||
|
|
||||||
bool IsDir = pkNode->getKind() == nod::Node::Kind::Directory;
|
bool IsDir = pkNode->getKind() == nod::Node::Kind::Directory;
|
||||||
|
|
||||||
QTreeWidgetItem *pItem = new QTreeWidgetItem(pParent, QStringList(QString::fromStdString(pkNode->getName())) );
|
QTreeWidgetItem *pItem = new QTreeWidgetItem(pParent, QStringList(QString::fromStdString(pkNode->getName())) );
|
||||||
|
@ -382,12 +420,11 @@ void CExportGameDialog::Export()
|
||||||
// Do export
|
// Do export
|
||||||
close();
|
close();
|
||||||
|
|
||||||
CGameExporter Exporter(mGame, mRegion, mGameTitle, mGameID, mBuildVer);
|
|
||||||
TString StrExportDir = TO_TSTRING(ExportDir);
|
TString StrExportDir = TO_TSTRING(ExportDir);
|
||||||
StrExportDir.EnsureEndsWith('/');
|
StrExportDir.EnsureEndsWith('/');
|
||||||
|
|
||||||
CProgressDialog Dialog("Creating new game project", false, true, parentWidget());
|
CProgressDialog Dialog("Creating new game project", false, true, parentWidget());
|
||||||
QFuture<bool> Future = QtConcurrent::run(&Exporter, &CGameExporter::Export, mpDisc, StrExportDir, &NameMap, &GameInfo, &Dialog);
|
QFuture<bool> Future = QtConcurrent::run(mpExporter, &CGameExporter::Export, mpDisc, StrExportDir, &NameMap, &GameInfo, &Dialog);
|
||||||
mExportSuccess = Dialog.WaitForResults(Future);
|
mExportSuccess = Dialog.WaitForResults(Future);
|
||||||
|
|
||||||
if (!mExportSuccess)
|
if (!mExportSuccess)
|
||||||
|
@ -396,5 +433,5 @@ void CExportGameDialog::Export()
|
||||||
UICommon::ErrorMsg(this, "Export failed!");
|
UICommon::ErrorMsg(this, "Export failed!");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mNewProjectPath = TO_QSTRING(Exporter.ProjectPath());
|
mNewProjectPath = TO_QSTRING(mpExporter->ProjectPath());
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define CEXPORTGAMEDIALOG_H
|
#define CEXPORTGAMEDIALOG_H
|
||||||
|
|
||||||
#include <Common/EGame.h>
|
#include <Common/EGame.h>
|
||||||
|
#include <Core/GameProject/CGameExporter.h>
|
||||||
#include <Core/GameProject/CGameProject.h>
|
#include <Core/GameProject/CGameProject.h>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
@ -17,13 +18,17 @@ class CExportGameDialog : public QDialog
|
||||||
|
|
||||||
Ui::CExportGameDialog *mpUI;
|
Ui::CExportGameDialog *mpUI;
|
||||||
nod::DiscBase *mpDisc;
|
nod::DiscBase *mpDisc;
|
||||||
|
CGameExporter *mpExporter;
|
||||||
|
|
||||||
TString mGameTitle;
|
TString mGameTitle;
|
||||||
TString mGameID;
|
TString mGameID;
|
||||||
|
|
||||||
|
// Build Info
|
||||||
|
EDiscType mDiscType;
|
||||||
EGame mGame;
|
EGame mGame;
|
||||||
ERegion mRegion;
|
ERegion mRegion;
|
||||||
float mBuildVer;
|
float mBuildVer;
|
||||||
bool mTrilogy;
|
bool mWiiFrontend;
|
||||||
|
|
||||||
bool mExportSuccess;
|
bool mExportSuccess;
|
||||||
QString mNewProjectPath;
|
QString mNewProjectPath;
|
||||||
|
@ -34,9 +39,12 @@ public:
|
||||||
|
|
||||||
void InitUI(QString ExportDir);
|
void InitUI(QString ExportDir);
|
||||||
bool ValidateGame();
|
bool ValidateGame();
|
||||||
bool RequestTrilogyGame();
|
bool RequestWiiPortGame();
|
||||||
float FindBuildVersion();
|
float FindBuildVersion();
|
||||||
|
|
||||||
|
// Disc Tree
|
||||||
|
void RecursiveAddToTree(const nod::Node *pkNode, class QTreeWidgetItem *pParent);
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
inline bool HasValidDisc() const { return mpDisc != nullptr; }
|
inline bool HasValidDisc() const { return mpDisc != nullptr; }
|
||||||
inline bool ExportSucceeded() const { return mExportSuccess; }
|
inline bool ExportSucceeded() const { return mExportSuccess; }
|
||||||
|
|
|
@ -18,15 +18,19 @@ CProgressDialog::CProgressDialog(QString OperationName, bool UseBusyIndicator, b
|
||||||
|
|
||||||
#if WIN32
|
#if WIN32
|
||||||
QWinTaskbarButton *pButton = new QWinTaskbarButton(this);
|
QWinTaskbarButton *pButton = new QWinTaskbarButton(this);
|
||||||
QWindow *pWindow = parentWidget()->windowHandle();
|
QWindow *pWindow = UICommon::FindWidgetWindowHandle( parentWidget() );
|
||||||
ASSERT(pWindow);
|
|
||||||
pButton->setWindow(pWindow);
|
|
||||||
|
|
||||||
mpTaskbarProgress = pButton->progress();
|
|
||||||
mpTaskbarProgress->setMinimum(0);
|
|
||||||
mpTaskbarProgress->setMaximum(UseBusyIndicator ? 0 : 10000);
|
|
||||||
mpTaskbarProgress->show();
|
|
||||||
|
|
||||||
|
if (pWindow)
|
||||||
|
{
|
||||||
|
pButton->setWindow(pWindow);
|
||||||
|
mpTaskbarProgress = pButton->progress();
|
||||||
|
mpTaskbarProgress->setMinimum(0);
|
||||||
|
mpTaskbarProgress->setMaximum(UseBusyIndicator ? 0 : 10000);
|
||||||
|
mpTaskbarProgress->show();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mpTaskbarProgress = nullptr;
|
||||||
|
|
||||||
setWindowFlags(windowFlags() | Qt::MSWindowsFixedSizeDialogHint);
|
setWindowFlags(windowFlags() | Qt::MSWindowsFixedSizeDialogHint);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -60,8 +64,11 @@ void CProgressDialog::closeEvent(QCloseEvent *pEvent)
|
||||||
pEvent->accept();
|
pEvent->accept();
|
||||||
|
|
||||||
#if WIN32
|
#if WIN32
|
||||||
mpTaskbarProgress->reset();
|
if (mpTaskbarProgress)
|
||||||
mpTaskbarProgress->hide();
|
{
|
||||||
|
mpTaskbarProgress->reset();
|
||||||
|
mpTaskbarProgress->hide();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,7 +109,8 @@ void CProgressDialog::UpdateUI(const QString& rkTaskDesc, const QString& rkStepD
|
||||||
mpUI->ProgressBar->setValue(ProgressValue);
|
mpUI->ProgressBar->setValue(ProgressValue);
|
||||||
|
|
||||||
#if WIN32
|
#if WIN32
|
||||||
mpTaskbarProgress->setValue(ProgressValue);
|
if (mpTaskbarProgress)
|
||||||
|
mpTaskbarProgress->setValue(ProgressValue);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,7 @@ public:
|
||||||
for (u32 Shift = 0; Shift <= MaxShift; Shift += 4)
|
for (u32 Shift = 0; Shift <= MaxShift; Shift += 4)
|
||||||
{
|
{
|
||||||
u64 ShiftCompare = mCompareID << Shift;
|
u64 ShiftCompare = mCompareID << Shift;
|
||||||
u32 Mask = mCompareMask << Shift;
|
u64 Mask = mCompareMask << Shift;
|
||||||
|
|
||||||
if ((ID & Mask) == ShiftCompare)
|
if ((ID & Mask) == ShiftCompare)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,14 @@
|
||||||
namespace UICommon
|
namespace UICommon
|
||||||
{
|
{
|
||||||
|
|
||||||
|
QWindow* FindWidgetWindowHandle(QWidget *pWidget)
|
||||||
|
{
|
||||||
|
while (pWidget && !pWidget->windowHandle())
|
||||||
|
pWidget = pWidget->parentWidget();
|
||||||
|
|
||||||
|
return pWidget ? pWidget->windowHandle() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void OpenContainingFolder(const QString& rkPath)
|
void OpenContainingFolder(const QString& rkPath)
|
||||||
{
|
{
|
||||||
#if WIN32
|
#if WIN32
|
||||||
|
|
|
@ -40,6 +40,7 @@ namespace UICommon
|
||||||
{
|
{
|
||||||
|
|
||||||
// Utility
|
// Utility
|
||||||
|
QWindow* FindWidgetWindowHandle(QWidget *pWidget);
|
||||||
void OpenContainingFolder(const QString& rkPath);
|
void OpenContainingFolder(const QString& rkPath);
|
||||||
bool OpenInExternalApplication(const QString& rkPath);
|
bool OpenInExternalApplication(const QString& rkPath);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue