mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-12-17 08:57:09 +00:00
Added support for Prime 3 package cooking
This commit is contained in:
@@ -1,11 +1,26 @@
|
||||
#include "CAreaCooker.h"
|
||||
#include "CScriptCooker.h"
|
||||
#include "Core/CompressionUtil.h"
|
||||
#include "Core/GameProject/DependencyListBuilders.h"
|
||||
#include <Common/Log.h>
|
||||
|
||||
const bool gkForceDisableCompression = false;
|
||||
const bool gkForceDisableCompression = true;
|
||||
|
||||
CAreaCooker::CAreaCooker()
|
||||
: mGeometrySecNum(-1)
|
||||
, mSCLYSecNum(-1)
|
||||
, mSCGNSecNum(-1)
|
||||
, mCollisionSecNum(-1)
|
||||
, mUnknownSecNum(-1)
|
||||
, mLightsSecNum(-1)
|
||||
, mVISISecNum(-1)
|
||||
, mPATHSecNum(-1)
|
||||
, mAROTSecNum(-1)
|
||||
, mFFFFSecNum(-1)
|
||||
, mPTLASecNum(-1)
|
||||
, mEGMCSecNum(-1)
|
||||
, mDepsSecNum(-1)
|
||||
, mModulesSecNum(-1)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -69,8 +84,10 @@ void CAreaCooker::DetermineSectionNumbersCorruption()
|
||||
for (u32 iNum = 0; iNum < mpArea->mSectionNumbers.size(); iNum++)
|
||||
{
|
||||
CGameArea::SSectionNumber& rNum = mpArea->mSectionNumbers[iNum];
|
||||
if (rNum.SectionID == "SOBJ") mSCLYSecNum = rNum.Index;
|
||||
if (rNum.SectionID == "SOBJ") mSCLYSecNum = rNum.Index;
|
||||
else if (rNum.SectionID == "SGEN") mSCGNSecNum = rNum.Index;
|
||||
else if (rNum.SectionID == "DEPS") mDepsSecNum = rNum.Index;
|
||||
else if (rNum.SectionID == "RSOS") mModulesSecNum = rNum.Index;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,6 +245,57 @@ void CAreaCooker::WriteEchoesSCLY(IOutputStream& rOut)
|
||||
FinishSection(true);
|
||||
}
|
||||
|
||||
void CAreaCooker::WriteDependencies(IOutputStream& rOut)
|
||||
{
|
||||
// Build dependency list
|
||||
std::list<CAssetID> Dependencies;
|
||||
std::list<u32> LayerOffsets;
|
||||
|
||||
CAreaDependencyListBuilder Builder(mpArea->Entry());
|
||||
Builder.BuildDependencyList(Dependencies, LayerOffsets);
|
||||
|
||||
// Write
|
||||
rOut.WriteLong(Dependencies.size());
|
||||
|
||||
for (auto Iter = Dependencies.begin(); Iter != Dependencies.end(); Iter++)
|
||||
{
|
||||
CAssetID ID = *Iter;
|
||||
CResourceEntry *pEntry = gpResourceStore->FindEntry(ID);
|
||||
ID.Write(rOut);
|
||||
pEntry->CookedExtension().Write(rOut);
|
||||
}
|
||||
|
||||
rOut.WriteLong(LayerOffsets.size());
|
||||
|
||||
for (auto Iter = LayerOffsets.begin(); Iter != LayerOffsets.end(); Iter++)
|
||||
rOut.WriteLong(*Iter);
|
||||
|
||||
FinishSection(false);
|
||||
}
|
||||
|
||||
void CAreaCooker::WriteModules(IOutputStream& rOut)
|
||||
{
|
||||
// Build module list
|
||||
std::vector<TString> ModuleNames;
|
||||
std::vector<u32> LayerOffsets;
|
||||
|
||||
CAreaDependencyTree *pAreaDeps = static_cast<CAreaDependencyTree*>(mpArea->Entry()->Dependencies());
|
||||
pAreaDeps->GetModuleDependencies(mpArea->Game(), ModuleNames, LayerOffsets);
|
||||
|
||||
// Write
|
||||
rOut.WriteLong(ModuleNames.size());
|
||||
|
||||
for (u32 ModuleIdx = 0; ModuleIdx < ModuleNames.size(); ModuleIdx++)
|
||||
rOut.WriteString( ModuleNames[ModuleIdx] );
|
||||
|
||||
rOut.WriteLong(LayerOffsets.size());
|
||||
|
||||
for (u32 OffsetIdx = 0; OffsetIdx < LayerOffsets.size(); OffsetIdx++)
|
||||
rOut.WriteLong(LayerOffsets[OffsetIdx]);
|
||||
|
||||
FinishSection(false);
|
||||
}
|
||||
|
||||
// ************ SECTION MANAGEMENT ************
|
||||
void CAreaCooker::AddSectionToBlock()
|
||||
{
|
||||
@@ -322,8 +390,14 @@ bool CAreaCooker::CookMREA(CGameArea *pArea, IOutputStream& rOut)
|
||||
// Write pre-SCLY data sections
|
||||
for (u32 iSec = 0; iSec < Cooker.mSCLYSecNum; iSec++)
|
||||
{
|
||||
Cooker.mSectionData.WriteBytes(pArea->mSectionDataBuffers[iSec].data(), pArea->mSectionDataBuffers[iSec].size());
|
||||
Cooker.FinishSection(false);
|
||||
if (iSec == Cooker.mDepsSecNum)
|
||||
Cooker.WriteDependencies(Cooker.mSectionData);
|
||||
|
||||
else
|
||||
{
|
||||
Cooker.mSectionData.WriteBytes(pArea->mSectionDataBuffers[iSec].data(), pArea->mSectionDataBuffers[iSec].size());
|
||||
Cooker.FinishSection(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Write SCLY
|
||||
@@ -336,8 +410,14 @@ bool CAreaCooker::CookMREA(CGameArea *pArea, IOutputStream& rOut)
|
||||
u32 PostSCLY = (Cooker.mVersion <= ePrime ? Cooker.mSCLYSecNum + 1 : Cooker.mSCGNSecNum + 1);
|
||||
for (u32 iSec = PostSCLY; iSec < pArea->mSectionDataBuffers.size(); iSec++)
|
||||
{
|
||||
Cooker.mSectionData.WriteBytes(pArea->mSectionDataBuffers[iSec].data(), pArea->mSectionDataBuffers[iSec].size());
|
||||
Cooker.FinishSection(false);
|
||||
if (iSec == Cooker.mModulesSecNum)
|
||||
Cooker.WriteModules(Cooker.mSectionData);
|
||||
|
||||
else
|
||||
{
|
||||
Cooker.mSectionData.WriteBytes(pArea->mSectionDataBuffers[iSec].data(), pArea->mSectionDataBuffers[iSec].size());
|
||||
Cooker.FinishSection(false);
|
||||
}
|
||||
}
|
||||
|
||||
Cooker.FinishBlock();
|
||||
|
||||
@@ -25,6 +25,8 @@ class CAreaCooker
|
||||
u32 mFFFFSecNum;
|
||||
u32 mPTLASecNum;
|
||||
u32 mEGMCSecNum;
|
||||
u32 mDepsSecNum;
|
||||
u32 mModulesSecNum;
|
||||
|
||||
struct SCompressedBlock
|
||||
{
|
||||
@@ -57,6 +59,10 @@ class CAreaCooker
|
||||
void WritePrimeSCLY(IOutputStream& rOut);
|
||||
void WriteEchoesSCLY(IOutputStream& rOut);
|
||||
|
||||
// Other Sections
|
||||
void WriteDependencies(IOutputStream& rOut);
|
||||
void WriteModules(IOutputStream& rOut);
|
||||
|
||||
// Section Management
|
||||
void AddSectionToBlock();
|
||||
void FinishSection(bool ForceFinishBlock);
|
||||
|
||||
@@ -25,7 +25,24 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
|
||||
if (Game == eEchoesDemo || Game == eEchoes)
|
||||
{
|
||||
DarkWorldNameID.Write(rMLVL);
|
||||
rMLVL.WriteLong(0);
|
||||
}
|
||||
if (Game >= eEchoesDemo && Game <= eCorruption)
|
||||
{
|
||||
rMLVL.WriteLong(pWorld->mTempleKeyWorldIndex);
|
||||
}
|
||||
if (Game == eReturns)
|
||||
{
|
||||
const CWorld::STimeAttackData& rkData = pWorld->mTimeAttackData;
|
||||
rMLVL.WriteBool(rkData.HasTimeAttack);
|
||||
|
||||
if (rkData.HasTimeAttack)
|
||||
{
|
||||
rMLVL.WriteString(rkData.ActNumber);
|
||||
rMLVL.WriteFloat(rkData.BronzeTime);
|
||||
rMLVL.WriteFloat(rkData.SilverTime);
|
||||
rMLVL.WriteFloat(rkData.GoldTime);
|
||||
rMLVL.WriteFloat(rkData.ShinyGoldTime);
|
||||
}
|
||||
}
|
||||
|
||||
SaveWorldID.Write(rMLVL);
|
||||
@@ -142,6 +159,10 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
|
||||
rMLVL.WriteLong(ModuleLayerOffsets[iOff]);
|
||||
}
|
||||
|
||||
// Unknown
|
||||
if (Game == eReturns)
|
||||
rMLVL.WriteLong(0);
|
||||
|
||||
// Internal Name
|
||||
if (Game >= eEchoesDemo)
|
||||
rMLVL.WriteString(rArea.InternalName);
|
||||
@@ -191,6 +212,7 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
|
||||
// Layers
|
||||
rMLVL.WriteLong(pWorld->mAreas.size());
|
||||
std::vector<TString> LayerNames;
|
||||
std::vector<CSavedStateID> LayerStateIDs;
|
||||
std::vector<u32> LayerNameOffsets;
|
||||
|
||||
// Layer Flags
|
||||
@@ -209,6 +231,7 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
|
||||
LayerActiveFlags &= ~(1 << iLyr);
|
||||
|
||||
LayerNames.push_back(rLayer.LayerName);
|
||||
LayerStateIDs.push_back(rLayer.LayerStateID);
|
||||
}
|
||||
|
||||
rMLVL.WriteLongLong(LayerActiveFlags);
|
||||
@@ -220,9 +243,13 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
|
||||
for (u32 iLyr = 0; iLyr < LayerNames.size(); iLyr++)
|
||||
rMLVL.WriteString(LayerNames[iLyr]);
|
||||
|
||||
// todo: Layer Saved State IDs go here for MP3/DKCR; need support for saved state IDs to implement
|
||||
if (Game == eCorruption || Game == eReturns)
|
||||
// Layer Saved State IDs
|
||||
if (Game >= eCorruption)
|
||||
{
|
||||
rMLVL.WriteLong(LayerStateIDs.size());
|
||||
|
||||
for (u32 iLyr = 0; iLyr < LayerStateIDs.size(); iLyr++)
|
||||
LayerStateIDs[iLyr].Write(rMLVL);
|
||||
}
|
||||
|
||||
// Layer Name Offsets
|
||||
|
||||
Reference in New Issue
Block a user