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