mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-19 08:55:32 +01:00
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
This commit is contained in:
5
externals/CMakeLists.txt
vendored
5
externals/CMakeLists.txt
vendored
@@ -1,7 +1,8 @@
|
||||
#add_subdirectory(ace)
|
||||
#add_subdirectory(bzip2)
|
||||
#add_subdirectory(libmpq)
|
||||
|
||||
add_subdirectory(zlib)
|
||||
add_subdirectory(bzip2)
|
||||
add_subdirectory(g3dlite)
|
||||
add_subdirectory(jemalloc)
|
||||
#add_subdirectory(libmpq)
|
||||
add_subdirectory(sockets)
|
||||
|
||||
2
externals/bzip2/CMakeLists.txt
vendored
2
externals/bzip2/CMakeLists.txt
vendored
@@ -1,4 +1,4 @@
|
||||
file(GLOB sources *.cpp)
|
||||
file(GLOB sources *.c)
|
||||
set(bzip2_STAT_SRCS
|
||||
${sources}
|
||||
)
|
||||
|
||||
74
externals/libmpq/config.h
vendored
Normal file
74
externals/libmpq/config.h
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
|
||||
#define HAVE_FSEEKO 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `bz2' library (-lbz2). */
|
||||
#define HAVE_LIBBZ2 1
|
||||
|
||||
/* Define to 1 if you have the `z' library (-lz). */
|
||||
#define HAVE_LIBZ 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "libmpq"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "mbroemme@plusserver.de"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "libmpq"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "libmpq 0.4.2"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "libmpq"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "0.4.2"
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "0.4.2"
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
|
||||
/* #undef _LARGEFILE_SOURCE */
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
/* #undef _LARGE_FILES */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) // 羼腓 溧眄<E6BAA7> ?Data1 ?忸溴 羼螯, 蝾 桴 磬漕 觐礅屦蜩痤忄螯
|
||||
{
|
||||
// 镥疱躅?镱 耢妁屙棹 桤 offsData1 我 桌?牦耜?
|
||||
mf.seek(base_pos + LiqOffsData->offsData1);
|
||||
mf.read(LiqChunkData1, 0x18); // 聍栩<E8818D>噱?襦扈 溧眄<E6BAA7> ?耱痼牝箴?蜩镟 MH2O_Data1
|
||||
// 玎眍耔?溧眄<E6BAA7> 綦嚆?潆<> 牦耜?
|
||||
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
|
||||
// 镳邃忄痂蝈朦眍 玎镱腠<E995B1>屐 忮顸 牦耦?溧眄<E6BAA7>?- 礤?忸潲
|
||||
for(int j = 0; j < 81; ++j)
|
||||
{
|
||||
ChunkLiqHeight[j] = -999999; // no liquid/water
|
||||
}
|
||||
// 蝈镥瘘 恹麒耠<E9BA92>屐 蝈 黩??忸漕??镥疱玎镨覃忄屐 桴 ?牦耜?
|
||||
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); // ?礤 玎猁螯 忮痦篁<E797A6><E7AF81> 磬 桉躅漤簋 镱玷鲨?桁屙眍 ?杖呐信
|
||||
}
|
||||
else // 羼腓 溧眄<E6BAA7> ?Data1 礤? 蝾 磬漕 玎镱腠栩?忮顸 牦耦? 眍 溧眄<E6BAA7>?- 礤?忸潲
|
||||
{
|
||||
for(int j = 0; j < 81; ++j)
|
||||
ChunkLiqHeight[j] = -999999; // no liquid/water
|
||||
}
|
||||
|
||||
if(!(chunk_num % 16))
|
||||
m = 1024 * (chunk_num / 16); // 耢妁屙桢 镱 ?溧?牦耜钼 ?镥疱牮<E796B1>桢?= 1024
|
||||
k = m + (chunk_num % 16) * 8; // 篑蜞磬怆桠噱祚<E599B1> 磬 磬鬣朦睇?桧溴犟 潆<> 玎镱腠屙? ?溧
|
||||
// 玎眍耔?溧眄<E6BAA7> 牦耜??爨耨桠 潆<> 赅痱? ?镥疱牮<E796B1>桢??钺疱玎龛屐 牦耜钼 蜿 溧眄<E6BAA7> 81
|
||||
// <20>?囗嚯钽 耱囵钽?钺疱玎龛<E78E8E> 沭囗梓睇?镳噔<E995B3>-犷觐恹??龛骓桴 溧眄<E6BAA7>
|
||||
for(int p = 0; p < 72; p += 9) // 龛骓桢 8 礤 玎眍耔?蜿 铐?潴犭桊箦蝰<E7AEA6> 耠邃 牦耜铎
|
||||
{
|
||||
for(int s = 0; s < 8; ++s) // 9 珥圜屙桢 ?耱痤赍 礤 玎眍耔?蜿 铐?潴犭桊箦蝰<E7AEA6> 耠邃 牦耜铎, ??镳恹?犷觐恹?钺疱玎弪? 潆<> 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) // 礤 狍溴?篦栩<E7AFA6>囹?羼腓 箧?猁腓 溧眄<E6BAA7> ?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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
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);
|
||||
|
||||
if ((blockindex == 0xFFFFFFFF) || (blockindex == 0))
|
||||
return;
|
||||
|
||||
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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user