From 07278ebbfa92307f89027aae15a07705529b5d08 Mon Sep 17 00:00:00 2001 From: TheApadayo Date: Fri, 1 Feb 2019 16:16:42 -0500 Subject: [PATCH] [ZoneBuilder] Add support for iw3 techsets, decl, vs, and ps --- .../AssetInterfaces/IMaterialPixelShader.cpp | 49 +++++++ .../AssetInterfaces/IMaterialPixelShader.hpp | 4 + .../AssetInterfaces/IMaterialTechniqueSet.cpp | 137 +++++++++++++++++- .../AssetInterfaces/IMaterialTechniqueSet.hpp | 6 + .../IMaterialVertexDeclaration.cpp | 43 ++++++ .../IMaterialVertexDeclaration.hpp | 4 + .../AssetInterfaces/IMaterialVertexShader.cpp | 48 ++++++ .../AssetInterfaces/IMaterialVertexShader.hpp | 4 + .../Modules/AssetInterfaces/IXModel.cpp | 28 ++-- .../Modules/AssetInterfaces/IXModel.hpp | 5 +- .../Modules/AssetInterfaces/IXModelSurfs.cpp | 16 +- src/Components/Modules/QuickPatch.cpp | 23 +-- src/Components/Modules/ZoneBuilder.cpp | 5 +- 13 files changed, 341 insertions(+), 31 deletions(-) diff --git a/src/Components/Modules/AssetInterfaces/IMaterialPixelShader.cpp b/src/Components/Modules/AssetInterfaces/IMaterialPixelShader.cpp index e4a74a17..ecf6c330 100644 --- a/src/Components/Modules/AssetInterfaces/IMaterialPixelShader.cpp +++ b/src/Components/Modules/AssetInterfaces/IMaterialPixelShader.cpp @@ -1,7 +1,56 @@ #include "STDInclude.hpp" +#define IW4X_TECHSET_VERSION "0" + namespace Assets { + + void IMaterialPixelShader::load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) + { + if (!header->data) this->loadNative(header, name, builder); // Check if there is a native one + if (!header->data) this->loadBinary(header, name, builder); // Check if we need to import a new one into the game + } + + void IMaterialPixelShader::loadNative(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* /*builder*/) + { + header->pixelShader = Components::AssetHandler::FindOriginalAsset(this->getType(), name.data()).pixelShader; + } + + void IMaterialPixelShader::loadBinary(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) + { + Components::FileSystem::File psFile(Utils::String::VA("ps/%s.iw4xPS", name.data())); + if (!psFile.exists()) return; + + Utils::Stream::Reader reader(builder->getAllocator(), psFile.getBuffer()); + + char* magic = reader.readArray(8); + if (std::memcmp(magic, "IW4xPIXL", 8)) + { + Components::Logger::Error(0, "Reading pixel shader '%s' failed, header is invalid!", name.data()); + } + + std::string version; + version.push_back(reader.read()); + if (version != IW4X_TECHSET_VERSION) + { + Components::Logger::Error("Reading pixel shader '%s' failed, expected version is %d, but it was %d!", name.data(), atoi(IW4X_TECHSET_VERSION), atoi(version.data())); + } + + Game::MaterialPixelShader* asset = reader.readObject(); + + if (asset->name) + { + asset->name = reader.readCString(); + } + + if (asset->prog.loadDef.program) + { + asset->prog.loadDef.program = reader.readArray(asset->prog.loadDef.programSize); + } + + header->pixelShader = asset; + } + void IMaterialPixelShader::save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) { AssertSize(Game::MaterialPixelShader, 16); diff --git a/src/Components/Modules/AssetInterfaces/IMaterialPixelShader.hpp b/src/Components/Modules/AssetInterfaces/IMaterialPixelShader.hpp index 2d12b78b..914f9bc2 100644 --- a/src/Components/Modules/AssetInterfaces/IMaterialPixelShader.hpp +++ b/src/Components/Modules/AssetInterfaces/IMaterialPixelShader.hpp @@ -8,5 +8,9 @@ namespace Assets virtual Game::XAssetType getType() override { return Game::XAssetType::ASSET_TYPE_PIXELSHADER; }; virtual void save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override; + virtual void load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) override; + + void loadNative(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder); + void loadBinary(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder); }; } diff --git a/src/Components/Modules/AssetInterfaces/IMaterialTechniqueSet.cpp b/src/Components/Modules/AssetInterfaces/IMaterialTechniqueSet.cpp index 2d3badc7..e390cfa3 100644 --- a/src/Components/Modules/AssetInterfaces/IMaterialTechniqueSet.cpp +++ b/src/Components/Modules/AssetInterfaces/IMaterialTechniqueSet.cpp @@ -1,9 +1,144 @@ #include "STDInclude.hpp" +#define IW4X_TECHSET_VERSION "0" + namespace Assets { + void IMaterialTechniqueSet::load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) + { + if (!header->data) this->loadNative(header, name, builder); // Check if there is a native one + if (!header->data) this->loadBinary(header, name, builder); // Check if we need to import a new one into the game + } + + void IMaterialTechniqueSet::loadNative(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* /*builder*/) + { + header->techniqueSet = Components::AssetHandler::FindOriginalAsset(this->getType(), name.data()).techniqueSet; + } + + void IMaterialTechniqueSet::loadBinaryTechnique(Game::MaterialTechnique** tech, const std::string& name, Components::ZoneBuilder::Zone* builder) + { + AssertSize(Game::MaterialPass, 20); + + Components::FileSystem::File techFile(Utils::String::VA("techniques/%s.iw4xTech", name.data())); + if (!techFile.exists()) { + *tech = nullptr; + Components::Logger::Print("Warning: Missing technique '%s'\n", name.data()); + return; + } + + Utils::Stream::Reader reader(builder->getAllocator(), techFile.getBuffer()); + + char* magic = reader.readArray(8); + if (std::memcmp(magic, "IW4xTECH", 8)) + { + Components::Logger::Error(0, "Reading technique '%s' failed, header is invalid!", name.data()); + } + + std::string version; + version.push_back(reader.read()); + if (version != IW4X_TECHSET_VERSION) + { + Components::Logger::Error("Reading technique '%s' failed, expected version is %d, but it was %d!", name.data(), atoi(IW4X_TECHSET_VERSION), atoi(version.data())); + } + + unsigned short flags = reader.read(); + unsigned short passCount = reader.read(); + + Game::MaterialTechnique* asset = (Game::MaterialTechnique*)builder->getAllocator()->allocateArray(sizeof(Game::MaterialTechnique) + (sizeof(Game::MaterialPass) * (passCount - 1))); + + asset->name = builder->getAllocator()->duplicateString(name); + asset->flags = flags; + asset->passCount = passCount; + + Game::MaterialPass* passes = reader.readArray(passCount); + std::memcpy(asset->passArray, passes, sizeof(Game::MaterialPass) * passCount); + + for (unsigned short i = 0; i < asset->passCount; i++) + { + Game::MaterialPass* pass = &asset->passArray[i]; + + if (pass->vertexDecl) + { + const char* declName = reader.readCString(); + pass->vertexDecl = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_VERTEXDECL, declName, builder).vertexDecl; + } + + if (pass->vertexShader) + { + const char* vsName = reader.readCString(); + pass->vertexShader = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_VERTEXSHADER, vsName, builder).vertexShader; + + } + + if (pass->pixelShader) + { + const char* psName = reader.readCString(); + pass->pixelShader = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_PIXELSHADER, psName, builder).pixelShader; + } + + pass->args = reader.readArray(pass->perPrimArgCount + pass->perObjArgCount + pass->stableArgCount); + + for (int j = 0; j < pass->perPrimArgCount + pass->perObjArgCount + pass->stableArgCount; j++) + { + if (pass->args[j].type == 1 || pass->args[j].type == 7) + { + pass->args[j].u.literalConst = reader.readArray(4); + } + + if (pass->args[j].type == 3 || pass->args[j].type == 5) + { + pass->args[j].u.codeConst.index = *reader.readObject(); + pass->args[j].u.codeConst.firstRow = *reader.readObject(); + pass->args[j].u.codeConst.rowCount = *reader.readObject(); + } + } + } + + *tech = asset; + } + + void IMaterialTechniqueSet::loadBinary(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) + { + Components::FileSystem::File tsFile(Utils::String::VA("techsets/%s.iw4xTS", name.data())); + if (!tsFile.exists()) return; + + Utils::Stream::Reader reader(builder->getAllocator(), tsFile.getBuffer()); + + char* magic = reader.readArray(8); + if (std::memcmp(magic, "IW4xTSET", 8)) + { + Components::Logger::Error(0, "Reading techset '%s' failed, header is invalid!", name.data()); + } + + std::string version; + version.push_back(reader.read()); + if (version != IW4X_TECHSET_VERSION) + { + Components::Logger::Error("Reading techset '%s' failed, expected version is %d, but it was %d!", name.data(), atoi(IW4X_TECHSET_VERSION), atoi(version.data())); + } + + Game::MaterialTechniqueSet* asset = reader.readObject(); + + if (asset->name) + { + asset->name = reader.readCString(); + } + + for (int i = 0; i < 48; i++) + { + if (asset->techniques[i]) + { + const char* techName = reader.readCString(); + this->loadBinaryTechnique(&asset->techniques[i], techName, builder); + } + } + + + header->techniqueSet = asset; + } + void IMaterialTechniqueSet::mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) - { + { Game::MaterialTechniqueSet* asset = header.techniqueSet; for (int i = 0; i < ARRAYSIZE(Game::MaterialTechniqueSet::techniques); ++i) diff --git a/src/Components/Modules/AssetInterfaces/IMaterialTechniqueSet.hpp b/src/Components/Modules/AssetInterfaces/IMaterialTechniqueSet.hpp index d610cd30..d5453249 100644 --- a/src/Components/Modules/AssetInterfaces/IMaterialTechniqueSet.hpp +++ b/src/Components/Modules/AssetInterfaces/IMaterialTechniqueSet.hpp @@ -9,5 +9,11 @@ namespace Assets virtual void save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override; virtual void mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override; + virtual void load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) override; + + void loadNative(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder); + void loadBinary(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder); + + void loadBinaryTechnique(Game::MaterialTechnique** tech, const std::string& name, Components::ZoneBuilder::Zone* builder); }; } diff --git a/src/Components/Modules/AssetInterfaces/IMaterialVertexDeclaration.cpp b/src/Components/Modules/AssetInterfaces/IMaterialVertexDeclaration.cpp index 42afbef1..fa51a556 100644 --- a/src/Components/Modules/AssetInterfaces/IMaterialVertexDeclaration.cpp +++ b/src/Components/Modules/AssetInterfaces/IMaterialVertexDeclaration.cpp @@ -1,7 +1,50 @@ #include "STDInclude.hpp" +#define IW4X_TECHSET_VERSION "0" + namespace Assets { + void IMaterialVertexDeclaration::load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) + { + if (!header->data) this->loadNative(header, name, builder); // Check if there is a native one + if (!header->data) this->loadBinary(header, name, builder); // Check if we need to import a new one into the game + } + + void IMaterialVertexDeclaration::loadNative(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* /*builder*/) + { + header->vertexDecl = Components::AssetHandler::FindOriginalAsset(this->getType(), name.data()).vertexDecl; + } + + void IMaterialVertexDeclaration::loadBinary(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) + { + Components::FileSystem::File declFile(Utils::String::VA("decl/%s.iw4xDECL", name.data())); + if (!declFile.exists()) return; + + Utils::Stream::Reader reader(builder->getAllocator(), declFile.getBuffer()); + + char* magic = reader.readArray(8); + if (std::memcmp(magic, "IW4xDECL", 8)) + { + Components::Logger::Error(0, "Reading vertex declaration '%s' failed, header is invalid!", name.data()); + } + + std::string version; + version.push_back(reader.read()); + if (version != IW4X_TECHSET_VERSION) + { + Components::Logger::Error("Reading vertex declaration '%s' failed, expected version is %d, but it was %d!", name.data(), atoi(IW4X_TECHSET_VERSION), atoi(version.data())); + } + + Game::MaterialVertexDeclaration* asset = reader.readObject(); + + if (asset->name) + { + asset->name = reader.readCString(); + } + + header->vertexDecl = asset; + } + void IMaterialVertexDeclaration::save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) { AssertSize(Game::MaterialVertexDeclaration, 100); diff --git a/src/Components/Modules/AssetInterfaces/IMaterialVertexDeclaration.hpp b/src/Components/Modules/AssetInterfaces/IMaterialVertexDeclaration.hpp index 49ec8352..d774f05a 100644 --- a/src/Components/Modules/AssetInterfaces/IMaterialVertexDeclaration.hpp +++ b/src/Components/Modules/AssetInterfaces/IMaterialVertexDeclaration.hpp @@ -8,5 +8,9 @@ namespace Assets virtual Game::XAssetType getType() override { return Game::XAssetType::ASSET_TYPE_VERTEXDECL; }; virtual void save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override; + virtual void load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) override; + + void loadNative(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder); + void loadBinary(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder); }; } diff --git a/src/Components/Modules/AssetInterfaces/IMaterialVertexShader.cpp b/src/Components/Modules/AssetInterfaces/IMaterialVertexShader.cpp index 3396c72b..c6d5ee04 100644 --- a/src/Components/Modules/AssetInterfaces/IMaterialVertexShader.cpp +++ b/src/Components/Modules/AssetInterfaces/IMaterialVertexShader.cpp @@ -1,7 +1,55 @@ #include "STDInclude.hpp" +#define IW4X_TECHSET_VERSION "0" + namespace Assets { + void IMaterialVertexShader::load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) + { + if (!header->data) this->loadNative(header, name, builder); // Check if there is a native one + if (!header->data) this->loadBinary(header, name, builder); // Check if we need to import a new one into the game + } + + void IMaterialVertexShader::loadNative(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* /*builder*/) + { + header->vertexShader = Components::AssetHandler::FindOriginalAsset(this->getType(), name.data()).vertexShader; + } + + void IMaterialVertexShader::loadBinary(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) + { + Components::FileSystem::File vsFile(Utils::String::VA("vs/%s.iw4xVS", name.data())); + if (!vsFile.exists()) return; + + Utils::Stream::Reader reader(builder->getAllocator(), vsFile.getBuffer()); + + char* magic = reader.readArray(8); + if (std::memcmp(magic, "IW4xVERT", 8)) + { + Components::Logger::Error(0, "Reading vertex shader '%s' failed, header is invalid!", name.data()); + } + + std::string version; + version.push_back(reader.read()); + if (version != IW4X_TECHSET_VERSION) + { + Components::Logger::Error("Reading vertex shader '%s' failed, expected version is %d, but it was %d!", name.data(), atoi(IW4X_TECHSET_VERSION), atoi(version.data())); + } + + Game::MaterialVertexShader* asset = reader.readObject(); + + if (asset->name) + { + asset->name = reader.readCString(); + } + + if (asset->prog.loadDef.program) + { + asset->prog.loadDef.program = reader.readArray(asset->prog.loadDef.programSize); + } + + header->vertexShader = asset; + } + void IMaterialVertexShader::save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) { AssertSize(Game::MaterialVertexShader, 16); diff --git a/src/Components/Modules/AssetInterfaces/IMaterialVertexShader.hpp b/src/Components/Modules/AssetInterfaces/IMaterialVertexShader.hpp index 38ef637d..25150635 100644 --- a/src/Components/Modules/AssetInterfaces/IMaterialVertexShader.hpp +++ b/src/Components/Modules/AssetInterfaces/IMaterialVertexShader.hpp @@ -8,5 +8,9 @@ namespace Assets virtual Game::XAssetType getType() override { return Game::XAssetType::ASSET_TYPE_VERTEXSHADER; }; virtual void save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override; + virtual void load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) override; + + void loadNative(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder); + void loadBinary(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder); }; } diff --git a/src/Components/Modules/AssetInterfaces/IXModel.cpp b/src/Components/Modules/AssetInterfaces/IXModel.cpp index 9145a54e..cdcee206 100644 --- a/src/Components/Modules/AssetInterfaces/IXModel.cpp +++ b/src/Components/Modules/AssetInterfaces/IXModel.cpp @@ -17,7 +17,7 @@ namespace Assets } } - void IXModel::loadXSurface(Game::XSurface* surf, Utils::Stream::Reader* reader) + void IXModel::loadXSurface(Game::XSurface* surf, Utils::Stream::Reader* reader, Components::ZoneBuilder::Zone* builder) { if (surf->vertInfo.vertsBlend) { @@ -48,13 +48,23 @@ namespace Assets } // Access index block - if (surf->triIndices) - { - surf->triIndices = reader->readArray(surf->triCount * 3); - } + if (surf->triIndices) + { + void* oldPtr = surf->triIndices; + surf->triIndices = reader->readArray(surf->triCount * 3); + + if (builder->getAllocator()->isPointerMapped(oldPtr)) + { + surf->triIndices = builder->getAllocator()->getPointer(oldPtr); + } + else + { + builder->getAllocator()->mapPointer(oldPtr, surf->triIndices); + } + } } - void IXModel::loadXModelSurfs(Game::XModelSurfs* asset, Utils::Stream::Reader* reader) + void IXModel::loadXModelSurfs(Game::XModelSurfs* asset, Utils::Stream::Reader* reader, Components::ZoneBuilder::Zone* builder) { if (asset->name) { @@ -67,7 +77,7 @@ namespace Assets for (int i = 0; i < asset->numsurfs; ++i) { - this->loadXSurface(&asset->surfs[i], reader); + this->loadXSurface(&asset->surfs[i], reader, builder); } } } @@ -165,7 +175,7 @@ namespace Assets if (asset->lodInfo[i].modelSurfs) { asset->lodInfo[i].modelSurfs = reader.readObject(); - this->loadXModelSurfs(asset->lodInfo[i].modelSurfs, &reader); + this->loadXModelSurfs(asset->lodInfo[i].modelSurfs, &reader, builder); Components::AssetHandler::StoreTemporaryAsset(Game::XAssetType::ASSET_TYPE_XMODEL_SURFS, { asset->lodInfo[i].modelSurfs }); asset->lodInfo[i].surfs = asset->lodInfo[i].modelSurfs->surfs; @@ -293,7 +303,7 @@ namespace Assets } Components::AssetHandler::StoreTemporaryAsset(Game::XAssetType::ASSET_TYPE_PHYSCOLLMAP, { asset->physCollmap }); - //asset->physCollmap = nullptr; + // asset->physCollmap = nullptr; } } diff --git a/src/Components/Modules/AssetInterfaces/IXModel.hpp b/src/Components/Modules/AssetInterfaces/IXModel.hpp index 3475c9c7..8f0fec30 100644 --- a/src/Components/Modules/AssetInterfaces/IXModel.hpp +++ b/src/Components/Modules/AssetInterfaces/IXModel.hpp @@ -12,8 +12,9 @@ namespace Assets virtual void load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) override; private: - void loadXModelSurfs(Game::XModelSurfs* asset, Utils::Stream::Reader* reader); - void loadXSurface(Game::XSurface* surf, Utils::Stream::Reader* reader); + std::map triIndicies; + void loadXModelSurfs(Game::XModelSurfs* asset, Utils::Stream::Reader* reader, Components::ZoneBuilder::Zone* builder); + void loadXSurface(Game::XSurface* surf, Utils::Stream::Reader* reader, Components::ZoneBuilder::Zone* builder); void loadXSurfaceCollisionTree(Game::XSurfaceCollisionTree* entry, Utils::Stream::Reader* reader); }; } diff --git a/src/Components/Modules/AssetInterfaces/IXModelSurfs.cpp b/src/Components/Modules/AssetInterfaces/IXModelSurfs.cpp index bcbaa7fe..6c67932b 100644 --- a/src/Components/Modules/AssetInterfaces/IXModelSurfs.cpp +++ b/src/Components/Modules/AssetInterfaces/IXModelSurfs.cpp @@ -81,12 +81,16 @@ namespace Assets // Access index block buffer->pushBlock(Game::XFILE_BLOCK_INDEX); - if (surf->triIndices) - { - buffer->align(Utils::Stream::ALIGN_16); - buffer->saveArray(surf->triIndices, surf->triCount * 3); - Utils::Stream::ClearPointer(&destSurf->triIndices); - } + if (builder->hasPointer(surf->triIndices)) + { + destSurf->triIndices = builder->getPointer(surf->triIndices); + } + else + { + buffer->align(Utils::Stream::ALIGN_16); + buffer->saveArray(surf->triIndices, surf->triCount * 3); + Utils::Stream::ClearPointer(&destSurf->triIndices); + } buffer->popBlock(); } diff --git a/src/Components/Modules/QuickPatch.cpp b/src/Components/Modules/QuickPatch.cpp index 40f50e62..d4ae5ce2 100644 --- a/src/Components/Modules/QuickPatch.cpp +++ b/src/Components/Modules/QuickPatch.cpp @@ -745,18 +745,21 @@ namespace Components if (!Game::CL_IsCgameInitialized() || !Dvar::Var("r_drawAabbTrees").get()) return; float cyan[4] = { 0.0f, 0.5f, 0.5f, 1.0f }; + float red[4] = { 1.0f, 0.0f, 0.0f, 1.0f }; - //Game::clipMap_t* clipMap = *reinterpret_cast(0x7998E0); - Game::GfxWorld* gameWorld = *reinterpret_cast(0x66DEE94); - if (!gameWorld) return; + Game::clipMap_t* clipMap = *reinterpret_cast(0x7998E0); + //Game::GfxWorld* gameWorld = *reinterpret_cast(0x66DEE94); + if (!clipMap) return; - for (int i = 0; i < gameWorld->dpvsPlanes.cellCount; ++i) - { - for (int j = 0; j < gameWorld->aabbTreeCounts[i].aabbTreeCount; ++j) - { - Game::R_AddDebugBounds(cyan, &gameWorld->aabbTrees[i].aabbTree[j].bounds); - } - } + for (unsigned short i = 0; i < clipMap->smodelNodeCount; ++i) + { + Game::R_AddDebugBounds(cyan, &clipMap->smodelNodes[i].bounds); + } + + for (unsigned int i = 0; i < clipMap->numStaticModels; i += 2) + { + Game::R_AddDebugBounds(red, &clipMap->staticModelList[i].absBounds); + } }); diff --git a/src/Components/Modules/ZoneBuilder.cpp b/src/Components/Modules/ZoneBuilder.cpp index 6cd757c8..2e42a819 100644 --- a/src/Components/Modules/ZoneBuilder.cpp +++ b/src/Components/Modules/ZoneBuilder.cpp @@ -223,8 +223,7 @@ namespace Components Game::XAssetHeader assetHeader = AssetHandler::FindAssetForZone(type, name, this, isSubAsset); if (!assetHeader.data) - { - Logger::Error("Error: Missing asset '%s' of type '%s'\n", name.data(), Game::DB_GetXAssetTypeName(type)); + { Logger::Error("Error: Missing asset '%s' of type '%s'\n", name.data(), Game::DB_GetXAssetTypeName(type)); return false; } @@ -708,7 +707,7 @@ namespace Components { Game::XAssetEntry* entry = Game::DB_FindXAssetEntry(type, name.data()); - if (entry->zoneIndex == zoneIndex) + if (entry && entry->zoneIndex == zoneIndex) { // Allocate an empty asset (filled with zeros) header.data = builder->getAllocator()->allocate(Game::DB_GetXAssetSizeHandlers[type]());