diff options
author | click <none@none> | 2010-06-11 05:01:30 +0200 |
---|---|---|
committer | click <none@none> | 2010-06-11 05:01:30 +0200 |
commit | 39e793b2bdfe4623b24a0528fd4954814f7e3a4b (patch) | |
tree | a145299807a5460664df94b7751d621e8a66e02e /src | |
parent | d6d9d50952aa244dfeba4d4ce6219527602ff8d8 (diff) |
Add extractors and assembler - EXTRACTION OF NEW MAPS IS REQUIRED!
This will allow for easier testing of functionality between different
projects, ie. one set of maps/vmaps instead of 2 (saves space, saves
time and saves us some confusion).
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Maps/Map.cpp | 10 | ||||
-rw-r--r-- | src/server/game/Maps/Map.h | 3 | ||||
-rw-r--r-- | src/tools/map_extractor/CMakeLists.txt | 44 | ||||
-rw-r--r-- | src/tools/map_extractor/System.cpp | 141 | ||||
-rw-r--r-- | src/tools/map_extractor/adt.cpp | 381 | ||||
-rw-r--r-- | src/tools/map_extractor/adt.h | 130 | ||||
-rw-r--r-- | src/tools/map_extractor/dbcfile.cpp | 2 | ||||
-rw-r--r-- | src/tools/map_extractor/loadlib/loadlib.cpp | 4 | ||||
-rw-r--r-- | src/tools/map_extractor/mpq_libmpq.cpp | 61 | ||||
-rw-r--r-- | src/tools/map_extractor/mpq_libmpq04.h (renamed from src/tools/map_extractor/mpq_libmpq.h) | 47 | ||||
-rw-r--r-- | src/tools/vmap3_assembler/CMakeLists.txt | 6 | ||||
-rw-r--r-- | src/tools/vmap3_extractor/CMakeLists.txt | 6 |
12 files changed, 168 insertions, 667 deletions
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 12d7f14090a..ee8fc3fd6da 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -94,10 +94,9 @@ bool Map::ExistMap(uint32 mapid,int gx,int gy) map_fileheader header; fread(&header, sizeof(header), 1, pf); - if (header.mapMagic != uint32(MAP_MAGIC) || - header.versionMagic != uint32(MAP_VERSION_MAGIC)) + if (header.mapMagic != uint32(MAP_MAGIC) || header.versionMagic != uint32(MAP_VERSION_MAGIC)) { - sLog.outError("Map file '%s' is non-compatible version (outdated?). Please, create new using ad.exe program.",tmp); + sLog.outError("Map file '%s' is from an incompatible clientversion. Please recreate using the mapextractor.",tmp); delete [] tmp; fclose(pf); //close file before return return false; @@ -1209,8 +1208,7 @@ bool GridMap::loadData(char *filename) if (!in) return true; fread(&header, sizeof(header),1,in); - if (header.mapMagic == uint32(MAP_MAGIC) && - header.versionMagic == uint32(MAP_VERSION_MAGIC)) + if (header.mapMagic == uint32(MAP_MAGIC) && header.versionMagic == uint32(MAP_VERSION_MAGIC)) { // loadup area data if (header.areaMapOffset && !loadAreaData(in, header.areaMapOffset, header.areaMapSize)) @@ -1236,7 +1234,7 @@ bool GridMap::loadData(char *filename) fclose(in); return true; } - sLog.outError("Map file '%s' is a non-compatible version (outdated?). Please, create new using the ad.exe program.", filename); + sLog.outError("Map file '%s' is from an incompatible clientversion. Please recreate using the mapextractor.", filename); fclose(in); return false; } diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index d2d442ca4cd..d17dc10ec07 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -57,7 +57,7 @@ class BattleGround; // Map file format defines //****************************************** #define MAP_MAGIC 'SPAM' -#define MAP_VERSION_MAGIC '0.1w' +#define MAP_VERSION_MAGIC '1.1v' #define MAP_AREA_MAGIC 'AERA' #define MAP_HEIGHT_MAGIC 'TGHM' #define MAP_LIQUID_MAGIC 'QILM' @@ -66,6 +66,7 @@ struct map_fileheader { uint32 mapMagic; uint32 versionMagic; + uint32 buildMagic; uint32 areaMapOffset; uint32 areaMapSize; uint32 heightMapOffset; diff --git a/src/tools/map_extractor/CMakeLists.txt b/src/tools/map_extractor/CMakeLists.txt index a2ceff1fa73..8e7fa0df891 100644 --- a/src/tools/map_extractor/CMakeLists.txt +++ b/src/tools/map_extractor/CMakeLists.txt @@ -12,17 +12,41 @@ file(GLOB sources *.cpp) file(GLOB loadlib_sources loadlib/*.cpp) -include_directories (${CMAKE_SOURCE_DIR}/src/server/shared) -include_directories (${CMAKE_SOURCE_DIR}/externals/libmpq) -include_directories (${CMAKE_SOURCE_DIR}/src/tools/map_extractor) -include_directories (${CMAKE_SOURCE_DIR}/src/tools/map_extractor/loadlib) +include_directories ( + ${CMAKE_SOURCE_DIR}/src/server/shared + ${CMAKE_SOURCE_DIR}/externals/libmpq + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/loadlib +) -link_directories (${CMAKE_SOURCE_DIR}/externals/libmpq/libmpq) -link_directories (${CMAKE_SOURCE_DIR}}/src/tools/map_extractor/loadlib) +link_directories( + ${CMAKE_SOURCE_DIR}/externals/libmpq/libmpq + ${CMAKE_CURRENT_SOURCE_DIR}}/loadlib +) -add_library (loadlib ${loadlib_sources}) -target_link_libraries (loadlib zlib) +add_library(loadlib + ${loadlib_sources} +) -add_executable (map_extractor ${sources}) +target_link_libraries(loadlib zlib) -target_link_libraries (map_extractor libmpq loadlib) +add_library(libmpq + ${CMAKE_SOURCE_DIR}/externals/libmpq/libmpq/common.c + ${CMAKE_SOURCE_DIR}/externals/libmpq/libmpq/explode.c + ${CMAKE_SOURCE_DIR}/externals/libmpq/libmpq/extract.c + ${CMAKE_SOURCE_DIR}/externals/libmpq/libmpq/huffman.c + ${CMAKE_SOURCE_DIR}/externals/libmpq/libmpq/mpq.c + ${CMAKE_SOURCE_DIR}/externals/libmpq/libmpq/wave.c +) + +add_executable(mapextractor + ${sources} +) + +target_link_libraries(mapextractor + libmpq + loadlib + bzip2 +) + +install(TARGETS mapextractor DESTINATION bin) diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index d5822c8d914..6abe2364cd6 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -12,13 +12,11 @@ #endif #include "dbcfile.h" -#include "mpq_libmpq.h" +#include "mpq_libmpq04.h" #include "loadlib/adt.h" #include "loadlib/wdt.h" #include <fcntl.h> -#include "revision.h" -#define _MAP_EXTRACTOR_VERSION 2 #if defined( __GNUC__ ) #define _open open @@ -35,7 +33,6 @@ #else #define OPEN_FLAGS (O_RDONLY | O_BINARY) #endif - extern ArchiveSet gOpenArchives; typedef struct @@ -123,13 +120,6 @@ void Usage(char* prg) exit(1); } -void Version(char* prg) -{ - printf("TrinityCore Rev: " _REVISION " " _BUILD_DIRECTIVE " Hash: " _HASH "\n"\ - "%s Ver: " _MAP_EXTRACTOR_VERSION, prg); - exit(0); -} - void HandleArgs(int argc, char * arg[]) { for(int c = 1; c < argc; ++c) @@ -145,13 +135,13 @@ void HandleArgs(int argc, char * arg[]) switch(arg[c][1]) { case 'i': - if (c + 1 < argc) // all ok + if(c + 1 < argc) // all ok strcpy(input_path, arg[(c++) + 1]); else Usage(arg[0]); break; case 'o': - if (c + 1 < argc) // all ok + if(c + 1 < argc) // all ok strcpy(output_path, arg[(c++) + 1]); else Usage(arg[0]); @@ -163,7 +153,7 @@ void HandleArgs(int argc, char * arg[]) Usage(arg[0]); break; case 'e': - if (c + 1 < argc) // all ok + if(c + 1 < argc) // all ok { CONF_extract=atoi(arg[(c++) + 1]); if(!(CONF_extract > 0 && CONF_extract < 4)) @@ -172,16 +162,47 @@ void HandleArgs(int argc, char * arg[]) else Usage(arg[0]); break; - case 'v': - if (c + 1 < argc) // all ok - Version(arg[0]); - else - Usage(arg[0]); - break; } } } +uint32 ReadBuild(int locale) +{ + // include build info file also + std::string filename = std::string("component.wow-")+langs[locale]+".txt"; + //printf("Read %s file... ", filename.c_str()); + + MPQFile m(filename.c_str()); + if(m.isEof()) + { + printf("Fatal error: Not found %s file!\n", filename.c_str()); + exit(1); + } + + std::string text = m.getPointer(); + m.close(); + + size_t pos = text.find("version=\""); + size_t pos1 = pos + strlen("version=\""); + size_t pos2 = text.find("\"",pos1); + if (pos == text.npos || pos2 == text.npos || pos1 >= pos2) + { + printf("Fatal error: Invalid %s file format!\n", filename.c_str()); + exit(1); + } + + std::string build_str = text.substr(pos1,pos2-pos1); + + int build = atoi(build_str.c_str()); + if (build <= 0) + { + printf("Fatal error: Invalid %s file format!\n", filename.c_str()); + exit(1); + } + + return build; +} + uint32 ReadMapDBC() { printf("Read Map.dbc file... "); @@ -254,16 +275,17 @@ void ReadLiquidTypeTableDBC() // // Map file format data -#define MAP_MAGIC 'SPAM' -#define MAP_VERSION_MAGIC '0.1w' -#define MAP_AREA_MAGIC 'AERA' -#define MAP_HEIGHT_MAGIC 'TGHM' -#define MAP_LIQUID_MAGIC 'QILM' +static char const* MAP_MAGIC = "MAPS"; +static char const* MAP_VERSION_MAGIC = "v1.1"; +static char const* MAP_AREA_MAGIC = "AREA"; +static char const* MAP_HEIGHT_MAGIC = "MHGT"; +static char const* MAP_LIQUID_MAGIC = "MLIQ"; struct map_fileheader { uint32 mapMagic; uint32 versionMagic; + uint32 buildMagic; uint32 areaMapOffset; uint32 areaMapSize; uint32 heightMapOffset; @@ -341,7 +363,7 @@ uint8 liquid_type[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]; bool liquid_show[ADT_GRID_SIZE][ADT_GRID_SIZE]; float liquid_height[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1]; -bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x) +bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x, uint32 build) { ADT_file adt; @@ -360,8 +382,9 @@ bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x) // Prepare map header map_fileheader map; - map.mapMagic = MAP_MAGIC; - map.versionMagic = MAP_VERSION_MAGIC; + map.mapMagic = *(uint32 const*)MAP_MAGIC; + map.versionMagic = *(uint32 const*)MAP_VERSION_MAGIC; + map.buildMagic = build; // Get area flags data for (int i=0;i<ADT_CELLS_PER_GRID;i++) @@ -403,7 +426,7 @@ bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x) map.areaMapSize = sizeof(map_areaHeader); map_areaHeader areaHeader; - areaHeader.fourcc = MAP_AREA_MAGIC; + areaHeader.fourcc = *(uint32 const*)MAP_AREA_MAGIC; areaHeader.flags = 0; if (fullAreaData) { @@ -532,7 +555,7 @@ bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x) map.heightMapSize = sizeof(map_heightHeader); map_heightHeader heightHeader; - heightHeader.fourcc = MAP_HEIGHT_MAGIC; + heightHeader.fourcc = *(uint32 const*)MAP_HEIGHT_MAGIC; heightHeader.flags = 0; heightHeader.gridHeight = minHeight; heightHeader.gridMaxHeight = maxHeight; @@ -767,7 +790,7 @@ bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x) } map.liquidMapOffset = map.heightMapOffset + map.heightMapSize; map.liquidMapSize = sizeof(map_liquidHeader); - liquidHeader.fourcc = MAP_LIQUID_MAGIC; + liquidHeader.fourcc = *(uint32 const*)MAP_LIQUID_MAGIC; liquidHeader.flags = 0; liquidHeader.liquidType = 0; liquidHeader.offsetX = minX; @@ -846,7 +869,7 @@ bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x) return true; } -void ExtractMapsFromMpq() +void ExtractMapsFromMpq(uint32 build) { char mpq_filename[1024]; char output_filename[1024]; @@ -884,7 +907,7 @@ void ExtractMapsFromMpq() continue; sprintf(mpq_filename, "World\\Maps\\%s\\%s_%u_%u.adt", map_ids[z].name, map_ids[z].name, x, y); sprintf(output_filename, "%s/maps/%03u%02u%02u.map", output_path, map_ids[z].id, y, x); - ConvertADT(mpq_filename, output_filename, y, x); + ConvertADT(mpq_filename, output_filename, y, x, build); } // draw progress bar printf("Processing........................%d%%\r", (100 * (y+1)) / WDT_MAP_SIZE); @@ -894,11 +917,27 @@ void ExtractMapsFromMpq() delete [] map_ids; } +bool ExtractFile( char const* mpq_name, std::string const& filename ) +{ + FILE *output = fopen(filename.c_str(), "wb"); + if(!output) + { + printf("Can't create the output file '%s'\n", filename.c_str()); + return false; + } + MPQFile m(mpq_name); + if(!m.isEof()) + fwrite(m.getPointer(), 1, m.getSize(), output); + + fclose(output); + return true; +} + void ExtractDBCFiles(int locale, bool basicLocale) { printf("Extracting dbc files...\n"); - set<string> dbcfiles; + std::set<std::string> dbcfiles; // get DBC file list for(ArchiveSet::iterator i = gOpenArchives.begin(); i != gOpenArchives.end();++i) @@ -910,7 +949,7 @@ void ExtractDBCFiles(int locale, bool basicLocale) dbcfiles.insert(*iter); } - string path = output_path; + std::string path = output_path; path += "/dbc/"; CreateDir(path); if(!basicLocale) @@ -920,6 +959,14 @@ void ExtractDBCFiles(int locale, bool basicLocale) CreateDir(path); } + // extract Build info file + { + string mpq_name = std::string("component.wow-") + langs[locale] + ".txt"; + string filename = path + mpq_name; + + ExtractFile(mpq_name.c_str(), filename); + } + // extract DBCs int count = 0; for (set<string>::iterator iter = dbcfiles.begin(); iter != dbcfiles.end(); ++iter) @@ -927,18 +974,8 @@ void ExtractDBCFiles(int locale, bool basicLocale) string filename = path; filename += (iter->c_str() + strlen("DBFilesClient\\")); - FILE *output = fopen(filename.c_str(), "wb"); - if(!output) - { - printf("Can't create the output file '%s'\n", filename.c_str()); - continue; - } - MPQFile m(iter->c_str()); - if(!m.isEof()) - fwrite(m.getPointer(), 1, m.getSize(), output); - - fclose(output); - ++count; + if(ExtractFile(iter->c_str(), filename)) + ++count; } printf("Extracted %u DBC files\n\n", count); } @@ -988,6 +1025,7 @@ int main(int argc, char * arg[]) HandleArgs(argc, arg); int FirstLocale = -1; + uint32 build = 0; for (int i = 0; i < LANG_COUNT; i++) { @@ -1003,14 +1041,18 @@ int main(int argc, char * arg[]) if((CONF_extract & EXTRACT_DBC) == 0) { FirstLocale = i; + build = ReadBuild(FirstLocale); + printf("Detected client build: %u\n", build); break; } //Extract DBC files if(FirstLocale < 0) { - ExtractDBCFiles(i, true); FirstLocale = i; + build = ReadBuild(FirstLocale); + printf("Detected client build: %u\n", build); + ExtractDBCFiles(i, true); } else ExtractDBCFiles(i, false); @@ -1035,7 +1077,7 @@ int main(int argc, char * arg[]) LoadCommonMPQFiles(); // Extract maps - ExtractMapsFromMpq(); + ExtractMapsFromMpq(build); // Close MPQs CloseMPQFiles(); @@ -1043,4 +1085,3 @@ int main(int argc, char * arg[]) return 0; } - diff --git a/src/tools/map_extractor/adt.cpp b/src/tools/map_extractor/adt.cpp deleted file mode 100644 index fcbfc95a072..00000000000 --- a/src/tools/map_extractor/adt.cpp +++ /dev/null @@ -1,381 +0,0 @@ -#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; -} - diff --git a/src/tools/map_extractor/adt.h b/src/tools/map_extractor/adt.h deleted file mode 100644 index 516ed88a86e..00000000000 --- a/src/tools/map_extractor/adt.h +++ /dev/null @@ -1,130 +0,0 @@ -#ifndef ADT_H -#define ADT_H - -#define TILESIZE (533.33333f) -#define CHUNKSIZE ((TILESIZE) / 16.0f) -#define UNITSIZE (CHUNKSIZE / 8.0f) - -typedef unsigned char uint8; -typedef unsigned short uint16; -typedef unsigned int uint32; -class Liquid; -typedef struct -{ - float x; - float y; - float z; -} svec; - -typedef struct -{ - double x; - double y; - double z; -} vec; - -typedef struct -{ - vec v[3]; -} triangle; - -typedef struct -{ - float v9[16 * 8 + 1][16 * 8 + 1]; - float v8[16 * 8][16 * 8]; -} Cell; - -typedef struct -{ - double v9[9][9]; - double v8[8][8]; - uint16 area_id; -} chunk; - -typedef struct -{ - chunk ch[16][16]; -} mcell; - -struct MapChunkHeader -{ - uint32 flags; - uint32 ix; - uint32 iy; - uint32 nLayers; - uint32 nDoodadRefs; - uint32 ofsHeight; - uint32 ofsNormal; - uint32 ofsLayer; - uint32 ofsRefs; - uint32 ofsAlpha; - uint32 sizeAlpha; - uint32 ofsShadow; - uint32 sizeShadow; - uint32 areaid; - uint32 nMapObjRefs; - uint32 holes; - uint16 s1; - uint16 s2; - uint32 d1; - uint32 d2; - uint32 d3; - uint32 predTex; - uint32 nEffectDoodad; - uint32 ofsSndEmitters; - uint32 nSndEmitters; - uint32 ofsLiquid; // not use in WotLK - uint32 sizeLiquid; // not use in WotLK - float zpos; - float xpos; - float ypos; - uint32 textureId; // new offsColorValues in WotLK - uint32 props; - uint32 effectId; -}; - -typedef struct -{ - uint32 offsData1; - uint32 used; - uint32 offsData2; -} MH2O_offsData; - -typedef struct -{ - uint16 LiquidTypeId; - uint16 type; - float heightLevel1; - float heightLevel2; - uint8 xOffset; - uint8 yOffset; - uint8 width; - uint8 height; - uint32 ofsData2a; - uint32 ofsData2b; -} MH2O_Data1; - -typedef struct -{ - uint16 unk1; - uint16 unk2; - float height; -} LiqData; - -enum LiquidType -{ - LIQUID_TYPE_WATER = 0, - LIQUID_TYPE_OCEAN = 1, - LIQUID_TYPE_MAGMA = 2, - LIQUID_TYPE_SLIME = 3 -}; - -class MPQFile; - -float *MapLiqHeight; -uint8 *MapLiqFlag; -uint32 k, m, chunk_num; -void LoadMapChunk(MPQFile &, chunk*); -#endif - - diff --git a/src/tools/map_extractor/dbcfile.cpp b/src/tools/map_extractor/dbcfile.cpp index dd58ac1b4a6..927d3d62b7f 100644 --- a/src/tools/map_extractor/dbcfile.cpp +++ b/src/tools/map_extractor/dbcfile.cpp @@ -1,7 +1,7 @@ #define _CRT_SECURE_NO_DEPRECATE #include "dbcfile.h" -#include "mpq_libmpq.h" +#include "mpq_libmpq04.h" DBCFile::DBCFile(const std::string &filename): filename(filename), diff --git a/src/tools/map_extractor/loadlib/loadlib.cpp b/src/tools/map_extractor/loadlib/loadlib.cpp index 90d95ebfe35..e2dd2d79d85 100644 --- a/src/tools/map_extractor/loadlib/loadlib.cpp +++ b/src/tools/map_extractor/loadlib/loadlib.cpp @@ -1,7 +1,7 @@ #define _CRT_SECURE_NO_DEPRECATE #include "loadlib.h" -#include "mpq_libmpq.h" +#include "mpq_libmpq04.h" class MPQFile; @@ -61,4 +61,4 @@ void FileLoader::free() data = 0; data_size = 0; version = 0; -}
\ No newline at end of file +} diff --git a/src/tools/map_extractor/mpq_libmpq.cpp b/src/tools/map_extractor/mpq_libmpq.cpp index 2a066a83b34..72a9de460eb 100644 --- a/src/tools/map_extractor/mpq_libmpq.cpp +++ b/src/tools/map_extractor/mpq_libmpq.cpp @@ -1,44 +1,30 @@ -#include "mpq_libmpq.h" +#include "mpq_libmpq04.h" #include <deque> +#include <cstdio> ArchiveSet gOpenArchives; MPQArchive::MPQArchive(const char* filename) { - int result = libmpq_archive_open(&mpq_a, (unsigned char*)filename); + int result = libmpq__archive_open(&mpq_a, filename, -1); printf("Opening %s\n", filename); if(result) { switch(result) { - case LIBMPQ_EFILE : /* error on file operation */ - printf("Error opening archive '%s': File operation Error\n", filename); + case LIBMPQ_ERROR_OPEN : + printf("Error opening archive '%s': Does file really exist?\n", filename); break; - case LIBMPQ_EFILE_FORMAT : /* bad file format */ + case LIBMPQ_ERROR_FORMAT : /* bad file format */ printf("Error opening archive '%s': Bad file format\n", filename); break; - case LIBMPQ_EFILE_CORRUPT : /* file corrupt */ - printf("Error opening archive '%s': File corrupt\n", filename); + case LIBMPQ_ERROR_SEEK : /* seeking in file failed */ + printf("Error opening archive '%s': Seeking in file failed\n", filename); break; - case LIBMPQ_EFILE_NOT_FOUND : /* file in archive not found */ - printf("Error opening archive '%s': File in archive not found\n", filename); - break; - case LIBMPQ_EFILE_READ : /* Read error in archive */ + case LIBMPQ_ERROR_READ : /* Read error in archive */ printf("Error opening archive '%s': Read error in archive\n", filename); break; - case LIBMPQ_EALLOCMEM : /* maybe not enough memory? :) */ + case LIBMPQ_ERROR_MALLOC : /* maybe not enough memory? :) */ printf("Error opening archive '%s': Maybe not enough memory\n", filename); break; - case LIBMPQ_EFREEMEM : /* can not free memory */ - printf("Error opening archive '%s': Cannot free memory\n", filename); - break; - case LIBMPQ_EINV_RANGE : /* Given filenumber is out of range */ - printf("Error opening archive '%s': Given filenumber is out of range\n", filename); - break; - case LIBMPQ_EHASHTABLE : /* error in reading hashtable */ - printf("Error opening archive '%s': Error in reading hashtable\n", filename); - break; - case LIBMPQ_EBLOCKTABLE : /* error in reading blocktable */ - printf("Error opening archive '%s': Error in reading blocktable\n", filename); - break; default: printf("Error opening archive '%s': Unknown error\n", filename); break; @@ -51,7 +37,7 @@ MPQArchive::MPQArchive(const char* filename) void MPQArchive::close() { //gOpenArchives.erase(erase(&mpq_a); - libmpq_archive_close(&mpq_a); + libmpq__archive_close(mpq_a); } MPQFile::MPQFile(const char* filename): @@ -62,25 +48,16 @@ MPQFile::MPQFile(const char* filename): { for(ArchiveSet::iterator i=gOpenArchives.begin(); i!=gOpenArchives.end();++i) { - mpq_archive &mpq_a = (*i)->mpq_a; + mpq_archive *mpq_a = (*i)->mpq_a; - mpq_hash hash = (*i)->GetHashEntry(filename); - uint32 blockindex = hash.blockindex; + uint32_t filenum; + if(libmpq__file_number(mpq_a, filename, &filenum)) continue; + libmpq__off_t transferred; + libmpq__file_unpacked_size(mpq_a, filenum, &size); - if ((blockindex == 0xFFFFFFFF) || (blockindex == 0)) { - continue; //file not found - } - - uint32 fileno = blockindex; - - //int fileno = libmpq_file_number(&mpq_a, filename); - //if(fileno == LIBMPQ_EFILE_NOT_FOUND) - // continue; - - // Found! - size = libmpq_file_info(&mpq_a, LIBMPQ_FILE_UNCOMPRESSED_SIZE, fileno); // HACK: in patch.mpq some files don't want to open and give 1 for filesize if (size<=1) { + printf("warning: file %s has size %d; cannot read.\n", filename, size); eof = true; buffer = 0; return; @@ -88,7 +65,8 @@ MPQFile::MPQFile(const char* filename): buffer = new char[size]; //libmpq_file_getdata - libmpq_file_getdata(&mpq_a, hash, fileno, (unsigned char*)buffer); + libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred); + /*libmpq_file_getdata(&mpq_a, hash, fileno, (unsigned char*)buffer);*/ return; } @@ -131,4 +109,3 @@ void MPQFile::close() buffer = 0; eof = true; } - diff --git a/src/tools/map_extractor/mpq_libmpq.h b/src/tools/map_extractor/mpq_libmpq04.h index d61cda7f919..26008f5fba1 100644 --- a/src/tools/map_extractor/mpq_libmpq.h +++ b/src/tools/map_extractor/mpq_libmpq04.h @@ -18,50 +18,20 @@ class MPQArchive { public: - mpq_archive mpq_a; + mpq_archive_s *mpq_a; MPQArchive(const char* filename); void close(); - uint32 HashString(const char* Input, uint32 Offset) { - uint32 seed1 = 0x7fed7fed; - uint32 seed2 = 0xeeeeeeee; - - for (uint32 i = 0; i < strlen(Input); i++) { - uint32 val = toupper(Input[i]); - seed1 = mpq_a.buf[Offset + val] ^ (seed1 + seed2); - seed2 = val + seed1 + seed2 + (seed2 << 5) + 3; - } - - return seed1; - } - mpq_hash GetHashEntry(const char* Filename) { - uint32 index = HashString(Filename, 0); - index &= mpq_a.header->hashtablesize - 1; - uint32 name1 = HashString(Filename, 0x100); - uint32 name2 = HashString(Filename, 0x200); - - for(uint32 i = index; i < mpq_a.header->hashtablesize; ++i) { - mpq_hash hash = mpq_a.hashtable[i]; - if (hash.name1 == name1 && hash.name2 == name2) return hash; - } - - mpq_hash nullhash; - nullhash.blockindex = 0xFFFFFFFF; - return nullhash; - } - void GetFileListTo(vector<string>& filelist) { - mpq_hash hash = GetHashEntry("(listfile)"); - uint32 blockindex = hash.blockindex; - - if ((blockindex == 0xFFFFFFFF) || (blockindex == 0)) - return; + uint32_t filenum; + if(libmpq__file_number(mpq_a, "(listfile)", &filenum)) return; + libmpq__off_t size, transferred; + libmpq__file_unpacked_size(mpq_a, filenum, &size); - uint32 size = libmpq_file_info(&mpq_a, LIBMPQ_FILE_UNCOMPRESSED_SIZE, blockindex); char *buffer = new char[size]; - - libmpq_file_getdata(&mpq_a, hash, blockindex, (unsigned char*)buffer); + + libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred); char seps[] = "\n"; char *token; @@ -87,7 +57,7 @@ class MPQFile //MPQHANDLE handle; bool eof; char *buffer; - size_t pointer,size; + libmpq__off_t pointer,size; // disable copying MPQFile(const MPQFile &f) {} @@ -119,4 +89,3 @@ inline void flipcc(char *fcc) } #endif - diff --git a/src/tools/vmap3_assembler/CMakeLists.txt b/src/tools/vmap3_assembler/CMakeLists.txt index 2088158af6a..b3b16d540c7 100644 --- a/src/tools/vmap3_assembler/CMakeLists.txt +++ b/src/tools/vmap3_assembler/CMakeLists.txt @@ -17,7 +17,7 @@ include_directories( ${ACE_INCLUDE_DIR} ) -add_executable(collision_assembler VMapAssembler.cpp) -target_link_libraries(collision_assembler collision g3dlib) - +add_executable(vmap3assembler VMapAssembler.cpp) +target_link_libraries(vmap3assembler collision g3dlib) +install(TARGETS vmap3assembler DESTINATION bin) diff --git a/src/tools/vmap3_extractor/CMakeLists.txt b/src/tools/vmap3_extractor/CMakeLists.txt index 03d609bf60d..02d044cdaa9 100644 --- a/src/tools/vmap3_extractor/CMakeLists.txt +++ b/src/tools/vmap3_extractor/CMakeLists.txt @@ -11,5 +11,7 @@ include_directories (${CMAKE_SOURCE_DIR}/externals/libmpq) -add_executable(collision_extractor adtfile.cpp dbcfile.cpp model.cpp mpq_libmpq.cpp vmapexport.cpp wdtfile.cpp wmo.cpp) -target_link_libraries(collision_extractor libmpq) +add_executable(vmap3extractor adtfile.cpp dbcfile.cpp model.cpp mpq_libmpq.cpp vmapexport.cpp wdtfile.cpp wmo.cpp) +target_link_libraries(vmap3extractor libmpq bzip2 zlib) + +install(TARGETS vmap3extractor DESTINATION bin) |