diff --git a/src/noggit/ChunkWater.cpp b/src/noggit/ChunkWater.cpp index 3585bc7a..4d941a2b 100755 --- a/src/noggit/ChunkWater.cpp +++ b/src/noggit/ChunkWater.cpp @@ -120,7 +120,7 @@ void ChunkWater::fromFile(BlizzardArchive::ClientFile &f, size_t basePos) } -void ChunkWater::save(sExtendableArray& adt, int base_pos, int& header_pos, int& current_pos) +void ChunkWater::save(util::sExtendableArray& adt, int base_pos, int& header_pos, int& current_pos) { MH2O_Header header; @@ -159,7 +159,7 @@ void ChunkWater::save(sExtendableArray& adt, int base_pos, int& header_pos, int& } } - memcpy(adt.GetPointer(header_pos), &header, sizeof(MH2O_Header)); + memcpy(adt.GetPointer(header_pos).get(), &header, sizeof(MH2O_Header)); header_pos += sizeof(MH2O_Header); } diff --git a/src/noggit/ChunkWater.hpp b/src/noggit/ChunkWater.hpp index 8838b79c..d8d413b3 100755 --- a/src/noggit/ChunkWater.hpp +++ b/src/noggit/ChunkWater.hpp @@ -4,12 +4,12 @@ #include #include #include +#include #include #include #include -class sExtendableArray; class MapChunk; class TileWater; @@ -31,7 +31,7 @@ public: void from_mclq(std::vector& layers); void fromFile(BlizzardArchive::ClientFile& f, size_t basePos); - void save(sExtendableArray& adt, int base_pos, int& header_pos, int& current_pos); + void save(util::sExtendableArray& adt, int base_pos, int& header_pos, int& current_pos); bool is_visible ( const float& cull_distance , const math::frustum& frustum diff --git a/src/noggit/MapChunk.cpp b/src/noggit/MapChunk.cpp index e4e1d2c9..ff5bb7a9 100755 --- a/src/noggit/MapChunk.cpp +++ b/src/noggit/MapChunk.cpp @@ -1427,7 +1427,7 @@ void MapChunk::setFlag(bool changeto, uint32_t flag) registerChunkUpdate(ChunkUpdateFlags::FLAGS); } -void MapChunk::save(sExtendableArray& lADTFile +void MapChunk::save(util::sExtendableArray& lADTFile , int& lCurrentPosition , int& lMCIN_Position , std::map &lTextures @@ -1443,7 +1443,7 @@ void MapChunk::save(sExtendableArray& lADTFile // MCNK data // lADTFile.Insert(lCurrentPosition + 8, 0x80, reinterpret_cast(&(header))); - MapChunkHeader *lMCNK_header = lADTFile.GetPointer(lCurrentPosition + 8); + auto const lMCNK_header = lADTFile.GetPointer(lCurrentPosition + 8); header_flags.flags.do_not_fix_alpha_map = 1; @@ -1505,9 +1505,13 @@ void MapChunk::save(sExtendableArray& lADTFile lADTFile.Extend(8 + lMCVT_Size); SetChunkHeader(lADTFile, lCurrentPosition, 'MCVT', lMCVT_Size); - lADTFile.GetPointer(lMCNK_Position + 8)->ofsHeight = lCurrentPosition - lMCNK_Position; + // lADTFile.GetPointer(lMCNK_Position + 8)->ofsHeight = lCurrentPosition - lMCNK_Position; - float* lHeightmap = lADTFile.GetPointer(lCurrentPosition + 8); + auto header_ptr = lADTFile.GetPointer(lMCNK_Position + 8); + + header_ptr->ofsHeight = lCurrentPosition - lMCNK_Position; + + auto const lHeightmap = lADTFile.GetPointer(lCurrentPosition + 8); for (int i = 0; i < mapbufsize; ++i) lHeightmap[i] = mVertices[i].y - mVertices[0].y; @@ -1522,15 +1526,15 @@ void MapChunk::save(sExtendableArray& lADTFile lMCCV_Size = mapbufsize * sizeof(unsigned int); lADTFile.Extend(8 + lMCCV_Size); SetChunkHeader(lADTFile, lCurrentPosition, 'MCCV', lMCCV_Size); - lADTFile.GetPointer(lMCNK_Position + 8)->ofsMCCV = lCurrentPosition - lMCNK_Position; + header_ptr->ofsMCCV = lCurrentPosition - lMCNK_Position; - unsigned int *lmccv = lADTFile.GetPointer(lCurrentPosition + 8); + auto const lmccv = lADTFile.GetPointer(lCurrentPosition + 8); for (int i = 0; i < mapbufsize; ++i) { - *lmccv++ = ((unsigned char)(mccv[i].z * 127.0f) & 0xFF) - + (((unsigned char)(mccv[i].y * 127.0f) & 0xFF) << 8) - + (((unsigned char)(mccv[i].x * 127.0f) & 0xFF) << 16); + lmccv[i] = (((unsigned char)(mccv[i].z * 127.0f) & 0xFF) << 0) + + (((unsigned char)(mccv[i].y * 127.0f) & 0xFF) << 8) + + (((unsigned char)(mccv[i].x * 127.0f) & 0xFF) << 16); } lCurrentPosition += 8 + lMCCV_Size; @@ -1538,7 +1542,7 @@ void MapChunk::save(sExtendableArray& lADTFile } else { - lADTFile.GetPointer(lMCNK_Position + 8)->ofsMCCV = 0; + header_ptr->ofsMCCV = 0; } // MCNR @@ -1547,9 +1551,9 @@ void MapChunk::save(sExtendableArray& lADTFile lADTFile.Extend(8 + lMCNR_Size); SetChunkHeader(lADTFile, lCurrentPosition, 'MCNR', lMCNR_Size); - lADTFile.GetPointer(lMCNK_Position + 8)->ofsNormal = lCurrentPosition - lMCNK_Position; + header_ptr->ofsNormal = lCurrentPosition - lMCNK_Position; - char * lNormals = lADTFile.GetPointer(lCurrentPosition + 8); + auto const lNormals = lADTFile.GetPointer(lCurrentPosition + 8); auto& tile_buffer = mt->getChunkHeightmapBuffer(); int chunk_start = (px * 16 + py) * mapbufsize * 4; @@ -1582,8 +1586,8 @@ void MapChunk::save(sExtendableArray& lADTFile lADTFile.Extend(static_cast(8 + lMCLY_Size)); SetChunkHeader(lADTFile, lCurrentPosition, 'MCLY', static_cast(lMCLY_Size)); - lADTFile.GetPointer(lMCNK_Position + 8)->ofsLayer = lCurrentPosition - lMCNK_Position; - lADTFile.GetPointer(lMCNK_Position + 8)->nLayers = texture_set ? static_cast(texture_set->num()) : 0; + header_ptr->ofsLayer = lCurrentPosition - lMCNK_Position; + header_ptr->nLayers = texture_set ? static_cast(texture_set->num()) : 0; std::vector> alphamaps; @@ -1596,7 +1600,7 @@ void MapChunk::save(sExtendableArray& lADTFile // MCLY data for (size_t j = 0; j < texture_set->num(); ++j) { - ENTRY_MCLY * lLayer = lADTFile.GetPointer(lCurrentPosition + 8 + 0x10 * static_cast(j)); + auto const lLayer = lADTFile.GetPointer(lCurrentPosition + 8 + 0x10 * static_cast(j)); lLayer->textureID = lTextures.find(texture_set->filename(j))->second; lLayer->flags = texture_set->flag(j); @@ -1659,12 +1663,12 @@ void MapChunk::save(sExtendableArray& lADTFile lADTFile.Extend(8 + lMCRF_Size); SetChunkHeader(lADTFile, lCurrentPosition, 'MCRF', lMCRF_Size); - lADTFile.GetPointer(lMCNK_Position + 8)->ofsRefs = lCurrentPosition - lMCNK_Position; - lADTFile.GetPointer(lMCNK_Position + 8)->nDoodadRefs = static_cast(lDoodadIDs.size()); - lADTFile.GetPointer(lMCNK_Position + 8)->nMapObjRefs = static_cast(lObjectIDs.size()); + header_ptr->ofsRefs = lCurrentPosition - lMCNK_Position; + header_ptr->nDoodadRefs = static_cast(lDoodadIDs.size()); + header_ptr->nMapObjRefs = static_cast(lObjectIDs.size()); // MCRF data - int *lReferences = lADTFile.GetPointer(lCurrentPosition + 8); + auto const lReferences = lADTFile.GetPointer(lCurrentPosition + 8); lID = 0; for (std::list::iterator it = lDoodadIDs.begin(); it != lDoodadIDs.end(); ++it) @@ -1692,13 +1696,13 @@ void MapChunk::save(sExtendableArray& lADTFile lADTFile.Extend(8 + lMCSH_Size); SetChunkHeader(lADTFile, lCurrentPosition, 'MCSH', lMCSH_Size); - lADTFile.GetPointer(lMCNK_Position + 8)->ofsShadow = lCurrentPosition - lMCNK_Position; - lADTFile.GetPointer(lMCNK_Position + 8)->sizeShadow = 0x200; + header_ptr->ofsShadow = lCurrentPosition - lMCNK_Position; + header_ptr->sizeShadow = 0x200; - char * lLayer = lADTFile.GetPointer(lCurrentPosition + 8); + auto const lLayer = lADTFile.GetPointer(lCurrentPosition + 8); auto shadow_map = compressed_shadow_map(); - memcpy(lLayer, shadow_map.data(), 0x200); + memcpy(lLayer.get(), shadow_map.data(), 0x200); lCurrentPosition += 8 + lMCSH_Size; lMCNK_Size += 8 + lMCSH_Size; @@ -1706,22 +1710,22 @@ void MapChunk::save(sExtendableArray& lADTFile else { header_flags.flags.has_mcsh = 0; - lADTFile.GetPointer(lMCNK_Position + 8)->ofsShadow = 0; - lADTFile.GetPointer(lMCNK_Position + 8)->sizeShadow = 0; + header_ptr->ofsShadow = 0; + header_ptr->sizeShadow = 0; } // MCAL lADTFile.Extend(8 + lMCAL_Size); SetChunkHeader(lADTFile, lCurrentPosition, 'MCAL', lMCAL_Size); - lADTFile.GetPointer(lMCNK_Position + 8)->ofsAlpha = lCurrentPosition - lMCNK_Position; - lADTFile.GetPointer(lMCNK_Position + 8)->sizeAlpha = 8 + lMCAL_Size; + header_ptr->ofsAlpha = lCurrentPosition - lMCNK_Position; + header_ptr->sizeAlpha = 8 + lMCAL_Size; - char * lAlphaMaps = lADTFile.GetPointer(lCurrentPosition + 8); + auto lAlphaMaps = lADTFile.GetPointer(lCurrentPosition + 8); for (auto& alpha : alphamaps) { - memcpy(lAlphaMaps, alpha.data(), alpha.size()); + memcpy(lAlphaMaps.get(), alpha.data(), alpha.size()); lAlphaMaps += alpha.size(); } @@ -1737,14 +1741,14 @@ void MapChunk::save(sExtendableArray& lADTFile lADTFile.Extend(8 + lMCSE_Size); SetChunkHeader(lADTFile, lCurrentPosition, 'MCSE', lMCSE_Size); - lADTFile.GetPointer(lMCNK_Position + 8)->ofsSndEmitters = lCurrentPosition - lMCNK_Position; - lADTFile.GetPointer(lMCNK_Position + 8)->nSndEmitters = lMCSE_Size / 0x1C; + header_ptr->ofsSndEmitters = lCurrentPosition - lMCNK_Position; + header_ptr->nSndEmitters = lMCSE_Size / 0x1C; lCurrentPosition += 8; for (auto& sound_emitter : sound_emitters) { - ENTRY_MCSE* MCSE = lADTFile.GetPointer(lCurrentPosition); + auto const MCSE = lADTFile.GetPointer(lCurrentPosition); MCSE->soundId = sound_emitter.soundId; diff --git a/src/noggit/MapChunk.h b/src/noggit/MapChunk.h index 9c4f7a99..8eb8c9fc 100755 --- a/src/noggit/MapChunk.h +++ b/src/noggit/MapChunk.h @@ -3,16 +3,19 @@ #pragma once #include #include // MapTile +#include #include #include #include #include +#include #include #include #include #include #include -#include +#include + #include #include #include @@ -31,7 +34,6 @@ namespace math } class Brush; class ChunkWater; -class sExtendableArray; class QPixmap; using StripType = uint16_t; @@ -194,7 +196,7 @@ public: void clearHeight(); //! \todo this is ugly create a build struct or sth - void save(sExtendableArray &lADTFile + void save(util::sExtendableArray &lADTFile , int &lCurrentPosition , int &lMCIN_Position , std::map &lTextures diff --git a/src/noggit/MapHeaders.h b/src/noggit/MapHeaders.h index 97077db0..7e58ae17 100755 --- a/src/noggit/MapHeaders.h +++ b/src/noggit/MapHeaders.h @@ -122,8 +122,8 @@ struct ENTRY_MODF struct MapChunkHeader { uint32_t flags = 0; - uint32_t ix; - uint32_t iy; + uint32_t ix = 0; + uint32_t iy = 0; uint32_t nLayers = 0; uint32_t nDoodadRefs = 0; uint32_t ofsHeight = 0; @@ -143,9 +143,9 @@ struct MapChunkHeader { uint32_t nSndEmitters = 0; uint32_t ofsLiquid = 0; uint32_t sizeLiquid = 0; - float zpos; - float xpos; - float ypos; + float zpos = 0.0f; + float xpos = 0.0f; + float ypos = 0.0f; uint32_t ofsMCCV = 0; uint32_t unused1 = 0; uint32_t unused2 = 0; diff --git a/src/noggit/MapTile.cpp b/src/noggit/MapTile.cpp index aca320a3..16a2eab9 100755 --- a/src/noggit/MapTile.cpp +++ b/src/noggit/MapTile.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -275,6 +276,8 @@ void MapTile::finishLoading() assert(fourcc == 'MH2O'); Water.readFromFile(theFile, ofsW); + + // Water.update_underground_vertices_depth(); } // - MFBO ---------------------------------------------- @@ -633,7 +636,7 @@ void MapTile::saveTile(World* world) texture.second = lID++; // Now write the file. - sExtendableArray lADTFile; + util::sExtendableArray lADTFile; int lCurrentPosition = 0; @@ -709,7 +712,7 @@ void MapTile::saveTile(World* world) // MMID data // WMO model names - int * lMMID_Data = lADTFile.GetPointer(lCurrentPosition + 8); + auto const lMMID_Data = lADTFile.GetPointer(lCurrentPosition + 8); lID = 0; for (auto const& model : lModels) @@ -744,7 +747,7 @@ void MapTile::saveTile(World* world) lADTFile.GetPointer(lMHDR_Position + 8)->mwid = lCurrentPosition - 0x14; // MWID data - int * lMWID_Data = lADTFile.GetPointer(lCurrentPosition + 8); + auto const lMWID_Data = lADTFile.GetPointer(lCurrentPosition + 8); lID = 0; for (auto const& object : lObjects) @@ -759,7 +762,7 @@ void MapTile::saveTile(World* world) lADTFile.GetPointer(lMHDR_Position + 8)->mddf = lCurrentPosition - 0x14; // MDDF data - ENTRY_MDDF* lMDDF_Data = lADTFile.GetPointer(lCurrentPosition + 8); + auto const lMDDF_Data = lADTFile.GetPointer(lCurrentPosition + 8); if(world->mapIndex.sort_models_by_size_class()) { @@ -803,7 +806,7 @@ void MapTile::saveTile(World* world) lADTFile.GetPointer(lMHDR_Position + 8)->modf = lCurrentPosition - 0x14; // MODF data - ENTRY_MODF *lMODF_Data = lADTFile.GetPointer(lCurrentPosition + 8); + auto const lMODF_Data = lADTFile.GetPointer(lCurrentPosition + 8); lID = 0; for (auto const& object : lObjectInstances) @@ -864,7 +867,7 @@ void MapTile::saveTile(World* world) SetChunkHeader(lADTFile, lCurrentPosition, 'MFBO', static_cast(chunkSize)); lADTFile.GetPointer(lMHDR_Position + 8)->mfbo = lCurrentPosition - 0x14; - int16_t *lMFBO_Data = lADTFile.GetPointer(lCurrentPosition + 8); + auto const lMFBO_Data = lADTFile.GetPointer(lCurrentPosition + 8); lID = 0; @@ -883,9 +886,9 @@ void MapTile::saveTile(World* world) //! \todo check if nTexEffects == nTextures, correct order etc. lADTFile.Extend(8 + 4 * mTextureEffects.size()); SetChunkHeader(lADTFile, lCurrentPosition, 'MTFX', 4 * mTextureEffects.size()); - lADTFile.GetPointer(lMHDR_Position + 8)->mtfx = lCurrentPosition - 0x14; + lADTFile.GetPointer(lMHDR_Position + 8)->mtxf = lCurrentPosition - 0x14; - uint32_t* lMTFX_Data = lADTFile.GetPointer(lCurrentPosition + 8); + auto const lMTFX_Data = lADTFile.GetPointer(lCurrentPosition + 8); lID = 0; //they should be in the correct order... @@ -898,13 +901,12 @@ void MapTile::saveTile(World* world) } #endif - lADTFile.Extend(static_cast(lCurrentPosition - lADTFile.data.size())); // cleaning unused nulls at the end of file - - { BlizzardArchive::ClientFile f(_file_key.filepath(), Noggit::Application::NoggitApplication::instance()->clientData() , BlizzardArchive::ClientFile::NEW_FILE); - f.setBuffer(lADTFile.data); + // \todo This sounds wrong. There shouldn't *be* unused nulls to + // begin with. + f.setBuffer(lADTFile.data_up_to(lCurrentPosition)); // cleaning unused nulls at the end of file f.save(); } diff --git a/src/noggit/Misc.cpp b/src/noggit/Misc.cpp index 0cc2d8fc..34f015ab 100755 --- a/src/noggit/Misc.cpp +++ b/src/noggit/Misc.cpp @@ -208,9 +208,9 @@ namespace misc } } -void SetChunkHeader(sExtendableArray& pArray, int pPosition, int pMagix, int pSize) +void SetChunkHeader(util::sExtendableArray& pArray, int pPosition, int pMagix, int pSize) { - sChunkHeader* Header = pArray.GetPointer(pPosition); + auto const Header = pArray.GetPointer(pPosition); Header->mMagic = pMagix; Header->mSize = pSize; } diff --git a/src/noggit/Misc.h b/src/noggit/Misc.h index 9677fca6..ca5d941a 100755 --- a/src/noggit/Misc.h +++ b/src/noggit/Misc.h @@ -13,6 +13,7 @@ #include #include #include +#include // namespace for static helper functions. @@ -119,49 +120,11 @@ namespace misc //! \todo collect all lose functions/classes/structs for now, sort them later -class sExtendableArray -{ -public: - std::vector data; - - void Allocate (unsigned long pSize) - { - data.resize (pSize); - } - - void Extend (long pAddition) - { - data.resize (data.size() + pAddition); - } - - void Insert (unsigned long pPosition, unsigned long pAddition) - { - std::vector tmp (pAddition); - data.insert (data.begin() + pPosition, tmp.begin(), tmp.end()); - } - - void Insert (unsigned long pPosition, unsigned long pAddition, const char * pAdditionalData) - { - data.insert (data.begin() + pPosition, pAdditionalData, pAdditionalData + pAddition); - } - - template - To * GetPointer(unsigned long pPosition = 0) - { - return(reinterpret_cast(data.data() + pPosition)); - } - - sExtendableArray() = default; - sExtendableArray(unsigned long pSize, const char *pData) - : data (pData, pData + pSize) - {} -}; - struct sChunkHeader { int mMagic; int mSize; }; -void SetChunkHeader(sExtendableArray& pArray, int pPosition, int pMagix, int pSize = 0); +void SetChunkHeader(util::sExtendableArray& pArray, int pPosition, int pMagix, int pSize = 0); diff --git a/src/noggit/TileWater.cpp b/src/noggit/TileWater.cpp index 29abc6a1..c0d6ae5f 100755 --- a/src/noggit/TileWater.cpp +++ b/src/noggit/TileWater.cpp @@ -59,7 +59,20 @@ void TileWater::autoGen(float factor) } } -void TileWater::saveToFile(sExtendableArray &lADTFile, int &lMHDR_Position, int &lCurrentPosition) +void TileWater::update_underground_vertices_depth() +{ + tagUpdate(); + + for (int z = 0; z < 16; ++z) + { + for (int x = 0; x < 16; ++x) + { + chunks[z][x]->update_underground_vertices_depth(tile->getChunk(x, z)); + } + } +} + +void TileWater::saveToFile(util::sExtendableArray &lADTFile, int &lMHDR_Position, int &lCurrentPosition) { if (!hasData(0)) { diff --git a/src/noggit/TileWater.hpp b/src/noggit/TileWater.hpp index 398e922f..53b90d55 100755 --- a/src/noggit/TileWater.hpp +++ b/src/noggit/TileWater.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -15,7 +16,6 @@ class MapTile; class liquid_layer; -class sExtendableArray; enum LiquidLayerUpdateFlags; namespace BlizzardArchive @@ -39,7 +39,7 @@ public: ChunkWater* getChunk(int x, int z); void readFromFile(BlizzardArchive::ClientFile& theFile, size_t basePos); - void saveToFile(sExtendableArray& lADTFile, int& lMHDR_Position, int& lCurrentPosition); + void saveToFile(util::sExtendableArray& lADTFile, int& lMHDR_Position, int& lCurrentPosition); void draw ( math::frustum const& frustum , const glm::vec3& camera diff --git a/src/noggit/liquid_layer.cpp b/src/noggit/liquid_layer.cpp index ca286182..efba81e8 100755 --- a/src/noggit/liquid_layer.cpp +++ b/src/noggit/liquid_layer.cpp @@ -261,7 +261,7 @@ void liquid_layer::create_vertices(float height) } } -void liquid_layer::save(sExtendableArray& adt, int base_pos, int& info_pos, int& current_pos) const +void liquid_layer::save(util::sExtendableArray& adt, int base_pos, int& info_pos, int& current_pos) const { int min_x = 9, min_z = 9, max_x = 0, max_z = 0; bool filled = true; @@ -334,7 +334,7 @@ void liquid_layer::save(sExtendableArray& adt, int base_pos, int& info_pos, int& { for (int x = info.xOffset; x <= info.xOffset + info.width; ++x) { - memcpy(adt.GetPointer(current_pos), &_vertices[z * 9 + x].position.y, sizeof(float)); + memcpy(adt.GetPointer(current_pos).get(), &_vertices[z * 9 + x].position.y, sizeof(float)); current_pos += sizeof(float); } } @@ -357,7 +357,7 @@ void liquid_layer::save(sExtendableArray& adt, int base_pos, int& info_pos, int& uv.x = static_cast(std::min(_vertices[z * 9 + x].uv.x * 255.f, 65535.f)); uv.y = static_cast(std::min(_vertices[z * 9 + x].uv.y * 255.f, 65535.f)); - memcpy(adt.GetPointer(current_pos), &uv, sizeof(mh2o_uv)); + memcpy(adt.GetPointer(current_pos).get(), &uv, sizeof(mh2o_uv)); current_pos += sizeof(mh2o_uv); } } @@ -372,13 +372,13 @@ void liquid_layer::save(sExtendableArray& adt, int base_pos, int& info_pos, int& for (int x = info.xOffset; x <= info.xOffset + info.width; ++x) { std::uint8_t depth = static_cast(std::min(_vertices[z * 9 + x].depth * 255.0f, 255.f)); - memcpy(adt.GetPointer(current_pos), &depth, sizeof(std::uint8_t)); + memcpy(adt.GetPointer(current_pos).get(), &depth, sizeof(std::uint8_t)); current_pos += sizeof(std::uint8_t); } } } - memcpy(adt.GetPointer(info_pos), &info, sizeof(MH2O_Information)); + memcpy(adt.GetPointer(info_pos).get(), &info, sizeof(MH2O_Information)); info_pos += sizeof(MH2O_Information); } diff --git a/src/noggit/liquid_layer.hpp b/src/noggit/liquid_layer.hpp index a60dadf0..e6bff468 100755 --- a/src/noggit/liquid_layer.hpp +++ b/src/noggit/liquid_layer.hpp @@ -7,9 +7,9 @@ #include #include #include +#include class MapChunk; -class sExtendableArray; class ChunkWater; enum LiquidLayerUpdateFlags @@ -59,7 +59,7 @@ public: liquid_layer& operator=(liquid_layer&&); liquid_layer& operator=(liquid_layer const& other); - void save(sExtendableArray& adt, int base_pos, int& info_pos, int& current_pos) const; + void save(util::sExtendableArray& adt, int base_pos, int& info_pos, int& current_pos) const; void update_attributes(MH2O_Attributes& attributes); void changeLiquidID(int id); diff --git a/src/noggit/map_horizon.cpp b/src/noggit/map_horizon.cpp index cb95fe38..4a085687 100755 --- a/src/noggit/map_horizon.cpp +++ b/src/noggit/map_horizon.cpp @@ -365,7 +365,7 @@ void map_horizon::save_wdl(World* world, bool regenerate) filename << "World\\Maps\\" << world->basename << "\\" << world->basename << ".wdl"; //Log << "Saving WDL \"" << filename << "\"." << std::endl; - sExtendableArray wdlFile = sExtendableArray(); + util::sExtendableArray wdlFile; int curPos = 0; // MVER @@ -475,7 +475,7 @@ void map_horizon::save_wdl(World* world, bool regenerate) } BlizzardArchive::ClientFile f(filename.str(), Noggit::Application::NoggitApplication::instance()->clientData(), BlizzardArchive::ClientFile::NEW_FILE); - f.setBuffer(wdlFile.data); + f.setBuffer(wdlFile.all_data()); f.save(); f.close(); diff --git a/src/noggit/map_index.cpp b/src/noggit/map_index.cpp index 7c59a3c6..039735b2 100755 --- a/src/noggit/map_index.cpp +++ b/src/noggit/map_index.cpp @@ -190,7 +190,7 @@ void MapIndex::save() //Log << "Saving WDT \"" << filename << "\"." << std::endl; - sExtendableArray wdtFile = sExtendableArray(); + util::sExtendableArray wdtFile; int curPos = 0; // MVER @@ -266,7 +266,7 @@ void MapIndex::save() BlizzardArchive::ClientFile f(filename.str(), Noggit::Application::NoggitApplication::instance()->clientData(), BlizzardArchive::ClientFile::NEW_FILE); - f.setBuffer(wdtFile.data); + f.setBuffer(wdtFile.all_data()); f.save(); f.close(); @@ -1240,7 +1240,7 @@ void MapIndex::create_empty_wdl() const filename << "World\\Maps\\" << basename << "\\" << basename << ".wdl"; // mapIndex.basename ? //Log << "Saving WDL \"" << filename << "\"." << std::endl; - sExtendableArray wdlFile = sExtendableArray(); + util::sExtendableArray wdlFile; int curPos = 0; // MVER @@ -1340,7 +1340,7 @@ void MapIndex::create_empty_wdl() const BlizzardArchive::ClientFile f(filename.str(), Noggit::Application::NoggitApplication::instance()->clientData(), BlizzardArchive::ClientFile::NEW_FILE); - f.setBuffer(wdlFile.data); + f.setBuffer(wdlFile.all_data()); f.save(); f.close(); } diff --git a/src/util/sExtendableArray.cpp b/src/util/sExtendableArray.cpp new file mode 100644 index 00000000..d5f00502 --- /dev/null +++ b/src/util/sExtendableArray.cpp @@ -0,0 +1,35 @@ +// This file is part of Noggit3, licensed under GNU General Public License (version 3). + +#include + +namespace util +{ + void sExtendableArray::Extend (long pAddition) + { + data.resize (data.size() + pAddition); + } + + void sExtendableArray::Insert (unsigned long pPosition, unsigned long pAddition) + { + std::vector tmp (pAddition); + data.insert (data.begin() + pPosition, tmp.begin(), tmp.end()); + } + + void sExtendableArray::Insert (unsigned long pPosition, unsigned long pAddition, const char * pAdditionalData) + { + data.insert (data.begin() + pPosition, pAdditionalData, pAdditionalData + pAddition); + } + + std::vector sExtendableArray::all_data() const + { + return data_up_to (data.size()); + } + std::vector sExtendableArray::data_up_to (std::size_t position) const + { + return std::vector (data.begin(), data.begin() + position); + } + + sExtendableArray::sExtendableArray(unsigned long pSize, const char *pData) + : data (pData, pData + pSize) + {} +} diff --git a/src/util/sExtendableArray.hpp b/src/util/sExtendableArray.hpp new file mode 100644 index 00000000..45383a84 --- /dev/null +++ b/src/util/sExtendableArray.hpp @@ -0,0 +1,52 @@ +// This file is part of Noggit3, licensed under GNU General Public License (version 3). + +#pragma once + +#include + +namespace util +{ + //! \todo This name is horrible. The API is mediocre. + class sExtendableArray + { + std::vector data; + + public: + //! Equivalent to `Allocate ($size + pAddition)`. + void Extend (long pAddition); + + //! At \a pPosition, insert \a pAddition bytes that are all '\0', + //! moving existing data further back. + void Insert (unsigned long pPosition, unsigned long pAddition); + + //! At \a pPosition, insert \a pAddition bytes with the data at \a + //! pAdditionalData, moving existing data further back. + void Insert (unsigned long pPosition, unsigned long pAddition, const char * pAdditionalData); + + template + struct LazyPointer + { + LazyPointer (std::vector& data, std::size_t position); + T* get() const; + T& operator*() const; + T* operator->() const; + T& operator[] (std::size_t) const; + LazyPointer& operator+= (std::size_t); + + private: + std::vector& _data; + std::size_t _position; + }; + + template + LazyPointer GetPointer(unsigned long pPosition = 0); + + std::vector all_data() const; + std::vector data_up_to (std::size_t position) const; + + sExtendableArray() = default; + sExtendableArray(unsigned long pSize, const char *pData); + }; +} + +#include diff --git a/src/util/sExtendableArray.ipp b/src/util/sExtendableArray.ipp new file mode 100644 index 00000000..03807675 --- /dev/null +++ b/src/util/sExtendableArray.ipp @@ -0,0 +1,47 @@ +// This file is part of Noggit3, licensed under GNU General Public License (version 3). + +namespace util +{ + template + sExtendableArray::LazyPointer sExtendableArray::GetPointer + (unsigned long pPosition) + { + return {data, pPosition}; + } + + template + sExtendableArray::LazyPointer::LazyPointer + (std::vector& data, std::size_t position) + : _data (data) + , _position (position) + {} + + template + T* sExtendableArray::LazyPointer::get() const + { + return reinterpret_cast (_data.data() + _position); + } + template + T& sExtendableArray::LazyPointer::operator*() const + { + return *get(); + } + template + T* sExtendableArray::LazyPointer::operator->() const + { + return get(); + } + template + T& sExtendableArray::LazyPointer::operator[] (std::size_t i) const + { + return *(get() + i); + } + + template + sExtendableArray::LazyPointer& + sExtendableArray::LazyPointer::operator+= (std::size_t num) + { + _position += num * sizeof (T); + return *this; + } +}