implement sound emitters load/save
rework chunk loading classes to be temporary
This commit is contained in:
@@ -43,19 +43,19 @@ MapChunk::MapChunk(MapTile* maintile, BlizzardArchive::ClientFile* f, bool bigAl
|
||||
if (init_empty)
|
||||
{
|
||||
|
||||
header.flags = 0;
|
||||
px = header.ix = chunk_idx / 16;
|
||||
py = header.iy = chunk_idx % 16;
|
||||
// header.flags = 0;
|
||||
px = chunk_idx / 16;
|
||||
py = chunk_idx % 16;
|
||||
|
||||
header.zpos = ZEROPOINT - (maintile->zbase + py * CHUNKSIZE);
|
||||
header.xpos = ZEROPOINT - (maintile->xbase + px * CHUNKSIZE);
|
||||
header.ypos = 0.0f;
|
||||
zbase = ZEROPOINT - (maintile->zbase + py * CHUNKSIZE);
|
||||
xbase = ZEROPOINT - (maintile->xbase + px * CHUNKSIZE);
|
||||
ybase = 0.0f;
|
||||
|
||||
areaID = header.areaid = 0;
|
||||
areaID = 0;
|
||||
|
||||
zbase = header.zpos;
|
||||
xbase = header.xpos;
|
||||
ybase = header.ypos;
|
||||
// zbase = header.zpos;
|
||||
// xbase = header.xpos;
|
||||
// ybase = header.ypos;
|
||||
|
||||
texture_set = nullptr;
|
||||
|
||||
@@ -108,7 +108,6 @@ MapChunk::MapChunk(MapTile* maintile, BlizzardArchive::ClientFile* f, bool bigAl
|
||||
|
||||
// use absolute y pos in vertices
|
||||
ybase = 0.0f;
|
||||
header.ypos = 0.0f;
|
||||
|
||||
vcenter = (vmin + vmax) * 0.5f;
|
||||
|
||||
@@ -123,6 +122,8 @@ MapChunk::MapChunk(MapTile* maintile, BlizzardArchive::ClientFile* f, bool bigAl
|
||||
|
||||
hasMCCV = false;
|
||||
|
||||
MapChunkHeader tmp_chunk_header;
|
||||
|
||||
// - MCNK ----------------------------------------------
|
||||
{
|
||||
f->read(&fourcc, 4);
|
||||
@@ -130,36 +131,40 @@ MapChunk::MapChunk(MapTile* maintile, BlizzardArchive::ClientFile* f, bool bigAl
|
||||
|
||||
assert(fourcc == 'MCNK');
|
||||
|
||||
f->read(&header, 0x80);
|
||||
|
||||
header_flags.value = header.flags;
|
||||
areaID = header.areaid;
|
||||
|
||||
zbase = header.zpos;
|
||||
xbase = header.xpos;
|
||||
ybase = header.ypos;
|
||||
f->read(&tmp_chunk_header, sizeof(MapChunkHeader));
|
||||
|
||||
px = header.ix;
|
||||
py = header.iy;
|
||||
header_flags.value = tmp_chunk_header.flags;
|
||||
areaID = tmp_chunk_header.areaid;
|
||||
|
||||
holes = header.holes;
|
||||
zbase = tmp_chunk_header.zpos;
|
||||
xbase = tmp_chunk_header.xpos;
|
||||
ybase = tmp_chunk_header.ypos;
|
||||
|
||||
px = tmp_chunk_header.ix;
|
||||
py = tmp_chunk_header.iy;
|
||||
|
||||
holes = tmp_chunk_header.holes;
|
||||
|
||||
// correct the x and z values ^_^
|
||||
zbase = zbase*-1.0f + ZEROPOINT;
|
||||
xbase = xbase*-1.0f + ZEROPOINT;
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (!load_textures)
|
||||
{
|
||||
this->header.nLayers = 0;
|
||||
tmp_chunk_header.nLayers = 0;
|
||||
}
|
||||
|
||||
texture_set = std::make_unique<TextureSet>(this, f, base, maintile, bigAlpha,
|
||||
!!header_flags.flags.do_not_fix_alpha_map, mode == tile_mode::uid_fix_all, _context);
|
||||
!!header_flags.flags.do_not_fix_alpha_map, mode == tile_mode::uid_fix_all, _context, tmp_chunk_header);
|
||||
|
||||
// - MCVT ----------------------------------------------
|
||||
{
|
||||
f->seek(base + header.ofsHeight);
|
||||
f->seek(base + tmp_chunk_header.ofsHeight);
|
||||
f->read(&fourcc, 4);
|
||||
f->read(&size, 4);
|
||||
|
||||
@@ -193,11 +198,11 @@ MapChunk::MapChunk(MapTile* maintile, BlizzardArchive::ClientFile* f, bool bigAl
|
||||
|
||||
// use absolute y pos in vertices
|
||||
ybase = 0.0f;
|
||||
header.ypos = 0.0f;
|
||||
tmp_chunk_header.ypos = 0.0f;
|
||||
}
|
||||
// - MCNR ----------------------------------------------
|
||||
{
|
||||
f->seek(base + header.ofsNormal);
|
||||
f->seek(base + tmp_chunk_header.ofsNormal);
|
||||
f->read(&fourcc, 4);
|
||||
f->read(&size, 4);
|
||||
|
||||
@@ -217,9 +222,9 @@ MapChunk::MapChunk(MapTile* maintile, BlizzardArchive::ClientFile* f, bool bigAl
|
||||
}
|
||||
}
|
||||
// - MCSH ----------------------------------------------
|
||||
if((header_flags.flags.has_mcsh) && header.ofsShadow && header.sizeShadow)
|
||||
if((header_flags.flags.has_mcsh) && tmp_chunk_header.ofsShadow && tmp_chunk_header.sizeShadow)
|
||||
{
|
||||
f->seek(base + header.ofsShadow);
|
||||
f->seek(base + tmp_chunk_header.ofsShadow);
|
||||
f->read(&fourcc, 4);
|
||||
f->read(&size, 4);
|
||||
|
||||
@@ -261,9 +266,9 @@ MapChunk::MapChunk(MapTile* maintile, BlizzardArchive::ClientFile* f, bool bigAl
|
||||
memset(_shadow_map, 0, 64 * 64);
|
||||
}
|
||||
// - MCCV ----------------------------------------------
|
||||
if(header.ofsMCCV)
|
||||
if(tmp_chunk_header.ofsMCCV)
|
||||
{
|
||||
f->seek(base + header.ofsMCCV);
|
||||
f->seek(base + tmp_chunk_header.ofsMCCV);
|
||||
f->read(&fourcc, 4);
|
||||
f->read(&size, 4);
|
||||
|
||||
@@ -292,16 +297,16 @@ MapChunk::MapChunk(MapTile* maintile, BlizzardArchive::ClientFile* f, bool bigAl
|
||||
}
|
||||
}
|
||||
|
||||
if (header.sizeLiquid > 8)
|
||||
if (tmp_chunk_header.sizeLiquid > 8)
|
||||
{
|
||||
f->seek(base + header.ofsLiquid);
|
||||
f->seek(base + tmp_chunk_header.ofsLiquid);
|
||||
|
||||
f->read(&fourcc, 4);
|
||||
f->seekRelative(4); // ignore the size here, the valid size is in the header
|
||||
|
||||
assert(fourcc == 'MCLQ');
|
||||
|
||||
int layer_count = (header.sizeLiquid - 8) / sizeof(mclq);
|
||||
int layer_count = (tmp_chunk_header.sizeLiquid - 8) / sizeof(mclq);
|
||||
std::vector<mclq> layers(layer_count);
|
||||
f->read(layers.data(), sizeof(mclq)*layer_count);
|
||||
|
||||
@@ -311,6 +316,31 @@ MapChunk::MapChunk(MapTile* maintile, BlizzardArchive::ClientFile* f, bool bigAl
|
||||
}
|
||||
|
||||
vcenter = (vmin + vmax) * 0.5f;
|
||||
|
||||
if (tmp_chunk_header.nSndEmitters)
|
||||
{
|
||||
f->seek(base + tmp_chunk_header.ofsSndEmitters);
|
||||
f->read(&fourcc, 4);
|
||||
f->read(&size, 4);
|
||||
|
||||
assert(fourcc == 'MCSE');
|
||||
|
||||
for (int i = 0; i < tmp_chunk_header.nSndEmitters; i++)
|
||||
{
|
||||
ENTRY_MCSE sound_emitter;
|
||||
f->read(&sound_emitter, sizeof(ENTRY_MCSE));
|
||||
|
||||
float pos_x = sound_emitter.pos[1] * -1.0f + ZEROPOINT;
|
||||
float pos_y = sound_emitter.pos[2];
|
||||
float pos_z = sound_emitter.pos[0] * -1.0f + ZEROPOINT;
|
||||
|
||||
sound_emitter.pos[0] = pos_x;
|
||||
sound_emitter.pos[1] = pos_y;
|
||||
sound_emitter.pos[2] = pos_z;
|
||||
|
||||
sound_emitters.emplace_back(sound_emitter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int MapChunk::indexLoD(int x, int y)
|
||||
@@ -1411,27 +1441,33 @@ void MapChunk::save(sExtendableArray& lADTFile
|
||||
lADTFile.GetPointer<MCIN>(lMCIN_Position + 8)->mEntries[py * 16 + px].offset = lCurrentPosition; // check this
|
||||
|
||||
// MCNK data
|
||||
lADTFile.Insert(lCurrentPosition + 8, 0x80, reinterpret_cast<char*>(&(header)));
|
||||
// lADTFile.Insert(lCurrentPosition + 8, 0x80, reinterpret_cast<char*>(&(header)));
|
||||
MapChunkHeader *lMCNK_header = lADTFile.GetPointer<MapChunkHeader>(lCurrentPosition + 8);
|
||||
|
||||
header_flags.flags.do_not_fix_alpha_map = 1;
|
||||
|
||||
lMCNK_header->flags = header_flags.value;
|
||||
lMCNK_header->ix = px;
|
||||
lMCNK_header->iy = py;
|
||||
lMCNK_header->zpos = zbase;
|
||||
lMCNK_header->xpos = xbase;
|
||||
lMCNK_header->ypos = ybase;
|
||||
|
||||
lMCNK_header->holes = holes;
|
||||
lMCNK_header->areaid = areaID;
|
||||
|
||||
lMCNK_header->nLayers = -1;
|
||||
lMCNK_header->nDoodadRefs = -1;
|
||||
lMCNK_header->ofsHeight = -1;
|
||||
lMCNK_header->ofsNormal = -1;
|
||||
lMCNK_header->ofsLayer = -1;
|
||||
lMCNK_header->ofsRefs = -1;
|
||||
lMCNK_header->ofsAlpha = -1;
|
||||
lMCNK_header->sizeAlpha = -1;
|
||||
lMCNK_header->ofsShadow = -1;
|
||||
lMCNK_header->sizeShadow = -1;
|
||||
lMCNK_header->nMapObjRefs = -1;
|
||||
lMCNK_header->ofsMCCV = -1;
|
||||
lMCNK_header->nLayers = 0;
|
||||
lMCNK_header->nDoodadRefs = 0;
|
||||
lMCNK_header->ofsHeight = 0;
|
||||
lMCNK_header->ofsNormal = 0;
|
||||
lMCNK_header->ofsLayer = 0;
|
||||
lMCNK_header->ofsRefs = 0;
|
||||
lMCNK_header->ofsAlpha = 0;
|
||||
lMCNK_header->sizeAlpha = 0;
|
||||
lMCNK_header->ofsShadow = 0;
|
||||
lMCNK_header->sizeShadow = 0;
|
||||
lMCNK_header->nMapObjRefs = 0;
|
||||
lMCNK_header->ofsMCCV = 0;
|
||||
|
||||
//! \todo Implement sound emitter support. Or not.
|
||||
lMCNK_header->ofsSndEmitters = 0;
|
||||
@@ -1692,14 +1728,33 @@ void MapChunk::save(sExtendableArray& lADTFile
|
||||
|
||||
|
||||
// MCSE
|
||||
int lMCSE_Size = 0;
|
||||
int lMCSE_Size = sizeof(ENTRY_MCSE) * sound_emitters.size();
|
||||
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;
|
||||
|
||||
lCurrentPosition += 8 + lMCSE_Size;
|
||||
lCurrentPosition += 8;
|
||||
|
||||
for (auto& sound_emitter : sound_emitters)
|
||||
{
|
||||
ENTRY_MCSE* MCSE = lADTFile.GetPointer<ENTRY_MCSE>(lCurrentPosition);
|
||||
|
||||
MCSE->soundId = sound_emitter.soundId;
|
||||
|
||||
MCSE->pos[0] = ZEROPOINT - sound_emitter.pos[2];
|
||||
MCSE->pos[1] = ZEROPOINT - sound_emitter.pos[0];
|
||||
MCSE->pos[2] = sound_emitter.pos[1];
|
||||
|
||||
MCSE->size[0] = sound_emitter.size[0];
|
||||
MCSE->size[1] = sound_emitter.size[1];
|
||||
MCSE->size[2] = sound_emitter.size[2];
|
||||
|
||||
lCurrentPosition += 0x1C;
|
||||
}
|
||||
|
||||
// lCurrentPosition += 8 + lMCSE_Size;
|
||||
lMCNK_Size += 8 + lMCSE_Size;
|
||||
|
||||
lADTFile.GetPointer<sChunkHeader>(lMCNK_Position)->mSize = lMCNK_Size;
|
||||
|
||||
@@ -72,7 +72,8 @@ public:
|
||||
glm::vec3 vmin, vmax, vcenter;
|
||||
int px, py;
|
||||
|
||||
MapChunkHeader header;
|
||||
// MapChunkHeader header;
|
||||
// uint32_t nLayers = 0;
|
||||
|
||||
float xbase, ybase, zbase; // global coords
|
||||
|
||||
@@ -86,6 +87,8 @@ public:
|
||||
|
||||
unsigned int areaID;
|
||||
|
||||
std::vector<ENTRY_MCSE> sound_emitters;
|
||||
|
||||
glm::vec3 mVertices[mapbufsize];
|
||||
glm::vec3 mNormals[mapbufsize];
|
||||
glm::vec3 mccv[mapbufsize]; // blizzard stores alpha, but deosn't seem to be used
|
||||
|
||||
@@ -167,10 +167,18 @@ struct MCLYFlags
|
||||
|
||||
struct ENTRY_MCLY
|
||||
{
|
||||
uint32_t textureID = 0;
|
||||
uint32_t flags = 0;
|
||||
uint32_t ofsAlpha = 0;
|
||||
uint32_t effectID = 0xFFFF; // default value, see https://wowdev.wiki/ADT/v18#MCLY_sub-chunk
|
||||
uint32_t textureID = 0;
|
||||
uint32_t flags = 0;
|
||||
uint32_t ofsAlpha = 0;
|
||||
uint32_t effectID = 0xFFFFFFFF; // default value, see https://wowdev.wiki/ADT/v18#MCLY_sub-chunk
|
||||
};
|
||||
|
||||
// sound emitters
|
||||
struct ENTRY_MCSE
|
||||
{
|
||||
uint32_t soundId; // foreign_keyⁱ<uint32_t, &SoundEntriesAdvancedRec::m_ID>
|
||||
float pos[3];
|
||||
float size[3];
|
||||
};
|
||||
|
||||
#include <string.h> // memcpy()
|
||||
|
||||
@@ -49,6 +49,9 @@ void selected_chunk_type::updateDetails(Noggit::Ui::detail_infos* detail_widget)
|
||||
|
||||
auto tile = chunk->mt;
|
||||
|
||||
bool debug_test = true;
|
||||
|
||||
if (debug_test)
|
||||
for (int chunk_x = 0; chunk_x < 16; chunk_x++)
|
||||
{
|
||||
for (int chunk_y = 0; chunk_y < 16; chunk_y++)
|
||||
@@ -119,7 +122,7 @@ void selected_chunk_type::updateDetails(Noggit::Ui::detail_infos* detail_widget)
|
||||
}
|
||||
}
|
||||
|
||||
float not_matching_percent = ((float)not_matching_count / (float)matching_count) * 100.f;
|
||||
float debug_not_matching_percent = ((float)not_matching_count / (float)matching_count) * 100.f;
|
||||
|
||||
|
||||
std::array<float, 4> weights = chunk->getTextureSet()->get_textures_weight_for_unit(unit_index.x, unit_index.y);
|
||||
|
||||
@@ -14,15 +14,13 @@
|
||||
|
||||
TextureSet::TextureSet (MapChunk* chunk, BlizzardArchive::ClientFile* f, size_t base, MapTile* tile
|
||||
, bool use_big_alphamaps, bool do_not_fix_alpha_map, bool do_not_convert_alphamaps
|
||||
, Noggit::NoggitRenderContext context)
|
||||
: nTextures(chunk->header.nLayers)
|
||||
, Noggit::NoggitRenderContext context, MapChunkHeader const& header)
|
||||
: nTextures(header.nLayers)
|
||||
, _do_not_convert_alphamaps(do_not_convert_alphamaps)
|
||||
, _context(context)
|
||||
, _chunk(chunk)
|
||||
{
|
||||
|
||||
auto& header = chunk->header;
|
||||
|
||||
std::copy(header.doodadMapping, header.doodadMapping + 8, _doodadMapping.begin());
|
||||
std::copy(header.doodadStencil, header.doodadStencil + 8, _doodadStencil.begin());
|
||||
|
||||
@@ -30,20 +28,24 @@ TextureSet::TextureSet (MapChunk* chunk, BlizzardArchive::ClientFile* f, size_t
|
||||
{
|
||||
f->seek(base + header.ofsLayer + 8);
|
||||
|
||||
ENTRY_MCLY tmp_entry_mcly[4];
|
||||
|
||||
for (size_t i = 0; i<nTextures; ++i)
|
||||
{
|
||||
f->read (&_layers_info[i], sizeof(ENTRY_MCLY));
|
||||
f->read (&tmp_entry_mcly[i], sizeof(ENTRY_MCLY)); // f->read (&_layers_info[i], sizeof(ENTRY_MCLY));
|
||||
|
||||
textures.emplace_back (tile->mTextureFilenames[_layers_info[i].textureID], _context);
|
||||
textures.emplace_back (tile->mTextureFilenames[tmp_entry_mcly[i].textureID], _context);
|
||||
_layers_info[i].effectID = tmp_entry_mcly[i].effectID;
|
||||
_layers_info[i].flags = tmp_entry_mcly[i].flags;
|
||||
}
|
||||
|
||||
size_t alpha_base = base + header.ofsAlpha + 8;
|
||||
|
||||
for (unsigned int layer = 0; layer < nTextures; ++layer)
|
||||
{
|
||||
if (_layers_info[layer].flags & 0x100)
|
||||
if (_layers_info[layer].flags & FLAG_USE_ALPHA)
|
||||
{
|
||||
f->seek (alpha_base + _layers_info[layer].ofsAlpha);
|
||||
f->seek (alpha_base + tmp_entry_mcly[layer].ofsAlpha);
|
||||
alphamaps[layer - 1].emplace(f, _layers_info[layer].flags, use_big_alphamaps, do_not_fix_alpha_map);
|
||||
}
|
||||
}
|
||||
@@ -68,7 +70,7 @@ int TextureSet::addTexture (scoped_blp_texture_reference texture)
|
||||
nTextures++;
|
||||
|
||||
textures.emplace_back (std::move (texture));
|
||||
_layers_info[texLevel] = ENTRY_MCLY();
|
||||
_layers_info[texLevel] = layer_info();
|
||||
|
||||
if (texLevel)
|
||||
{
|
||||
@@ -189,7 +191,7 @@ void TextureSet::eraseTextures()
|
||||
{
|
||||
alphamaps[i - 1] = std::nullopt;
|
||||
}
|
||||
_layers_info[i] = ENTRY_MCLY();
|
||||
_layers_info[i] = layer_info();
|
||||
}
|
||||
|
||||
nTextures = 0;
|
||||
@@ -235,7 +237,7 @@ void TextureSet::eraseTexture(size_t id)
|
||||
nTextures--;
|
||||
|
||||
// erase the old info as a precaution but it's overriden when adding a new texture
|
||||
_layers_info[nTextures] = ENTRY_MCLY();
|
||||
_layers_info[nTextures] = layer_info();
|
||||
|
||||
// set the default values for the temporary alphamap too
|
||||
if (tmp_edit_values)
|
||||
|
||||
@@ -31,13 +31,21 @@ struct tmp_edit_alpha_values
|
||||
}
|
||||
};
|
||||
|
||||
struct layer_info
|
||||
{
|
||||
// uint32_t textureID = 0;
|
||||
uint32_t flags = 0;
|
||||
// uint32_t ofsAlpha = 0;
|
||||
uint32_t effectID = 0xFFFFFFFF; // default value, see https://wowdev.wiki/ADT/v18#MCLY_sub-chunk
|
||||
};
|
||||
|
||||
class TextureSet
|
||||
{
|
||||
public:
|
||||
TextureSet() = delete;
|
||||
TextureSet(MapChunk* chunk, BlizzardArchive::ClientFile* f, size_t base, MapTile* tile
|
||||
, bool use_big_alphamaps, bool do_not_fix_alpha_map, bool do_not_convert_alphamaps
|
||||
, Noggit::NoggitRenderContext context);
|
||||
, Noggit::NoggitRenderContext context, MapChunkHeader const& header);
|
||||
|
||||
int addTexture(scoped_blp_texture_reference texture);
|
||||
void eraseTexture(size_t id);
|
||||
@@ -102,7 +110,7 @@ public:
|
||||
uint8_t const getDoodadActiveLayerIdAt(unsigned int x, unsigned int y); // max is 8
|
||||
bool const getDoodadDisabledAt(int x, int y); // max is 8
|
||||
auto getEffectForLayer(std::size_t idx) const -> unsigned { return _layers_info[idx].effectID; }
|
||||
ENTRY_MCLY* getMCLYEntries() { return &_layers_info[0]; };
|
||||
layer_info* getMCLYEntries() { return &_layers_info[0]; };
|
||||
void setNTextures(size_t n) { nTextures = n; };
|
||||
std::vector<scoped_blp_texture_reference>* getTextures() { return &textures; };
|
||||
|
||||
@@ -135,7 +143,8 @@ private:
|
||||
// this is actually uint1_t[8][8] (8*8 -> 1 bit each)
|
||||
bool _need_lod_texture_map_update = false;
|
||||
|
||||
ENTRY_MCLY _layers_info[4]; // TODO rework this, don't need to store textureid and offset
|
||||
// ENTRY_MCLY _layers_info[4]; // TODO rework this, don't need to store textureid and offset
|
||||
layer_info _layers_info[4];
|
||||
|
||||
std::optional<tmp_edit_alpha_values> tmp_edit_values;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user