From 72a7f8c226dd59dc860469249f8f6f80d5b1cce7 Mon Sep 17 00:00:00 2001 From: TheApadayo Date: Wed, 28 Dec 2016 21:30:34 -0500 Subject: [PATCH] [clipMap_t] added clip map importer --- .../Modules/AssetInterfaces/IMapEnts.cpp | 9 +- .../Modules/AssetInterfaces/IclipMap_t.cpp | 1222 ++++++++++------- 2 files changed, 738 insertions(+), 493 deletions(-) diff --git a/src/Components/Modules/AssetInterfaces/IMapEnts.cpp b/src/Components/Modules/AssetInterfaces/IMapEnts.cpp index 0912a8ca..7ba68fe4 100644 --- a/src/Components/Modules/AssetInterfaces/IMapEnts.cpp +++ b/src/Components/Modules/AssetInterfaces/IMapEnts.cpp @@ -4,7 +4,14 @@ namespace Assets { void IMapEnts::load(Game::XAssetHeader* header, std::string name, Components::ZoneBuilder::Zone* builder) { - Components::FileSystem::File ents(name + ".ents"); + std::string basename(name); + + basename.erase(0, 8); + basename.erase(basename.end() - 7, basename.end()); + + Components::Logger::Print("Using basename %s for mapents %s\n", basename.c_str(), name.c_str()); + + Components::FileSystem::File ents(Utils::String::VA("mapents/%s.ents", basename.c_str())); if (ents.exists()) { Game::MapEnts* entites = builder->getAllocator()->allocate(); diff --git a/src/Components/Modules/AssetInterfaces/IclipMap_t.cpp b/src/Components/Modules/AssetInterfaces/IclipMap_t.cpp index 571f3d71..14349201 100644 --- a/src/Components/Modules/AssetInterfaces/IclipMap_t.cpp +++ b/src/Components/Modules/AssetInterfaces/IclipMap_t.cpp @@ -1,30 +1,32 @@ -#include - -namespace Assets -{ - void IclipMap_t::save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) - { - AssertSize(Game::clipMap_t, 256); - SaveLogEnter("clipMap_t"); - - Utils::Stream* buffer = builder->getBuffer(); - Game::clipMap_t* asset = header.clipMap; - Game::clipMap_t* dest = buffer->dest(); - buffer->save(asset); - - buffer->pushBlock(Game::XFILE_BLOCK_VIRTUAL); - +#include + +#define IW4X_CLIPMAP_VERSION 1 + +namespace Assets +{ + void IclipMap_t::save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) + { + AssertSize(Game::clipMap_t, 256); + SaveLogEnter("clipMap_t"); + + Utils::Stream* buffer = builder->getBuffer(); + Game::clipMap_t* asset = header.clipMap; + Game::clipMap_t* dest = buffer->dest(); + buffer->save(asset); + + buffer->pushBlock(Game::XFILE_BLOCK_VIRTUAL); + if (asset->name) { buffer->saveString(builder->getAssetName(this->getType(), asset->name)); Utils::Stream::ClearPointer(&dest->name); - } - - if (asset->cPlanes) - { - AssertSize(Game::cplane_t, 20); - SaveLogEnter("cplane_t"); - + } + + if (asset->cPlanes) + { + AssertSize(Game::cplane_t, 20); + SaveLogEnter("cplane_t"); + if (builder->hasPointer(asset->cPlanes)) { dest->cPlanes = builder->getPointer(asset->cPlanes); @@ -32,81 +34,81 @@ namespace Assets else { buffer->align(Utils::Stream::ALIGN_4); - - // not sure if this is neede but both brushside and brushedge need it and it can't hurt - for(int i = 0; i < asset->numCPlanes; i++) - { - builder->storePointer(&asset->cPlanes[i]); - buffer->save(&asset->cPlanes[i]); - } + + // not sure if this is neede but both brushside and brushedge need it and it can't hurt + for(int i = 0; i < asset->numCPlanes; i++) + { + builder->storePointer(&asset->cPlanes[i]); + buffer->save(&asset->cPlanes[i]); + } Utils::Stream::ClearPointer(&dest->cPlanes); - } - - SaveLogExit(); - } - - if (asset->staticModelList) - { - - AssertSize(Game::cStaticModel_t, 76); - SaveLogEnter("cStaticModel_t"); - - // xmodel is already stored - buffer->align(Utils::Stream::ALIGN_4); - Game::cStaticModel_t* destStaticModelList = buffer->dest(); - buffer->saveArray(asset->staticModelList, asset->numStaticModels); - - for (int i = 0; i < asset->numStaticModels; ++i) - { - if (asset->staticModelList[i].xmodel) - { - destStaticModelList[i].xmodel = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_XMODEL, asset->staticModelList[i].xmodel).model; - } - } - - Utils::Stream::ClearPointer(&dest->staticModelList); - SaveLogExit(); - } - - if (asset->materials) - { - AssertSize(Game::ClipMaterial, 12); - SaveLogEnter("ClipMaterial"); - - buffer->align(Utils::Stream::ALIGN_4); - Game::ClipMaterial* mats = buffer->dest(); - buffer->saveArray(asset->materials, asset->numMaterials); - - for (int i = 0; i < asset->numMaterials; ++i) - { - buffer->saveString(asset->materials[i].name); - Utils::Stream::ClearPointer(&mats[i].name); - } - - Utils::Stream::ClearPointer(&dest->materials); - SaveLogExit(); - } - - if (asset->cBrushSides) - { - AssertSize(Game::cbrushside_t, 8); - SaveLogEnter("cbrushside_t"); - - buffer->align(Utils::Stream::ALIGN_4); - Game::cbrushside_t* sides = buffer->dest(); - // we need the pointer to each of these to be stored so we can't write them all at once - for(int i = 0; i < asset->numCBrushSides; ++i) - { - builder->storePointer(&asset->cBrushSides[i]); // for reference in cBrush - buffer->save(&asset->cBrushSides[i]); - } - - for (int i = 0; i < asset->numCBrushSides; ++i) - { - if (sides[i].side) - { - AssertSize(Game::cplane_t, 20); - + } + + SaveLogExit(); + } + + if (asset->staticModelList) + { + + AssertSize(Game::cStaticModel_t, 76); + SaveLogEnter("cStaticModel_t"); + + // xmodel is already stored + buffer->align(Utils::Stream::ALIGN_4); + Game::cStaticModel_t* destStaticModelList = buffer->dest(); + buffer->saveArray(asset->staticModelList, asset->numStaticModels); + + for (int i = 0; i < asset->numStaticModels; ++i) + { + if (asset->staticModelList[i].xmodel) + { + destStaticModelList[i].xmodel = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_XMODEL, asset->staticModelList[i].xmodel).model; + } + } + + Utils::Stream::ClearPointer(&dest->staticModelList); + SaveLogExit(); + } + + if (asset->materials) + { + AssertSize(Game::ClipMaterial, 12); + SaveLogEnter("ClipMaterial"); + + buffer->align(Utils::Stream::ALIGN_4); + Game::ClipMaterial* mats = buffer->dest(); + buffer->saveArray(asset->materials, asset->numMaterials); + + for (int i = 0; i < asset->numMaterials; ++i) + { + buffer->saveString(asset->materials[i].name); + Utils::Stream::ClearPointer(&mats[i].name); + } + + Utils::Stream::ClearPointer(&dest->materials); + SaveLogExit(); + } + + if (asset->cBrushSides) + { + AssertSize(Game::cbrushside_t, 8); + SaveLogEnter("cbrushside_t"); + + buffer->align(Utils::Stream::ALIGN_4); + Game::cbrushside_t* sides = buffer->dest(); + // we need the pointer to each of these to be stored so we can't write them all at once + for(int i = 0; i < asset->numCBrushSides; ++i) + { + builder->storePointer(&asset->cBrushSides[i]); // for reference in cBrush + buffer->save(&asset->cBrushSides[i]); + } + + for (int i = 0; i < asset->numCBrushSides; ++i) + { + if (sides[i].side) + { + AssertSize(Game::cplane_t, 20); + if (builder->hasPointer(sides[i].side)) { sides[i].side = builder->getPointer(sides[i].side); @@ -115,45 +117,45 @@ namespace Assets { buffer->align(Utils::Stream::ALIGN_4); builder->storePointer(sides[i].side); - - buffer->save(sides[i].side); + + buffer->save(sides[i].side); Utils::Stream::ClearPointer(&sides[i].side); - } - } - } - - Utils::Stream::ClearPointer(&dest->cBrushSides); - SaveLogExit(); - } - - if (asset->cBrushEdges) - { - SaveLogEnter("cBrushEdge"); - - // no align for char - for(int i = 0; i < asset->numCBrushEdges; ++i) - { - builder->storePointer(&asset->cBrushEdges[i]); // for reference in cBrush - buffer->save(&asset->cBrushEdges[i]); - } - Utils::Stream::ClearPointer(&dest->cBrushEdges); - - SaveLogExit(); - } - - if (asset->cNodes) - { - AssertSize(Game::cNode_t, 8); - SaveLogEnter("cNode_t"); - - buffer->align(Utils::Stream::ALIGN_4); - Game::cNode_t* nodes = buffer->dest(); - buffer->saveArray(asset->cNodes, asset->numCNodes); - - for (int i = 0; i < asset->numCNodes; ++i) - { - if (nodes[i].plane) - { + } + } + } + + Utils::Stream::ClearPointer(&dest->cBrushSides); + SaveLogExit(); + } + + if (asset->cBrushEdges) + { + SaveLogEnter("cBrushEdge"); + + // no align for char + for(int i = 0; i < asset->numCBrushEdges; ++i) + { + builder->storePointer(&asset->cBrushEdges[i]); // for reference in cBrush + buffer->save(&asset->cBrushEdges[i]); + } + Utils::Stream::ClearPointer(&dest->cBrushEdges); + + SaveLogExit(); + } + + if (asset->cNodes) + { + AssertSize(Game::cNode_t, 8); + SaveLogEnter("cNode_t"); + + buffer->align(Utils::Stream::ALIGN_4); + Game::cNode_t* nodes = buffer->dest(); + buffer->saveArray(asset->cNodes, asset->numCNodes); + + for (int i = 0; i < asset->numCNodes; ++i) + { + if (nodes[i].plane) + { if (builder->hasPointer(nodes[i].plane)) { nodes[i].plane = builder->getPointer(nodes[i].plane); @@ -162,54 +164,54 @@ namespace Assets { buffer->align(Utils::Stream::ALIGN_4); builder->storePointer(nodes[i].plane); - - buffer->save(nodes[i].plane); + + buffer->save(nodes[i].plane); Utils::Stream::ClearPointer(&nodes[i].plane); - } - } - } - - Utils::Stream::ClearPointer(&dest->cNodes); - SaveLogExit(); - } - - if (asset->cLeaf) - { - AssertSize(Game::cLeaf_t, 40); - SaveLogEnter("cLeaf_t"); - - buffer->align(Utils::Stream::ALIGN_4); - buffer->saveArray(asset->cLeaf, asset->numCLeaf); - Utils::Stream::ClearPointer(&dest->cLeaf); - SaveLogExit(); - } - - if (asset->leafBrushes) - { - SaveLogEnter("cLeafBrush_t"); - - buffer->align(Utils::Stream::ALIGN_2); - buffer->saveArray(asset->leafBrushes, asset->numLeafBrushes); - Utils::Stream::ClearPointer(&dest->leafBrushes); - - SaveLogExit(); - } - - if (asset->cLeafBrushNodes) - { - AssertSize(Game::cLeafBrushNode_t, 20); - SaveLogEnter("cLeafBrushNode_t"); - - buffer->align(Utils::Stream::ALIGN_4); - Game::cLeafBrushNode_t* node = buffer->dest(); - buffer->saveArray(asset->cLeafBrushNodes, asset->numCLeafBrushNodes); - - for (int i = 0; i < asset->numCLeafBrushNodes; ++i) - { - if (node[i].leafBrushCount > 0) - { - if (node[i].data.brushes) - { + } + } + } + + Utils::Stream::ClearPointer(&dest->cNodes); + SaveLogExit(); + } + + if (asset->cLeaf) + { + AssertSize(Game::cLeaf_t, 40); + SaveLogEnter("cLeaf_t"); + + buffer->align(Utils::Stream::ALIGN_4); + buffer->saveArray(asset->cLeaf, asset->numCLeaf); + Utils::Stream::ClearPointer(&dest->cLeaf); + SaveLogExit(); + } + + if (asset->leafBrushes) + { + SaveLogEnter("cLeafBrush_t"); + + buffer->align(Utils::Stream::ALIGN_2); + buffer->saveArray(asset->leafBrushes, asset->numLeafBrushes); + Utils::Stream::ClearPointer(&dest->leafBrushes); + + SaveLogExit(); + } + + if (asset->cLeafBrushNodes) + { + AssertSize(Game::cLeafBrushNode_t, 20); + SaveLogEnter("cLeafBrushNode_t"); + + buffer->align(Utils::Stream::ALIGN_4); + Game::cLeafBrushNode_t* node = buffer->dest(); + buffer->saveArray(asset->cLeafBrushNodes, asset->numCLeafBrushNodes); + + for (int i = 0; i < asset->numCLeafBrushNodes; ++i) + { + if (node[i].leafBrushCount > 0) + { + if (node[i].data.brushes) + { if (builder->hasPointer(node[i].data.brushes)) { node[i].data.brushes = builder->getPointer(node[i].data.brushes); @@ -223,84 +225,84 @@ namespace Assets builder->storePointer(&node[i].data.brushes[j]); buffer->save(&node[i].data.brushes[j]); } - + Utils::Stream::ClearPointer(&node[i].data.brushes); - } - } - } - } - - Utils::Stream::ClearPointer(&dest->cLeafBrushNodes); - SaveLogExit(); - } - - if (asset->leafSurfaces) - { - SaveLogEnter("cLeafSurface_t"); - - buffer->align(Utils::Stream::ALIGN_4); - buffer->saveArray(asset->leafSurfaces, asset->numLeafSurfaces); - Utils::Stream::ClearPointer(&dest->leafSurfaces); - - SaveLogExit(); - } - - if (asset->verts) - { - AssertSize(Game::vec3_t, 12); - - buffer->align(Utils::Stream::ALIGN_4); - buffer->saveArray(asset->verts, asset->numVerts); - Utils::Stream::ClearPointer(&dest->verts); - } - - if (asset->triIndices) - { - buffer->align(Utils::Stream::ALIGN_2); - buffer->save(asset->triIndices, 6, asset->numTriIndices); - Utils::Stream::ClearPointer(&dest->triIndices); - } - - if (asset->triEdgeIsWalkable) - { - // no align for char - buffer->save(asset->triEdgeIsWalkable, 1, 4 * ((3 * asset->numTriIndices + 31) >> 5)); - Utils::Stream::ClearPointer(&dest->triEdgeIsWalkable); - } - - if (asset->collisionBorders) - { - AssertSize(Game::CollisionBorder, 28); - SaveLogEnter("CollisionBorder"); - - buffer->align(Utils::Stream::ALIGN_4); - + } + } + } + } + + Utils::Stream::ClearPointer(&dest->cLeafBrushNodes); + SaveLogExit(); + } + + if (asset->leafSurfaces) + { + SaveLogEnter("cLeafSurface_t"); + + buffer->align(Utils::Stream::ALIGN_4); + buffer->saveArray(asset->leafSurfaces, asset->numLeafSurfaces); + Utils::Stream::ClearPointer(&dest->leafSurfaces); + + SaveLogExit(); + } + + if (asset->verts) + { + AssertSize(Game::vec3_t, 12); + + buffer->align(Utils::Stream::ALIGN_4); + buffer->saveArray(asset->verts, asset->numVerts); + Utils::Stream::ClearPointer(&dest->verts); + } + + if (asset->triIndices) + { + buffer->align(Utils::Stream::ALIGN_2); + buffer->save(asset->triIndices, 6, asset->numTriIndices); + Utils::Stream::ClearPointer(&dest->triIndices); + } + + if (asset->triEdgeIsWalkable) + { + // no align for char + buffer->save(asset->triEdgeIsWalkable, 1, 4 * ((3 * asset->numTriIndices + 31) >> 5)); + Utils::Stream::ClearPointer(&dest->triEdgeIsWalkable); + } + + if (asset->collisionBorders) + { + AssertSize(Game::CollisionBorder, 28); + SaveLogEnter("CollisionBorder"); + + buffer->align(Utils::Stream::ALIGN_4); + for (int i = 0; i < asset->numCollisionBorders; ++i) { builder->storePointer(&asset->collisionBorders[i]); buffer->save(&asset->collisionBorders[i]); - } - - Utils::Stream::ClearPointer(&dest->collisionBorders); - SaveLogExit(); - } - - if (asset->collisionPartitions) - { - AssertSize(Game::CollisionPartition, 12); - SaveLogEnter("CollisionPartition"); - - buffer->align(Utils::Stream::ALIGN_4); - Game::CollisionPartition* destPartitions = buffer->dest(); - buffer->saveArray(asset->collisionPartitions, asset->numCollisionPartitions); - - for (int i = 0; i < asset->numCollisionPartitions; ++i) - { - Game::CollisionPartition* destPartition = &destPartitions[i]; - Game::CollisionPartition* partition = &asset->collisionPartitions[i]; - - if (partition->borders) - { + } + + Utils::Stream::ClearPointer(&dest->collisionBorders); + SaveLogExit(); + } + + if (asset->collisionPartitions) + { + AssertSize(Game::CollisionPartition, 12); + SaveLogEnter("CollisionPartition"); + + buffer->align(Utils::Stream::ALIGN_4); + Game::CollisionPartition* destPartitions = buffer->dest(); + buffer->saveArray(asset->collisionPartitions, asset->numCollisionPartitions); + + for (int i = 0; i < asset->numCollisionPartitions; ++i) + { + Game::CollisionPartition* destPartition = &destPartitions[i]; + Game::CollisionPartition* partition = &asset->collisionPartitions[i]; + + if (partition->borders) + { if (builder->hasPointer(partition->borders)) { destPartition->borders = builder->getPointer(partition->borders); @@ -308,75 +310,75 @@ namespace Assets else { buffer->align(Utils::Stream::ALIGN_4); - builder->storePointer(partition->borders); - buffer->save(partition->borders); + builder->storePointer(partition->borders); + buffer->save(partition->borders); Utils::Stream::ClearPointer(&destPartition->borders); - } - } - } - - Utils::Stream::ClearPointer(&dest->collisionPartitions); - SaveLogExit(); - } - - if (asset->collisionAABBTrees) - { - AssertSize(Game::CollisionAabbTree, 32); - SaveLogEnter("CollisionAabbTree"); - - buffer->align(Utils::Stream::ALIGN_16); - buffer->saveArray(asset->collisionAABBTrees, asset->numCollisionAABBTrees); - Utils::Stream::ClearPointer(&dest->collisionAABBTrees); - - SaveLogExit(); - } - - if (asset->cModels) - { - AssertSize(Game::cmodel_t, 68); - SaveLogEnter("cmodel_t"); - - buffer->align(Utils::Stream::ALIGN_4); - buffer->saveArray(asset->cModels, asset->numCModels); - Utils::Stream::ClearPointer(&dest->cModels); - - SaveLogExit(); - } - - if (asset->cBrushes) - { - AssertSize(Game::cbrush_t, 36); - SaveLogEnter("cbrush_t"); - - buffer->align(Utils::Stream::ALIGN_128); - Game::cbrush_t* destBrushes = buffer->dest(); - buffer->saveArray(asset->cBrushes, asset->numCBrushes); - - for (short i = 0; i < asset->numCBrushes; ++i) - { - Game::cbrush_t* destBrush = &destBrushes[i]; - Game::cbrush_t* brush = &asset->cBrushes[i]; - - if (brush->brushSide) - { + } + } + } + + Utils::Stream::ClearPointer(&dest->collisionPartitions); + SaveLogExit(); + } + + if (asset->collisionAABBTrees) + { + AssertSize(Game::CollisionAabbTree, 32); + SaveLogEnter("CollisionAabbTree"); + + buffer->align(Utils::Stream::ALIGN_16); + buffer->saveArray(asset->collisionAABBTrees, asset->numCollisionAABBTrees); + Utils::Stream::ClearPointer(&dest->collisionAABBTrees); + + SaveLogExit(); + } + + if (asset->cModels) + { + AssertSize(Game::cmodel_t, 68); + SaveLogEnter("cmodel_t"); + + buffer->align(Utils::Stream::ALIGN_4); + buffer->saveArray(asset->cModels, asset->numCModels); + Utils::Stream::ClearPointer(&dest->cModels); + + SaveLogExit(); + } + + if (asset->cBrushes) + { + AssertSize(Game::cbrush_t, 36); + SaveLogEnter("cbrush_t"); + + buffer->align(Utils::Stream::ALIGN_128); + Game::cbrush_t* destBrushes = buffer->dest(); + buffer->saveArray(asset->cBrushes, asset->numCBrushes); + + for (short i = 0; i < asset->numCBrushes; ++i) + { + Game::cbrush_t* destBrush = &destBrushes[i]; + Game::cbrush_t* brush = &asset->cBrushes[i]; + + if (brush->brushSide) + { if (builder->hasPointer(brush->brushSide)) { destBrush->brushSide = builder->getPointer(brush->brushSide); } else { - AssertSize(Game::cbrushside_t, 8); - - MessageBoxA(0, "BrushSide shouldn't be written in cBrush!", "WARNING", MB_ICONEXCLAMATION); - + AssertSize(Game::cbrushside_t, 8); + + MessageBoxA(0, "BrushSide shouldn't be written in cBrush!", "WARNING", MB_ICONEXCLAMATION); + buffer->align(Utils::Stream::ALIGN_4); builder->storePointer(brush->brushSide); - - Game::cbrushside_t* side = buffer->dest(); - buffer->save(brush->brushSide); - - if (brush->brushSide->side) - { + + Game::cbrushside_t* side = buffer->dest(); + buffer->save(brush->brushSide); + + if (brush->brushSide->side) + { if (builder->hasPointer(brush->brushSide->side)) { side->side = builder->getPointer(brush->brushSide->side); @@ -384,18 +386,18 @@ namespace Assets else { buffer->align(Utils::Stream::ALIGN_4); - builder->storePointer(brush->brushSide->side); - buffer->save(brush->brushSide->side); + builder->storePointer(brush->brushSide->side); + buffer->save(brush->brushSide->side); Utils::Stream::ClearPointer(&side->side); - } - } - + } + } + Utils::Stream::ClearPointer(&destBrush->brushSide); - } - } - - if (brush->brushEdge) - { + } + } + + if (brush->brushEdge) + { if (builder->hasPointer(brush->brushEdge)) { destBrush->brushEdge = builder->getPointer(brush->brushEdge); @@ -403,172 +405,408 @@ namespace Assets else { builder->storePointer(brush->brushEdge); - buffer->save(brush->brushEdge); + buffer->save(brush->brushEdge); Utils::Stream::ClearPointer(&destBrush->brushEdge); - } - } - } + } + } + } + + Utils::Stream::ClearPointer(&dest->cBrushes); + SaveLogExit(); + } + + if (asset->cBrushBounds) + { + AssertSize(Game::Bounds, 24); + SaveLogEnter("Bounds"); + + buffer->align(Utils::Stream::ALIGN_128); + buffer->saveArray(asset->cBrushBounds, asset->numCBrushes); + Utils::Stream::ClearPointer(&dest->cBrushBounds); + + SaveLogExit(); + } + + if (asset->cBrushContents) + { + buffer->align(Utils::Stream::ALIGN_4); + buffer->saveArray(asset->cBrushContents, asset->numCBrushes); + Utils::Stream::ClearPointer(&dest->cBrushContents); + } + + if (asset->unknown4) + { + AssertSize(Game::SModelAabbNode, 28); + SaveLogEnter("SModelAabbNode"); + + buffer->align(Utils::Stream::ALIGN_4); + buffer->saveArray(asset->unknown4, asset->unkCount4); + Utils::Stream::ClearPointer(&dest->unknown4); + + SaveLogExit(); + } + + if (asset->mapEnts) + { + dest->mapEnts = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_MAP_ENTS, asset->mapEnts).mapEnts; + } + + for (int i = 0; i < 2; ++i) + { + if (asset->dynEntDefList[i]) + { + AssertSize(Game::DynEntityDef, 92); + + buffer->align(Utils::Stream::ALIGN_4); + Game::DynEntityDef* dynEntDest = buffer->dest(); + buffer->saveArray(asset->dynEntDefList[i], asset->dynEntCount[i]); + + Game::DynEntityDef* dynEnt = asset->dynEntDefList[i]; + for (int j = 0; j < asset->dynEntCount[i]; ++j) + { + if (dynEnt[j].xModel) + { + dynEntDest[j].xModel = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_XMODEL, dynEnt[j].xModel).model; + } + + if (dynEnt[j].destroyFx) + { + dynEntDest[j].destroyFx = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_FX, dynEnt[j].destroyFx).fx; + } + + if (dynEnt[j].physPreset) + { + dynEntDest[j].physPreset = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_PHYSPRESET, dynEnt[j].physPreset).physPreset; + } + } + + Utils::Stream::ClearPointer(&dest->dynEntDefList[i]); + } + } + + buffer->pushBlock(Game::XFILE_BLOCK_RUNTIME); + + for (int i = 0; i < 2; ++i) + { + if (asset->dynEntPoseList[i]) + { + AssertSize(Game::DynEntityPose, 32); + + buffer->align(Utils::Stream::ALIGN_4); + buffer->saveArray(asset->dynEntPoseList[i], asset->dynEntCount[i]); + Utils::Stream::ClearPointer(&dest->dynEntPoseList[i]); + + } + } + + for (int i = 0; i < 2; ++i) + { + if (asset->dynEntClientList[i]) + { + AssertSize(Game::DynEntityClient, 12); + + buffer->align(Utils::Stream::ALIGN_4); + buffer->saveArray(asset->dynEntClientList[i], asset->dynEntCount[i]); + Utils::Stream::ClearPointer(&dest->dynEntClientList[i]); + } + } + + for (int i = 0; i < 2; ++i) + { + if (asset->dynEntCollList[i]) + { + AssertSize(Game::DynEntityColl, 20); + + buffer->align(Utils::Stream::ALIGN_4); + buffer->saveArray(asset->dynEntCollList[i], asset->dynEntCount[i]); + Utils::Stream::ClearPointer(&dest->dynEntCollList[i]); + } + } + + buffer->popBlock(); + buffer->popBlock(); + + SaveLogExit(); + } + + void IclipMap_t::mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) + { + Game::clipMap_t* asset = header.clipMap; + for (int i = 0; i < asset->numStaticModels; ++i) + { + Game::XModel* m = asset->staticModelList[i].xmodel; + if (m) + { + builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODEL, m); + } + } + + for (int j = 0; j < 2; ++j) + { + Game::DynEntityDef* def = asset->dynEntDefList[j]; + + for (int i = 0; i < asset->dynEntCount[j]; ++i) + { + if (def[i].xModel) + { + builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODEL, def[i].xModel); + } + + if (def[i].destroyFx) + { + builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, def[i].destroyFx); + } + + if (def[i].physPreset) + { + builder->loadAsset(Game::XAssetType::ASSET_TYPE_PHYSPRESET, def[i].physPreset); + } + } + } + builder->loadAsset(Game::XAssetType::ASSET_TYPE_MAP_ENTS, asset); + } + + void IclipMap_t::load(Game::XAssetHeader* /*header*/, std::string name, Components::ZoneBuilder::Zone* builder) + { + Game::clipMap_t* map = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_CLIPMAP_PVS, name.data()).clipMap; + if (map) return; + + std::string basename(name); - Utils::Stream::ClearPointer(&dest->cBrushes); - SaveLogExit(); - } - - if (asset->cBrushBounds) - { - AssertSize(Game::Bounds, 24); - SaveLogEnter("Bounds"); - - buffer->align(Utils::Stream::ALIGN_128); - buffer->saveArray(asset->cBrushBounds, asset->numCBrushes); - Utils::Stream::ClearPointer(&dest->cBrushBounds); - - SaveLogExit(); - } - - if (asset->cBrushContents) - { - buffer->align(Utils::Stream::ALIGN_4); - buffer->saveArray(asset->cBrushContents, asset->numCBrushes); - Utils::Stream::ClearPointer(&dest->cBrushContents); - } - - if (asset->unknown4) - { - AssertSize(Game::SModelAabbNode, 28); - SaveLogEnter("SModelAabbNode"); - - buffer->align(Utils::Stream::ALIGN_4); - buffer->saveArray(asset->unknown4, asset->unkCount4); - Utils::Stream::ClearPointer(&dest->unknown4); - - SaveLogExit(); - } - - if (asset->mapEnts) - { - dest->mapEnts = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_MAP_ENTS, asset->mapEnts).mapEnts; - } - - for (int i = 0; i < 2; ++i) - { - if (asset->dynEntDefList[i]) - { - AssertSize(Game::DynEntityDef, 92); - - buffer->align(Utils::Stream::ALIGN_4); - Game::DynEntityDef* dynEntDest = buffer->dest(); - buffer->saveArray(asset->dynEntDefList[i], asset->dynEntCount[i]); - - Game::DynEntityDef* dynEnt = asset->dynEntDefList[i]; - for (int j = 0; j < asset->dynEntCount[i]; ++j) - { - if (dynEnt[j].xModel) - { - dynEntDest[j].xModel = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_XMODEL, dynEnt[j].xModel).model; - } - - if (dynEnt[j].destroyFx) - { - dynEntDest[j].destroyFx = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_FX, dynEnt[j].destroyFx).fx; - } - - if (dynEnt[j].physPreset) - { - dynEntDest[j].physPreset = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_PHYSPRESET, dynEnt[j].physPreset).physPreset; - } - } - - Utils::Stream::ClearPointer(&dest->dynEntDefList[i]); - } - } - - buffer->pushBlock(Game::XFILE_BLOCK_RUNTIME); - - for (int i = 0; i < 2; ++i) - { - if (asset->dynEntPoseList[i]) - { - AssertSize(Game::DynEntityPose, 32); - - buffer->align(Utils::Stream::ALIGN_4); - buffer->saveArray(asset->dynEntPoseList[i], asset->dynEntCount[i]); - Utils::Stream::ClearPointer(&dest->dynEntPoseList[i]); - - } - } - - for (int i = 0; i < 2; ++i) - { - if (asset->dynEntClientList[i]) - { - AssertSize(Game::DynEntityClient, 12); - - buffer->align(Utils::Stream::ALIGN_4); - buffer->saveArray(asset->dynEntClientList[i], asset->dynEntCount[i]); - Utils::Stream::ClearPointer(&dest->dynEntClientList[i]); - } - } - - for (int i = 0; i < 2; ++i) - { - if (asset->dynEntCollList[i]) - { - AssertSize(Game::DynEntityColl, 20); - - buffer->align(Utils::Stream::ALIGN_4); - buffer->saveArray(asset->dynEntCollList[i], asset->dynEntCount[i]); - Utils::Stream::ClearPointer(&dest->dynEntCollList[i]); - } - } - - buffer->popBlock(); - buffer->popBlock(); - - SaveLogExit(); - } - - void IclipMap_t::mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) - { - Game::clipMap_t* asset = header.clipMap; - for (int i = 0; i < asset->numStaticModels; ++i) - { - Game::XModel* m = asset->staticModelList[i].xmodel; - if (m) - { - builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODEL, m); - } - } - - for (int j = 0; j < 2; ++j) - { - Game::DynEntityDef* def = asset->dynEntDefList[j]; - - for (int i = 0; i < asset->dynEntCount[j]; ++i) - { - if (def[i].xModel) - { - builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODEL, def[i].xModel); - } - - if (def[i].destroyFx) - { - builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, def[i].destroyFx); - } - - if (def[i].physPreset) - { - builder->loadAsset(Game::XAssetType::ASSET_TYPE_PHYSPRESET, def[i].physPreset); - } - } - } - builder->loadAsset(Game::XAssetType::ASSET_TYPE_MAP_ENTS, asset); - } - - void IclipMap_t::load(Game::XAssetHeader* /*header*/, std::string name, Components::ZoneBuilder::Zone* /*builder*/) - { - Game::clipMap_t* map = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_CLIPMAP_PVS, name.data()).clipMap; - if (map) return; - - Components::Logger::Error("Missing clipMap_t %s... you can't make them yet you idiot.", name.data()); - } -} + basename.erase(0, 8); + basename.erase(basename.end() - 7, basename.end()); + + Components::FileSystem::File clipFile(fmt::sprintf("clipmap/%s.iw4xClipMap", basename.data())); + if (!clipFile.exists()) return; + + Game::clipMap_t* clipMap = builder->getAllocator()->allocate(); + if (!clipMap) + { + Components::Logger::Print("Error allocating memory for clipMap_t structure!\n"); + return; + } + + Utils::Stream::Reader reader(builder->getAllocator(), clipFile.getBuffer()); + + if (reader.read<__int64>() != *reinterpret_cast<__int64*>("IW4xClip")) + { + Components::Logger::Error(0, "Reading clipMap_t '%s' failed, header is invalid!", name.data()); + } + + int version = reader.read(); + if (version != IW4X_CLIPMAP_VERSION) + { + Components::Logger::Error(0, "Reading clipmap '%s' failed, expected version is %d, but it was %d!", name.data(), IW4X_CLIPMAP_VERSION, version); + } + + clipMap->name = reader.readCString(); + + clipMap->numCPlanes = reader.read(); + clipMap->numStaticModels = reader.read(); + clipMap->numMaterials = reader.read(); + clipMap->numCBrushSides = reader.read(); + clipMap->numCBrushEdges = reader.read(); + clipMap->numCNodes = reader.read(); + clipMap->numCLeaf = reader.read(); + clipMap->numCLeafBrushNodes = reader.read(); + clipMap->numLeafBrushes = reader.read(); + clipMap->numLeafSurfaces = reader.read(); + clipMap->numVerts = reader.read(); + clipMap->numTriIndices = reader.read(); + clipMap->numCollisionBorders = reader.read(); + clipMap->numCollisionPartitions = reader.read(); + clipMap->numCollisionAABBTrees = reader.read(); + clipMap->numCModels = reader.read(); + clipMap->numCBrushes = reader.read(); + clipMap->dynEntCount[0] = reader.read(); + clipMap->dynEntCount[1] = reader.read(); + + if (clipMap->numCPlanes) + { + clipMap->cPlanes = reader.readArray(clipMap->numCPlanes); + } + + if (clipMap->numStaticModels) + { + clipMap->staticModelList = reader.readArray(clipMap->numStaticModels); + } + + if (clipMap->numMaterials) + { + clipMap->materials = builder->getAllocator()->allocateArray(clipMap->numMaterials); + for (int i = 0; i < clipMap->numMaterials; ++i) + { + clipMap->materials[i].name = reader.readArray(64); + clipMap->materials[i].unk = reader.read(); + clipMap->materials[i].unk2 = reader.read(); + } + } + + if (clipMap->numCBrushSides) + { + clipMap->cBrushSides = builder->getAllocator()->allocateArray(clipMap->numCBrushSides); + for (int i = 0; i < clipMap->numCBrushSides; ++i) + { + int planeIndex = reader.read(); + clipMap->cBrushSides[i].side = &clipMap->cPlanes[planeIndex]; + // not sure how to fill out texInfo and dispInfo + // just leave zero for now + } + } + + if (clipMap->numCBrushEdges) + { + clipMap->cBrushEdges = reader.readArray(clipMap->numCBrushEdges); + } + + if (clipMap->numCNodes) + { + clipMap->cNodes = builder->getAllocator()->allocateArray(clipMap->numCNodes); + for (int i = 0; i < clipMap->numCNodes; ++i) + { + int planeIndex = reader.read(); + clipMap->cNodes[i].plane = &clipMap->cPlanes[planeIndex]; + clipMap->cNodes[i].children[0] = reader.read(); + clipMap->cNodes[i].children[1] = reader.read(); + } + } + + if (clipMap->numCLeaf) + { + clipMap->cLeaf = reader.readArray(clipMap->numCLeaf); + } + + if (clipMap->numCLeafBrushNodes) + { + clipMap->cLeafBrushNodes = builder->getAllocator()->allocateArray(clipMap->numCLeafBrushNodes); + for (int i = 0; i < clipMap->numCLeafBrushNodes; ++i) + { + Game::cLeafBrushNode_t tmp = reader.read(); + memcpy(&clipMap->cLeafBrushNodes[i], &tmp, sizeof(Game::cLeafBrushNode_t)); + + if (tmp.leafBrushCount > 0) + { + clipMap->cLeafBrushNodes[i].data.brushes = reader.readArray(tmp.leafBrushCount); + } + } + } + + if (clipMap->numLeafBrushes) + { + clipMap->leafBrushes = reader.readArray(clipMap->numLeafBrushes); + } + + if (clipMap->numLeafSurfaces) + { + clipMap->leafSurfaces = reader.readArray(clipMap->numLeafSurfaces); + } + + if (clipMap->numVerts) + { + clipMap->verts = reader.readArray(clipMap->numVerts); + } + + if (clipMap->numTriIndices) + { + clipMap->triIndices = reader.readArray(clipMap->numTriIndices * 3); + clipMap->triEdgeIsWalkable = reader.readArray(4 * ((3 * clipMap->numTriIndices + 31) >> 5)); + } + + if (clipMap->numCollisionBorders) + { + clipMap->collisionBorders = reader.readArray(clipMap->numCollisionBorders); + } + + if (clipMap->numCollisionPartitions) + { + clipMap->collisionPartitions = builder->getAllocator()->allocateArray(clipMap->numCollisionPartitions); + for (int i = 0; i < clipMap->numCollisionPartitions; ++i) + { + clipMap->collisionPartitions[i].triCount = reader.read(); + clipMap->collisionPartitions[i].borderCount = reader.read(); + clipMap->collisionPartitions[i].firstTri = reader.read(); + + if (clipMap->collisionPartitions[i].borderCount > 0) + { + int index = reader.read(); + clipMap->collisionPartitions[i].borders = &clipMap->collisionBorders[index]; + } + } + } + + if (clipMap->numCollisionAABBTrees) + { + clipMap->collisionAABBTrees = reader.readArray(clipMap->numCollisionAABBTrees); + } + + if (clipMap->numCModels) + { + clipMap->cModels = reader.readArray(clipMap->numCModels); + } + + if (clipMap->numCBrushes) + { + clipMap->cBrushes = builder->getAllocator()->allocateArray(clipMap->numCBrushes); + for (int i = 0; i < clipMap->numCBrushes; ++i) + { + clipMap->cBrushes[i].count = reader.read(); + if (clipMap->cBrushes[i].count > 0) + { + int index = reader.read(); + clipMap->cBrushes[i].brushSide = &clipMap->cBrushSides[index]; + } + + int index = reader.read(); + clipMap->cBrushes[i].brushEdge = &clipMap->cBrushEdges[index]; + + reader.readArray(6); // don't know where these go + reader.readArray(6); + reader.readArray(6); + } + + clipMap->cBrushBounds = reader.readArray(clipMap->numCBrushes); + clipMap->cBrushContents = reader.readArray(clipMap->numCBrushes); + } + + for (int x = 0; x < 2; ++x) + { + if (clipMap->dynEntCount[x]) + { + clipMap->dynEntDefList[x] = builder->getAllocator()->allocateArray(clipMap->dynEntCount[x]); + for (int i = 0; i < clipMap->dynEntCount[x]; ++i) + { + clipMap->dynEntDefList[x][i].type = reader.read(); + clipMap->dynEntDefList[x][i].pose = reader.read(); + std::string tempName = reader.readString(); + if (tempName != "NONE"s) + { + clipMap->dynEntDefList[x][i].xModel = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_XMODEL, name, builder).model; + } + + clipMap->dynEntDefList[x][i].brushModel = reader.read(); + clipMap->dynEntDefList[x][i].physicsBrushModel = reader.read(); + + tempName = reader.readString(); + if (tempName != "NONE"s) + { + clipMap->dynEntDefList[x][i].destroyFx = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_FX, name, builder).fx; + } + + tempName = reader.readString(); + if (tempName != "NONE"s) + { + clipMap->dynEntDefList[x][i].physPreset = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_PHYSPRESET, name, builder).physPreset; + } + + clipMap->dynEntDefList[x][i].health = reader.read(); + clipMap->dynEntDefList[x][i].mass = reader.read(); + clipMap->dynEntDefList[x][i].contents = reader.read(); + } + } + } + + clipMap->checksum = reader.read(); + + clipMap->mapEnts = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_MAP_ENTS, basename.c_str(), builder).mapEnts; + } +}