Noggit3 : extendable array: prevent use after extend
https://github.com/wowdev/noggit3/pull/91
+ adspartan mapchunk: store pointer to the header when saving f7e5f8396f
This commit is contained in:
@@ -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<char>(header_pos), &header, sizeof(MH2O_Header));
|
||||
memcpy(adt.GetPointer<char>(header_pos).get(), &header, sizeof(MH2O_Header));
|
||||
header_pos += sizeof(MH2O_Header);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
#include <noggit/liquid_layer.hpp>
|
||||
#include <noggit/MapHeaders.h>
|
||||
#include <noggit/tool_enums.hpp>
|
||||
#include <util/sExtendableArray.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <optional>
|
||||
|
||||
class sExtendableArray;
|
||||
class MapChunk;
|
||||
class TileWater;
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
|
||||
void from_mclq(std::vector<mclq>& 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
|
||||
|
||||
@@ -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<std::string, int> &lTextures
|
||||
@@ -1443,7 +1443,7 @@ void MapChunk::save(sExtendableArray& lADTFile
|
||||
|
||||
// MCNK data
|
||||
// lADTFile.Insert(lCurrentPosition + 8, 0x80, reinterpret_cast<char*>(&(header)));
|
||||
MapChunkHeader *lMCNK_header = lADTFile.GetPointer<MapChunkHeader>(lCurrentPosition + 8);
|
||||
auto const lMCNK_header = lADTFile.GetPointer<MapChunkHeader>(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<MapChunkHeader>(lMCNK_Position + 8)->ofsHeight = lCurrentPosition - lMCNK_Position;
|
||||
// lADTFile.GetPointer<MapChunkHeader>(lMCNK_Position + 8)->ofsHeight = lCurrentPosition - lMCNK_Position;
|
||||
|
||||
float* lHeightmap = lADTFile.GetPointer<float>(lCurrentPosition + 8);
|
||||
auto header_ptr = lADTFile.GetPointer<MapChunkHeader>(lMCNK_Position + 8);
|
||||
|
||||
header_ptr->ofsHeight = lCurrentPosition - lMCNK_Position;
|
||||
|
||||
auto const lHeightmap = lADTFile.GetPointer<float>(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<MapChunkHeader>(lMCNK_Position + 8)->ofsMCCV = lCurrentPosition - lMCNK_Position;
|
||||
header_ptr->ofsMCCV = lCurrentPosition - lMCNK_Position;
|
||||
|
||||
unsigned int *lmccv = lADTFile.GetPointer<unsigned int>(lCurrentPosition + 8);
|
||||
auto const lmccv = lADTFile.GetPointer<unsigned int>(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<MapChunkHeader>(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<MapChunkHeader>(lMCNK_Position + 8)->ofsNormal = lCurrentPosition - lMCNK_Position;
|
||||
header_ptr->ofsNormal = lCurrentPosition - lMCNK_Position;
|
||||
|
||||
char * lNormals = lADTFile.GetPointer<char>(lCurrentPosition + 8);
|
||||
auto const lNormals = lADTFile.GetPointer<char>(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<long>(8 + lMCLY_Size));
|
||||
SetChunkHeader(lADTFile, lCurrentPosition, 'MCLY', static_cast<int>(lMCLY_Size));
|
||||
|
||||
lADTFile.GetPointer<MapChunkHeader>(lMCNK_Position + 8)->ofsLayer = lCurrentPosition - lMCNK_Position;
|
||||
lADTFile.GetPointer<MapChunkHeader>(lMCNK_Position + 8)->nLayers = texture_set ? static_cast<std::uint32_t>(texture_set->num()) : 0;
|
||||
header_ptr->ofsLayer = lCurrentPosition - lMCNK_Position;
|
||||
header_ptr->nLayers = texture_set ? static_cast<std::uint32_t>(texture_set->num()) : 0;
|
||||
|
||||
std::vector<std::vector<uint8_t>> 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<ENTRY_MCLY>(lCurrentPosition + 8 + 0x10 * static_cast<unsigned long>(j));
|
||||
auto const lLayer = lADTFile.GetPointer<ENTRY_MCLY>(lCurrentPosition + 8 + 0x10 * static_cast<unsigned long>(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<MapChunkHeader>(lMCNK_Position + 8)->ofsRefs = lCurrentPosition - lMCNK_Position;
|
||||
lADTFile.GetPointer<MapChunkHeader>(lMCNK_Position + 8)->nDoodadRefs = static_cast<std::uint32_t>(lDoodadIDs.size());
|
||||
lADTFile.GetPointer<MapChunkHeader>(lMCNK_Position + 8)->nMapObjRefs = static_cast<std::uint32_t>(lObjectIDs.size());
|
||||
header_ptr->ofsRefs = lCurrentPosition - lMCNK_Position;
|
||||
header_ptr->nDoodadRefs = static_cast<std::uint32_t>(lDoodadIDs.size());
|
||||
header_ptr->nMapObjRefs = static_cast<std::uint32_t>(lObjectIDs.size());
|
||||
|
||||
// MCRF data
|
||||
int *lReferences = lADTFile.GetPointer<int>(lCurrentPosition + 8);
|
||||
auto const lReferences = lADTFile.GetPointer<int>(lCurrentPosition + 8);
|
||||
|
||||
lID = 0;
|
||||
for (std::list<int>::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<MapChunkHeader>(lMCNK_Position + 8)->ofsShadow = lCurrentPosition - lMCNK_Position;
|
||||
lADTFile.GetPointer<MapChunkHeader>(lMCNK_Position + 8)->sizeShadow = 0x200;
|
||||
header_ptr->ofsShadow = lCurrentPosition - lMCNK_Position;
|
||||
header_ptr->sizeShadow = 0x200;
|
||||
|
||||
char * lLayer = lADTFile.GetPointer<char>(lCurrentPosition + 8);
|
||||
auto const lLayer = lADTFile.GetPointer<char>(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<MapChunkHeader>(lMCNK_Position + 8)->ofsShadow = 0;
|
||||
lADTFile.GetPointer<MapChunkHeader>(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<MapChunkHeader>(lMCNK_Position + 8)->ofsAlpha = lCurrentPosition - lMCNK_Position;
|
||||
lADTFile.GetPointer<MapChunkHeader>(lMCNK_Position + 8)->sizeAlpha = 8 + lMCAL_Size;
|
||||
header_ptr->ofsAlpha = lCurrentPosition - lMCNK_Position;
|
||||
header_ptr->sizeAlpha = 8 + lMCAL_Size;
|
||||
|
||||
char * lAlphaMaps = lADTFile.GetPointer<char>(lCurrentPosition + 8);
|
||||
auto lAlphaMaps = lADTFile.GetPointer<char>(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<MapChunkHeader>(lMCNK_Position + 8)->ofsSndEmitters = lCurrentPosition - lMCNK_Position;
|
||||
lADTFile.GetPointer<MapChunkHeader>(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<ENTRY_MCSE>(lCurrentPosition);
|
||||
auto const MCSE = lADTFile.GetPointer<ENTRY_MCSE>(lCurrentPosition);
|
||||
|
||||
MCSE->soundId = sound_emitter.soundId;
|
||||
|
||||
|
||||
@@ -3,16 +3,19 @@
|
||||
#pragma once
|
||||
#include <noggit/map_enums.hpp>
|
||||
#include <noggit/MapTile.h> // MapTile
|
||||
#include <noggit/Misc.h>
|
||||
#include <noggit/ModelInstance.h>
|
||||
#include <noggit/Selection.h>
|
||||
#include <noggit/TextureManager.h>
|
||||
#include <noggit/WMOInstance.h>
|
||||
#include <noggit/map_enums.hpp>
|
||||
#include <noggit/texture_set.hpp>
|
||||
#include <noggit/tool_enums.hpp>
|
||||
#include <noggit/ContextObject.hpp>
|
||||
#include <opengl/scoped.hpp>
|
||||
#include <opengl/texture.hpp>
|
||||
#include <noggit/Misc.h>
|
||||
#include <util/sExtendableArray.hpp>
|
||||
|
||||
#include <optional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@@ -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<std::string, int> &lTextures
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <opengl/shader.hpp>
|
||||
#include <external/tracy/Tracy.hpp>
|
||||
#include <util/CurrentFunction.hpp>
|
||||
#include <util/sExtendableArray.hpp>
|
||||
|
||||
#include <noggit/World.inl>
|
||||
#include <QtCore/QSettings>
|
||||
@@ -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<int>(lCurrentPosition + 8);
|
||||
auto const lMMID_Data = lADTFile.GetPointer<int>(lCurrentPosition + 8);
|
||||
|
||||
lID = 0;
|
||||
for (auto const& model : lModels)
|
||||
@@ -744,7 +747,7 @@ void MapTile::saveTile(World* world)
|
||||
lADTFile.GetPointer<MHDR>(lMHDR_Position + 8)->mwid = lCurrentPosition - 0x14;
|
||||
|
||||
// MWID data
|
||||
int * lMWID_Data = lADTFile.GetPointer<int>(lCurrentPosition + 8);
|
||||
auto const lMWID_Data = lADTFile.GetPointer<int>(lCurrentPosition + 8);
|
||||
|
||||
lID = 0;
|
||||
for (auto const& object : lObjects)
|
||||
@@ -759,7 +762,7 @@ void MapTile::saveTile(World* world)
|
||||
lADTFile.GetPointer<MHDR>(lMHDR_Position + 8)->mddf = lCurrentPosition - 0x14;
|
||||
|
||||
// MDDF data
|
||||
ENTRY_MDDF* lMDDF_Data = lADTFile.GetPointer<ENTRY_MDDF>(lCurrentPosition + 8);
|
||||
auto const lMDDF_Data = lADTFile.GetPointer<ENTRY_MDDF>(lCurrentPosition + 8);
|
||||
|
||||
if(world->mapIndex.sort_models_by_size_class())
|
||||
{
|
||||
@@ -803,7 +806,7 @@ void MapTile::saveTile(World* world)
|
||||
lADTFile.GetPointer<MHDR>(lMHDR_Position + 8)->modf = lCurrentPosition - 0x14;
|
||||
|
||||
// MODF data
|
||||
ENTRY_MODF *lMODF_Data = lADTFile.GetPointer<ENTRY_MODF>(lCurrentPosition + 8);
|
||||
auto const lMODF_Data = lADTFile.GetPointer<ENTRY_MODF>(lCurrentPosition + 8);
|
||||
|
||||
lID = 0;
|
||||
for (auto const& object : lObjectInstances)
|
||||
@@ -864,7 +867,7 @@ void MapTile::saveTile(World* world)
|
||||
SetChunkHeader(lADTFile, lCurrentPosition, 'MFBO', static_cast<int>(chunkSize));
|
||||
lADTFile.GetPointer<MHDR>(lMHDR_Position + 8)->mfbo = lCurrentPosition - 0x14;
|
||||
|
||||
int16_t *lMFBO_Data = lADTFile.GetPointer<int16_t>(lCurrentPosition + 8);
|
||||
auto const lMFBO_Data = lADTFile.GetPointer<int16_t>(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<MHDR>(lMHDR_Position + 8)->mtfx = lCurrentPosition - 0x14;
|
||||
lADTFile.GetPointer<MHDR>(lMHDR_Position + 8)->mtxf = lCurrentPosition - 0x14;
|
||||
|
||||
uint32_t* lMTFX_Data = lADTFile.GetPointer<uint32_t>(lCurrentPosition + 8);
|
||||
auto const lMTFX_Data = lADTFile.GetPointer<uint32_t>(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<long>(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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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<sChunkHeader>(pPosition);
|
||||
auto const Header = pArray.GetPointer<sChunkHeader>(pPosition);
|
||||
Header->mMagic = pMagix;
|
||||
Header->mSize = pSize;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <glm/vec4.hpp>
|
||||
#include <glm/vec2.hpp>
|
||||
#include <noggit/Selection.h>
|
||||
#include <util/sExtendableArray.hpp>
|
||||
|
||||
|
||||
// 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<char> 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<char> 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<typename To>
|
||||
To * GetPointer(unsigned long pPosition = 0)
|
||||
{
|
||||
return(reinterpret_cast<To*>(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);
|
||||
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <opengl/types.hpp>
|
||||
#include <noggit/rendering/LiquidTextureManager.hpp>
|
||||
#include <noggit/rendering/LiquidRender.hpp>
|
||||
#include <util/sExtendableArray.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
@@ -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
|
||||
|
||||
@@ -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<char>(current_pos), &_vertices[z * 9 + x].position.y, sizeof(float));
|
||||
memcpy(adt.GetPointer<char>(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::uint16_t>(std::min(_vertices[z * 9 + x].uv.x * 255.f, 65535.f));
|
||||
uv.y = static_cast<std::uint16_t>(std::min(_vertices[z * 9 + x].uv.y * 255.f, 65535.f));
|
||||
|
||||
memcpy(adt.GetPointer<char>(current_pos), &uv, sizeof(mh2o_uv));
|
||||
memcpy(adt.GetPointer<char>(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::uint8_t>(std::min(_vertices[z * 9 + x].depth * 255.0f, 255.f));
|
||||
memcpy(adt.GetPointer<char>(current_pos), &depth, sizeof(std::uint8_t));
|
||||
memcpy(adt.GetPointer<char>(current_pos).get(), &depth, sizeof(std::uint8_t));
|
||||
current_pos += sizeof(std::uint8_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(adt.GetPointer<char>(info_pos), &info, sizeof(MH2O_Information));
|
||||
memcpy(adt.GetPointer<char>(info_pos).get(), &info, sizeof(MH2O_Information));
|
||||
info_pos += sizeof(MH2O_Information);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
#include <opengl/scoped.hpp>
|
||||
#include <array>
|
||||
#include <glm/vec2.hpp>
|
||||
#include <util/sExtendableArray.hpp>
|
||||
|
||||
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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
35
src/util/sExtendableArray.cpp
Normal file
35
src/util/sExtendableArray.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include <util/sExtendableArray.hpp>
|
||||
|
||||
namespace util
|
||||
{
|
||||
void sExtendableArray::Extend (long pAddition)
|
||||
{
|
||||
data.resize (data.size() + pAddition);
|
||||
}
|
||||
|
||||
void sExtendableArray::Insert (unsigned long pPosition, unsigned long pAddition)
|
||||
{
|
||||
std::vector<char> 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<char> sExtendableArray::all_data() const
|
||||
{
|
||||
return data_up_to (data.size());
|
||||
}
|
||||
std::vector<char> sExtendableArray::data_up_to (std::size_t position) const
|
||||
{
|
||||
return std::vector<char> (data.begin(), data.begin() + position);
|
||||
}
|
||||
|
||||
sExtendableArray::sExtendableArray(unsigned long pSize, const char *pData)
|
||||
: data (pData, pData + pSize)
|
||||
{}
|
||||
}
|
||||
52
src/util/sExtendableArray.hpp
Normal file
52
src/util/sExtendableArray.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace util
|
||||
{
|
||||
//! \todo This name is horrible. The API is mediocre.
|
||||
class sExtendableArray
|
||||
{
|
||||
std::vector<char> 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<typename T>
|
||||
struct LazyPointer
|
||||
{
|
||||
LazyPointer (std::vector<char>& data, std::size_t position);
|
||||
T* get() const;
|
||||
T& operator*() const;
|
||||
T* operator->() const;
|
||||
T& operator[] (std::size_t) const;
|
||||
LazyPointer<T>& operator+= (std::size_t);
|
||||
|
||||
private:
|
||||
std::vector<char>& _data;
|
||||
std::size_t _position;
|
||||
};
|
||||
|
||||
template<typename To>
|
||||
LazyPointer<To> GetPointer(unsigned long pPosition = 0);
|
||||
|
||||
std::vector<char> all_data() const;
|
||||
std::vector<char> data_up_to (std::size_t position) const;
|
||||
|
||||
sExtendableArray() = default;
|
||||
sExtendableArray(unsigned long pSize, const char *pData);
|
||||
};
|
||||
}
|
||||
|
||||
#include <util/sExtendableArray.ipp>
|
||||
47
src/util/sExtendableArray.ipp
Normal file
47
src/util/sExtendableArray.ipp
Normal file
@@ -0,0 +1,47 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
namespace util
|
||||
{
|
||||
template<typename To>
|
||||
sExtendableArray::LazyPointer<To> sExtendableArray::GetPointer
|
||||
(unsigned long pPosition)
|
||||
{
|
||||
return {data, pPosition};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
sExtendableArray::LazyPointer<T>::LazyPointer
|
||||
(std::vector<char>& data, std::size_t position)
|
||||
: _data (data)
|
||||
, _position (position)
|
||||
{}
|
||||
|
||||
template<typename T>
|
||||
T* sExtendableArray::LazyPointer<T>::get() const
|
||||
{
|
||||
return reinterpret_cast<T*> (_data.data() + _position);
|
||||
}
|
||||
template<typename T>
|
||||
T& sExtendableArray::LazyPointer<T>::operator*() const
|
||||
{
|
||||
return *get();
|
||||
}
|
||||
template<typename T>
|
||||
T* sExtendableArray::LazyPointer<T>::operator->() const
|
||||
{
|
||||
return get();
|
||||
}
|
||||
template<typename T>
|
||||
T& sExtendableArray::LazyPointer<T>::operator[] (std::size_t i) const
|
||||
{
|
||||
return *(get() + i);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
sExtendableArray::LazyPointer<T>&
|
||||
sExtendableArray::LazyPointer<T>::operator+= (std::size_t num)
|
||||
{
|
||||
_position += num * sizeof (T);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user