aboutsummaryrefslogtreecommitdiff
path: root/contrib/map_extractor/adt.cpp
diff options
context:
space:
mode:
authorBrian <runningnak3d@gmail.com>2010-05-03 20:06:29 -0600
committerBrian <runningnak3d@gmail.com>2010-05-03 20:06:29 -0600
commit889fbc5b0b19662ab69edbbd061dd462b0a5989f (patch)
tree21e8475986f50810fe8d10e6a7bbf467fe07a6e5 /contrib/map_extractor/adt.cpp
parent92bb16334348c86ef0d3df9ab07b8b56eb16cb46 (diff)
* Renamed map extractor folder to something more fitting
--HG-- branch : trunk rename : contrib/extractor/CMakeLists.txt => contrib/map_extractor/CMakeLists.txt rename : contrib/extractor/README.linux => contrib/map_extractor/README.linux rename : contrib/extractor/System.cpp => contrib/map_extractor/System.cpp rename : contrib/extractor/VC90_AD.sln => contrib/map_extractor/VC90_AD.sln rename : contrib/extractor/VC90_ad.vcproj => contrib/map_extractor/VC90_ad.vcproj rename : contrib/extractor/ad => contrib/map_extractor/ad rename : contrib/extractor/ad.exe => contrib/map_extractor/ad.exe rename : contrib/extractor/adt.cpp => contrib/map_extractor/adt.cpp rename : contrib/extractor/adt.h => contrib/map_extractor/adt.h rename : contrib/extractor/dbcfile.cpp => contrib/map_extractor/dbcfile.cpp rename : contrib/extractor/dbcfile.h => contrib/map_extractor/dbcfile.h rename : contrib/extractor/debug/zlib.lib => contrib/map_extractor/debug/zlib.lib rename : contrib/extractor/libmpq/CMakeLists.txt => contrib/map_extractor/libmpq/CMakeLists.txt rename : contrib/extractor/libmpq/common.cpp => contrib/map_extractor/libmpq/common.cpp rename : contrib/extractor/libmpq/common.h => contrib/map_extractor/libmpq/common.h rename : contrib/extractor/libmpq/explode.cpp => contrib/map_extractor/libmpq/explode.cpp rename : contrib/extractor/libmpq/explode.h => contrib/map_extractor/libmpq/explode.h rename : contrib/extractor/libmpq/extract.cpp => contrib/map_extractor/libmpq/extract.cpp rename : contrib/extractor/libmpq/huffman.cpp => contrib/map_extractor/libmpq/huffman.cpp rename : contrib/extractor/libmpq/huffman.h => contrib/map_extractor/libmpq/huffman.h rename : contrib/extractor/libmpq/mpq.cpp => contrib/map_extractor/libmpq/mpq.cpp rename : contrib/extractor/libmpq/mpq.h => contrib/map_extractor/libmpq/mpq.h rename : contrib/extractor/libmpq/parser.cpp => contrib/map_extractor/libmpq/parser.cpp rename : contrib/extractor/libmpq/wave.cpp => contrib/map_extractor/libmpq/wave.cpp rename : contrib/extractor/libmpq/wave.h => contrib/map_extractor/libmpq/wave.h rename : contrib/extractor/libmpq/zconf.h => contrib/map_extractor/libmpq/zconf.h rename : contrib/extractor/libmpq/zlib.h => contrib/map_extractor/libmpq/zlib.h rename : contrib/extractor/loadlib/CMakeLists.txt => contrib/map_extractor/loadlib/CMakeLists.txt rename : contrib/extractor/loadlib/adt.cpp => contrib/map_extractor/loadlib/adt.cpp rename : contrib/extractor/loadlib/adt.h => contrib/map_extractor/loadlib/adt.h rename : contrib/extractor/loadlib/loadlib.cpp => contrib/map_extractor/loadlib/loadlib.cpp rename : contrib/extractor/loadlib/loadlib.h => contrib/map_extractor/loadlib/loadlib.h rename : contrib/extractor/loadlib/wdt.cpp => contrib/map_extractor/loadlib/wdt.cpp rename : contrib/extractor/loadlib/wdt.h => contrib/map_extractor/loadlib/wdt.h rename : contrib/extractor/mpq_libmpq.cpp => contrib/map_extractor/mpq_libmpq.cpp rename : contrib/extractor/mpq_libmpq.h => contrib/map_extractor/mpq_libmpq.h rename : contrib/extractor/release/zlib.lib => contrib/map_extractor/release/zlib.lib
Diffstat (limited to 'contrib/map_extractor/adt.cpp')
-rw-r--r--contrib/map_extractor/adt.cpp381
1 files changed, 381 insertions, 0 deletions
diff --git a/contrib/map_extractor/adt.cpp b/contrib/map_extractor/adt.cpp
new file mode 100644
index 00000000000..fcbfc95a072
--- /dev/null
+++ b/contrib/map_extractor/adt.cpp
@@ -0,0 +1,381 @@
+#define _CRT_SECURE_NO_DEPRECATE
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include <string>
+#include <map>
+#include <vector>
+#include <set>
+
+#include "adt.h"
+#include "mpq_libmpq.h"
+
+extern uint16 *areas;
+extern uint16 *LiqType;
+extern uint32 maxAreaId;
+
+vec wmoc;
+
+Cell *cell;
+mcell *mcells;
+int holetab_h[4] = {0x1111, 0x2222, 0x4444, 0x8888};
+int holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000};
+
+bool LoadADT(char* filename)
+{
+ size_t size;
+ MPQFile mf(filename);
+
+ if(mf.isEof())
+ {
+ //printf("No such file %s\n", filename);
+ return false;
+ }
+
+ MapLiqFlag = new uint8[256];
+ for(uint32 j = 0; j < 256; ++j)
+ MapLiqFlag[j] = 0; // no water
+
+ MapLiqHeight = new float[16384];
+ for(uint32 j = 0; j < 16384; ++j)
+ MapLiqHeight[j] = -999999; // no water
+
+ mcells = new mcell;
+
+ wmoc.x = 65 * TILESIZE;
+ wmoc.z = 65 * TILESIZE;
+
+ size_t mcnk_offsets[256], mcnk_sizes[256];
+
+ chunk_num = 0;
+ k = 0;
+ m = 0;
+ while (!mf.isEof())
+ {
+ uint32 fourcc;
+ mf.read(&fourcc, 4);
+ mf.read(&size, 4);
+
+ size_t nextpos = mf.getPos() + size;
+
+ //if(fourcc==0x4d484452) // MHDR header
+ //if(fourcc==0x4d564552) // MVER
+ if(fourcc == 0x4d43494e) // MCIN
+ {
+ for (uint32 i = 0; i < 256; ++i)
+ {
+ mf.read(&mcnk_offsets[i], 4);
+ mf.read(&mcnk_sizes[i], 4);
+ mf.seekRelative(8);
+ }
+ }
+ //if(fourcc == 0x4d544558) // MTEX textures (strings)
+ //if(fourcc == 0x4d4d4458) // MMDX m2 models (strings)
+ //if(fourcc == 0x4d4d4944) // MMID offsets for strings in MMDX
+ //if(fourcc == 0x4d574d4f) // MWMO
+ //if(fourcc == 0x4d574944) // MWID offsets for strings in MWMO
+ //if(fourcc == 0x4d444446) // MDDF
+ //if(fourcc == 0x4d4f4446) // MODF
+ if(fourcc == 0x4d48324f) // MH2O new in WotLK
+ {
+ // здес?надо запомнит?базову?позици??файл?тк вс?смещен? буду?от него
+ uint32 base_pos = mf.getPos();
+ uint32 header_pos = 0;
+ MH2O_offsData *LiqOffsData = new MH2O_offsData;
+ MH2O_Data1 *LiqChunkData1 = new MH2O_Data1;
+ float *ChunkLiqHeight = new float[81];
+ for(chunk_num = 0; chunk_num < 256; ++chunk_num)
+ {
+ mf.read(LiqOffsData, 0x0C);
+ header_pos = mf.getPos();
+ if(LiqOffsData->offsData1 != 0) // если данные ?Data1 ?воде есть, то их надо конвертировать
+ {
+ // перехо?по смещению из offsData1 ОТ ЧА?куск?
+ mf.seek(base_pos + LiqOffsData->offsData1);
+ mf.read(LiqChunkData1, 0x18); // считывае?сами данные ?структур?типа MH2O_Data1
+ // заноси?данные флаг?для куск?
+ if(LiqType[LiqChunkData1->LiquidTypeId] == 0xffff)
+ printf("\nCan't find Liquid type for map %s\nchunk %d\n", filename, chunk_num);
+ else if(LiqType[LiqChunkData1->LiquidTypeId] == LIQUID_TYPE_WATER || LiqType[LiqChunkData1->LiquidTypeId] == LIQUID_TYPE_OCEAN)
+ MapLiqFlag[chunk_num] |= 1; // water/ocean
+ else if(LiqType[LiqChunkData1->LiquidTypeId] == LIQUID_TYPE_MAGMA || LiqType[LiqChunkData1->LiquidTypeId] == LIQUID_TYPE_SLIME)
+ MapLiqFlag[chunk_num] |= 2; // magma/slime
+ // предварительно заполняем весь кусо?данным?- не?воды
+ for(int j = 0; j < 81; ++j)
+ {
+ ChunkLiqHeight[j] = -999999; // no liquid/water
+ }
+ // теперь вычисляем те чт??водо??перезаписываем их ?куск?
+ for(int b = 0; b <= LiqChunkData1->height; ++b)
+ {
+ for(int c = LiqChunkData1->xOffset; c <= (LiqChunkData1->xOffset + LiqChunkData1->width); ++c)
+ {
+ int n = (9 * (LiqChunkData1->yOffset + b)) + c;
+ ChunkLiqHeight[n] = LiqChunkData1->heightLevel1;
+ }
+ }
+ mf.seek(header_pos); // ?не забыть вернуться на исходную позици?именно ?ХИДЕРЕ
+ }
+ else // если данных ?Data1 не? то надо заполнит?весь кусо? но данным?- не?воды
+ {
+ for(int j = 0; j < 81; ++j)
+ ChunkLiqHeight[j] = -999999; // no liquid/water
+ }
+
+ if(!(chunk_num % 16))
+ m = 1024 * (chunk_num / 16); // смещение по ?да?кусков ?перекрытие?= 1024
+ k = m + (chunk_num % 16) * 8; // устанавливаемся на начальны?индекс для заполнен? ?да
+ // заноси?данные куск??массив для карт? ?перекрытие??обрезанием кусков тк данных 81
+ // эт?аналог старог?обрезания граничны?правых-боковы??нижних данных
+ for(int p = 0; p < 72; p += 9) // нижние 8 не заноси?тк он?дублируется след куском
+ {
+ for(int s = 0; s < 8; ++s) // 9 значение ?строке не заноси?тк он?дублируется след куском, ??првы?боковы?обрезает? для 128?28
+ {
+ MapLiqHeight[k] = ChunkLiqHeight[p + s];
+ ++k;
+ }
+ k = k + 120;
+ }
+ }
+ delete LiqOffsData;
+ delete LiqChunkData1;
+ delete []ChunkLiqHeight;
+
+ }
+ //case 0x4d434e4b: // MCNK
+ //case 0x4d46424f: // MFBO new in BC
+ //case 0x4d545846: // MTXF new in WotLK
+ mf.seek(nextpos);
+ }
+
+ //printf("Loading chunks info\n");
+ // read individual map chunks
+ chunk_num = 0;
+ k = 0;
+ m = 0;
+ for (int j = 0; j < 16; ++j)
+ {
+ for (int i = 0; i < 16; ++i)
+ {
+ mf.seek((int)mcnk_offsets[j * 16 + i]);
+ LoadMapChunk(mf, &(mcells->ch[i][j]));
+ ++chunk_num;
+ }
+ }
+ mf.close();
+ return true;
+}
+
+bool isHole(int holes, int i, int j)
+{
+ int testi = i / 2;
+ int testj = j / 4;
+ if(testi > 3) testi = 3;
+ if(testj > 3) testj = 3;
+ return (holes & holetab_h[testi] & holetab_v[testj]) != 0;
+}
+
+inline void LoadMapChunk(MPQFile &mf, chunk *_chunk)
+{
+ float h;
+ uint32 fourcc;
+ uint32 size;
+ MapChunkHeader header;
+
+ mf.seekRelative(4);
+ mf.read(&size, 4);
+
+ size_t lastpos = mf.getPos() + size;
+ mf.read(&header, 0x80); // what if header size got changed?
+ _chunk->area_id = header.areaid;
+
+ float xbase = header.xpos;
+ float ybase = header.ypos;
+ float zbase = header.zpos;
+ zbase = TILESIZE * 32 - zbase;
+ xbase = TILESIZE * 32 - xbase;
+ if(wmoc.x > xbase) wmoc.x = xbase;
+ if(wmoc.z > zbase) wmoc.z = zbase;
+ int chunkflags = header.flags;
+ //printf("LMC: flags %X\n", chunkflags);
+ float zmin = 999999999.0f;
+ float zmax = -999999999.0f;
+ // must be there, bl!zz uses some crazy format
+ while (mf.getPos() < lastpos)
+ {
+ mf.read(&fourcc, 4);
+ mf.read(&size, 4);
+ size_t nextpos = mf.getPos() + size;
+ if(fourcc == 0x4d435654) // MCVT
+ {
+ for (int j = 0; j < 17; ++j)
+ {
+ for (int i = 0; i < ((j % 2) ? 8 : 9); ++i)
+ {
+ mf.read(&h, 4);
+ float z = h + ybase;
+ if (j % 2)
+ {
+ if(isHole(header.holes, i, j))
+ _chunk->v8[i][j / 2] = -1000;
+ else
+ _chunk->v8[i][j / 2] = z;
+ }
+ else
+ {
+ if(isHole(header.holes, i, j))
+ _chunk->v9[i][j / 2] = -1000;
+ else
+ _chunk->v9[i][j / 2] = z;
+ }
+
+ if(z > zmax) zmax = z;
+ //if(z < zmin) zmin = z;
+ }
+ }
+ }
+ else if(fourcc == 0x4d434e52) // MCNR
+ {
+ nextpos = mf.getPos() + 0x1C0; // size fix
+ }
+ else if(fourcc == 0x4d434c51) // не буде?учитыват?если уж?были данные ?MH2O, перестраховк?:) // MCLQ
+ {
+ // liquid / water level
+ char fcc1[5];
+ mf.read(fcc1, 4);
+ flipcc(fcc1);
+ fcc1[4] = 0;
+ float *ChunkLiqHeight = new float[81];
+
+ if (!strcmp(fcc1, "MCSE"))
+ {
+ for(int j = 0; j < 81; ++j)
+ {
+ ChunkLiqHeight[j] = -999999; // no liquid/water
+ }
+ }
+ else
+ {
+ float maxheight;
+ mf.read(&maxheight, 4);
+ for(int j = 0; j < 81; ++j)
+ {
+ LiqData liq;
+ mf.read(&liq, 8);
+
+ if(liq.height > maxheight)
+ ChunkLiqHeight[j] = -999999;
+ else
+ ChunkLiqHeight[j] = h;
+ }
+
+ if(chunkflags & 4 || chunkflags & 8)
+ MapLiqFlag[chunk_num] |= 1; // water
+ if(chunkflags & 16)
+ MapLiqFlag[chunk_num] |= 2; // magma/slime
+ }
+ // аполне?та?же ка??MH2O
+ if(!(chunk_num % 16))
+ m = 1024 * (chunk_num / 16);
+ k = m + (chunk_num % 16) * 8;
+
+ for(int p = 0; p < 72; p += 9)
+ {
+ for(int s = 0; s < 8; ++s)
+ {
+ MapLiqHeight[k] = ChunkLiqHeight[p + s];
+ ++k;
+ }
+ k = k + 120;
+ }
+ delete []ChunkLiqHeight;
+ break;
+ }
+ mf.seek(nextpos);
+ }
+}
+
+inline void TransformData()
+{
+ cell = new Cell;
+
+ for(uint32 x = 0; x < 128; ++x)
+ {
+ for(uint32 y = 0; y < 128; ++y)
+ {
+ cell->v8[y][x] = (float)mcells->ch[x / 8][y / 8].v8[x % 8][y % 8];
+ cell->v9[y][x] = (float)mcells->ch[x / 8][y / 8].v9[x % 8][y % 8];
+ }
+
+ // extra 1 point on bounds
+ cell->v9[128][x] = (float)mcells->ch[x / 8][15].v9[x % 8][8];
+ // x == y
+ cell->v9[x][128] = (float)mcells->ch[15][x / 8].v9[8][x % 8];
+ }
+
+ // and the last 1
+ cell->v9[128][128] = (float)mcells->ch[15][15].v9[8][8];
+
+ delete mcells;
+}
+
+const char MAP_MAGIC[] = "MAP_3.00";
+
+bool ConvertADT(char *filename, char *filename2)
+{
+ if(!LoadADT(filename))
+ return false;
+
+ FILE *output=fopen(filename2, "wb");
+ if(!output)
+ {
+ printf("Can't create the output file '%s'\n", filename2);
+ delete [] MapLiqHeight;
+ delete [] MapLiqFlag;
+ return false;
+ }
+
+ // write magic header
+ fwrite(MAP_MAGIC, 1, 8, output);
+
+ for(uint32 x = 0; x < 16; ++x)
+ {
+ for(uint32 y = 0; y < 16; ++y)
+ {
+ if(mcells->ch[y][x].area_id && mcells->ch[y][x].area_id <= maxAreaId)
+ {
+ if(areas[mcells->ch[y][x].area_id] == 0xffff)
+ printf("\nCan't find area flag for areaid %u.\n", mcells->ch[y][x].area_id);
+
+ fwrite(&areas[mcells->ch[y][x].area_id], 1, 2, output);
+ }
+ else
+ {
+ uint16 flag = 0xffff;
+ fwrite(&flag, 1, 2, output);
+ }
+ }
+ }
+
+ fwrite(MapLiqFlag, 1, 256, output);
+ delete [] MapLiqFlag;
+
+ fwrite(MapLiqHeight, sizeof(float), 16384, output);
+ delete [] MapLiqHeight;
+
+ TransformData();
+
+
+ fwrite(&cell->v9, 1, sizeof(cell->v9), output);
+ fwrite(&cell->v8, 1, sizeof(cell->v8), output);
+ fclose(output);
+ delete cell;
+
+ return true;
+}
+