implement sound emitters load/save

rework chunk loading classes to be temporary
This commit is contained in:
T1ti
2024-03-08 07:53:14 +01:00
parent 43073136c4
commit 6d376f31cb
6 changed files with 147 additions and 67 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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()

View File

@@ -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);

View File

@@ -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)

View File

@@ -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;