mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-05-30 03:01:32 +00:00
Added support for saving/loading game projects
This commit is contained in:
parent
f55b3666a0
commit
12bd4eff90
@ -1,6 +1,7 @@
|
|||||||
#include "CGameExporter.h"
|
#include "CGameExporter.h"
|
||||||
#include "Core/GameProject/CResourceStore.h"
|
#include "Core/GameProject/CResourceStore.h"
|
||||||
#include "Core/Resource/CWorld.h"
|
#include "Core/Resource/CWorld.h"
|
||||||
|
#include "Core/Resource/Script/CMasterTemplate.h"
|
||||||
#include <FileIO/FileIO.h>
|
#include <FileIO/FileIO.h>
|
||||||
#include <Common/AssertMacro.h>
|
#include <Common/AssertMacro.h>
|
||||||
#include <Common/CompressionUtil.h>
|
#include <Common/CompressionUtil.h>
|
||||||
@ -8,11 +9,11 @@
|
|||||||
#include <Common/FileUtil.h>
|
#include <Common/FileUtil.h>
|
||||||
#include <tinyxml2.h>
|
#include <tinyxml2.h>
|
||||||
|
|
||||||
#define COPY_DISC_DATA 0
|
#define COPY_DISC_DATA 1
|
||||||
#define LOAD_PAKS 1
|
#define LOAD_PAKS 1
|
||||||
#define SAVE_PACKAGE_DEFINITIONS 1
|
#define SAVE_PACKAGE_DEFINITIONS 1
|
||||||
#define EXPORT_WORLDS 0
|
#define EXPORT_WORLDS 1
|
||||||
#define EXPORT_COOKED 0
|
#define EXPORT_COOKED 1
|
||||||
|
|
||||||
CGameExporter::CGameExporter(const TString& rkInputDir, const TString& rkOutputDir)
|
CGameExporter::CGameExporter(const TString& rkInputDir, const TString& rkOutputDir)
|
||||||
: mStore(this)
|
: mStore(this)
|
||||||
@ -91,12 +92,7 @@ void CGameExporter::CopyDiscData()
|
|||||||
|
|
||||||
// Detect paks
|
// Detect paks
|
||||||
if (FullPath.GetFileExtension().ToLower() == L"pak")
|
if (FullPath.GetFileExtension().ToLower() == L"pak")
|
||||||
{
|
mPaks.push_back(FullPath);
|
||||||
if (FullPath.GetFileName(false).StartsWith(L"Metroid", false) || RelPath.Contains(L"Worlds", false))
|
|
||||||
mWorldPaks.push_back(FullPath);
|
|
||||||
else
|
|
||||||
mResourcePaks.push_back(FullPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if COPY_DISC_DATA
|
#if COPY_DISC_DATA
|
||||||
// Create directory
|
// Create directory
|
||||||
@ -110,6 +106,8 @@ void CGameExporter::CopyDiscData()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(Game() != eUnknownVersion);
|
ASSERT(Game() != eUnknownVersion);
|
||||||
|
mpProject->SetGame(Game());
|
||||||
|
mpProject->SetProjectName(CMasterTemplate::FindGameName(Game()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameExporter::LoadAssetList()
|
void CGameExporter::LoadAssetList()
|
||||||
@ -168,14 +166,9 @@ void CGameExporter::LoadPaks()
|
|||||||
{
|
{
|
||||||
#if LOAD_PAKS
|
#if LOAD_PAKS
|
||||||
SCOPED_TIMER(LoadPaks);
|
SCOPED_TIMER(LoadPaks);
|
||||||
|
|
||||||
for (u32 iList = 0; iList < 2; iList++)
|
|
||||||
{
|
|
||||||
const TWideStringList& rkList = (iList == 0 ? mWorldPaks : mResourcePaks);
|
|
||||||
bool IsWorldPak = (iList == 0);
|
|
||||||
EUIDLength IDLength = (Game() < eCorruptionProto ? e32Bit : e64Bit);
|
EUIDLength IDLength = (Game() < eCorruptionProto ? e32Bit : e64Bit);
|
||||||
|
|
||||||
for (auto It = rkList.begin(); It != rkList.end(); It++)
|
for (auto It = mPaks.begin(); It != mPaks.end(); It++)
|
||||||
{
|
{
|
||||||
TWideString PakPath = *It;
|
TWideString PakPath = *It;
|
||||||
TString CharPak = PakPath.ToUTF8();
|
TString CharPak = PakPath.ToUTF8();
|
||||||
@ -296,12 +289,11 @@ void CGameExporter::LoadPaks()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add package to project and save
|
// Add package to project and save
|
||||||
mpProject->AddPackage(pPackage, IsWorldPak);
|
mpProject->AddPackage(pPackage);
|
||||||
#if SAVE_PACKAGE_DEFINITIONS
|
#if SAVE_PACKAGE_DEFINITIONS
|
||||||
pPackage->Save();
|
pPackage->Save();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,9 +398,9 @@ void CGameExporter::ExportWorlds()
|
|||||||
#if EXPORT_WORLDS
|
#if EXPORT_WORLDS
|
||||||
SCOPED_TIMER(ExportWorlds);
|
SCOPED_TIMER(ExportWorlds);
|
||||||
|
|
||||||
for (u32 iPak = 0; iPak < mpProject->NumWorldPaks(); iPak++)
|
for (u32 iPak = 0; iPak < mpProject->NumPackages(); iPak++)
|
||||||
{
|
{
|
||||||
CPackage *pPak = mpProject->WorldPakByIndex(iPak);
|
CPackage *pPak = mpProject->PackageByIndex(iPak);
|
||||||
|
|
||||||
// Get output path. DKCR paks are stored in a Worlds folder so we should get the path relative to that so we don't have Worlds\Worlds\.
|
// Get output path. DKCR paks are stored in a Worlds folder so we should get the path relative to that so we don't have Worlds\Worlds\.
|
||||||
// Other games have all paks in the game root dir so we're fine just taking the original root dir-relative directory.
|
// Other games have all paks in the game root dir so we're fine just taking the original root dir-relative directory.
|
||||||
@ -460,20 +452,11 @@ void CGameExporter::ExportWorlds()
|
|||||||
if (pTable) GameAreaName = pTable->String("ENGL", 0);
|
if (pTable) GameAreaName = pTable->String("ENGL", 0);
|
||||||
if (GameAreaName.IsEmpty()) GameAreaName = InternalAreaName;
|
if (GameAreaName.IsEmpty()) GameAreaName = InternalAreaName;
|
||||||
|
|
||||||
// Load area
|
|
||||||
CUniqueID AreaID = pWorld->AreaResourceID(iArea);
|
|
||||||
CGameArea *pArea = (CGameArea*) mStore.LoadResource(AreaID, "MREA");
|
|
||||||
|
|
||||||
if (!pArea)
|
|
||||||
{
|
|
||||||
Log::Error("Unable to export area " + GameAreaName.ToUTF8() + " from world " + rkRes.Name + "; couldn't load area");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Export area
|
// Export area
|
||||||
TWideString AreaDir = WorldDir + TWideString::FromInt32(iArea, 2, 10) + L"_" + FileUtil::SanitizeName(GameAreaName, true) + L"\\";
|
TWideString AreaDir = WorldDir + TWideString::FromInt32(iArea, 2, 10) + L"_" + FileUtil::SanitizeName(GameAreaName, true) + L"\\";
|
||||||
FileUtil::CreateDirectory(mCookedDir + AreaDir);
|
FileUtil::CreateDirectory(mCookedDir + AreaDir);
|
||||||
|
|
||||||
|
CUniqueID AreaID = pWorld->AreaResourceID(iArea);
|
||||||
SResourceInstance *pInst = FindResourceInstance(AreaID);
|
SResourceInstance *pInst = FindResourceInstance(AreaID);
|
||||||
ASSERT(pInst != nullptr);
|
ASSERT(pInst != nullptr);
|
||||||
|
|
||||||
@ -483,11 +466,6 @@ void CGameExporter::ExportWorlds()
|
|||||||
|
|
||||||
mStore.DestroyUnreferencedResources();
|
mStore.DestroyUnreferencedResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log::Error("Unexpected named resource type in world pak: " + rkRes.Type.ToString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -506,11 +484,14 @@ void CGameExporter::ExportCookedResources()
|
|||||||
ExportResource(rRes);
|
ExportResource(rRes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
SCOPED_TIMER(SaveResourceDatabase);
|
SCOPED_TIMER(SaveResourceDatabase);
|
||||||
|
#if EXPORT_COOKED
|
||||||
mStore.SaveResourceDatabase(this->mExportDir.ToUTF8() + "ResourceDatabase.rdb");
|
mStore.SaveResourceDatabase(this->mExportDir.ToUTF8() + "ResourceDatabase.rdb");
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
mpProject->Save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameExporter::ExportResource(SResourceInstance& rRes)
|
void CGameExporter::ExportResource(SResourceInstance& rRes)
|
||||||
|
@ -25,8 +25,7 @@ class CGameExporter
|
|||||||
TWideString mWorldsDirName;
|
TWideString mWorldsDirName;
|
||||||
|
|
||||||
// Resources
|
// Resources
|
||||||
TWideStringList mWorldPaks;
|
TWideStringList mPaks;
|
||||||
TWideStringList mResourcePaks;
|
|
||||||
|
|
||||||
struct SResourceInstance
|
struct SResourceInstance
|
||||||
{
|
{
|
||||||
|
@ -1,10 +1,103 @@
|
|||||||
#include "CGameProject.h"
|
#include "CGameProject.h"
|
||||||
|
#include "Core/Resource/Script/CMasterTemplate.h"
|
||||||
|
#include <tinyxml2.h>
|
||||||
|
|
||||||
void CGameProject::AddPackage(CPackage *pPackage, bool WorldPak)
|
using namespace tinyxml2;
|
||||||
|
|
||||||
|
void CGameProject::Load()
|
||||||
{
|
{
|
||||||
if (WorldPak)
|
TString ProjPath = ProjectPath().ToUTF8();
|
||||||
mWorldPaks.push_back(pPackage);
|
XMLDocument Doc;
|
||||||
|
Doc.LoadFile(*ProjPath);
|
||||||
|
|
||||||
|
if (Doc.Error())
|
||||||
|
{
|
||||||
|
Log::Error("Unable to open game project at " + ProjPath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
XMLElement *pRoot = Doc.FirstChildElement("GameProject");
|
||||||
|
//EProjectVersion Version = (EProjectVersion) TString(pRoot->Attribute("Version")).ToInt32(10);
|
||||||
|
|
||||||
|
// Verify all elements are present
|
||||||
|
XMLElement *pProjName = pRoot->FirstChildElement("Name");
|
||||||
|
XMLElement *pGame = pRoot->FirstChildElement("Game");
|
||||||
|
XMLElement *pResDB = pRoot->FirstChildElement("ResourceDB");
|
||||||
|
XMLElement *pPackages = pRoot->FirstChildElement("Packages");
|
||||||
|
|
||||||
|
if (!pProjName || !pGame || !pResDB || !pPackages)
|
||||||
|
{
|
||||||
|
TString MissingElem = pProjName ? (pGame ? (pResDB ? "Packages" : "ResourceDB") : "Game") : "Name";
|
||||||
|
Log::Error("Unable to load game project at " + ProjPath + "; " + MissingElem + " element is missing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mProjectName = pProjName->GetText();
|
||||||
|
mGame = CMasterTemplate::FindGameForName( pGame->GetText() );
|
||||||
|
mResourceDBPath = pResDB->GetText();
|
||||||
|
|
||||||
|
// Load packages
|
||||||
|
XMLElement *pPkgElem = pPackages->FirstChildElement("Package");
|
||||||
|
|
||||||
|
while (pPkgElem)
|
||||||
|
{
|
||||||
|
pPkgElem = pPkgElem->NextSiblingElement("Package");
|
||||||
|
TString Path = pPkgElem->Attribute("Path");
|
||||||
|
|
||||||
|
if (Path.IsEmpty())
|
||||||
|
Log::Error("Failed to load package in game project " + ProjPath + "; Path attribute is missing or empty");
|
||||||
|
|
||||||
else
|
else
|
||||||
mResourcePaks.push_back(pPackage);
|
{
|
||||||
|
CPackage *pPackage = new CPackage(this, Path.GetFileName(false), TString(Path.GetFileDirectory()).ToUTF16());
|
||||||
|
pPackage->Load();
|
||||||
|
mPackages.push_back(pPackage);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGameProject::Save()
|
||||||
|
{
|
||||||
|
XMLDocument Doc;
|
||||||
|
|
||||||
|
XMLDeclaration *pDecl = Doc.NewDeclaration();
|
||||||
|
Doc.LinkEndChild(pDecl);
|
||||||
|
|
||||||
|
XMLElement *pRoot = Doc.NewElement("GameProject");
|
||||||
|
pRoot->SetAttribute("Version", eVer_Current);
|
||||||
|
Doc.LinkEndChild(pRoot);
|
||||||
|
|
||||||
|
XMLElement *pProjName = Doc.NewElement("Name");
|
||||||
|
pProjName->SetText(*mProjectName);
|
||||||
|
pRoot->LinkEndChild(pProjName);
|
||||||
|
|
||||||
|
XMLElement *pGame = Doc.NewElement("Game");
|
||||||
|
pGame->SetText(*CMasterTemplate::FindGameName(mGame));
|
||||||
|
pRoot->LinkEndChild(pGame);
|
||||||
|
|
||||||
|
XMLElement *pResDB = Doc.NewElement("ResourceDB");
|
||||||
|
pResDB->SetText(*mResourceDBPath.ToUTF8());
|
||||||
|
pRoot->LinkEndChild(pResDB);
|
||||||
|
|
||||||
|
XMLElement *pPackages = Doc.NewElement("Packages");
|
||||||
|
pRoot->LinkEndChild(pPackages);
|
||||||
|
|
||||||
|
for (u32 iPkg = 0; iPkg < mPackages.size(); iPkg++)
|
||||||
|
{
|
||||||
|
CPackage *pPackage = mPackages[iPkg];
|
||||||
|
TWideString FullDefPath = pPackage->DefinitionPath(false);
|
||||||
|
TWideString RelDefPath = FileUtil::MakeRelative(FullDefPath.GetFileDirectory(), PackagesDir(false));
|
||||||
|
TString DefPath = TWideString(RelDefPath + FullDefPath.GetFileName()).ToUTF8();
|
||||||
|
|
||||||
|
XMLElement *pPakElem = Doc.NewElement("Package");
|
||||||
|
pPakElem->SetAttribute("Path", *DefPath);
|
||||||
|
pPackages->LinkEndChild(pPakElem);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save Project
|
||||||
|
TString ProjPath = ProjectPath().ToUTF8();
|
||||||
|
XMLError Result = Doc.SaveFile(*ProjPath);
|
||||||
|
|
||||||
|
if (Result != XML_SUCCESS)
|
||||||
|
Log::Error("Failed to save game project at: " + ProjPath);
|
||||||
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "CPackage.h"
|
#include "CPackage.h"
|
||||||
#include "CResourceStore.h"
|
#include "CResourceStore.h"
|
||||||
#include "Core/Resource/EGame.h"
|
#include "Core/Resource/EGame.h"
|
||||||
|
#include <Common/FileUtil.h>
|
||||||
#include <Common/CUniqueID.h>
|
#include <Common/CUniqueID.h>
|
||||||
#include <Common/TString.h>
|
#include <Common/TString.h>
|
||||||
#include <Common/types.h>
|
#include <Common/types.h>
|
||||||
@ -14,18 +15,25 @@ class CGameProject
|
|||||||
TString mProjectName;
|
TString mProjectName;
|
||||||
TWideString mProjectRoot;
|
TWideString mProjectRoot;
|
||||||
TWideString mResourceDBPath;
|
TWideString mResourceDBPath;
|
||||||
std::vector<CPackage*> mWorldPaks;
|
std::vector<CPackage*> mPackages;
|
||||||
std::vector<CPackage*> mResourcePaks;
|
|
||||||
|
|
||||||
|
enum EProjectVersion
|
||||||
|
{
|
||||||
|
eVer_Initial,
|
||||||
|
|
||||||
|
eVer_Max,
|
||||||
|
eVer_Current = eVer_Max - 1
|
||||||
|
};
|
||||||
public:
|
public:
|
||||||
CGameProject(const TWideString& rkProjRootDir)
|
CGameProject(const TWideString& rkProjRootDir)
|
||||||
: mGame(eUnknownVersion)
|
: mGame(eUnknownVersion)
|
||||||
, mProjectName("UnnamedProject")
|
, mProjectName("Unnamed Project")
|
||||||
, mProjectRoot(rkProjRootDir)
|
, mProjectRoot(rkProjRootDir)
|
||||||
, mResourceDBPath(L"ResourceDB.rdb")
|
, mResourceDBPath(L"ResourceDB.rdb")
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void AddPackage(CPackage *pPackage, bool WorldPak);
|
void Load();
|
||||||
|
void Save();
|
||||||
|
|
||||||
// Directory Handling
|
// Directory Handling
|
||||||
inline TWideString ProjectRoot() const { return mProjectRoot; }
|
inline TWideString ProjectRoot() const { return mProjectRoot; }
|
||||||
@ -34,13 +42,15 @@ public:
|
|||||||
inline TWideString ContentDir(bool Relative) const { return Relative ? L"Content\\" : mProjectRoot + L"Content\\"; }
|
inline TWideString ContentDir(bool Relative) const { return Relative ? L"Content\\" : mProjectRoot + L"Content\\"; }
|
||||||
inline TWideString CookedDir(bool Relative) const { return Relative ? L"Cooked\\" : mProjectRoot + L"Cooked\\"; }
|
inline TWideString CookedDir(bool Relative) const { return Relative ? L"Cooked\\" : mProjectRoot + L"Cooked\\"; }
|
||||||
inline TWideString PackagesDir(bool Relative) const { return Relative ? L"Packages\\" : mProjectRoot + L"Packages\\"; }
|
inline TWideString PackagesDir(bool Relative) const { return Relative ? L"Packages\\" : mProjectRoot + L"Packages\\"; }
|
||||||
|
inline TWideString ProjectPath() const { return mProjectRoot + FileUtil::SanitizeName(mProjectName.ToUTF16(), false) + L".prj"; }
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
inline void SetGame(EGame Game) { mGame = Game; }
|
inline void SetGame(EGame Game) { mGame = Game; }
|
||||||
inline void SetProjectName(const TString& rkName) { mProjectName = rkName; }
|
inline void SetProjectName(const TString& rkName) { mProjectName = rkName; }
|
||||||
|
|
||||||
inline u32 NumWorldPaks() const { return mWorldPaks.size(); }
|
inline u32 NumPackages() const { return mPackages.size(); }
|
||||||
inline CPackage* WorldPakByIndex(u32 Index) const { return mWorldPaks[Index]; }
|
inline CPackage* PackageByIndex(u32 Index) const { return mPackages[Index]; }
|
||||||
|
inline void AddPackage(CPackage *pPackage) { mPackages.push_back(pPackage); }
|
||||||
|
|
||||||
inline EGame Game() const { return mGame; }
|
inline EGame Game() const { return mGame; }
|
||||||
};
|
};
|
||||||
|
@ -119,6 +119,26 @@ std::list<CMasterTemplate*> CMasterTemplate::MasterList()
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TString CMasterTemplate::FindGameName(EGame Game)
|
||||||
|
{
|
||||||
|
CMasterTemplate *pMaster = MasterForGame(Game);
|
||||||
|
return pMaster ? pMaster->GameName() : "Unknown Game";
|
||||||
|
}
|
||||||
|
|
||||||
|
EGame CMasterTemplate::FindGameForName(const TString& rkName)
|
||||||
|
{
|
||||||
|
std::list<CMasterTemplate*> Masters = MasterList();
|
||||||
|
|
||||||
|
for (auto It = Masters.begin(); It != Masters.end(); It++)
|
||||||
|
{
|
||||||
|
CMasterTemplate *pMaster = *It;
|
||||||
|
if (pMaster->GameName() == rkName)
|
||||||
|
return pMaster->Game();
|
||||||
|
}
|
||||||
|
|
||||||
|
return eUnknownVersion;
|
||||||
|
}
|
||||||
|
|
||||||
TString CMasterTemplate::PropertyName(u32 PropertyID)
|
TString CMasterTemplate::PropertyName(u32 PropertyID)
|
||||||
{
|
{
|
||||||
auto it = smPropertyNames.find(PropertyID);
|
auto it = smPropertyNames.find(PropertyID);
|
||||||
|
@ -51,17 +51,20 @@ public:
|
|||||||
CStructTemplate* StructAtSource(const TString& rkSource);
|
CStructTemplate* StructAtSource(const TString& rkSource);
|
||||||
|
|
||||||
// Inline Accessors
|
// Inline Accessors
|
||||||
EGame Game() const { return mGame; }
|
inline EGame Game() const { return mGame; }
|
||||||
u32 NumGameVersions() const { return mGameVersions.empty() ? 1 : mGameVersions.size(); }
|
inline TString GameName() const { return mGameName; }
|
||||||
u32 NumScriptTemplates() const { return mTemplates.size(); }
|
inline u32 NumGameVersions() const { return mGameVersions.empty() ? 1 : mGameVersions.size(); }
|
||||||
u32 NumStates() const { return mStates.size(); }
|
inline u32 NumScriptTemplates() const { return mTemplates.size(); }
|
||||||
u32 NumMessages() const { return mMessages.size(); }
|
inline u32 NumStates() const { return mStates.size(); }
|
||||||
bool IsLoadedSuccessfully() { return mFullyLoaded; }
|
inline u32 NumMessages() const { return mMessages.size(); }
|
||||||
TString GetDirectory() const { return mSourceFile.GetFileDirectory(); }
|
inline bool IsLoadedSuccessfully() { return mFullyLoaded; }
|
||||||
|
inline TString GetDirectory() const { return mSourceFile.GetFileDirectory(); }
|
||||||
|
|
||||||
// Static
|
// Static
|
||||||
static CMasterTemplate* MasterForGame(EGame Game);
|
static CMasterTemplate* MasterForGame(EGame Game);
|
||||||
static std::list<CMasterTemplate*> MasterList();
|
static std::list<CMasterTemplate*> MasterList();
|
||||||
|
static TString FindGameName(EGame Game);
|
||||||
|
static EGame FindGameForName(const TString& rkName);
|
||||||
static TString PropertyName(u32 PropertyID);
|
static TString PropertyName(u32 PropertyID);
|
||||||
static u32 CreatePropertyID(IPropertyTemplate *pTemp);
|
static u32 CreatePropertyID(IPropertyTemplate *pTemp);
|
||||||
static void AddProperty(IPropertyTemplate *pTemp, const TString& rkTemplateName = "");
|
static void AddProperty(IPropertyTemplate *pTemp, const TString& rkTemplateName = "");
|
||||||
|
@ -274,6 +274,14 @@ void CStartWindow::ExportGame()
|
|||||||
if (ExportDir.isEmpty()) return;
|
if (ExportDir.isEmpty()) return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Verify valid game root by checking if opening.bnr exists
|
||||||
|
TString OpeningBNR = TO_TSTRING(GameRoot) + "/opening.bnr";
|
||||||
|
if (!FileUtil::Exists(OpeningBNR.ToUTF16()))
|
||||||
|
{
|
||||||
|
QMessageBox::warning(this, "Error", "Error; this is not a valid game root directory!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CGameExporter Exporter(TO_TSTRING(GameRoot), TO_TSTRING(ExportDir));
|
CGameExporter Exporter(TO_TSTRING(GameRoot), TO_TSTRING(ExportDir));
|
||||||
Exporter.Export();
|
Exporter.Export();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user