From 2691c9f55c03bc0347da70f37ee67cfe95abcf4b Mon Sep 17 00:00:00 2001 From: Edo Date: Sat, 4 Feb 2023 18:29:04 +0000 Subject: [PATCH] [Assets]: Revert last two commits as it's not compatible with iwx3-port (#752) --- .../Modules/AssetInterfaces/IFxEffectDef.cpp | 211 ++- .../Modules/AssetInterfaces/IFxEffectDef.hpp | 8 +- .../Modules/AssetInterfaces/IFxWorld.cpp | 162 +- .../Modules/AssetInterfaces/IFxWorld.hpp | 2 - .../Modules/AssetInterfaces/IGameWorldMp.cpp | 6 +- .../Modules/AssetInterfaces/IGfxWorld.cpp | 631 ++++---- .../Modules/AssetInterfaces/ILoadedSound.cpp | 20 +- .../Modules/AssetInterfaces/IMaterial.cpp | 13 +- .../AssetInterfaces/IMaterialTechniqueSet.cpp | 3 - .../Modules/AssetInterfaces/IPhysPreset.cpp | 58 +- .../Modules/AssetInterfaces/IPhysPreset.hpp | 2 - .../Modules/AssetInterfaces/ISndCurve.cpp | 52 +- .../Modules/AssetInterfaces/ISndCurve.hpp | 1 - .../Modules/AssetInterfaces/IXAnimParts.cpp | 196 +-- .../Modules/AssetInterfaces/IXModel.cpp | 14 +- .../Modules/AssetInterfaces/IclipMap_t.cpp | 1308 +---------------- .../Modules/AssetInterfaces/IclipMap_t.hpp | 5 - .../AssetInterfaces/Isnd_alias_list_t.cpp | 168 +-- .../AssetInterfaces/Isnd_alias_list_t.hpp | 1 - src/Components/Modules/Debug.cpp | 5 - src/Components/Modules/Logger.cpp | 3 +- src/Components/Modules/Renderer.cpp | 52 +- src/Components/Modules/Renderer.hpp | 4 +- src/Game/Structs.hpp | 385 +---- src/Utils/Json.cpp | 8 - src/Utils/Json.hpp | 18 +- src/Utils/Maths.cpp | 4 +- src/Utils/Maths.hpp | 4 +- src/Utils/Stream.cpp | 58 +- src/Utils/Stream.hpp | 66 +- 30 files changed, 655 insertions(+), 2813 deletions(-) diff --git a/src/Components/Modules/AssetInterfaces/IFxEffectDef.cpp b/src/Components/Modules/AssetInterfaces/IFxEffectDef.cpp index 74942a3b..994a6349 100644 --- a/src/Components/Modules/AssetInterfaces/IFxEffectDef.cpp +++ b/src/Components/Modules/AssetInterfaces/IFxEffectDef.cpp @@ -1,7 +1,7 @@ #include #include "IFxEffectDef.hpp" -#define IW4X_FX_VERSION 2 +#define IW4X_FX_VERSION 1 namespace Assets { @@ -65,139 +65,132 @@ namespace Assets void IFxEffectDef::loadBinary(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) { Components::FileSystem::File fxFile(std::format("fx/{}.iw4xFx", name)); - if (!fxFile.exists()) + + if (fxFile.exists()) { - return; - } + Utils::Stream::Reader buffer(builder->getAllocator(), fxFile.getBuffer()); - Utils::Stream::Reader buffer(builder->getAllocator(), fxFile.getBuffer()); - - auto magic = buffer.read(); - if (std::memcmp(&magic, "IW4xFx ", 8) != 0) - { - Components::Logger::Error(Game::ERR_FATAL, "Reading fx '{}' failed, header is invalid!", name); - } - - int version = buffer.read(); - if (version > IW4X_FX_VERSION) - { - Components::Logger::Error(Game::ERR_FATAL, "Reading fx '{}' failed, expected version is {}, but it was {}!", name, IW4X_FX_VERSION, version); - } - - auto* asset = buffer.readObject(); - header->fx = asset; - - if (asset->name) - { - asset->name = buffer.readCString(); - } - - if (asset->elemDefs) - { - asset->elemDefs = buffer.readArray(asset->elemDefCountEmission + asset->elemDefCountLooping + asset->elemDefCountOneShot); - - for (auto i = 0; i < (asset->elemDefCountEmission + asset->elemDefCountLooping + asset->elemDefCountOneShot); ++i) + __int64 magic = buffer.read<__int64>(); + if (std::memcmp(&magic, "IW4xFx ", 8)) { - auto* elemDef = &asset->elemDefs[i]; + Components::Logger::Error(Game::ERR_FATAL, "Reading fx '{}' failed, header is invalid!", name); + } - if (elemDef->velSamples) - { - elemDef->velSamples = buffer.readArray(elemDef->velIntervalCount + 1); - } + int version = buffer.read(); + if (version != IW4X_FX_VERSION) + { + Components::Logger::Error(Game::ERR_FATAL, "Reading fx '{}' failed, expected version is {}, but it was {}!", name, IW4X_FX_VERSION, version); + } - if (elemDef->visSamples) - { - elemDef->visSamples = buffer.readArray(elemDef->visStateIntervalCount + 1); - } + Game::FxEffectDef* asset = buffer.readObject(); + header->fx = asset; - // Save_FxElemDefVisuals + if (asset->name) + { + asset->name = buffer.readCString(); + } + + if (asset->elemDefs) + { + asset->elemDefs = buffer.readArray(asset->elemDefCountEmission + asset->elemDefCountLooping + asset->elemDefCountOneShot); + + for (int i = 0; i < (asset->elemDefCountEmission + asset->elemDefCountLooping + asset->elemDefCountOneShot); ++i) { - if (elemDef->elemType == Game::FX_ELEM_TYPE_DECAL) + Game::FxElemDef* elemDef = &asset->elemDefs[i]; + + if (elemDef->velSamples) { - if (elemDef->visuals.markArray) + elemDef->velSamples = buffer.readArray(elemDef->velIntervalCount + 1); + } + + if (elemDef->visSamples) + { + elemDef->visSamples = buffer.readArray(elemDef->visStateIntervalCount + 1); + } + + // Save_FxElemDefVisuals + { + if (elemDef->elemType == Game::FX_ELEM_TYPE_DECAL) { - elemDef->visuals.markArray = buffer.readArray(elemDef->visualCount); - - for (char j = 0; j < elemDef->visualCount; ++j) + if (elemDef->visuals.markArray) { - if (elemDef->visuals.markArray[j].materials[0]) - { - elemDef->visuals.markArray[j].materials[0] = Components::AssetHandler::FindAssetForZone(Game::ASSET_TYPE_MATERIAL, buffer.readString(), builder).material; - } + elemDef->visuals.markArray = buffer.readArray(elemDef->visualCount); - if (elemDef->visuals.markArray[j].materials[1]) + for (char j = 0; j < elemDef->visualCount; ++j) { - elemDef->visuals.markArray[j].materials[1] = Components::AssetHandler::FindAssetForZone(Game::ASSET_TYPE_MATERIAL, buffer.readString(), builder).material; + if (elemDef->visuals.markArray[j].materials[0]) + { + elemDef->visuals.markArray[j].materials[0] = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_MATERIAL, buffer.readString().data(), builder).material; + } + + if (elemDef->visuals.markArray[j].materials[1]) + { + elemDef->visuals.markArray[j].materials[1] = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_MATERIAL, buffer.readString().data(), builder).material; + } } } } - } - else if (elemDef->visualCount > 1) - { - if (elemDef->visuals.array) + else if (elemDef->visualCount > 1) { - elemDef->visuals.array = buffer.readArray(elemDef->visualCount); - - for (char j = 0; j < elemDef->visualCount; ++j) + if (elemDef->visuals.array) { - this->loadFxElemVisuals(&elemDef->visuals.array[j], elemDef->elemType, builder, &buffer); - } - } - } - else if (elemDef->visualCount == 1) - { - this->loadFxElemVisuals(&elemDef->visuals.instance, elemDef->elemType, builder, &buffer); - } - } + elemDef->visuals.array = buffer.readArray(elemDef->visualCount); - if (elemDef->effectOnImpact.handle) - { - elemDef->effectOnImpact.handle = Components::AssetHandler::FindAssetForZone(Game::ASSET_TYPE_FX, buffer.readString(), builder).fx; - } - - if (elemDef->effectOnDeath.handle) - { - elemDef->effectOnDeath.handle = Components::AssetHandler::FindAssetForZone(Game::ASSET_TYPE_FX, buffer.readString(), builder).fx; - } - - if (elemDef->effectEmitted.handle) - { - elemDef->effectEmitted.handle = Components::AssetHandler::FindAssetForZone(Game::ASSET_TYPE_FX, buffer.readString(), builder).fx; - } - - // Save_FxElemExtendedDefPtr - { - - if (elemDef->elemType == Game::FX_ELEM_TYPE_TRAIL) - { - // Save_FxTrailDef - { - if (elemDef->extended.trailDef) - { - auto* trailDef = buffer.readObject(); - elemDef->extended.trailDef = trailDef; - - if (trailDef->verts) + for (char j = 0; j < elemDef->visualCount; ++j) { - trailDef->verts = buffer.readArray(trailDef->vertCount); - } - - if (trailDef->inds) - { - trailDef->inds = buffer.readArray(trailDef->indCount); + this->loadFxElemVisuals(&elemDef->visuals.array[j], elemDef->elemType, builder, &buffer); } } } - } - else if (version >= 2) - { - if (elemDef->elemType == Game::FX_ELEM_TYPE_SPARK_FOUNTAIN) + else { - if (elemDef->extended.sparkFountainDef) + this->loadFxElemVisuals(&elemDef->visuals.instance, elemDef->elemType, builder, &buffer); + } + } + + if (elemDef->effectOnImpact.handle) + { + elemDef->effectOnImpact.handle = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_FX, buffer.readString().data(), builder).fx; + } + + if (elemDef->effectOnDeath.handle) + { + elemDef->effectOnDeath.handle = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_FX, buffer.readString().data(), builder).fx; + } + + if (elemDef->effectEmitted.handle) + { + elemDef->effectEmitted.handle = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_FX, buffer.readString().data(), builder).fx; + } + + // Save_FxElemExtendedDefPtr + { + + if (elemDef->elemType == Game::FX_ELEM_TYPE_TRAIL) + { + // Save_FxTrailDef { - elemDef->extended.sparkFountainDef = buffer.readObject(); + if (elemDef->extended.trailDef) + { + Game::FxTrailDef* trailDef = buffer.readObject(); + elemDef->extended.trailDef = trailDef; + + if (trailDef->verts) + { + trailDef->verts = buffer.readArray(trailDef->vertCount); + } + + if (trailDef->inds) + { + trailDef->inds = buffer.readArray(trailDef->indCount); + } + } } } + else if (elemDef->extended.trailDef) + { + Components::Logger::Error(Game::ERR_FATAL, "Fx element of type {} has traildef, that's impossible?\n", elemDef->elemType); + } } } } @@ -277,7 +270,7 @@ namespace Assets // TODO: Convert editor fx to real fx } #else - (void)name; + (name); #endif } diff --git a/src/Components/Modules/AssetInterfaces/IFxEffectDef.hpp b/src/Components/Modules/AssetInterfaces/IFxEffectDef.hpp index defa408e..9a877050 100644 --- a/src/Components/Modules/AssetInterfaces/IFxEffectDef.hpp +++ b/src/Components/Modules/AssetInterfaces/IFxEffectDef.hpp @@ -12,13 +12,13 @@ namespace Assets void load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) override; private: - static void markFxElemVisuals(Game::FxElemVisuals* visuals, char elemType, Components::ZoneBuilder::Zone* builder); - static void saveFxElemVisuals(Game::FxElemVisuals* visuals, Game::FxElemVisuals* destVisuals, char elemType, Components::ZoneBuilder::Zone* builder); + void markFxElemVisuals(Game::FxElemVisuals* visuals, char elemType, Components::ZoneBuilder::Zone* builder); + void saveFxElemVisuals(Game::FxElemVisuals* visuals, Game::FxElemVisuals* destVisuals, char elemType, Components::ZoneBuilder::Zone* builder); - static void loadEfx(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder); + void loadEfx(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder); 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); - static void loadFxElemVisuals(Game::FxElemVisuals* visuals, char elemType, Components::ZoneBuilder::Zone* builder, Utils::Stream::Reader* reader); + void loadFxElemVisuals(Game::FxElemVisuals* visuals, char elemType, Components::ZoneBuilder::Zone* builder, Utils::Stream::Reader* reader); }; } diff --git a/src/Components/Modules/AssetInterfaces/IFxWorld.cpp b/src/Components/Modules/AssetInterfaces/IFxWorld.cpp index 98d99d78..6988543f 100644 --- a/src/Components/Modules/AssetInterfaces/IFxWorld.cpp +++ b/src/Components/Modules/AssetInterfaces/IFxWorld.cpp @@ -1,11 +1,6 @@ #include - -#include - #include "IFxWorld.hpp" -#define IW4X_FXWORLD_VERSION 1 - namespace Assets { void IFxWorld::save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) @@ -192,161 +187,6 @@ namespace Assets } void IFxWorld::load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) - { - if (!header->fxWorld) loadFromDisk(header, name, builder); - if (!header->fxWorld) generate(header, name, builder); - - assert(header->fxWorld); - } - - void IFxWorld::loadFromDisk(Game::XAssetHeader* header, const std::string& _name, Components::ZoneBuilder::Zone* builder) - { - std::string name = _name; - Utils::String::Replace(name, "maps/mp/", ""); - Utils::String::Replace(name, ".d3dbsp", ""); - - Components::FileSystem::File fxWorldFile(std::format("fxworld/{}.iw4x.json", name)); - if (!fxWorldFile.exists()) - { - return; - } - - nlohmann::json fxWorldJson; - try - { - fxWorldJson = nlohmann::json::parse(fxWorldFile.getBuffer()); - } - catch (const std::exception& e) - { - Components::Logger::PrintError(Game::CON_CHANNEL_ERROR, "Invalid JSON for gameworld {}! Error message: {}", name, e.what()); - return; - } - - if (!fxWorldJson.is_object()) - { - Components::Logger::PrintError(Game::CON_CHANNEL_ERROR, "Invalid FXWORLD JSON for {}\n", name); - return; - } - - auto version = fxWorldJson["version"].is_number() ? fxWorldJson["version"].get() : 0; - if (version != IW4X_FXWORLD_VERSION) - { - Components::Logger::PrintError(Game::CON_CHANNEL_ERROR, "Invalid FXWORLD json version for {}, expected {} and got {}\n", name, IW4X_FXWORLD_VERSION, version); - return; - } - - auto map = builder->getAllocator()->allocate(); - map->name = builder->getAllocator()->duplicateString(_name); - - try - { - auto glassSys = &map->glassSys; - auto glassSysJson = fxWorldJson["glassSys"]; - - glassSys->time = glassSysJson["time"].get(); - glassSys->prevTime = glassSysJson["prevTime"].get(); - glassSys->defCount = glassSysJson["defCount"].get(); - glassSys->pieceLimit = glassSysJson["pieceLimit"].get(); - glassSys->pieceWordCount = glassSysJson["pieceWordCount"].get(); - glassSys->initPieceCount = glassSysJson["initPieceCount"].get(); - glassSys->cellCount = glassSysJson["cellCount"].get(); - glassSys->activePieceCount = glassSysJson["activePieceCount"].get(); - glassSys->firstFreePiece = glassSysJson["firstFreePiece"].get(); - glassSys->geoDataLimit = glassSysJson["geoDataLimit"].get(); - glassSys->geoDataCount = glassSysJson["geoDataCount"].get(); - glassSys->initGeoDataCount = glassSysJson["initGeoDataCount"].get(); - - auto i = 0; - glassSys->defs = builder->getAllocator()->allocateArray(glassSys->defCount); - for (auto member : glassSysJson["defs"]) - { - auto def = &glassSys->defs[i]; - - def->halfThickness = member["halfThickness"].get(); - - auto xy = 0; - for (auto x = 0; x < 2; x++) - { - for (auto y = 0; y < 2; y++) - { - def->texVecs[x][y] = member["texVecs"][xy].get(); - xy++; - } - } - - def->color.packed = member["color"].get(); - - auto matShateredName = member["materialShattered"].get(); - auto matName = member["material"].get(); - auto physPresetName = member["physPreset"].get(); - def->material = Components::AssetHandler::FindAssetForZone(Game::ASSET_TYPE_MATERIAL, matName, builder).material; - def->materialShattered = Components::AssetHandler::FindAssetForZone(Game::ASSET_TYPE_MATERIAL, matShateredName, builder).material; - def->physPreset = Components::AssetHandler::FindAssetForZone(Game::ASSET_TYPE_PHYSPRESET, physPresetName, builder ).physPreset; - - assert(def->material); - assert(def->materialShattered); - assert(def->physPreset); - ++i; - } - - i = 0; - glassSys->initPieceStates = builder->getAllocator()->allocateArray(glassSys->initPieceCount); - for (auto member : glassSysJson["initPieceStates"]) - { - auto initial = &glassSys->initPieceStates[i]; - - for (int j = 0; j < ARRAYSIZE(initial->frame.quat); j++) - { - initial->frame.quat[j] = member["frame"]["quat"][j].get(); - } - - for (int j = 0; j < ARRAYSIZE(initial->frame.origin); j++) - { - initial->frame.origin[j] = member["frame"]["origin"][j].get(); - } - - initial->radius = member["radius"].get(); - initial->texCoordOrigin[0] = member["texCoordOrigin"][0].get(); - initial->texCoordOrigin[1] = member["texCoordOrigin"][1].get(); - initial->supportMask = member["supportMask"].get(); - initial->areaX2 = member["areaX2"].get(); - initial->defIndex = member["defIndex"].get(); - initial->vertCount = member["vertCount"].get(); - initial->fanDataCount = member["fanDataCount"].get(); - ++i; - } - - i = 0; - glassSys->initGeoData = builder->getAllocator()->allocateArray(glassSys->initGeoDataCount); - for (auto member : glassSysJson["initGeoData"]) - { - auto data = &glassSys->initGeoData[i]; - data->anonymous[0] = member[0]; - data->anonymous[1] = member[1]; - ++i; - } - } - catch (const nlohmann::json::exception& e) - { - Components::Logger::PrintError(Game::CON_CHANNEL_ERROR, "Malformed FXWORLD JSON for {}! Error message: {}\n", name, e.what()); - return; - } - - map->glassSys.piecePlaces = builder->getAllocator()->allocateArray(map->glassSys.pieceLimit); - map->glassSys.pieceStates = builder->getAllocator()->allocateArray(map->glassSys.pieceLimit); - map->glassSys.pieceDynamics = builder->getAllocator()->allocateArray(map->glassSys.pieceLimit); - map->glassSys.geoData = builder->getAllocator()->allocateArray(map->glassSys.geoDataLimit); - map->glassSys.isInUse = builder->getAllocator()->allocateArray(map->glassSys.pieceWordCount); - map->glassSys.cellBits = builder->getAllocator()->allocateArray(map->glassSys.pieceWordCount * map->glassSys.cellCount); - map->glassSys.visData = builder->getAllocator()->allocateArray((map->glassSys.pieceLimit + 15) & 0xFFFFFFF0); // ugh - map->glassSys.linkOrg = reinterpret_cast(builder->getAllocator()->allocateArray(map->glassSys.pieceLimit)); - map->glassSys.halfThickness = builder->getAllocator()->allocateArray(map->glassSys.pieceLimit * 3); - map->glassSys.lightingHandles = builder->getAllocator()->allocateArray(map->glassSys.initPieceCount); - - header->fxWorld = map; - } - - void IFxWorld::generate(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) { Game::FxWorld* map = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_FXWORLD, name.data()).fxWorld; if (map) return; @@ -354,7 +194,7 @@ namespace Assets // Generate map = builder->getAllocator()->allocate(); map->name = builder->getAllocator()->duplicateString(name); - + // No glass for you! ZeroMemory(&map->glassSys, sizeof(map->glassSys)); diff --git a/src/Components/Modules/AssetInterfaces/IFxWorld.hpp b/src/Components/Modules/AssetInterfaces/IFxWorld.hpp index 4f1590c1..a19ddf56 100644 --- a/src/Components/Modules/AssetInterfaces/IFxWorld.hpp +++ b/src/Components/Modules/AssetInterfaces/IFxWorld.hpp @@ -10,7 +10,5 @@ namespace Assets void save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override; void mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override; void load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) override; - void loadFromDisk(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder); - void generate(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder); }; } diff --git a/src/Components/Modules/AssetInterfaces/IGameWorldMp.cpp b/src/Components/Modules/AssetInterfaces/IGameWorldMp.cpp index b3f5e5f0..2bbbb004 100644 --- a/src/Components/Modules/AssetInterfaces/IGameWorldMp.cpp +++ b/src/Components/Modules/AssetInterfaces/IGameWorldMp.cpp @@ -153,7 +153,7 @@ namespace Assets { nlohmann::json::array_t jsonPiecesIndices = jsonGlassName["piecesIndices"]; glassData->glassNames[i].pieceCount = static_cast(jsonPiecesIndices.size()); - glassData->glassNames[i].pieceIndices = builder->getAllocator()->allocateArray(glassData->glassNames[i].pieceCount); + for (size_t j = 0; j < glassData->glassNames[i].pieceCount; j++) { glassData->glassNames[i].pieceIndices[j] = jsonPiecesIndices[j].get(); @@ -162,9 +162,9 @@ namespace Assets } } - if (jsonGlassData["glassPieces"].is_array()) + if (gameWorldJson["glassPieces"].is_array()) { - nlohmann::json::array_t glassPieces = jsonGlassData["glassPieces"]; + nlohmann::json::array_t glassPieces = gameWorldJson["glassPieces"]; glassData->pieceCount = glassPieces.size(); glassData->glassPieces = builder->getAllocator()->allocateArray(glassData->pieceCount); diff --git a/src/Components/Modules/AssetInterfaces/IGfxWorld.cpp b/src/Components/Modules/AssetInterfaces/IGfxWorld.cpp index 5a9e2bd7..8548c309 100644 --- a/src/Components/Modules/AssetInterfaces/IGfxWorld.cpp +++ b/src/Components/Modules/AssetInterfaces/IGfxWorld.cpp @@ -3,6 +3,27 @@ #define IW4X_GFXMAP_VERSION 1 +// The xmodel vehicle_small_hatch_green_destructible_mp causes EXTREME lag +// when placed in the world, for reasons unknown. +// +// Something happens with the SModelSurfIterator which makes it load garbage +// as an XSurface in the middle of otherwise valid surfaces. This bug is very +// easy to reproduce with an empty map and just this car in the middle +// +// As of know we do not know why the iterator corruption occurs or what causes +// it. It doesn't seem linked to the SModel, nor to the materials or techsets, +// nor to the sortkeys, nor to the tilemode, boneinfo, and so on. So for now +// and to make it work for majority of users, we just swap the car. (no, using +// the identical car from iw4's favela_escape doesn't work either!) +// +// Two other models have this problem: ch_apartment_9story_noentry_02 and +// ch_apartment_5story_noentry_01 +// But these exist in mp_vacant in slightly different versions, and can be +// swapped safely by deleting the two .iw4XModel files and requiring mp_vacant +// or a minimal zone containing just these two models. +// +#define SWAP_GREEN_VEHICLE_XMODEL 1 + namespace Assets { void IGfxWorld::loadGfxWorldDpvsStatic(Game::GfxWorld* world, Game::GfxWorldDpvsStatic* asset, Components::ZoneBuilder::Zone* builder, Utils::Stream::Reader* reader) @@ -23,12 +44,11 @@ namespace Assets for (unsigned int i = 0; i < world->surfaceCount; ++i) { - auto* surface = &asset->surfaces[i]; + Game::GfxSurface* surface = &asset->surfaces[i]; + if (surface->material) { - auto materialName = reader->readString(); - world->dpvs.surfaces[i].material = Components::AssetHandler::FindAssetForZone(Game::ASSET_TYPE_MATERIAL, materialName, builder).material; - assert(world->dpvs.surfaces[i].material); + world->dpvs.surfaces[i].material = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_MATERIAL, reader->readString().data(), builder).material; } } } @@ -49,19 +69,8 @@ namespace Assets if (model->model) { auto name = reader->readString(); - while (name.ends_with(".")) - { - // Happens with some flowers in mp_paris - // I'm not confident this will work on every map - // But regardless Game FS does not support having a file terminated with "." - // Probably an artist made a typo in MW3... - // Example: "foliage_gardenflowers_red_bright..iw4xModel" - name = name.substr(0, name.size() - 1); - } - - assert(!name.empty()); - model->model = Components::AssetHandler::FindAssetForZone(Game::ASSET_TYPE_XMODEL, name, builder).model; + model->model = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_XMODEL, name.data(), builder).model; assert(model->model); } @@ -77,7 +86,7 @@ namespace Assets for (unsigned int i = 0; i < asset->reflectionProbeCount; ++i) { - asset->reflectionProbes[i] = Components::AssetHandler::FindAssetForZone(Game::ASSET_TYPE_IMAGE, reader->readString(), builder).image; + asset->reflectionProbes[i] = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_IMAGE, reader->readString().data(), builder).image; } } @@ -92,27 +101,28 @@ namespace Assets for (int i = 0; i < asset->lightmapCount; ++i) { - auto* lightmapArray = &asset->lightmaps[i]; + Game::GfxLightmapArray* lightmapArray = &asset->lightmaps[i]; + if (lightmapArray->primary) { - lightmapArray->primary = Components::AssetHandler::FindAssetForZone(Game::ASSET_TYPE_IMAGE, reader->readString(), builder).image; + lightmapArray->primary = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_IMAGE, reader->readString().data(), builder).image; } if (lightmapArray->secondary) { - lightmapArray->secondary = Components::AssetHandler::FindAssetForZone(Game::ASSET_TYPE_IMAGE, reader->readString(), builder).image; + lightmapArray->secondary = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_IMAGE, reader->readString().data(), builder).image; } } } if (asset->lightmapOverridePrimary) { - asset->lightmapOverridePrimary = Components::AssetHandler::FindAssetForZone(Game::ASSET_TYPE_IMAGE, reader->readString(), builder).image; + asset->lightmapOverridePrimary = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_IMAGE, reader->readString().data(), builder).image; } if (asset->lightmapOverrideSecondary) { - asset->lightmapOverrideSecondary = Components::AssetHandler::FindAssetForZone(Game::ASSET_TYPE_IMAGE, reader->readString(), builder).image; + asset->lightmapOverrideSecondary = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_IMAGE, reader->readString().data(), builder).image; } // saveGfxWorldVertexData @@ -146,305 +156,295 @@ namespace Assets Components::FileSystem::File mapFile(std::format("gfxworld/{}.iw4xGfxWorld", name)); - if (!mapFile.exists()) + if (mapFile.exists()) { - return; - } + Utils::Stream::Reader reader(builder->getAllocator(), mapFile.getBuffer()); - Utils::Stream::Reader reader(builder->getAllocator(), mapFile.getBuffer()); - - auto magic = reader.read(); - if (std::memcmp(&magic, "IW4xGfxW", 8) != 0) - { - Components::Logger::Error(Game::ERR_FATAL, "Reading gfxworld '{}' failed, header is invalid!", name); - } - - int version = reader.read(); - if (version != IW4X_GFXMAP_VERSION) - { - Components::Logger::Error(Game::ERR_FATAL, "Reading gfxworld '{}' failed, expected version is {}, but it was {}!", name, IW4X_GFXMAP_VERSION, version); - } - - auto* asset = reader.readObject(); - header->gfxWorld = asset; - - if (asset->name) - { - asset->name = reader.readCString(); - } - - if (asset->baseName) - { - asset->baseName = reader.readCString(); - } - - if (asset->skies) - { - asset->skies = reader.readArray(asset->skyCount); - - for (int i = 0; i < asset->skyCount; ++i) + __int64 magic = reader.read<__int64>(); + if (std::memcmp(&magic, "IW4xGfxW", 8)) { - auto* sky = &asset->skies[i]; - - if (sky->skyStartSurfs) - { - sky->skyStartSurfs = reader.readArray(sky->skySurfCount); - } - - if (sky->skyImage) - { - sky->skyImage = Components::AssetHandler::FindAssetForZone(Game::ASSET_TYPE_IMAGE, reader.readString(), builder).image; - } + Components::Logger::Error(Game::ERR_FATAL, "Reading gfxworld '{}' failed, header is invalid!", name); } - } - // GfxWorldDpvsPlanes - { - if (asset->dpvsPlanes.planes) + int version = reader.read(); + if (version != IW4X_GFXMAP_VERSION) { - asset->dpvsPlanes.planes = reader.readArray(asset->planeCount); + Components::Logger::Error(Game::ERR_FATAL, "Reading gfxworld '{}' failed, expected version is {}, but it was {}!", name, IW4X_GFXMAP_VERSION, version); + } - auto clip = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_CLIPMAP_MP, asset->name, builder).clipMap; - if (clip) + Game::GfxWorld* asset = reader.readObject(); + header->gfxWorld = asset; + + if (asset->name) + { + asset->name = reader.readCString(); + } + + if (asset->baseName) + { + asset->baseName = reader.readCString(); + } + + if (asset->skies) + { + asset->skies = reader.readArray(asset->skyCount); + + for (int i = 0; i < asset->skyCount; ++i) { - assert(clip->planeCount == static_cast(asset->planeCount)); - for (size_t i = 0; i < clip->planeCount; i++) + Game::GfxSky* sky = &asset->skies[i]; + + if (sky->skyStartSurfs) { - assert(!std::memcmp(&clip->planes[i], &asset->dpvsPlanes.planes[i], sizeof Game::cplane_s)); + sky->skyStartSurfs = reader.readArray(sky->skySurfCount); } - asset->dpvsPlanes.planes = clip->planes; - } - else - { - Components::Logger::Error(Game::ERR_FATAL, "GfxWorld dpvs planes not mapped. This shouldn't happen. Make sure to load the ClipMap first!\n"); - } - } - - if (asset->dpvsPlanes.nodes) - { - asset->dpvsPlanes.nodes = reader.readArray(asset->nodeCount); - } - } - - auto cellCount = asset->dpvsPlanes.cellCount; - - if (asset->aabbTreeCounts) - { - asset->aabbTreeCounts = reader.readArray(cellCount); - } - - if (asset->aabbTrees) - { - asset->aabbTrees = reader.readArray(cellCount); - - for (auto i = 0; i < cellCount; ++i) - { - auto* cellTree = &asset->aabbTrees[i]; - - if (cellTree->aabbTree) - { - cellTree->aabbTree = reader.readArray(asset->aabbTreeCounts[i].aabbTreeCount); - - for (int j = 0; j < asset->aabbTreeCounts[i].aabbTreeCount; ++j) + if (sky->skyImage) { - auto* aabbTree = &cellTree->aabbTree[j]; + sky->skyImage = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_IMAGE, reader.readString().data(), builder).image; + } + } + } - if (aabbTree->smodelIndexes) + // GfxWorldDpvsPlanes + { + if (asset->dpvsPlanes.planes) + { + void* oldPtr = asset->dpvsPlanes.planes; + asset->dpvsPlanes.planes = reader.readArray(asset->planeCount); + + if (builder->getAllocator()->isPointerMapped(oldPtr)) + { + asset->dpvsPlanes.planes = builder->getAllocator()->getPointer(oldPtr); + } + else + { + builder->getAllocator()->mapPointer(oldPtr, asset->dpvsPlanes.planes); + Components::Logger::Print("GfxWorld dpvs planes not mapped. This shouldn't happen. Make sure to load the ClipMap first!\n"); + } + } + + if (asset->dpvsPlanes.nodes) + { + asset->dpvsPlanes.nodes = reader.readArray(asset->nodeCount); + } + } + + + int cellCount = asset->dpvsPlanes.cellCount; + + if (asset->aabbTreeCounts) + { + asset->aabbTreeCounts = reader.readArray(cellCount); + } + + if (asset->aabbTrees) + { + asset->aabbTrees = reader.readArray(cellCount); + + for (int i = 0; i < cellCount; ++i) + { + Game::GfxCellTree* cellTree = &asset->aabbTrees[i]; + + if (cellTree->aabbTree) + { + cellTree->aabbTree = reader.readArray(asset->aabbTreeCounts[i].aabbTreeCount); + + for (int j = 0; j < asset->aabbTreeCounts[i].aabbTreeCount; ++j) { - auto* oldPointer = aabbTree->smodelIndexes; - if (builder->getAllocator()->isPointerMapped(oldPointer)) - { - // We still have to read it - reader.readArray(aabbTree->smodelIndexCount); + Game::GfxAabbTree* aabbTree = &cellTree->aabbTree[j]; - aabbTree->smodelIndexes = builder->getAllocator()->getPointer(oldPointer); - } - else + if (aabbTree->smodelIndexes) { - aabbTree->smodelIndexes = reader.readArray(aabbTree->smodelIndexCount); - - for (unsigned short k = 0; k < aabbTree->smodelIndexCount; ++k) + unsigned short* oldPointer = aabbTree->smodelIndexes; + if(builder->getAllocator()->isPointerMapped(oldPointer)) { - builder->getAllocator()->mapPointer(&oldPointer[k], &aabbTree->smodelIndexes[k]); + // We still have to read it + reader.readArray(aabbTree->smodelIndexCount); + + aabbTree->smodelIndexes = builder->getAllocator()->getPointer(oldPointer); + } + else + { + aabbTree->smodelIndexes = reader.readArray(aabbTree->smodelIndexCount); + + for (unsigned short k = 0; k < aabbTree->smodelIndexCount; ++k) + { + builder->getAllocator()->mapPointer(&oldPointer[k], &aabbTree->smodelIndexes[k]); + } } } } } } } - } - if (asset->cells) - { - asset->cells = reader.readArray(cellCount); - - for (auto i = 0; i < cellCount; ++i) + if (asset->cells) { - auto* cell = &asset->cells[i]; + asset->cells = reader.readArray(cellCount); - if (cell->portals) + for (int i = 0; i < cellCount; ++i) { - cell->portals = reader.readArray(cell->portalCount); + Game::GfxCell* cell = &asset->cells[i]; - for (auto j = 0; j < cell->portalCount; ++j) + if (cell->portals) { - auto* portal = &cell->portals[j]; - if (portal->vertices) + cell->portals = reader.readArray(cell->portalCount); + + for (int j = 0; j < cell->portalCount; ++j) { - portal->vertices = reader.readArray(portal->vertexCount); + Game::GfxPortal* portal = &cell->portals[j]; + + if (portal->vertices) + { + portal->vertices = reader.readArray(portal->vertexCount); + } } } - } - if (cell->reflectionProbes) - { - cell->reflectionProbes = reader.readArray(cell->reflectionProbeCount); - } - } - } - - this->loadGfxWorldDraw(&asset->draw, builder, &reader); - - // GfxLightGrid - { - if (asset->lightGrid.rowDataStart) - { - asset->lightGrid.rowDataStart = reader.readArray((asset->lightGrid.maxs[asset->lightGrid.rowAxis] - asset->lightGrid.mins[asset->lightGrid.rowAxis]) + 1); - } - - if (asset->lightGrid.rawRowData) - { - asset->lightGrid.rawRowData = reader.readArray(asset->lightGrid.rawRowDataSize); - } - - if (asset->lightGrid.entries) - { - asset->lightGrid.entries = reader.readArray(asset->lightGrid.entryCount); - } - - if (asset->lightGrid.colors) - { - asset->lightGrid.colors = reader.readArray(asset->lightGrid.colorCount); - } - } - - if (asset->models) - { - asset->models = reader.readArray(asset->modelCount); - } - - if (asset->materialMemory) - { - asset->materialMemory = reader.readArray(asset->materialMemoryCount); - - for (auto i = 0; i < asset->materialMemoryCount; ++i) - { - auto* materialMemory = &asset->materialMemory[i]; - if (materialMemory->material) - { - auto materialName = reader.readString(); - materialMemory->material = Components::AssetHandler::FindAssetForZone(Game::ASSET_TYPE_MATERIAL, materialName, builder).material; - assert(materialMemory->material); - } - } - } - - if (asset->sun.spriteMaterial) - { - auto materialName = reader.readString(); - asset->sun.spriteMaterial = Components::AssetHandler::FindAssetForZone(Game::ASSET_TYPE_MATERIAL, materialName, builder).material; - assert(asset->sun.spriteMaterial); - } - - if (asset->sun.flareMaterial) - { - auto materialName = reader.readString(); - asset->sun.flareMaterial = Components::AssetHandler::FindAssetForZone(Game::ASSET_TYPE_MATERIAL, materialName, builder).material; - assert(asset->sun.flareMaterial); - } - - if (asset->outdoorImage) - { - auto materialName = reader.readString(); - asset->outdoorImage = Components::AssetHandler::FindAssetForZone(Game::ASSET_TYPE_IMAGE, materialName, builder).image; - assert(asset->outdoorImage); - } - - if (asset->primaryLightCount > 0) - { - Utils::Stream::ClearPointer(&asset->primaryLightEntityShadowVis); - } - - if (asset->dpvsDyn.dynEntClientCount[0] > 0) - { - Utils::Stream::ClearPointer(&asset->sceneDynModel); - Utils::Stream::ClearPointer(&asset->primaryLightDynEntShadowVis[0]); - Utils::Stream::ClearPointer(&asset->nonSunPrimaryLightForModelDynEnt); - } - - if (asset->dpvsDyn.dynEntClientCount[1] > 0) - { - Utils::Stream::ClearPointer(&asset->sceneDynBrush); - Utils::Stream::ClearPointer(&asset->primaryLightDynEntShadowVis[1]); - } - - if (asset->shadowGeom) - { - asset->shadowGeom = reader.readArray(asset->primaryLightCount); - - for (unsigned int i = 0; i < asset->primaryLightCount; ++i) - { - auto* shadowGeometry = &asset->shadowGeom[i]; - - if (shadowGeometry->sortedSurfIndex) - { - shadowGeometry->sortedSurfIndex = reader.readArray(shadowGeometry->surfaceCount); - } - - if (shadowGeometry->smodelIndex) - { - shadowGeometry->smodelIndex = reader.readArray(shadowGeometry->smodelCount); - } - } - } - - if (asset->lightRegion) - { - asset->lightRegion = reader.readArray(asset->primaryLightCount); - - for (unsigned int i = 0; i < asset->primaryLightCount; ++i) - { - auto* lightRegion = &asset->lightRegion[i]; - - if (lightRegion->hulls) - { - lightRegion->hulls = reader.readArray(lightRegion->hullCount); - - for (unsigned int j = 0; j < lightRegion->hullCount; ++j) + if (cell->reflectionProbes) { - auto* lightRegionHull = &lightRegion->hulls[j]; - if (lightRegionHull->axis) + cell->reflectionProbes = reader.readArray(cell->reflectionProbeCount); + } + } + } + + this->loadGfxWorldDraw(&asset->draw, builder, &reader); + + // GfxLightGrid + { + if (asset->lightGrid.rowDataStart) + { + asset->lightGrid.rowDataStart = reader.readArray((asset->lightGrid.maxs[asset->lightGrid.rowAxis] - asset->lightGrid.mins[asset->lightGrid.rowAxis]) + 1); + } + + if (asset->lightGrid.rawRowData) + { + asset->lightGrid.rawRowData = reader.readArray(asset->lightGrid.rawRowDataSize); + } + + if (asset->lightGrid.entries) + { + asset->lightGrid.entries = reader.readArray(asset->lightGrid.entryCount); + } + + if (asset->lightGrid.colors) + { + asset->lightGrid.colors = reader.readArray(asset->lightGrid.colorCount); + } + } + + if (asset->models) + { + asset->models = reader.readArray(asset->modelCount); + } + + if (asset->materialMemory) + { + asset->materialMemory = reader.readArray(asset->materialMemoryCount); + + for (int i = 0; i < asset->materialMemoryCount; ++i) + { + Game::MaterialMemory* materialMemory = &asset->materialMemory[i]; + + if (materialMemory->material) + { + materialMemory->material = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_MATERIAL, reader.readString().data(), builder).material; + } + } + } + + if (asset->sun.spriteMaterial) + { + asset->sun.spriteMaterial = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_MATERIAL, reader.readString().data(), builder).material; + } + + if (asset->sun.flareMaterial) + { + asset->sun.flareMaterial = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_MATERIAL, reader.readString().data(), builder).material; + } + + if (asset->outdoorImage) + { + asset->outdoorImage = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_IMAGE, reader.readString().data(), builder).image; + } + + if (asset->primaryLightCount > 0) + { + Utils::Stream::ClearPointer(&asset->primaryLightEntityShadowVis); + } + + if (asset->dpvsDyn.dynEntClientCount[0] > 0) + { + Utils::Stream::ClearPointer(&asset->sceneDynModel); + Utils::Stream::ClearPointer(&asset->primaryLightDynEntShadowVis[0]); + Utils::Stream::ClearPointer(&asset->nonSunPrimaryLightForModelDynEnt); + } + + if (asset->dpvsDyn.dynEntClientCount[1] > 0) + { + Utils::Stream::ClearPointer(&asset->sceneDynBrush); + Utils::Stream::ClearPointer(&asset->primaryLightDynEntShadowVis[1]); + } + + if (asset->shadowGeom) + { + asset->shadowGeom = reader.readArray(asset->primaryLightCount); + + for (unsigned int i = 0; i < asset->primaryLightCount; ++i) + { + Game::GfxShadowGeometry* shadowGeometry = &asset->shadowGeom[i]; + + if (shadowGeometry->sortedSurfIndex) + { + shadowGeometry->sortedSurfIndex = reader.readArray(shadowGeometry->surfaceCount); + } + + if (shadowGeometry->smodelIndex) + { + shadowGeometry->smodelIndex = reader.readArray(shadowGeometry->smodelCount); + } + } + } + + if (asset->lightRegion) + { + asset->lightRegion = reader.readArray(asset->primaryLightCount); + + for (unsigned int i = 0; i < asset->primaryLightCount; ++i) + { + Game::GfxLightRegion* lightRegion = &asset->lightRegion[i]; + + if (lightRegion->hulls) + { + lightRegion->hulls = reader.readArray(lightRegion->hullCount); + + for (unsigned int j = 0; j < lightRegion->hullCount; ++j) { - lightRegionHull->axis = reader.readArray(lightRegionHull->axisCount); + Game::GfxLightRegionHull* lightRegionHull = &lightRegion->hulls[j]; + + if (lightRegionHull->axis) + { + lightRegionHull->axis = reader.readArray(lightRegionHull->axisCount); + } } } } } - } - this->loadGfxWorldDpvsStatic(asset, &asset->dpvs, builder, &reader); + this->loadGfxWorldDpvsStatic(asset, &asset->dpvs, builder, &reader); - // Obsolete, IW3 has no support for that - if (asset->heroOnlyLights) - { - asset->heroOnlyLights = reader.readArray(asset->heroOnlyLightCount); + // Obsolete, IW3 has no support for that + if (asset->heroOnlyLights) + { + asset->heroOnlyLights = reader.readArray(asset->heroOnlyLightCount); + } } } void IGfxWorld::mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) { - auto* asset = header.gfxWorld; + Game::GfxWorld* asset = header.gfxWorld; + if (asset->draw.reflectionProbes) { for (unsigned int i = 0; i < asset->draw.reflectionProbeCount; ++i) @@ -455,7 +455,7 @@ namespace Assets if (asset->draw.lightmaps) { - for (auto i = 0; i < asset->draw.lightmapCount; ++i) + for (int i = 0; i < asset->draw.lightmapCount; ++i) { if (asset->draw.lightmaps[i].primary) { @@ -599,7 +599,7 @@ namespace Assets { buffer->align(Utils::Stream::ALIGN_4); - auto** imageDest = buffer->dest(); + Game::GfxImage** imageDest = buffer->dest(); buffer->saveArray(asset->reflectionProbes, asset->reflectionProbeCount); for (unsigned int i = 0; i < asset->reflectionProbeCount; ++i) @@ -648,13 +648,13 @@ namespace Assets buffer->align(Utils::Stream::ALIGN_4); - auto* lightmapArrayDestTable = buffer->dest(); + Game::GfxLightmapArray* lightmapArrayDestTable = buffer->dest(); buffer->saveArray(asset->lightmaps, asset->lightmapCount); for (int i = 0; i < asset->lightmapCount; ++i) { - auto* lightmapArrayDest = &lightmapArrayDestTable[i]; - auto* lightmapArray = &asset->lightmaps[i]; + Game::GfxLightmapArray* lightmapArrayDest = &lightmapArrayDestTable[i]; + Game::GfxLightmapArray* lightmapArray = &asset->lightmaps[i]; if (lightmapArray->primary) { @@ -854,13 +854,13 @@ namespace Assets SaveLogEnter("GfxSurface"); buffer->align(Utils::Stream::ALIGN_4); - auto* destSurfaceTable = buffer->dest(); + Game::GfxSurface* destSurfaceTable = buffer->dest(); buffer->saveArray(asset->surfaces, world->surfaceCount); for (unsigned int i = 0; i < world->surfaceCount; ++i) { - auto* surface = &asset->surfaces[i]; - auto* destSurface = &destSurfaceTable[i]; + Game::GfxSurface* surface = &asset->surfaces[i]; + Game::GfxSurface* destSurface = &destSurfaceTable[i]; if (surface->material) { @@ -890,13 +890,13 @@ namespace Assets SaveLogEnter("GfxStaticModelDrawInst"); buffer->align(Utils::Stream::ALIGN_4); - auto* destModelTable = buffer->dest(); + Game::GfxStaticModelDrawInst* destModelTable = buffer->dest(); buffer->saveArray(asset->smodelDrawInsts, asset->smodelCount); for (unsigned int i = 0; i < asset->smodelCount; ++i) { - auto* model = &asset->smodelDrawInsts[i]; - auto* destModel = &destModelTable[i]; + Game::GfxStaticModelDrawInst* model = &asset->smodelDrawInsts[i]; + Game::GfxStaticModelDrawInst* destModel = &destModelTable[i]; if (model->model) { @@ -986,8 +986,8 @@ namespace Assets Utils::Stream* buffer = builder->getBuffer(); SaveLogEnter("GfxWorld"); - auto* asset = header.gfxWorld; - auto* dest = buffer->dest(); + Game::GfxWorld* asset = header.gfxWorld; + Game::GfxWorld* dest = buffer->dest(); buffer->save(asset); buffer->pushBlock(Game::XFILE_BLOCK_VIRTUAL); @@ -1012,13 +1012,13 @@ namespace Assets SaveLogEnter("GfxSky"); buffer->align(Utils::Stream::ALIGN_4); - auto* destSkyTable = buffer->dest(); + Game::GfxSky* destSkyTable = buffer->dest(); buffer->saveArray(asset->skies, asset->skyCount); for (int i = 0; i < asset->skyCount; ++i) { - auto* destSky = &destSkyTable[i]; - auto* sky = &asset->skies[i]; + Game::GfxSky* destSky = &destSkyTable[i]; + Game::GfxSky* sky = &asset->skies[i]; if (sky->skyStartSurfs) { @@ -1059,13 +1059,13 @@ namespace Assets SaveLogEnter("GfxCellTree"); buffer->align(Utils::Stream::ALIGN_128); - auto* destCellTreeTable = buffer->dest(); + Game::GfxCellTree* destCellTreeTable = buffer->dest(); buffer->saveArray(asset->aabbTrees, cellCount); for (int i = 0; i < cellCount; ++i) { - auto* destCellTree = &destCellTreeTable[i]; - auto* cellTree = &asset->aabbTrees[i]; + Game::GfxCellTree* destCellTree = &destCellTreeTable[i]; + Game::GfxCellTree* cellTree = &asset->aabbTrees[i]; if (cellTree->aabbTree) { @@ -1073,7 +1073,7 @@ namespace Assets SaveLogEnter("GfxAabbTree"); buffer->align(Utils::Stream::ALIGN_4); - auto* destAabbTreeTable = buffer->dest(); + Game::GfxAabbTree* destAabbTreeTable = buffer->dest(); buffer->saveArray(cellTree->aabbTree, asset->aabbTreeCounts[i].aabbTreeCount); // ok this one is based on some assumptions because the actual count is this @@ -1083,8 +1083,8 @@ namespace Assets for (int j = 0; j < asset->aabbTreeCounts[i].aabbTreeCount; ++j) { - auto* destAabbTree = &destAabbTreeTable[j]; - auto* aabbTree = &cellTree->aabbTree[j]; + Game::GfxAabbTree* destAabbTree = &destAabbTreeTable[j]; + Game::GfxAabbTree* aabbTree = &cellTree->aabbTree[j]; if (aabbTree->smodelIndexes) { @@ -1122,13 +1122,13 @@ namespace Assets SaveLogEnter("GfxCell"); buffer->align(Utils::Stream::ALIGN_4); - auto* destCellTable = buffer->dest(); + Game::GfxCell* destCellTable = buffer->dest(); buffer->saveArray(asset->cells, cellCount); for (int i = 0; i < cellCount; ++i) { - auto* destCell = &destCellTable[i]; - auto* cell = &asset->cells[i]; + Game::GfxCell* destCell = &destCellTable[i]; + Game::GfxCell* cell = &asset->cells[i]; if (cell->portals) { @@ -1136,13 +1136,13 @@ namespace Assets SaveLogEnter("GfxPortal"); buffer->align(Utils::Stream::ALIGN_4); - auto* destPortalTable = buffer->dest(); + Game::GfxPortal* destPortalTable = buffer->dest(); buffer->saveArray(cell->portals, cell->portalCount); for (int j = 0; j < cell->portalCount; ++j) { - auto* destPortal = &destPortalTable[j]; - auto* portal = &cell->portals[j]; + Game::GfxPortal* destPortal = &destPortalTable[j]; + Game::GfxPortal* portal = &cell->portals[j]; if (portal->vertices) { @@ -1189,13 +1189,13 @@ namespace Assets SaveLogEnter("MaterialMemory"); buffer->align(Utils::Stream::ALIGN_4); - auto* destMaterialMemoryTable = buffer->dest(); + Game::MaterialMemory* destMaterialMemoryTable = buffer->dest(); buffer->saveArray(asset->materialMemory, asset->materialMemoryCount); for (int i = 0; i < asset->materialMemoryCount; ++i) { - auto* destMaterialMemory = &destMaterialMemoryTable[i]; - auto* materialMemory = &asset->materialMemory[i]; + Game::MaterialMemory* destMaterialMemory = &destMaterialMemoryTable[i]; + Game::MaterialMemory* materialMemory = &asset->materialMemory[i]; if (materialMemory->material) { @@ -1284,13 +1284,13 @@ namespace Assets SaveLogEnter("GfxShadowGeometry"); buffer->align(Utils::Stream::ALIGN_4); - auto* destShadowGeometryTable = buffer->dest(); + Game::GfxShadowGeometry* destShadowGeometryTable = buffer->dest(); buffer->saveArray(asset->shadowGeom, asset->primaryLightCount); for (unsigned int i = 0; i < asset->primaryLightCount; ++i) { - auto* destShadowGeometry = &destShadowGeometryTable[i]; - auto* shadowGeometry = &asset->shadowGeom[i]; + Game::GfxShadowGeometry* destShadowGeometry = &destShadowGeometryTable[i]; + Game::GfxShadowGeometry* shadowGeometry = &asset->shadowGeom[i]; if (shadowGeometry->sortedSurfIndex) { @@ -1317,13 +1317,13 @@ namespace Assets SaveLogEnter("GfxLightRegion"); buffer->align(Utils::Stream::ALIGN_4); - auto* destLightRegionTable = buffer->dest(); + Game::GfxLightRegion* destLightRegionTable = buffer->dest(); buffer->saveArray(asset->lightRegion, asset->primaryLightCount); for (unsigned int i = 0; i < asset->primaryLightCount; ++i) { - auto* destLightRegion = &destLightRegionTable[i]; - auto* lightRegion = &asset->lightRegion[i]; + Game::GfxLightRegion* destLightRegion = &destLightRegionTable[i]; + Game::GfxLightRegion* lightRegion = &asset->lightRegion[i]; if (lightRegion->hulls) { @@ -1331,13 +1331,13 @@ namespace Assets SaveLogEnter("GfxLightRegionHull"); buffer->align(Utils::Stream::ALIGN_4); - auto* destLightRegionHullTable = buffer->dest(); + Game::GfxLightRegionHull* destLightRegionHullTable = buffer->dest(); buffer->saveArray(lightRegion->hulls, lightRegion->hullCount); for (unsigned int j = 0; j < lightRegion->hullCount; ++j) { - auto* destLightRegionHull = &destLightRegionHullTable[j]; - auto* lightRegionHull = &lightRegion->hulls[j]; + Game::GfxLightRegionHull* destLightRegionHull = &destLightRegionHullTable[j]; + Game::GfxLightRegionHull* lightRegionHull = &lightRegion->hulls[j]; if (lightRegionHull->axis) { @@ -1373,6 +1373,7 @@ namespace Assets Utils::Stream::ClearPointer(&dest->heroOnlyLights); } + //buffer->setPointerAssertion(false); buffer->popBlock(); SaveLogExit(); } diff --git a/src/Components/Modules/AssetInterfaces/ILoadedSound.cpp b/src/Components/Modules/AssetInterfaces/ILoadedSound.cpp index 5aa1533e..d651e99a 100644 --- a/src/Components/Modules/AssetInterfaces/ILoadedSound.cpp +++ b/src/Components/Modules/AssetInterfaces/ILoadedSound.cpp @@ -12,7 +12,7 @@ namespace Assets return; } - auto* sound = builder->getAllocator()->allocate(); + Game::LoadedSound* sound = builder->getAllocator()->allocate(); if (!sound) { Components::Logger::Print("Error allocating memory for sound structure!\n"); @@ -27,16 +27,16 @@ namespace Assets Utils::Stream::Reader reader(builder->getAllocator(), soundFile.getBuffer()); - auto chunkIDBuffer = reader.read(); + unsigned int chunkIDBuffer = reader.read(); if (chunkIDBuffer != 0x46464952) // RIFF { Components::Logger::Error(Game::ERR_FATAL, "Reading sound '{}' failed, header is invalid!", name); return; } - auto chunkSize = reader.read(); + unsigned int chunkSize = reader.read(); - auto format = reader.read(); + unsigned int format = reader.read(); if (format != 0x45564157) // WAVE { Components::Logger::Error(Game::ERR_FATAL, "Reading sound '{}' failed, header is invalid!", name); @@ -62,10 +62,7 @@ namespace Assets sound->sound.info.channels = reader.read(); sound->sound.info.rate = reader.read(); - - // We read samples later, this is byte rate we don't need it - reader.read(); - + sound->sound.info.samples = reader.read(); sound->sound.info.block_size = reader.read(); sound->sound.info.bits = reader.read(); @@ -79,7 +76,6 @@ namespace Assets case 0x61746164: // data sound->sound.info.data_len = chunkSize; - sound->sound.info.samples = chunkSize / (sound->sound.info.bits / 8); sound->sound.data = reader.readArray(chunkSize); break; @@ -106,9 +102,9 @@ namespace Assets { AssertSize(Game::LoadedSound, 44); - auto* buffer = builder->getBuffer(); - auto* asset = header.loadSnd; - auto* dest = buffer->dest(); + Utils::Stream* buffer = builder->getBuffer(); + Game::LoadedSound* asset = header.loadSnd; + Game::LoadedSound* dest = buffer->dest(); buffer->save(asset); buffer->pushBlock(Game::XFILE_BLOCK_VIRTUAL); diff --git a/src/Components/Modules/AssetInterfaces/IMaterial.cpp b/src/Components/Modules/AssetInterfaces/IMaterial.cpp index 7e05f08d..ebe509e2 100644 --- a/src/Components/Modules/AssetInterfaces/IMaterial.cpp +++ b/src/Components/Modules/AssetInterfaces/IMaterial.cpp @@ -40,8 +40,6 @@ namespace Assets if (!header->data) this->loadJson(header, name, builder); // Check if we want to load a material from disk if (!header->data) this->loadBinary(header, name, builder); // Check if we want to load a material from disk (binary format) if (!header->data) this->loadNative(header, name, builder); // Check if there is a native one - - assert(header->data); } @@ -208,17 +206,12 @@ namespace Assets textureDef->u.image = nullptr; if (textureJson["image"].is_string()) { - textureDef->u.image = Components::AssetHandler::FindAssetForZone( - Game::ASSET_TYPE_IMAGE, + textureDef->u.image = Components::AssetHandler::FindAssetForZone + ( + Game::XAssetType::ASSET_TYPE_IMAGE, textureJson["image"].get(), builder ).image; - - assert(textureDef->u.image); - } - else - { - AssertUnreachable; } } } diff --git a/src/Components/Modules/AssetInterfaces/IMaterialTechniqueSet.cpp b/src/Components/Modules/AssetInterfaces/IMaterialTechniqueSet.cpp index c0f5253f..a7519a12 100644 --- a/src/Components/Modules/AssetInterfaces/IMaterialTechniqueSet.cpp +++ b/src/Components/Modules/AssetInterfaces/IMaterialTechniqueSet.cpp @@ -11,8 +11,6 @@ namespace Assets { if (!header->data) this->loadFromDisk(header, name, builder); // Check if we need to import a new one into the game if (!header->data) this->loadNative(header, name, builder); // Check if there is a native one - - assert(header->data); } void IMaterialTechniqueSet::loadNative(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* /*builder*/) @@ -30,7 +28,6 @@ namespace Assets *tech = nullptr; Components::Logger::Warning(Game::CON_CHANNEL_DONT_FILTER, "Missing technique '{}'\n", name); - AssertUnreachable; return; } diff --git a/src/Components/Modules/AssetInterfaces/IPhysPreset.cpp b/src/Components/Modules/AssetInterfaces/IPhysPreset.cpp index 63803140..ad753a5c 100644 --- a/src/Components/Modules/AssetInterfaces/IPhysPreset.cpp +++ b/src/Components/Modules/AssetInterfaces/IPhysPreset.cpp @@ -1,6 +1,4 @@ #include -#include - #include "IPhysPreset.hpp" namespace Assets @@ -9,9 +7,9 @@ namespace Assets { AssertSize(Game::PhysPreset, 44); - auto* buffer = builder->getBuffer(); - auto* asset = header.physPreset; - auto* dest = buffer->dest(); + Utils::Stream* buffer = builder->getBuffer(); + Game::PhysPreset* asset = header.physPreset; + Game::PhysPreset* dest = buffer->dest(); buffer->save(asset); buffer->pushBlock(Game::XFILE_BLOCK_VIRTUAL); @@ -30,54 +28,4 @@ namespace Assets buffer->popBlock(); } - - void IPhysPreset::load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) - { - loadFromDisk(header, name, builder); - } - - void IPhysPreset::loadFromDisk(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) - { - Components::FileSystem::File physPresetFile(std::format("physpreset/{}.iw4x.json", name)); - auto* asset = builder->getAllocator()->allocate(); - - if (physPresetFile.exists()) - { - nlohmann::json physPresetJson; - try - { - physPresetJson = nlohmann::json::parse(physPresetFile.getBuffer()); - } - catch (const std::exception& e) - { - Components::Logger::PrintError(Game::CON_CHANNEL_ERROR, "Invalid JSON for physpreset {}! {}", name, e.what()); - return; - } - - try - { - asset->name = builder->getAllocator()->duplicateString(physPresetJson["name"].get()); - asset->type = physPresetJson["type"].get(); - asset->bounce = physPresetJson["bounce"].get(); - asset->mass = physPresetJson["mass"].get(); - asset->friction = physPresetJson["friction"].get(); - asset->bulletForceScale = physPresetJson["bulletForceScale"].get(); - asset->explosiveForceScale = physPresetJson["explosiveForceScale"].get(); - asset->sndAliasPrefix = builder->getAllocator()->duplicateString(physPresetJson["sndAliasPrefix"].get()); - asset->piecesSpreadFraction = physPresetJson["piecesSpreadFraction"].get(); - asset->piecesUpwardVelocity = physPresetJson["piecesUpwardVelocity"].get(); - asset->tempDefaultToCylinder = physPresetJson["tempDefaultToCylinder"].get(); - asset->perSurfaceSndAlias = physPresetJson["perSurfaceSndAlias"].get(); - - assert(asset->mass > std::numeric_limits::epsilon()); - } - catch (const std::exception& e) - { - Components::Logger::PrintError(Game::CON_CHANNEL_ERROR, "Malformed JSON for physpreset {}! {}", name, e.what()); - return; - } - } - - header->physPreset = asset; - } } diff --git a/src/Components/Modules/AssetInterfaces/IPhysPreset.hpp b/src/Components/Modules/AssetInterfaces/IPhysPreset.hpp index 47fb85e8..f3939a08 100644 --- a/src/Components/Modules/AssetInterfaces/IPhysPreset.hpp +++ b/src/Components/Modules/AssetInterfaces/IPhysPreset.hpp @@ -8,7 +8,5 @@ namespace Assets Game::XAssetType getType() override { return Game::XAssetType::ASSET_TYPE_PHYSPRESET; } void save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override; - void load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) override; - void loadFromDisk(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder); }; } diff --git a/src/Components/Modules/AssetInterfaces/ISndCurve.cpp b/src/Components/Modules/AssetInterfaces/ISndCurve.cpp index 3f418a16..1a7d0f01 100644 --- a/src/Components/Modules/AssetInterfaces/ISndCurve.cpp +++ b/src/Components/Modules/AssetInterfaces/ISndCurve.cpp @@ -1,6 +1,4 @@ #include -#include - #include "ISndCurve.hpp" namespace Assets @@ -9,9 +7,9 @@ namespace Assets { AssertSize(Game::SndCurve, 136); - auto* buffer = builder->getBuffer(); - auto* asset = header.sndCurve; - auto* dest = buffer->dest(); + Utils::Stream* buffer = builder->getBuffer(); + Game::SndCurve* asset = header.sndCurve; + Game::SndCurve* dest = buffer->dest(); buffer->save(asset); buffer->pushBlock(Game::XFILE_BLOCK_VIRTUAL); @@ -24,48 +22,4 @@ namespace Assets buffer->popBlock(); } - - void ISndCurve::load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) - { - Components::FileSystem::File sndCurveFile(std::format("sndcurve/{}.iw4x.json", name)); - - if (!sndCurveFile.exists()) - { - Components::Logger::PrintError(Game::CON_CHANNEL_ERROR, "Missing file for sndcurve {}!", name); - return; - } - - nlohmann::json sndCurveJson; - try - { - sndCurveJson = nlohmann::json::parse(sndCurveFile.getBuffer()); - } - catch (const std::exception& e) - { - Components::Logger::PrintError(Game::CON_CHANNEL_ERROR, "Invalid JSON for sndcurve {}! {}", name, e.what()); - return; - } - - auto* sndCurve = builder->getAllocator()->allocate(); - try - { - sndCurve->filename = builder->getAllocator()->duplicateString(sndCurveJson["filename"].get()); - sndCurve->knotCount = sndCurveJson["knotCount"].get(); - - for (auto side = 0; side < 2; side++) - { - for (auto knot = 0; knot < 16; knot++) - { - sndCurve->knots[knot][side] = sndCurveJson["knots"][knot][side].get(); - } - } - } - catch (const std::exception& e) - { - Components::Logger::PrintError(Game::CON_CHANNEL_ERROR, "Malformed JSON for sndcurve {}! {}", name, e.what()); - return; - } - - header->sndCurve = sndCurve; - } } diff --git a/src/Components/Modules/AssetInterfaces/ISndCurve.hpp b/src/Components/Modules/AssetInterfaces/ISndCurve.hpp index 0d2cc831..0b0d7564 100644 --- a/src/Components/Modules/AssetInterfaces/ISndCurve.hpp +++ b/src/Components/Modules/AssetInterfaces/ISndCurve.hpp @@ -8,6 +8,5 @@ namespace Assets Game::XAssetType getType() override { return Game::XAssetType::ASSET_TYPE_SOUND_CURVE; } void save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override; - void load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) override; }; } diff --git a/src/Components/Modules/AssetInterfaces/IXAnimParts.cpp b/src/Components/Modules/AssetInterfaces/IXAnimParts.cpp index 44104a43..0bd5e2ce 100644 --- a/src/Components/Modules/AssetInterfaces/IXAnimParts.cpp +++ b/src/Components/Modules/AssetInterfaces/IXAnimParts.cpp @@ -1,7 +1,7 @@ #include #include "IXAnimParts.hpp" -#define IW4X_ANIM_VERSION 2 +#define IW4X_ANIM_VERSION 1 namespace Assets { @@ -9,148 +9,100 @@ namespace Assets { Components::FileSystem::File animFile(std::format("xanim/{}.iw4xAnim", name)); - if (!animFile.exists()) + if (animFile.exists()) { - return; - } + Utils::Stream::Reader reader(builder->getAllocator(), animFile.getBuffer()); - Utils::Stream::Reader reader(builder->getAllocator(), animFile.getBuffer()); - - auto magic = reader.read(); - if (std::memcmp(&magic, "IW4xAnim", 8) != 0) - { - Components::Logger::Error(Game::ERR_FATAL, "Reading animation '{}' failed, header is invalid!", name); - } - - int version = reader.read(); - if (version > IW4X_ANIM_VERSION) - { - Components::Logger::Error(Game::ERR_FATAL, "Reading animation '{}' failed, expected version is {}, but it was {}!", name, IW4X_ANIM_VERSION, version); - } - - auto* xanim = reader.readArray(); - if (!xanim) - { - return; - } - - if (xanim->name) - { - xanim->name = reader.readCString(); - } - - if (xanim->names) - { - xanim->names = builder->getAllocator()->allocateArray(xanim->boneCount[Game::PART_TYPE_ALL]); - for (int i = 0; i < xanim->boneCount[Game::PART_TYPE_ALL]; ++i) + __int64 magic = reader.read<__int64>(); + if (std::memcmp(&magic, "IW4xAnim", 8)) { - xanim->names[i] = static_cast(Game::SL_GetString(reader.readCString(), 0)); + Components::Logger::Error(Game::ERR_FATAL, "Reading animation '{}' failed, header is invalid!", name); } - } - if (xanim->notify) - { - xanim->notify = reader.readArray(xanim->notifyCount); - - for (int i = 0; i < xanim->notifyCount; ++i) + int version = reader.read(); + if (version != IW4X_ANIM_VERSION) { - xanim->notify[i].name = static_cast(Game::SL_GetString(reader.readCString(), 0)); + Components::Logger::Error(Game::ERR_FATAL, "Reading animation '{}' failed, expected version is {}, but it was {}!", name, IW4X_ANIM_VERSION, version); } - } - if (xanim->dataByte) - { - xanim->dataByte = reader.readArray(xanim->dataByteCount); - } + Game::XAnimParts* xanim = reader.readArray(); - if (xanim->dataShort) - { - xanim->dataShort = reader.readArray(xanim->dataShortCount); - } - - if (xanim->dataInt) - { - xanim->dataInt = reader.readArray(xanim->dataIntCount); - } - - if (xanim->randomDataByte) - { - xanim->randomDataByte = reader.readArray(xanim->randomDataByteCount); - } - - if (xanim->randomDataShort) - { - xanim->randomDataShort = reader.readArray(xanim->randomDataShortCount); - } - - if (xanim->randomDataInt) - { - xanim->randomDataInt = reader.readArray(xanim->randomDataIntCount); - } - - if (xanim->indices.data) - { - if (xanim->numframes < 256) + if (xanim) { - xanim->indices._1 = reader.readArray(xanim->indexCount); - } - else - { - xanim->indices._2 = reader.readArray(xanim->indexCount); - } - } - - if (version > 1) - { - if (xanim->deltaPart) - { - xanim->deltaPart = reader.readObject(); - auto delta = xanim->deltaPart; - if (delta->trans) + if (xanim->name) { - delta->trans = reader.readObject(); - if (delta->trans->size) + xanim->name = reader.readCString(); + } + + if (xanim->names) + { + xanim->names = builder->getAllocator()->allocateArray(xanim->boneCount[Game::PART_TYPE_ALL]); + for (int i = 0; i < xanim->boneCount[Game::PART_TYPE_ALL]; ++i) { - delta->trans->u.frames = reader.read(); + xanim->names[i] = static_cast(Game::SL_GetString(reader.readCString(), 0)); + } + } - if (xanim->numframes > 0xFF) - { - auto indices2 = reader.readArray(delta->trans->size + 1); - std::memcpy(delta->trans->u.frames.indices._2, indices2, sizeof(short) * (delta->trans->size + 1)); - } - else - { - auto indices1 = reader.readArray(delta->trans->size + 1); - std::memcpy(delta->trans->u.frames.indices._1, indices1, delta->trans->size + 1); - } + if (xanim->notify) + { + xanim->notify = reader.readArray(xanim->notifyCount); - if (delta->trans->u.frames.frames._1) - { - if (delta->trans->smallTrans) - { - delta->trans->u.frames.frames._1 = reinterpret_cast(3, (delta->trans->size + 1)); - } - else - { - delta->trans->u.frames.frames._2 = reinterpret_cast(6, (delta->trans->size + 1)); - } - } + for (int i = 0; i < xanim->notifyCount; ++i) + { + xanim->notify[i].name = static_cast(Game::SL_GetString(reader.readCString(), 0)); + } + } + + if (xanim->dataByte) + { + xanim->dataByte = reader.readArray(xanim->dataByteCount); + } + + if (xanim->dataShort) + { + xanim->dataShort = reader.readArray(xanim->dataShortCount); + } + + if (xanim->dataInt) + { + xanim->dataInt = reader.readArray(xanim->dataIntCount); + } + + if (xanim->randomDataByte) + { + xanim->randomDataByte = reader.readArray(xanim->randomDataByteCount); + } + + if (xanim->randomDataShort) + { + xanim->randomDataShort = reader.readArray(xanim->randomDataShortCount); + } + + if (xanim->randomDataInt) + { + xanim->randomDataInt = reader.readArray(xanim->randomDataIntCount); + } + + if (xanim->indices.data) + { + if (xanim->numframes < 256) + { + xanim->indices._1 = reader.readArray(xanim->indexCount); } else { - auto frames = reader.readObject(); - std::memcpy(delta->trans->u.frame0, frames, sizeof(Game::vec3_t)); + xanim->indices._2 = reader.readArray(xanim->indexCount); } } + + if (!reader.end()) + { + Components::Logger::Error(Game::ERR_FATAL, "Reading animation '{}' failed, remaining raw data found!", name); + } + + header->parts = xanim; } } - - if (!reader.end()) - { - Components::Logger::Error(Game::ERR_FATAL, "Reading animation '{}' failed, remaining raw data found!", name); - } - - header->parts = xanim; } void IXAnimParts::mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) diff --git a/src/Components/Modules/AssetInterfaces/IXModel.cpp b/src/Components/Modules/AssetInterfaces/IXModel.cpp index 4cbe02c1..c8173537 100644 --- a/src/Components/Modules/AssetInterfaces/IXModel.cpp +++ b/src/Components/Modules/AssetInterfaces/IXModel.cpp @@ -1,7 +1,7 @@ #include #include "IXModel.hpp" -#define IW4X_MODEL_VERSION 9 +#define IW4X_MODEL_VERSION 8 namespace Assets { @@ -250,32 +250,34 @@ namespace Assets if (geom->brushWrapper) { - Game::BrushWrapper* brush = reader.readArrayOnce(); + Game::BrushWrapper* brush = reader.readObject(); geom->brushWrapper = brush; { if (brush->brush.sides) { - brush->brush.sides = reader.readArrayOnce(brush->brush.numsides); + brush->brush.sides = reader.readArray(brush->brush.numsides); for (unsigned short j = 0; j < brush->brush.numsides; ++j) { Game::cbrushside_t* side = &brush->brush.sides[j]; + // TODO: Add pointer support if (side->plane) { - side->plane = reader.readArrayOnce(); + side->plane = reader.readObject(); } } } if (brush->brush.baseAdjacentSide) { - brush->brush.baseAdjacentSide = reader.readArrayOnce(brush->totalEdgeCount); + brush->brush.baseAdjacentSide = reader.readArray(brush->totalEdgeCount); } } + // TODO: Add pointer support if (brush->planes) { - brush->planes = reader.readArrayOnce(brush->brush.numsides); + brush->planes = reader.readArray(brush->brush.numsides); } } } diff --git a/src/Components/Modules/AssetInterfaces/IclipMap_t.cpp b/src/Components/Modules/AssetInterfaces/IclipMap_t.cpp index 2a3c0814..f0524227 100644 --- a/src/Components/Modules/AssetInterfaces/IclipMap_t.cpp +++ b/src/Components/Modules/AssetInterfaces/IclipMap_t.cpp @@ -1,8 +1,7 @@ #include #include "IclipMap_t.hpp" -#include "Utils/Json.hpp" -#define IW4X_CLIPMAP_VERSION 3 +#define IW4X_CLIPMAP_VERSION 2 namespace Assets { @@ -38,7 +37,7 @@ namespace Assets buffer->align(Utils::Stream::ALIGN_4); // not sure if this is needed but both brushside and brushedge need it and it can't hurt - for (size_t i = 0; i < asset->planeCount; ++i) + for (int i = 0; i < asset->planeCount; ++i) { builder->storePointer(&asset->planes[i]); buffer->save(&asset->planes[i]); @@ -193,13 +192,7 @@ namespace Assets SaveLogEnter("cLeafBrush_t"); buffer->align(Utils::Stream::ALIGN_2); - - for (size_t i = 0; i < asset->numLeafBrushes; i++) - { - builder->storePointer(&asset->leafbrushes[i]); - buffer->saveObject(asset->leafbrushes[i]); - } - + buffer->saveArray(asset->leafbrushes, asset->numLeafBrushes); Utils::Stream::ClearPointer(&dest->leafbrushes); SaveLogExit(); @@ -220,9 +213,6 @@ namespace Assets { if (node[i].data.leaf.brushes) { - assert(node[i].data.leaf.brushes >= asset->leafbrushes); - assert(node[i].data.leaf.brushes < asset->leafbrushes + sizeof(unsigned short) * asset->numLeafBrushes); - if (builder->hasPointer(node[i].data.leaf.brushes)) { node[i].data.leaf.brushes = builder->getPointer(node[i].data.leaf.brushes); @@ -288,7 +278,7 @@ namespace Assets buffer->align(Utils::Stream::ALIGN_4); - for (size_t i = 0; i < asset->borderCount; ++i) + for (int i = 0; i < asset->borderCount; ++i) { builder->storePointer(&asset->borders[i]); buffer->save(&asset->borders[i]); @@ -578,13 +568,6 @@ namespace Assets } void IclipMap_t::load(Game::XAssetHeader* header, const std::string& _name, Components::ZoneBuilder::Zone* builder) - { - if (!header->data) loadFromJSON(header, _name, builder); - if (!header->data) loadBinary(header, _name, builder); - assert(header->data); - } - - void IclipMap_t::loadBinary(Game::XAssetHeader* header, const std::string& _name, Components::ZoneBuilder::Zone* builder) { std::string name = _name; Utils::String::Replace(name, "maps/mp/", ""); @@ -697,7 +680,7 @@ namespace Assets clipMap->brushsides = builder->getAllocator()->allocateArray(clipMap->numBrushSides); for (unsigned int i = 0; i < clipMap->numBrushSides; ++i) { - auto planeIndex = reader.read(); + int planeIndex = reader.read(); if (planeIndex < 0 || planeIndex >= clipMap->planeCount) { Components::Logger::Error(Game::ERR_FATAL, "invalid plane index"); @@ -705,17 +688,14 @@ namespace Assets } clipMap->brushsides[i].plane = &clipMap->planes[planeIndex]; clipMap->brushsides[i].materialNum = static_cast(reader.read()); // materialNum - - assert(clipMap->brushsides[i].materialNum < clipMap->numMaterials); - clipMap->brushsides[i].firstAdjacentSideOffset = static_cast(reader.read()); // firstAdjacentSide - clipMap->brushsides[i].edgeCount = reader.read(); // edgeCount + clipMap->brushsides[i].edgeCount = reader.read(); // edgeCount } } if (clipMap->numBrushEdges) { - clipMap->brushEdges = reader.readArray(clipMap->numBrushEdges); + clipMap->brushEdges = reader.readArray(clipMap->numBrushEdges); } if (clipMap->numNodes) @@ -723,7 +703,7 @@ namespace Assets clipMap->nodes = builder->getAllocator()->allocateArray(clipMap->numNodes); for (unsigned int i = 0; i < clipMap->numNodes; ++i) { - auto planeIndex = reader.read(); + int planeIndex = reader.read(); if (planeIndex < 0 || planeIndex >= clipMap->planeCount) { Components::Logger::Error(Game::ERR_FATAL, "invalid plane index\n"); @@ -749,7 +729,7 @@ namespace Assets if (clipMap->leafbrushNodes[i].leafBrushCount > 0) { - clipMap->leafbrushNodes[i].data.leaf.brushes = reader.readArrayOnce(clipMap->leafbrushNodes[i].leafBrushCount); + clipMap->leafbrushNodes[i].data.leaf.brushes = reader.readArray(clipMap->leafbrushNodes[i].leafBrushCount); } } } @@ -772,21 +752,7 @@ namespace Assets if (clipMap->triCount) { clipMap->triIndices = reader.readArray(clipMap->triCount * 3); - clipMap->triEdgeIsWalkable = reader.readArray(4 * ((3 * clipMap->triCount + 31) >> 5)); - - // check - for (size_t i = 0; i < clipMap->triCount; i++) - { - for (size_t x = 0; x < 3; x++) - { - auto vIndex = clipMap->triIndices[i * 3 + x]; - assert(clipMap->vertCount > vIndex); - assert(vIndex >= 0); - assert(vIndex != clipMap->triIndices[i * 3 + ((x + 1) % 3)]); - assert(vIndex != clipMap->triIndices[i * 3 + ((x + 2) % 3)]); - (void)vIndex; - } - } + clipMap->triEdgeIsWalkable = reader.readArray(4 * ((3 * clipMap->triCount + 31) >> 5)); } if (clipMap->borderCount) @@ -799,13 +765,13 @@ namespace Assets clipMap->partitions = builder->getAllocator()->allocateArray(clipMap->partitionCount); for (int i = 0; i < clipMap->partitionCount; ++i) { - clipMap->partitions[i].triCount = reader.read(); - clipMap->partitions[i].borderCount = reader.read(); + clipMap->partitions[i].triCount = reader.read(); + clipMap->partitions[i].borderCount = reader.read(); clipMap->partitions[i].firstTri = reader.read(); if (clipMap->partitions[i].borderCount > 0) { - auto index = reader.read(); + int index = reader.read(); if (index < 0 || index > clipMap->borderCount) { Components::Logger::Error(Game::ERR_FATAL, "invalid border index\n"); @@ -813,47 +779,17 @@ namespace Assets } clipMap->partitions[i].borders = &clipMap->borders[index]; } - - for (size_t j = 0; j < clipMap->partitions[i].triCount; j++) - { - assert(clipMap->partitions[i].firstTri + j >= 0); - assert(clipMap->partitions[i].firstTri + j < clipMap->triCount); - } } } if (clipMap->aabbTreeCount) { clipMap->aabbTrees = reader.readArray(clipMap->aabbTreeCount); - - // Check - for (size_t i = 0; i < clipMap->aabbTreeCount; i++) - { - assert(clipMap->aabbTrees->materialIndex >= 0); - assert(clipMap->aabbTrees->materialIndex < clipMap->numMaterials); - assert(clipMap->materials[clipMap->aabbTrees->materialIndex].contents); - } - } if (clipMap->numSubModels) { clipMap->cmodels = reader.readArray(clipMap->numSubModels); - - // Check - for (size_t i = 0; i < clipMap->numSubModels; i++) - { - auto cmodel = clipMap->cmodels[i]; - - for (size_t j = 0; j < cmodel.leaf.collAabbCount; j++) - { - auto index = cmodel.leaf.firstCollAabbIndex + j; - assert(index >= 0); - assert(index < clipMap->aabbTreeCount); - assert(cmodel.leaf.brushContents); - (void)index; - } - } } if (clipMap->numBrushes) @@ -863,12 +799,6 @@ namespace Assets for (int i = 0; i < clipMap->numBrushes; ++i) { clipMap->brushes[i].numsides = reader.read() & 0xFFFF; // todo: check for overflow here - - if (version >= 3) - { - clipMap->brushes[i].glassPieceIndex = reader.read(); - } - if (clipMap->brushes[i].numsides > 0) { auto index = reader.read(); @@ -885,37 +815,15 @@ namespace Assets } auto index = reader.read(); - - if (index == -1) + if (index > clipMap->numBrushEdges) { - clipMap->brushes[i].baseAdjacentSide = nullptr; // Happens + Components::Logger::Error(Game::ERR_FATAL, "invalid edge index\n"); + return; } - else - { - if (index > clipMap->numBrushEdges) - { - Components::Logger::Error(Game::ERR_FATAL, "invalid edge index\n"); - return; - } + clipMap->brushes[i].baseAdjacentSide = &clipMap->brushEdges[index]; - clipMap->brushes[i].baseAdjacentSide = &clipMap->brushEdges[index]; - assert(*clipMap->brushes[i].baseAdjacentSide >= 0); - assert(*clipMap->brushes[i].baseAdjacentSide < clipMap->numBrushSides); - } - - for (size_t x = 0; x < 2; x++) - { - for (size_t y = 0; y < 3; y++) - { - auto material = reader.read(); - - assert(material >= 0); - assert(material < clipMap->numMaterials); - assert(clipMap->materials[material].contents); - - clipMap->brushes[i].axialMaterialNum[x][y] = material; - } - } + char* tmp = reader.readArray(12); + memcpy(&clipMap->brushes[i].axialMaterialNum, tmp, 12); //todo check for overflow for (int r = 0; r < 2; ++r) @@ -926,24 +834,12 @@ namespace Assets } } - for (int r = 0; r < 2; ++r) - { - for (int c = 0; c < 3; ++c) - { - clipMap->brushes[i].edgeCount[r][c] = reader.read(); - } - } + tmp = reader.readArray(6); + memcpy(&clipMap->brushes[i].edgeCount, tmp, 6); } clipMap->brushBounds = reader.readArray(clipMap->numBrushes); clipMap->brushContents = reader.readArray(clipMap->numBrushes); - - for (size_t i = 0; i < clipMap->numBrushes; i++) - { - assert(clipMap->brushContents[i]); - } - - assert(clipMap->brushContents); } for (int x = 0; x < 2; ++x) @@ -954,15 +850,11 @@ namespace Assets for (int i = 0; i < clipMap->dynEntCount[x]; ++i) { clipMap->dynEntDefList[x][i].type = reader.read(); - assert(clipMap->dynEntDefList[x][i].type != Game::DynEntityType::DYNENT_TYPE_INVALID); - clipMap->dynEntDefList[x][i].pose = reader.read(); std::string tempName = reader.readString(); if (tempName != "NONE"s) { - auto xModel = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_XMODEL, tempName, builder).model; - clipMap->dynEntDefList[x][i].xModel = xModel; - assert(xModel); + clipMap->dynEntDefList[x][i].xModel = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_XMODEL, tempName, builder).model; } clipMap->dynEntDefList[x][i].brushModel = reader.read(); @@ -971,17 +863,13 @@ namespace Assets tempName = reader.readString(); if (tempName != "NONE"s) { - auto fx = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_FX, tempName, builder).fx; - clipMap->dynEntDefList[x][i].destroyFx = fx; - assert(fx); + clipMap->dynEntDefList[x][i].destroyFx = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_FX, tempName, builder).fx; } tempName = reader.readString(); if (tempName != "NONE"s) { - auto preset = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_PHYSPRESET, tempName, builder).physPreset; - clipMap->dynEntDefList[x][i].physPreset = preset; - assert(preset); + clipMap->dynEntDefList[x][i].physPreset = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_PHYSPRESET, tempName, builder).physPreset; } clipMap->dynEntDefList[x][i].health = reader.read(); @@ -997,53 +885,13 @@ namespace Assets clipMap->mapEnts = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_MAP_ENTS, std::format("maps/mp/{}.d3dbsp", name), builder).mapEnts; // add triggers to mapEnts - if (version >= 3) - { - auto trigger = &clipMap->mapEnts->trigger; - trigger->count = reader.read(); - trigger->models = builder->getAllocator()->allocateArray(trigger->count); - for (size_t i = 0; i < trigger->count; i++) - { - trigger->models[i] = reader.read(); - } - - trigger->hullCount = reader.read(); - trigger->hulls = builder->getAllocator()->allocateArray(trigger->hullCount); - for (size_t i = 0; i < trigger->hullCount; i++) - { - trigger->hulls[i] = reader.read(); - } - - trigger->slabCount = reader.read(); - trigger->slabs = builder->getAllocator()->allocateArray(trigger->slabCount); - for (size_t i = 0; i < trigger->slabCount; i++) - { - trigger->slabs[i] = reader.read(); - } - - // Check -#if DEBUG - for (size_t i = 0; i < trigger->count; i++) - { - assert(trigger->models[i].firstHull < trigger->hullCount); - } - - for (size_t i = 0; i < trigger->hullCount; i++) - { - assert(trigger->hulls[i].firstSlab < trigger->slabCount); - } -#endif - } - // This code is wrong but we keep it for backwards compatability with old versions of iw3xport - else if (version == 2) - { - if (clipMap->numSubModels > 0) - { + if (version >= 2) { + if (clipMap->numSubModels > 0) { clipMap->mapEnts->trigger.count = clipMap->numSubModels; clipMap->mapEnts->trigger.hullCount = clipMap->numSubModels; - auto* hulls = builder->getAllocator()->allocateArray(clipMap->mapEnts->trigger.hullCount); - auto* models = builder->getAllocator()->allocateArray(clipMap->mapEnts->trigger.count); + Game::TriggerHull* hulls = builder->getAllocator()->allocateArray(clipMap->mapEnts->trigger.hullCount); + Game::TriggerModel* models = builder->getAllocator()->allocateArray(clipMap->mapEnts->trigger.count); for (unsigned int i = 0; i < clipMap->numSubModels; ++i) { @@ -1051,14 +899,14 @@ namespace Assets hulls[i] = reader.read(); } - auto slabCount = reader.read(); + size_t slabCount = reader.read(); clipMap->mapEnts->trigger.slabCount = slabCount; - auto* slabs = builder->getAllocator()->allocateArray(clipMap->mapEnts->trigger.slabCount); - for (unsigned int i = 0; i < clipMap->mapEnts->trigger.slabCount; i++) - { + Game::TriggerSlab* slabs = builder->getAllocator()->allocateArray(clipMap->mapEnts->trigger.slabCount); + for (unsigned int i = 0; i < clipMap->mapEnts->trigger.slabCount; i++) { slabs[i] = reader.read(); } + clipMap->mapEnts->trigger.models = &models[0]; clipMap->mapEnts->trigger.hulls = &hulls[0]; clipMap->mapEnts->trigger.slabs = &slabs[0]; @@ -1093,1096 +941,4 @@ namespace Assets header->clipMap = clipMap; } - - - void IclipMap_t::loadFromJSON(Game::XAssetHeader* header, const std::string& _name, Components::ZoneBuilder::Zone* builder) - { - std::string name = _name; - Utils::String::Replace(name, "maps/mp/", ""); - Utils::String::Replace(name, ".d3dbsp", ""); - - Components::FileSystem::File clipMapFile(std::format("clipmap/{}.iw4x.json", name)); - - if (!clipMapFile.exists()) return; - - - nlohmann::json clipMapJson; - try - { - clipMapJson = nlohmann::json::parse(clipMapFile.getBuffer()); - } - catch (const std::exception& e) - { - Components::Logger::PrintError(Game::CON_CHANNEL_ERROR, "Invalid JSON for clipmap {}! {}", name, e.what()); - return; - } - - auto clipMap = builder->getAllocator()->allocate(); - - try - { - assert(clipMapJson["version"].get() <= IW4X_CLIPMAP_VERSION); - - clipMap->name = builder->getAllocator()->duplicateString(clipMapJson["name"].get()); - clipMap->isInUse = clipMapJson["isInUse"]; - - // planes - clipMap->planeCount = clipMapJson["planes"].size(); - clipMap->planes = clipMap->planeCount == 0 ? nullptr : builder->getAllocator()->allocateArray(clipMap->planeCount); - - for (size_t i = 0; i < clipMap->planeCount; i++) - { - auto plane = &clipMap->planes[i]; - Utils::Json::CopyArray(plane->normal, clipMapJson["planes"][i]["normal"], 3); - plane->dist = clipMapJson["planes"][i]["dist"]; - plane->type = clipMapJson["planes"][i]["type"].get(); - } - - // Smodel list - clipMap->numStaticModels = clipMapJson["staticModelList"].size(); - clipMap->staticModelList = clipMap->numStaticModels == 0 ? nullptr : builder->getAllocator()->allocateArray(clipMap->numStaticModels); - - for (size_t i = 0; i < clipMap->numStaticModels; i++) - { - auto model = &clipMap->staticModelList[i]; - auto jsonModel = clipMapJson["staticModelList"][i]; - - model->xmodel = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_XMODEL, jsonModel["xmodel"], builder).model; - - Utils::Json::CopyArray(model->origin, jsonModel["origin"], 3); - for (size_t j = 0; j < 3; j++) - { - Utils::Json::CopyArray(model->invScaledAxis[j], jsonModel["invScaledAxis"][j], 3); - } - - model->absBounds = Utils::Json::ReadBounds(jsonModel["absBounds"]); - } - - clipMap->numMaterials = clipMapJson["materials"].size(); - clipMap->materials = clipMap->numMaterials == 0 ? nullptr : builder->getAllocator()->allocateArray(clipMap->numMaterials); - - for (size_t i = 0; i < clipMap->numMaterials; i++) - { - auto material = &clipMap->materials[i]; - auto json_material = clipMapJson["materials"][i]; - - material->name = builder->getAllocator()->duplicateString(json_material["name"].get()); - material->surfaceFlags = json_material["surfaceFlags"]; - material->contents = json_material["contents"]; - } - - - clipMap->numBrushSides = clipMapJson["brushsides"].size(); - clipMap->brushsides = clipMap->numBrushSides == 0 ? nullptr : builder->getAllocator()->allocateArray(clipMap->numBrushSides); - - for (size_t i = 0; i < clipMap->numBrushSides; i++) - { - auto* brushside = &clipMap->brushsides[i]; - auto json_brushside = clipMapJson["brushsides"][i]; - - assert(clipMap->planes); - brushside->plane = &clipMap->planes[std::stoi(json_brushside["plane"].get().substr(1))]; - brushside->materialNum = json_brushside["materialNum"]; - brushside->firstAdjacentSideOffset = json_brushside["firstAdjacentSideOffset"].get(); - brushside->edgeCount = json_brushside["edgeCount"].get(); - } - - clipMap->numBrushEdges = clipMapJson["brushEdges"].size(); - clipMap->brushEdges = clipMap->numBrushEdges == 0 ? nullptr : builder->getAllocator()->allocateArray(clipMap->numBrushEdges); - Utils::Json::CopyArray(clipMap->brushEdges, clipMapJson["brushEdges"]); - - clipMap->numNodes = clipMapJson["nodes"].size(); - clipMap->nodes = clipMap->numNodes == 0 ? nullptr : builder->getAllocator()->allocateArray(clipMap->numNodes); - - for (size_t i = 0; i < clipMap->numNodes; i++) - { - auto node = &clipMap->nodes[i]; - auto jsonNode = clipMapJson["nodes"][i]; - - assert(clipMap->planes); - node->plane = &clipMap->planes[std::stoi(jsonNode["plane"].get().substr(1))]; - node->children[0] = jsonNode["children"][0]; - node->children[1] = jsonNode["children"][1]; - } - - - // LEaves - clipMap->numLeafs = clipMapJson["leafs"].size(); - clipMap->leafs = clipMap->numLeafs == 0 ? nullptr : builder->getAllocator()->allocateArray(clipMap->numLeafs); - - for (size_t i = 0; i < clipMap->numLeafs; i++) - { - auto leaf = &clipMap->leafs[i]; - auto jsonLeaf = clipMapJson["leafs"][i]; - - leaf->bounds = Utils::Json::ReadBounds(jsonLeaf["bounds"]); - leaf->firstCollAabbIndex = jsonLeaf["firstCollAabbIndex"]; - leaf->collAabbCount = jsonLeaf["collAabbCount"]; - leaf->brushContents = jsonLeaf["brushContents"]; - leaf->terrainContents = jsonLeaf["terrainContents"]; - leaf->leafBrushNode = jsonLeaf["leafBrushNode"]; - } - - // Leafbrushnodes - clipMap->leafbrushNodesCount = clipMapJson["leafbrushNodes"].size(); - clipMap->leafbrushNodes = clipMap->leafbrushNodesCount == 0 ? nullptr : builder->getAllocator()->allocateArray(clipMap->leafbrushNodesCount); - - // Leafbrushes - clipMap->numLeafBrushes = clipMapJson["leafbrushes"].size(); - clipMap->leafbrushes = clipMap->numLeafBrushes == 0 ? nullptr : builder->getAllocator()->allocateArray(clipMap->numLeafBrushes); - Utils::Json::CopyArray(clipMap->leafbrushes, clipMapJson["leafbrushes"]); - - clipMap->numLeafSurfaces = clipMapJson["leafsurfaces"].size(); - clipMap->leafsurfaces = clipMap->numLeafSurfaces == 0 ? nullptr : builder->getAllocator()->allocateArray(clipMap->numLeafSurfaces); - Utils::Json::CopyArray(clipMap->leafsurfaces, clipMapJson["leafsurfaces"]); - - clipMap->vertCount = clipMapJson["verts"].size(); - clipMap->verts = clipMap->vertCount == 0 ? nullptr : builder->getAllocator()->allocateArray(clipMap->vertCount); - for (size_t i = 0; i < clipMap->vertCount; i++) - { - Utils::Json::CopyArray(clipMap->verts[i], clipMapJson["verts"][i]); - } - - for (size_t i = 0; i < clipMap->leafbrushNodesCount; i++) - { - auto* lbn = &clipMap->leafbrushNodes[i]; - auto jsonLbn = clipMapJson["leafbrushNodes"][i]; - - lbn->axis = jsonLbn["axis"]; - lbn->leafBrushCount = jsonLbn["leafBrushCount"]; - lbn->contents = jsonLbn["contents"]; - - if (lbn->leafBrushCount > 0) - { - int index = std::stoi(jsonLbn["data"].get().substr(1)); - - assert(index < clipMap->numLeafBrushes); - assert(index >= 0); - - lbn->data.leaf.brushes = &clipMap->leafbrushes[index]; - assert(lbn->data.leaf.brushes); - } - else - { - lbn->data.children.dist = jsonLbn["data"]["dist"]; - lbn->data.children.range = jsonLbn["data"]["range"]; - Utils::Json::CopyArray(lbn->data.children.childOffset, jsonLbn["data"]["childOffset"]); - } - } - - // Tri indices - auto indiceCountJson = clipMapJson["triIndices"].size(); - clipMap->triCount = indiceCountJson; - clipMap->triIndices = clipMap->triCount == 0 ? nullptr : builder->getAllocator()->allocateArray(clipMap->triCount * 3); - - for (size_t i = 0; i < clipMap->triCount * 3; i +=3) - { - Utils::Json::CopyArray(&clipMap->triIndices[i], clipMapJson["triIndices"][i/3]); - } - - // Walkable - auto walkableCount = 4 * ((3 * clipMap->triCount + 31) >> 5) * 3; - assert(clipMapJson["triEdgeIsWalkable"].size() == walkableCount); - clipMap->triEdgeIsWalkable = walkableCount == 0 ? nullptr : builder->getAllocator()->allocateArray(walkableCount); - Utils::Json::CopyArray(clipMap->triEdgeIsWalkable, clipMapJson["triEdgeIsWalkable"]); - - // Borders - clipMap->borderCount = clipMapJson["borders"].size(); - clipMap->borders = clipMap->borderCount == 0 ? nullptr : builder->getAllocator()->allocateArray(clipMap->borderCount); - for (size_t i = 0; i < clipMap->borderCount; i++) - { - auto border = &clipMap->borders[i]; - auto json_border = clipMapJson["borders"][i]; - - Utils::Json::CopyArray(border->distEq, json_border["distEq"]); - border->zBase = json_border["zBase"]; - border->zSlope = json_border["zSlope"]; - border->start = json_border["start"]; - border->length = json_border["length"]; - } - - - // Collision partitions - clipMap->partitionCount = clipMapJson["partitions"].size(); - clipMap->partitions = clipMap->partitionCount == 0 ? nullptr : builder->getAllocator()->allocateArray(clipMap->partitionCount); - for (auto i = 0; i < clipMap->partitionCount; i++) - { - auto partition = &clipMap->partitions[i]; - auto json_partition = clipMapJson["partitions"][i]; - - partition->triCount = json_partition["triCount"]; - partition->firstVertSegment = json_partition["firstVertSegment"]; - partition->firstTri = json_partition["firstTri"]; - partition->borderCount = json_partition["borderCount"]; - - if (partition->borderCount > 0) - { - // They're always consecutive (I checked) - auto index = std::stoi(json_partition["firstBorder"].get().substr(1)); - assert(clipMap->borders); - partition->borders = &clipMap->borders[index]; - } - } - - // Tree - clipMap->aabbTreeCount = clipMapJson["aabbTrees"].size(); - clipMap->aabbTrees = clipMap->aabbTreeCount == 0 ? nullptr : builder->getAllocator()->allocateArray(clipMap->aabbTreeCount); - for (size_t i = 0; i < clipMap->aabbTreeCount; i++) - { - auto tree = &clipMap->aabbTrees[i]; - auto json_tree = clipMapJson["aabbTrees"][i]; - - Utils::Json::CopyArray(tree->midPoint, json_tree["midPoint"]); - Utils::Json::CopyArray(tree->halfSize, json_tree["halfSize"]); - tree->materialIndex = json_tree["materialIndex"]; - tree->childCount = json_tree["childCount"]; - tree->u.firstChildIndex = json_tree["u"]; - } - - // CModels - clipMap->numSubModels = clipMapJson["cmodels"].size(); - clipMap->cmodels = clipMap->numSubModels == 0 ? nullptr : builder->getAllocator()->allocateArray(clipMap->numSubModels); - for (size_t i = 0; i < clipMap->numSubModels; i++) - { - auto cmodel = &clipMap->cmodels[i]; - auto json_cmodel = clipMapJson["cmodels"][i]; - - cmodel->bounds = Utils::Json::ReadBounds(json_cmodel["bounds"]); - cmodel->radius = json_cmodel["radius"]; - - auto leaf = &cmodel->leaf; - auto json_leaf = json_cmodel["leaf"]; - - leaf->firstCollAabbIndex = json_leaf["firstCollAabbIndex"]; - leaf->collAabbCount = json_leaf["collAabbCount"]; - leaf->brushContents = json_leaf["brushContents"]; - leaf->terrainContents = json_leaf["terrainContents"]; - leaf->leafBrushNode = json_leaf["leafBrushNode"]; - leaf->bounds = Utils::Json::ReadBounds(json_leaf["bounds"]); - printf(""); - } - - // Brushes - clipMap->numBrushes = static_cast(clipMapJson["brushes"].size()); - clipMap->brushes = clipMap->numBrushes == 0 ? nullptr : builder->getAllocator()->allocateArray < Game::cbrush_t >(clipMap->numBrushes); - for (size_t i = 0; i < clipMap->numBrushes; i++) - { - auto brush = &clipMap->brushes[i]; - auto json_brush = clipMapJson["brushes"][i]; - - brush->glassPieceIndex = json_brush["glassPieceIndex"]; - brush->numsides = json_brush["numsides"]; - - if (brush->numsides) - { - // Always consecutive - auto index = std::stoi(json_brush["firstSide"].get().substr(1)); - assert(clipMap->brushsides); - brush->sides = &clipMap->brushsides[index]; - } - - if (json_brush["baseAdjacentSide"].is_string()) // Not null that means - { - auto index = std::stoi(json_brush["baseAdjacentSide"].get().substr(1)); - assert(clipMap->brushEdges); - brush->baseAdjacentSide = &clipMap->brushEdges[index]; - } - - for (size_t x = 0; x < 2; x++) - { - Utils::Json::CopyArray(brush->axialMaterialNum[x], json_brush["axialMaterialNum"][x]); - Utils::Json::CopyArray(brush->firstAdjacentSideOffsets[x], json_brush["firstAdjacentSideOffsets"][x]); - Utils::Json::CopyArray(brush->edgeCount[x], json_brush["edgeCount"][x]); - } - } - - assert(clipMapJson["brushes"].size() == clipMapJson["brushBounds"].size()); - clipMap->brushBounds = builder->getAllocator()->allocateArray(clipMap->numBrushes); - for (size_t i = 0; i < clipMap->numBrushes; i++) - { - clipMap->brushBounds[i] = Utils::Json::ReadBounds(clipMapJson["brushBounds"][i]); - } - - assert(clipMapJson["brushes"].size() == clipMapJson["brushContents"].size()); - clipMap->brushContents = builder->getAllocator()->allocateArray(clipMap->numBrushes); - Utils::Json::CopyArray(clipMap->brushContents, clipMapJson["brushContents"]); - - auto json_ents= clipMapJson["mapEnts"]; - if (!json_ents.is_null()) - { - auto ents_name = json_ents["name"]; - clipMap->mapEnts = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_MAP_ENTS, ents_name, builder).mapEnts; - - auto json_trigger = json_ents["trigger"]; - auto trigger = &clipMap->mapEnts->trigger; - trigger->count = json_trigger["models"].size(); - trigger->models = builder->getAllocator()->allocateArray(trigger->count); - - for (size_t i = 0; i < trigger->count; i++) - { - trigger->models[i].contents = json_trigger["models"][i]["contents"]; - trigger->models[i].hullCount = json_trigger["models"][i]["hullCount"]; - trigger->models[i].firstHull = json_trigger["models"][i]["firstHull"]; - } - - trigger->hullCount = json_trigger["hulls"].size(); - trigger->hulls = builder->getAllocator()->allocateArray(trigger->hullCount); - for (size_t i = 0; i < trigger->hullCount; i++) - { - trigger->hulls[i].bounds = Utils::Json::ReadBounds(json_trigger["hulls"][i]["bounds"]); - - trigger->hulls[i].contents = json_trigger["hulls"][i]["contents"]; - trigger->hulls[i].firstSlab = json_trigger["hulls"][i]["firstSlab"]; - trigger->hulls[i].slabCount = json_trigger["hulls"][i]["slabCount"]; - } - - trigger->slabCount = json_trigger["slabs"].size(); - trigger->slabs = builder->getAllocator()->allocateArray(trigger->slabCount); - for (size_t i = 0; i < trigger->slabCount; i++) - { - Utils::Json::CopyArray(trigger->slabs[i].dir, json_trigger["slabs"][i]["dir"]); - trigger->slabs[i].midPoint = json_trigger["slabs"][i]["midPoint"]; - trigger->slabs[i].halfSize = json_trigger["slabs"][i]["halfSize"]; - } - - // Stages - clipMap->mapEnts->stageCount = static_cast(json_ents["stages"].size()); - clipMap->mapEnts->stages = builder->getAllocator()->allocateArray (clipMap->mapEnts->stageCount); - for (auto i = 0; i < clipMap->mapEnts->stageCount; i++) - { - auto stage = &clipMap->mapEnts->stages[i]; - auto json_stage = json_ents["stages"][i]; - - stage->name = builder->getAllocator()->duplicateString(json_stage["name"]); - Utils::Json::CopyArray(stage->origin, json_stage["origin"]); - stage->triggerIndex = json_stage["triggerIndex"]; - stage->sunPrimaryLightIndex = json_stage["sunPrimaryLightIndex"].get(); - } - } - - // SmodelNodes - clipMap->smodelNodeCount = static_cast(clipMapJson["smodelNodes"].size()); - clipMap->smodelNodes = clipMap->smodelNodeCount == 0 ? nullptr : builder->getAllocator()->allocateArray(clipMap->smodelNodeCount); - for (size_t i = 0; i < clipMap->smodelNodeCount; i++) - { - auto json_node = clipMapJson["smodelNodes"][i]; - auto node = &clipMap->smodelNodes[i]; - - node->bounds = Utils::Json::ReadBounds(json_node["bounds"]); - node->firstChild = json_node["firstChild"]; - node->childCount = json_node["childCount"]; - } - - for (size_t i = 0; i < 2; i++) - { - clipMap->dynEntCount[i] = static_cast(clipMapJson["dynEntities"][i].size()); - - auto json_entities = clipMapJson["dynEntities"][i]; - clipMap->dynEntClientList[i] = clipMap->dynEntCount[i] == 0 ? nullptr : builder->getAllocator()->allocateArray(clipMap->dynEntCount[i]); - clipMap->dynEntCollList[i] = clipMap->dynEntCount[i] == 0 ? nullptr : builder->getAllocator()->allocateArray(clipMap->dynEntCount[i]); - clipMap->dynEntPoseList[i] = clipMap->dynEntCount[i] == 0 ? nullptr : builder->getAllocator()->allocateArray(clipMap->dynEntCount[i]); - clipMap->dynEntDefList[i] = clipMap->dynEntCount[i] == 0 ? nullptr : builder->getAllocator()->allocateArray(clipMap->dynEntCount[i]); - - for (size_t j = 0; j < clipMap->dynEntCount[i]; j++) - { - auto json_entity = json_entities[j]["dynEntityDef"]; - auto entity = &clipMap->dynEntDefList[i][j]; - - entity->type = json_entity["type"]; - Utils::Json::CopyArray(entity->pose.quat, json_entity["pose"]["quat"]); - Utils::Json::CopyArray(entity->pose.origin, json_entity["pose"]["origin"]); - - entity->xModel = json_entity["xModel"].is_string() ? Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_XMODEL, json_entity["xModel"], builder).model : nullptr; - entity->brushModel = json_entity["brushModel"]; - entity->physicsBrushModel = json_entity["physicsBrushModel"]; - entity->destroyFx = json_entity["destroyFx"].is_string() ? Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_FX, json_entity["destroyFx"], builder).fx : nullptr; - entity->physPreset = json_entity["physPreset"].is_string() ? Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_PHYSPRESET, json_entity["physPreset"], builder).physPreset : nullptr; - entity->health = json_entity["health"]; - - Utils::Json::CopyArray(entity->mass.centerOfMass, json_entity["mass"]["centerOfMass"]); - Utils::Json::CopyArray(entity->mass.momentsOfInertia, json_entity["mass"]["momentsOfInertia"]); - Utils::Json::CopyArray(entity->mass.productsOfInertia, json_entity["mass"]["productsOfInertia"]); - - entity->contents = json_entity["contents"]; - } - } - - clipMap->checksum = clipMapJson["checksum"]; - } - catch (const std::exception& e) - { - Components::Logger::PrintError(Game::CON_CHANNEL_ERROR, "Malformed JSON for clipmap {}! {}", name, e.what()); - return; - } - - header->clipMap = clipMap; - } - - void IclipMap_t::dump(Game::XAssetHeader header) - { - assert(header.clipMap); - - static_assert(sizeof Game::clipMap_t == 256); - static_assert(sizeof Game::ClipMaterial == 12); - static_assert(sizeof Game::cbrushside_t == 8); - static_assert(sizeof Game::cNode_t == 8); - static_assert(sizeof Game::cLeaf_t == 40); - static_assert(sizeof Game::cLeafBrushNode_s == 20); - static_assert(sizeof Game::CollisionBorder == 28); - static_assert(sizeof Game::CollisionPartition == 12); - static_assert(sizeof Game::CollisionAabbTree == 32); - static_assert(sizeof Game::cmodel_t == 68); - static_assert(sizeof Game::SModelAabbNode == 28); - - - const auto clipMap = header.clipMap; - - if (!clipMap) return; - - std::unordered_map planes; - std::unordered_map brush_sides; - std::unordered_map brush_edges; - std::unordered_map leaf_brushes; - std::unordered_map borders; - - Utils::Memory::Allocator strDuplicator; - nlohmann::json output; - - auto float_array_to_json = [](const float* array, int size) - { - auto arr = nlohmann::json::array(); - for (auto i = 0; i < size; ++i) - { - arr.push_back(array[i]); - } - - return arr; - }; - - auto ushort_to_array = [](const unsigned short* array, int size) - { - auto arr = nlohmann::json::array(); - for (auto i = 0; i < size; ++i) - { - arr.push_back(array[i]); - } - - return arr; - }; - - auto uchar_to_array = [](const unsigned char* array, int size) - { - auto arr = nlohmann::json::array(); - for (auto i = 0; i < size; ++i) - { - arr.push_back(array[i]); - } - - return arr; - }; - - auto bounds_to_json = [&float_array_to_json](const Game::Bounds& bounds) - { - auto bounds_json= nlohmann::json::object(); - - bounds_json.emplace("midPoint", float_array_to_json(bounds.midPoint, 3)); - bounds_json.emplace("halfSize", float_array_to_json(bounds.halfSize, 3)); - - return bounds_json; - }; - - auto placement_to_json = [&float_array_to_json](const Game::GfxPlacement& placement) - { - auto placement_json= nlohmann::json::object(); - - placement_json.emplace("quat", float_array_to_json(placement.quat, 4)); - placement_json.emplace("origin", float_array_to_json(placement.origin, 3)); - - return placement_json; - }; - - auto leaf_to_json = [&bounds_to_json](const Game::cLeaf_t& leaf) - { - auto json_leave= nlohmann::json::object(); - - json_leave.emplace("firstCollAabbIndex", leaf.firstCollAabbIndex); - json_leave.emplace("collAabbCount", leaf.collAabbCount); - json_leave.emplace("brushContents", leaf.brushContents); - json_leave.emplace("terrainContents", leaf.terrainContents); - json_leave.emplace("leafBrushNode", leaf.leafBrushNode); - json_leave.emplace("bounds", bounds_to_json(leaf.bounds)); - - return json_leave; - }; - - output.emplace("version", IW4X_CLIPMAP_VERSION); - output.emplace("name", (clipMap->name)); - output.emplace("isInUse", clipMap->isInUse); - - // Planes - auto json_planes = nlohmann::json::array(); - for (size_t i = 0; i < clipMap->planeCount; i++) - { - auto json_plane= nlohmann::json::object(); - auto plane = &clipMap->planes[i]; - - json_plane.emplace( - "normal", - float_array_to_json(plane->normal, 3) - ); - - json_plane.emplace("dist", plane->dist); - json_plane.emplace("type", plane->type); - - json_planes.push_back(json_plane); - - planes[plane] = i; - } - - output.emplace("planes", json_planes); - - // Static models - auto json_static_models = nlohmann::json::array(); - for (size_t i = 0; i < clipMap->numStaticModels; i++) - { - auto json_static_model= nlohmann::json::object(); - auto static_model = &clipMap->staticModelList[i]; - - json_static_model.emplace( - "xmodel", (static_model->xmodel->name) - ); - - json_static_model.emplace( - "origin", - float_array_to_json(static_model->origin, 3) - ); - - auto inv_scaled_axis = nlohmann::json::array(); - for (size_t j = 0; j < ARRAYSIZE(static_model->invScaledAxis); j++) - { - inv_scaled_axis.push_back( - float_array_to_json(static_model->invScaledAxis[j], 3) - ); - } - - json_static_model.emplace("invScaledAxis", inv_scaled_axis); - - json_static_model.emplace( - "absBounds", - bounds_to_json(static_model->absBounds) - ); - - json_static_models.push_back(json_static_model); - } - - output.emplace("staticModelList", json_static_models); - - // Materials - auto json_materials = nlohmann::json::array(); - for (size_t i = 0; i < clipMap->numMaterials; i++) - { - auto json_material= nlohmann::json::object(); - auto material = &clipMap->materials[i]; - - json_material.emplace( - "name", - (material->name) - ); - - json_material.emplace("surfaceFlags", material->surfaceFlags); - json_material.emplace("contents", material->contents); - - json_materials.push_back(json_material); - } - - output.emplace("materials", json_materials); - - // Brushsides - auto json_brush_sides = nlohmann::json::array(); - for (size_t i = 0; i < clipMap->numBrushSides; i++) - { - auto json_brush_side= nlohmann::json::object(); - auto brush_side = &clipMap->brushsides[i]; - - auto index = planes[brush_side->plane]; - auto plane_index = std::format("#{}", index); - json_brush_side.emplace( - "plane", - (strDuplicator.duplicateString(plane_index)) - ); - - json_brush_side.emplace("materialNum", brush_side->materialNum); - json_brush_side.emplace("firstAdjacentSideOffset", brush_side->firstAdjacentSideOffset); - json_brush_side.emplace("edgeCount", brush_side->edgeCount); - - json_brush_sides.push_back(json_brush_side); - - brush_sides[brush_side] = i; - } - - output.emplace("brushsides", json_brush_sides); - - // Brush edges - auto json_brush_edges = nlohmann::json::array(); - for (size_t i = 0; i < clipMap->numBrushEdges; i++) - { - json_brush_edges.push_back(clipMap->brushEdges[i]); - brush_edges[&clipMap->brushEdges[i]] = i; - } - - output.emplace("brushEdges", json_brush_edges); - - // Brush nodes - auto json_nodes = nlohmann::json::array(); - for (size_t i = 0; i < clipMap->numNodes; i++) - { - auto node = &clipMap->nodes[i]; - - auto json_node= nlohmann::json::object(); - - auto index = planes[node->plane]; - auto plane_index = std::format("#{}", index); - json_node.emplace("plane", (strDuplicator.duplicateString(plane_index))); - - auto children = nlohmann::json::array(); - for (size_t j = 0; j < ARRAYSIZE(node->children); j++) - { - children.push_back(node->children[j]); - } - - json_node.emplace("children", children); - - json_nodes.push_back(json_node); - } - - output.emplace("nodes", json_nodes); - - // Leaves - auto json_leaves = nlohmann::json::array(); - for (size_t i = 0; i < clipMap->numLeafs; i++) - { - auto leaf = &clipMap->leafs[i]; - - json_leaves.push_back(leaf_to_json(*leaf)); - } - - output.emplace("leafs", json_leaves); - - // Brush leafs - auto json_brush_leafs = nlohmann::json::array(); - for (size_t i = 0; i < clipMap->numLeafBrushes; i++) - { - json_brush_leafs.push_back(clipMap->leafbrushes[i]); - leaf_brushes[&clipMap->leafbrushes[i]] = i; - } - - output.emplace("leafbrushes", json_brush_leafs); - - - // LeafBrushNodes - auto json_leaf_brush_nodes = nlohmann::json::array(); - for (size_t i = 0; i < clipMap->leafbrushNodesCount; i++) - { - auto json_leaf_brush_node= nlohmann::json::object(); - auto leaf_brush_node = &clipMap->leafbrushNodes[i]; - - json_leaf_brush_node.emplace("axis", leaf_brush_node->axis); - json_leaf_brush_node.emplace("leafBrushCount", leaf_brush_node->leafBrushCount); - json_leaf_brush_node.emplace("contents", leaf_brush_node->contents); - - if (leaf_brush_node->leafBrushCount > 0) - { - assert(leaf_brushes.contains(leaf_brush_node->data.leaf.brushes)); - auto index_str = std::format("#{}", leaf_brushes[leaf_brush_node->data.leaf.brushes]); - json_leaf_brush_node.emplace("data", strDuplicator.duplicateString(index_str)); - } - else - { - auto data= nlohmann::json::object(); - - data.emplace("dist", leaf_brush_node->data.children.dist); - data.emplace("range", leaf_brush_node->data.children.range); - - auto child_offset = nlohmann::json::array(); - for (size_t x = 0; x < 2; x++) - { - child_offset.push_back(leaf_brush_node->data.children.childOffset[x]); - } - - data.emplace("childOffset", child_offset); - - json_leaf_brush_node.emplace("data", data); - } - - json_leaf_brush_nodes.push_back(json_leaf_brush_node); - } - - output.emplace("leafbrushNodes", json_leaf_brush_nodes); - - - // leafsurfaces (unused) - auto json_leaf_surfaces = nlohmann::json::array(); - for (size_t i = 0; i < clipMap->numLeafSurfaces; i++) - { - json_leaf_surfaces.push_back(clipMap->leafsurfaces[i]); - } - - output.emplace("leafsurfaces", json_leaf_surfaces); - - // vertices - auto json_vertices = nlohmann::json::array(); - for (size_t i = 0; i < clipMap->vertCount; i++) - { - json_vertices.push_back(float_array_to_json(clipMap->verts[i], 3)); - } - - output.emplace("verts", json_vertices); - - // tris - auto json_tris = nlohmann::json::array(); - for (size_t i = 0; i < clipMap->triCount * 3; i += 3) - { - json_tris.push_back(ushort_to_array(&clipMap->triIndices[i], 3)); - } - - output.emplace("triIndices", json_tris); - - auto json_tris_walkable = nlohmann::json::array(); - auto walkable_count = 4 * ((3 * clipMap->triCount + 31) >> 5); - for (size_t i = 0; i < walkable_count * 3; i++) - { - json_tris_walkable.push_back(static_cast(clipMap->triEdgeIsWalkable[i])); - } - - output.emplace("triEdgeIsWalkable", json_tris_walkable); - - // Collision borders - auto json_collision_borders = nlohmann::json::array(); - for (size_t i = 0; i < clipMap->borderCount; i++) - { - auto collision_border = &clipMap->borders[i]; - - auto json_collision_border= nlohmann::json::object(); - - json_collision_border.emplace("distEq", float_array_to_json(collision_border->distEq, 3)); - json_collision_border.emplace("zBase", collision_border->zBase); - json_collision_border.emplace("zSlope", collision_border->zSlope); - json_collision_border.emplace("start", collision_border->start); - json_collision_border.emplace("length", collision_border->length); - - json_collision_borders.push_back(json_collision_border); - - borders[collision_border] = i; - } - - output.emplace("borders", json_collision_borders); - - // Collision partitions - auto json_collision_partitions = nlohmann::json::array(); - for (auto i = 0; i < clipMap->partitionCount; i++) - { - auto collision_partition = &clipMap->partitions[i]; - - auto json_collision_partition= nlohmann::json::object(); - - json_collision_partition.emplace("triCount", collision_partition->triCount); - json_collision_partition.emplace("firstVertSegment", collision_partition->firstVertSegment); - json_collision_partition.emplace("firstTri", collision_partition->firstTri); - json_collision_partition.emplace("borderCount", collision_partition->borderCount); - - if (collision_partition->borderCount) - { - auto index_str = strDuplicator.duplicateString(std::format("#{}", borders[&collision_partition->borders[0]])); - json_collision_partition.emplace("firstBorder", (index_str)); - } - - json_collision_partitions.push_back(json_collision_partition); - } - - output.emplace("partitions", json_collision_partitions); - - // Trees - auto json_aabbtrees = nlohmann::json::array(); - for (size_t i = 0; i < clipMap->aabbTreeCount; i++) - { - auto aabbtree = &clipMap->aabbTrees[i]; - - auto json_aabbtree= nlohmann::json::object(); - - json_aabbtree.emplace("midPoint", float_array_to_json(aabbtree->midPoint, 3)); - json_aabbtree.emplace("halfSize", float_array_to_json(aabbtree->halfSize, 3)); - json_aabbtree.emplace("materialIndex", aabbtree->materialIndex); - json_aabbtree.emplace("childCount", aabbtree->childCount); - json_aabbtree.emplace("u", aabbtree->u.firstChildIndex); - - json_aabbtrees.push_back(json_aabbtree); - } - - output.emplace("aabbTrees", json_aabbtrees); - - // Cmodels - auto json_cmodels = nlohmann::json::array(); - for (size_t i = 0; i < clipMap->numSubModels; i++) - { - auto cmodel = &clipMap->cmodels[i]; - - auto json_cmodel= nlohmann::json::object(); - - json_cmodel.emplace("bounds", bounds_to_json(cmodel->bounds)); - json_cmodel.emplace("radius", cmodel->radius); - json_cmodel.emplace("leaf", leaf_to_json(cmodel->leaf)); - - json_cmodels.push_back(json_cmodel); - } - - output.emplace("cmodels", json_cmodels); - - // Brushes - auto json_brushes = nlohmann::json::array(); - for (size_t i = 0; i < clipMap->numBrushes; i++) - { - auto brush = &clipMap->brushes[i]; - - auto json_brush= nlohmann::json::object(); - - json_brush.emplace("glassPieceIndex", brush->glassPieceIndex); - json_brush.emplace("numsides", brush->numsides); - - // Sides - if (brush->numsides > 0) - { - auto index_str = strDuplicator.duplicateString(std::format("#{}", brush_sides[brush->sides])); - json_brush.emplace("firstSide", (index_str)); - } - - if (brush->baseAdjacentSide) - { - auto index_str = strDuplicator.duplicateString(std::format("#{}", brush_edges[brush->baseAdjacentSide])); - json_brush.emplace("baseAdjacentSide", (index_str)); - } - else - { - json_brush.emplace("baseAdjacentSide", nlohmann::json()); - } - - auto axial_material_num = nlohmann::json::array(); - for (size_t x = 0; x < 2; x++) - { - axial_material_num.push_back(ushort_to_array(brush->axialMaterialNum[x], 3)); - } - json_brush.emplace("axialMaterialNum", axial_material_num); - - auto first_adjacent_side_offsets = nlohmann::json::array(); - for (size_t x = 0; x < 2; x++) - { - first_adjacent_side_offsets.push_back(uchar_to_array(brush->firstAdjacentSideOffsets[x], 3)); - } - json_brush.emplace("firstAdjacentSideOffsets", first_adjacent_side_offsets); - - auto edge_count = nlohmann::json::array(); - for (size_t x = 0; x < 2; x++) - { - edge_count.push_back(uchar_to_array(brush->edgeCount[x], 3)); - } - json_brush.emplace("edgeCount", edge_count); - - json_brushes.push_back(json_brush); - } - - output.emplace("brushes", json_brushes); - - // Brushbounds - auto json_brush_bounds = nlohmann::json::array(); - for (size_t i = 0; i < clipMap->numBrushes; i++) - { - json_brush_bounds.push_back(bounds_to_json(clipMap->brushBounds[i])); - } - - output.emplace("brushBounds", json_brush_bounds); - - // Brush contents - auto json_brush_contents = nlohmann::json::array(); - for (size_t i = 0; i < clipMap->numBrushes; i++) - { - json_brush_contents.push_back(clipMap->brushContents[i]); - } - - output.emplace("brushContents", json_brush_contents); - - // ENTITIES - if (clipMap->mapEnts) - { - static_assert(sizeof Game::TriggerSlab == 20); - static_assert(sizeof Game::TriggerModel == 8); - static_assert(sizeof Game::TriggerHull == 32); - - auto json_map_ents= nlohmann::json::object(); - const auto ents = clipMap->mapEnts; - - json_map_ents.emplace("name", (ents->name)); - - auto json_trigger= nlohmann::json::object(); - - auto json_trigger_models = nlohmann::json::array(); - for (size_t i = 0; i < ents->trigger.count; i++) - { - auto json_trigger_model= nlohmann::json::object(); - json_trigger_model.emplace("contents", ents->trigger.models[i].contents); - json_trigger_model.emplace("hullCount", ents->trigger.models[i].hullCount); - json_trigger_model.emplace("firstHull", ents->trigger.models[i].firstHull); - - json_trigger_models.push_back(json_trigger_model); - } - - json_trigger.emplace("models", json_trigger_models); - - auto json_trigger_hulls = nlohmann::json::array(); - for (size_t i = 0; i < ents->trigger.hullCount; i++) - { - auto json_trigger_hull= nlohmann::json::object(); - json_trigger_hull.emplace("bounds", bounds_to_json(ents->trigger.hulls[i].bounds)); - json_trigger_hull.emplace("contents", ents->trigger.hulls[i].contents); - json_trigger_hull.emplace("slabCount", ents->trigger.hulls[i].slabCount); - json_trigger_hull.emplace("firstSlab", ents->trigger.hulls[i].firstSlab); - - json_trigger_hulls.push_back(json_trigger_hull); - } - - json_trigger.emplace("hulls", json_trigger_hulls); - - auto json_trigger_slabs = nlohmann::json::array(); - for (size_t i = 0; i < ents->trigger.slabCount; i++) - { - auto json_trigger_slab= nlohmann::json::object(); - json_trigger_slab.emplace("dir", float_array_to_json(ents->trigger.slabs[i].dir, 3)); - json_trigger_slab.emplace("midPoint", ents->trigger.slabs[i].midPoint); - json_trigger_slab.emplace("halfSize", ents->trigger.slabs[i].halfSize); - - json_trigger_slabs.push_back(json_trigger_slab); - } - - json_trigger.emplace("slabs", json_trigger_slabs); - json_map_ents.emplace("trigger", json_trigger); - - auto json_stages = nlohmann::json::array(); - for (auto i = 0; i < ents->stageCount; i++) - { - auto stage = &ents->stages[i]; - auto json_stage= nlohmann::json::object(); - json_stage.emplace("name", (stage->name)); - json_stage.emplace("origin", float_array_to_json(stage->origin, 3)); - json_stage.emplace("triggerIndex", stage->triggerIndex); - json_stage.emplace("sunPrimaryLightIndex", stage->sunPrimaryLightIndex); - - json_stages.push_back(json_stage); - } - - json_map_ents.emplace("stages", json_stages); - - output.emplace("mapEnts", json_map_ents); - } - else - { - output.emplace("mapEnts", nlohmann::json()); - } - - //Smodel nodes - auto json_smodelnodes = nlohmann::json::array(); - for (size_t i = 0; i < clipMap->smodelNodeCount; i++) - { - auto smodelNode = &clipMap->smodelNodes[i]; - - auto json_smodelnode = nlohmann::json::object(); - - json_smodelnode.emplace("bounds", bounds_to_json(smodelNode->bounds)); - json_smodelnode.emplace("firstChild", smodelNode->firstChild); - json_smodelnode.emplace("childCount", smodelNode->childCount); - - json_smodelnodes.push_back(json_smodelnode); - } - - output.emplace("smodelNodes", json_smodelnodes); - - // Dynent - auto json_dyn_entities = nlohmann::json::array(); - for (size_t i = 0; i < ARRAYSIZE(clipMap->dynEntCount); i++) - { - auto def_list = clipMap->dynEntDefList[i]; - if (def_list) - { - auto json_dyn_entity_def_list = nlohmann::json::array(); - - for (size_t j = 0; j < clipMap->dynEntCount[i]; j++) - { - auto json_dyn_entity_def_pack= nlohmann::json::object(); - auto json_dyn_entity_def= nlohmann::json::object(); - auto def = &def_list[j]; - - json_dyn_entity_def.emplace("type", def->type); - json_dyn_entity_def.emplace("pose", placement_to_json(def->pose)); - json_dyn_entity_def.emplace("xModel", def->xModel ? (def->xModel->name) : nlohmann::json()); - json_dyn_entity_def.emplace("brushModel", def->brushModel); - json_dyn_entity_def.emplace("physicsBrushModel", def->physicsBrushModel); - json_dyn_entity_def.emplace("destroyFx", def->destroyFx ? (def->destroyFx->name) : nlohmann::json()); - json_dyn_entity_def.emplace("physPreset", def->physPreset ? (def->physPreset->name) : nlohmann::json()); - json_dyn_entity_def.emplace("health", def->health); - - auto json_mass= nlohmann::json::object(); - json_mass.emplace("centerOfMass", float_array_to_json(def->mass.centerOfMass, 3)); - json_mass.emplace("momentsOfInertia", float_array_to_json(def->mass.momentsOfInertia, 3)); - json_mass.emplace("productsOfInertia", float_array_to_json(def->mass.productsOfInertia, 3)); - json_dyn_entity_def.emplace("mass", json_mass); - - json_dyn_entity_def.emplace("contents", def->contents); - - json_dyn_entity_def_pack.emplace("dynEntityDef", json_dyn_entity_def); - - /// All that follows is garbage data - //auto json_dyn_entity_pose= nlohmann::json::object(); - //auto pose = &clipMap->dynEntPoseList[i][j]; - //json_dyn_entity_pose.emplace("pose", placement_to_json(pose->pose)); - //json_dyn_entity_pose.emplace("radius", pose->radius); - //json_dyn_entity_def_pack.emplace("dynEntPose", json_dyn_entity_pose); - - //auto json_dyn_entity_client= nlohmann::json::object(); - //auto client = &clipMap->dynEntClientList[i][j]; - //json_dyn_entity_client.emplace("physObjId", client->physObjId); - //json_dyn_entity_client.emplace("flags", client->flags); - //json_dyn_entity_client.emplace("lightingHandle", client->lightingHandle); - //json_dyn_entity_client.emplace("health", client->health); - //json_dyn_entity_def_pack.emplace("dynEntClient", json_dyn_entity_client); - - //auto json_dyn_entity_coll= nlohmann::json::object(); - //auto coll = &clipMap->dynEntCollList[i][j]; - //json_dyn_entity_coll.emplace("sector", coll->sector); - //json_dyn_entity_coll.emplace("nextEntInSector", coll->nextEntInSector); - //json_dyn_entity_coll.emplace("linkMins", float_array_to_json(coll->linkMins, 2)); - //json_dyn_entity_coll.emplace("linkMaxs", float_array_to_json(coll->linkMaxs, 2)); - //json_dyn_entity_def_pack.emplace("dynEntColl", json_dyn_entity_coll); - // - - json_dyn_entity_def_list.push_back(json_dyn_entity_def_pack); - } - - json_dyn_entities.push_back(json_dyn_entity_def_list); - } - else - { - - json_dyn_entities.push_back(nlohmann::json()); - } - } - output.emplace("dynEntities", json_dyn_entities); - - // Checksum - output.emplace("checksum", clipMap->checksum); - - // Write to disk - constexpr auto* prefix = "maps/mp/"; - constexpr auto* suffix = ".d3dbsp"; - - std::string basename(header.clipMap->name); - basename = basename.substr(std::strlen(prefix), basename.size() - std::strlen(suffix) - std::strlen(prefix)); - Utils::IO::WriteFile(std::format("raw/clipmap/{}.iw4x.json", basename), output.dump(4)); - } } diff --git a/src/Components/Modules/AssetInterfaces/IclipMap_t.hpp b/src/Components/Modules/AssetInterfaces/IclipMap_t.hpp index 5099b77a..fbd5e307 100644 --- a/src/Components/Modules/AssetInterfaces/IclipMap_t.hpp +++ b/src/Components/Modules/AssetInterfaces/IclipMap_t.hpp @@ -10,7 +10,6 @@ namespace Assets void save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override; void mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override; void load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) override; - static void dump(Game::XAssetHeader /*header*/); private: class SModelQuadtree @@ -90,9 +89,5 @@ namespace Assets float x, y, z; float halfX, halfY, halfZ; }; - - void loadBinary(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder); - void loadFromJSON(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder); - }; } diff --git a/src/Components/Modules/AssetInterfaces/Isnd_alias_list_t.cpp b/src/Components/Modules/AssetInterfaces/Isnd_alias_list_t.cpp index 7304873f..545acc75 100644 --- a/src/Components/Modules/AssetInterfaces/Isnd_alias_list_t.cpp +++ b/src/Components/Modules/AssetInterfaces/Isnd_alias_list_t.cpp @@ -222,10 +222,7 @@ namespace Assets { alias->soundFile->exists = true; - - // These must be THE SAME POINTER !! - // Wanna know why ? Check out 0x685646 - alias->aliasName = aliasList->aliasName; + alias->aliasName = builder->getAllocator()->duplicateString(aliasName.get()); if (subtitle.is_string()) { @@ -247,7 +244,7 @@ namespace Assets alias->pitchMax = pitchMax.get(); alias->distMin = distMin.get(); alias->distMax = distMax.get(); - alias->flags.intValue = flags.get(); + alias->flags = flags.get(); alias->___u15.slavePercentage = slavePercentage.get(); alias->probability = probability.get(); alias->lfePercentage = lfePercentage.get(); @@ -311,9 +308,6 @@ namespace Assets } auto curve = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_SOUND_CURVE, fallOffCurve, builder).sndCurve; - - assert(curve); - alias->volumeFalloffCurve = curve; } @@ -326,10 +320,11 @@ namespace Assets { alias->soundFile->type = Game::SAT_STREAMED; - auto streamedFile = soundFile.get(); - std::string directory; - auto split = streamedFile.find_last_of('/'); - if (split != std::string::npos) + std::string streamedFile = soundFile.get(); + std::string directory = ""s; + int split = streamedFile.find_last_of('/'); + + if (split >= 0) { directory = streamedFile.substr(0, split); streamedFile = streamedFile.substr(split+1); @@ -384,127 +379,6 @@ namespace Assets } } - void Isnd_alias_list_t::dump(Game::XAssetHeader header) - { - nlohmann::json output; - Utils::Memory::Allocator strDuplicator; - auto ents = header.sound; - - auto head = nlohmann::json::array_t(); - - for (size_t i = 0; i < ents->count; i++) - { - Game::snd_alias_t alias = ents->head[i]; - - auto channelMaps = nlohmann::json::array_t(); - - for (size_t j = 0; j < 2; j++) - { - for (size_t k = 0; k < 2; k++) - { - auto iw3ChannelMap = alias.speakerMap->channelMaps[j][k]; - auto speakers = nlohmann::json::array_t(); - - for (size_t speakerIndex = 0; speakerIndex < iw3ChannelMap.speakerCount; speakerIndex++) - { - auto iw4Speaker = iw3ChannelMap.speakers[speakerIndex]; - - nlohmann::json::object_t speaker; - speaker.emplace("levels0", iw4Speaker.numLevels > 0 ? iw4Speaker.levels[0] : 0); - speaker.emplace("levels1", iw4Speaker.numLevels > 1 ? iw4Speaker.levels[1] : 0); - speaker.emplace("numLevels", iw4Speaker.numLevels); - speaker.emplace("speaker", iw4Speaker.speaker); - speakers.emplace_back(speaker); - } - - auto channelMap = nlohmann::json::object_t(); - channelMap.emplace("entryCount", iw3ChannelMap.speakerCount); - channelMap.emplace("speakers", speakers); - channelMaps.emplace_back(channelMap); - } - } - - auto speakerMap = nlohmann::json::object_t(); - speakerMap.emplace("channelMaps", channelMaps); - speakerMap.emplace("isDefault", alias.speakerMap->isDefault); - speakerMap.emplace("name", (alias.speakerMap->name)); - - std::string soundFile; - if (alias.soundFile) - { - switch (alias.soundFile->type) - { - // LOADED - case Game::snd_alias_type_t::SAT_LOADED: - // Save the LoadedSound subasset - soundFile = alias.soundFile->u.loadSnd->name; - break; - - // STREAMED - case Game::snd_alias_type_t::SAT_STREAMED: - { - soundFile = alias.soundFile->u.streamSnd.filename.info.raw.name; - - if (alias.soundFile->u.streamSnd.filename.info.raw.dir) - { - soundFile = Utils::String::VA("%s/%s", alias.soundFile->u.streamSnd.filename.info.raw.dir, soundFile.c_str()); - } - - break; - } - - // I DON'T KNOW :( - default: - Components::Logger::Print("Error dumping sound alias %s: unknown format %d\n", alias.aliasName, alias.soundFile->type); - return; - } - } - else - { - Components::Logger::Print("Error dumping sound alias %s: NULL soundfile!\n", alias.aliasName); - return; - } - - auto iw4Flags = alias.flags.intValue; - - auto json_alias = nlohmann::json::object_t(); - json_alias.emplace("aliasName", (alias.aliasName)); - json_alias.emplace("centerPercentage", alias.centerPercentage); - json_alias.emplace("chainAliasName", (alias.chainAliasName == nullptr ? nlohmann::json() : alias.chainAliasName)); - json_alias.emplace("distMax", alias.distMax); - json_alias.emplace("distMin", alias.distMin); - json_alias.emplace("envelopMax", alias.envelopMax); - json_alias.emplace("envelopMin", alias.envelopMin); - json_alias.emplace("envelopPercentage", alias.envelopPercentage); - json_alias.emplace("flags", iw4Flags); - json_alias.emplace("lfePercentage", alias.lfePercentage); - json_alias.emplace("mixerGroup", nlohmann::json()); - json_alias.emplace("pitchMax", alias.pitchMax); - json_alias.emplace("pitchMin", alias.pitchMin); - json_alias.emplace("probability", alias.probability); - json_alias.emplace("secondaryAliasName", (alias.secondaryAliasName == nullptr ? nlohmann::json() : alias.secondaryAliasName)); - json_alias.emplace("sequence", alias.sequence); - json_alias.emplace("slavePercentage", alias.___u15.slavePercentage); - json_alias.emplace("speakerMap", speakerMap); - json_alias.emplace("soundFile", (strDuplicator.duplicateString(soundFile))); - json_alias.emplace("startDelay", alias.startDelay); - json_alias.emplace("subtitle", (alias.subtitle == nullptr ? nlohmann::json() : alias.subtitle)); - json_alias.emplace("type", alias.soundFile->type); - json_alias.emplace("volMax", alias.volMax); - json_alias.emplace("volMin", alias.volMin); - json_alias.emplace("volumeFalloffCurve", (alias.volumeFalloffCurve->filename)); - - head.emplace_back(json_alias); - } - - output.emplace("aliasName", (ents->aliasName)); - output.emplace("count", ents->count); - output.emplace("head", head); - - const auto dump = output.dump(4); - Utils::IO::WriteFile(std::format("raw/sounds/{}.json", ents->aliasName), dump); - } - void Isnd_alias_list_t::save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) { AssertSize(Game::snd_alias_list_t, 12); @@ -518,16 +392,8 @@ namespace Assets if (asset->aliasName) { - if (builder->hasPointer(asset->aliasName)) - { - dest->aliasName = builder->getPointer(asset->aliasName); - } - else - { - builder->storePointer(asset->aliasName); - buffer->saveString(asset->aliasName); - Utils::Stream::ClearPointer(&dest->aliasName); - } + buffer->saveString(builder->getAssetName(this->getType(), asset->aliasName)); + Utils::Stream::ClearPointer(&dest->aliasName); } if (asset->head) @@ -553,16 +419,8 @@ namespace Assets if (alias->aliasName) { - if (builder->hasPointer(alias->aliasName)) - { - destAlias->aliasName = builder->getPointer(alias->aliasName); - } - else - { - builder->storePointer(alias->aliasName); - buffer->saveString(alias->aliasName); - Utils::Stream::ClearPointer(&destAlias->aliasName); - } + buffer->saveString(alias->aliasName); + Utils::Stream::ClearPointer(&destAlias->aliasName); } if (alias->subtitle) @@ -609,7 +467,7 @@ namespace Assets { if (alias->soundFile->type == Game::snd_alias_type_t::SAT_LOADED) { - destSoundFile->u.loadSnd = builder->saveSubAsset(Game::ASSET_TYPE_LOADED_SOUND, alias->soundFile->u.loadSnd).loadSnd; + destSoundFile->u.loadSnd = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_LOADED_SOUND, alias->soundFile->u.loadSnd).loadSnd; } else { @@ -636,7 +494,7 @@ namespace Assets if (alias->volumeFalloffCurve) { - destAlias->volumeFalloffCurve = builder->saveSubAsset(Game::ASSET_TYPE_SOUND_CURVE, alias->volumeFalloffCurve).sndCurve; + destAlias->volumeFalloffCurve = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_SOUND_CURVE, alias->volumeFalloffCurve).sndCurve; } if (alias->speakerMap) diff --git a/src/Components/Modules/AssetInterfaces/Isnd_alias_list_t.hpp b/src/Components/Modules/AssetInterfaces/Isnd_alias_list_t.hpp index fca10006..d7f2337b 100644 --- a/src/Components/Modules/AssetInterfaces/Isnd_alias_list_t.hpp +++ b/src/Components/Modules/AssetInterfaces/Isnd_alias_list_t.hpp @@ -10,6 +10,5 @@ namespace Assets void load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) override; void save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override; void mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override; - void dump(Game::XAssetHeader header) override; }; } diff --git a/src/Components/Modules/Debug.cpp b/src/Components/Modules/Debug.cpp index 6ae52dae..949ff759 100644 --- a/src/Components/Modules/Debug.cpp +++ b/src/Components/Modules/Debug.cpp @@ -242,11 +242,6 @@ namespace Components void Debug::CG_DrawDebugOverlays_Hk(const int localClientNum) { - if (!DebugOverlay) - { - return; - } - switch (DebugOverlay->current.integer) { case 2: diff --git a/src/Components/Modules/Logger.cpp b/src/Components/Modules/Logger.cpp index c6db9af7..c1e446b7 100644 --- a/src/Components/Modules/Logger.cpp +++ b/src/Components/Modules/Logger.cpp @@ -80,12 +80,11 @@ namespace Components void Logger::ErrorInternal(const Game::errorParm_t error, const std::string_view& fmt, std::format_args&& args) { - const auto msg = std::vformat(fmt, args); - #ifdef _DEBUG if (IsDebuggerPresent()) __debugbreak(); #endif + const auto msg = std::vformat(fmt, args); Game::Com_Error(error, "%s", msg.data()); } diff --git a/src/Components/Modules/Renderer.cpp b/src/Components/Modules/Renderer.cpp index 2bde06b9..498b075b 100644 --- a/src/Components/Modules/Renderer.cpp +++ b/src/Components/Modules/Renderer.cpp @@ -15,7 +15,6 @@ namespace Components Dvar::Var Renderer::r_drawAABBTrees; Dvar::Var Renderer::r_playerDrawDebugDistance; Dvar::Var Renderer::r_forceTechnique; - Dvar::Var Renderer::r_drawRunners; float cyan[4] = { 0.0f, 0.5f, 0.5f, 1.0f }; float red[4] = { 1.0f, 0.0f, 0.0f, 1.0f }; @@ -119,13 +118,10 @@ namespace Components } } - void Renderer::R_TextureFromCodeError(const char* sampler, Game::GfxCmdBufState* state, int samplerCode) + void Renderer::R_TextureFromCodeError(const char* sampler, Game::GfxCmdBufState* state) { - Logger::Error( - Game::ERR_FATAL, - "Tried to use sampler #{} ('{}') at the wrong timing! Additional info:\nMaterial: '{}'\nTechnique {}\nTechnique slot: {}\nTechnique flags:{}\nPass: {}\nPixel shader: {}\n", - samplerCode, sampler, state->material->info.name, state->technique->name, (int)state->techType, state->technique->flags, state->passIndex, state->pixelShader->name - ); + Logger::Error(Game::ERR_FATAL, "Tried to use sampler '{}' when it isn't valid for material '{}' and technique '{}'", + sampler, state->material->info.name, state->technique->name); } __declspec(naked) void Renderer::StoreGfxBufContextPtrStub1() @@ -158,11 +154,10 @@ namespace Components // show error pushad - push eax push ebx push edx call R_TextureFromCodeError - add esp, 0xC + add esp, 8 popad // go back @@ -366,7 +361,7 @@ namespace Components if (staticModel->model) { - Game::R_AddDebugBounds(staticModelsColor, b); + Game::R_AddDebugBounds(staticModelsColor, b); } } } @@ -463,41 +458,6 @@ namespace Components } } - void Renderer::DebugDrawRunners() - { - if (!Game::CL_IsCgameInitialized()) - { - return; - } - - if (r_drawRunners.get()) - { - auto* fxSystem = reinterpret_cast(0x173F200); - - if (fxSystem) - { - for (auto i = 0; i < fxSystem->activeElemCount; i++) - { - auto* elem = &fxSystem->effects[i]; - if (elem->def) - { - Game::R_AddDebugString(sceneModelsColor, elem->frameNow.origin, 1.0f, elem->def->name); - } - } - } - - auto soundCount = *reinterpret_cast(0x7C5C90); - auto* sounds = reinterpret_cast(0x7C5CA0); - - for (auto i = 0; i < soundCount; i++) - { - if (sounds[i].aliasList) - { - Game::R_AddDebugString(staticModelsColor, sounds[i].origin, 1.0f, sounds[i].aliasList->aliasName); - } - } - } - } void Renderer::DebugDrawAABBTrees() { if (!r_drawAABBTrees.get()) return; @@ -547,7 +507,6 @@ namespace Components { if (Game::CL_IsCgameInitialized()) { - DebugDrawRunners(); DebugDrawAABBTrees(); DebugDrawModelNames(); DebugDrawModelBoundingBoxes(); @@ -602,7 +561,6 @@ namespace Components nullptr }; - Renderer::r_drawRunners = Game::Dvar_RegisterBool("r_drawRunners", false, Game::DVAR_NONE, "Draw active sound & fx runners"); Renderer::r_drawModelBoundingBoxes = Game::Dvar_RegisterEnum("r_drawModelBoundingBoxes", values, 0, Game::DVAR_CHEAT, "Draw scene model bounding boxes"); Renderer::r_drawSceneModelCollisions = Game::Dvar_RegisterBool("r_drawSceneModelCollisions", false, Game::DVAR_CHEAT, "Draw scene model collisions"); Renderer::r_drawTriggers = Game::Dvar_RegisterBool("r_drawTriggers", false, Game::DVAR_CHEAT, "Draw triggers"); diff --git a/src/Components/Modules/Renderer.hpp b/src/Components/Modules/Renderer.hpp index ab939543..c856376e 100644 --- a/src/Components/Modules/Renderer.hpp +++ b/src/Components/Modules/Renderer.hpp @@ -28,7 +28,7 @@ namespace Components static void PostVidRestart(); static void PostVidRestartStub(); - static void R_TextureFromCodeError(const char* sampler, Game::GfxCmdBufState* state, int samplerCode); + static void R_TextureFromCodeError(const char* sampler, Game::GfxCmdBufState* state); static void StoreGfxBufContextPtrStub1(); static void StoreGfxBufContextPtrStub2(); @@ -38,7 +38,6 @@ namespace Components static void DebugDrawSceneModelCollisions(); static void DebugDrawModelBoundingBoxes(); static void DebugDrawModelNames(); - static void DebugDrawRunners(); static void DebugDrawAABBTrees(); static void ForceTechnique(); @@ -51,7 +50,6 @@ namespace Components static Utils::Signal SingleBackendFrameSignal; static Dvar::Var r_drawTriggers; - static Dvar::Var r_drawRunners; static Dvar::Var r_drawSceneModelCollisions; static Dvar::Var r_drawModelBoundingBoxes; static Dvar::Var r_drawModelNames; diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index caccd403..5297d176 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -882,8 +882,8 @@ namespace Game { float normal[3]; float dist; - unsigned char type; - unsigned char pad[3]; + char type; + char pad[3]; }; struct cbrushside_t @@ -896,13 +896,13 @@ namespace Game struct cbrush_t { - unsigned short numsides; - unsigned short glassPieceIndex; + unsigned __int16 numsides; + unsigned __int16 glassPieceIndex; cbrushside_t* sides; - unsigned char* baseAdjacentSide; - unsigned short axialMaterialNum[2][3]; - unsigned char firstAdjacentSideOffsets[2][3]; - unsigned char edgeCount[2][3]; + char* baseAdjacentSide; + __int16 axialMaterialNum[2][3]; + char firstAdjacentSideOffsets[2][3]; + char edgeCount[2][3]; }; struct BrushWrapper @@ -2497,189 +2497,6 @@ namespace Game SAT_COUNT = 0x4, }; - struct snd_volume_info_t - { - float volume; - float goalvolume; - float goalrate; - }; - - struct snd_channelvolgroup - { - snd_volume_info_t channelvol[64]; - bool active; - }; - - struct snd_background_info_t - { - float goalvolume; - float goalrate; - }; - - struct snd_enveffect - { - int roomtype; - float drylevel; - float drygoal; - float dryrate; - float wetlevel; - float wetgoal; - float wetrate; - bool active; - }; - - struct orientation_t - { - float origin[3]; - float axis[3][3]; - }; - - struct snd_listener - { - orientation_t orient; - float velocity; - int clientNum; - bool active; - }; - - struct snd_amplifier - { - snd_listener* listener; - int minRadius; - int maxRadius; - float falloffExp; - float minVol; - float maxVol; - }; - - struct snd_entchannel_info_t - { - char name[64]; - int priority; - bool is3d; - bool isRestricted; - bool isPausable; - int maxVoices; - int voiceCount; - }; - - struct snd_entchan_overrides_t - { - unsigned int isPausable[2]; - float timescaleLerp[64]; - }; - - enum SndFileLoadingState - { - SFLS_UNLOADED = 0x0, - SFLS_LOADING = 0x1, - SFLS_LOADED = 0x2, - }; - - struct SndFileSpecificChannelInfo - { - SndFileLoadingState loadingState; - int srcChannelCount; - int baserate; - }; - - union SndEntHandle - { - struct - { - unsigned int entIndex; - } field; - int handle; - }; - - enum SndLengthId - { - SndLengthNotify_Subtitle = 0x0, - SndLengthNotify_EntityCustom = 0x1, - SndLengthNotifyCount = 0x2, - }; - - struct sndLengthNotifyInfo - { - SndLengthId id[4]; - void* data[4]; - int count; - }; - - enum snd_alias_system_t - { - SASYS_UI = 0x0, - SASYS_CGAME = 0x1, - SASYS_GAME = 0x2, - SASYS_COUNT = 0x3, - }; - - struct snd_channel_info_t - { - SndFileSpecificChannelInfo soundFileInfo; - SndEntHandle sndEnt; - int entchannel; - int startDelay; - int looptime; - int totalMsec; - int playbackId; - sndLengthNotifyInfo lengthNotifyInfo; - float basevolume; - float pitch; - struct snd_alias_t* alias0; - struct snd_alias_t* alias1; - int saveIndex0; - int saveIndex1; - float lerp; - float org[3]; - float offset[3]; - bool paused; - bool master; - float timescaleLerp; - snd_alias_system_t system; - }; - - struct snd_local_t - { - bool Initialized2d; - bool Initialized3d; - bool paused; - int playbackIdCounter; - unsigned int playback_rate; - int playback_channels; - float timescale; - int pausetime; - int cpu; - struct - { - char buffer[16384]; - volatile int size; - bool compress; - } restore; - float volume; - snd_volume_info_t mastervol; - snd_channelvolgroup channelVolGroups[4]; - snd_channelvolgroup* channelvol; - snd_background_info_t background[4]; - int ambient_track; - float slaveLerp; - float masterPercentage; - snd_enveffect envEffects[5]; - snd_enveffect* effect; - snd_listener listeners[2]; - int time; - int looptime; - snd_amplifier amplifier; - snd_entchannel_info_t entchaninfo[64]; - snd_entchan_overrides_t entchanOverrides; - int entchannel_count; - snd_channel_info_t chaninfo[52]; - int max_2D_channels; - int max_3D_channels; - int max_stream_channels; - }; - - struct SoundFile { char type; @@ -2687,6 +2504,12 @@ namespace Game SoundFileRef u; }; + union $C8D87EB0090687D323381DFB7A82089C + { + float slavePercentage; + float masterPercentage; + }; + struct SndCurve { const char* filename; @@ -2714,26 +2537,6 @@ namespace Game MSSChannelMap channelMaps[2][2]; }; - union SoundAliasFlags - { -#pragma warning(push) -#pragma warning(disable: 4201) - struct - { - unsigned int looping : 1; // & 1 / 0x1 / 0000 0000 0000 0001 - unsigned int isMaster : 1; // & 2 / 0x2 / 0000 0000 0000 0010 - unsigned int isSlave : 1; // & 4 / 0x4 / 0000 0000 0000 0100 - unsigned int fullDryLevel : 1; // & 8 / 0x8 / 0000 0000 0000 1000 - unsigned int noWetLevel : 1; // & 16 / 0x10 / 0000 0000 0001 0000 - unsigned int unknown : 1; // & 32 / 0x20 / 0000 0000 0010 0000 - unsigned int unk_is3D : 1; // & 64 / 0x40 / 0000 0000 0100 0000 // CONFIRMED IW4 IW5 - unsigned int type : 2; // & 384 / 0x180 / 0000 0001 1000 0000 // CONFIRMED IW4 IW5 - unsigned int channel : 6; // & 32256 / 0x7E00 / 0111 1110 0000 0000 // CONFIRMED IW4 IW5 - }; -#pragma warning(pop) - unsigned int intValue; - }; - const struct snd_alias_t { const char* aliasName; @@ -2750,12 +2553,8 @@ namespace Game float distMin; float distMax; float velocityMin; - SoundAliasFlags flags; - union - { - float slavePercentage; - float masterPercentage; - } ___u15; + int flags; + $C8D87EB0090687D323381DFB7A82089C ___u15; float probability; float lfePercentage; float centerPercentage; @@ -2838,7 +2637,7 @@ namespace Game struct cLeafBrushNode_s { - unsigned char axis; + char axis; __int16 leafBrushCount; int contents; cLeafBrushNodeData_t data; @@ -2855,9 +2654,9 @@ namespace Game struct CollisionPartition { - unsigned char triCount; - unsigned char borderCount; - unsigned char firstVertSegment; + char triCount; + char borderCount; + char firstVertSegment; int firstTri; CollisionBorder* borders; }; @@ -3194,7 +2993,7 @@ namespace Game { const char* name; int isInUse; - unsigned int planeCount; + int planeCount; cplane_s* planes; unsigned int numStaticModels; cStaticModel_s* staticModelList; @@ -3203,7 +3002,7 @@ namespace Game unsigned int numBrushSides; cbrushside_t* brushsides; unsigned int numBrushEdges; - unsigned char* brushEdges; + char* brushEdges; unsigned int numNodes; cNode_t* nodes; unsigned int numLeafs; @@ -3215,15 +3014,15 @@ namespace Game unsigned int numLeafSurfaces; unsigned int* leafsurfaces; unsigned int vertCount; - vec3_t* verts; - unsigned int triCount; + float(*verts)[3]; + int triCount; unsigned __int16* triIndices; - unsigned char* triEdgeIsWalkable; - unsigned int borderCount; + char* triEdgeIsWalkable; + int borderCount; CollisionBorder* borders; int partitionCount; CollisionPartition* partitions; - unsigned int aabbTreeCount; + int aabbTreeCount; CollisionAabbTree* aabbTrees; unsigned int numSubModels; cmodel_t* cmodels; @@ -3595,9 +3394,9 @@ namespace Game float texCoordOrigin[2]; unsigned int supportMask; float areaX2; - unsigned char defIndex; - unsigned char vertCount; - unsigned char fanDataCount; + char defIndex; + char vertCount; + char fanDataCount; char pad[1]; }; @@ -8855,12 +8654,6 @@ namespace Game unsigned __int16 children; }; - struct ClientEntSound - { - float origin[3]; - snd_alias_list_t* aliasList; - }; - struct FxEffect { const FxEffectDef* def; @@ -10879,124 +10672,6 @@ namespace Game HANDLE handle; }; - struct FxCamera - { - float origin[3]; - volatile int isValid; - float frustum[6][4]; - float axis[3][3]; - unsigned int frustumPlaneCount; - float viewOffset[3]; - bool thermal; - unsigned int pad[2]; - }; - - struct r_double_index_t - { - unsigned __int16 value[2]; - }; - - struct FxSpriteInfo - { - r_double_index_t* indices; - unsigned int indexCount; - Material* material; - const char* name; - }; - - struct FxVisBlocker - { - float origin[3]; - unsigned __int16 radius; - unsigned __int16 visibility; - }; - - struct FxVisState - { - FxVisBlocker blocker[256]; - volatile int blockerCount; - unsigned int pad[3]; - }; - - struct FxElem - { - char defIndex; - char sequence; - char atRestFraction; - char emitResidual; - unsigned __int16 nextElemHandleInEffect; - unsigned __int16 prevElemHandleInEffect; - int msecBegin; - float baseVel[3]; - union - { - int physObjId; - float origin[3]; - } ___u8; - union - { - unsigned __int16 lightingHandle; - unsigned __int16 sparkCloudHandle; - unsigned __int16 sparkFountainHandle; - } u; - }; - - struct FxSystem - { - FxCamera camera; - FxCamera cameraPrev; - FxSpriteInfo sprite; - FxEffect* effects; - FxElem *elems; - void* trails; - void* trailElems; - void* bolts; - void* sparkClouds; - void* sparkFountains; - void* sparkFountainClusters; - unsigned __int16* deferredElems; - volatile int firstFreeElem; - volatile int firstFreeTrailElem; - volatile int firstFreeTrail; - volatile int firstFreeBolt; - volatile int firstFreeSparkCloud; - volatile int firstFreeSparkFountain; - volatile int firstFreeSparkFountainCluster; - volatile int deferredElemCount; - volatile int activeElemCount; - volatile int activeTrailElemCount; - volatile int activeTrailCount; - volatile int activeBoltCount; - volatile int activeSparkCloudCount; - volatile int activeSparkFountainCount; - volatile int activeSparkFountainClusterCount; - volatile int gfxCloudCount; - FxVisState* visState; - FxVisState* visStateBufferRead; - FxVisState* visStateBufferWrite; - volatile int firstActiveEffect; - volatile int firstNewEffect; - volatile int firstFreeEffect; - unsigned __int16 allEffectHandles[1024]; - volatile int activeSpotLightEffectCount; - volatile int activeSpotLightElemCount; - unsigned __int16 activeSpotLightEffectHandle; - unsigned __int16 activeSpotLightElemHandle; - __int16 activeSpotLightBoltDobj; - volatile int iteratorCount; - int msecNow; - volatile int msecDraw; - int frameCount; - bool isInitialized; - bool needsGarbageCollection; - bool isArchiving; - char localClientNum; - unsigned int restartList[32]; - FxEffect** restartEffectsList; - unsigned int restartCount; - unsigned int pad1[14]; - }; - #pragma endregion #ifndef IDA diff --git a/src/Utils/Json.cpp b/src/Utils/Json.cpp index ffa427d9..ff401f86 100644 --- a/src/Utils/Json.cpp +++ b/src/Utils/Json.cpp @@ -62,12 +62,4 @@ namespace Utils::Json return input.to_ulong(); } - Game::Bounds ReadBounds(const nlohmann::json_abi_v3_11_2::json value) - { - Game::Bounds bounds{}; - Utils::Json::CopyArray(bounds.midPoint, value["midPoint"]); - Utils::Json::CopyArray(bounds.halfSize, value["halfSize"]); - - return bounds; - } } diff --git a/src/Utils/Json.hpp b/src/Utils/Json.hpp index 6a4d07c5..c73de553 100644 --- a/src/Utils/Json.hpp +++ b/src/Utils/Json.hpp @@ -1,25 +1,9 @@ #pragma once - #include namespace Utils::Json { std::string TypeToString(nlohmann::json::value_t type); - unsigned long ReadFlags(const std::string binaryFlags, size_t size); - - Game::Bounds ReadBounds(const nlohmann::json_abi_v3_11_2::json value); - - template void CopyArray(T* destination, const nlohmann::json_abi_v3_11_2::json& json_member, size_t count = 0) - { - if (count == 0) - { - count = json_member.size(); - } - - for (size_t i = 0; i < count; i++) - { - destination[i] = json_member[i].get(); - } - } + unsigned long ReadFlags(std::string binaryFlags, size_t size); } diff --git a/src/Utils/Maths.cpp b/src/Utils/Maths.cpp index 35f12ff3..2b840002 100644 --- a/src/Utils/Maths.cpp +++ b/src/Utils/Maths.cpp @@ -7,7 +7,7 @@ namespace Utils::Maths return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; } - void VectorSubtract(const float va[3], const float vb[3], float out[3]) + void VectorSubtract(float va[3], float vb[3], float out[3]) { out[0] = va[0] - vb[0]; out[1] = va[1] - vb[1]; @@ -35,7 +35,7 @@ namespace Utils::Maths out[2] = v[2] * scale; } - float Vec3SqrDistance(const float v1[3], const float v2[3]) + float Vec3SqrDistance(float v1[3], float v2[3]) { float out[3]; diff --git a/src/Utils/Maths.hpp b/src/Utils/Maths.hpp index 7d2111df..47f37ed5 100644 --- a/src/Utils/Maths.hpp +++ b/src/Utils/Maths.hpp @@ -7,9 +7,9 @@ namespace Utils::Maths constexpr auto VectorNegate(float x[3]) { x[0] = -x[0]; x[1] = -x[1]; x[2] = -x[2]; } float DotProduct(float v1[3], float v2[3]); - void VectorSubtract(const float va[3], const float vb[3], float out[3]); + void VectorSubtract(float va[3], float vb[3], float out[3]); void VectorAdd(float va[3], float vb[3], float out[3]); void VectorCopy(float in[3], float out[3]); void VectorScale(float v[3], float scale, float out[3]); - float Vec3SqrDistance(const float v1[3], const float v2[3]); + float Vec3SqrDistance(float v1[3], float v2[3]); } diff --git a/src/Utils/Stream.cpp b/src/Utils/Stream.cpp index fb50955c..dc50f51c 100644 --- a/src/Utils/Stream.cpp +++ b/src/Utils/Stream.cpp @@ -16,14 +16,14 @@ namespace Utils const char* Stream::Reader::readCString() { - return this->allocator_->duplicateString(this->readString()); + return this->allocator->duplicateString(this->readString()); } char Stream::Reader::readByte() { - if ((this->position_ + 1) <= this->buffer_.size()) + if ((this->position + 1) <= this->buffer.size()) { - return this->buffer_[this->position_++]; + return this->buffer[this->position++]; } throw std::runtime_error("Reading past the buffer"); @@ -31,45 +31,45 @@ namespace Utils void* Stream::Reader::read(size_t size, std::size_t count) { - auto bytes = size * count; + size_t bytes = size * count; - if ((this->position_ + bytes) <= this->buffer_.size()) + if ((this->position + bytes) <= this->buffer.size()) { - auto* buffer = this->allocator_->allocate(bytes); + void* _buffer = this->allocator->allocate(bytes); - std::memcpy(buffer, this->buffer_.data() + this->position_, bytes); - this->position_ += bytes; + std::memcpy(_buffer, this->buffer.data() + this->position, bytes); + this->position += bytes; - return buffer; + return _buffer; } throw std::runtime_error("Reading past the buffer"); } - bool Stream::Reader::end() const + bool Stream::Reader::end() { - return (this->buffer_.size() == this->position_); + return (this->buffer.size() == this->position); } - void Stream::Reader::seek(unsigned int position) + void Stream::Reader::seek(unsigned int _position) { - if (this->buffer_.size() >= position) + if (this->buffer.size() >= _position) { - this->position_ = position; + this->position = _position; } } - void Stream::Reader::seekRelative(unsigned int position) + void Stream::Reader::seekRelative(unsigned int _position) { - return this->seek(position + this->position_); + return this->seek(_position + this->position); } void* Stream::Reader::readPointer() { - auto* pointer = this->read(); + void* pointer = this->read(); if (!this->hasPointer(pointer)) { - this->pointerMap_[pointer] = nullptr; + this->pointerMap[pointer] = nullptr; } return pointer; } @@ -78,18 +78,18 @@ namespace Utils { if (this->hasPointer(oldPointer)) { - this->pointerMap_[oldPointer] = newPointer; + this->pointerMap[oldPointer] = newPointer; } } - bool Stream::Reader::hasPointer(void* pointer) const + bool Stream::Reader::hasPointer(void* pointer) { - return this->pointerMap_.contains(pointer); + return this->pointerMap.find(pointer) != this->pointerMap.end(); } Stream::Stream() : ptrAssertion(false), criticalSectionState(0) { - std::memset(this->blockSize, 0, sizeof(this->blockSize)); + memset(this->blockSize, 0, sizeof(this->blockSize)); #ifdef WRITE_LOGS this->structLevel = 0; @@ -99,12 +99,12 @@ namespace Utils Stream::Stream(size_t size) : Stream() { - this->buffer_.reserve(size); + this->buffer.reserve(size); } Stream::~Stream() { - this->buffer_.clear(); + this->buffer.clear(); if (this->criticalSectionState != 0) { @@ -114,12 +114,12 @@ namespace Utils std::size_t Stream::length() const { - return this->buffer_.length(); + return this->buffer.length(); } std::size_t Stream::capacity() const { - return this->buffer_.capacity(); + return this->buffer.capacity(); } void Stream::assertPointer(const void* pointer, std::size_t length) @@ -159,7 +159,7 @@ namespace Utils return this->at(); } - auto* data = this->data(); + auto data = this->data(); if (this->isCriticalSection() && this->length() + (size * count) > this->capacity()) { @@ -167,7 +167,7 @@ namespace Utils __debugbreak(); } - this->buffer_.append(static_cast(_str), size * count); + this->buffer.append(static_cast(_str), size * count); if (this->data() != data && this->isCriticalSection()) { @@ -319,7 +319,7 @@ namespace Utils char* Stream::data() { - return const_cast(this->buffer_.data()); + return const_cast(this->buffer.data()); } unsigned int Stream::getBlockSize(Game::XFILE_BLOCK_TYPES stream) diff --git a/src/Utils/Stream.hpp b/src/Utils/Stream.hpp index ba2b92f2..3739cc3a 100644 --- a/src/Utils/Stream.hpp +++ b/src/Utils/Stream.hpp @@ -21,13 +21,13 @@ namespace Utils int criticalSectionState; unsigned int blockSize[Game::MAX_XFILE_COUNT]; std::vector streamStack; - std::string buffer_; + std::string buffer; public: class Reader { public: - Reader(Memory::Allocator* allocator, std::string& buffer) : position_(0), buffer_(std::move(buffer)), allocator_(allocator) {} + Reader(Memory::Allocator* _allocator, const std::string& _buffer) : position(0), buffer(_buffer), allocator(_allocator) {} std::string readString(); const char* readCString(); @@ -53,18 +53,18 @@ namespace Utils auto ptr = read(); auto* voidPtr = reinterpret_cast(ptr); - if (this->allocator_->isPointerMapped(voidPtr)) + if (allocator->isPointerMapped(voidPtr)) { - return this->allocator_->getPointer(voidPtr); + return allocator->getPointer(voidPtr); } throw std::runtime_error("Bad data: missing ptr"); } case FOLLOWING: { - auto filePosition = this->position_; + auto filePosition = position; auto data = readArray(count); - this->allocator_->mapPointer(reinterpret_cast(filePosition), data); + allocator->mapPointer(reinterpret_cast(filePosition), data); return data; } default: @@ -89,19 +89,19 @@ namespace Utils return obj; } - bool end() const; + bool end(); void seek(unsigned int position); void seekRelative(unsigned int position); void* readPointer(); void mapPointer(void* oldPointer, void* newPointer); - bool hasPointer(void* pointer) const; + bool hasPointer(void* pointer); private: - unsigned int position_; - std::string buffer_; - std::map pointerMap_; - Memory::Allocator* allocator_; + unsigned int position; + std::string buffer; + std::map pointerMap; + Memory::Allocator* allocator; }; enum Alignment @@ -123,13 +123,11 @@ namespace Utils Stream(size_t size); ~Stream(); - std::unordered_map dataPointers; - [[nodiscard]] std::size_t length() const; [[nodiscard]] std::size_t capacity() const; - char* save(const void * str, std::size_t size, std::size_t count = 1); - char* save(Game::XFILE_BLOCK_TYPES stream, const void * str, std::size_t size, std::size_t count); + char* save(const void * _str, std::size_t size, std::size_t count = 1); + char* save(Game::XFILE_BLOCK_TYPES stream, const void * _str, std::size_t size, std::size_t count); char* save(Game::XFILE_BLOCK_TYPES stream, int value, std::size_t count); template char* save(T* object) @@ -137,42 +135,6 @@ namespace Utils return saveArray(object, 1); } - template char* saveObject(T value) - { - return saveArray(&value, 1); - } - - template void saveArrayIfNotExisting(T* data, size_t count) - { -#define POINTER 255 -#define FOLLOWING 254 - - if (const auto itr = dataPointers.find(data); itr != dataPointers.end()) - { - saveByte(POINTER); - saveObject(itr->second); - } - else - { - saveByte(FOLLOWING); - dataPointers.insert_or_assign(reinterpret_cast(data), length()); - saveArray(data, count); - } - } - - - char* save(int value, size_t count = 1) - { - auto ret = this->length(); - - for (size_t i = 0; i < count; ++i) - { - this->save(&value, 4, 1); - } - - return this->data() + ret; - } - template char* saveArray(T* array, std::size_t count) { return save(array, sizeof(T), count);