mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-12-17 17:05:37 +00:00
Added project overview dialog with placeholder UI to allow loading worlds through a game project
This commit is contained in:
@@ -460,7 +460,7 @@ void CGameExporter::ExportWorlds()
|
||||
SResourceInstance *pInst = FindResourceInstance(AreaID);
|
||||
ASSERT(pInst != nullptr);
|
||||
|
||||
SetResourcePath(AreaID, AreaDir, HasInternalName ? InternalAreaName : GameAreaName);
|
||||
SetResourcePath(AreaID, AreaDir, GameAreaName);
|
||||
ExportResource(*pInst);
|
||||
}
|
||||
|
||||
@@ -488,7 +488,7 @@ void CGameExporter::ExportCookedResources()
|
||||
{
|
||||
SCOPED_TIMER(SaveResourceDatabase);
|
||||
#if EXPORT_COOKED
|
||||
mStore.SaveResourceDatabase(this->mExportDir.ToUTF8() + "ResourceDatabase.rdb");
|
||||
mStore.SaveResourceDatabase(mpProject->ResourceDBPath(false).ToUTF8());
|
||||
#endif
|
||||
mpProject->Save();
|
||||
}
|
||||
|
||||
@@ -3,17 +3,27 @@
|
||||
#include <tinyxml2.h>
|
||||
|
||||
using namespace tinyxml2;
|
||||
CGameProject *CGameProject::mspActiveProject = nullptr;
|
||||
|
||||
void CGameProject::Load()
|
||||
CGameProject::~CGameProject()
|
||||
{
|
||||
TString ProjPath = ProjectPath().ToUTF8();
|
||||
if (IsActive())
|
||||
{
|
||||
mspActiveProject = nullptr;
|
||||
gpResourceStore->SetActiveProject(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
bool CGameProject::Load(const TWideString& rkPath)
|
||||
{
|
||||
TString ProjPath = rkPath.ToUTF8();
|
||||
XMLDocument Doc;
|
||||
Doc.LoadFile(*ProjPath);
|
||||
|
||||
if (Doc.Error())
|
||||
{
|
||||
Log::Error("Unable to open game project at " + ProjPath);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
XMLElement *pRoot = Doc.FirstChildElement("GameProject");
|
||||
@@ -29,7 +39,7 @@ void CGameProject::Load()
|
||||
{
|
||||
TString MissingElem = pProjName ? (pGame ? (pResDB ? "Packages" : "ResourceDB") : "Game") : "Name";
|
||||
Log::Error("Unable to load game project at " + ProjPath + "; " + MissingElem + " element is missing");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
mProjectName = pProjName->GetText();
|
||||
@@ -41,7 +51,6 @@ void CGameProject::Load()
|
||||
|
||||
while (pPkgElem)
|
||||
{
|
||||
pPkgElem = pPkgElem->NextSiblingElement("Package");
|
||||
TString Path = pPkgElem->Attribute("Path");
|
||||
|
||||
if (Path.IsEmpty())
|
||||
@@ -53,7 +62,13 @@ void CGameProject::Load()
|
||||
pPackage->Load();
|
||||
mPackages.push_back(pPackage);
|
||||
}
|
||||
|
||||
pPkgElem = pPkgElem->NextSiblingElement("Package");
|
||||
}
|
||||
|
||||
// All loaded!
|
||||
mProjectRoot = rkPath.GetFileDirectory();
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGameProject::Save()
|
||||
@@ -101,3 +116,33 @@ void CGameProject::Save()
|
||||
if (Result != XML_SUCCESS)
|
||||
Log::Error("Failed to save game project at: " + ProjPath);
|
||||
}
|
||||
|
||||
void CGameProject::SetActive()
|
||||
{
|
||||
if (mspActiveProject != this)
|
||||
{
|
||||
mspActiveProject = this;
|
||||
gpResourceStore->SetActiveProject(this);
|
||||
}
|
||||
}
|
||||
|
||||
void CGameProject::GetWorldList(std::list<CUniqueID>& rOut) const
|
||||
{
|
||||
for (u32 iPkg = 0; iPkg < mPackages.size(); iPkg++)
|
||||
{
|
||||
CPackage *pPkg = mPackages[iPkg];
|
||||
|
||||
for (u32 iCol = 0; iCol < pPkg->NumCollections(); iCol++)
|
||||
{
|
||||
CResourceCollection *pCol = pPkg->CollectionByIndex(iCol);
|
||||
|
||||
for (u32 iRes = 0; iRes < pCol->NumResources(); iRes++)
|
||||
{
|
||||
const SNamedResource& rkRes = pCol->ResourceByIndex(iRes);
|
||||
|
||||
if (rkRes.Type == "MLVL" && !rkRes.Name.EndsWith("NODEPEND"))
|
||||
rOut.push_back(rkRes.ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,15 @@ class CGameProject
|
||||
eVer_Max,
|
||||
eVer_Current = eVer_Max - 1
|
||||
};
|
||||
|
||||
static CGameProject *mspActiveProject;
|
||||
|
||||
public:
|
||||
CGameProject()
|
||||
: mGame(eUnknownVersion)
|
||||
, mProjectName("Unnamed Project")
|
||||
{}
|
||||
|
||||
CGameProject(const TWideString& rkProjRootDir)
|
||||
: mGame(eUnknownVersion)
|
||||
, mProjectName("Unnamed Project")
|
||||
@@ -32,8 +40,12 @@ public:
|
||||
, mResourceDBPath(L"ResourceDB.rdb")
|
||||
{}
|
||||
|
||||
void Load();
|
||||
~CGameProject();
|
||||
|
||||
bool Load(const TWideString& rkPath);
|
||||
void Save();
|
||||
void SetActive();
|
||||
void GetWorldList(std::list<CUniqueID>& rOut) const;
|
||||
|
||||
// Directory Handling
|
||||
inline TWideString ProjectRoot() const { return mProjectRoot; }
|
||||
@@ -53,6 +65,9 @@ public:
|
||||
inline void AddPackage(CPackage *pPackage) { mPackages.push_back(pPackage); }
|
||||
|
||||
inline EGame Game() const { return mGame; }
|
||||
inline bool IsActive() const { return mspActiveProject == this; }
|
||||
|
||||
static inline CGameProject* ActiveProject() { return mspActiveProject; }
|
||||
};
|
||||
|
||||
extern CGameProject *gpProject;
|
||||
|
||||
@@ -137,6 +137,7 @@ CResource* CResourceEntry::Load(IInputStream& rInput)
|
||||
default: mpResource = new CResource(this); break;
|
||||
}
|
||||
|
||||
mpStore->TrackLoadedResource(this);
|
||||
return mpResource;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,50 +49,21 @@ void CResourceStore::LoadResourceDatabase(const TString& rkPath)
|
||||
|
||||
while (pRes)
|
||||
{
|
||||
XMLElement *pChild = pRes->FirstChildElement();
|
||||
XMLElement *pID = pRes->FirstChildElement("ID");
|
||||
XMLElement *pType = pRes->FirstChildElement("Type");
|
||||
XMLElement *pDir = pRes->FirstChildElement("FileDir");
|
||||
XMLElement *pName = pRes->FirstChildElement("FileName");
|
||||
|
||||
bool HasID = false, HasType = false, HasDir = false, HasName = false;
|
||||
CUniqueID ID;
|
||||
EResType Type;
|
||||
TWideString FileDir;
|
||||
TWideString FileName;
|
||||
|
||||
while (pChild)
|
||||
if (pID && pType && pDir && pName)
|
||||
{
|
||||
TString NodeName = pChild->Name();
|
||||
|
||||
if (NodeName == "ID")
|
||||
{
|
||||
ID = CUniqueID::FromString(pChild->GetText());
|
||||
HasID = true;
|
||||
}
|
||||
|
||||
else if (NodeName == "Type")
|
||||
{
|
||||
Type = CResource::ResTypeForExtension(pChild->GetText());
|
||||
HasType = true;
|
||||
ASSERT(Type != eInvalidResType);
|
||||
}
|
||||
|
||||
else if (NodeName == "FileDir")
|
||||
{
|
||||
FileDir = pChild->GetText();
|
||||
HasDir = true;
|
||||
}
|
||||
|
||||
else if (NodeName == "FileName")
|
||||
{
|
||||
FileName = pChild->GetText();
|
||||
HasName = true;
|
||||
}
|
||||
|
||||
pChild = pChild->NextSiblingElement();
|
||||
}
|
||||
|
||||
if (HasID && HasType && HasDir && HasName)
|
||||
CUniqueID ID = CUniqueID::FromString(pID->GetText());
|
||||
EResType Type = CResource::ResTypeForExtension(pType->GetText());
|
||||
TWideString FileDir = pDir->GetText();
|
||||
TWideString FileName = pName->GetText();
|
||||
RegisterResource(ID, Type, FileDir, FileName);
|
||||
}
|
||||
else
|
||||
Log::Error("Error reading " + rkPath + ": Resource entry " + TString::FromInt32(ResIndex, 0, 10) + " is missing one or more components");
|
||||
Log::Error("Error reading " + rkPath + ": Resource entry " + TString::FromInt32(ResIndex, 0, 10) + " is missing one or more required components");
|
||||
|
||||
ResIndex++;
|
||||
pRes = pRes->NextSiblingElement("Resource");
|
||||
@@ -292,12 +263,6 @@ CResource* CResourceStore::LoadResource(const CUniqueID& rkID, const CFourCC& rk
|
||||
EResType Type = CResource::ResTypeForExtension(rkType);
|
||||
CResourceEntry *pEntry = RegisterTransientResource(Type, rkID);
|
||||
CResource *pRes = pEntry->Load(MemStream);
|
||||
|
||||
if (pRes)
|
||||
{
|
||||
mLoadedResources[rkID] = pEntry;
|
||||
}
|
||||
|
||||
return pRes;
|
||||
}
|
||||
|
||||
@@ -322,8 +287,7 @@ CResource* CResourceStore::LoadResource(const CUniqueID& rkID, const CFourCC& rk
|
||||
CFileInStream File(Path.ToStdString(), IOUtil::eBigEndian);
|
||||
CResource *pRes = pEntry->Load(File);
|
||||
|
||||
if (pRes) mLoadedResources[rkID] = pEntry;
|
||||
else DeleteResourceEntry(pEntry);
|
||||
if (!pRes) DeleteResourceEntry(pEntry);
|
||||
return pRes;
|
||||
}
|
||||
|
||||
@@ -371,15 +335,20 @@ CResource* CResourceStore::LoadResource(const TString& rkPath)
|
||||
|
||||
CResourceEntry *pEntry = RegisterTransientResource(Type, ID, Dir, Name);
|
||||
CResource *pRes = pEntry->Load(File);
|
||||
|
||||
if (pRes) mLoadedResources[ID] = pEntry;
|
||||
else DeleteResourceEntry(pEntry);
|
||||
if (!pRes) DeleteResourceEntry(pEntry);
|
||||
|
||||
mTransientLoadDir = OldTransientDir;
|
||||
|
||||
return pRes;
|
||||
}
|
||||
|
||||
void CResourceStore::TrackLoadedResource(CResourceEntry *pEntry)
|
||||
{
|
||||
ASSERT(pEntry->IsLoaded());
|
||||
ASSERT(mLoadedResources.find(pEntry->ID()) == mLoadedResources.end());
|
||||
mLoadedResources[pEntry->ID()] = pEntry;
|
||||
}
|
||||
|
||||
CFourCC CResourceStore::ResourceTypeByID(const CUniqueID& rkID, const TStringList& rkPossibleTypes) const
|
||||
{
|
||||
if (!rkID.IsValid()) return eInvalidResType;
|
||||
|
||||
@@ -54,6 +54,7 @@ public:
|
||||
|
||||
CResource* LoadResource(const CUniqueID& rkID, const CFourCC& rkType);
|
||||
CResource* LoadResource(const TString& rkPath);
|
||||
void TrackLoadedResource(CResourceEntry *pEntry);
|
||||
CFourCC ResourceTypeByID(const CUniqueID& rkID, const TStringList& rkPossibleTypes) const;
|
||||
void DestroyUnreferencedResources();
|
||||
bool DeleteResourceEntry(CResourceEntry *pEntry);
|
||||
|
||||
@@ -94,14 +94,7 @@ void CVirtualDirectory::AddChild(const TWideString &rkPath, CResourceEntry *pEnt
|
||||
if (rkPath.IsEmpty())
|
||||
{
|
||||
if (pEntry)
|
||||
{
|
||||
#if !PUBLIC_RELEASE
|
||||
for (u32 iRes = 0; iRes < mResources.size(); iRes++)
|
||||
ASSERT(mResources[iRes] != pEntry);
|
||||
#endif
|
||||
|
||||
mResources.push_back(pEntry);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user