diff options
Diffstat (limited to 'contrib/extractor')
23 files changed, 1851 insertions, 951 deletions
diff --git a/contrib/extractor/CMakeLists.txt b/contrib/extractor/CMakeLists.txt new file mode 100644 index 00000000000..9052903b1ed --- /dev/null +++ b/contrib/extractor/CMakeLists.txt @@ -0,0 +1,26 @@ +# Copyright (C) 2005-2009 MaNGOS project <http://getmangos.com/> +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +cmake_minimum_required (VERSION 2.6) +project (MANGOS_MAP_EXTRACTOR) + +add_subdirectory (libmpq) +add_subdirectory (loadlib) + +include_directories (${MANGOS_MAP_EXTRACTOR_SOURCE_DIR}/libmpq) +include_directories (${MANGOS_MAP_EXTRACTOR_SOURCE_DIR}/loadlib) + +link_directories (${MANGOS_MAP_EXTRACTOR_SOURCE_DIR}/libmpq) +link_directories (${MANGOS_MAP_EXTRACTOR_SOURCE_DIR}/loadlib) + +add_executable (ad dbcfile.cpp mpq_libmpq.cpp System.cpp) + +target_link_libraries (ad libmpq) +target_link_libraries (ad loadlib) diff --git a/contrib/extractor/Makefile b/contrib/extractor/Makefile deleted file mode 100644 index 55eb35f336a..00000000000 --- a/contrib/extractor/Makefile +++ /dev/null @@ -1,471 +0,0 @@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - - -# Copyright (C) 2008 Trinity <http://www.trinitycore.org/> -# -# Thanks to the original authors: MaNGOS <http://www.mangosproject.org/> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -SOURCES = $(ad_SOURCES) - -srcdir = . -top_srcdir = . - -pkgdatadir = $(datadir)/mangos -pkglibdir = $(libdir)/mangos -pkgincludedir = $(includedir)/mangos -top_builddir = ../.. -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = /usr/bin/ginstall -c -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = i686-pc-linux-gnu -host_triplet = i686-pc-linux-gnu -bin_PROGRAMS = ad$(EXEEXT) -subdir = contrib/extractor -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -am__installdirs = "$(DESTDIR)$(bindir)" -binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) -PROGRAMS = $(bin_PROGRAMS) -am_ad_OBJECTS = System.$(OBJEXT) adt.$(OBJEXT) dbcfile.$(OBJEXT) \ - mpq_libmpq.$(OBJEXT) -ad_OBJECTS = $(am_ad_OBJECTS) -ad_DEPENDENCIES = -DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CXXFLAGS) $(CXXFLAGS) -CXXLD = $(CXX) -CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(ad_SOURCES) -DIST_SOURCES = $(ad_SOURCES) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = -ALLOCA = -AMDEP_FALSE = # -AMDEP_TRUE = -AMTAR = ${SHELL} /home/wow/MaNGOS/trunk/missing --run tar -AR = ar -AUTOCONF = ${SHELL} /home/wow/MaNGOS/trunk/missing --run autoconf -AUTOHEADER = ${SHELL} /home/wow/MaNGOS/trunk/missing --run autoheader -AUTOMAKE = ${SHELL} /home/wow/MaNGOS/trunk/missing --run automake-1.9 -AWK = gawk -CC = gcc -CCDEPMODE = depmode=gcc3 -CFLAGS = -g -O3 -COMPILER_OPTIONS = -g -O3 -CPP = gcc -E -CPPFLAGS = -CXX = g++ -CXXCPP = g++ -E -CXXDEPMODE = depmode=gcc3 -CXXFLAGS = -g -O3 -CYGPATH_W = echo -DEFS = -DHAVE_CONFIG_H -DEPDIR = .deps -ECHO = echo -ECHO_C = -ECHO_N = -n -ECHO_T = -EGREP = grep -E -EXEEXT = -EXTRA_COMPILER_OPTIONS = -EXTRA_LINKER_OPTIONS = -F77 = -FFLAGS = -INCLUDES = -I$(srcdir) -INSTALL_DATA = ${INSTALL} -m 644 -INSTALL_PROGRAM = ${INSTALL} -INSTALL_SCRIPT = ${INSTALL} -INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s -LDFLAGS = -LIBOBJS = -LIBS = -lz -lpthread -LIBTOOL = $(SHELL) $(top_builddir)/libtool -LINKER_OPTIONS = -static -LN_S = ln -s -LTLIBOBJS = -LT_AGE = 2 -LT_CURRENT = 2 -LT_RELEASE = 2.3.2 -LT_REVISION = 3 -MAINT = # -MAINTAINER_MODE_FALSE = -MAINTAINER_MODE_TRUE = # -MAKEINFO = -MANGOSD_CONFIG = /home/wow/server/etc/mangosd.conf -MANGOSD_CONFIGDIR = /home/wow/server/etc -MANGOSD_DATA = /home/wow/server/share/mangos -OBJEXT = o -PACKAGE = mangos -PACKAGE_BUGREPORT = http://www.mangosproject.org/ -PACKAGE_NAME = MaNGOS -PACKAGE_STRING = MaNGOS 0.2-SVN -PACKAGE_TARNAME = mangos -PACKAGE_VERSION = 0.2-SVN -PATH_SEPARATOR = : -RANLIB = ranlib -SET_MAKE = -SHELL = /bin/sh -STRIP = strip -VERSION = 0.2-SVN -ac_ct_AR = ar -ac_ct_CC = gcc -ac_ct_CXX = g++ -ac_ct_F77 = -ac_ct_RANLIB = ranlib -ac_ct_STRIP = strip -am__fastdepCC_FALSE = # -am__fastdepCC_TRUE = -am__fastdepCXX_FALSE = # -am__fastdepCXX_TRUE = -am__include = include -am__leading_dot = . -am__quote = -am__tar = ${AMTAR} chof - "$$tardir" -am__untar = ${AMTAR} xf - -bindir = ${exec_prefix}/bin -build = i686-pc-linux-gnu -build_alias = -build_cpu = i686 -build_os = linux-gnu -build_vendor = pc -datadir = ${prefix}/share -exec_prefix = ${prefix} -host = i686-pc-linux-gnu -host_alias = -host_cpu = i686 -host_os = linux-gnu -host_vendor = pc -includedir = ${prefix}/include -infodir = ${prefix}/info -install_sh = /home/wow/MaNGOS/trunk/install-sh -libdir = ${exec_prefix}/lib -libexecdir = ${exec_prefix}/libexec -localstatedir = ${prefix}/var -mandir = ${prefix}/man -mkdir_p = mkdir -p -- -oldincludedir = /usr/include -prefix = /home/wow/server -program_transform_name = s,x,x, -sbindir = ${exec_prefix}/sbin -sharedstatedir = ${prefix}/com - -# use our configured sysconfdir -sysconfdir = /home/wow/server/etc -target_alias = -ad_SOURCES = \ - System.cpp \ - adt.h \ - adt.cpp \ - dbcfile.cpp \ - dbcfile.h \ - mpq_libmpq.cpp \ - mpq_libmpq.h - -ad_LDADD = libmpq/libmpq.a -add_LDFLAGS = -L$(srcdir) -L$(srcdir)/libmpq - -all: create-dir all-am - -.SUFFIXES: -.SUFFIXES: .cpp .lo .o .obj - -.PRECIOUS: Makefile - -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)" - @list='$(bin_PROGRAMS)'; for p in $$list; do \ - p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ - if test -f $$p \ - || test -f $$p1 \ - ; then \ - f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ - else :; fi; \ - done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; for p in $$list; do \ - f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ - rm -f "$(DESTDIR)$(bindir)/$$f"; \ - done - -clean-binPROGRAMS: - @list='$(bin_PROGRAMS)'; for p in $$list; do \ - f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f $$p $$f"; \ - rm -f $$p $$f ; \ - done -ad$(EXEEXT): $(ad_OBJECTS) $(ad_DEPENDENCIES) - @rm -f ad$(EXEEXT) - $(CXXLINK) $(ad_LDFLAGS) $(ad_OBJECTS) $(ad_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -.cpp.o: - if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ - then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi -# source='$<' object='$@' libtool=no \ -# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ -# $(CXXCOMPILE) -c -o $@ $< - -.cpp.obj: - if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ - then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi -# source='$<' object='$@' libtool=no \ -# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ -# $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.cpp.lo: - if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ - then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi -# source='$<' object='$@' libtool=yes \ -# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ -# $(LTCXXCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -rm .deps/* - -distclean-libtool: - -rm -f libtool -uninstall-info-am: - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(CTAGS_ARGS)$$tags$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$tags $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ - list='$(DISTFILES)'; for file in $$list; do \ - case $$file in \ - $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ - $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ - esac; \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkdir_p) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ - if test -d $$d/$$file; then \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(PROGRAMS); -installdirs: - for dir in "$(DESTDIR)$(bindir)"; do \ - test -z "$$dir" || $(mkdir_p) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-libtool distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -info: info-am - -info-am: - -install-data-am: - -install-exec-am: install-binPROGRAMS - -install-info: install-info-am - -install-man: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-binPROGRAMS uninstall-info-am - -create-dir: - mkdir -p ".deps" - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ - clean-generic clean-libtool ctags distclean distclean-compile \ - distclean-generic distclean-libtool distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-binPROGRAMS install-data install-data-am install-exec \ - install-exec-am install-info install-info-am install-man \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am \ - uninstall-binPROGRAMS uninstall-info-am - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/contrib/extractor/README.linux b/contrib/extractor/README.linux index 52b907391b8..1986831e751 100644 --- a/contrib/extractor/README.linux +++ b/contrib/extractor/README.linux @@ -1,7 +1,7 @@ -= Trinity Core -- Linux instructions for extractor = +Linux instructions +------------------ -Copyright (C) Trinity Core (http://www.trinitycore.org) - -1: Configure and build MaNGOS. -2: cd contrib/extractor/libmpq && make && cd .. && make -3: run ad
\ No newline at end of file +1. install cmake +2. cmake -i +3. make +4. ./ad diff --git a/contrib/extractor/System.cpp b/contrib/extractor/System.cpp index a1641699163..b656a6ab535 100644 --- a/contrib/extractor/System.cpp +++ b/contrib/extractor/System.cpp @@ -3,6 +3,7 @@ #include <stdio.h> #include <deque> #include <set> +#include <cstdlib> #ifdef WIN32 #include "direct.h" @@ -13,37 +14,78 @@ #include "dbcfile.h" #include "mpq_libmpq.h" -extern unsigned int iRes; -extern ArchiveSet gOpenArchives; +#include "loadlib/adt.h" +#include "loadlib/wdt.h" +#include <fcntl.h> -bool ConvertADT(char*,char*); +#if defined( __GNUC__ ) + #define _open open + #define _close close + #ifndef O_BINARY + #define O_BINARY 0 + #endif +#else + #include <io.h> +#endif -typedef struct{ - char name[64]; - unsigned int id; -}map_id; +#ifdef O_LARGEFILE + #define OPEN_FLAGS (O_RDONLY | O_BINARY | O_LARGEFILE) +#else + #define OPEN_FLAGS (O_RDONLY | O_BINARY) +#endif +extern ArchiveSet gOpenArchives; -typedef unsigned char uint8; -typedef unsigned short uint16; -typedef unsigned int uint32; +typedef struct +{ + char name[64]; + uint32 id; +} map_id; -map_id * map_ids; -uint16 * areas; -char output_path[128]="."; -char input_path[128]="."; +map_id *map_ids; +uint16 *areas; +uint16 *LiqType; +char output_path[128] = "."; +char input_path[128] = "."; +uint32 maxAreaId = 0; +//************************************************** +// Extractor options +//************************************************** enum Extract { EXTRACT_MAP = 1, EXTRACT_DBC = 2 }; -int extract = EXTRACT_MAP | EXTRACT_DBC; + +// Select data for extract +int CONF_extract = EXTRACT_MAP | EXTRACT_DBC; +// This option allow limit minimum height to some value (Allow save some memory) +bool CONF_allow_height_limit = true; +float CONF_use_minHeight = -500.0f; + +// This option allow use float to int conversion +bool CONF_allow_float_to_int = true; +float CONF_float_to_int8_limit = 2.0f; // Max accuracy = val/256 +float CONF_float_to_int16_limit = 2048.0f; // Max accuracy = val/65536 +float CONF_flat_height_delta_limit = 0.005f; // If max - min less this value - surface is flat +float CONF_flat_liquid_delta_limit = 0.001f; // If max - min less this value - liquid surface is flat + +// List MPQ for extract from +char *CONF_mpq_list[]={ + "common.MPQ", + "common-2.MPQ", + "lichking.MPQ", + "expansion.MPQ", + "patch.MPQ", + "patch-2.MPQ", + "patch-3.MPQ", + "patch-4.MPQ", + "patch-5.MPQ", +}; static char* const langs[] = {"enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" }; #define LANG_COUNT 12 -#define ADT_RES 64 - void CreateDir( const std::string& Path ) { #ifdef WIN32 @@ -55,9 +97,10 @@ void CreateDir( const std::string& Path ) bool FileExists( const char* FileName ) { - if(FILE* fp = fopen( FileName, "rb" )) + int fp = _open(FileName, OPEN_FLAGS); + if(fp != -1) { - fclose(fp); + _close(fp); return true; } @@ -66,47 +109,54 @@ bool FileExists( const char* FileName ) void Usage(char* prg) { - printf("Usage:\n%s -[var] [value]\n-i set input path\n-o set output path\n-r set resolution\n-e extract only MAP(1)/DBC(2) - standard: both(3)\nExample: %s -r 256 -i \"c:\\games\\game\"", - prg,prg); + printf( + "Usage:\n"\ + "%s -[var] [value]\n"\ + "-i set input path\n"\ + "-o set output path\n"\ + "-e extract only MAP(1)/DBC(2) - standard: both(3)\n"\ + "-f height stored as int (less map size but lost some accuracy) 1 by default\n"\ + "Example: %s -f 0 -i \"c:\\games\\game\"", prg, prg); exit(1); } void HandleArgs(int argc, char * arg[]) { - for(int c=1;c<argc;c++) + for(int c = 1; c < argc; ++c) { - //i - input path - //o - output path - //r - resolution, array of (r * r) heights will be created - //e - extract only MAP(1)/DBC(2) - standard both(3) + // i - input path + // o - output path + // e - extract only MAP(1)/DBC(2) - standard both(3) + // f - use float to int conversion + // h - limit minimum height if(arg[c][0] != '-') Usage(arg[0]); switch(arg[c][1]) { case 'i': - if(c+1<argc)//all ok - strcpy(input_path,arg[(c++) +1]); + 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 - strcpy(output_path,arg[(c++) +1]); + if(c + 1 < argc) // all ok + strcpy(output_path, arg[(c++) + 1]); else Usage(arg[0]); break; - case 'r': - if(c+1<argc)//all ok - iRes=atoi(arg[(c++) +1]); + case 'f': + if(c + 1 < argc) // all ok + CONF_allow_float_to_int=atoi(arg[(c++) + 1])!=0; else Usage(arg[0]); break; case 'e': - if(c+1<argc)//all ok + if(c + 1 < argc) // all ok { - extract=atoi(arg[(c++) +1]); - if(!(extract > 0 && extract < 4)) + CONF_extract=atoi(arg[(c++) + 1]); + if(!(CONF_extract > 0 && CONF_extract < 4)) Usage(arg[0]); } else @@ -120,14 +170,19 @@ uint32 ReadMapDBC() { printf("Read Map.dbc file... "); DBCFile dbc("DBFilesClient\\Map.dbc"); - dbc.open(); - uint32 map_count=dbc.getRecordCount(); - map_ids=new map_id[map_count]; - for(unsigned int x=0;x<map_count;x++) + if(!dbc.open()) { - map_ids[x].id=dbc.getRecord(x).getUInt(0); - strcpy(map_ids[x].name,dbc.getRecord(x).getString(1)); + printf("Fatal error: Invalid Map.dbc file format!\n"); + exit(1); + } + + size_t map_count = dbc.getRecordCount(); + map_ids = new map_id[map_count]; + for(uint32 x = 0; x < map_count; ++x) + { + map_ids[x].id = dbc.getRecord(x).getUInt(0); + strcpy(map_ids[x].name, dbc.getRecord(x).getString(1)); } printf("Done! (%u maps loaded)\n", map_count); return map_count; @@ -135,60 +190,689 @@ uint32 ReadMapDBC() void ReadAreaTableDBC() { - printf("Read AreaTable.dbc file... "); + printf("Read AreaTable.dbc file..."); DBCFile dbc("DBFilesClient\\AreaTable.dbc"); - dbc.open(); - unsigned int area_count=dbc.getRecordCount(); - uint32 maxid = dbc.getMaxId(); - areas=new uint16[maxid + 1]; - memset(areas, 0xff, sizeof(areas)); - for(unsigned int x=0; x<area_count;++x) + if(!dbc.open()) + { + printf("Fatal error: Invalid AreaTable.dbc file format!\n"); + exit(1); + } + + size_t area_count = dbc.getRecordCount(); + size_t maxid = dbc.getMaxId(); + areas = new uint16[maxid + 1]; + memset(areas, 0xff, (maxid + 1) * sizeof(uint16)); + + for(uint32 x = 0; x < area_count; ++x) areas[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3); + maxAreaId = dbc.getMaxId(); + printf("Done! (%u areas loaded)\n", area_count); } +void ReadLiquidTypeTableDBC() +{ + printf("Read LiquidType.dbc file..."); + DBCFile dbc("DBFilesClient\\LiquidType.dbc"); + if(!dbc.open()) + { + printf("Fatal error: Invalid LiquidType.dbc file format!\n"); + exit(1); + } + + size_t LiqType_count = dbc.getRecordCount(); + size_t LiqType_maxid = dbc.getMaxId(); + LiqType = new uint16[LiqType_maxid + 1]; + memset(LiqType, 0xff, (LiqType_maxid + 1) * sizeof(uint16)); + + for(uint32 x = 0; x < LiqType_count; ++x) + LiqType[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3); + + printf("Done! (%u LiqTypes loaded)\n", LiqType_count); +} + +// +// Adt file convertor function and data +// + +// Map file format data +#define MAP_MAGIC 'SPAM' +#define MAP_VERSION_MAGIC '0.1w' +#define MAP_AREA_MAGIC 'AERA' +#define MAP_HEIGTH_MAGIC 'TGHM' +#define MAP_LIQUID_MAGIC 'QILM' + +struct map_fileheader{ + uint32 mapMagic; + uint32 versionMagic; + uint32 areaMapOffset; + uint32 areaMapSize; + uint32 heightMapOffset; + uint32 heightMapSize; + uint32 liquidMapOffset; + uint32 liquidMapSize; +}; + +#define MAP_AREA_NO_AREA 0x0001 +struct map_areaHeader{ + uint32 fourcc; + uint16 flags; + uint16 gridArea; +}; + +#define MAP_HEIGHT_NO_HIGHT 0x0001 +#define MAP_HEIGHT_AS_INT16 0x0002 +#define MAP_HEIGHT_AS_INT8 0x0004 + +struct map_heightHeader{ + uint32 fourcc; + uint32 flags; + float gridHeight; + float gridMaxHeight; +}; + +#define MAP_LIQUID_TYPE_NO_WATER 0x00 +#define MAP_LIQUID_TYPE_WATER 0x01 +#define MAP_LIQUID_TYPE_OCEAN 0x02 +#define MAP_LIQUID_TYPE_MAGMA 0x04 +#define MAP_LIQUID_TYPE_SLIME 0x08 + +#define MAP_LIQUID_TYPE_DARK_WATER 0x10 +#define MAP_LIQUID_TYPE_WMO_WATER 0x20 + + +#define MAP_LIQUID_NO_TYPE 0x0001 +#define MAP_LIQUID_NO_HIGHT 0x0002 + +struct map_liquidHeader{ + uint32 fourcc; + uint16 flags; + uint16 liquidType; + uint8 offsetX; + uint8 offsetY; + uint8 width; + uint8 height; + float liquidLevel; +}; + +float selectUInt8StepStore(float maxDiff) +{ + return 255 / maxDiff; +} + +float selectUInt16StepStore(float maxDiff) +{ + return 65535 / maxDiff; +} +// Temporary grid data store +uint16 area_flags[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]; + +float V8[ADT_GRID_SIZE][ADT_GRID_SIZE]; +float V9[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1]; +uint16 uint16_V8[ADT_GRID_SIZE][ADT_GRID_SIZE]; +uint16 uint16_V9[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1]; +uint8 uint8_V8[ADT_GRID_SIZE][ADT_GRID_SIZE]; +uint8 uint8_V9[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1]; + +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) +{ + ADT_file adt; + + if (!adt.loadFile(filename)) + return false; + + adt_MCIN *cells = adt.a_grid->getMCIN(); + if (!cells) + { + printf("Can't find cells in '%s'\n", filename); + return false; + } + + memset(liquid_show, 0, sizeof(liquid_show)); + memset(liquid_type, 0, sizeof(liquid_type)); + + // Prepare map header + map_fileheader map; + map.mapMagic = MAP_MAGIC; + map.versionMagic = MAP_VERSION_MAGIC; + + // Get area flags data + for (int i=0;i<ADT_CELLS_PER_GRID;i++) + { + for(int j=0;j<ADT_CELLS_PER_GRID;j++) + { + adt_MCNK * cell = cells->getMCNK(i,j); + uint32 areaid = cell->areaid; + if(areaid && areaid <= maxAreaId) + { + if(areas[areaid] != 0xffff) + { + area_flags[i][j] = areas[areaid]; + continue; + } + printf("File: filename\nCan't find area flag for areaid %u [%d, %d].\n", filename, areaid, cell->ix, cell->iy); + } + area_flags[i][j] = 0xffff; + } + } + //============================================ + // Try pack area data + //============================================ + bool fullAreaData = false; + uint32 areaflag = area_flags[0][0]; + for (int y=0;y<ADT_CELLS_PER_GRID;y++) + { + for(int x=0;x<ADT_CELLS_PER_GRID;x++) + { + if(area_flags[y][x]!=areaflag) + { + fullAreaData = true; + break; + } + } + } + + map.areaMapOffset = sizeof(map); + map.areaMapSize = sizeof(map_areaHeader); + + map_areaHeader areaHeader; + areaHeader.fourcc = MAP_AREA_MAGIC; + areaHeader.flags = 0; + if (fullAreaData) + { + areaHeader.gridArea = 0; + map.areaMapSize+=sizeof(area_flags); + } + else + { + areaHeader.flags |= MAP_AREA_NO_AREA; + areaHeader.gridArea = (uint16)areaflag; + } + + // + // Get Height map from grid + // + for (int i=0;i<ADT_CELLS_PER_GRID;i++) + { + for(int j=0;j<ADT_CELLS_PER_GRID;j++) + { + adt_MCNK * cell = cells->getMCNK(i,j); + if (!cell) + continue; + // Height values for triangles stored in order: + // 1 2 3 4 5 6 7 8 9 + // 10 11 12 13 14 15 16 17 + // 18 19 20 21 22 23 24 25 26 + // 27 28 29 30 31 32 33 34 + // . . . . . . . . + // For better get height values merge it to V9 and V8 map + // V9 height map: + // 1 2 3 4 5 6 7 8 9 + // 18 19 20 21 22 23 24 25 26 + // . . . . . . . . + // V8 height map: + // 10 11 12 13 14 15 16 17 + // 27 28 29 30 31 32 33 34 + // . . . . . . . . + + // Set map height as grid height + for (int y=0; y <= ADT_CELL_SIZE; y++) + { + int cy = i*ADT_CELL_SIZE + y; + for (int x=0; x <= ADT_CELL_SIZE; x++) + { + int cx = j*ADT_CELL_SIZE + x; + V9[cy][cx]=cell->ypos; + } + } + for (int y=0; y < ADT_CELL_SIZE; y++) + { + int cy = i*ADT_CELL_SIZE + y; + for (int x=0; x < ADT_CELL_SIZE; x++) + { + int cx = j*ADT_CELL_SIZE + x; + V8[cy][cx]=cell->ypos; + } + } + // Get custom height + adt_MCVT *v = cell->getMCVT(); + if (!v) + continue; + // get V9 height map + for (int y=0; y <= ADT_CELL_SIZE; y++) + { + int cy = i*ADT_CELL_SIZE + y; + for (int x=0; x <= ADT_CELL_SIZE; x++) + { + int cx = j*ADT_CELL_SIZE + x; + V9[cy][cx]+=v->height_map[y*(ADT_CELL_SIZE*2+1)+x]; + } + } + // get V8 height map + for (int y=0; y < ADT_CELL_SIZE; y++) + { + int cy = i*ADT_CELL_SIZE + y; + for (int x=0; x < ADT_CELL_SIZE; x++) + { + int cx = j*ADT_CELL_SIZE + x; + V8[cy][cx]+=v->height_map[y*(ADT_CELL_SIZE*2+1)+ADT_CELL_SIZE+1+x]; + } + } + } + } + //============================================ + // Try pack height data + //============================================ + float maxHeight = -20000; + float minHeight = 20000; + for (int y=0; y<ADT_GRID_SIZE; y++) + { + for(int x=0;x<ADT_GRID_SIZE;x++) + { + float h = V8[y][x]; + if (maxHeight < h) maxHeight = h; + if (minHeight > h) minHeight = h; + } + } + for (int y=0; y<=ADT_GRID_SIZE; y++) + { + for(int x=0;x<=ADT_GRID_SIZE;x++) + { + float h = V9[y][x]; + if (maxHeight < h) maxHeight = h; + if (minHeight > h) minHeight = h; + } + } + + // Check for allow limit minimum height (not store height in deep ochean - allow save some memory) + if (CONF_allow_height_limit && minHeight < CONF_use_minHeight) + { + for (int y=0; y<ADT_GRID_SIZE; y++) + for(int x=0;x<ADT_GRID_SIZE;x++) + if (V8[y][x] < CONF_use_minHeight) + V8[y][x] = CONF_use_minHeight; + for (int y=0; y<=ADT_GRID_SIZE; y++) + for(int x=0;x<=ADT_GRID_SIZE;x++) + if (V9[y][x] < CONF_use_minHeight) + V9[y][x] = CONF_use_minHeight; + if (minHeight < CONF_use_minHeight) + minHeight = CONF_use_minHeight; + if (maxHeight < CONF_use_minHeight) + maxHeight = CONF_use_minHeight; + } + + map.heightMapOffset = map.areaMapOffset + map.areaMapSize; + map.heightMapSize = sizeof(map_heightHeader); + + map_heightHeader heightHeader; + heightHeader.fourcc = MAP_HEIGTH_MAGIC; + heightHeader.flags = 0; + heightHeader.gridHeight = minHeight; + heightHeader.gridMaxHeight = maxHeight; + + if (maxHeight == minHeight) + heightHeader.flags |=MAP_HEIGHT_NO_HIGHT; + + // Not need store if flat surface + if (CONF_allow_float_to_int && (maxHeight - minHeight) < CONF_flat_height_delta_limit) + heightHeader.flags |=MAP_HEIGHT_NO_HIGHT; + + // Try store as packed in uint16 or uint8 values + if (!(heightHeader.flags&MAP_HEIGHT_NO_HIGHT)) + { + float step; + // Try Store as uint values + if (CONF_allow_float_to_int) + { + float diff = maxHeight - minHeight; + if (diff < CONF_float_to_int8_limit) // As uint8 (max accuracy = CONF_float_to_int8_limit/256) + { + heightHeader.flags|=MAP_HEIGHT_AS_INT8; + step = selectUInt8StepStore(diff); + } + else if (diff<CONF_float_to_int16_limit) // As uint16 (max accuracy = CONF_float_to_int16_limit/65536) + { + heightHeader.flags|=MAP_HEIGHT_AS_INT16; + step = selectUInt16StepStore(diff); + } + } + + // Pack it to int values if need + if (heightHeader.flags&MAP_HEIGHT_AS_INT8) + { + for (int y=0; y<ADT_GRID_SIZE; y++) + for(int x=0;x<ADT_GRID_SIZE;x++) + uint8_V8[y][x] = uint8((V8[y][x] - minHeight) * step + 0.5f); + for (int y=0; y<=ADT_GRID_SIZE; y++) + for(int x=0;x<=ADT_GRID_SIZE;x++) + uint8_V9[y][x] = uint8((V9[y][x] - minHeight) * step + 0.5f); + map.heightMapSize+= sizeof(uint8_V9) + sizeof(uint8_V8); + } + else if (heightHeader.flags&MAP_HEIGHT_AS_INT16) + { + for (int y=0; y<ADT_GRID_SIZE; y++) + for(int x=0;x<ADT_GRID_SIZE;x++) + uint16_V8[y][x] = uint16((V8[y][x] - minHeight) * step + 0.5f); + for (int y=0; y<=ADT_GRID_SIZE; y++) + for(int x=0;x<=ADT_GRID_SIZE;x++) + uint16_V9[y][x] = uint16((V9[y][x] - minHeight) * step + 0.5f); + map.heightMapSize+= sizeof(uint16_V9) + sizeof(uint16_V8); + } + else + map.heightMapSize+= sizeof(V9) + sizeof(V8); + } + + // Get liquid map for grid (in WOTLK used MH2O chunk) + adt_MH2O * h2o = adt.a_grid->getMH2O(); + if (h2o) + { + for (int i=0;i<ADT_CELLS_PER_GRID;i++) + { + for(int j=0;j<ADT_CELLS_PER_GRID;j++) + { + adt_liquid_header *h = h2o->getLiquidData(i,j); + if (!h) + continue; + + int count = 0; + uint64 show = h2o->getLiquidShowMap(h); + for (int y=0; y < h->height;y++) + { + int cy = i*ADT_CELL_SIZE + y + h->yOffset; + for (int x=0; x < h->width; x++) + { + int cx = j*ADT_CELL_SIZE + x + h->xOffset; + if (show & 1) + { + liquid_show[cy][cx] = true; + ++count; + } + show>>=1; + } + } + + uint32 type = LiqType[h->liquidType]; + switch (type) + { + case LIQUID_TYPE_WATER: liquid_type[i][j] |= MAP_LIQUID_TYPE_WATER; break; + case LIQUID_TYPE_OCEAN: liquid_type[i][j] |= MAP_LIQUID_TYPE_OCEAN; break; + case LIQUID_TYPE_MAGMA: liquid_type[i][j] |= MAP_LIQUID_TYPE_MAGMA; break; + case LIQUID_TYPE_SLIME: liquid_type[i][j] |= MAP_LIQUID_TYPE_SLIME; break; + default: + printf("\nCan't find Liquid type %u for map %s\nchunk %d,%d\n", h->liquidType, filename, i, j); + break; + } + // Dark water detect + if (type == LIQUID_TYPE_OCEAN) + { + uint8 *lm = h2o->getLiquidLightMap(h); + if (!lm) + liquid_type[i][j]|=MAP_LIQUID_TYPE_DARK_WATER; + } + + if (!count && liquid_type[i][j]) + printf("Wrong liquid detect in MH2O chunk"); + + float *height = h2o->getLiquidHeightMap(h); + int pos = 0; + for (int y=0; y<=h->height;y++) + { + int cy = i*ADT_CELL_SIZE + y + h->yOffset; + for (int x=0; x<= h->width; x++) + { + int cx = j*ADT_CELL_SIZE + x + h->xOffset; + if (height) + liquid_height[cy][cx] = height[pos]; + else + liquid_height[cy][cx] = h->heightLevel1; + pos++; + } + } + } + } + } + else + { + // Get from MCLQ chunk (old) + for (int i=0;i<ADT_CELLS_PER_GRID;i++) + { + for(int j=0;j<ADT_CELLS_PER_GRID;j++) + { + adt_MCNK *cell = cells->getMCNK(i, j); + if (!cell) + continue; + + adt_MCLQ *liquid = cell->getMCLQ(); + int count = 0; + if (!liquid || cell->sizeMCLQ <= 8) + continue; + + for (int y=0; y < ADT_CELL_SIZE; y++) + { + int cy = i*ADT_CELL_SIZE + y; + for (int x=0; x < ADT_CELL_SIZE; x++) + { + int cx = j*ADT_CELL_SIZE + x; + if (liquid->flags[y][x] != 0x0F) + { + liquid_show[cy][cx] = true; + if (liquid->flags[y][x]&(1<<7)) + liquid_type[i][j]|=MAP_LIQUID_TYPE_DARK_WATER; + ++count; + } + } + } + + uint32 c_flag = cell->flags; + if(c_flag & (1<<2)) + liquid_type[i][j]|=MAP_LIQUID_TYPE_WATER; // water + if(c_flag & (1<<3)) + liquid_type[i][j]|=MAP_LIQUID_TYPE_OCEAN; // ochean + if(c_flag & (1<<4)) + liquid_type[i][j]|=MAP_LIQUID_TYPE_MAGMA; // magma/slime + + if (!count && liquid_type[i][j]) + printf("Wrong liquid detect in MCLQ chunk"); + + for (int y=0; y <= ADT_CELL_SIZE; y++) + { + int cy = i*ADT_CELL_SIZE + y; + for (int x=0; x<= ADT_CELL_SIZE; x++) + { + int cx = j*ADT_CELL_SIZE + x; + liquid_height[cy][cx] = liquid->liquid[y][x].height; + } + } + } + } + } + + //============================================ + // Pack liquid data + //============================================ + uint8 type = liquid_type[0][0]; + bool fullType = false; + for (int y=0;y<ADT_CELLS_PER_GRID;y++) + { + for(int x=0;x<ADT_CELLS_PER_GRID;x++) + { + if (liquid_type[y][x]!=type) + { + fullType = true; + y = ADT_CELLS_PER_GRID; + break; + } + } + } + + map_liquidHeader liquidHeader; + + // no water data (if all grid have 0 liquid type) + if (type == 0 && !fullType) + { + // No liquid data + map.liquidMapOffset = 0; + map.liquidMapSize = 0; + } + else + { + int minX = 255, minY = 255; + int maxX = 0, maxY = 0; + maxHeight = -20000; + minHeight = 20000; + for (int y=0; y<ADT_GRID_SIZE; y++) + { + for(int x=0; x<ADT_GRID_SIZE; x++) + { + if (liquid_show[y][x]) + { + if (minX > x) minX = x; + if (maxX < x) maxX = x; + if (minY > y) minY = y; + if (maxY < y) maxY = y; + float h = liquid_height[y][x]; + if (maxHeight < h) maxHeight = h; + if (minHeight > h) minHeight = h; + } + else + liquid_height[y][x] = CONF_use_minHeight; + } + } + map.liquidMapOffset = map.heightMapOffset + map.heightMapSize; + map.liquidMapSize = sizeof(map_liquidHeader); + liquidHeader.fourcc = MAP_LIQUID_MAGIC; + liquidHeader.flags = 0; + liquidHeader.liquidType = 0; + liquidHeader.offsetX = minX; + liquidHeader.offsetY = minY; + liquidHeader.width = maxX - minX + 1; + liquidHeader.height = maxY - minY + 1; + liquidHeader.liquidLevel = minHeight; + + if (maxHeight == minHeight) + liquidHeader.flags|=MAP_LIQUID_NO_HIGHT; + + // Not need store if flat surface + if (CONF_allow_float_to_int && (maxHeight - minHeight) < CONF_flat_liquid_delta_limit) + liquidHeader.flags|=MAP_LIQUID_NO_HIGHT; + + if (!fullType) + liquidHeader.flags|=MAP_LIQUID_NO_TYPE; + + if (liquidHeader.flags&MAP_LIQUID_NO_TYPE) + liquidHeader.liquidType = type; + else + map.liquidMapSize+=sizeof(liquid_type); + + if (!(liquidHeader.flags&MAP_LIQUID_NO_HIGHT)) + map.liquidMapSize+=sizeof(float)*liquidHeader.width*liquidHeader.height; + } + + // Ok all data prepared - store it + FILE *output=fopen(filename2, "wb"); + if(!output) + { + printf("Can't create the output file '%s'\n", filename2); + return false; + } + fwrite(&map, sizeof(map), 1, output); + // Store area data + fwrite(&areaHeader, sizeof(areaHeader), 1, output); + if (!(areaHeader.flags&MAP_AREA_NO_AREA)) + fwrite(area_flags, sizeof(area_flags), 1, output); + + // Store height data + fwrite(&heightHeader, sizeof(heightHeader), 1, output); + if (!(heightHeader.flags&MAP_HEIGHT_NO_HIGHT)) + { + if (heightHeader.flags&MAP_HEIGHT_AS_INT16) + { + fwrite(uint16_V9, sizeof(uint16_V9), 1, output); + fwrite(uint16_V8, sizeof(uint16_V8), 1, output); + } + else if (heightHeader.flags&MAP_HEIGHT_AS_INT8) + { + fwrite(uint8_V9, sizeof(uint8_V9), 1, output); + fwrite(uint8_V8, sizeof(uint8_V8), 1, output); + } + else + { + fwrite(V9, sizeof(V9), 1, output); + fwrite(V8, sizeof(V8), 1, output); + } + } + + // Store liquid data if need + if (map.liquidMapOffset) + { + fwrite(&liquidHeader, sizeof(liquidHeader), 1, output); + if (!(liquidHeader.flags&MAP_LIQUID_NO_TYPE)) + fwrite(liquid_type, sizeof(liquid_type), 1, output); + if (!(liquidHeader.flags&MAP_LIQUID_NO_HIGHT)) + { + for (int y=0; y<liquidHeader.height;y++) + fwrite(&liquid_height[y+liquidHeader.offsetY][liquidHeader.offsetX], sizeof(float), liquidHeader.width, output); + } + } + fclose(output); + + return true; +} + void ExtractMapsFromMpq() { char mpq_filename[1024]; char output_filename[1024]; + char mpq_map_name[1024]; printf("Extracting maps...\n"); uint32 map_count = ReadMapDBC(); ReadAreaTableDBC(); - - unsigned int total=map_count*ADT_RES*ADT_RES; - unsigned int done=0; + ReadLiquidTypeTableDBC(); std::string path = output_path; path += "/maps/"; CreateDir(path); - for(unsigned int x = 0; x < ADT_RES; ++x) + printf("Convert map files\n"); + for(uint32 z = 0; z < map_count; ++z) { - for(unsigned int y = 0; y < ADT_RES; ++y) + printf("Extract %s (%d/%d) \n", map_ids[z].name, z+1, map_count); + // Loadup map grid data + sprintf(mpq_map_name, "World\\Maps\\%s\\%s.wdt", map_ids[z].name, map_ids[z].name); + WDT_file wdt; + if (!wdt.loadFile(mpq_map_name, false)) { - for(unsigned int z = 0; z < map_count; ++z) +// printf("Error loading %s map wdt data\n", map_ids[z].name); + continue; + } + + for(uint32 y = 0; y < WDT_MAP_SIZE; ++y) + { + for(uint32 x = 0; x < WDT_MAP_SIZE; ++x) { - 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); - done++; + if (!wdt.main->adt_list[y][x].exist) + 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); } - //draw progess bar - printf("Processing........................%d%%\r",(100*done)/total); + // draw progress bar + printf("Processing........................%d%%\r", (100 * (y+1)) / WDT_MAP_SIZE); } } - delete [] areas; delete [] map_ids; } -//bool WMO(char* filename); - void ExtractDBCFiles(int locale, bool basicLocale) { printf("Extracting dbc files...\n"); @@ -222,7 +906,7 @@ void ExtractDBCFiles(int locale, bool basicLocale) string filename = path; filename += (iter->c_str() + strlen("DBFilesClient\\")); - FILE *output=fopen(filename.c_str(), "wb"); + FILE *output = fopen(filename.c_str(), "wb"); if(!output) { printf("Can't create the output file '%s'\n", filename.c_str()); @@ -260,18 +944,10 @@ void LoadLocaleMPQFiles(int const locale) void LoadCommonMPQFiles() { char filename[512]; - - sprintf(filename,"%s/Data/common.MPQ", input_path); - new MPQArchive(filename); - sprintf(filename,"%s/Data/expansion.MPQ", input_path); - new MPQArchive(filename); - for(int i = 1; i < 5; ++i) + int count = sizeof(CONF_mpq_list)/sizeof(char*); + for(int i = 0; i < count; ++i) { - char ext[3] = ""; - if(i > 1) - sprintf(ext, "-%i", i); - - sprintf(filename,"%s/Data/patch%s.MPQ", input_path, ext); + sprintf(filename, "%s/Data/%s", input_path, CONF_mpq_list[i]); if(FileExists(filename)) new MPQArchive(filename); } @@ -303,7 +979,7 @@ int main(int argc, char * arg[]) //Open MPQs LoadLocaleMPQFiles(i); - if((extract & EXTRACT_DBC) == 0) + if((CONF_extract & EXTRACT_DBC) == 0) { FirstLocale = i; break; @@ -329,7 +1005,7 @@ int main(int argc, char * arg[]) return 0; } - if (extract & EXTRACT_MAP) + if (CONF_extract & EXTRACT_MAP) { printf("Using locale: %s\n", langs[FirstLocale]); diff --git a/contrib/extractor/VC71_ad.vcproj b/contrib/extractor/VC71_ad.vcproj index fd2d16120e8..541540ceaa2 100644 --- a/contrib/extractor/VC71_ad.vcproj +++ b/contrib/extractor/VC71_ad.vcproj @@ -213,7 +213,15 @@ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" > <File - RelativePath=".\adt.cpp" + RelativePath=".\loadlib\loadlib.cpp" + > + </File> + <File + RelativePath=".\loadlib\adt.cpp" + > + </File> + <File + RelativePath=".\loadlib\wdt.cpp" > </File> <File diff --git a/contrib/extractor/VC80_ad.vcproj b/contrib/extractor/VC80_ad.vcproj index fedab5b89eb..a20ff016ca8 100644 --- a/contrib/extractor/VC80_ad.vcproj +++ b/contrib/extractor/VC80_ad.vcproj @@ -218,7 +218,7 @@ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" > <File - RelativePath=".\adt.cpp" + RelativePath=".\loadlib\adt.cpp" > </File> <File @@ -226,6 +226,10 @@ > </File> <File + RelativePath=".\loadlib\loadlib.cpp" + > + </File> + <File RelativePath=".\mpq_libmpq.cpp" > </File> @@ -253,6 +257,10 @@ /> </FileConfiguration> </File> + <File + RelativePath=".\loadlib\wdt.cpp" + > + </File> <Filter Name="libmpq" > diff --git a/contrib/extractor/VC90_ad.vcproj b/contrib/extractor/VC90_ad.vcproj index 59fdf6d21f1..9a039a0fbb0 100644 --- a/contrib/extractor/VC90_ad.vcproj +++ b/contrib/extractor/VC90_ad.vcproj @@ -216,7 +216,15 @@ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" > <File - RelativePath=".\adt.cpp" + RelativePath=".\loadlib\loadlib.cpp" + > + </File> + <File + RelativePath=".\loadlib\adt.cpp" + > + </File> + <File + RelativePath=".\loadlib\wdt.cpp" > </File> <File diff --git a/contrib/extractor/ad.exe b/contrib/extractor/ad.exe Binary files differindex f0a7e4408ce..208eb2da030 100644 --- a/contrib/extractor/ad.exe +++ b/contrib/extractor/ad.exe diff --git a/contrib/extractor/adt.cpp b/contrib/extractor/adt.cpp index a8f640a63bc..fcbfc95a072 100644 --- a/contrib/extractor/adt.cpp +++ b/contrib/extractor/adt.cpp @@ -15,16 +15,14 @@ #include "adt.h" #include "mpq_libmpq.h" -//#include <windows.h> -unsigned int iRes=256; -extern uint16*areas; +extern uint16 *areas; +extern uint16 *LiqType; +extern uint32 maxAreaId; vec wmoc; -Cell * cell; -uint32 wmo_count; +Cell *cell; mcell *mcells; - int holetab_h[4] = {0x1111, 0x2222, 0x4444, 0x8888}; int holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000}; @@ -35,168 +33,154 @@ bool LoadADT(char* filename) if(mf.isEof()) { - //printf("No such file.\n"); + //printf("No such file %s\n", filename); return false; } - mcells=new mcell; - wmoc.x =65*TILESIZE; - wmoc.z =65*TILESIZE; + 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]; - wmo_count=0; - bool found=false; - //uint32 fs=mf.getSize()-3; - //while (mf.getPos()<fs) + chunk_num = 0; + k = 0; + m = 0; while (!mf.isEof()) { uint32 fourcc; - mf.read(&fourcc,4); + mf.read(&fourcc, 4); mf.read(&size, 4); size_t nextpos = mf.getPos() + size; - switch(fourcc) + + //if(fourcc==0x4d484452) // MHDR header + //if(fourcc==0x4d564552) // MVER + if(fourcc == 0x4d43494e) // MCIN { - case 0x4d43494e: // MCIN + for (uint32 i = 0; i < 256; ++i) { - //printf("Found chunks info\n"); - // mapchunk offsets/sizes - for (int i=0; i<256; i++) - { - mf.read(&mcnk_offsets[i],4); - mf.read(&mcnk_sizes[i],4); - mf.seekRelative(8); - } - break; + mf.read(&mcnk_offsets[i], 4); + mf.read(&mcnk_sizes[i], 4); + mf.seekRelative(8); } - case 0x4d4f4446: // MODF + } + //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) { - /* - if(size) + mf.read(LiqOffsData, 0x0C); + header_pos = mf.getPos(); + if(LiqOffsData->offsData1 != 0) // если данные ?Data1 ?воде есть, то их надо конвертировать { - //printf("\nwmo count %d\n",size/64); - wmo_count =size/64; - for (int i=0; i<wmo_count; i++) + // перехо?по смещению из 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) { - int id; - mf.read(&id, 4); - WMO *wmo = (WMO*)wmomanager.items[wmomanager.get(wmos[id])]; - WMOInstance inst(wmo, mf); - wmois.push_back(inst); + 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 + } - }*/ - break; - } - case 0x4d574d4f: // MWMO - { - /* - if (size) + 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 не заноси?тк он?дублируется след куском { - char *buf = new char[size]; - mf.read(buf, size); - char *p=buf; - while (p<buf+size) + for(int s = 0; s < 8; ++s) // 9 значение ?строке не заноси?тк он?дублируется след куском, ??првы?боковы?обрезает? для 128?28 { - std::string path(p); - p+=strlen(p)+1; - fixname(path); - - wmomanager.add(path); - wmos.push_back(path); + MapLiqHeight[k] = ChunkLiqHeight[p + s]; + ++k; } - delete[] buf; - }*/ - break; - } - case 0x4d564552: // MVER - case 0x4d484452: // MHDR header - case 0x4d434e4b: // MCNK - case 0x4d544558: // MTEX textures (strings) - case 0x4d4d4458: // MMDX m2 models (strings) - case 0x4d4d4944: // MMID offsets for strings in MMDX - case 0x4d574944: // MWID offsets for strings in MWMO - case 0x4d444446: // MDDF - case 0x4d46424f: // MFBO new in BC - case 0x4d48324f: // MH2O new in WotLK - break; - default: - { - // mf.seekRelative(-3); - printf("Unhandled map chunk: %u\n",fourcc); - break; + 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 - for (int j=0; j<16; j++) - for (int i=0; i<16; i++) + 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])); + mf.seek((int)mcnk_offsets[j * 16 + i]); + LoadMapChunk(mf, &(mcells->ch[i][j])); + ++chunk_num; } - - /* - for(uint32 t=0;t<wmo_count ;t++) - { - wmois[t].draw(); - }*/ - + } mf.close(); return true; } -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; - uint32 sizeLiquid; - float zpos; - float xpos; - float ypos; - uint32 textureId; - uint32 props; - uint32 effectId; -}; - 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; + 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) +inline void LoadMapChunk(MPQFile &mf, chunk *_chunk) { float h; uint32 fourcc; @@ -207,298 +191,191 @@ void LoadMapChunk(MPQFile & mf, chunk*_chunk) mf.read(&size, 4); size_t lastpos = mf.getPos() + size; - mf.read(&header, 0x80); - _chunk->area_id =header.areaid ; - _chunk->flag =0; + 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; + 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; - float zmin=999999999.0f; - float zmax=-999999999.0f; - //must be there, bl!zz uses some crazy format - int nTextures; + //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(&fourcc, 4); mf.read(&size, 4); - //if(size!=580) - // printf("\n sz=%d",size); - size_t nextpos = mf.getPos() + size; - if(fourcc==0x4d435654) // MCVT + 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++) + 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) + mf.read(&h, 4); + float z = h + ybase; + if (j % 2) { - if(isHole(header.holes,i,j)) - _chunk->v8[i][j/2] = -1000; + if(isHole(header.holes, i, j)) + _chunk->v8[i][j / 2] = -1000; else - _chunk->v8[i][j/2] = z; + _chunk->v8[i][j / 2] = z; } else { - if(isHole(header.holes,i,j)) - _chunk->v9[i][j/2] = -1000; + if(isHole(header.holes, i, j)) + _chunk->v9[i][j / 2] = -1000; else - _chunk->v9[i][j/2] = z; + _chunk->v9[i][j / 2] = z; } - if(z>zmax)zmax=z; - //if(z<zmin)zmin=z; + if(z > zmax) zmax = z; + //if(z < zmin) zmin = z; } + } } - else if(fourcc==0x4d434e52) // MCNR + else if(fourcc == 0x4d434e52) // MCNR { - nextpos = mf.getPos() + 0x1C0; // size fix + nextpos = mf.getPos() + 0x1C0; // size fix } - else if(fourcc==0x4d434c51) // MCLQ + else if(fourcc == 0x4d434c51) // не буде?учитыват?если уж?были данные ?MH2O, перестраховк?:) // MCLQ { // liquid / water level - //bool haswater; char fcc1[5]; - mf.read(fcc1,4); + mf.read(fcc1, 4); flipcc(fcc1); - fcc1[4]=0; + fcc1[4] = 0; + float *ChunkLiqHeight = new float[81]; - if (!strcmp(fcc1,"MCSE")) + if (!strcmp(fcc1, "MCSE")) { - for(int i=0;i<9;i++) - for(int j=0;j<9;j++) - _chunk->waterlevel[i][j]=-999999; // no liquid/water + 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); - for(int j=0;j<9;j++) - for(int i=0;i<9;i++) - { - mf.read(&h, 4); - mf.read(&h, 4); - if(h > maxheight) - _chunk->waterlevel[i][j]=-999999; - else - _chunk->waterlevel[i][j]=h; - } + if(liq.height > maxheight) + ChunkLiqHeight[j] = -999999; + else + ChunkLiqHeight[j] = h; + } if(chunkflags & 4 || chunkflags & 8) - _chunk->flag |=1; + MapLiqFlag[chunk_num] |= 1; // water if(chunkflags & 16) - _chunk->flag |=2; - + 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; } - else if (fourcc==0x4d434c59) // MCLY - { - // texture info - nTextures = (int)size; - } - else if (fourcc==0x4d43414c) // MCAL - { - if (nTextures<=0) - continue; - } - mf.seek(nextpos); } } -double solve (vec *v,vec *p) +inline void TransformData() { - double a = v[0].y *(v[1].z - v[2].z) + v[1].y *(v[2].z - v[0].z) + v[2].y *(v[0].z - v[1].z); - double b = v[0].z *(v[1].x - v[2].x) + v[1].z *(v[2].x - v[0].x) + v[2].z *(v[0].x - v[1].x); - double c = v[0].x *(v[1].y - v[2].y) + v[1].x *(v[2].y - v[0].y) + v[2].x *(v[0].y - v[1].y); - double d = v[0].x *(v[1].y*v[2].z - v[2].y*v[1].z) + v[1].x* (v[2].y*v[0].z - v[0].y*v[2].z) + v[2].x* (v[0].y*v[1].z - v[1].y*v[0].z); - //-d - - //plane equation ax+by+cz+d=0 - return ((a*p->x+c*p->z-d)/b); -} - -inline -double GetZ(double x,double z) -{ - vec v[3]; - vec p; - - //bool inWMO=false; + cell = new Cell; - //if(!inWMO) + for(uint32 x = 0; x < 128; ++x) { - //find out quadrant - int xc=(int)(x/UNITSIZE); - int zc=(int)(z/UNITSIZE); - if(xc>127)xc=127; - if(zc>127)zc=127; - - double lx=x-xc*UNITSIZE; - double lz=z-zc*UNITSIZE; - p.x=lx; - p.z=lz; - - v[0].x=UNITSIZE/2; - v[0].y =cell->v8[xc][zc]; - v[0].z=UNITSIZE/2; - - if(lx>lz) + for(uint32 y = 0; y < 128; ++y) { - v[1].x=UNITSIZE; - v[1].y =cell->v9[xc+1][zc]; - v[1].z=0; - } - else - { - v[1].x=0.0; - v[1].y =cell->v9[xc][zc+1]; - v[1].z=UNITSIZE; - } - - if(lz>UNITSIZE-lx) - { - v[2].x=UNITSIZE; - v[2].y =cell->v9[xc+1][zc+1]; - v[2].z=UNITSIZE; - } - else - { - v[2].x=0; - v[2].y=cell->v9[xc][zc]; - v[2].z=0; + 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]; } - return -solve(v,&p); + // 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]; } -} - -inline -void TransformWaterData() -{ - cell= new Cell; - for(int x=0;x<128;x++) - for(int y=0;y<128;y++) - cell->v9[x][y] = mcells->ch[x/8][y/8].waterlevel[x%8][y%8]; - - //and the last 1 - cell->v9[128][128] = mcells->ch[15][15].waterlevel[8][8]; -} - -inline -void TransformData() -{ - cell= new Cell; - - for(int x=0;x<128;x++) - { - for(int 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 + // and the last 1 cell->v9[128][128] = (float)mcells->ch[15][15].v9[8][8]; delete mcells; } -const char MAP_MAGIC[] = "MAP_2.50"; +const char MAP_MAGIC[] = "MAP_3.00"; -bool ConvertADT(char * filename,char * filename2) +bool ConvertADT(char *filename, char *filename2) { - //if(!strstr(filename,"oth_32_48"))return false; if(!LoadADT(filename)) return false; - FILE *output=fopen(filename2,"wb"); + FILE *output=fopen(filename2, "wb"); if(!output) { - printf("Can't create the output file '%s'\n",filename2); + 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); + fwrite(MAP_MAGIC, 1, 8, output); - for(unsigned int x=0;x<16;x++) + for(uint32 x = 0; x < 16; ++x) { - for(unsigned int y=0;y<16;y++) + for(uint32 y = 0; y < 16; ++y) { - if(mcells->ch[y][x].area_id && mcells->ch[y][x].area_id < 0x102D) + 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); + 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); + fwrite(&areas[mcells->ch[y][x].area_id], 1, 2, output); } else { - uint16 flag=0xffff; - fwrite(&flag,1,2,output); + uint16 flag = 0xffff; + fwrite(&flag, 1, 2, output); } } } - for(unsigned int x=0;x<16;x++) - for(unsigned int y=0;y<16;y++) - fwrite(&mcells->ch[y][x].flag,1,1,output); - - TransformWaterData(); + fwrite(MapLiqFlag, 1, 256, output); + delete [] MapLiqFlag; - for(unsigned int x=0;x<128;x++) - for(unsigned int y=0;y<128;y++) - fwrite(&cell->v9[y][x],1,sizeof(float),output); + fwrite(MapLiqHeight, sizeof(float), 16384, output); + delete [] MapLiqHeight; - delete cell; TransformData(); - /* - for(unsigned int x=0;x<iRes;x++) - for(unsigned int y=0;y<iRes;y++) - { - float z=(float)GetZ( - (((double)(y))*TILESIZE)/((double)(iRes-1)), - (((double)(x))*TILESIZE)/((double)(iRes-1))); - - fwrite(&z,1,sizeof(z),output); - }*/ fwrite(&cell->v9, 1, sizeof(cell->v9), output); fwrite(&cell->v8, 1, sizeof(cell->v8), output); fclose(output); delete cell; -/* - for (std::vector<std::string>::iterator it = wmos.begin(); it != wmos.end(); ++it) - wmomanager.delbyname(*it); - - wmos.clear(); - wmois.clear(); - - for (std::vector<model>::iterator it = wmomodel.begin(); it != wmomodel.end(); ++it) - { - it->tr.clear(); - - } - //printf("\n %d \n",in); - wmomodel.clear(); - //polygons.clear();*/ + return true; } diff --git a/contrib/extractor/adt.h b/contrib/extractor/adt.h index 9af85b14d8c..516ed88a86e 100644 --- a/contrib/extractor/adt.h +++ b/contrib/extractor/adt.h @@ -9,47 +9,122 @@ 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{ +typedef struct +{ + float x; + float y; + float z; +} svec; + +typedef struct +{ + double x; + double y; + double z; +} vec; + +typedef struct +{ vec v[3]; -}triangle; +} 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{ -float v9[16*8+1][16*8+1]; -float v8[16*8][16*8]; -}Cell; +typedef struct +{ + chunk ch[16][16]; +} mcell; -typedef struct{ -double v9[9][9]; -double v8[8][8]; -uint16 area_id; -//Liquid *lq; -float waterlevel[9][9]; -uint8 flag; -}chunk; +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; +}; -class WMO; -class WMOManager; -void fixname(std::string &name); +typedef struct +{ + uint32 offsData1; + uint32 used; + uint32 offsData2; +} MH2O_offsData; typedef struct { -chunk ch[16][16]; -}mcell; + 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; -void LoadMapChunk(MPQFile &,chunk*); -bool LoadWMO(char* filename); + +float *MapLiqHeight; +uint8 *MapLiqFlag; +uint32 k, m, chunk_num; +void LoadMapChunk(MPQFile &, chunk*); #endif diff --git a/contrib/extractor/dbcfile.cpp b/contrib/extractor/dbcfile.cpp index dbe379d27f7..dd58ac1b4a6 100644 --- a/contrib/extractor/dbcfile.cpp +++ b/contrib/extractor/dbcfile.cpp @@ -9,29 +9,42 @@ DBCFile::DBCFile(const std::string &filename): { } -void DBCFile::open() +bool DBCFile::open() { MPQFile f(filename.c_str()); char header[4]; unsigned int na,nb,es,ss; - f.read(header,4); // Number of records - assert(header[0]=='W' && header[1]=='D' && header[2]=='B' && header[3] == 'C'); - f.read(&na,4); // Number of records - f.read(&nb,4); // Number of fields - f.read(&es,4); // Size of a record - f.read(&ss,4); // String size + if(f.read(header,4)!=4) // Number of records + return false; + + if(header[0]!='W' || header[1]!='D' || header[2]!='B' || header[3]!='C') + return false; + + if(f.read(&na,4)!=4) // Number of records + return false; + if(f.read(&nb,4)!=4) // Number of fields + return false; + if(f.read(&es,4)!=4) // Size of a record + return false; + if(f.read(&ss,4)!=4) // String size + return false; recordSize = es; recordCount = na; fieldCount = nb; stringSize = ss; - assert(fieldCount*4 == recordSize); + if(fieldCount*4 != recordSize) + return false; data = new unsigned char[recordSize*recordCount+stringSize]; stringTable = data + recordSize*recordCount; - f.read(data,recordSize*recordCount+stringSize); + + size_t data_size = recordSize*recordCount+stringSize; + if(f.read(data,data_size)!=data_size) + return false; f.close(); + return true; } DBCFile::~DBCFile() { diff --git a/contrib/extractor/dbcfile.h b/contrib/extractor/dbcfile.h index 7d709e80948..aef61df7aaa 100644 --- a/contrib/extractor/dbcfile.h +++ b/contrib/extractor/dbcfile.h @@ -10,7 +10,7 @@ public: ~DBCFile(); // Open database. It must be openened before it can be used. - void open(); + bool open(); // Database exceptions class Exception diff --git a/contrib/extractor/libmpq/CMakeLists.txt b/contrib/extractor/libmpq/CMakeLists.txt new file mode 100644 index 00000000000..c00120c6e48 --- /dev/null +++ b/contrib/extractor/libmpq/CMakeLists.txt @@ -0,0 +1,13 @@ +# Copyright (C) 2005-2009 MaNGOS project <http://getmangos.com/> +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +add_library (libmpq common.cpp explode.cpp extract.cpp huffman.cpp mpq.cpp parser.cpp wave.cpp ) +# link libmpq with zlib +target_link_libraries (libmpq z) diff --git a/contrib/extractor/libmpq/Makefile b/contrib/extractor/libmpq/Makefile deleted file mode 100644 index eb1965e29f1..00000000000 --- a/contrib/extractor/libmpq/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -CC = g++ -AR = ar -objects = common.o explode.o extract.o huffman.o wave.o mpq.o parser.o -zlib_objects = ../../../dep/src/zlib/*.o #adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o zutil.o inflate.o inftrees.o inffast.o - -all: libmpq.a libmpq.so - -clean: - rm -f libmpq.a libmpq.so *.o - -libmpq.a: $(objects) $(zlib_objects) - $(AR) cru $@ $+ -libmpq.so: $(objects) $(zlib_objects) - $(CC) -fPIC -o $@ $+ - -%.o:%.cpp - $(CC) -I../ -c $+ diff --git a/contrib/extractor/libmpq/mpq.cpp b/contrib/extractor/libmpq/mpq.cpp index eddd92ac483..a59d3dff2f1 100644 --- a/contrib/extractor/libmpq/mpq.cpp +++ b/contrib/extractor/libmpq/mpq.cpp @@ -199,7 +199,7 @@ int libmpq_archive_info(mpq_archive *mpq_a, unsigned int infotype) { /* * This function returns some useful file information. */ -int libmpq_file_info(mpq_archive *mpq_a, unsigned int infotype, const int unsigned number) { +int libmpq_file_info(mpq_archive *mpq_a, unsigned int infotype, const unsigned int number) { int blockindex = number; //-1; int i = 0; mpq_block *mpq_b = NULL; diff --git a/contrib/extractor/loadlib/CMakeLists.txt b/contrib/extractor/loadlib/CMakeLists.txt new file mode 100644 index 00000000000..5680c61d424 --- /dev/null +++ b/contrib/extractor/loadlib/CMakeLists.txt @@ -0,0 +1,13 @@ +# Copyright (C) 2005-2009 MaNGOS project <http://getmangos.com/> +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +add_library (loadlib loadlib.cpp adt.cpp wdt.cpp) +# link loadlib with zlib +target_link_libraries (loadlib z) diff --git a/contrib/extractor/loadlib/adt.cpp b/contrib/extractor/loadlib/adt.cpp new file mode 100644 index 00000000000..fde70681113 --- /dev/null +++ b/contrib/extractor/loadlib/adt.cpp @@ -0,0 +1,131 @@ +#define _CRT_SECURE_NO_DEPRECATE + +#include "adt.h" + +// Helper +int holetab_h[4] = {0x1111, 0x2222, 0x4444, 0x8888}; +int holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000}; + +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; +} + +// +// Adt file loader class +// +ADT_file::ADT_file() +{ + a_grid = 0; +} + +ADT_file::~ADT_file() +{ + free(); +} + +void ADT_file::free() +{ + a_grid = 0; + FileLoader::free(); +} + +// +// Adt file check function +// +bool ADT_file::prepareLoadedData() +{ + // Check parent + if (!FileLoader::prepareLoadedData()) + return false; + + // Check and prepare MHDR + a_grid = (adt_MHDR *)(GetData()+8+version->size); + if (!a_grid->prepareLoadedData()) + return false; + + return true; +} + +bool adt_MHDR::prepareLoadedData() +{ + if (fcc != 'MHDR') + return false; + + if (size!=sizeof(adt_MHDR)-8) + return false; + + // Check and prepare MCIN + if (offsMCIN && !getMCIN()->prepareLoadedData()) + return false; + + // Check and prepare MH2O + if (offsMH2O && !getMH2O()->prepareLoadedData()) + return false; + + return true; +} + +bool adt_MCIN::prepareLoadedData() +{ + if (fcc != 'MCIN') + return false; + + // Check cells data + for (int i=0; i<ADT_CELLS_PER_GRID;i++) + for (int j=0; j<ADT_CELLS_PER_GRID;j++) + if (cells[i][j].offsMCNK && !getMCNK(i,j)->prepareLoadedData()) + return false; + + return true; +} + +bool adt_MH2O::prepareLoadedData() +{ + if (fcc != 'MH2O') + return false; + + // Check liquid data +// for (int i=0; i<ADT_CELLS_PER_GRID;i++) +// for (int j=0; j<ADT_CELLS_PER_GRID;j++) + + return true; +} + +bool adt_MCNK::prepareLoadedData() +{ + if (fcc != 'MCNK') + return false; + + // Check height map + if (offsMCVT && !getMCVT()->prepareLoadedData()) + return false; + // Check liquid data + if (offsMCLQ && !getMCLQ()->prepareLoadedData()) + return false; + + return true; +} + +bool adt_MCVT::prepareLoadedData() +{ + if (fcc != 'MCVT') + return false; + + if (size != sizeof(adt_MCVT)-8) + return false; + + return true; +} + +bool adt_MCLQ::prepareLoadedData() +{ + if (fcc != 'MCLQ') + return false; + + return true; +}
\ No newline at end of file diff --git a/contrib/extractor/loadlib/adt.h b/contrib/extractor/loadlib/adt.h new file mode 100644 index 00000000000..725c5b994ee --- /dev/null +++ b/contrib/extractor/loadlib/adt.h @@ -0,0 +1,289 @@ +#ifndef ADT_H +#define ADT_H + +#include "loadlib.h" + +#define TILESIZE (533.33333f) +#define CHUNKSIZE ((TILESIZE) / 16.0f) +#define UNITSIZE (CHUNKSIZE / 8.0f) + +enum LiquidType +{ + LIQUID_TYPE_WATER = 0, + LIQUID_TYPE_OCEAN = 1, + LIQUID_TYPE_MAGMA = 2, + LIQUID_TYPE_SLIME = 3 +}; + +//************************************************************************************** +// ADT file class +//************************************************************************************** +#define ADT_CELLS_PER_GRID 16 +#define ADT_CELL_SIZE 8 +#define ADT_GRID_SIZE (ADT_CELLS_PER_GRID*ADT_CELL_SIZE) + +// +// Adt file height map chunk +// +class adt_MCVT +{ + union{ + uint32 fcc; + char fcc_txt[4]; + }; + uint32 size; +public: + float height_map[(ADT_CELL_SIZE+1)*(ADT_CELL_SIZE+1)+ADT_CELL_SIZE*ADT_CELL_SIZE]; + + bool prepareLoadedData(); +}; + +// +// Adt file liquid map chunk (old) +// +class adt_MCLQ +{ + union{ + uint32 fcc; + char fcc_txt[4]; + }; + uint32 size; +public: + float height1; + float height2; + struct liquid_data{ + uint32 light; + float height; + } liquid[ADT_CELL_SIZE+1][ADT_CELL_SIZE+1]; + + // 1<<0 - ochen + // 1<<1 - lava/slime + // 1<<2 - water + // 1<<6 - all water + // 1<<7 - dark water + // == 0x0F - not show liquid + uint8 flags[ADT_CELL_SIZE][ADT_CELL_SIZE]; + uint8 data[84]; + bool prepareLoadedData(); +}; + +// +// Adt file cell chunk +// +class adt_MCNK +{ + union{ + uint32 fcc; + char fcc_txt[4]; + }; + uint32 size; +public: + uint32 flags; + uint32 ix; + uint32 iy; + uint32 nLayers; + uint32 nDoodadRefs; + uint32 offsMCVT; // height map + uint32 offsMCNR; // Normal vectors for each vertex + uint32 offsMCLY; // Texture layer definitions + uint32 offsMCRF; // A list of indices into the parent file's MDDF chunk + uint32 offsMCAL; // Alpha maps for additional texture layers + uint32 sizeMCAL; + uint32 offsMCSH; // Shadow map for static shadows on the terrain + uint32 sizeMCSH; + uint32 areaid; + uint32 nMapObjRefs; + uint32 holes; + uint16 s[2]; + uint32 data1; + uint32 data2; + uint32 data3; + uint32 predTex; + uint32 nEffectDoodad; + uint32 offsMCSE; + uint32 nSndEmitters; + uint32 offsMCLQ; // Liqid level (old) + uint32 sizeMCLQ; // + float zpos; + float xpos; + float ypos; + uint32 offsMCCV; // offsColorValues in WotLK + uint32 props; + uint32 effectId; + + bool prepareLoadedData(); + adt_MCVT *getMCVT() + { + if (offsMCVT) + return (adt_MCVT *)((uint8 *)this + offsMCVT); + return 0; + } + adt_MCLQ *getMCLQ() + { + if (offsMCLQ) + return (adt_MCLQ *)((uint8 *)this + offsMCLQ); + return 0; + } +}; + +// +// Adt file grid chunk +// +class adt_MCIN +{ + union{ + uint32 fcc; + char fcc_txt[4]; + }; + uint32 size; +public: + struct adt_CELLS{ + uint32 offsMCNK; + uint32 size; + uint32 flags; + uint32 asyncId; + } cells[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]; + + bool prepareLoadedData(); + // offset from begin file (used this-84) + adt_MCNK *getMCNK(int x, int y) + { + if (cells[x][y].offsMCNK) + return (adt_MCNK *)((uint8 *)this + cells[x][y].offsMCNK - 84); + return 0; + } +}; + +#define ADT_LIQUID_HEADER_FULL_LIGHT 0x01 +#define ADT_LIQUID_HEADER_NO_HIGHT 0x02 + +struct adt_liquid_header{ + uint16 liquidType; // Index from LiquidType.dbc + uint16 formatFlags; + float heightLevel1; + float heightLevel2; + uint8 xOffset; + uint8 yOffset; + uint8 width; + uint8 height; + uint32 offsData2a; + uint32 offsData2b; +}; + +// +// Adt file liquid data chunk (new) +// +class adt_MH2O +{ +public: + union{ + uint32 fcc; + char fcc_txt[4]; + }; + uint32 size; + + struct adt_LIQUID{ + uint32 offsData1; + uint32 used; + uint32 offsData2; + } liquid[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]; + + bool prepareLoadedData(); + + adt_liquid_header *getLiquidData(int x, int y) + { + if (liquid[x][y].used && liquid[x][y].offsData1) + return (adt_liquid_header *)((uint8*)this + 8 + liquid[x][y].offsData1); + return 0; + } + + float *getLiquidHeightMap(adt_liquid_header *h) + { + if (h->formatFlags & ADT_LIQUID_HEADER_NO_HIGHT) + return 0; + if (h->offsData2b) + return (float *)((uint8*)this + 8 + h->offsData2b); + return 0; + } + + uint8 *getLiquidLightMap(adt_liquid_header *h) + { + if (h->formatFlags&ADT_LIQUID_HEADER_FULL_LIGHT) + return 0; + if (h->offsData2b) + { + if (h->formatFlags & ADT_LIQUID_HEADER_NO_HIGHT) + return (uint8 *)((uint8*)this + 8 + h->offsData2b); + return (uint8 *)((uint8*)this + 8 + h->offsData2b + (h->width+1)*(h->height+1)*4); + } + return 0; + } + + uint32 *getLiquidFullLightMap(adt_liquid_header *h) + { + if (!(h->formatFlags&ADT_LIQUID_HEADER_FULL_LIGHT)) + return 0; + if (h->offsData2b) + { + if (h->formatFlags & ADT_LIQUID_HEADER_NO_HIGHT) + return (uint32 *)((uint8*)this + 8 + h->offsData2b); + return (uint32 *)((uint8*)this + 8 + h->offsData2b + (h->width+1)*(h->height+1)*4); + } + return 0; + } + + uint64 getLiquidShowMap(adt_liquid_header *h) + { + if (h->offsData2a) + return *((uint64 *)((uint8*)this + 8 + h->offsData2a)); + else + return 0xFFFFFFFFFFFFFFFFLL; + } + +}; + +// +// Adt file header chunk +// +class adt_MHDR +{ + union{ + uint32 fcc; + char fcc_txt[4]; + }; + uint32 size; + + uint32 pad; + uint32 offsMCIN; // MCIN + uint32 offsTex; // MTEX + uint32 offsModels; // MMDX + uint32 offsModelsIds; // MMID + uint32 offsMapObejcts; // MWMO + uint32 offsMapObejctsIds; // MWID + uint32 offsDoodsDef; // MDDF + uint32 offsObjectsDef; // MODF + uint32 offsMFBO; // MFBO + uint32 offsMH2O; // MH2O + uint32 data1; + uint32 data2; + uint32 data3; + uint32 data4; + uint32 data5; +public: + bool prepareLoadedData(); + adt_MCIN *getMCIN(){ return (adt_MCIN *)((uint8 *)&pad+offsMCIN);} + adt_MH2O *getMH2O(){ return offsMH2O ? (adt_MH2O *)((uint8 *)&pad+offsMH2O) : 0;} + +}; + +class ADT_file : public FileLoader{ +public: + bool prepareLoadedData(); + ADT_file(); + ~ADT_file(); + void free(); + + adt_MHDR *a_grid; +}; + +#endif diff --git a/contrib/extractor/loadlib/loadlib.cpp b/contrib/extractor/loadlib/loadlib.cpp new file mode 100644 index 00000000000..ed5bd9acb71 --- /dev/null +++ b/contrib/extractor/loadlib/loadlib.cpp @@ -0,0 +1,64 @@ +#define _CRT_SECURE_NO_DEPRECATE + +#include "loadlib.h" +#include "../mpq_libmpq.h" + +class MPQFile; + +FileLoader::FileLoader() +{ + data = 0; + data_size = 0; + version = 0; +} + +FileLoader::~FileLoader() +{ + free(); +} + +bool FileLoader::loadFile(char *filename, bool log) +{ + free(); + MPQFile mf(filename); + if(mf.isEof()) + { + if (log) + printf("No such file %s\n", filename); + return false; + } + + data_size = mf.getSize(); + + data = new uint8 [data_size]; + if (data) + { + mf.read(data, data_size); + mf.close(); + if (prepareLoadedData()) + return true; + } + printf("Error loading %s", filename); + mf.close(); + free(); + return false; +} + +bool FileLoader::prepareLoadedData() +{ + // Check version + version = (file_MVER *) data; + if (version->fcc != 'MVER') + return false; + if (version->ver != FILE_FORMAT_VERSION) + return false; + return true; +} + +void FileLoader::free() +{ + if (data) delete[] data; + data = 0; + data_size = 0; + version = 0; +}
\ No newline at end of file diff --git a/contrib/extractor/loadlib/loadlib.h b/contrib/extractor/loadlib/loadlib.h new file mode 100644 index 00000000000..6acfd107ec7 --- /dev/null +++ b/contrib/extractor/loadlib/loadlib.h @@ -0,0 +1,57 @@ +#ifndef LOAD_LIB_H +#define LOAD_LIB_H + +#ifdef WIN32 +typedef __int64 int64; +typedef long int32; +typedef short int16; +typedef char int8; +typedef unsigned __int64 uint64; +typedef unsigned long uint32; +typedef unsigned short uint16; +typedef unsigned char uint8; +#else +#include <stdint.h> +#ifndef uint64_t +#include <linux/types.h> +#endif +typedef int64_t int64; +typedef long int32; +typedef short int16; +typedef char int8; +typedef uint64_t uint64; +typedef unsigned long uint32; +typedef unsigned short uint16; +typedef unsigned char uint8; +#endif + +#define FILE_FORMAT_VERSION 18 + +// +// File version chunk +// +struct file_MVER +{ + union{ + uint32 fcc; + char fcc_txt[4]; + }; + uint32 size; + uint32 ver; +}; + +class FileLoader{ + uint8 *data; + uint32 data_size; +public: + virtual bool prepareLoadedData(); + uint8 *GetData() {return data;} + uint32 GetDataSize() {return data_size;} + + file_MVER *version; + FileLoader(); + ~FileLoader(); + bool loadFile(char *filename, bool log = true); + virtual void free(); +}; +#endif diff --git a/contrib/extractor/loadlib/wdt.cpp b/contrib/extractor/loadlib/wdt.cpp new file mode 100644 index 00000000000..dedefbb64e5 --- /dev/null +++ b/contrib/extractor/loadlib/wdt.cpp @@ -0,0 +1,62 @@ +#define _CRT_SECURE_NO_DEPRECATE + +#include "wdt.h" + +bool wdt_MWMO::prepareLoadedData() +{ + if (fcc != 'MWMO') + return false; + return true; +} + +bool wdt_MPHD::prepareLoadedData() +{ + if (fcc != 'MPHD') + return false; + return true; +} + +bool wdt_MAIN::prepareLoadedData() +{ + if (fcc != 'MAIN') + return false; + return true; +} + +WDT_file::WDT_file() +{ + mphd = 0; + main = 0; + wmo = 0; +} + +WDT_file::~WDT_file() +{ + free(); +} + +void WDT_file::free() +{ + mphd = 0; + main = 0; + wmo = 0; + FileLoader::free(); +} + +bool WDT_file::prepareLoadedData() +{ + // Check parent + if (!FileLoader::prepareLoadedData()) + return false; + + mphd = (wdt_MPHD *)((uint8*)version+version->size+8); + if (!mphd->prepareLoadedData()) + return false; + main = (wdt_MAIN *)((uint8*)mphd + mphd->size+8); + if (!main->prepareLoadedData()) + return false; + wmo = (wdt_MWMO *)((uint8*)main+ main->size+8); + if (!wmo->prepareLoadedData()) + return false; + return true; +}
\ No newline at end of file diff --git a/contrib/extractor/loadlib/wdt.h b/contrib/extractor/loadlib/wdt.h new file mode 100644 index 00000000000..fcee8ac64f2 --- /dev/null +++ b/contrib/extractor/loadlib/wdt.h @@ -0,0 +1,68 @@ +#ifndef WDT_H +#define WDT_H +#include "loadlib.h" + +//************************************************************************************** +// WDT file class and structures +//************************************************************************************** +#define WDT_MAP_SIZE 64 + +class wdt_MWMO{ + union{ + uint32 fcc; + char fcc_txt[4]; + }; +public: + uint32 size; + bool prepareLoadedData(); +}; + +class wdt_MPHD{ + union{ + uint32 fcc; + char fcc_txt[4]; + }; +public: + uint32 size; + + uint32 data1; + uint32 data2; + uint32 data3; + uint32 data4; + uint32 data5; + uint32 data6; + uint32 data7; + uint32 data8; + bool prepareLoadedData(); +}; + +class wdt_MAIN{ + union{ + uint32 fcc; + char fcc_txt[4]; + }; +public: + uint32 size; + + struct adtData{ + uint32 exist; + uint32 data1; + } adt_list[64][64]; + + bool prepareLoadedData(); +}; + +class WDT_file : public FileLoader{ +public: + bool prepareLoadedData(); + + WDT_file(); + ~WDT_file(); + void free(); + + wdt_MPHD *mphd; + wdt_MAIN *main; + wdt_MWMO *wmo; +}; + +#endif
\ No newline at end of file diff --git a/contrib/extractor/mpq_libmpq.h b/contrib/extractor/mpq_libmpq.h index 97b7b75035b..d61cda7f919 100644 --- a/contrib/extractor/mpq_libmpq.h +++ b/contrib/extractor/mpq_libmpq.h @@ -4,6 +4,7 @@ #ifndef MPQ_H #define MPQ_H +#include "loadlib/loadlib.h" #include "libmpq/mpq.h" #include <string.h> #include <ctype.h> @@ -13,7 +14,6 @@ using namespace std; -typedef unsigned int uint32; class MPQArchive { |
