zonetool/src/IW5/Assets/GfxWorld.cpp

1294 lines
40 KiB
C++

// ======================= ZoneTool =======================
// zonetool, a fastfile linker for various
// Call of Duty titles.
//
// Project: https://github.com/ZoneTool/zonetool
// Author: RektInator (https://github.com/RektInator)
// License: GNU GPL v3.0
// ========================================================
#include "stdafx.hpp"
namespace ZoneTool
{
namespace IW5
{
/*legacy zonetool code, refactor me!*/
GfxWorld* IGfxWorld::parse(const std::string& name, ZoneMemory* mem)
{
if (!FileSystem::FileExists(name + ".gfxmap"))
{
return nullptr;
}
// alloc GfxWorld
auto asset = mem->Alloc<GfxWorld>();
memset(asset, 0, sizeof(GfxWorld));
AssetReader read(mem);
if (!read.open(name + ".gfxmap"))
{
return nullptr;
}
ZONETOOL_INFO("Parsing GfxWorld \"%s\"...", name.data());
#ifdef USE_VMPROTECT
VMProtectBeginUltra("IW5::IGfxWorld::parse");
#endif
asset->name = read.read_string();
asset->baseName = read.read_string();
asset->planeCount = read.read_int();
asset->nodeCount = read.read_int();
asset->indexCount = read.read_int();
asset->skyCount = read.read_int();
asset->skies = read.read_array<GfxSky>();
for (unsigned int i = 0; i < asset->skyCount; i++)
{
asset->skies[i].skyStartSurfs = read.read_array<std::uint32_t>();
asset->skies[i].skyImage = read.read_asset<GfxImage>();
}
asset->sunPrimaryLightIndex = read.read_int();
asset->primaryLightCount = read.read_int();
asset->primaryLightEnvCount = read.read_int();
char* unknown1 = read.read_array<char>();
memcpy(asset->unknown1, unknown1, 12);
// dpvsplanes
asset->dpvsPlanes.cellCount = read.read_int();
asset->dpvsPlanes.planes = read.read_array<cplane_s>();
asset->dpvsPlanes.nodes = read.read_array<unsigned short>();
asset->dpvsPlanes.sceneEntCellBits = read.read_array<unsigned char>();
// dpvs
GfxWorldDpvsStatic* dpvs = read.read_array<GfxWorldDpvsStatic>();
memcpy(&asset->dpvs, dpvs, sizeof(GfxWorldDpvsStatic));
asset->dpvs.smodelVisData[0] = read.read_array<char>();
asset->dpvs.smodelVisData[1] = read.read_array<char>();
asset->dpvs.smodelVisData[2] = read.read_array<char>();
asset->dpvs.surfaceVisData[0] = read.read_array<char>();
asset->dpvs.surfaceVisData[1] = read.read_array<char>();
asset->dpvs.surfaceVisData[2] = read.read_array<char>();
asset->dpvs.sortedSurfIndex = read.read_array<unsigned short>();
asset->dpvs.smodelInsts = read.read_array<GfxStaticModelInst>();
asset->dpvs.surfaces = read.read_array<GfxSurface>();
for (int i = 0; i < asset->indexCount; i++)
{
asset->dpvs.surfaces[i].material = read.read_asset<Material>();
}
asset->dpvs.surfacesBounds = read.read_array<GfxSurfaceBounds>();
asset->dpvs.smodelDrawInsts = read.read_array<GfxStaticModelDrawInst>();
for (unsigned int i = 0; i < asset->dpvs.smodelCount; i++)
{
asset->dpvs.smodelDrawInsts[i].model = read.read_asset<XModel>();
}
asset->dpvs.surfaceMaterials = read.read_array<GfxDrawSurf>();
asset->dpvs.surfaceCastsSunShadow = read.read_array<unsigned int>();
// dpvsDyn
GfxWorldDpvsDynamic* dpvsDyn = read.read_array<GfxWorldDpvsDynamic>();
memcpy(&asset->dpvsDyn, dpvsDyn, sizeof(GfxWorldDpvsDynamic));
asset->dpvsDyn.dynEntCellBits[0] = read.read_array<unsigned int>();
asset->dpvsDyn.dynEntCellBits[1] = read.read_array<unsigned int>();
asset->dpvsDyn.dynEntVisData[0][0] = read.read_array<char>();
asset->dpvsDyn.dynEntVisData[1][0] = read.read_array<char>();
asset->dpvsDyn.dynEntVisData[0][1] = read.read_array<char>();
asset->dpvsDyn.dynEntVisData[1][1] = read.read_array<char>();
asset->dpvsDyn.dynEntVisData[0][2] = read.read_array<char>();
asset->dpvsDyn.dynEntVisData[1][2] = read.read_array<char>();
// aabbTreeCount
asset->aabbTreeCounts = read.read_array<GfxCellTreeCount>();
// GfxCellTree
asset->aabbTree = read.read_array<GfxCellTree>();
for (int i = 0; i < asset->dpvsPlanes.cellCount; i++)
{
asset->aabbTree[i].aabbtree = read.read_array<GfxAabbTree>();
for (int j = 0; j < asset->aabbTreeCounts[i].aabbTreeCount; j++)
{
asset->aabbTree[i].aabbtree[j].smodelIndexes = read.read_array<unsigned short>();
}
}
// read GFX cells
asset->cells = read.read_array<GfxCell>();
for (int i = 0; i < asset->dpvsPlanes.cellCount; i++)
{
asset->cells[i].portals = read.read_array<GfxPortal>();
for (int j = 0; j < asset->cells[i].portalCount; j++)
{
asset->cells[i].portals[j].vertices = read.read_array<float[3]>();
}
asset->cells[i].reflectionProbes = read.read_array<char>();
asset->cells[i].reflectionProbeReferences = read.read_array<char>();
}
auto worldDraw = read.read_array<GfxWorldDraw>();
memcpy(&asset->worldDraw, worldDraw, sizeof GfxWorldDraw);
asset->worldDraw.reflectionImages = mem->Alloc<GfxImage*>(asset->worldDraw.reflectionProbeCount);
// new GfxImage*[asset->draw.reflectionProbeCount];
memset(asset->worldDraw.reflectionImages, 0, sizeof(GfxImage*) * asset->worldDraw.reflectionProbeCount);
for (unsigned int i = 0; i < asset->worldDraw.reflectionProbeCount; i++)
{
asset->worldDraw.reflectionImages[i] = read.read_asset<GfxImage>();
}
asset->worldDraw.reflectionProbes = read.read_array<GfxReflectionProbe>();
asset->worldDraw.reflectionProbeReferences = read.read_array<char>();
asset->worldDraw.reflectionProbeReferenceOrigins = read.read_array<GfxReflectionProbeReferenceOrigin>();
asset->worldDraw.reflectionProbeTextures = read.read_array<GfxTexture>();
asset->worldDraw.lightmaps = read.read_array<GfxLightmapArray>();
for (int i = 0; i < asset->worldDraw.lightmapCount; i++)
{
asset->worldDraw.lightmaps[i].primary = read.read_asset<GfxImage>();
asset->worldDraw.lightmaps[i].secondary = read.read_asset<GfxImage>();
}
asset->worldDraw.lightmapPrimaryTextures = read.read_array<GfxTexture>();
asset->worldDraw.lightmapSecondaryTextures = read.read_array<GfxTexture>();
asset->worldDraw.skyImage = read.read_asset<GfxImage>();
asset->worldDraw.outdoorImage = read.read_asset<GfxImage>();
asset->worldDraw.vd.vertices = read.read_array<GfxWorldVertex>();
asset->worldDraw.vld.data = read.read_array<char>();
asset->worldDraw.indices = read.read_array<unsigned short>();
// GfxLightGrid
GfxLightGrid* lightGrid = read.read_array<GfxLightGrid>();
memcpy(&asset->lightGrid, lightGrid, sizeof(GfxLightGrid));
asset->lightGrid.rowDataStart = read.read_array<unsigned short>();
asset->lightGrid.rawRowData = read.read_array<char>();
asset->lightGrid.entries = read.read_array<GfxLightGridEntry>();
asset->lightGrid.colors = read.read_array<GfxLightGridColors>();
// models
asset->modelCount = read.read_int();
asset->models = read.read_array<GfxBrushModel>();
// mins/maxs
float* mins = read.read_array<float>();
memcpy(asset->mins, mins, sizeof(float) * 3);
float* maxs = read.read_array<float>();
memcpy(asset->maxs, maxs, sizeof(float) * 3);
asset->checksum = read.read_int();
// materialmemory
asset->materialMemoryCount = read.read_int();
asset->materialMemory = read.read_array<MaterialMemory>();
for (int i = 0; i < asset->materialMemoryCount; i++)
{
asset->materialMemory[i].material = read.read_asset<Material>();
}
// sun data
sunflare_t* sun = read.read_array<sunflare_t>();
memcpy(&asset->sun, sun, sizeof(sunflare_t));
asset->sun.spriteMaterial = read.read_asset<Material>();
asset->sun.flareMaterial = read.read_asset<Material>();
// outdoor shit
auto lookupMatrix = read.read_array<VecInternal<4>>();
memcpy(&asset->outdoorLookupMatrix, lookupMatrix, sizeof(VecInternal<4>) * 4);
asset->outdoorImage = read.read_asset<GfxImage>();
// CellcasterBits
asset->cellCasterBits[0] = read.read_array<unsigned int>();
asset->cellCasterBits[1] = read.read_array<unsigned int>();
// SceneDynModel
asset->sceneDynModel = read.read_array<GfxSceneDynModel>();
// SceneDynBrush
asset->sceneDynBrush = read.read_array<GfxSceneDynBrush>();
// PrimaryLightEntityShadowVis
asset->primaryLightEntityShadowVis = read.read_array<unsigned char>();
// PrimaryLightDynEntShadowVis
asset->primaryLightDynEntShadowVis[0] = read.read_array<unsigned int>();
asset->primaryLightDynEntShadowVis[1] = read.read_array<unsigned int>();
// PrimaryLightForModelDynEnt
asset->primaryLightForModelDynEnt = read.read_array<char>();
// GfxShadowGeometry
asset->shadowGeom = read.read_array<GfxShadowGeometry>();
for (int i = 0; i < asset->primaryLightCount; i++)
{
asset->shadowGeom[i].sortedSurfIndex = read.read_array<unsigned short>();
asset->shadowGeom[i].smodelIndex = read.read_array<unsigned short>();
}
// GfxLightRegion
asset->lightRegion = read.read_array<GfxLightRegion>();
for (int i = 0; i < asset->primaryLightCount; i++)
{
asset->lightRegion[i].hulls = read.read_array<GfxLightRegionHull>();
for (unsigned int j = 0; j < asset->lightRegion[i].hullCount; j++)
{
asset->lightRegion[i].hulls[j].axis = read.read_array<GfxLightRegionAxis>();
}
}
asset->mapVtxChecksum = read.read_int();
// heroLights
asset->heroLightCount = 0;
asset->heroLights = nullptr;
asset->fogTypesAllowed = read.read_int();
#ifdef USE_VMPROTECT
VMProtectEnd();
#endif
return asset;
}
IGfxWorld::IGfxWorld()
{
}
IGfxWorld::~IGfxWorld()
{
}
void IGfxWorld::init(const std::string& name, ZoneMemory* mem)
{
this->name_ = "maps/"s + (currentzone.substr(0, 3) == "mp_" ? "mp/" : "") + currentzone + ".d3dbsp"; // name;
this->asset_ = this->parse(name, mem);
if (!this->asset_)
{
this->asset_ = DB_FindXAssetHeader(this->type(), name.data(), 1).gfxworld;
}
}
void IGfxWorld::prepare(ZoneBuffer* buf, ZoneMemory* mem)
{
}
void IGfxWorld::load_depending(IZone* zone)
{
#ifdef USE_VMPROTECT
VMProtectBeginUltra("IW5::IGfxWorld::load_depending");
#endif
auto data = this->asset_;
// Skies
if (data->skyCount)
{
for (unsigned int i = 0; i < data->skyCount; i++)
{
if (data->skies[i].skyImage)
{
zone->add_asset_of_type(image, data->skies[i].skyImage->name);
}
}
}
// ReflectionImages
if (data->worldDraw.reflectionImages)
{
for (unsigned int i = 0; i < data->worldDraw.reflectionProbeCount; i++)
{
if (data->worldDraw.reflectionImages[i])
{
zone->add_asset_of_type(image, data->worldDraw.reflectionImages[i]->name);
}
}
}
// Lightmaps
if (data->worldDraw.lightmaps)
{
for (int i = 0; i < data->worldDraw.lightmapCount; i++)
{
if (data->worldDraw.lightmaps[i].primary)
{
zone->add_asset_of_type(image, data->worldDraw.lightmaps[i].primary->name);
}
if (data->worldDraw.lightmaps[i].secondary)
{
zone->add_asset_of_type(image, data->worldDraw.lightmaps[i].secondary->name);
}
}
}
// SkyImage (Unused?)
if (data->worldDraw.skyImage)
{
zone->add_asset_of_type(image, data->worldDraw.skyImage->name);
}
// OutdoorImage (Unused?)
if (data->worldDraw.outdoorImage)
{
zone->add_asset_of_type(image, data->worldDraw.outdoorImage->name);
}
// MaterialMemory
if (data->materialMemory)
{
for (int i = 0; i < data->materialMemoryCount; i++)
{
if (data->materialMemory[i].material)
{
zone->add_asset_of_type(material, data->materialMemory[i].material->name);
}
}
}
// Sunflare_t
if (data->sun.spriteMaterial)
{
zone->add_asset_of_type(material, data->sun.spriteMaterial->name);
}
if (data->sun.flareMaterial)
{
zone->add_asset_of_type(material, data->sun.flareMaterial->name);
}
// OutdoorImage
if (data->outdoorImage)
{
zone->add_asset_of_type(image, data->outdoorImage->name);
}
// Dpvs.Surfaces
if (data->dpvs.surfaces)
{
for (int i = 0; i < data->indexCount; i++)
{
if (data->dpvs.surfaces[i].material)
{
zone->add_asset_of_type(material, data->dpvs.surfaces[i].material->name);
}
}
}
if (data->dpvs.smodelDrawInsts)
{
for (unsigned int i = 0; i < data->dpvs.smodelCount; i++)
{
if (data->dpvs.smodelDrawInsts[i].model)
{
zone->add_asset_of_type(xmodel, data->dpvs.smodelDrawInsts[i].model->name);
}
}
}
#ifdef USE_VMPROTECT
VMProtectEnd();
#endif
}
std::string IGfxWorld::name()
{
return this->name_;
}
std::int32_t IGfxWorld::type()
{
return gfx_map;
}
void IGfxWorld::write(IZone* zone, ZoneBuffer* buf)
{
#ifdef USE_VMPROTECT
VMProtectBeginUltra("IW5::IGfxWorld::write");
#endif
auto data = this->asset_;
auto dest = buf->write(data);
buf->push_stream(3);
START_LOG_STREAM;
if (data->name)
{
dest->name = buf->write_str(this->name());
}
if (data->baseName)
{
dest->baseName = buf->write_str(this->name());
}
if (data->skies)
{
buf->align(3);
auto skiesArray = buf->write(data->skies, data->skyCount);
for (std::uint32_t i = 0; i < data->skyCount; i++)
{
if (data->skies[i].skyStartSurfs)
{
buf->align(3);
buf->write_p(data->skies[i].skyStartSurfs, data->skies[i].skySurfCount);
ZoneBuffer::clear_pointer(&skiesArray[i].skyStartSurfs);
}
if (data->skies[i].skyImage)
{
skiesArray[i].skyImage = reinterpret_cast<GfxImage*>(zone->get_asset_pointer(
image, data->skies[i].skyImage->name));
}
}
ZoneBuffer::clear_pointer(&dest->skies);
}
if (dest->dpvsPlanes.planes)
{
dest->dpvsPlanes.planes = buf->write_s(3, data->dpvsPlanes.planes, data->planeCount);
}
if (dest->dpvsPlanes.nodes)
{
buf->align(1);
buf->write_p(data->dpvsPlanes.nodes, data->nodeCount);
ZoneBuffer::clear_pointer(&dest->dpvsPlanes.nodes);
}
buf->push_stream(2);
if (dest->dpvsPlanes.sceneEntCellBits)
{
buf->align(3);
buf->write(data->dpvsPlanes.sceneEntCellBits, data->dpvsPlanes.cellCount << 11);
ZoneBuffer::clear_pointer(&dest->dpvsPlanes.sceneEntCellBits);
}
buf->pop_stream();
if (data->aabbTreeCounts)
{
buf->align(3);
buf->write_p(data->aabbTreeCounts, data->dpvsPlanes.cellCount);
ZoneBuffer::clear_pointer(&dest->aabbTreeCounts);
}
if (data->aabbTree)
{
buf->align(127);
auto cell_tree = buf->write_p(data->aabbTree, data->dpvsPlanes.cellCount);
for (std::int32_t i = 0; i < data->dpvsPlanes.cellCount; i++)
{
if (data->aabbTree[i].aabbtree)
{
buf->align(3);
auto gfx_aabb_tree = buf->write_p(data->aabbTree[i].aabbtree,
data->aabbTreeCounts[i].aabbTreeCount);
for (std::int32_t i2 = 0; i2 < data->aabbTreeCounts[i].aabbTreeCount; i2++)
{
if (data->aabbTree[i].aabbtree[i2].smodelIndexes)
{
gfx_aabb_tree[i2].smodelIndexes = buf->write_s(
1, data->aabbTree[i].aabbtree[i2].smodelIndexes,
data->aabbTree[i].aabbtree[i2].smodelIndexCount);
}
}
ZoneBuffer::clear_pointer(&cell_tree[i].aabbtree);
}
}
ZoneBuffer::clear_pointer(&dest->aabbTree);
}
if (data->cells)
{
buf->align(3);
auto gfx_cell = buf->write(data->cells, data->dpvsPlanes.cellCount);
for (std::int32_t i = 0; i < data->dpvsPlanes.cellCount; i++)
{
if (data->cells[i].portals)
{
buf->align(3);
auto gfx_portal = buf->write(data->cells[i].portals, data->cells[i].portalCount);
for (std::int32_t i2 = 0; i2 < data->cells[i].portalCount; i2++)
{
if (data->cells[i].portals[i2].vertices)
{
buf->align(3);
buf->write(data->cells[i].portals[i2].vertices, data->cells[i].portals[i2].vertexCount);
ZoneBuffer::clear_pointer(&gfx_portal[i2].vertices);
}
}
ZoneBuffer::clear_pointer(&gfx_cell[i].portals);
}
if (data->cells[i].reflectionProbes)
{
buf->align(0);
buf->write(data->cells[i].reflectionProbes, data->cells[i].reflectionProbeCount);
ZoneBuffer::clear_pointer(&gfx_cell[i].reflectionProbes);
}
if (data->cells[i].reflectionProbeReferences)
{
buf->align(0);
buf->write(data->cells[i].reflectionProbeReferences,
data->cells[i].reflectionProbeReferenceCount);
ZoneBuffer::clear_pointer(&gfx_cell[i].reflectionProbeReferences);
}
ZoneBuffer::clear_pointer(&dest->cells);
}
}
if (data->worldDraw.reflectionImages)
{
buf->align(3);
auto reflectionProbes = buf->write(data->worldDraw.reflectionImages,
data->worldDraw.reflectionProbeCount);
for (std::uint64_t i = 0; i < data->worldDraw.reflectionProbeCount; i++)
{
if (reflectionProbes[i])
{
reflectionProbes[i] = reinterpret_cast<GfxImage*>(zone->get_asset_pointer(
image, data->worldDraw.reflectionImages[i]->name));
}
}
ZoneBuffer::clear_pointer(&dest->worldDraw.reflectionImages);
}
if (data->worldDraw.reflectionProbes)
{
buf->align(3);
buf->write(data->worldDraw.reflectionProbes, data->worldDraw.reflectionProbeCount);
ZoneBuffer::clear_pointer(&dest->worldDraw.reflectionProbes);
}
buf->push_stream(2);
if (data->worldDraw.reflectionProbeTextures)
{
buf->align(3);
buf->write(data->worldDraw.reflectionProbeTextures, data->worldDraw.reflectionProbeCount);
ZoneBuffer::clear_pointer(&dest->worldDraw.reflectionProbeTextures);
}
buf->pop_stream();
if (data->worldDraw.reflectionProbeReferenceOrigins)
{
buf->align(3);
buf->write(data->worldDraw.reflectionProbeReferenceOrigins,
data->worldDraw.reflectionProbeReferenceCount);
ZoneBuffer::clear_pointer(&dest->worldDraw.reflectionProbeReferenceOrigins);
}
if (data->worldDraw.reflectionProbeReferences)
{
buf->align(0);
buf->write(data->worldDraw.reflectionProbeReferences, data->worldDraw.reflectionProbeReferenceCount);
ZoneBuffer::clear_pointer(&dest->worldDraw.reflectionProbeReferences);
}
if (data->worldDraw.lightmaps)
{
buf->align(3);
auto gfx_lightmap_array = buf->write(data->worldDraw.lightmaps, data->worldDraw.lightmapCount);
for (std::int32_t i = 0; i < data->worldDraw.lightmapCount; i++)
{
if (data->worldDraw.lightmaps[i].primary)
{
gfx_lightmap_array[i].primary = reinterpret_cast<GfxImage*>(zone->get_asset_pointer(
image, data->worldDraw.lightmaps[i].primary->name));
}
if (data->worldDraw.lightmaps[i].secondary)
{
gfx_lightmap_array[i].secondary = reinterpret_cast<GfxImage*>(zone->get_asset_pointer(
image, data->worldDraw.lightmaps[i].secondary->name));
}
}
ZoneBuffer::clear_pointer(&dest->worldDraw.lightmaps);
}
buf->push_stream(2);
if (data->worldDraw.lightmapPrimaryTextures)
{
buf->align(3);
buf->write_p(data->worldDraw.lightmapPrimaryTextures, data->worldDraw.lightmapCount);
ZoneBuffer::clear_pointer(&dest->worldDraw.lightmapPrimaryTextures);
}
if (data->worldDraw.lightmapSecondaryTextures)
{
buf->align(3);
buf->write_p(data->worldDraw.lightmapSecondaryTextures, data->worldDraw.lightmapCount);
ZoneBuffer::clear_pointer(&dest->worldDraw.lightmapSecondaryTextures);
}
buf->pop_stream();
if (data->worldDraw.skyImage)
{
dest->worldDraw.skyImage = reinterpret_cast<GfxImage*>(zone->get_asset_pointer(
image, data->worldDraw.skyImage->name));
}
if (data->worldDraw.outdoorImage)
{
dest->worldDraw.outdoorImage = reinterpret_cast<GfxImage*>(zone->get_asset_pointer(
image, data->worldDraw.outdoorImage->name));
}
if (data->worldDraw.vd.vertices)
{
buf->align(3);
buf->write_p(data->worldDraw.vd.vertices, data->worldDraw.vertexCount);
ZoneBuffer::clear_pointer(&dest->worldDraw.vd.vertices);
}
if (data->worldDraw.vld.data)
{
buf->align(0);
buf->write_p(data->worldDraw.vld.data, data->worldDraw.vertexLayerDataSize);
ZoneBuffer::clear_pointer(&dest->worldDraw.vld.data);
}
if (data->worldDraw.indices)
{
buf->align(1);
buf->write_p(data->worldDraw.indices, data->worldDraw.indexCount);
ZoneBuffer::clear_pointer(&dest->worldDraw.indices);
}
if (data->lightGrid.rowDataStart)
{
buf->align(1);
buf->write_p(data->lightGrid.rowDataStart,
data->lightGrid.maxs[data->lightGrid.rowAxis] - data->lightGrid.mins[data
->lightGrid.rowAxis] +
1);
ZoneBuffer::clear_pointer(&dest->lightGrid.rowDataStart);
}
if (data->lightGrid.rawRowData)
{
buf->align(0);
buf->write_p(data->lightGrid.rawRowData, data->lightGrid.rawRowDataSize);
ZoneBuffer::clear_pointer(&dest->lightGrid.rawRowData);
}
if (data->lightGrid.entries)
{
buf->align(3);
buf->write(data->lightGrid.entries, data->lightGrid.entryCount);
ZoneBuffer::clear_pointer(&dest->lightGrid.entries);
}
if (data->lightGrid.colors)
{
buf->align(3);
buf->write(data->lightGrid.colors, data->lightGrid.colorCount);
ZoneBuffer::clear_pointer(&dest->lightGrid.colors);
}
if (data->models)
{
buf->align(3);
buf->write(data->models, data->modelCount);
ZoneBuffer::clear_pointer(&dest->models);
}
if (data->materialMemory)
{
buf->align(3);
auto memory = buf->write(data->materialMemory, data->materialMemoryCount);
for (std::int32_t i = 0; i < data->materialMemoryCount; i++)
{
memory[i].material = reinterpret_cast<Material*>(zone->get_asset_pointer(
material, data->materialMemory[i].material->name));
}
ZoneBuffer::clear_pointer(&dest->materialMemory);
}
if (data->sun.spriteMaterial)
{
dest->sun.spriteMaterial = reinterpret_cast<Material*>(zone->get_asset_pointer(
material, data->sun.spriteMaterial->name));
}
if (data->sun.flareMaterial)
{
dest->sun.flareMaterial = reinterpret_cast<Material*>(zone->get_asset_pointer(
material, data->sun.flareMaterial->name));
}
if (data->outdoorImage)
{
dest->outdoorImage = reinterpret_cast<GfxImage*>(zone->get_asset_pointer(image, data->outdoorImage->name)
);
}
buf->push_stream(2);
if (data->cellCasterBits[0])
{
buf->align(3);
buf->write(data->cellCasterBits[0],
data->dpvsPlanes.cellCount * ((data->dpvsPlanes.cellCount + 31) >> 5));
ZoneBuffer::clear_pointer(&dest->cellCasterBits[0]);
}
if (data->cellCasterBits[1])
{
buf->align(3);
buf->write(data->cellCasterBits[1], (data->dpvsPlanes.cellCount + 31) >> 5);
ZoneBuffer::clear_pointer(&dest->cellCasterBits[1]);
}
if (data->sceneDynModel)
{
buf->align(3);
buf->write(data->sceneDynModel, data->dpvsDyn.dynEntClientCount[0]);
ZoneBuffer::clear_pointer(&dest->sceneDynModel);
}
if (data->sceneDynBrush)
{
buf->align(3);
buf->write(data->sceneDynBrush, data->dpvsDyn.dynEntClientCount[1]);
ZoneBuffer::clear_pointer(&dest->sceneDynBrush);
}
if (data->primaryLightEntityShadowVis)
{
buf->align(3);
buf->write(data->primaryLightEntityShadowVis,
(data->primaryLightCount - data->sunPrimaryLightIndex - 1) << 15);
ZoneBuffer::clear_pointer(&dest->primaryLightEntityShadowVis);
}
if (data->primaryLightDynEntShadowVis[0])
{
buf->align(3);
buf->write(data->primaryLightDynEntShadowVis[0],
data->dpvsDyn.dynEntClientCount[0] * (data->primaryLightCount - data->sunPrimaryLightIndex -
1));
ZoneBuffer::clear_pointer(&dest->primaryLightDynEntShadowVis[0]);
}
if (data->primaryLightDynEntShadowVis[1])
{
buf->align(3);
buf->write(data->primaryLightDynEntShadowVis[1],
data->dpvsDyn.dynEntClientCount[1] * (data->primaryLightCount - data->sunPrimaryLightIndex -
1));
ZoneBuffer::clear_pointer(&dest->primaryLightDynEntShadowVis[1]);
}
if (data->primaryLightForModelDynEnt)
{
buf->align(0);
buf->write(data->primaryLightForModelDynEnt, data->dpvsDyn.dynEntClientCount[0]);
ZoneBuffer::clear_pointer(&dest->primaryLightForModelDynEnt);
}
buf->pop_stream();
if (data->shadowGeom)
{
buf->align(3);
auto shadow_geometry = buf->write(data->shadowGeom, data->primaryLightCount);
for (std::int32_t i = 0; i < data->primaryLightCount; i++)
{
if (data->shadowGeom[i].sortedSurfIndex)
{
buf->align(1);
buf->write_p(data->shadowGeom[i].sortedSurfIndex, data->shadowGeom[i].surfaceCount);
ZoneBuffer::clear_pointer(&shadow_geometry[i].sortedSurfIndex);
}
if (data->shadowGeom[i].smodelIndex)
{
buf->align(1);
buf->write_p(data->shadowGeom[i].smodelIndex, data->shadowGeom[i].smodelCount);
ZoneBuffer::clear_pointer(&shadow_geometry[i].smodelIndex);
}
}
ZoneBuffer::clear_pointer(&dest->shadowGeom);
}
if (data->lightRegion)
{
buf->align(3);
auto light_region = buf->write(data->lightRegion, data->primaryLightCount);
for (std::int32_t i = 0; i < data->primaryLightCount; i++)
{
if (data->lightRegion[i].hulls)
{
buf->align(3);
auto light_region_hull = buf->write(data->lightRegion[i].hulls, data->lightRegion[i].hullCount);
for (std::uint32_t i2 = 0; i2 < data->lightRegion[i].hullCount; i2++)
{
if (data->lightRegion[i].hulls[i2].axis)
{
buf->align(3);
buf->write(data->lightRegion[i].hulls[i2].axis,
data->lightRegion[i].hulls[i2].axisCount);
ZoneBuffer::clear_pointer(&light_region_hull[i2].axis);
}
}
ZoneBuffer::clear_pointer(&light_region[i].hulls);
}
}
ZoneBuffer::clear_pointer(&dest->lightRegion);
}
buf->push_stream(2);
if (data->dpvs.smodelVisData[0])
{
buf->align(0);
buf->write(data->dpvs.smodelVisData[0], data->dpvs.smodelCount);
ZoneBuffer::clear_pointer(&dest->dpvs.smodelVisData[0]);
}
if (data->dpvs.smodelVisData[1])
{
buf->align(0);
buf->write(data->dpvs.smodelVisData[1], data->dpvs.smodelCount);
ZoneBuffer::clear_pointer(&dest->dpvs.smodelVisData[1]);
}
if (data->dpvs.smodelVisData[2])
{
buf->align(0);
buf->write(data->dpvs.smodelVisData[2], data->dpvs.smodelCount);
ZoneBuffer::clear_pointer(&dest->dpvs.smodelVisData[2]);
}
if (data->dpvs.surfaceVisData[0])
{
buf->align(0);
buf->write(data->dpvs.surfaceVisData[0], data->dpvs.staticSurfaceCount);
ZoneBuffer::clear_pointer(&dest->dpvs.surfaceVisData[0]);
}
if (data->dpvs.surfaceVisData[1])
{
buf->align(0);
buf->write(data->dpvs.surfaceVisData[1], data->dpvs.staticSurfaceCount);
ZoneBuffer::clear_pointer(&dest->dpvs.surfaceVisData[1]);
}
if (data->dpvs.surfaceVisData[2])
{
buf->align(0);
buf->write(data->dpvs.surfaceVisData[2], data->dpvs.staticSurfaceCount);
ZoneBuffer::clear_pointer(&dest->dpvs.surfaceVisData[2]);
}
buf->pop_stream();
if (data->dpvs.sortedSurfIndex)
{
buf->align(1);
buf->write_p(data->dpvs.sortedSurfIndex,
data->dpvs.staticSurfaceCount + data->dpvs.staticSurfaceCountNoDecal);
ZoneBuffer::clear_pointer(&dest->dpvs.sortedSurfIndex);
}
if (data->dpvs.smodelInsts)
{
buf->align(3);
buf->write(data->dpvs.smodelInsts, data->dpvs.smodelCount);
ZoneBuffer::clear_pointer(&dest->dpvs.smodelInsts);
}
if (data->dpvs.surfaces)
{
buf->align(3);
auto surface = buf->write(data->dpvs.surfaces, data->indexCount);
for (std::int32_t i = 0; i < data->indexCount; i++)
{
if (data->dpvs.surfaces[i].material)
{
surface[i].material = reinterpret_cast<Material*>(zone->get_asset_pointer(
material, data->dpvs.surfaces[i].material->name));
}
assert(surface[i].material != nullptr);
}
ZoneBuffer::clear_pointer(&dest->dpvs.surfaces);
}
assert(data->indexCount > 0);
assert(data->dpvs.surfaces != nullptr);
if (data->dpvs.surfacesBounds)
{
buf->align(3);
buf->write(data->dpvs.surfacesBounds, data->indexCount);
ZoneBuffer::clear_pointer(&dest->dpvs.surfacesBounds);
}
if (data->dpvs.smodelDrawInsts)
{
buf->align(3);
auto static_model_draw_inst = buf->write(data->dpvs.smodelDrawInsts, data->dpvs.smodelCount);
for (std::uint32_t i = 0; i < data->dpvs.smodelCount; i++)
{
if (data->dpvs.smodelDrawInsts[i].model)
{
static_model_draw_inst[i].model = reinterpret_cast<XModel*>(zone->get_asset_pointer(
xmodel, data->dpvs.smodelDrawInsts[i].model->name));
}
}
ZoneBuffer::clear_pointer(&dest->dpvs.smodelDrawInsts);
}
buf->push_stream(2);
if (data->dpvs.surfaceMaterials)
{
buf->align(7);
buf->write(data->dpvs.surfaceMaterials, data->indexCount);
ZoneBuffer::clear_pointer(&dest->dpvs.smodelDrawInsts);
}
if (data->dpvs.surfaceCastsSunShadow)
{
buf->align(127);
buf->write(data->dpvs.surfaceCastsSunShadow, data->dpvs.surfaceVisDataCount);
ZoneBuffer::clear_pointer(&dest->dpvs.surfaceCastsSunShadow);
}
if (data->dpvsDyn.dynEntCellBits[0])
{
buf->align(3);
buf->write(data->dpvsDyn.dynEntCellBits[0],
data->dpvsDyn.dynEntClientWordCount[0] * data->dpvsPlanes.cellCount);
ZoneBuffer::clear_pointer(&dest->dpvsDyn.dynEntCellBits[0]);
}
if (data->dpvsDyn.dynEntCellBits[1])
{
buf->align(3);
buf->write(data->dpvsDyn.dynEntCellBits[1],
data->dpvsDyn.dynEntClientWordCount[1] * data->dpvsPlanes.cellCount);
ZoneBuffer::clear_pointer(&dest->dpvsDyn.dynEntCellBits[1]);
}
if (data->dpvsDyn.dynEntVisData[0][0])
{
buf->align(15);
buf->write(data->dpvsDyn.dynEntVisData[0][0], 32 * data->dpvsDyn.dynEntClientWordCount[0]);
ZoneBuffer::clear_pointer(&dest->dpvsDyn.dynEntVisData[0][0]);
}
if (data->dpvsDyn.dynEntVisData[1][0])
{
buf->align(15);
buf->write(data->dpvsDyn.dynEntVisData[1][0], 32 * data->dpvsDyn.dynEntClientWordCount[1]);
ZoneBuffer::clear_pointer(&dest->dpvsDyn.dynEntVisData[1][0]);
}
if (data->dpvsDyn.dynEntVisData[0][1])
{
buf->align(15);
buf->write(data->dpvsDyn.dynEntVisData[0][1], 32 * data->dpvsDyn.dynEntClientWordCount[0]);
ZoneBuffer::clear_pointer(&dest->dpvsDyn.dynEntVisData[0][1]);
}
if (data->dpvsDyn.dynEntVisData[1][1])
{
buf->align(15);
buf->write(data->dpvsDyn.dynEntVisData[1][1], 32 * data->dpvsDyn.dynEntClientWordCount[1]);
ZoneBuffer::clear_pointer(&dest->dpvsDyn.dynEntVisData[1][1]);
}
if (data->dpvsDyn.dynEntVisData[0][2])
{
buf->align(15);
buf->write(data->dpvsDyn.dynEntVisData[0][2], 32 * data->dpvsDyn.dynEntClientWordCount[0]);
ZoneBuffer::clear_pointer(&dest->dpvsDyn.dynEntVisData[0][2]);
}
if (data->dpvsDyn.dynEntVisData[1][2])
{
buf->align(15);
buf->write(data->dpvsDyn.dynEntVisData[1][2], 32 * data->dpvsDyn.dynEntClientWordCount[1]);
ZoneBuffer::clear_pointer(&dest->dpvsDyn.dynEntVisData[1][2]);
}
buf->pop_stream();
if (data->heroLights)
{
buf->align(3);
buf->write(data->heroLights, data->heroLightCount);
ZoneBuffer::clear_pointer(&dest->heroLights);
}
END_LOG_STREAM;
buf->pop_stream();
encrypt_data(dest, sizeof GfxWorld);
#ifdef USE_VMPROTECT
VMProtectEnd();
#endif
}
void IGfxWorld::dump(GfxWorld* asset)
{
// dump code
AssetDumper write;
if (!write.open(asset->name + ".gfxmap"s))
{
return;
}
write.dump_string(asset->name);
write.dump_string(asset->baseName);
write.dump_int(asset->planeCount);
write.dump_int(asset->nodeCount);
write.dump_int(asset->indexCount);
write.dump_int(asset->skyCount);
write.dump_array(asset->skies, asset->skyCount);
for (unsigned int i = 0; i < asset->skyCount; i++)
{
write.dump_array(asset->skies[i].skyStartSurfs, asset->skies[i].skySurfCount);
write.dump_asset(asset->skies[i].skyImage);
}
write.dump_int(asset->sunPrimaryLightIndex);
write.dump_int(asset->primaryLightCount);
write.dump_int(asset->primaryLightEnvCount);
write.dump_array(asset->unknown1, 12);
// dpvsplanes
write.dump_int(asset->dpvsPlanes.cellCount);
write.dump_array(asset->dpvsPlanes.planes, asset->planeCount);
write.dump_array(asset->dpvsPlanes.nodes, asset->nodeCount);
write.dump_array(asset->dpvsPlanes.sceneEntCellBits, asset->dpvsPlanes.cellCount << 11);
// dpvs
write.dump_array(&asset->dpvs, 1);
write.dump_array(asset->dpvs.smodelVisData[0], asset->dpvs.smodelCount);
write.dump_array(asset->dpvs.smodelVisData[1], asset->dpvs.smodelCount);
write.dump_array(asset->dpvs.smodelVisData[2], asset->dpvs.smodelCount);
write.dump_array(asset->dpvs.surfaceVisData[0], asset->dpvs.staticSurfaceCount);
write.dump_array(asset->dpvs.surfaceVisData[1], asset->dpvs.staticSurfaceCount);
write.dump_array(asset->dpvs.surfaceVisData[2], asset->dpvs.staticSurfaceCount);
write.dump_array(asset->dpvs.sortedSurfIndex,
(asset->dpvs.staticSurfaceCount + asset->dpvs.staticSurfaceCountNoDecal));
write.dump_array(asset->dpvs.smodelInsts, asset->dpvs.smodelCount);
write.dump_array(asset->dpvs.surfaces, asset->indexCount);
for (int i = 0; i < asset->indexCount; i++)
{
write.dump_asset(asset->dpvs.surfaces[i].material);
}
write.dump_array(asset->dpvs.surfacesBounds, asset->indexCount);
write.dump_array(asset->dpvs.smodelDrawInsts, asset->dpvs.smodelCount);
for (unsigned int i = 0; i < asset->dpvs.smodelCount; i++)
{
write.dump_asset(asset->dpvs.smodelDrawInsts[i].model);
}
write.dump_array(asset->dpvs.surfaceMaterials, asset->indexCount);
write.dump_array(asset->dpvs.surfaceCastsSunShadow, asset->dpvs.surfaceVisDataCount);
// dpvsDyn
write.dump_array(&asset->dpvsDyn, 1);
write.dump_array(asset->dpvsDyn.dynEntCellBits[0],
asset->dpvsDyn.dynEntClientWordCount[0] * asset->dpvsPlanes.cellCount);
write.dump_array(asset->dpvsDyn.dynEntCellBits[1],
asset->dpvsDyn.dynEntClientWordCount[1] * asset->dpvsPlanes.cellCount);
write.dump_array(asset->dpvsDyn.dynEntVisData[0][0], asset->dpvsDyn.dynEntClientWordCount[0] * 32);
write.dump_array(asset->dpvsDyn.dynEntVisData[1][0], asset->dpvsDyn.dynEntClientWordCount[1] * 32);
write.dump_array(asset->dpvsDyn.dynEntVisData[0][1], asset->dpvsDyn.dynEntClientWordCount[0] * 32);
write.dump_array(asset->dpvsDyn.dynEntVisData[1][1], asset->dpvsDyn.dynEntClientWordCount[1] * 32);
write.dump_array(asset->dpvsDyn.dynEntVisData[0][2], asset->dpvsDyn.dynEntClientWordCount[0] * 32);
write.dump_array(asset->dpvsDyn.dynEntVisData[1][2], asset->dpvsDyn.dynEntClientWordCount[1] * 32);
// aabbTreeCount
write.dump_array(asset->aabbTreeCounts, asset->dpvsPlanes.cellCount);
// GfxCellTree
write.dump_array(asset->aabbTree, asset->dpvsPlanes.cellCount);
for (int i = 0; i < asset->dpvsPlanes.cellCount; i++)
{
write.dump_array(asset->aabbTree[i].aabbtree, asset->aabbTreeCounts[i].aabbTreeCount);
for (int j = 0; j < asset->aabbTreeCounts[i].aabbTreeCount; j++)
{
write.dump_array(asset->aabbTree[i].aabbtree[j].smodelIndexes,
asset->aabbTree[i].aabbtree[j].smodelIndexCount);
}
}
// read GFX cells
write.dump_array(asset->cells, asset->dpvsPlanes.cellCount);
for (int i = 0; i < asset->dpvsPlanes.cellCount; i++)
{
write.dump_array(asset->cells[i].portals, asset->cells[i].portalCount);
for (int j = 0; j < asset->cells[i].portalCount; j++)
{
write.dump_array(asset->cells[i].portals[j].vertices, asset->cells[i].portals[j].vertexCount);
}
write.dump_array(asset->cells[i].reflectionProbes, asset->cells[i].reflectionProbeCount);
write.dump_array(asset->cells[i].reflectionProbeReferences, asset->cells[i].reflectionProbeReferenceCount);
}
// draw
write.dump_array(&asset->worldDraw, 1);
for (unsigned int i = 0; i < asset->worldDraw.reflectionProbeCount; i++)
{
write.dump_asset(asset->worldDraw.reflectionImages[i]);
}
write.dump_array(asset->worldDraw.reflectionProbes, asset->worldDraw.reflectionProbeCount);
write.dump_array(asset->worldDraw.reflectionProbeReferences, asset->worldDraw.reflectionProbeReferenceCount);
write.dump_array(asset->worldDraw.reflectionProbeReferenceOrigins,
asset->worldDraw.reflectionProbeReferenceCount);
write.dump_array(asset->worldDraw.reflectionProbeTextures, asset->worldDraw.reflectionProbeCount);
write.dump_array(asset->worldDraw.lightmaps, asset->worldDraw.lightmapCount);
for (int i = 0; i < asset->worldDraw.lightmapCount; i++)
{
write.dump_asset(asset->worldDraw.lightmaps[i].primary);
write.dump_asset(asset->worldDraw.lightmaps[i].secondary);
}
write.dump_array(asset->worldDraw.lightmapPrimaryTextures, asset->worldDraw.lightmapCount);
write.dump_array(asset->worldDraw.lightmapSecondaryTextures, asset->worldDraw.lightmapCount);
write.dump_asset(asset->worldDraw.skyImage);
write.dump_asset(asset->worldDraw.outdoorImage);
write.dump_array(asset->worldDraw.vd.vertices, asset->worldDraw.vertexCount);
write.dump_array(asset->worldDraw.vld.data, asset->worldDraw.vertexLayerDataSize);
write.dump_array(asset->worldDraw.indices, asset->worldDraw.indexCount);
// GfxLightGrid
write.dump_array(&asset->lightGrid, 1);
write.dump_array(asset->lightGrid.rowDataStart,
(asset->lightGrid.maxs[asset->lightGrid.rowAxis] - asset->lightGrid.mins[asset
->lightGrid.rowAxis] +
1));
write.dump_array(asset->lightGrid.rawRowData, asset->lightGrid.rawRowDataSize);
write.dump_array(asset->lightGrid.entries, asset->lightGrid.entryCount);
write.dump_array(asset->lightGrid.colors, asset->lightGrid.colorCount);
// models
write.dump_int(asset->modelCount);
write.dump_array(asset->models, asset->modelCount);
// mins/maxs
write.dump_array(asset->mins, 3);
write.dump_array(asset->maxs, 3);
write.dump_int(asset->checksum);
// materialmemory
write.dump_int(asset->materialMemoryCount);
write.dump_array(asset->materialMemory, asset->materialMemoryCount);
for (int i = 0; i < asset->materialMemoryCount; i++)
{
write.dump_asset(asset->materialMemory[i].material);
}
// sun data
write.dump_array(&asset->sun, 1);
write.dump_asset(asset->sun.spriteMaterial);
write.dump_asset(asset->sun.flareMaterial);
// outdoor shit
write.dump_array(asset->outdoorLookupMatrix, 4);
write.dump_asset(asset->outdoorImage);
// CellcasterBits
write.dump_array(asset->cellCasterBits[0],
asset->dpvsPlanes.cellCount * ((asset->dpvsPlanes.cellCount + 31) >> 5));
write.dump_array(asset->cellCasterBits[1], (asset->dpvsPlanes.cellCount + 31) >> 5);
// SceneDynModel
write.dump_array(asset->sceneDynModel, asset->dpvsDyn.dynEntClientCount[0]);
// SceneDynBrush
write.dump_array(asset->sceneDynBrush, asset->dpvsDyn.dynEntClientCount[1]);
// PrimaryLightEntityShadowVis
write.dump_array(asset->primaryLightEntityShadowVis,
(asset->primaryLightCount - asset->sunPrimaryLightIndex - 1) << 15);
// PrimaryLightDynEntShadowVis
write.dump_array(asset->primaryLightDynEntShadowVis[0],
asset->dpvsDyn.dynEntClientCount[0] * (asset->primaryLightCount - asset->sunPrimaryLightIndex -
1));
write.dump_array(asset->primaryLightDynEntShadowVis[1],
asset->dpvsDyn.dynEntClientCount[1] * (asset->primaryLightCount - asset->sunPrimaryLightIndex -
1));
// PrimaryLightForModelDynEnt
write.dump_array(asset->primaryLightForModelDynEnt, asset->dpvsDyn.dynEntClientCount[0]);
// GfxShadowGeometry
write.dump_array(asset->shadowGeom, asset->primaryLightCount);
for (int i = 0; i < asset->primaryLightCount; i++)
{
write.dump_array(asset->shadowGeom[i].sortedSurfIndex, asset->shadowGeom[i].surfaceCount);
write.dump_array(asset->shadowGeom[i].smodelIndex, asset->shadowGeom[i].smodelCount);
}
// GfxLightRegion
write.dump_array(asset->lightRegion, asset->primaryLightCount);
for (int i = 0; i < asset->primaryLightCount; i++)
{
write.dump_array(asset->lightRegion[i].hulls, asset->lightRegion[i].hullCount);
for (unsigned int j = 0; j < asset->lightRegion[i].hullCount; j++)
{
write.dump_array(asset->lightRegion[i].hulls[j].axis, asset->lightRegion[i].hulls[j].axisCount);
}
}
write.dump_int(asset->mapVtxChecksum);
write.dump_int(asset->fogTypesAllowed);
// save file to disk!
write.close();
}
}
}