Changed EGame to an enum class. Created NGameList and NPropertyMap to change how templates are managed/saved/loaded. Added support for property map keeping track of ID/type pairs.

This commit is contained in:
Aruki
2018-10-07 17:53:19 -06:00
parent 42d021e757
commit 84d689e104
108 changed files with 1074 additions and 1198 deletions

View File

@@ -35,14 +35,14 @@ void CAreaCooker::DetermineSectionNumbersPrime()
switch (mVersion)
{
case ePrimeDemo:
case ePrime:
case EGame::PrimeDemo:
case EGame::Prime:
GeometrySections = 1 + (7 * OriginalMeshCount); // Accounting for materials
break;
case eEchoesDemo:
case EGame::EchoesDemo:
GeometrySections = 2 + (9 * OriginalMeshCount); // Account for materials + AROT
break;
case eEchoes:
case EGame::Echoes:
GeometrySections = 3 + (9 * OriginalMeshCount); // Acount for materials + AROT + an unknown section
break;
}
@@ -52,13 +52,13 @@ void CAreaCooker::DetermineSectionNumbersPrime()
// Set section numbers
u32 SecNum = GeometrySections;
if (mVersion <= ePrime) mAROTSecNum = SecNum++;
if (mVersion >= eEchoesDemo) mFFFFSecNum = SecNum++;
if (mVersion <= EGame::Prime) mAROTSecNum = SecNum++;
if (mVersion >= EGame::EchoesDemo) mFFFFSecNum = SecNum++;
if (mVersion >= eEchoesDemo)
if (mVersion >= EGame::EchoesDemo)
{
mSCLYSecNum = SecNum;
SecNum += (mVersion >= eEchoes ? mpArea->mScriptLayers.size() : 1);
SecNum += (mVersion >= EGame::Echoes ? mpArea->mScriptLayers.size() : 1);
mSCGNSecNum = SecNum++;
}
else
@@ -70,7 +70,7 @@ void CAreaCooker::DetermineSectionNumbersPrime()
mVISISecNum = SecNum++;
mPATHSecNum = SecNum++;
if (mVersion >= eEchoesDemo)
if (mVersion >= EGame::EchoesDemo)
{
mPTLASecNum = SecNum++;
mEGMCSecNum = SecNum++;
@@ -98,18 +98,18 @@ void CAreaCooker::WritePrimeHeader(IOutputStream& rOut)
rOut.WriteLong(GetMREAVersion(mVersion));
mpArea->mTransform.Write(rOut);
rOut.WriteLong(mpArea->mOriginalWorldMeshCount);
if (mVersion >= eEchoes) rOut.WriteLong(mpArea->mScriptLayers.size());
if (mVersion >= EGame::Echoes) rOut.WriteLong(mpArea->mScriptLayers.size());
rOut.WriteLong(mpArea->mSectionDataBuffers.size());
rOut.WriteLong(mGeometrySecNum);
rOut.WriteLong(mSCLYSecNum);
if (mVersion >= eEchoesDemo) rOut.WriteLong(mSCGNSecNum);
if (mVersion >= EGame::EchoesDemo) rOut.WriteLong(mSCGNSecNum);
rOut.WriteLong(mCollisionSecNum);
rOut.WriteLong(mUnknownSecNum);
rOut.WriteLong(mLightsSecNum);
rOut.WriteLong(mVISISecNum);
rOut.WriteLong(mPATHSecNum);
if (mVersion <= ePrime) rOut.WriteLong(mAROTSecNum);
if (mVersion <= EGame::Prime) rOut.WriteLong(mAROTSecNum);
else
{
@@ -118,9 +118,9 @@ void CAreaCooker::WritePrimeHeader(IOutputStream& rOut)
rOut.WriteLong(mEGMCSecNum);
}
if (mVersion >= eEchoesDemo)
if (mVersion >= EGame::EchoesDemo)
{
if (mVersion >= eEchoes) rOut.WriteLong(mCompressedBlocks.size());
if (mVersion >= EGame::Echoes) rOut.WriteLong(mCompressedBlocks.size());
rOut.WriteToBoundary(32, 0);
}
@@ -128,7 +128,7 @@ void CAreaCooker::WritePrimeHeader(IOutputStream& rOut)
rOut.WriteLong(mSectionSizes[iSec]);
rOut.WriteToBoundary(32, 0);
if (mVersion >= eEchoes)
if (mVersion >= EGame::Echoes)
WriteCompressionHeader(rOut);
}
@@ -188,7 +188,7 @@ void CAreaCooker::WritePrimeSCLY(IOutputStream& rOut)
// This function covers both Prime 1 and the Echoes demo.
// The Echoes demo has a similar SCLY format but with minor layout differences and with SCGN.
rOut.WriteFourCC( FOURCC('SCLY') );
mVersion <= ePrime ? rOut.WriteLong(1) : rOut.WriteByte(1);
mVersion <= EGame::Prime ? rOut.WriteLong(1) : rOut.WriteByte(1);
u32 NumLayers = mpArea->mScriptLayers.size();
rOut.WriteLong(NumLayers);
@@ -227,7 +227,7 @@ void CAreaCooker::WritePrimeSCLY(IOutputStream& rOut)
FinishSection(false);
// SCGN
if (mVersion == eEchoesDemo)
if (mVersion == EGame::EchoesDemo)
{
rOut.WriteFourCC( FOURCC('SCGN') );
rOut.WriteByte(1);
@@ -327,7 +327,7 @@ void CAreaCooker::FinishSection(bool SingleSectionBlock)
mSectionSizes.push_back(SecSize);
// Only track compressed blocks for MP2+. Write everything to one block for MP1.
if (mVersion >= eEchoes)
if (mVersion >= EGame::Echoes)
{
// Finish the current block if this is a single section block OR if the new section would push the block over the size limit.
if (mCurBlock.NumSections > 0 && (mCurBlock.DecompressedSize + SecSize > kSizeThreshold || SingleSectionBlock))
@@ -350,8 +350,8 @@ void CAreaCooker::FinishBlock()
if (mCurBlock.NumSections == 0) return;
std::vector<u8> CompressedBuf(mCompressedData.Size() * 2);
bool EnableCompression = (mVersion >= eEchoes) && mpArea->mUsesCompression && !gkForceDisableCompression;
bool UseZlib = (mVersion == eReturns);
bool EnableCompression = (mVersion >= EGame::Echoes) && mpArea->mUsesCompression && !gkForceDisableCompression;
bool UseZlib = (mVersion == EGame::DKCReturns);
u32 CompressedSize = 0;
bool WriteCompressedData = false;
@@ -394,7 +394,7 @@ bool CAreaCooker::CookMREA(CGameArea *pArea, IOutputStream& rOut)
Cooker.mpArea = pArea;
Cooker.mVersion = pArea->Game();
if (Cooker.mVersion <= eEchoes)
if (Cooker.mVersion <= EGame::Echoes)
Cooker.DetermineSectionNumbersPrime();
else
Cooker.DetermineSectionNumbersCorruption();
@@ -413,13 +413,13 @@ bool CAreaCooker::CookMREA(CGameArea *pArea, IOutputStream& rOut)
}
// Write SCLY
if (Cooker.mVersion <= eEchoesDemo)
if (Cooker.mVersion <= EGame::EchoesDemo)
Cooker.WritePrimeSCLY(Cooker.mSectionData);
else
Cooker.WriteEchoesSCLY(Cooker.mSectionData);
// Write post-SCLY data sections
u32 PostSCLY = (Cooker.mVersion <= ePrime ? Cooker.mSCLYSecNum + 1 : Cooker.mSCGNSecNum + 1);
u32 PostSCLY = (Cooker.mVersion <= EGame::Prime ? Cooker.mSCLYSecNum + 1 : Cooker.mSCGNSecNum + 1);
for (u32 iSec = PostSCLY; iSec < pArea->mSectionDataBuffers.size(); iSec++)
{
if (iSec == Cooker.mModulesSecNum)
@@ -435,7 +435,7 @@ bool CAreaCooker::CookMREA(CGameArea *pArea, IOutputStream& rOut)
Cooker.FinishBlock();
// Write to actual file
if (Cooker.mVersion <= eEchoes)
if (Cooker.mVersion <= EGame::Echoes)
Cooker.WritePrimeHeader(rOut);
else
Cooker.WriteCorruptionHeader(rOut);
@@ -448,13 +448,13 @@ u32 CAreaCooker::GetMREAVersion(EGame Version)
{
switch (Version)
{
case ePrimeDemo: return 0xC;
case ePrime: return 0xF;
case eEchoesDemo: return 0x15;
case eEchoes: return 0x19;
case eCorruptionProto: return 0x1D;
case eCorruption: return 0x1E;
case eReturns: return 0x20;
default: return 0;
case EGame::PrimeDemo: return 0xC;
case EGame::Prime: return 0xF;
case EGame::EchoesDemo: return 0x15;
case EGame::Echoes: return 0x19;
case EGame::CorruptionProto: return 0x1D;
case EGame::Corruption: return 0x1E;
case EGame::DKCReturns: return 0x20;
default: return 0;
}
}

View File

@@ -161,7 +161,7 @@ void CMaterialCooker::WriteMaterialPrime(IOutputStream& rOut)
bool HasKonst = (NumKonst > 0);
u32 Flags;
if (mVersion <= ePrime)
if (mVersion <= EGame::Prime)
Flags = 0x1003;
else
Flags = 0x4002;
@@ -178,13 +178,13 @@ void CMaterialCooker::WriteMaterialPrime(IOutputStream& rOut)
// Vertex description
u32 VtxFlags = ConvertFromVertexDescription( mpMat->VtxDesc() );
if (mVersion < eEchoes)
if (mVersion < EGame::Echoes)
VtxFlags &= 0x00FFFFFF;
rOut.WriteLong(VtxFlags);
// Echoes unknowns
if (mVersion == eEchoes)
if (mVersion == EGame::Echoes)
{
rOut.WriteLong(mpMat->EchoesUnknownA());
rOut.WriteLong(mpMat->EchoesUnknownB());
@@ -359,10 +359,10 @@ void CMaterialCooker::WriteCookedMatSet(CMaterialSet *pSet, EGame Version, IOutp
switch (Version)
{
case ePrimeDemo:
case ePrime:
case eEchoesDemo:
case eEchoes:
case EGame::PrimeDemo:
case EGame::Prime:
case EGame::EchoesDemo:
case EGame::Echoes:
Cooker.WriteMatSetPrime(rOut);
break;
}
@@ -376,10 +376,10 @@ void CMaterialCooker::WriteCookedMaterial(CMaterial *pMat, EGame Version, IOutpu
switch (Version)
{
case ePrimeDemo:
case ePrime:
case eEchoesDemo:
case eEchoes:
case EGame::PrimeDemo:
case EGame::Prime:
case EGame::EchoesDemo:
case EGame::Echoes:
Cooker.WriteMaterialPrime(rOut);
break;
// TODO: Corruption/Uncooked

View File

@@ -168,7 +168,7 @@ void CModelCooker::WriteModelPrime(IOutputStream& rOut)
{
CVertex *pVert = &pPrimitive->Vertices[iVert];
if (mVersion == eEchoes)
if (mVersion == EGame::Echoes)
{
for (u32 iMtxAttribs = 0; iMtxAttribs < 8; iMtxAttribs++)
if (VtxAttribs & (ePosMtx << iMtxAttribs))
@@ -232,10 +232,10 @@ bool CModelCooker::CookCMDL(CModel *pModel, IOutputStream& rOut)
switch (pModel->Game())
{
case ePrimeDemo:
case ePrime:
case eEchoesDemo:
case eEchoes:
case EGame::PrimeDemo:
case EGame::Prime:
case EGame::EchoesDemo:
case EGame::Echoes:
Cooker.WriteModelPrime(rOut);
return true;
@@ -248,17 +248,17 @@ u32 CModelCooker::GetCMDLVersion(EGame Version)
{
switch (Version)
{
case ePrimeDemo:
case ePrime:
case EGame::PrimeDemo:
case EGame::Prime:
return 0x2;
case eEchoesDemo:
case EGame::EchoesDemo:
return 0x3;
case eEchoes:
case EGame::Echoes:
return 0x4;
case eCorruptionProto:
case eCorruption:
case EGame::CorruptionProto:
case EGame::Corruption:
return 0x5;
case eReturns:
case EGame::DKCReturns:
return 0xA;
default:
return 0;

View File

@@ -10,7 +10,7 @@ void CScriptCooker::WriteProperty(IOutputStream& rOut, IProperty* pProperty, boo
u32 SizeOffset = 0, PropStart = 0;
void* pData = (mpArrayItemData ? mpArrayItemData : mpObject->PropertyData());
if (mGame >= eEchoesDemo && !InAtomicStruct)
if (mGame >= EGame::EchoesDemo && !InAtomicStruct)
{
rOut.WriteLong(pProperty->ID());
SizeOffset = rOut.Tell();
@@ -143,7 +143,7 @@ void CScriptCooker::WriteProperty(IOutputStream& rOut, IProperty* pProperty, boo
}
else
{
if (mGame < eReturns)
if (mGame < EGame::DKCReturns)
{
rOut.WriteShort(0);
rOut.WriteLong(0);
@@ -190,7 +190,7 @@ void CScriptCooker::WriteProperty(IOutputStream& rOut, IProperty* pProperty, boo
if (!pStruct->IsAtomic())
{
if (mGame <= ePrime)
if (mGame <= EGame::Prime)
rOut.WriteLong(PropertiesToWrite.size());
else
rOut.WriteShort((u16) PropertiesToWrite.size());
@@ -238,7 +238,7 @@ void CScriptCooker::WriteInstance(IOutputStream& rOut, CScriptObject *pInstance)
// Note the format is pretty much the same between games; the main difference is a
// number of fields changed size between MP1 and 2, but they're still the same fields
bool IsPrime1 = (mGame <= ePrime);
bool IsPrime1 = (mGame <= EGame::Prime);
u32 ObjectType = pInstance->ObjectTypeID();
IsPrime1 ? rOut.WriteByte((u8) ObjectType) : rOut.WriteLong(ObjectType);
@@ -275,7 +275,7 @@ void CScriptCooker::WriteLayer(IOutputStream& rOut, CScriptLayer *pLayer)
{
ASSERT(pLayer->Area()->Game() == mGame);
rOut.WriteByte( mGame <= ePrime ? 0 : 1 ); // Version
rOut.WriteByte( mGame <= EGame::Prime ? 0 : 1 ); // Version
u32 InstanceCountOffset = rOut.Tell();
u32 NumWrittenInstances = 0;
@@ -291,7 +291,7 @@ void CScriptCooker::WriteLayer(IOutputStream& rOut, CScriptLayer *pLayer)
if (mWriteGeneratedSeparately)
{
// GenericCreature instances in DKCR always write to both SCLY and SCGN
if (mGame == eReturns && pInstance->ObjectTypeID() == FOURCC('GCTR'))
if (mGame == EGame::DKCReturns && pInstance->ObjectTypeID() == FOURCC('GCTR'))
mGeneratedObjects.push_back(pInstance);
// Instances receiving a Generate/Activate message (MP2) or a
@@ -302,7 +302,7 @@ void CScriptCooker::WriteLayer(IOutputStream& rOut, CScriptLayer *pLayer)
{
CLink *pLink = pInstance->Link(eIncoming, LinkIdx);
if (mGame <= eEchoes)
if (mGame <= EGame::Echoes)
{
if (pLink->State() == FOURCC('GRNT') && pLink->Message() == FOURCC('ACTV'))
{

View File

@@ -22,7 +22,7 @@ public:
: mGame(Game)
, mpObject(nullptr)
, mpArrayItemData(nullptr)
, mWriteGeneratedSeparately(WriteGeneratedObjectsSeparately && mGame >= eEchoesDemo)
, mWriteGeneratedSeparately(WriteGeneratedObjectsSeparately && mGame >= EGame::EchoesDemo)
{}
void WriteInstance(IOutputStream& rOut, CScriptObject *pInstance);

View File

@@ -22,15 +22,15 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
WorldNameID.Write(rMLVL);
if (Game == eEchoesDemo || Game == eEchoes)
if (Game == EGame::EchoesDemo || Game == EGame::Echoes)
{
DarkWorldNameID.Write(rMLVL);
}
if (Game >= eEchoesDemo && Game <= eCorruption)
if (Game >= EGame::EchoesDemo && Game <= EGame::Corruption)
{
rMLVL.WriteLong(pWorld->mTempleKeyWorldIndex);
}
if (Game == eReturns)
if (Game == EGame::DKCReturns)
{
const CWorld::STimeAttackData& rkData = pWorld->mTimeAttackData;
rMLVL.WriteBool(rkData.HasTimeAttack);
@@ -49,7 +49,7 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
DefaultSkyID.Write(rMLVL);
// Memory Relays
if (Game == ePrime)
if (Game == EGame::Prime)
{
rMLVL.WriteLong( pWorld->mMemoryRelays.size() );
@@ -65,7 +65,7 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
// Areas
rMLVL.WriteLong(pWorld->mAreas.size());
if (Game <= ePrime) rMLVL.WriteLong(1); // Unknown
if (Game <= EGame::Prime) rMLVL.WriteLong(1); // Unknown
std::set<CAssetID> AudioGroups;
for (u32 iArea = 0; iArea < pWorld->mAreas.size(); iArea++)
@@ -83,7 +83,7 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
rArea.AreaID.Write(rMLVL);
// Attached Areas
if (Game <= eCorruption)
if (Game <= EGame::Corruption)
{
rMLVL.WriteLong( rArea.AttachedAreaIDs.size() );
@@ -92,7 +92,7 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
}
// Dependencies
if (Game <= eEchoes)
if (Game <= EGame::Echoes)
{
std::list<CAssetID> Dependencies;
std::list<u32> LayerDependsOffsets;
@@ -117,7 +117,7 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
}
// Docks
if (Game <= eCorruption)
if (Game <= EGame::Corruption)
{
rMLVL.WriteLong( rArea.Docks.size() );
@@ -141,7 +141,7 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
}
// Module Dependencies
if (Game == eEchoesDemo || Game == eEchoes)
if (Game == EGame::EchoesDemo || Game == EGame::Echoes)
{
std::vector<TString> ModuleNames;
std::vector<u32> ModuleLayerOffsets;
@@ -160,15 +160,15 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
}
// Unknown
if (Game == eReturns)
if (Game == EGame::DKCReturns)
rMLVL.WriteLong(0);
// Internal Name
if (Game >= eEchoesDemo)
if (Game >= EGame::EchoesDemo)
rMLVL.WriteString(rArea.InternalName);
}
if (Game <= eCorruption)
if (Game <= EGame::Corruption)
{
// World Map
CAssetID MapWorldID = pWorld->mpMapWorld ? pWorld->mpMapWorld->ID() : CAssetID::skInvalidID32;
@@ -180,7 +180,7 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
}
// Audio Groups
if (Game <= ePrime)
if (Game <= EGame::Prime)
{
// Create sorted list of audio groups (sort by group ID)
std::vector<CAudioGroup*> SortedAudioGroups;
@@ -244,7 +244,7 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
rMLVL.WriteString(LayerNames[iLyr]);
// Layer Saved State IDs
if (Game >= eCorruption)
if (Game >= EGame::Corruption)
{
rMLVL.WriteLong(LayerStateIDs.size());
@@ -265,12 +265,12 @@ u32 CWorldCooker::GetMLVLVersion(EGame Version)
{
switch (Version)
{
case ePrimeDemo: return 0xD;
case ePrime: return 0x11;
case eEchoesDemo: return 0x14;
case eEchoes: return 0x17;
case eCorruption: return 0x19;
case eReturns: return 0x1B;
case EGame::PrimeDemo: return 0xD;
case EGame::Prime: return 0x11;
case EGame::EchoesDemo: return 0x14;
case EGame::Echoes: return 0x17;
case EGame::Corruption: return 0x19;
case EGame::DKCReturns: return 0x1B;
default: return 0;
}
}