diff --git a/src/noggit/MapChunk.cpp b/src/noggit/MapChunk.cpp index af72b8cc..02bb5dff 100755 --- a/src/noggit/MapChunk.cpp +++ b/src/noggit/MapChunk.cpp @@ -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(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 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(lMCIN_Position + 8)->mEntries[py * 16 + px].offset = lCurrentPosition; // check this // MCNK data - lADTFile.Insert(lCurrentPosition + 8, 0x80, reinterpret_cast(&(header))); + // lADTFile.Insert(lCurrentPosition + 8, 0x80, reinterpret_cast(&(header))); MapChunkHeader *lMCNK_header = lADTFile.GetPointer(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(lMCNK_Position + 8)->ofsSndEmitters = lCurrentPosition - lMCNK_Position; lADTFile.GetPointer(lMCNK_Position + 8)->nSndEmitters = lMCSE_Size / 0x1C; - lCurrentPosition += 8 + lMCSE_Size; + lCurrentPosition += 8; + + for (auto& sound_emitter : sound_emitters) + { + ENTRY_MCSE* MCSE = lADTFile.GetPointer(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(lMCNK_Position)->mSize = lMCNK_Size; diff --git a/src/noggit/MapChunk.h b/src/noggit/MapChunk.h index 0632551e..96fe1b97 100755 --- a/src/noggit/MapChunk.h +++ b/src/noggit/MapChunk.h @@ -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 sound_emitters; + glm::vec3 mVertices[mapbufsize]; glm::vec3 mNormals[mapbufsize]; glm::vec3 mccv[mapbufsize]; // blizzard stores alpha, but deosn't seem to be used diff --git a/src/noggit/MapHeaders.h b/src/noggit/MapHeaders.h index 599370d3..43386995 100755 --- a/src/noggit/MapHeaders.h +++ b/src/noggit/MapHeaders.h @@ -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ⁱ + float pos[3]; + float size[3]; }; #include // memcpy() diff --git a/src/noggit/Selection.cpp b/src/noggit/Selection.cpp index a958bb14..deb98c84 100755 --- a/src/noggit/Selection.cpp +++ b/src/noggit/Selection.cpp @@ -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 weights = chunk->getTextureSet()->get_textures_weight_for_unit(unit_index.x, unit_index.y); diff --git a/src/noggit/texture_set.cpp b/src/noggit/texture_set.cpp index 749a2586..010e36f6 100755 --- a/src/noggit/texture_set.cpp +++ b/src/noggit/texture_set.cpp @@ -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; iread (&_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) diff --git a/src/noggit/texture_set.hpp b/src/noggit/texture_set.hpp index 59bc175d..1df1c015 100755 --- a/src/noggit/texture_set.hpp +++ b/src/noggit/texture_set.hpp @@ -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* 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_values;