mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-12-21 02:39:17 +00:00
Fixed some missed dependencies in a few formats and implemented support for building file lists for paks and MLVLs, and implemented support for package cooking for MP1
This commit is contained in:
@@ -36,14 +36,11 @@ CDependencyTree* CGameArea::BuildDependencyTree() const
|
||||
// Base dependencies
|
||||
CAreaDependencyTree *pTree = new CAreaDependencyTree(ID());
|
||||
|
||||
for (u32 iMat = 0; iMat < mpMaterialSet->NumMaterials(); iMat++)
|
||||
{
|
||||
CMaterial *pMat = mpMaterialSet->MaterialByIndex(iMat);
|
||||
pTree->AddDependency(pMat->IndTexture());
|
||||
std::set<CAssetID> MatTextures;
|
||||
mpMaterialSet->GetUsedTextureIDs(MatTextures);
|
||||
|
||||
for (u32 iPass = 0; iPass < pMat->PassCount(); iPass++)
|
||||
pTree->AddDependency(pMat->Pass(iPass)->Texture());
|
||||
}
|
||||
for (auto Iter = MatTextures.begin(); Iter != MatTextures.end(); Iter++)
|
||||
pTree->AddDependency(*Iter);
|
||||
|
||||
pTree->AddDependency(mPathID);
|
||||
pTree->AddDependency(mPortalAreaID);
|
||||
|
||||
@@ -58,12 +58,23 @@ public:
|
||||
CDependencyTree* BuildDependencyTree() const
|
||||
{
|
||||
CAnimSetDependencyTree *pTree = new CAnimSetDependencyTree(ID());
|
||||
std::set<CAssetID> BaseUsedSet;
|
||||
|
||||
// Base dependencies
|
||||
for (u32 iAnim = 0; iAnim < mAnims.size(); iAnim++)
|
||||
pTree->AddDependency(mAnims[iAnim].pAnim);
|
||||
{
|
||||
CAnimation *pAnim = mAnims[iAnim].pAnim;
|
||||
|
||||
if (pAnim)
|
||||
{
|
||||
pTree->AddDependency(mAnims[iAnim].pAnim);
|
||||
BaseUsedSet.insert(pAnim->ID());
|
||||
}
|
||||
}
|
||||
|
||||
// Character dependencies
|
||||
for (u32 iNode = 0; iNode < mCharacters.size(); iNode++)
|
||||
pTree->AddCharacter(&mCharacters[iNode]);
|
||||
pTree->AddCharacter(&mCharacters[iNode], BaseUsedSet);
|
||||
|
||||
return pTree;
|
||||
}
|
||||
|
||||
@@ -59,6 +59,21 @@ public:
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void GetUsedTextureIDs(std::set<CAssetID>& rOut)
|
||||
{
|
||||
for (u32 iMat = 0; iMat < mMaterials.size(); iMat++)
|
||||
{
|
||||
CMaterial *pMat = mMaterials[iMat];
|
||||
if (pMat->IndTexture()) rOut.insert(pMat->IndTexture()->ID());
|
||||
|
||||
for (u32 iPass = 0; iPass < pMat->PassCount(); iPass++)
|
||||
{
|
||||
CTexture *pTex = pMat->Pass(iPass)->Texture();
|
||||
if (pTex) rOut.insert(pTex->ID());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CMATERIALSET_H
|
||||
|
||||
@@ -24,16 +24,16 @@ public:
|
||||
|
||||
private:
|
||||
EGame mVersion;
|
||||
TResPtr<CResource> mpFrame;
|
||||
CAssetID mFrameID;
|
||||
TResPtr<CStringTable> mpStringTable;
|
||||
bool mIsSlow;
|
||||
bool mIsImportant;
|
||||
ELogbookCategory mCategory;
|
||||
CAssetID mScanImageTextures[4];
|
||||
|
||||
public:
|
||||
CScan(CResourceEntry *pEntry = 0)
|
||||
: CResource(pEntry)
|
||||
, mpFrame(nullptr)
|
||||
, mpStringTable(nullptr)
|
||||
, mIsSlow(false)
|
||||
, mIsImportant(false)
|
||||
@@ -46,8 +46,12 @@ public:
|
||||
Log::Warning("CScan::BuildDependencyTree not handling Echoes/Corruption dependencies");
|
||||
|
||||
CDependencyTree *pTree = new CDependencyTree(ID());
|
||||
pTree->AddDependency(mpFrame);
|
||||
pTree->AddDependency(mFrameID);
|
||||
pTree->AddDependency(mpStringTable);
|
||||
|
||||
for (u32 iImg = 0; iImg < 4; iImg++)
|
||||
pTree->AddDependency(mScanImageTextures[iImg]);
|
||||
|
||||
return pTree;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
|
||||
CDependencyTree* BuildDependencyTree() const
|
||||
{
|
||||
// The only dependencies STRGs have is they can reference FONTs with the &font=; formatting tag
|
||||
// STRGs can reference FONTs with the &font=; formatting tag and TXTRs with the &image=; tag
|
||||
CDependencyTree *pTree = new CDependencyTree(ID());
|
||||
EIDLength IDLength = (Game() <= eEchoes ? e32Bit : e64Bit);
|
||||
|
||||
@@ -54,14 +54,69 @@ public:
|
||||
|
||||
for (u32 iStr = 0; iStr < rkTable.Strings.size(); iStr++)
|
||||
{
|
||||
static const TWideString skTag = L"&font=";
|
||||
const TWideString& rkStr = rkTable.Strings[iStr];
|
||||
|
||||
for (u32 FontIdx = rkStr.IndexOfPhrase(*skTag); FontIdx != -1; FontIdx = rkStr.IndexOfPhrase(*skTag, FontIdx + 1))
|
||||
for (u32 TagIdx = rkStr.IndexOf(L'&'); TagIdx != -1; TagIdx = rkStr.IndexOf(L'&', TagIdx + 1))
|
||||
{
|
||||
u32 IDStart = FontIdx + skTag.Size();
|
||||
TWideString StrFontID = rkStr.SubString(IDStart, IDLength * 2);
|
||||
pTree->AddDependency( CAssetID::FromString(StrFontID) );
|
||||
// Check for double ampersand (escape character in DKCR, not sure about other games)
|
||||
if (rkStr.At(TagIdx + 1) == L'&')
|
||||
{
|
||||
TagIdx++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get tag name and parameters
|
||||
u32 NameEnd = rkStr.IndexOf(L'=', TagIdx);
|
||||
u32 TagEnd = rkStr.IndexOf(L';', TagIdx);
|
||||
if (NameEnd == -1 || TagEnd == -1) continue;
|
||||
|
||||
TWideString TagName = rkStr.SubString(TagIdx + 1, NameEnd - TagIdx - 1);
|
||||
TWideString ParamString = rkStr.SubString(NameEnd + 1, TagEnd - NameEnd - 1);
|
||||
|
||||
// Font
|
||||
if (TagName == L"font")
|
||||
{
|
||||
ASSERT(ParamString.Size() == IDLength * 2);
|
||||
pTree->AddDependency( CAssetID::FromString(ParamString) );
|
||||
}
|
||||
|
||||
// Image
|
||||
else if (TagName == L"image")
|
||||
{
|
||||
// Determine which params are textures based on image type
|
||||
TWideStringList Params = ParamString.Split(L",");
|
||||
TWideString ImageType = Params.front();
|
||||
u32 TexturesStart = -1;
|
||||
|
||||
if (ImageType == L"A")
|
||||
TexturesStart = 2;
|
||||
|
||||
else if (ImageType == L"SI")
|
||||
TexturesStart = 3;
|
||||
|
||||
else if (ImageType == L"SA")
|
||||
TexturesStart = 4;
|
||||
|
||||
else
|
||||
{
|
||||
Log::Error("Unrecognized image type: " + ImageType.ToUTF8());
|
||||
DEBUG_BREAK;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Load texture IDs
|
||||
TWideStringList::iterator Iter = Params.begin();
|
||||
|
||||
for (u32 iParam = 0; iParam < Params.size(); iParam++, Iter++)
|
||||
{
|
||||
if (iParam >= TexturesStart)
|
||||
{
|
||||
TWideString Param = *Iter;
|
||||
ASSERT(Param.Size() == IDLength * 2);
|
||||
pTree->AddDependency( CAssetID::FromString(Param) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,7 @@ void Serialize(IArchive& rArc, CWorld::SArea& rArea)
|
||||
<< SERIAL("BoundingBox", rArea.AetherBox)
|
||||
<< SERIAL("AreaMREA", rArea.AreaResID)
|
||||
<< SERIAL_HEX("AreaID", rArea.AreaID)
|
||||
<< SERIAL("AllowPakDuplicates", rArea.AllowPakDuplicates)
|
||||
<< SERIAL_CONTAINER("AttachedAreas", rArea.AttachedAreaIDs, "AreaIndex")
|
||||
<< SERIAL_CONTAINER("Dependencies", rArea.Dependencies, "Dependency")
|
||||
<< SERIAL_CONTAINER("RelModules", rArea.RelFilenames, "Module")
|
||||
|
||||
@@ -11,6 +11,7 @@ class CWorld : public CResource
|
||||
{
|
||||
DECLARE_RESOURCE_TYPE(eWorld)
|
||||
friend class CWorldLoader;
|
||||
friend class CWorldCooker;
|
||||
|
||||
// Instances of CResource pointers are placeholders for unimplemented resource types (eg CMapWorld)
|
||||
EGame mWorldVersion;
|
||||
@@ -48,6 +49,7 @@ class CWorld : public CResource
|
||||
CAABox AetherBox;
|
||||
CAssetID AreaResID; // Loading every single area as a CResource would be a very bad idea
|
||||
u64 AreaID;
|
||||
bool AllowPakDuplicates;
|
||||
|
||||
std::vector<u16> AttachedAreaIDs;
|
||||
std::vector<CAssetID> Dependencies;
|
||||
@@ -103,11 +105,14 @@ public:
|
||||
inline CResource* MapWorld() const { return mpMapWorld; }
|
||||
|
||||
inline u32 NumAreas() const { return mAreas.size(); }
|
||||
inline u64 AreaResourceID(u32 AreaIndex) const { return mAreas[AreaIndex].AreaResID.ToLongLong(); }
|
||||
inline CAssetID AreaResourceID(u32 AreaIndex) const { return mAreas[AreaIndex].AreaResID; }
|
||||
inline u32 AreaAttachedCount(u32 AreaIndex) const { return mAreas[AreaIndex].AttachedAreaIDs.size(); }
|
||||
inline u32 AreaAttachedID(u32 AreaIndex, u32 AttachedIndex) const { return mAreas[AreaIndex].AttachedAreaIDs[AttachedIndex]; }
|
||||
inline TString AreaInternalName(u32 AreaIndex) const { return mAreas[AreaIndex].InternalName; }
|
||||
inline CStringTable* AreaName(u32 AreaIndex) const { return mAreas[AreaIndex].pAreaName; }
|
||||
inline bool DoesAreaAllowPakDuplicates(u32 AreaIndex) const { return mAreas[AreaIndex].AllowPakDuplicates; }
|
||||
|
||||
inline void SetAreaAllowsPakDuplicates(u32 AreaIndex, bool Allow) { mAreas[AreaIndex].AllowPakDuplicates = Allow; }
|
||||
};
|
||||
|
||||
#endif // CWORLD_H
|
||||
|
||||
@@ -31,6 +31,4 @@ void CPoiToWorldCooker::WriteEGMC(CPoiToWorld *pPoiToWorld, IOutputStream& rOut)
|
||||
rOut.WriteLong(Mappings[iMap].MeshID);
|
||||
rOut.WriteLong(Mappings[iMap].PoiID);
|
||||
}
|
||||
|
||||
rOut.WriteToBoundary(32, -1);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,162 @@
|
||||
#include "CWorldCooker.h"
|
||||
#include "Core/GameProject/DependencyListBuilders.h"
|
||||
|
||||
CWorldCooker::CWorldCooker()
|
||||
{
|
||||
}
|
||||
|
||||
// ************ STATIC ************
|
||||
bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
|
||||
{
|
||||
ASSERT(rMLVL.IsValid());
|
||||
|
||||
// MLVL Header
|
||||
rMLVL.WriteLong(0xDEAFBABE);
|
||||
rMLVL.WriteLong( GetMLVLVersion(pWorld->Game()) );
|
||||
|
||||
CAssetID WorldNameID = pWorld->mpWorldName ? pWorld->mpWorldName->ID() : CAssetID::skInvalidID32;
|
||||
CAssetID SaveWorldID = pWorld->mpSaveWorld ? pWorld->mpSaveWorld->ID() : CAssetID::skInvalidID32;
|
||||
CAssetID DefaultSkyID = pWorld->mpDefaultSkybox ? pWorld->mpDefaultSkybox->ID() : CAssetID::skInvalidID32;
|
||||
|
||||
WorldNameID.Write(rMLVL);
|
||||
SaveWorldID.Write(rMLVL);
|
||||
DefaultSkyID.Write(rMLVL);
|
||||
|
||||
// Memory Relays
|
||||
rMLVL.WriteLong( pWorld->mMemoryRelays.size() );
|
||||
|
||||
for (u32 iMem = 0; iMem < pWorld->mMemoryRelays.size(); iMem++)
|
||||
{
|
||||
CWorld::SMemoryRelay& rRelay = pWorld->mMemoryRelays[iMem];
|
||||
rMLVL.WriteLong(rRelay.InstanceID);
|
||||
rMLVL.WriteLong(rRelay.TargetID);
|
||||
rMLVL.WriteShort(rRelay.Message);
|
||||
rMLVL.WriteByte(rRelay.Unknown);
|
||||
}
|
||||
|
||||
// Areas
|
||||
rMLVL.WriteLong(pWorld->mAreas.size());
|
||||
rMLVL.WriteLong(1); // Unknown
|
||||
|
||||
for (u32 iArea = 0; iArea < pWorld->mAreas.size(); iArea++)
|
||||
{
|
||||
// Area Header
|
||||
CWorld::SArea& rArea = pWorld->mAreas[iArea];
|
||||
CResourceEntry *pAreaEntry = gpResourceStore->FindEntry(rArea.AreaResID);
|
||||
ASSERT(pAreaEntry && pAreaEntry->ResourceType() == eArea);
|
||||
|
||||
CAssetID AreaNameID = rArea.pAreaName ? rArea.pAreaName->ID() : CAssetID::skInvalidID32;
|
||||
AreaNameID.Write(rMLVL);
|
||||
rArea.Transform.Write(rMLVL);
|
||||
rArea.AetherBox.Write(rMLVL);
|
||||
rArea.AreaResID.Write(rMLVL);
|
||||
rMLVL.WriteLong( (u32) rArea.AreaID );
|
||||
|
||||
// Attached Areas
|
||||
rMLVL.WriteLong( rArea.AttachedAreaIDs.size() );
|
||||
|
||||
for (u32 iAttach = 0; iAttach < rArea.AttachedAreaIDs.size(); iAttach++)
|
||||
rMLVL.WriteShort(rArea.AttachedAreaIDs[iAttach]);
|
||||
|
||||
// Dependencies
|
||||
std::list<CAssetID> Dependencies;
|
||||
std::list<u32> LayerDependsOffsets;
|
||||
CAreaDependencyListBuilder Builder(pAreaEntry);
|
||||
Builder.BuildDependencyList(Dependencies, LayerDependsOffsets);
|
||||
|
||||
rMLVL.WriteLong(0);
|
||||
rMLVL.WriteLong( Dependencies.size() );
|
||||
|
||||
for (auto Iter = Dependencies.begin(); Iter != Dependencies.end(); Iter++)
|
||||
{
|
||||
CAssetID ID = *Iter;
|
||||
CResourceEntry *pEntry = gpResourceStore->FindEntry(ID);
|
||||
ID.Write(rMLVL);
|
||||
pEntry->CookedExtension().Write(rMLVL);
|
||||
}
|
||||
|
||||
rMLVL.WriteLong(LayerDependsOffsets.size());
|
||||
|
||||
for (auto Iter = LayerDependsOffsets.begin(); Iter != LayerDependsOffsets.end(); Iter++)
|
||||
rMLVL.WriteLong(*Iter);
|
||||
|
||||
// Docks
|
||||
rMLVL.WriteLong( rArea.Docks.size() );
|
||||
|
||||
for (u32 iDock = 0; iDock < rArea.Docks.size(); iDock++)
|
||||
{
|
||||
CWorld::SArea::SDock& rDock = rArea.Docks[iDock];
|
||||
rMLVL.WriteLong( rDock.ConnectingDocks.size() );
|
||||
|
||||
for (u32 iCon = 0; iCon < rDock.ConnectingDocks.size(); iCon++)
|
||||
{
|
||||
CWorld::SArea::SDock::SConnectingDock& rConDock = rDock.ConnectingDocks[iCon];
|
||||
rMLVL.WriteLong(rConDock.AreaIndex);
|
||||
rMLVL.WriteLong(rConDock.DockIndex);
|
||||
}
|
||||
|
||||
rMLVL.WriteLong( rDock.DockCoordinates.size() );
|
||||
|
||||
for (u32 iCoord = 0; iCoord < rDock.DockCoordinates.size(); iCoord++)
|
||||
rDock.DockCoordinates[iCoord].Write(rMLVL);
|
||||
}
|
||||
}
|
||||
|
||||
CAssetID MapWorldID = pWorld->mpMapWorld ? pWorld->mpMapWorld->ID() : CAssetID::skInvalidID32;
|
||||
MapWorldID.Write(rMLVL);
|
||||
rMLVL.WriteByte(0);
|
||||
rMLVL.WriteLong(0);
|
||||
|
||||
// Audio Groups
|
||||
rMLVL.WriteLong(pWorld->mAudioGrps.size());
|
||||
|
||||
for (u32 iGrp = 0; iGrp < pWorld->mAudioGrps.size(); iGrp++)
|
||||
{
|
||||
CWorld::SAudioGrp& rAudioGroup = pWorld->mAudioGrps[iGrp];
|
||||
rMLVL.WriteLong(rAudioGroup.Unknown);
|
||||
rAudioGroup.ResID.Write(rMLVL);
|
||||
}
|
||||
|
||||
rMLVL.WriteByte(0);
|
||||
|
||||
// Layers
|
||||
rMLVL.WriteLong(pWorld->mAreas.size());
|
||||
std::vector<TString> LayerNames;
|
||||
std::vector<u32> LayerNameOffsets;
|
||||
|
||||
for (u32 iArea = 0; iArea < pWorld->mAreas.size(); iArea++)
|
||||
{
|
||||
CWorld::SArea& rArea = pWorld->mAreas[iArea];
|
||||
LayerNameOffsets.push_back(LayerNames.size());
|
||||
rMLVL.WriteLong(rArea.Layers.size());
|
||||
|
||||
u64 LayerActiveFlags = -1;
|
||||
|
||||
for (u32 iLyr = 0; iLyr < rArea.Layers.size(); iLyr++)
|
||||
{
|
||||
CWorld::SArea::SLayer& rLayer = rArea.Layers[iLyr];
|
||||
if (!rLayer.EnabledByDefault)
|
||||
LayerActiveFlags &= ~(1 << iLyr);
|
||||
|
||||
LayerNames.push_back(rLayer.LayerName);
|
||||
}
|
||||
|
||||
rMLVL.WriteLongLong(LayerActiveFlags);
|
||||
}
|
||||
|
||||
rMLVL.WriteLong(LayerNames.size());
|
||||
|
||||
for (u32 iLyr = 0; iLyr < LayerNames.size(); iLyr++)
|
||||
rMLVL.WriteString(LayerNames[iLyr].ToStdString());
|
||||
|
||||
rMLVL.WriteLong(LayerNameOffsets.size());
|
||||
|
||||
for (u32 iOff = 0; iOff < LayerNameOffsets.size(); iOff++)
|
||||
rMLVL.WriteLong(LayerNameOffsets[iOff]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 CWorldCooker::GetMLVLVersion(EGame Version)
|
||||
{
|
||||
switch (Version)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef CWORLDCOOKER_H
|
||||
#define CWORLDCOOKER_H
|
||||
|
||||
#include "Core/Resource/CWorld.h"
|
||||
#include "Core/Resource/EGame.h"
|
||||
#include <Common/types.h>
|
||||
|
||||
@@ -8,6 +9,7 @@ class CWorldCooker
|
||||
{
|
||||
CWorldCooker();
|
||||
public:
|
||||
static bool CookMLVL(CWorld *pWorld, IOutputStream& rOut);
|
||||
static u32 GetMLVLVersion(EGame Version);
|
||||
};
|
||||
|
||||
|
||||
@@ -681,6 +681,7 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA, CResourceEntry *pEntry)
|
||||
Loader.ReadSCLYPrime();
|
||||
Loader.ReadCollision();
|
||||
Loader.ReadLightsPrime();
|
||||
Loader.ReadPATH();
|
||||
break;
|
||||
case eEchoesDemo:
|
||||
Loader.ReadHeaderEchoes();
|
||||
@@ -688,6 +689,8 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA, CResourceEntry *pEntry)
|
||||
Loader.ReadSCLYPrime();
|
||||
Loader.ReadCollision();
|
||||
Loader.ReadLightsPrime();
|
||||
Loader.ReadPATH();
|
||||
Loader.ReadPTLA();
|
||||
Loader.ReadEGMC();
|
||||
break;
|
||||
case eEchoes:
|
||||
@@ -696,6 +699,8 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA, CResourceEntry *pEntry)
|
||||
Loader.ReadSCLYEchoes();
|
||||
Loader.ReadCollision();
|
||||
Loader.ReadLightsPrime();
|
||||
Loader.ReadPATH();
|
||||
Loader.ReadPTLA();
|
||||
Loader.ReadEGMC();
|
||||
break;
|
||||
case eCorruptionProto:
|
||||
@@ -704,6 +709,8 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA, CResourceEntry *pEntry)
|
||||
Loader.ReadSCLYEchoes();
|
||||
Loader.ReadCollision();
|
||||
Loader.ReadLightsCorruption();
|
||||
Loader.ReadPATH();
|
||||
Loader.ReadPTLA();
|
||||
Loader.ReadEGMC();
|
||||
break;
|
||||
case eCorruption:
|
||||
@@ -715,6 +722,8 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA, CResourceEntry *pEntry)
|
||||
if (Loader.mVersion == eCorruption)
|
||||
{
|
||||
Loader.ReadLightsCorruption();
|
||||
Loader.ReadPATH();
|
||||
Loader.ReadPTLA();
|
||||
Loader.ReadEGMC();
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -5,8 +5,8 @@ EGame CDependencyGroupLoader::VersionTest(IInputStream& rDGRP, u32 DepCount)
|
||||
{
|
||||
// Only difference between versions is asset ID length. Just check for EOF with 32-bit ID length.
|
||||
u32 Start = rDGRP.Tell();
|
||||
rDGRP.Seek(DepCount * 4, SEEK_CUR);
|
||||
u32 Remaining = rDGRP.Size() - Start;
|
||||
rDGRP.Seek(DepCount * 8, SEEK_CUR);
|
||||
u32 Remaining = rDGRP.Size() - rDGRP.Tell();
|
||||
|
||||
EGame Game = ePrimeDemo;
|
||||
|
||||
@@ -14,7 +14,9 @@ EGame CDependencyGroupLoader::VersionTest(IInputStream& rDGRP, u32 DepCount)
|
||||
{
|
||||
for (u32 iRem = 0; iRem < Remaining; iRem++)
|
||||
{
|
||||
if (rDGRP.ReadByte() != 0xFF)
|
||||
u8 Byte = rDGRP.ReadByte();
|
||||
|
||||
if (Byte != 0xFF)
|
||||
{
|
||||
Game = eCorruptionProto;
|
||||
break;
|
||||
|
||||
@@ -120,7 +120,7 @@ CMaterial* CMaterialLoader::ReadPrimeMaterial()
|
||||
if (pMat->mOptions & CMaterial::eIndStage)
|
||||
{
|
||||
u32 IndTexIndex = mpFile->ReadLong();
|
||||
pMat->mpIndirectTexture = mTextures[IndTexIndex];
|
||||
pMat->mpIndirectTexture = mTextures[TextureIndices[IndTexIndex]];
|
||||
}
|
||||
|
||||
// Color channels
|
||||
@@ -162,7 +162,7 @@ CMaterial* CMaterialLoader::ReadPrimeMaterial()
|
||||
|
||||
u8 TexSel = mpFile->ReadByte();
|
||||
|
||||
if ((TexSel == 0xFF) || (TexSel >= mTextures.size()))
|
||||
if ((TexSel == 0xFF) || (TexSel >= TextureIndices.size()))
|
||||
pPass->mpTexture = nullptr;
|
||||
else
|
||||
pPass->mpTexture = mTextures[TextureIndices[TexSel]];
|
||||
|
||||
@@ -9,11 +9,18 @@ CScanLoader::CScanLoader()
|
||||
CScan* CScanLoader::LoadScanMP1(IInputStream& rSCAN)
|
||||
{
|
||||
// Basic support at the moment - don't read animation/scan image data
|
||||
rSCAN.Seek(0x4, SEEK_CUR); // Skip FRME ID
|
||||
mpScan->mFrameID = CAssetID(rSCAN, e32Bit);
|
||||
mpScan->mpStringTable = gpResourceStore->LoadResource(rSCAN.ReadLong(), "STRG");
|
||||
mpScan->mIsSlow = (rSCAN.ReadLong() != 0);
|
||||
mpScan->mCategory = (CScan::ELogbookCategory) rSCAN.ReadLong();
|
||||
mpScan->mIsImportant = (rSCAN.ReadByte() == 1);
|
||||
|
||||
for (u32 iImg = 0; iImg < 4; iImg++)
|
||||
{
|
||||
mpScan->mScanImageTextures[iImg] = CAssetID(rSCAN, e32Bit);
|
||||
rSCAN.Seek(0x18, SEEK_CUR);
|
||||
}
|
||||
|
||||
mpScan->mVersion = ePrime;
|
||||
return mpScan;
|
||||
}
|
||||
|
||||
@@ -33,24 +33,17 @@ CModel::~CModel()
|
||||
CDependencyTree* CModel::BuildDependencyTree() const
|
||||
{
|
||||
CDependencyTree *pTree = new CDependencyTree(ID());
|
||||
std::set<CAssetID> TextureIDs;
|
||||
|
||||
for (u32 iSet = 0; iSet < mMaterialSets.size(); iSet++)
|
||||
{
|
||||
CMaterialSet *pSet = mMaterialSets[iSet];
|
||||
|
||||
for (u32 iMat = 0; iMat < pSet->NumMaterials(); iMat++)
|
||||
{
|
||||
CMaterial *pMat = pSet->MaterialByIndex(iMat);
|
||||
pTree->AddDependency(pMat->IndTexture());
|
||||
|
||||
for (u32 iPass = 0; iPass < pMat->PassCount(); iPass++)
|
||||
{
|
||||
CMaterialPass *pPass = pMat->Pass(iPass);
|
||||
pTree->AddDependency(pPass->Texture());
|
||||
}
|
||||
}
|
||||
pSet->GetUsedTextureIDs(TextureIDs);
|
||||
}
|
||||
|
||||
for (auto Iter = TextureIDs.begin(); Iter != TextureIDs.end(); Iter++)
|
||||
pTree->AddDependency(*Iter);
|
||||
|
||||
return pTree;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user