Added support for Prime 3 package cooking

This commit is contained in:
Aruki
2017-05-09 21:08:52 -06:00
parent 560706d285
commit 7f18a33fae
10 changed files with 402 additions and 52 deletions

View File

@@ -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();

View File

@@ -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);

View File

@@ -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