mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-12-16 08:27:01 +00:00
Added support for bitfield properties
This commit is contained in:
@@ -58,6 +58,21 @@ CPropertyStruct* CScriptLoader::LoadStructMP1(CInputStream& SCLY, CStructTemplat
|
||||
pProp = new CLongProperty(v);
|
||||
break;
|
||||
}
|
||||
case eBitfieldProperty: {
|
||||
long v = SCLY.ReadLong();
|
||||
pProp = new CBitfieldProperty(v);
|
||||
|
||||
// Validate
|
||||
u32 mask = 0;
|
||||
CBitfieldTemplate *pBitfieldTemp = static_cast<CBitfieldTemplate*>(pPropTmp);
|
||||
for (u32 iMask = 0; iMask < pBitfieldTemp->NumFlags(); iMask++)
|
||||
mask |= pBitfieldTemp->FlagMask(iMask);
|
||||
|
||||
u32 check = v & ~mask;
|
||||
if (check != 0) Log::FileWarning(SCLY.GetSourceString(), SCLY.Tell() - 4, "Bitfield property \"" + pBitfieldTemp->Name() + "\" in struct \"" + pTemp->Name() + "\" has flags set that aren't in the template: " + StringUtil::ToHexString(check, true, true, 8));
|
||||
|
||||
break;
|
||||
}
|
||||
case eEnumProperty: {
|
||||
CEnumTemplate *pEnumTemp = static_cast<CEnumTemplate*>(pPropTmp);
|
||||
u32 ID = SCLY.ReadLong();
|
||||
@@ -273,6 +288,22 @@ void CScriptLoader::LoadStructMP2(CInputStream& SCLY, CPropertyStruct *pStruct,
|
||||
break;
|
||||
}
|
||||
|
||||
case eBitfieldProperty: {
|
||||
CBitfieldProperty *pBitfieldCast = static_cast<CBitfieldProperty*>(pProp);
|
||||
pBitfieldCast->Set(SCLY.ReadLong());
|
||||
|
||||
// Validate
|
||||
u32 mask = 0;
|
||||
CBitfieldTemplate *pBitfieldTemp = static_cast<CBitfieldTemplate*>(pPropTemp);
|
||||
for (u32 iMask = 0; iMask < pBitfieldTemp->NumFlags(); iMask++)
|
||||
mask |= pBitfieldTemp->FlagMask(iMask);
|
||||
|
||||
u32 check = pBitfieldCast->Get() & ~mask;
|
||||
if (check != 0) Log::FileWarning(SCLY.GetSourceString(), SCLY.Tell() - 4, "Bitfield property \"" + pBitfieldTemp->Name() + "\" in struct \"" + pTemp->Name() + "\" has flags set that aren't in the template: " + StringUtil::ToHexString(check, true, true, 8));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case eEnumProperty: {
|
||||
CEnumProperty *pEnumCast = static_cast<CEnumProperty*>(pProp);
|
||||
CEnumTemplate *pEnumTemp = static_cast<CEnumTemplate*>(pPropTemp);
|
||||
|
||||
@@ -2,6 +2,31 @@
|
||||
#include "CWorldLoader.h"
|
||||
#include <Core/Log.h>
|
||||
|
||||
void CTemplateLoader::LoadBitFlags(tinyxml2::XMLElement *pElem, CBitfieldTemplate *pTemp, const std::string& templateName)
|
||||
{
|
||||
tinyxml2::XMLElement *pChild = pElem->FirstChildElement("bitflag");
|
||||
|
||||
while (pChild)
|
||||
{
|
||||
const char *kpMask = pChild->Attribute("mask");
|
||||
const char *kpName = pChild->Attribute("name");
|
||||
|
||||
if (kpMask && kpName)
|
||||
pTemp->mBitFlags.push_back(CBitfieldTemplate::SBitFlag(kpName, StringUtil::ToInt32(kpMask)));
|
||||
|
||||
else
|
||||
{
|
||||
std::string LogErrorBase = "Couldn't parse bit flag in " + templateName + "; ";
|
||||
|
||||
if (!kpMask && kpName) Log::Error(LogErrorBase + "no mask (" + kpName + ")");
|
||||
else if (kpMask && !kpName) Log::Error(LogErrorBase + "no name (mask " + kpMask + ")");
|
||||
else Log::Error(LogErrorBase + "no valid ID or name");
|
||||
}
|
||||
|
||||
pChild = pChild->NextSiblingElement("bitflag");
|
||||
}
|
||||
}
|
||||
|
||||
void CTemplateLoader::LoadEnumerators(tinyxml2::XMLElement *pElem, CEnumTemplate *pTemp, const std::string& templateName)
|
||||
{
|
||||
tinyxml2::XMLElement *pChild = pElem->FirstChildElement("enumerator");
|
||||
@@ -18,8 +43,8 @@ void CTemplateLoader::LoadEnumerators(tinyxml2::XMLElement *pElem, CEnumTemplate
|
||||
{
|
||||
std::string LogErrorBase = "Couldn't parse enumerator in " + templateName + "; ";
|
||||
|
||||
if (!kpID && kpName) Log::Error(LogErrorBase + "no valid ID (" + kpName + ")");
|
||||
if (kpID && !kpName) Log::Error(LogErrorBase + "no valid name (ID " + kpID + ")");
|
||||
if (!kpID && kpName) Log::Error(LogErrorBase + "no valid ID (" + kpName + ")");
|
||||
else if (kpID && !kpName) Log::Error(LogErrorBase + "no valid name (ID " + kpID + ")");
|
||||
else Log::Error(LogErrorBase + "no valid ID or name");
|
||||
}
|
||||
|
||||
@@ -193,15 +218,54 @@ CPropertyTemplate* CTemplateLoader::LoadPropertyTemplate(tinyxml2::XMLElement *p
|
||||
|
||||
LoadEnumerators(pRoot, pEnum, kpTemplateStr );
|
||||
}
|
||||
|
||||
// Name
|
||||
if (!name.empty())
|
||||
pEnum->mPropName = name;
|
||||
|
||||
return pEnum;
|
||||
}
|
||||
|
||||
// Name
|
||||
if (!name.empty())
|
||||
pEnum->mPropName = name;
|
||||
|
||||
return pEnum;
|
||||
}
|
||||
|
||||
|
||||
// Load Bitfield
|
||||
else if (strcmp(pElem->Name(), "bitfield") == 0)
|
||||
{
|
||||
CBitfieldTemplate *pBitfield = new CBitfieldTemplate(ID);
|
||||
|
||||
// Embedded
|
||||
if (!pElem->NoChildren())
|
||||
LoadBitFlags(pElem, pBitfield, templateName);
|
||||
|
||||
// Template
|
||||
else if (kpTemplateStr)
|
||||
{
|
||||
std::string tempPath = mMasterDir + kpTemplateStr;
|
||||
|
||||
tinyxml2::XMLDocument bitfieldXML;
|
||||
bitfieldXML.LoadFile(tempPath.c_str());
|
||||
|
||||
if (bitfieldXML.Error())
|
||||
Log::Error("Couldn't open bitfield XML: " + mMasterDir + kpTemplateStr);
|
||||
|
||||
else
|
||||
{
|
||||
tinyxml2::XMLElement *pRoot = bitfieldXML.FirstChildElement("bitfield");
|
||||
pBitfield->mSourceFile = kpTemplateStr;
|
||||
|
||||
if (pRoot->Attribute("name"))
|
||||
pBitfield->mPropName = pRoot->Attribute("name");
|
||||
|
||||
LoadBitFlags(pRoot, pBitfield, kpTemplateStr);
|
||||
}
|
||||
}
|
||||
|
||||
// Name
|
||||
if (!name.empty())
|
||||
pBitfield->mPropName = name;
|
||||
|
||||
return pBitfield;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ class CTemplateLoader
|
||||
CTemplateLoader(const std::string& templatesDir) : mTemplatesDir(templatesDir) {}
|
||||
|
||||
// Load Property
|
||||
void LoadBitFlags(tinyxml2::XMLElement *pElem, CBitfieldTemplate *pTemp, const std::string& templateName);
|
||||
void LoadEnumerators(tinyxml2::XMLElement *pElem, CEnumTemplate *pTemp, const std::string& templateName);
|
||||
void LoadStructProperties(tinyxml2::XMLElement *pElem, CStructTemplate *pTemp, const std::string& templateName);
|
||||
CPropertyTemplate* LoadPropertyTemplate(tinyxml2::XMLElement *pElem, const std::string& templateName);
|
||||
|
||||
Reference in New Issue
Block a user