diff --git a/src/shared.vcproj b/src/shared.vcproj index 92f19bd..e696250 100644 --- a/src/shared.vcproj +++ b/src/shared.vcproj @@ -265,6 +265,18 @@ + + + + + + + + diff --git a/src/shared/ADTFile.cpp b/src/shared/ADTFile.cpp index 31cb106..025c311 100644 --- a/src/shared/ADTFile.cpp +++ b/src/shared/ADTFile.cpp @@ -143,7 +143,7 @@ bool ADTFile::LoadMem(ByteBuffer& buf) } else if(!strcmp((char*)fourcc,"MCNK")) { - _chunks[mcnkid].hdr = buf.read(); + _chunks[mcnkid].hdr = buf.read(); uint8 *mfcc = new uint8[5]; mfcc[4]=0; uint32 msize; while(buf.rpos() _textures; std::vector _wmos; std::vector _models; diff --git a/src/shared/ADTFileStructs.h b/src/shared/ADTFileStructs.h index 4c78f5c..663e77f 100644 --- a/src/shared/ADTFileStructs.h +++ b/src/shared/ADTFileStructs.h @@ -81,7 +81,7 @@ struct MODF_chunk uint16 nameSet; }; -enum MapChunkHeaderFlags +enum ADTMapChunkHeaderFlags { FLAG_SHADOW, FLAG_IMPASS, @@ -90,7 +90,7 @@ enum MapChunkHeaderFlags FLAG_LQ_MAGMA, }; -struct MapChunkHeader +struct ADTMapChunkHeader { uint32 flags; uint32 IndexX; @@ -190,9 +190,9 @@ struct NormalVector // also known as MCNK block // 256 per adt file -struct MapChunk +struct ADTMapChunk { - MapChunkHeader hdr; + ADTMapChunkHeader hdr; float vertices[145]; NormalVector normalvecs[145]; MCLY_chunk layer[4]; // can be less diff --git a/src/shared/MapTile.cpp b/src/shared/MapTile.cpp new file mode 100644 index 0000000..fa298ec --- /dev/null +++ b/src/shared/MapTile.cpp @@ -0,0 +1,44 @@ +#include "common.h" +#include "MapTile.h" + + +MapTile::MapTile() +{ +} + +MapTile::~MapTile() +{ +} + +void MapTile::ImportFromADT(ADTFile *adt) +{ + // strip the path name from the dependency files, just store the plain filename + for(std::vector::iterator it = adt->_textures.begin(); it != adt->_textures.end(); it++) + this->_textures.push_back(_PathToFileName(*it)); + for(std::vector::iterator it = adt->_models.begin(); it != adt->_models.end(); it++) + this->_models.push_back(_PathToFileName(*it)); + for(std::vector::iterator it = adt->_wmos.begin(); it != adt->_wmos.end(); it++) + this->_wmos.push_back(_PathToFileName(*it)); + + // import the height map + for(uint32 ch=0; ch_chunks[ch].hdr.xbase; + _chunks[ch].ybase = adt->_chunks[ch].hdr.ybase; + _chunks[ch].zbase = adt->_chunks[ch].hdr.zbase; + uint32 fcnt=0, rcnt=0; + while(fcnt+rcnt < 145) //9*9 + 8*8 + { + for(uint32 h=0; h<9; h++) + { + rcnt++; + _chunks[ch].hmap_rough[rcnt] = adt->_chunks[ch].vertices[fcnt+rcnt]; + } + for(uint32 h=0; h<8; h++) + { + fcnt++; + _chunks[ch].hmap_fine[rcnt] = adt->_chunks[ch].vertices[fcnt+rcnt]; + } + } + } +} \ No newline at end of file diff --git a/src/shared/MapTile.h b/src/shared/MapTile.h new file mode 100644 index 0000000..c8b08a4 --- /dev/null +++ b/src/shared/MapTile.h @@ -0,0 +1,80 @@ +#ifndef MAPTILE_H +#define MAPTILE_H + +#include "WDTFile.h" +#include "ADTFile.h" + +#define TILESIZE (533.33333f) +#define CHUNKSIZE ((TILESIZE) / 16.0f) +#define UNITSIZE (CHUNKSIZE / 8.0f) +#define ZEROPOINT (32.0f * (TILESIZE)) + +// individual chunks of a map +class MapChunk +{ +public: + float hmap_rough[9*9]; + float hmap_fine[8*8]; + float xbase,ybase,zbase; + //... TODO: implement the rest of this +}; + +// generic map tile class. stores the information previously stored in an ADT file +// in an easier to use form. +class MapTile +{ +public: + MapTile(); + ~MapTile(); + void ImportFromADT(ADTFile*); + +private: + MapChunk _chunks[256]; // 16x16 + std::vector _textures; + std::vector _wmos; + std::vector _models; + + float _xbase,_ybase; + +}; + +// store which map tiles are present in the world +class MapTileStorage +{ +public: + inline void ImportTileMap(WDTFile* w) + { + for(uint32 i=0; i<64; i++) + for(uint32 j=0; j<64; j++) + if(w->_main.tiles[i*64 + j]) + _hasTile[i] &= (1 << j); + } + inline void SetTile(MapTile* tile, uint32 x, uint32 y) { SetTile(tile, y*64 + x); } + inline void SetTile(MapTile* tile, uint32 pos) + { + _tiles[pos] = tile; + } + inline void UnloadMapTile(uint32 x, uint32 y) { UnloadMapTile(y*64 + x); } + inline void UnloadMapTile(uint32 pos) + { + delete _tiles[pos]; + _tiles[pos] = NULL; + } + inline void TileExists(uint32 x, uint32 y) { TileExists(y*64 + x); } + inline bool TileExists(uint32 pos) + { + return _hasTile[pos/64] & (1<<(pos%64)); + } + inline MapTile *GetTile(uint32 x, uint32 y) { GetTile(y*64 + x); } + inline MapTile *GetTile(uint32 pos) + { + return _tiles[pos]; + } +private: + MapTile *_tiles[4096]; //64x64 + uint64 _hasTile[64]; //64 x 64 bits, this saves some mem compared to bluzz format +}; + + + +#endif diff --git a/src/shared/WDTFile.cpp b/src/shared/WDTFile.cpp new file mode 100644 index 0000000..c5fa82c --- /dev/null +++ b/src/shared/WDTFile.cpp @@ -0,0 +1,85 @@ +#include +#include "common.h" +#include "ByteBuffer.h" +#include "WDTFile.h" + +inline void flipcc(uint8 *fcc) +{ + char t; + t=fcc[0]; + fcc[0]=fcc[3]; + fcc[3]=t; + t=fcc[1]; + fcc[1]=fcc[2]; + fcc[2]=t; +} + +bool WDTFile::Load(std::string fn) +{ + std::fstream fh; + fh.open(fn.c_str(),std::ios_base::in | std::ios_base::binary); + if(!fh.is_open()) + return false; + uint32 fs = GetFileSize(fn.c_str()); + ByteBuffer bb(fs); + fh.read((char*)bb.contents(),fs); + fh.close(); + return LoadMem(bb); +} + +bool WDTFile::LoadMem(ByteBuffer& buf) +{ + uint8 *fourcc = new uint8[5]; + fourcc[4] = 0; + uint32 size; + + while(buf.rpos() < buf.size()) + { + buf.read(fourcc,4); flipcc(fourcc); + buf >> size; + + if(!strcmp((char*)fourcc,"MVER")) + { + _mver = buf.read(); + } + else if(!strcmp((char*)fourcc,"MPHD")) + { + _mphd = buf.read(); + } + else if(!strcmp((char*)fourcc,"MAIN")) + { + _main = buf.read(); + } + else if(!strcmp((char*)fourcc,"MWMO")) + { + if(size) + { + DEBUG(printf("WDTFile::LoadMem() abort load, MWMO block isnt empty\n")); + break; + } + } + else if(!strcmp((char*)fourcc,"MODF")) + { + DEBUG(printf("WDTFile::LoadMem() abort load, MODF block exists\n")); + break; + } + } + delete [] fourcc; + return true; +} + +void WDTFile::_DebugDump(void) +{ + std::string out; + for(uint32 i=0; i<64; i++) + { + for(uint32 j=0; j<64; j++) + { + out += (_main.tiles[i*64+j] ? "1" : "0"); + } + out += "\n"; + } + printf("WDT DEBUG DUMP, 64x64 TILES:\n"); + printf(out.c_str()); +} + diff --git a/src/shared/WDTFile.h b/src/shared/WDTFile.h new file mode 100644 index 0000000..20bdb06 --- /dev/null +++ b/src/shared/WDTFile.h @@ -0,0 +1,43 @@ +#ifndef WDTFILE_H +#define WDTFILE_H + +struct WDT_MVER_Chunk +{ + uint32 ver; +}; + +struct WDT_MPHD_Chunk +{ + uint32 noTerrain; + uint32 unk2; + uint32 unk3; + uint32 unk4; + uint32 unk5; + uint32 unk6; + uint32 unk7; + uint32 unk8; +}; + +struct WDT_MAIN_Chunk +{ + uint64 tiles[4096]; //64x64 +}; + + +class WDTFile +{ +public: + bool Load(std::string); + bool LoadMem(ByteBuffer&); + void _DebugDump(void); + WDT_MVER_Chunk _mver; + WDT_MPHD_Chunk _mphd; + WDT_MAIN_Chunk _main; + // TODO: implement support for MWMO & MODF chunks (see ADT) +}; + + + + + +#endif diff --git a/src/shared/tools.cpp b/src/shared/tools.cpp index 42af2f9..eb72aa8 100644 --- a/src/shared/tools.cpp +++ b/src/shared/tools.cpp @@ -195,4 +195,22 @@ uint32 GetFileSize(const char* sFileName) return f.tellg() - begin_pos; } +// fix filenames for linux ( '/' instead of windows '\') +void _FixFileName(std::string& str) +{ + for(uint32 i = 0; i < str.length(); i++) + if(str[i]=='\\') + str[i]='/'; +} + +std::string _PathToFileName(std::string str) +{ + uint32 pathend = str.find_last_of("/\\"); + if(pathend != std::string::npos) + { + return str.substr(pathend+1); + } + return str; +} + diff --git a/src/shared/tools.h b/src/shared/tools.h index 364ecb4..ebd0e4d 100644 --- a/src/shared/tools.h +++ b/src/shared/tools.h @@ -20,5 +20,7 @@ bool FileExists(std::string); bool CreateDir(const char*); uint32 getMSTime(void); uint32 GetFileSize(const char*); +void _FixFileName(std::string&); +std::string _PathToFileName(std::string); #endif \ No newline at end of file diff --git a/src/tools/stuffextract/StuffExtract.cpp b/src/tools/stuffextract/StuffExtract.cpp index 05d4ea3..2186d92 100644 --- a/src/tools/stuffextract/StuffExtract.cpp +++ b/src/tools/stuffextract/StuffExtract.cpp @@ -2,9 +2,11 @@ #include #define _COMMON_NO_THREADS #include "common.h" +#include "tools.h" #include "MPQHelper.h" #include "dbcfile.h" #include "ADTFile.h" +#include "WDTFile.h" #include "StuffExtract.h" #include "DBCFieldData.h" #include "Locale.h" @@ -266,6 +268,24 @@ void ExtractMaps(void) CreateDir("stuffextract/data/maps"); for(uint32 it=0; it < mapNames.size(); it++) { + // extract the WDT file that stores tile information + char wdt_name[300], wdt_out[300]; + sprintf(wdt_name,"World\\Maps\\%s\\%s.wdt",mapNames[it].c_str(),mapNames[it].c_str()); + sprintf(wdt_out,MAPSDIR"/%s.wdt",mapNames[it].c_str()); + ByteBuffer& wdt_bb = mpq.ExtractFile(wdt_name); + std::fstream wdt_fh; + wdt_fh.open(wdt_out, std::ios_base::out|std::ios_base::binary); + if(!wdt_fh.is_open()) + { + printf("\nERROR: Map extraction failed: could not save file %s\n",wdt_out); + return; + } + wdt_fh.write((char*)wdt_bb.contents(),wdt_bb.size()); + wdt_fh.close(); + + printf("Extracted WDT '%s'\n",wdt_name); + + // then extract all ADT files extr=0; for(uint32 x=0; x<64; x++) { @@ -406,24 +426,4 @@ void ExtractMapDependencies(void) } -// fix filenames for linux ( '/' instead of windows '\') -void _FixFileName(std::string& str) -{ - for(uint32 i = 0; i < str.length(); i++) - if(str[i]=='\\') - str[i]='/'; -} - -std::string _PathToFileName(std::string str) -{ - uint32 pathend = str.find_last_of("/\\"); - if(pathend != std::string::npos) - { - return str.substr(pathend+1); - } - return str; -} - - - diff --git a/src/tools/stuffextract/StuffExtract.h b/src/tools/stuffextract/StuffExtract.h index b33d88d..90e11c2 100644 --- a/src/tools/stuffextract/StuffExtract.h +++ b/src/tools/stuffextract/StuffExtract.h @@ -17,8 +17,5 @@ void OutSCP(char*, SCPStorageMap&); bool ConvertDBC(void); void ExtractMaps(void); void ExtractMapDependencies(void); -void _FixFileName(std::string&); -std::string _PathToFileName(std::string); - #endif \ No newline at end of file