mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-16 10:30:27 +00:00
Big re-organization of repository [W.I.P]
This commit is contained in:
@@ -1,39 +0,0 @@
|
||||
# Copyright (C)
|
||||
# Copyright (C)
|
||||
#
|
||||
# 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.
|
||||
|
||||
file(GLOB_RECURSE sources *.cpp *.h)
|
||||
|
||||
set(include_Dirs
|
||||
${CMAKE_SOURCE_DIR}/modules/dep/libmpq
|
||||
)
|
||||
|
||||
if( WIN32 )
|
||||
set(include_Dirs
|
||||
${include_Dirs}
|
||||
${CMAKE_SOURCE_DIR}/modules/dep/libmpq/win
|
||||
)
|
||||
endif()
|
||||
|
||||
include_directories(${include_Dirs})
|
||||
|
||||
add_executable(vmap4extractor ${sources})
|
||||
|
||||
target_link_libraries(vmap4extractor
|
||||
mpq
|
||||
${BZIP2_LIBRARIES}
|
||||
${ZLIB_LIBRARIES}
|
||||
)
|
||||
|
||||
if( UNIX )
|
||||
install(TARGETS vmap4extractor DESTINATION bin)
|
||||
elseif( WIN32 )
|
||||
install(TARGETS vmap4extractor DESTINATION "${CMAKE_INSTALL_PREFIX}")
|
||||
endif()
|
||||
@@ -1,214 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vmapexport.h"
|
||||
#include "adtfile.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
|
||||
#ifdef WIN32
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
char const* GetPlainName(char const* FileName)
|
||||
{
|
||||
const char * szTemp;
|
||||
|
||||
if((szTemp = strrchr(FileName, '\\')) != NULL)
|
||||
FileName = szTemp + 1;
|
||||
return FileName;
|
||||
}
|
||||
|
||||
char* GetPlainName(char* FileName)
|
||||
{
|
||||
char * szTemp;
|
||||
|
||||
if((szTemp = strrchr(FileName, '\\')) != NULL)
|
||||
FileName = szTemp + 1;
|
||||
return FileName;
|
||||
}
|
||||
|
||||
void fixnamen(char* name, size_t len)
|
||||
{
|
||||
for (size_t i = 0; i < len-3; i++)
|
||||
{
|
||||
if (i > 0 && name[i] >= 'A' && name[i] <= 'Z' && isalpha(name[i-1]))
|
||||
name[i] |= 0x20;
|
||||
else if ((i == 0 || !isalpha(name[i-1])) && name[i]>='a' && name[i]<='z')
|
||||
name[i] &= ~0x20;
|
||||
}
|
||||
//extension in lowercase
|
||||
for (size_t i = len - 3; i < len; i++)
|
||||
name[i] |= 0x20;
|
||||
}
|
||||
|
||||
void fixname2(char* name, size_t len)
|
||||
{
|
||||
for (size_t i=0; i<len-3; i++)
|
||||
{
|
||||
if(name[i] == ' ')
|
||||
name[i] = '_';
|
||||
}
|
||||
}
|
||||
|
||||
char* GetExtension(char* FileName)
|
||||
{
|
||||
if (char* szTemp = strrchr(FileName, '.'))
|
||||
return szTemp;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ADTFile::ADTFile(char* filename): ADT(filename), nWMO(0), nMDX(0), WmoInstansName(NULL), ModelInstansName(NULL)
|
||||
{
|
||||
Adtfilename.append(filename);
|
||||
}
|
||||
|
||||
bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY)
|
||||
{
|
||||
if(ADT.isEof ())
|
||||
return false;
|
||||
|
||||
uint32 size;
|
||||
|
||||
string xMap;
|
||||
string yMap;
|
||||
|
||||
Adtfilename.erase(Adtfilename.find(".adt"),4);
|
||||
string TempMapNumber;
|
||||
TempMapNumber = Adtfilename.substr(Adtfilename.length()-6,6);
|
||||
xMap = TempMapNumber.substr(TempMapNumber.find("_")+1,(TempMapNumber.find_last_of("_")-1) - (TempMapNumber.find("_")));
|
||||
yMap = TempMapNumber.substr(TempMapNumber.find_last_of("_")+1,(TempMapNumber.length()) - (TempMapNumber.find_last_of("_")));
|
||||
Adtfilename.erase((Adtfilename.length()-xMap.length()-yMap.length()-2), (xMap.length()+yMap.length()+2));
|
||||
//string AdtMapNumber = xMap + ' ' + yMap + ' ' + GetPlainName((char*)Adtfilename.c_str());
|
||||
//printf("Processing map %s...\n", AdtMapNumber.c_str());
|
||||
//printf("MapNumber = %s\n", TempMapNumber.c_str());
|
||||
//printf("xMap = %s\n", xMap.c_str());
|
||||
//printf("yMap = %s\n", yMap.c_str());
|
||||
|
||||
std::string dirname = std::string(szWorkDirWmo) + "/dir_bin";
|
||||
FILE *dirfile;
|
||||
dirfile = fopen(dirname.c_str(), "ab");
|
||||
if(!dirfile)
|
||||
{
|
||||
printf("Can't open dirfile!'%s'\n", dirname.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!ADT.isEof())
|
||||
{
|
||||
char fourcc[5];
|
||||
ADT.read(&fourcc,4);
|
||||
ADT.read(&size, 4);
|
||||
flipcc(fourcc);
|
||||
fourcc[4] = 0;
|
||||
|
||||
size_t nextpos = ADT.getPos() + size;
|
||||
|
||||
if (!strcmp(fourcc,"MCIN"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MTEX"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MMDX"))
|
||||
{
|
||||
if (size)
|
||||
{
|
||||
char *buf = new char[size];
|
||||
ADT.read(buf, size);
|
||||
char *p=buf;
|
||||
int t=0;
|
||||
ModelInstansName = new string[size];
|
||||
while (p<buf+size)
|
||||
{
|
||||
fixnamen(p,strlen(p));
|
||||
char* s = GetPlainName(p);
|
||||
fixname2(s,strlen(s));
|
||||
|
||||
ModelInstansName[t++] = s;
|
||||
|
||||
string path(p);
|
||||
ExtractSingleModel(path);
|
||||
|
||||
p = p+strlen(p)+1;
|
||||
}
|
||||
delete[] buf;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(fourcc,"MWMO"))
|
||||
{
|
||||
if (size)
|
||||
{
|
||||
char* buf = new char[size];
|
||||
ADT.read(buf, size);
|
||||
char* p=buf;
|
||||
int q = 0;
|
||||
WmoInstansName = new string[size];
|
||||
while (p<buf+size)
|
||||
{
|
||||
char* s = GetPlainName(p);
|
||||
fixnamen(s, strlen(s));
|
||||
fixname2(s, strlen(s));
|
||||
p += strlen(p) + 1;
|
||||
WmoInstansName[q++] = s;
|
||||
}
|
||||
delete[] buf;
|
||||
}
|
||||
}
|
||||
//======================
|
||||
else if (!strcmp(fourcc,"MDDF"))
|
||||
{
|
||||
if (size)
|
||||
{
|
||||
nMDX = (int)size / 36;
|
||||
for (int i=0; i<nMDX; ++i)
|
||||
{
|
||||
uint32 id;
|
||||
ADT.read(&id, 4);
|
||||
ModelInstance inst(ADT,ModelInstansName[id].c_str(), map_num, tileX, tileY, dirfile);
|
||||
}
|
||||
delete[] ModelInstansName;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(fourcc,"MODF"))
|
||||
{
|
||||
if (size)
|
||||
{
|
||||
nWMO = (int)size / 64;
|
||||
for (int i=0; i<nWMO; ++i)
|
||||
{
|
||||
uint32 id;
|
||||
ADT.read(&id, 4);
|
||||
WMOInstance inst(ADT,WmoInstansName[id].c_str(), map_num, tileX, tileY, dirfile);
|
||||
}
|
||||
delete[] WmoInstansName;
|
||||
}
|
||||
}
|
||||
//======================
|
||||
ADT.seek(nextpos);
|
||||
}
|
||||
ADT.close();
|
||||
fclose(dirfile);
|
||||
return true;
|
||||
}
|
||||
|
||||
ADTFile::~ADTFile()
|
||||
{
|
||||
ADT.close();
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ADT_H
|
||||
#define ADT_H
|
||||
|
||||
#include "mpq_libmpq04.h"
|
||||
#include "wmo.h"
|
||||
#include "model.h"
|
||||
|
||||
#define TILESIZE (533.33333f)
|
||||
#define CHUNKSIZE ((TILESIZE) / 16.0f)
|
||||
#define UNITSIZE (CHUNKSIZE / 8.0f)
|
||||
|
||||
class Liquid;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
}svec;
|
||||
|
||||
struct vec
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
double z;
|
||||
};
|
||||
|
||||
struct triangle
|
||||
{
|
||||
vec v[3];
|
||||
};
|
||||
|
||||
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;
|
||||
//Liquid *lq;
|
||||
float waterlevel[9][9];
|
||||
uint8 flag;
|
||||
}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;
|
||||
uint32 sizeLiquid;
|
||||
float zpos;
|
||||
float xpos;
|
||||
float ypos;
|
||||
uint32 textureId;
|
||||
uint32 props;
|
||||
uint32 effectId;
|
||||
};
|
||||
|
||||
|
||||
class ADTFile
|
||||
{
|
||||
private:
|
||||
//size_t mcnk_offsets[256], mcnk_sizes[256];
|
||||
MPQFile ADT;
|
||||
//mcell Mcell;
|
||||
string Adtfilename;
|
||||
public:
|
||||
ADTFile(char* filename);
|
||||
~ADTFile();
|
||||
int nWMO;
|
||||
int nMDX;
|
||||
string* WmoInstansName;
|
||||
string* ModelInstansName;
|
||||
bool init(uint32 map_num, uint32 tileX, uint32 tileY);
|
||||
//void LoadMapChunks();
|
||||
|
||||
//uint32 wmo_count;
|
||||
/*
|
||||
const mcell& Getmcell() const
|
||||
{
|
||||
return Mcell;
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
const char * GetPlainName(const char * FileName);
|
||||
char * GetPlainName(char * FileName);
|
||||
char * GetExtension(char * FileName);
|
||||
void fixnamen(char *name, size_t len);
|
||||
void fixname2(char *name, size_t len);
|
||||
//void fixMapNamen(char *name, size_t len);
|
||||
|
||||
#endif
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dbcfile.h"
|
||||
#include "mpq_libmpq04.h"
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
DBCFile::DBCFile(const std::string& filename):
|
||||
filename(filename), recordSize(0), recordCount(0), fieldCount(0), stringSize(0), data(NULL), stringTable(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool DBCFile::open()
|
||||
{
|
||||
MPQFile f(filename.c_str());
|
||||
|
||||
// Need some error checking, otherwise an unhandled exception error occurs
|
||||
// if people screw with the data path.
|
||||
if (f.isEof() == true)
|
||||
return false;
|
||||
|
||||
unsigned char header[4];
|
||||
unsigned int na,nb,es,ss;
|
||||
|
||||
f.read(header,4); // File Header
|
||||
|
||||
if (header[0]!='W' || header[1]!='D' || header[2]!='B' || header[3] != 'C')
|
||||
{
|
||||
f.close();
|
||||
data = NULL;
|
||||
printf("Critical Error: An error occured while trying to read the DBCFile %s.", filename.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
//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
|
||||
|
||||
recordSize = es;
|
||||
recordCount = na;
|
||||
fieldCount = nb;
|
||||
stringSize = ss;
|
||||
//assert(fieldCount*4 == recordSize);
|
||||
assert(fieldCount*4 >= recordSize);
|
||||
|
||||
data = new unsigned char[recordSize*recordCount+stringSize];
|
||||
stringTable = data + recordSize*recordCount;
|
||||
f.read(data,recordSize*recordCount+stringSize);
|
||||
f.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
DBCFile::~DBCFile()
|
||||
{
|
||||
delete [] data;
|
||||
}
|
||||
|
||||
DBCFile::Record DBCFile::getRecord(size_t id)
|
||||
{
|
||||
assert(data);
|
||||
return Record(*this, data + id*recordSize);
|
||||
}
|
||||
|
||||
DBCFile::Iterator DBCFile::begin()
|
||||
{
|
||||
assert(data);
|
||||
return Iterator(*this, data);
|
||||
}
|
||||
|
||||
DBCFile::Iterator DBCFile::end()
|
||||
{
|
||||
assert(data);
|
||||
return Iterator(*this, stringTable);
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DBCFILE_H
|
||||
#define DBCFILE_H
|
||||
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
|
||||
class DBCFile
|
||||
{
|
||||
public:
|
||||
DBCFile(const std::string &filename);
|
||||
~DBCFile();
|
||||
|
||||
// Open database. It must be openened before it can be used.
|
||||
bool open();
|
||||
|
||||
// TODO: Add a close function?
|
||||
|
||||
// Database exceptions
|
||||
class Exception
|
||||
{
|
||||
public:
|
||||
Exception(const std::string &message): message(message)
|
||||
{ }
|
||||
virtual ~Exception()
|
||||
{ }
|
||||
const std::string &getMessage() {return message;}
|
||||
private:
|
||||
std::string message;
|
||||
};
|
||||
|
||||
//
|
||||
class NotFound: public Exception
|
||||
{
|
||||
public:
|
||||
NotFound(): Exception("Key was not found")
|
||||
{ }
|
||||
};
|
||||
|
||||
// Iteration over database
|
||||
class Iterator;
|
||||
class Record
|
||||
{
|
||||
public:
|
||||
Record& operator= (const Record& r)
|
||||
{
|
||||
file = r.file;
|
||||
offset = r.offset;
|
||||
return *this;
|
||||
}
|
||||
float getFloat(size_t field) const
|
||||
{
|
||||
assert(field < file.fieldCount);
|
||||
return *reinterpret_cast<float*>(offset+field*4);
|
||||
}
|
||||
unsigned int getUInt(size_t field) const
|
||||
{
|
||||
assert(field < file.fieldCount);
|
||||
return *reinterpret_cast<unsigned int*>(offset+(field*4));
|
||||
}
|
||||
int getInt(size_t field) const
|
||||
{
|
||||
assert(field < file.fieldCount);
|
||||
return *reinterpret_cast<int*>(offset+field*4);
|
||||
}
|
||||
unsigned char getByte(size_t ofs) const
|
||||
{
|
||||
assert(ofs < file.recordSize);
|
||||
return *reinterpret_cast<unsigned char*>(offset+ofs);
|
||||
}
|
||||
const char *getString(size_t field) const
|
||||
{
|
||||
assert(field < file.fieldCount);
|
||||
size_t stringOffset = getUInt(field);
|
||||
assert(stringOffset < file.stringSize);
|
||||
//char * tmp = (char*)file.stringTable + stringOffset;
|
||||
//unsigned char * tmp2 = file.stringTable + stringOffset;
|
||||
return reinterpret_cast<char*>(file.stringTable + stringOffset);
|
||||
}
|
||||
private:
|
||||
Record(DBCFile &file, unsigned char *offset): file(file), offset(offset) {}
|
||||
DBCFile &file;
|
||||
unsigned char *offset;
|
||||
|
||||
friend class DBCFile;
|
||||
friend class Iterator;
|
||||
};
|
||||
|
||||
/* Iterator that iterates over records */
|
||||
class Iterator
|
||||
{
|
||||
public:
|
||||
Iterator(DBCFile &file, unsigned char *offset):
|
||||
record(file, offset) {}
|
||||
/// Advance (prefix only)
|
||||
Iterator & operator++() {
|
||||
record.offset += record.file.recordSize;
|
||||
return *this;
|
||||
}
|
||||
/// Return address of current instance
|
||||
Record const & operator*() const { return record; }
|
||||
const Record* operator->() const {
|
||||
return &record;
|
||||
}
|
||||
/// Comparison
|
||||
bool operator==(const Iterator &b) const
|
||||
{
|
||||
return record.offset == b.record.offset;
|
||||
}
|
||||
bool operator!=(const Iterator &b) const
|
||||
{
|
||||
return record.offset != b.record.offset;
|
||||
}
|
||||
private:
|
||||
Record record;
|
||||
};
|
||||
|
||||
// Get record by id
|
||||
Record getRecord(size_t id);
|
||||
/// Get begin iterator over records
|
||||
Iterator begin();
|
||||
/// Get begin iterator over records
|
||||
Iterator end();
|
||||
/// Trivial
|
||||
size_t getRecordCount() const { return recordCount;}
|
||||
size_t getFieldCount() const { return fieldCount; }
|
||||
|
||||
private:
|
||||
std::string filename;
|
||||
size_t recordSize;
|
||||
size_t recordCount;
|
||||
size_t fieldCount;
|
||||
size_t stringSize;
|
||||
unsigned char *data;
|
||||
unsigned char *stringTable;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "model.h"
|
||||
#include "dbcfile.h"
|
||||
#include "adtfile.h"
|
||||
#include "vmapexport.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdio.h>
|
||||
|
||||
bool ExtractSingleModel(std::string& fname)
|
||||
{
|
||||
char * name = GetPlainName((char*)fname.c_str());
|
||||
char * ext = GetExtension(name);
|
||||
|
||||
// < 3.1.0 ADT MMDX section store filename.mdx filenames for corresponded .m2 file
|
||||
if (!strcmp(ext, ".mdx"))
|
||||
{
|
||||
// replace .mdx -> .m2
|
||||
fname.erase(fname.length()-2,2);
|
||||
fname.append("2");
|
||||
}
|
||||
// >= 3.1.0 ADT MMDX section store filename.m2 filenames for corresponded .m2 file
|
||||
// nothing do
|
||||
|
||||
std::string output(szWorkDirWmo);
|
||||
output += "/";
|
||||
output += name;
|
||||
|
||||
if (FileExists(output.c_str()))
|
||||
return true;
|
||||
|
||||
Model mdl(fname);
|
||||
if (!mdl.open())
|
||||
return false;
|
||||
|
||||
return mdl.ConvertToVMAPModel(output.c_str());
|
||||
}
|
||||
|
||||
void ExtractGameobjectModels()
|
||||
{
|
||||
printf("Extracting GameObject models...");
|
||||
DBCFile dbc("DBFilesClient\\GameObjectDisplayInfo.dbc");
|
||||
if(!dbc.open())
|
||||
{
|
||||
printf("Fatal error: Invalid GameObjectDisplayInfo.dbc file format!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
std::string basepath = szWorkDirWmo;
|
||||
basepath += "/";
|
||||
std::string path;
|
||||
|
||||
std::string modelListPath = basepath + "temp_gameobject_models";
|
||||
FILE* model_list = fopen(modelListPath.c_str(), "wb");
|
||||
if (!model_list)
|
||||
{
|
||||
printf("Fatal error: Could not open file %s\n", modelListPath.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
for (DBCFile::Iterator it = dbc.begin(); it != dbc.end(); ++it)
|
||||
{
|
||||
path = it->getString(1);
|
||||
|
||||
if (path.length() < 4)
|
||||
continue;
|
||||
|
||||
fixnamen((char*)path.c_str(), path.size());
|
||||
char * name = GetPlainName((char*)path.c_str());
|
||||
fixname2(name, strlen(name));
|
||||
|
||||
char * ch_ext = GetExtension(name);
|
||||
if (!ch_ext)
|
||||
continue;
|
||||
|
||||
strToLower(ch_ext);
|
||||
|
||||
bool result = false;
|
||||
if (!strcmp(ch_ext, ".wmo"))
|
||||
{
|
||||
result = ExtractSingleWmo(path);
|
||||
}
|
||||
else if (!strcmp(ch_ext, ".mdl"))
|
||||
{
|
||||
// TODO: extract .mdl files, if needed
|
||||
continue;
|
||||
}
|
||||
else //if (!strcmp(ch_ext, ".mdx") || !strcmp(ch_ext, ".m2"))
|
||||
{
|
||||
result = ExtractSingleModel(path);
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
uint32 displayId = it->getUInt(0);
|
||||
uint32 path_length = strlen(name);
|
||||
fwrite(&displayId, sizeof(uint32), 1, model_list);
|
||||
fwrite(&path_length, sizeof(uint32), 1, model_list);
|
||||
fwrite(name, sizeof(char), path_length, model_list);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(model_list);
|
||||
|
||||
printf("Done!\n");
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LOAD_LIB_H
|
||||
#define LOAD_LIB_H
|
||||
|
||||
#ifdef WIN32
|
||||
typedef __int64 int64;
|
||||
typedef __int32 int32;
|
||||
typedef __int16 int16;
|
||||
typedef __int8 int8;
|
||||
typedef unsigned __int64 uint64;
|
||||
typedef unsigned __int32 uint32;
|
||||
typedef unsigned __int16 uint16;
|
||||
typedef unsigned __int8 uint8;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#ifndef uint64_t
|
||||
#ifdef __linux__
|
||||
#include <linux/types.h>
|
||||
#endif
|
||||
#endif
|
||||
typedef int64_t int64;
|
||||
typedef int32_t int32;
|
||||
typedef int16_t int16;
|
||||
typedef int8_t int8;
|
||||
typedef uint64_t uint64;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint8_t 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
|
||||
@@ -1,195 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vmapexport.h"
|
||||
#include "model.h"
|
||||
#include "wmo.h"
|
||||
#include "mpq_libmpq04.h"
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
|
||||
Model::Model(std::string &filename) : filename(filename), vertices(0), indices(0)
|
||||
{
|
||||
memset(&header, 0, sizeof(header));
|
||||
}
|
||||
|
||||
bool Model::open()
|
||||
{
|
||||
MPQFile f(filename.c_str());
|
||||
|
||||
if (f.isEof())
|
||||
{
|
||||
f.close();
|
||||
// Do not show this error on console to avoid confusion, the extractor can continue working even if some models fail to load
|
||||
//printf("Error loading model %s\n", filename.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
_unload();
|
||||
|
||||
memcpy(&header, f.getBuffer(), sizeof(ModelHeader));
|
||||
if(header.nBoundingTriangles > 0)
|
||||
{
|
||||
f.seek(0);
|
||||
f.seekRelative(header.ofsBoundingVertices);
|
||||
vertices = new Vec3D[header.nBoundingVertices];
|
||||
f.read(vertices,header.nBoundingVertices*12);
|
||||
for (uint32 i=0; i<header.nBoundingVertices; i++)
|
||||
vertices[i] = fixCoordSystem(vertices[i]);
|
||||
f.seek(0);
|
||||
f.seekRelative(header.ofsBoundingTriangles);
|
||||
indices = new uint16[header.nBoundingTriangles];
|
||||
f.read(indices,header.nBoundingTriangles*2);
|
||||
f.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("not included %s\n", filename.c_str());
|
||||
f.close();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Model::ConvertToVMAPModel(const char * outfilename)
|
||||
{
|
||||
int N[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
FILE* output=fopen(outfilename, "wb");
|
||||
if (!output)
|
||||
{
|
||||
printf("Can't create the output file '%s'\n",outfilename);
|
||||
return false;
|
||||
}
|
||||
fwrite(szRawVMAPMagic, 8, 1, output);
|
||||
uint32 nVertices = header.nBoundingVertices;
|
||||
fwrite(&nVertices, sizeof(int), 1, output);
|
||||
uint32 nofgroups = 1;
|
||||
fwrite(&nofgroups,sizeof(uint32), 1, output);
|
||||
fwrite(N,4*3,1,output);// rootwmoid, flags, groupid
|
||||
fwrite(N,sizeof(float),3*2,output);//bbox, only needed for WMO currently
|
||||
fwrite(N,4,1,output);// liquidflags
|
||||
fwrite("GRP ",4,1,output);
|
||||
uint32 branches = 1;
|
||||
int wsize;
|
||||
wsize = sizeof(branches) + sizeof(uint32) * branches;
|
||||
fwrite(&wsize, sizeof(int), 1, output);
|
||||
fwrite(&branches,sizeof(branches), 1, output);
|
||||
uint32 nIndexes = header.nBoundingTriangles;
|
||||
fwrite(&nIndexes,sizeof(uint32), 1, output);
|
||||
fwrite("INDX",4, 1, output);
|
||||
wsize = sizeof(uint32) + sizeof(unsigned short) * nIndexes;
|
||||
fwrite(&wsize, sizeof(int), 1, output);
|
||||
fwrite(&nIndexes, sizeof(uint32), 1, output);
|
||||
if (nIndexes >0)
|
||||
fwrite(indices, sizeof(unsigned short), nIndexes, output);
|
||||
|
||||
fwrite("VERT", 4, 1, output);
|
||||
wsize = sizeof(int) + sizeof(float) * 3 * nVertices;
|
||||
fwrite(&wsize, sizeof(int), 1, output);
|
||||
fwrite(&nVertices, sizeof(int), 1, output);
|
||||
if (nVertices >0)
|
||||
{
|
||||
for(uint32 vpos=0; vpos <nVertices; ++vpos)
|
||||
std::swap(vertices[vpos].y, vertices[vpos].z);
|
||||
|
||||
fwrite(vertices, sizeof(float)*3, nVertices, output);
|
||||
}
|
||||
|
||||
fclose(output);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Vec3D fixCoordSystem(Vec3D v)
|
||||
{
|
||||
return Vec3D(v.x, v.z, -v.y);
|
||||
}
|
||||
|
||||
Vec3D fixCoordSystem2(Vec3D v)
|
||||
{
|
||||
return Vec3D(v.x, v.z, v.y);
|
||||
}
|
||||
|
||||
ModelInstance::ModelInstance(MPQFile& f, char const* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE *pDirfile)
|
||||
{
|
||||
float ff[3];
|
||||
f.read(&id, 4);
|
||||
f.read(ff, 12);
|
||||
pos = fixCoords(Vec3D(ff[0], ff[1], ff[2]));
|
||||
f.read(ff, 12);
|
||||
rot = Vec3D(ff[0], ff[1], ff[2]);
|
||||
f.read(&scale, 2);
|
||||
f.read(&flags, 2);
|
||||
// scale factor - divide by 1024. blizzard devs must be on crack, why not just use a float?
|
||||
sc = scale / 1024.0f;
|
||||
|
||||
char tempname[512];
|
||||
sprintf(tempname, "%s/%s", szWorkDirWmo, ModelInstName);
|
||||
FILE* input = fopen(tempname, "r+b");
|
||||
|
||||
if (!input)
|
||||
{
|
||||
//printf("ModelInstance::ModelInstance couldn't open %s\n", tempname);
|
||||
return;
|
||||
}
|
||||
|
||||
fseek(input, 8, SEEK_SET); // get the correct no of vertices
|
||||
int nVertices;
|
||||
int count = fread(&nVertices, sizeof (int), 1, input);
|
||||
fclose(input);
|
||||
|
||||
if (count != 1 || nVertices == 0)
|
||||
return;
|
||||
|
||||
uint16 adtId = 0;// not used for models
|
||||
uint32 flags = MOD_M2;
|
||||
if (tileX == 65 && tileY == 65)
|
||||
flags |= MOD_WORLDSPAWN;
|
||||
|
||||
//write mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, name
|
||||
fwrite(&mapID, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(&tileX, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(&tileY, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(&flags, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(&adtId, sizeof(uint16), 1, pDirfile);
|
||||
fwrite(&id, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(&pos, sizeof(float), 3, pDirfile);
|
||||
fwrite(&rot, sizeof(float), 3, pDirfile);
|
||||
fwrite(&sc, sizeof(float), 1, pDirfile);
|
||||
uint32 nlen=strlen(ModelInstName);
|
||||
fwrite(&nlen, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(ModelInstName, sizeof(char), nlen, pDirfile);
|
||||
|
||||
/* int realx1 = (int) ((float) pos.x / 533.333333f);
|
||||
int realy1 = (int) ((float) pos.z / 533.333333f);
|
||||
int realx2 = (int) ((float) pos.x / 533.333333f);
|
||||
int realy2 = (int) ((float) pos.z / 533.333333f);
|
||||
|
||||
fprintf(pDirfile,"%s/%s %f,%f,%f_%f,%f,%f %f %d %d %d,%d %d\n",
|
||||
MapName,
|
||||
ModelInstName,
|
||||
(float) pos.x, (float) pos.y, (float) pos.z,
|
||||
(float) rot.x, (float) rot.y, (float) rot.z,
|
||||
sc,
|
||||
nVertices,
|
||||
realx1, realy1,
|
||||
realx2, realy2
|
||||
); */
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MODEL_H
|
||||
#define MODEL_H
|
||||
|
||||
#include "loadlib/loadlib.h"
|
||||
#include "vec3d.h"
|
||||
#include "modelheaders.h"
|
||||
#include <vector>
|
||||
|
||||
class MPQFile;
|
||||
|
||||
Vec3D fixCoordSystem(Vec3D v);
|
||||
|
||||
class Model
|
||||
{
|
||||
private:
|
||||
void _unload()
|
||||
{
|
||||
delete[] vertices;
|
||||
delete[] indices;
|
||||
vertices = NULL;
|
||||
indices = NULL;
|
||||
}
|
||||
std::string filename;
|
||||
public:
|
||||
ModelHeader header;
|
||||
Vec3D* vertices;
|
||||
uint16* indices;
|
||||
|
||||
bool open();
|
||||
bool ConvertToVMAPModel(char const* outfilename);
|
||||
|
||||
Model(std::string& filename);
|
||||
~Model() { _unload(); }
|
||||
};
|
||||
|
||||
class ModelInstance
|
||||
{
|
||||
public:
|
||||
uint32 id;
|
||||
Vec3D pos, rot;
|
||||
uint16 scale, flags;
|
||||
float sc;
|
||||
|
||||
ModelInstance() : id(0), scale(0), flags(0), sc(0.0f) {}
|
||||
ModelInstance(MPQFile& f, char const* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MODELHEADERS_H
|
||||
#define MODELHEADERS_H
|
||||
|
||||
/* typedef unsigned char uint8;
|
||||
typedef char int8;
|
||||
typedef unsigned short uint16;
|
||||
typedef short int16;
|
||||
typedef unsigned int uint32;
|
||||
typedef int int32; */
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
||||
struct ModelHeader
|
||||
{
|
||||
char id[4];
|
||||
uint8 version[4];
|
||||
uint32 nameLength;
|
||||
uint32 nameOfs;
|
||||
uint32 type;
|
||||
uint32 nGlobalSequences;
|
||||
uint32 ofsGlobalSequences;
|
||||
uint32 nAnimations;
|
||||
uint32 ofsAnimations;
|
||||
uint32 nAnimationLookup;
|
||||
uint32 ofsAnimationLookup;
|
||||
uint32 nBones;
|
||||
uint32 ofsBones;
|
||||
uint32 nKeyBoneLookup;
|
||||
uint32 ofsKeyBoneLookup;
|
||||
uint32 nVertices;
|
||||
uint32 ofsVertices;
|
||||
uint32 nViews;
|
||||
uint32 nColors;
|
||||
uint32 ofsColors;
|
||||
uint32 nTextures;
|
||||
uint32 ofsTextures;
|
||||
uint32 nTransparency;
|
||||
uint32 ofsTransparency;
|
||||
uint32 nTextureanimations;
|
||||
uint32 ofsTextureanimations;
|
||||
uint32 nTexReplace;
|
||||
uint32 ofsTexReplace;
|
||||
uint32 nRenderFlags;
|
||||
uint32 ofsRenderFlags;
|
||||
uint32 nBoneLookupTable;
|
||||
uint32 ofsBoneLookupTable;
|
||||
uint32 nTexLookup;
|
||||
uint32 ofsTexLookup;
|
||||
uint32 nTexUnits;
|
||||
uint32 ofsTexUnits;
|
||||
uint32 nTransLookup;
|
||||
uint32 ofsTransLookup;
|
||||
uint32 nTexAnimLookup;
|
||||
uint32 ofsTexAnimLookup;
|
||||
float floats[14];
|
||||
uint32 nBoundingTriangles;
|
||||
uint32 ofsBoundingTriangles;
|
||||
uint32 nBoundingVertices;
|
||||
uint32 ofsBoundingVertices;
|
||||
uint32 nBoundingNormals;
|
||||
uint32 ofsBoundingNormals;
|
||||
uint32 nAttachments;
|
||||
uint32 ofsAttachments;
|
||||
uint32 nAttachLookup;
|
||||
uint32 ofsAttachLookup;
|
||||
uint32 nAttachments_2;
|
||||
uint32 ofsAttachments_2;
|
||||
uint32 nLights;
|
||||
uint32 ofsLights;
|
||||
uint32 nCameras;
|
||||
uint32 ofsCameras;
|
||||
uint32 nCameraLookup;
|
||||
uint32 ofsCameraLookup;
|
||||
uint32 nRibbonEmitters;
|
||||
uint32 ofsRibbonEmitters;
|
||||
uint32 nParticleEmitters;
|
||||
uint32 ofsParticleEmitters;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
@@ -1,129 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "mpq_libmpq04.h"
|
||||
#include <deque>
|
||||
#include <cstdio>
|
||||
|
||||
ArchiveSet gOpenArchives;
|
||||
|
||||
MPQArchive::MPQArchive(const char* filename)
|
||||
{
|
||||
int result = libmpq__archive_open(&mpq_a, filename, -1);
|
||||
printf("Opening %s\n", filename);
|
||||
if(result) {
|
||||
switch(result) {
|
||||
case LIBMPQ_ERROR_OPEN :
|
||||
printf("Error opening archive '%s': Does file really exist?\n", filename);
|
||||
break;
|
||||
case LIBMPQ_ERROR_FORMAT : /* bad file format */
|
||||
printf("Error opening archive '%s': Bad file format\n", filename);
|
||||
break;
|
||||
case LIBMPQ_ERROR_SEEK : /* seeking in file failed */
|
||||
printf("Error opening archive '%s': Seeking in file failed\n", filename);
|
||||
break;
|
||||
case LIBMPQ_ERROR_READ : /* Read error in archive */
|
||||
printf("Error opening archive '%s': Read error in archive\n", filename);
|
||||
break;
|
||||
case LIBMPQ_ERROR_MALLOC : /* maybe not enough memory? :) */
|
||||
printf("Error opening archive '%s': Maybe not enough memory\n", filename);
|
||||
break;
|
||||
default:
|
||||
printf("Error opening archive '%s': Unknown error\n", filename);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
gOpenArchives.push_front(this);
|
||||
}
|
||||
|
||||
void MPQArchive::close()
|
||||
{
|
||||
//gOpenArchives.erase(erase(&mpq_a);
|
||||
libmpq__archive_close(mpq_a);
|
||||
}
|
||||
|
||||
MPQFile::MPQFile(const char* filename):
|
||||
eof(false),
|
||||
buffer(0),
|
||||
pointer(0),
|
||||
size(0)
|
||||
{
|
||||
for(ArchiveSet::iterator i=gOpenArchives.begin(); i!=gOpenArchives.end();++i)
|
||||
{
|
||||
mpq_archive *mpq_a = (*i)->mpq_a;
|
||||
|
||||
uint32 filenum;
|
||||
if(libmpq__file_number(mpq_a, filename, &filenum)) continue;
|
||||
libmpq__off_t transferred;
|
||||
libmpq__file_unpacked_size(mpq_a, filenum, &size);
|
||||
|
||||
// HACK: in patch.mpq some files don't want to open and give 1 for filesize
|
||||
if (size<=1) {
|
||||
// printf("info: file %s has size %d; considered dummy file.\n", filename, size);
|
||||
eof = true;
|
||||
buffer = 0;
|
||||
return;
|
||||
}
|
||||
buffer = new char[size];
|
||||
|
||||
//libmpq_file_getdata
|
||||
libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred);
|
||||
/*libmpq_file_getdata(&mpq_a, hash, fileno, (unsigned char*)buffer);*/
|
||||
return;
|
||||
|
||||
}
|
||||
eof = true;
|
||||
buffer = 0;
|
||||
}
|
||||
|
||||
size_t MPQFile::read(void* dest, size_t bytes)
|
||||
{
|
||||
if (eof) return 0;
|
||||
|
||||
size_t rpos = pointer + bytes;
|
||||
if (rpos > size_t(size)) {
|
||||
bytes = size - pointer;
|
||||
eof = true;
|
||||
}
|
||||
|
||||
memcpy(dest, &(buffer[pointer]), bytes);
|
||||
|
||||
pointer = rpos;
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void MPQFile::seek(int offset)
|
||||
{
|
||||
pointer = offset;
|
||||
eof = (pointer >= size);
|
||||
}
|
||||
|
||||
void MPQFile::seekRelative(int offset)
|
||||
{
|
||||
pointer += offset;
|
||||
eof = (pointer >= size);
|
||||
}
|
||||
|
||||
void MPQFile::close()
|
||||
{
|
||||
if (buffer) delete[] buffer;
|
||||
buffer = 0;
|
||||
eof = true;
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MPQ_H
|
||||
#define MPQ_H
|
||||
|
||||
#include "loadlib/loadlib.h"
|
||||
#include "libmpq/mpq.h"
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <deque>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class MPQArchive
|
||||
{
|
||||
|
||||
public:
|
||||
mpq_archive_s *mpq_a;
|
||||
|
||||
MPQArchive(const char* filename);
|
||||
void close();
|
||||
|
||||
void GetFileListTo(vector<string>& filelist) {
|
||||
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);
|
||||
|
||||
char *buffer = new char[size + 1];
|
||||
buffer[size] = '\0';
|
||||
|
||||
libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred);
|
||||
|
||||
char seps[] = "\n";
|
||||
char *token;
|
||||
|
||||
token = strtok( buffer, seps );
|
||||
uint32 counter = 0;
|
||||
while ((token != NULL) && (counter < size)) {
|
||||
//cout << token << endl;
|
||||
token[strlen(token) - 1] = 0;
|
||||
string s = token;
|
||||
filelist.push_back(s);
|
||||
counter += strlen(token) + 2;
|
||||
token = strtok(NULL, seps);
|
||||
}
|
||||
|
||||
delete[] buffer;
|
||||
}
|
||||
};
|
||||
typedef std::deque<MPQArchive*> ArchiveSet;
|
||||
|
||||
class MPQFile
|
||||
{
|
||||
//MPQHANDLE handle;
|
||||
bool eof;
|
||||
char *buffer;
|
||||
libmpq__off_t pointer,size;
|
||||
|
||||
// disable copying
|
||||
MPQFile(const MPQFile& /*f*/) {}
|
||||
void operator=(const MPQFile& /*f*/) {}
|
||||
|
||||
public:
|
||||
MPQFile(const char* filename); // filenames are not case sensitive
|
||||
~MPQFile() { close(); }
|
||||
size_t read(void* dest, size_t bytes);
|
||||
size_t getSize() { return size; }
|
||||
size_t getPos() { return pointer; }
|
||||
char* getBuffer() { return buffer; }
|
||||
char* getPointer() { return buffer + pointer; }
|
||||
bool isEof() { return eof; }
|
||||
void seek(int offset);
|
||||
void seekRelative(int offset);
|
||||
void close();
|
||||
};
|
||||
|
||||
inline void flipcc(char *fcc)
|
||||
{
|
||||
char t;
|
||||
t=fcc[0];
|
||||
fcc[0]=fcc[3];
|
||||
fcc[3]=t;
|
||||
t=fcc[1];
|
||||
fcc[1]=fcc[2];
|
||||
fcc[2]=t;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,248 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef VEC3D_H
|
||||
#define VEC3D_H
|
||||
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
class Vec3D
|
||||
{
|
||||
public:
|
||||
float x,y,z;
|
||||
|
||||
Vec3D(float x0 = 0.0f, float y0 = 0.0f, float z0 = 0.0f) : x(x0), y(y0), z(z0) {}
|
||||
|
||||
Vec3D(const Vec3D& v) : x(v.x), y(v.y), z(v.z) {}
|
||||
|
||||
Vec3D& operator= (const Vec3D &v) {
|
||||
x = v.x;
|
||||
y = v.y;
|
||||
z = v.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec3D operator+ (const Vec3D &v) const
|
||||
{
|
||||
Vec3D r(x+v.x,y+v.y,z+v.z);
|
||||
return r;
|
||||
}
|
||||
|
||||
Vec3D operator- (const Vec3D &v) const
|
||||
{
|
||||
Vec3D r(x-v.x,y-v.y,z-v.z);
|
||||
return r;
|
||||
}
|
||||
|
||||
float operator* (const Vec3D &v) const
|
||||
{
|
||||
return x*v.x + y*v.y + z*v.z;
|
||||
}
|
||||
|
||||
Vec3D operator* (float d) const
|
||||
{
|
||||
Vec3D r(x*d,y*d,z*d);
|
||||
return r;
|
||||
}
|
||||
|
||||
friend Vec3D operator* (float d, const Vec3D& v)
|
||||
{
|
||||
return v * d;
|
||||
}
|
||||
|
||||
Vec3D operator% (const Vec3D &v) const
|
||||
{
|
||||
Vec3D r(y*v.z-z*v.y, z*v.x-x*v.z, x*v.y-y*v.x);
|
||||
return r;
|
||||
}
|
||||
|
||||
Vec3D& operator+= (const Vec3D &v)
|
||||
{
|
||||
x += v.x;
|
||||
y += v.y;
|
||||
z += v.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec3D& operator-= (const Vec3D &v)
|
||||
{
|
||||
x -= v.x;
|
||||
y -= v.y;
|
||||
z -= v.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec3D& operator*= (float d)
|
||||
{
|
||||
x *= d;
|
||||
y *= d;
|
||||
z *= d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
float lengthSquared() const
|
||||
{
|
||||
return x*x+y*y+z*z;
|
||||
}
|
||||
|
||||
float length() const
|
||||
{
|
||||
return sqrt(x*x+y*y+z*z);
|
||||
}
|
||||
|
||||
Vec3D& normalize()
|
||||
{
|
||||
this->operator*= (1.0f/length());
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec3D operator~ () const
|
||||
{
|
||||
Vec3D r(*this);
|
||||
r.normalize();
|
||||
return r;
|
||||
}
|
||||
|
||||
friend std::istream& operator>>(std::istream& in, Vec3D& v)
|
||||
{
|
||||
in >> v.x >> v.y >> v.z;
|
||||
return in;
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& out, const Vec3D& v)
|
||||
{
|
||||
out << v.x << " " << v.y << " " << v.z;
|
||||
return out;
|
||||
}
|
||||
|
||||
operator float*()
|
||||
{
|
||||
return (float*)this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Vec2D
|
||||
{
|
||||
public:
|
||||
float x,y;
|
||||
|
||||
Vec2D(float x0 = 0.0f, float y0 = 0.0f) : x(x0), y(y0) {}
|
||||
|
||||
Vec2D(const Vec2D& v) : x(v.x), y(v.y) {}
|
||||
|
||||
Vec2D& operator= (const Vec2D &v) {
|
||||
x = v.x;
|
||||
y = v.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec2D operator+ (const Vec2D &v) const
|
||||
{
|
||||
Vec2D r(x+v.x,y+v.y);
|
||||
return r;
|
||||
}
|
||||
|
||||
Vec2D operator- (const Vec2D &v) const
|
||||
{
|
||||
Vec2D r(x-v.x,y-v.y);
|
||||
return r;
|
||||
}
|
||||
|
||||
float operator* (const Vec2D &v) const
|
||||
{
|
||||
return x*v.x + y*v.y;
|
||||
}
|
||||
|
||||
Vec2D operator* (float d) const
|
||||
{
|
||||
Vec2D r(x*d,y*d);
|
||||
return r;
|
||||
}
|
||||
|
||||
friend Vec2D operator* (float d, const Vec2D& v)
|
||||
{
|
||||
return v * d;
|
||||
}
|
||||
|
||||
Vec2D& operator+= (const Vec2D &v)
|
||||
{
|
||||
x += v.x;
|
||||
y += v.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec2D& operator-= (const Vec2D &v)
|
||||
{
|
||||
x -= v.x;
|
||||
y -= v.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec2D& operator*= (float d)
|
||||
{
|
||||
x *= d;
|
||||
y *= d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
float lengthSquared() const
|
||||
{
|
||||
return x*x+y*y;
|
||||
}
|
||||
|
||||
float length() const
|
||||
{
|
||||
return sqrt(x*x+y*y);
|
||||
}
|
||||
|
||||
Vec2D& normalize()
|
||||
{
|
||||
this->operator*= (1.0f/length());
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec2D operator~ () const
|
||||
{
|
||||
Vec2D r(*this);
|
||||
r.normalize();
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
friend std::istream& operator>>(std::istream& in, Vec2D& v)
|
||||
{
|
||||
in >> v.x >> v.y;
|
||||
return in;
|
||||
}
|
||||
|
||||
operator float*()
|
||||
{
|
||||
return (float*)this;
|
||||
}
|
||||
};
|
||||
|
||||
inline void rotate(float x0, float y0, float *x, float *y, float angle)
|
||||
{
|
||||
float xa = *x - x0, ya = *y - y0;
|
||||
*x = xa*cosf(angle) - ya*sinf(angle) + x0;
|
||||
*y = xa*sinf(angle) + ya*cosf(angle) + y0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,538 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#include <sys/stat.h>
|
||||
#include <direct.h>
|
||||
#define mkdir _mkdir
|
||||
#else
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
//#pragma warning(disable : 4505)
|
||||
//#pragma comment(lib, "Winmm.lib")
|
||||
|
||||
#include <map>
|
||||
|
||||
//From Extractor
|
||||
#include "adtfile.h"
|
||||
#include "wdtfile.h"
|
||||
#include "dbcfile.h"
|
||||
#include "wmo.h"
|
||||
#include "mpq_libmpq04.h"
|
||||
|
||||
#include "vmapexport.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Defines
|
||||
|
||||
#define MPQ_BLOCK_SIZE 0x1000
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
extern ArchiveSet gOpenArchives;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[64];
|
||||
unsigned int id;
|
||||
}map_id;
|
||||
|
||||
map_id * map_ids;
|
||||
uint16 *LiqType = 0;
|
||||
uint32 map_count;
|
||||
char output_path[128]=".";
|
||||
char input_path[1024]=".";
|
||||
bool hasInputPathParam = false;
|
||||
bool preciseVectorData = false;
|
||||
|
||||
// Constants
|
||||
|
||||
//static const char * szWorkDirMaps = ".\\Maps";
|
||||
const char* szWorkDirWmo = "./Buildings";
|
||||
const char* szRawVMAPMagic = "VMAP041";
|
||||
|
||||
// Local testing functions
|
||||
|
||||
bool FileExists(const char* file)
|
||||
{
|
||||
if (FILE* n = fopen(file, "rb"))
|
||||
{
|
||||
fclose(n);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void strToLower(char* str)
|
||||
{
|
||||
while(*str)
|
||||
{
|
||||
*str=tolower(*str);
|
||||
++str;
|
||||
}
|
||||
}
|
||||
|
||||
// copied from contrib/extractor/System.cpp
|
||||
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.getRecord(LiqType_count - 1).getUInt(0);
|
||||
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", (unsigned int)LiqType_count);
|
||||
}
|
||||
|
||||
bool ExtractWmo()
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
//const char* ParsArchiveNames[] = {"patch-2.MPQ", "patch.MPQ", "common.MPQ", "expansion.MPQ"};
|
||||
|
||||
for (ArchiveSet::const_iterator ar_itr = gOpenArchives.begin(); ar_itr != gOpenArchives.end() && success; ++ar_itr)
|
||||
{
|
||||
vector<string> filelist;
|
||||
|
||||
(*ar_itr)->GetFileListTo(filelist);
|
||||
for (vector<string>::iterator fname = filelist.begin(); fname != filelist.end() && success; ++fname)
|
||||
{
|
||||
if (fname->find(".wmo") != string::npos)
|
||||
success = ExtractSingleWmo(*fname);
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
printf("\nExtract wmo complete (No (fatal) errors)\n");
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool ExtractSingleWmo(std::string& fname)
|
||||
{
|
||||
// Copy files from archive
|
||||
|
||||
char szLocalFile[1024];
|
||||
const char * plain_name = GetPlainName(fname.c_str());
|
||||
sprintf(szLocalFile, "%s/%s", szWorkDirWmo, plain_name);
|
||||
fixnamen(szLocalFile,strlen(szLocalFile));
|
||||
|
||||
if (FileExists(szLocalFile))
|
||||
return true;
|
||||
|
||||
int p = 0;
|
||||
// Select root wmo files
|
||||
char const* rchr = strrchr(plain_name, '_');
|
||||
if (rchr != NULL)
|
||||
{
|
||||
char cpy[4];
|
||||
memcpy(cpy, rchr, 4);
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
int m = cpy[i];
|
||||
if (isdigit(m))
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
if (p == 3)
|
||||
return true;
|
||||
|
||||
bool file_ok = true;
|
||||
std::cout << "Extracting " << fname << std::endl;
|
||||
WMORoot froot(fname);
|
||||
if(!froot.open())
|
||||
{
|
||||
printf("Couldn't open RootWmo!!!\n");
|
||||
return true;
|
||||
}
|
||||
FILE *output = fopen(szLocalFile,"wb");
|
||||
if(!output)
|
||||
{
|
||||
printf("couldn't open %s for writing!\n", szLocalFile);
|
||||
return false;
|
||||
}
|
||||
froot.ConvertToVMAPRootWmo(output);
|
||||
int Wmo_nVertices = 0;
|
||||
//printf("root has %d groups\n", froot->nGroups);
|
||||
if (froot.nGroups !=0)
|
||||
{
|
||||
for (uint32 i = 0; i < froot.nGroups; ++i)
|
||||
{
|
||||
char temp[1024];
|
||||
strcpy(temp, fname.c_str());
|
||||
temp[fname.length()-4] = 0;
|
||||
char groupFileName[1024];
|
||||
sprintf(groupFileName, "%s_%03u.wmo", temp, i);
|
||||
//printf("Trying to open groupfile %s\n",groupFileName);
|
||||
|
||||
string s = groupFileName;
|
||||
WMOGroup fgroup(s);
|
||||
if(!fgroup.open())
|
||||
{
|
||||
printf("Could not open all Group file for: %s\n", plain_name);
|
||||
file_ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
Wmo_nVertices += fgroup.ConvertToVMAPGroupWmo(output, &froot, preciseVectorData);
|
||||
}
|
||||
}
|
||||
|
||||
fseek(output, 8, SEEK_SET); // store the correct no of vertices
|
||||
fwrite(&Wmo_nVertices,sizeof(int),1,output);
|
||||
fclose(output);
|
||||
|
||||
// Delete the extracted file in the case of an error
|
||||
if (!file_ok)
|
||||
remove(szLocalFile);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ParsMapFiles()
|
||||
{
|
||||
char fn[512];
|
||||
//char id_filename[64];
|
||||
char id[10];
|
||||
for (unsigned int i=0; i<map_count; ++i)
|
||||
{
|
||||
sprintf(id,"%03u",map_ids[i].id);
|
||||
sprintf(fn,"World\\Maps\\%s\\%s.wdt", map_ids[i].name, map_ids[i].name);
|
||||
WDTFile WDT(fn,map_ids[i].name);
|
||||
if(WDT.init(id, map_ids[i].id))
|
||||
{
|
||||
printf("Processing Map %u\n[", map_ids[i].id);
|
||||
for (int x=0; x<64; ++x)
|
||||
{
|
||||
for (int y=0; y<64; ++y)
|
||||
{
|
||||
if (ADTFile *ADT = WDT.GetMap(x,y))
|
||||
{
|
||||
//sprintf(id_filename,"%02u %02u %03u",x,y,map_ids[i].id);//!!!!!!!!!
|
||||
ADT->init(map_ids[i].id, x, y);
|
||||
delete ADT;
|
||||
}
|
||||
}
|
||||
printf("#");
|
||||
fflush(stdout);
|
||||
}
|
||||
printf("]\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void getGamePath()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
strcpy(input_path,"Data\\");
|
||||
#else
|
||||
strcpy(input_path,"Data/");
|
||||
#endif
|
||||
}
|
||||
|
||||
bool scan_patches(char* scanmatch, std::vector<std::string>& pArchiveNames)
|
||||
{
|
||||
int i;
|
||||
char path[512];
|
||||
|
||||
for (i = 1; i <= 99; i++)
|
||||
{
|
||||
if (i != 1)
|
||||
{
|
||||
sprintf(path, "%s-%d.MPQ", scanmatch, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(path, "%s.MPQ", scanmatch);
|
||||
}
|
||||
#ifdef __linux__
|
||||
if(FILE* h = fopen64(path, "rb"))
|
||||
#else
|
||||
if(FILE* h = fopen(path, "rb"))
|
||||
#endif
|
||||
{
|
||||
fclose(h);
|
||||
//matches.push_back(path);
|
||||
pArchiveNames.push_back(path);
|
||||
}
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool fillArchiveNameVector(std::vector<std::string>& pArchiveNames)
|
||||
{
|
||||
if(!hasInputPathParam)
|
||||
getGamePath();
|
||||
|
||||
printf("\nGame path: %s\n", input_path);
|
||||
|
||||
char path[512];
|
||||
string in_path(input_path);
|
||||
std::vector<std::string> locales, searchLocales;
|
||||
|
||||
searchLocales.push_back("enGB");
|
||||
searchLocales.push_back("enUS");
|
||||
searchLocales.push_back("deDE");
|
||||
searchLocales.push_back("esES");
|
||||
searchLocales.push_back("frFR");
|
||||
searchLocales.push_back("koKR");
|
||||
searchLocales.push_back("zhCN");
|
||||
searchLocales.push_back("zhTW");
|
||||
searchLocales.push_back("enCN");
|
||||
searchLocales.push_back("enTW");
|
||||
searchLocales.push_back("esMX");
|
||||
searchLocales.push_back("ruRU");
|
||||
|
||||
for (std::vector<std::string>::iterator i = searchLocales.begin(); i != searchLocales.end(); ++i)
|
||||
{
|
||||
std::string localePath = in_path + *i;
|
||||
// check if locale exists:
|
||||
struct stat status;
|
||||
if (stat(localePath.c_str(), &status))
|
||||
continue;
|
||||
if ((status.st_mode & S_IFDIR) == 0)
|
||||
continue;
|
||||
printf("Found locale '%s'\n", i->c_str());
|
||||
locales.push_back(*i);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// open locale expansion and common files
|
||||
printf("Adding data files from locale directories.\n");
|
||||
for (std::vector<std::string>::iterator i = locales.begin(); i != locales.end(); ++i)
|
||||
{
|
||||
pArchiveNames.push_back(in_path + *i + "/locale-" + *i + ".MPQ");
|
||||
pArchiveNames.push_back(in_path + *i + "/expansion-locale-" + *i + ".MPQ");
|
||||
pArchiveNames.push_back(in_path + *i + "/lichking-locale-" + *i + ".MPQ");
|
||||
}
|
||||
|
||||
// open expansion and common files
|
||||
pArchiveNames.push_back(input_path + string("common.MPQ"));
|
||||
pArchiveNames.push_back(input_path + string("common-2.MPQ"));
|
||||
pArchiveNames.push_back(input_path + string("expansion.MPQ"));
|
||||
pArchiveNames.push_back(input_path + string("lichking.MPQ"));
|
||||
|
||||
// now, scan for the patch levels in the core dir
|
||||
printf("Scanning patch levels from data directory.\n");
|
||||
sprintf(path, "%spatch", input_path);
|
||||
if (!scan_patches(path, pArchiveNames))
|
||||
return(false);
|
||||
|
||||
// now, scan for the patch levels in locale dirs
|
||||
printf("Scanning patch levels from locale directories.\n");
|
||||
bool foundOne = false;
|
||||
for (std::vector<std::string>::iterator i = locales.begin(); i != locales.end(); ++i)
|
||||
{
|
||||
printf("Locale: %s\n", i->c_str());
|
||||
sprintf(path, "%s%s/patch-%s", input_path, i->c_str(), i->c_str());
|
||||
if(scan_patches(path, pArchiveNames))
|
||||
foundOne = true;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
if(!foundOne)
|
||||
{
|
||||
printf("no locale found\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool processArgv(int argc, char ** argv, const char *versionString)
|
||||
{
|
||||
bool result = true;
|
||||
hasInputPathParam = false;
|
||||
preciseVectorData = false;
|
||||
|
||||
for(int i = 1; i < argc; ++i)
|
||||
{
|
||||
if(strcmp("-s",argv[i]) == 0)
|
||||
{
|
||||
preciseVectorData = false;
|
||||
}
|
||||
else if(strcmp("-d",argv[i]) == 0)
|
||||
{
|
||||
if((i+1)<argc)
|
||||
{
|
||||
hasInputPathParam = true;
|
||||
strcpy(input_path, argv[i+1]);
|
||||
if (input_path[strlen(input_path) - 1] != '\\' && input_path[strlen(input_path) - 1] != '/')
|
||||
strcat(input_path, "/");
|
||||
++i;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
else if(strcmp("-?",argv[1]) == 0)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
else if(strcmp("-l",argv[i]) == 0)
|
||||
{
|
||||
preciseVectorData = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!result)
|
||||
{
|
||||
printf("Extract %s.\n",versionString);
|
||||
printf("%s [-?][-s][-l][-d <path>]\n", argv[0]);
|
||||
printf(" -s : (default) small size (data size optimization), ~500MB less vmap data.\n");
|
||||
printf(" -l : large size, ~500MB more vmap data. (might contain more details)\n");
|
||||
printf(" -d <path>: Path to the vector data source folder.\n");
|
||||
printf(" -? : This message.\n");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
// Main
|
||||
//
|
||||
// The program must be run with two command line arguments
|
||||
//
|
||||
// Arg1 - The source MPQ name (for testing reading and file find)
|
||||
// Arg2 - Listfile name
|
||||
//
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
bool success=true;
|
||||
const char *versionString = "V4.00 2012_02";
|
||||
|
||||
// Use command line arguments, when some
|
||||
if (!processArgv(argc, argv, versionString))
|
||||
return 1;
|
||||
|
||||
// some simple check if working dir is dirty
|
||||
else
|
||||
{
|
||||
std::string sdir = std::string(szWorkDirWmo) + "/dir";
|
||||
std::string sdir_bin = std::string(szWorkDirWmo) + "/dir_bin";
|
||||
struct stat status;
|
||||
if (!stat(sdir.c_str(), &status) || !stat(sdir_bin.c_str(), &status))
|
||||
{
|
||||
printf("Your output directory seems to be polluted, please use an empty directory!\n");
|
||||
printf("<press return to exit>");
|
||||
char garbage[2];
|
||||
return scanf("%c", garbage);
|
||||
}
|
||||
}
|
||||
|
||||
printf("Extract %s. Beginning work ....\n",versionString);
|
||||
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
// Create the working directory
|
||||
if (mkdir(szWorkDirWmo
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
, 0711
|
||||
#endif
|
||||
))
|
||||
success = (errno == EEXIST);
|
||||
|
||||
// prepare archive name list
|
||||
std::vector<std::string> archiveNames;
|
||||
fillArchiveNameVector(archiveNames);
|
||||
for (size_t i=0; i < archiveNames.size(); ++i)
|
||||
{
|
||||
MPQArchive *archive = new MPQArchive(archiveNames[i].c_str());
|
||||
if (gOpenArchives.empty() || gOpenArchives.front() != archive)
|
||||
delete archive;
|
||||
}
|
||||
|
||||
if (gOpenArchives.empty())
|
||||
{
|
||||
printf("FATAL ERROR: None MPQ archive found by path '%s'. Use -d option with proper path.\n",input_path);
|
||||
return 1;
|
||||
}
|
||||
ReadLiquidTypeTableDBC();
|
||||
|
||||
// extract data
|
||||
if (success)
|
||||
success = ExtractWmo();
|
||||
|
||||
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
//map.dbc
|
||||
if (success)
|
||||
{
|
||||
DBCFile * dbc = new DBCFile("DBFilesClient\\Map.dbc");
|
||||
if (!dbc->open())
|
||||
{
|
||||
delete dbc;
|
||||
printf("FATAL ERROR: Map.dbc not found in data file.\n");
|
||||
return 1;
|
||||
}
|
||||
map_count=dbc->getRecordCount ();
|
||||
map_ids=new map_id[map_count];
|
||||
for (unsigned int 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("Map - %s\n",map_ids[x].name);
|
||||
}
|
||||
|
||||
|
||||
delete dbc;
|
||||
ParsMapFiles();
|
||||
delete [] map_ids;
|
||||
//nError = ERROR_SUCCESS;
|
||||
// Extract models, listed in DameObjectDisplayInfo.dbc
|
||||
ExtractGameobjectModels();
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
if (!success)
|
||||
{
|
||||
printf("ERROR: Extract %s. Work NOT complete.\n Precise vector data=%d.\nPress any key.\n",versionString, preciseVectorData);
|
||||
getchar();
|
||||
}
|
||||
|
||||
printf("Extract %s. Work complete. No errors.\n",versionString);
|
||||
delete [] LiqType;
|
||||
return 0;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef VMAPEXPORT_H
|
||||
#define VMAPEXPORT_H
|
||||
|
||||
#include <string>
|
||||
|
||||
enum ModelFlags
|
||||
{
|
||||
MOD_M2 = 1,
|
||||
MOD_WORLDSPAWN = 1<<1,
|
||||
MOD_HAS_BOUND = 1<<2
|
||||
};
|
||||
|
||||
extern const char * szWorkDirWmo;
|
||||
extern const char * szRawVMAPMagic; // vmap magic string for extracted raw vmap data
|
||||
|
||||
bool FileExists(const char * file);
|
||||
void strToLower(char* str);
|
||||
|
||||
bool ExtractSingleWmo(std::string& fname);
|
||||
bool ExtractSingleModel(std::string& fname);
|
||||
|
||||
void ExtractGameobjectModels();
|
||||
|
||||
#endif
|
||||
@@ -1,130 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vmapexport.h"
|
||||
#include "wdtfile.h"
|
||||
#include "adtfile.h"
|
||||
#include <cstdio>
|
||||
|
||||
char * wdtGetPlainName(char * FileName)
|
||||
{
|
||||
char * szTemp;
|
||||
|
||||
if((szTemp = strrchr(FileName, '\\')) != NULL)
|
||||
FileName = szTemp + 1;
|
||||
return FileName;
|
||||
}
|
||||
|
||||
WDTFile::WDTFile(char* file_name, char* file_name1) : WDT(file_name), gWmoInstansName(NULL), gnWMO(0)
|
||||
{
|
||||
filename.append(file_name1,strlen(file_name1));
|
||||
}
|
||||
|
||||
bool WDTFile::init(char* /*map_id*/, unsigned int mapID)
|
||||
{
|
||||
if (WDT.isEof())
|
||||
{
|
||||
//printf("Can't find WDT file.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
char fourcc[5];
|
||||
uint32 size;
|
||||
|
||||
std::string dirname = std::string(szWorkDirWmo) + "/dir_bin";
|
||||
FILE *dirfile;
|
||||
dirfile = fopen(dirname.c_str(), "ab");
|
||||
if(!dirfile)
|
||||
{
|
||||
printf("Can't open dirfile!'%s'\n", dirname.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!WDT.isEof())
|
||||
{
|
||||
WDT.read(fourcc,4);
|
||||
WDT.read(&size, 4);
|
||||
|
||||
flipcc(fourcc);
|
||||
fourcc[4] = 0;
|
||||
|
||||
size_t nextpos = WDT.getPos() + size;
|
||||
|
||||
if (!strcmp(fourcc,"MAIN"))
|
||||
{
|
||||
}
|
||||
if (!strcmp(fourcc,"MWMO"))
|
||||
{
|
||||
// global map objects
|
||||
if (size)
|
||||
{
|
||||
char *buf = new char[size];
|
||||
WDT.read(buf, size);
|
||||
char *p=buf;
|
||||
int q = 0;
|
||||
gWmoInstansName = new string[size];
|
||||
while (p < buf + size)
|
||||
{
|
||||
char* s=wdtGetPlainName(p);
|
||||
fixnamen(s,strlen(s));
|
||||
p=p+strlen(p)+1;
|
||||
gWmoInstansName[q++] = s;
|
||||
}
|
||||
delete[] buf;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(fourcc, "MODF"))
|
||||
{
|
||||
// global wmo instance data
|
||||
if (size)
|
||||
{
|
||||
gnWMO = (int)size / 64;
|
||||
|
||||
for (int i = 0; i < gnWMO; ++i)
|
||||
{
|
||||
int id;
|
||||
WDT.read(&id, 4);
|
||||
WMOInstance inst(WDT,gWmoInstansName[id].c_str(), mapID, 65, 65, dirfile);
|
||||
}
|
||||
|
||||
delete[] gWmoInstansName;
|
||||
}
|
||||
}
|
||||
WDT.seek((int)nextpos);
|
||||
}
|
||||
|
||||
WDT.close();
|
||||
fclose(dirfile);
|
||||
return true;
|
||||
}
|
||||
|
||||
WDTFile::~WDTFile(void)
|
||||
{
|
||||
WDT.close();
|
||||
}
|
||||
|
||||
ADTFile* WDTFile::GetMap(int x, int z)
|
||||
{
|
||||
if(!(x>=0 && z >= 0 && x<64 && z<64))
|
||||
return NULL;
|
||||
|
||||
char name[512];
|
||||
|
||||
sprintf(name,"World\\Maps\\%s\\%s_%d_%d.adt", filename.c_str(), filename.c_str(), x, z);
|
||||
return new ADTFile(name);
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef WDTFILE_H
|
||||
#define WDTFILE_H
|
||||
|
||||
#include "mpq_libmpq04.h"
|
||||
#include "wmo.h"
|
||||
#include <string>
|
||||
#include "stdlib.h"
|
||||
|
||||
class ADTFile;
|
||||
|
||||
class WDTFile
|
||||
{
|
||||
private:
|
||||
MPQFile WDT;
|
||||
string filename;
|
||||
public:
|
||||
WDTFile(char* file_name, char* file_name1);
|
||||
~WDTFile(void);
|
||||
bool init(char* map_id, unsigned int mapID);
|
||||
|
||||
string* gWmoInstansName;
|
||||
int gnWMO;
|
||||
|
||||
ADTFile* GetMap(int x, int z);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,568 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vmapexport.h"
|
||||
#include "wmo.h"
|
||||
#include "vec3d.h"
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <fstream>
|
||||
#undef min
|
||||
#undef max
|
||||
#include "mpq_libmpq04.h"
|
||||
|
||||
using namespace std;
|
||||
extern uint16 *LiqType;
|
||||
|
||||
WMORoot::WMORoot(std::string &filename)
|
||||
: filename(filename), col(0), nTextures(0), nGroups(0), nP(0), nLights(0),
|
||||
nModels(0), nDoodads(0), nDoodadSets(0), RootWMOID(0), liquidType(0)
|
||||
{
|
||||
memset(bbcorn1, 0, sizeof(bbcorn1));
|
||||
memset(bbcorn2, 0, sizeof(bbcorn2));
|
||||
}
|
||||
|
||||
bool WMORoot::open()
|
||||
{
|
||||
MPQFile f(filename.c_str());
|
||||
if(f.isEof ())
|
||||
{
|
||||
printf("No such file.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 size;
|
||||
char fourcc[5];
|
||||
|
||||
while (!f.isEof())
|
||||
{
|
||||
f.read(fourcc,4);
|
||||
f.read(&size, 4);
|
||||
|
||||
flipcc(fourcc);
|
||||
fourcc[4] = 0;
|
||||
|
||||
size_t nextpos = f.getPos() + size;
|
||||
|
||||
if (!strcmp(fourcc,"MOHD")) // header
|
||||
{
|
||||
f.read(&nTextures, 4);
|
||||
f.read(&nGroups, 4);
|
||||
f.read(&nP, 4);
|
||||
f.read(&nLights, 4);
|
||||
f.read(&nModels, 4);
|
||||
f.read(&nDoodads, 4);
|
||||
f.read(&nDoodadSets, 4);
|
||||
f.read(&col, 4);
|
||||
f.read(&RootWMOID, 4);
|
||||
f.read(bbcorn1, 12);
|
||||
f.read(bbcorn2, 12);
|
||||
f.read(&liquidType, 4);
|
||||
break;
|
||||
}
|
||||
/*
|
||||
else if (!strcmp(fourcc,"MOTX"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOMT"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOGN"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOGI"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOLT"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MODN"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MODS"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MODD"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOSB"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOPV"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOPT"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOPR"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MFOG"))
|
||||
{
|
||||
}
|
||||
*/
|
||||
f.seek((int)nextpos);
|
||||
}
|
||||
f.close ();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WMORoot::ConvertToVMAPRootWmo(FILE* pOutfile)
|
||||
{
|
||||
//printf("Convert RootWmo...\n");
|
||||
|
||||
fwrite(szRawVMAPMagic, 1, 8, pOutfile);
|
||||
unsigned int nVectors = 0;
|
||||
fwrite(&nVectors,sizeof(nVectors), 1, pOutfile); // will be filled later
|
||||
fwrite(&nGroups, 4, 1, pOutfile);
|
||||
fwrite(&RootWMOID, 4, 1, pOutfile);
|
||||
return true;
|
||||
}
|
||||
|
||||
WMOGroup::WMOGroup(const std::string &filename) :
|
||||
filename(filename), MOPY(0), MOVI(0), MoviEx(0), MOVT(0), MOBA(0), MobaEx(0),
|
||||
hlq(0), LiquEx(0), LiquBytes(0), groupName(0), descGroupName(0), mogpFlags(0),
|
||||
moprIdx(0), moprNItems(0), nBatchA(0), nBatchB(0), nBatchC(0), fogIdx(0),
|
||||
liquidType(0), groupWMOID(0), mopy_size(0), moba_size(0), LiquEx_size(0),
|
||||
nVertices(0), nTriangles(0), liquflags(0)
|
||||
{
|
||||
memset(bbcorn1, 0, sizeof(bbcorn1));
|
||||
memset(bbcorn2, 0, sizeof(bbcorn2));
|
||||
}
|
||||
|
||||
bool WMOGroup::open()
|
||||
{
|
||||
MPQFile f(filename.c_str());
|
||||
if(f.isEof ())
|
||||
{
|
||||
printf("No such file.\n");
|
||||
return false;
|
||||
}
|
||||
uint32 size;
|
||||
char fourcc[5];
|
||||
while (!f.isEof())
|
||||
{
|
||||
f.read(fourcc,4);
|
||||
f.read(&size, 4);
|
||||
flipcc(fourcc);
|
||||
if (!strcmp(fourcc,"MOGP"))//Fix sizeoff = Data size.
|
||||
{
|
||||
size = 68;
|
||||
}
|
||||
fourcc[4] = 0;
|
||||
size_t nextpos = f.getPos() + size;
|
||||
LiquEx_size = 0;
|
||||
liquflags = 0;
|
||||
|
||||
if (!strcmp(fourcc,"MOGP"))//header
|
||||
{
|
||||
f.read(&groupName, 4);
|
||||
f.read(&descGroupName, 4);
|
||||
f.read(&mogpFlags, 4);
|
||||
f.read(bbcorn1, 12);
|
||||
f.read(bbcorn2, 12);
|
||||
f.read(&moprIdx, 2);
|
||||
f.read(&moprNItems, 2);
|
||||
f.read(&nBatchA, 2);
|
||||
f.read(&nBatchB, 2);
|
||||
f.read(&nBatchC, 4);
|
||||
f.read(&fogIdx, 4);
|
||||
f.read(&liquidType, 4);
|
||||
f.read(&groupWMOID,4);
|
||||
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOPY"))
|
||||
{
|
||||
MOPY = new char[size];
|
||||
mopy_size = size;
|
||||
nTriangles = (int)size / 2;
|
||||
f.read(MOPY, size);
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOVI"))
|
||||
{
|
||||
MOVI = new uint16[size/2];
|
||||
f.read(MOVI, size);
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOVT"))
|
||||
{
|
||||
MOVT = new float[size/4];
|
||||
f.read(MOVT, size);
|
||||
nVertices = (int)size / 12;
|
||||
}
|
||||
else if (!strcmp(fourcc,"MONR"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOTV"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOBA"))
|
||||
{
|
||||
MOBA = new uint16[size/2];
|
||||
moba_size = size/2;
|
||||
f.read(MOBA, size);
|
||||
}
|
||||
else if (!strcmp(fourcc,"MLIQ"))
|
||||
{
|
||||
liquflags |= 1;
|
||||
hlq = new WMOLiquidHeader();
|
||||
f.read(hlq, 0x1E);
|
||||
LiquEx_size = sizeof(WMOLiquidVert) * hlq->xverts * hlq->yverts;
|
||||
LiquEx = new WMOLiquidVert[hlq->xverts * hlq->yverts];
|
||||
f.read(LiquEx, LiquEx_size);
|
||||
int nLiquBytes = hlq->xtiles * hlq->ytiles;
|
||||
LiquBytes = new char[nLiquBytes];
|
||||
f.read(LiquBytes, nLiquBytes);
|
||||
|
||||
/* std::ofstream llog("Buildings/liquid.log", ios_base::out | ios_base::app);
|
||||
llog << filename;
|
||||
llog << "\nbbox: " << bbcorn1[0] << ", " << bbcorn1[1] << ", " << bbcorn1[2] << " | " << bbcorn2[0] << ", " << bbcorn2[1] << ", " << bbcorn2[2];
|
||||
llog << "\nlpos: " << hlq->pos_x << ", " << hlq->pos_y << ", " << hlq->pos_z;
|
||||
llog << "\nx-/yvert: " << hlq->xverts << "/" << hlq->yverts << " size: " << size << " expected size: " << 30 + hlq->xverts*hlq->yverts*8 + hlq->xtiles*hlq->ytiles << std::endl;
|
||||
llog.close(); */
|
||||
}
|
||||
f.seek((int)nextpos);
|
||||
}
|
||||
f.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, WMORoot *rootWMO, bool preciseVectorData)
|
||||
{
|
||||
fwrite(&mogpFlags,sizeof(uint32),1,output);
|
||||
fwrite(&groupWMOID,sizeof(uint32),1,output);
|
||||
// group bound
|
||||
fwrite(bbcorn1, sizeof(float), 3, output);
|
||||
fwrite(bbcorn2, sizeof(float), 3, output);
|
||||
fwrite(&liquflags,sizeof(uint32),1,output);
|
||||
int nColTriangles = 0;
|
||||
if (preciseVectorData)
|
||||
{
|
||||
char GRP[] = "GRP ";
|
||||
fwrite(GRP,1,4,output);
|
||||
|
||||
int k = 0;
|
||||
int moba_batch = moba_size/12;
|
||||
MobaEx = new int[moba_batch*4];
|
||||
for(int i=8; i<moba_size; i+=12)
|
||||
{
|
||||
MobaEx[k++] = MOBA[i];
|
||||
}
|
||||
int moba_size_grp = moba_batch*4+4;
|
||||
fwrite(&moba_size_grp,4,1,output);
|
||||
fwrite(&moba_batch,4,1,output);
|
||||
fwrite(MobaEx,4,k,output);
|
||||
delete [] MobaEx;
|
||||
|
||||
uint32 nIdexes = nTriangles * 3;
|
||||
|
||||
if(fwrite("INDX",4, 1, output) != 1)
|
||||
{
|
||||
printf("Error while writing file nbraches ID");
|
||||
exit(0);
|
||||
}
|
||||
int wsize = sizeof(uint32) + sizeof(unsigned short) * nIdexes;
|
||||
if(fwrite(&wsize, sizeof(int), 1, output) != 1)
|
||||
{
|
||||
printf("Error while writing file wsize");
|
||||
// no need to exit?
|
||||
}
|
||||
if(fwrite(&nIdexes, sizeof(uint32), 1, output) != 1)
|
||||
{
|
||||
printf("Error while writing file nIndexes");
|
||||
exit(0);
|
||||
}
|
||||
if(nIdexes >0)
|
||||
{
|
||||
if(fwrite(MOVI, sizeof(unsigned short), nIdexes, output) != nIdexes)
|
||||
{
|
||||
printf("Error while writing file indexarray");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
if(fwrite("VERT",4, 1, output) != 1)
|
||||
{
|
||||
printf("Error while writing file nbraches ID");
|
||||
exit(0);
|
||||
}
|
||||
wsize = sizeof(int) + sizeof(float) * 3 * nVertices;
|
||||
if(fwrite(&wsize, sizeof(int), 1, output) != 1)
|
||||
{
|
||||
printf("Error while writing file wsize");
|
||||
// no need to exit?
|
||||
}
|
||||
if(fwrite(&nVertices, sizeof(int), 1, output) != 1)
|
||||
{
|
||||
printf("Error while writing file nVertices");
|
||||
exit(0);
|
||||
}
|
||||
if(nVertices >0)
|
||||
{
|
||||
if(fwrite(MOVT, sizeof(float)*3, nVertices, output) != nVertices)
|
||||
{
|
||||
printf("Error while writing file vectors");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
nColTriangles = nTriangles;
|
||||
}
|
||||
else
|
||||
{
|
||||
char GRP[] = "GRP ";
|
||||
fwrite(GRP,1,4,output);
|
||||
int k = 0;
|
||||
int moba_batch = moba_size/12;
|
||||
MobaEx = new int[moba_batch*4];
|
||||
for(int i=8; i<moba_size; i+=12)
|
||||
{
|
||||
MobaEx[k++] = MOBA[i];
|
||||
}
|
||||
|
||||
int moba_size_grp = moba_batch*4+4;
|
||||
fwrite(&moba_size_grp,4,1,output);
|
||||
fwrite(&moba_batch,4,1,output);
|
||||
fwrite(MobaEx,4,k,output);
|
||||
delete [] MobaEx;
|
||||
|
||||
//-------INDX------------------------------------
|
||||
//-------MOPY--------
|
||||
MoviEx = new uint16[nTriangles*3]; // "worst case" size...
|
||||
int *IndexRenum = new int[nVertices];
|
||||
memset(IndexRenum, 0xFF, nVertices*sizeof(int));
|
||||
for (int i=0; i<nTriangles; ++i)
|
||||
{
|
||||
// Skip no collision triangles
|
||||
if (MOPY[2*i]&WMO_MATERIAL_NO_COLLISION ||
|
||||
!(MOPY[2*i]&(WMO_MATERIAL_HINT|WMO_MATERIAL_COLLIDE_HIT)) )
|
||||
continue;
|
||||
// Use this triangle
|
||||
for (int j=0; j<3; ++j)
|
||||
{
|
||||
IndexRenum[MOVI[3*i + j]] = 1;
|
||||
MoviEx[3*nColTriangles + j] = MOVI[3*i + j];
|
||||
}
|
||||
++nColTriangles;
|
||||
}
|
||||
|
||||
// assign new vertex index numbers
|
||||
int nColVertices = 0;
|
||||
for (uint32 i=0; i<nVertices; ++i)
|
||||
{
|
||||
if (IndexRenum[i] == 1)
|
||||
{
|
||||
IndexRenum[i] = nColVertices;
|
||||
++nColVertices;
|
||||
}
|
||||
}
|
||||
|
||||
// translate triangle indices to new numbers
|
||||
for (int i=0; i<3*nColTriangles; ++i)
|
||||
{
|
||||
assert(MoviEx[i] < nVertices);
|
||||
MoviEx[i] = IndexRenum[MoviEx[i]];
|
||||
}
|
||||
|
||||
// write triangle indices
|
||||
int INDX[] = {0x58444E49, nColTriangles*6+4, nColTriangles*3};
|
||||
fwrite(INDX,4,3,output);
|
||||
fwrite(MoviEx,2,nColTriangles*3,output);
|
||||
|
||||
// write vertices
|
||||
int VERT[] = {0x54524556, nColVertices*3*static_cast<int>(sizeof(float))+4, nColVertices};// "VERT"
|
||||
int check = 3*nColVertices;
|
||||
fwrite(VERT,4,3,output);
|
||||
for (uint32 i=0; i<nVertices; ++i)
|
||||
if(IndexRenum[i] >= 0)
|
||||
check -= fwrite(MOVT+3*i, sizeof(float), 3, output);
|
||||
|
||||
assert(check==0);
|
||||
|
||||
delete [] MoviEx;
|
||||
delete [] IndexRenum;
|
||||
}
|
||||
|
||||
//------LIQU------------------------
|
||||
if (LiquEx_size != 0)
|
||||
{
|
||||
int LIQU_h[] = {0x5551494C, static_cast<int>(sizeof(WMOLiquidHeader) + LiquEx_size) + hlq->xtiles*hlq->ytiles};// "LIQU"
|
||||
fwrite(LIQU_h, 4, 2, output);
|
||||
|
||||
// according to WoW.Dev Wiki:
|
||||
uint32 liquidEntry;
|
||||
if (rootWMO->liquidType & 4)
|
||||
liquidEntry = liquidType;
|
||||
else if (liquidType == 15)
|
||||
liquidEntry = 0;
|
||||
else
|
||||
liquidEntry = liquidType + 1;
|
||||
|
||||
if (!liquidEntry)
|
||||
{
|
||||
int v1; // edx@1
|
||||
int v2; // eax@1
|
||||
|
||||
v1 = hlq->xtiles * hlq->ytiles;
|
||||
v2 = 0;
|
||||
if (v1 > 0)
|
||||
{
|
||||
while ((LiquBytes[v2] & 0xF) == 15)
|
||||
{
|
||||
++v2;
|
||||
if (v2 >= v1)
|
||||
break;
|
||||
}
|
||||
|
||||
if (v2 < v1 && (LiquBytes[v2] & 0xF) != 15)
|
||||
liquidEntry = (LiquBytes[v2] & 0xF) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (liquidEntry && liquidEntry < 21)
|
||||
{
|
||||
switch ((liquidEntry - 1) & 3)
|
||||
{
|
||||
case 0:
|
||||
liquidEntry = ((mogpFlags & 0x80000) != 0) + 13;
|
||||
break;
|
||||
case 1:
|
||||
liquidEntry = 14;
|
||||
break;
|
||||
case 2:
|
||||
liquidEntry = 19;
|
||||
break;
|
||||
case 3:
|
||||
liquidEntry = 20;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hlq->type = liquidEntry;
|
||||
|
||||
/* std::ofstream llog("Buildings/liquid.log", ios_base::out | ios_base::app);
|
||||
llog << filename;
|
||||
llog << ":\nliquidEntry: " << liquidEntry << " type: " << hlq->type << " (root:" << rootWMO->liquidType << " group:" << liquidType << ")\n";
|
||||
llog.close(); */
|
||||
|
||||
fwrite(hlq, sizeof(WMOLiquidHeader), 1, output);
|
||||
// only need height values, the other values are unknown anyway
|
||||
for (uint32 i = 0; i<LiquEx_size/sizeof(WMOLiquidVert); ++i)
|
||||
fwrite(&LiquEx[i].height, sizeof(float), 1, output);
|
||||
// todo: compress to bit field
|
||||
fwrite(LiquBytes, 1, hlq->xtiles*hlq->ytiles, output);
|
||||
}
|
||||
|
||||
return nColTriangles;
|
||||
}
|
||||
|
||||
WMOGroup::~WMOGroup()
|
||||
{
|
||||
delete [] MOPY;
|
||||
delete [] MOVI;
|
||||
delete [] MOVT;
|
||||
delete [] MOBA;
|
||||
delete hlq;
|
||||
delete [] LiquEx;
|
||||
delete [] LiquBytes;
|
||||
}
|
||||
|
||||
WMOInstance::WMOInstance(MPQFile& f, char const* WmoInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile)
|
||||
: currx(0), curry(0), wmo(NULL), doodadset(0), pos(), indx(0), id(0), d2(0), d3(0)
|
||||
{
|
||||
float ff[3];
|
||||
f.read(&id, 4);
|
||||
f.read(ff,12);
|
||||
pos = Vec3D(ff[0],ff[1],ff[2]);
|
||||
f.read(ff,12);
|
||||
rot = Vec3D(ff[0],ff[1],ff[2]);
|
||||
f.read(ff,12);
|
||||
pos2 = Vec3D(ff[0],ff[1],ff[2]);
|
||||
f.read(ff,12);
|
||||
pos3 = Vec3D(ff[0],ff[1],ff[2]);
|
||||
f.read(&d2,4);
|
||||
|
||||
uint16 trash,adtId;
|
||||
f.read(&adtId,2);
|
||||
f.read(&trash,2);
|
||||
|
||||
//-----------add_in _dir_file----------------
|
||||
|
||||
char tempname[512];
|
||||
sprintf(tempname, "%s/%s", szWorkDirWmo, WmoInstName);
|
||||
FILE *input;
|
||||
input = fopen(tempname, "r+b");
|
||||
|
||||
if(!input)
|
||||
{
|
||||
printf("WMOInstance::WMOInstance: couldn't open %s\n", tempname);
|
||||
return;
|
||||
}
|
||||
|
||||
fseek(input, 8, SEEK_SET); // get the correct no of vertices
|
||||
int nVertices;
|
||||
int count = fread(&nVertices, sizeof (int), 1, input);
|
||||
fclose(input);
|
||||
|
||||
if (count != 1 || nVertices == 0)
|
||||
return;
|
||||
|
||||
float x,z;
|
||||
x = pos.x;
|
||||
z = pos.z;
|
||||
if(x==0 && z == 0)
|
||||
{
|
||||
pos.x = 533.33333f*32;
|
||||
pos.z = 533.33333f*32;
|
||||
}
|
||||
pos = fixCoords(pos);
|
||||
pos2 = fixCoords(pos2);
|
||||
pos3 = fixCoords(pos3);
|
||||
|
||||
float scale = 1.0f;
|
||||
uint32 flags = MOD_HAS_BOUND;
|
||||
if(tileX == 65 && tileY == 65) flags |= MOD_WORLDSPAWN;
|
||||
//write mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, Bound_lo, Bound_hi, name
|
||||
fwrite(&mapID, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(&tileX, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(&tileY, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(&flags, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(&adtId, sizeof(uint16), 1, pDirfile);
|
||||
fwrite(&id, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(&pos, sizeof(float), 3, pDirfile);
|
||||
fwrite(&rot, sizeof(float), 3, pDirfile);
|
||||
fwrite(&scale, sizeof(float), 1, pDirfile);
|
||||
fwrite(&pos2, sizeof(float), 3, pDirfile);
|
||||
fwrite(&pos3, sizeof(float), 3, pDirfile);
|
||||
uint32 nlen=strlen(WmoInstName);
|
||||
fwrite(&nlen, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(WmoInstName, sizeof(char), nlen, pDirfile);
|
||||
|
||||
/* fprintf(pDirfile,"%s/%s %f,%f,%f_%f,%f,%f 1.0 %d %d %d,%d %d\n",
|
||||
MapName,
|
||||
WmoInstName,
|
||||
(float) x, (float) pos.y, (float) z,
|
||||
(float) rot.x, (float) rot.y, (float) rot.z,
|
||||
nVertices,
|
||||
realx1, realy1,
|
||||
realx2, realy2
|
||||
); */
|
||||
|
||||
// fclose(dirfile);
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef WMO_H
|
||||
#define WMO_H
|
||||
#define TILESIZE (533.33333f)
|
||||
#define CHUNKSIZE ((TILESIZE) / 16.0f)
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include "vec3d.h"
|
||||
#include "loadlib/loadlib.h"
|
||||
|
||||
// MOPY flags
|
||||
#define WMO_MATERIAL_NOCAMCOLLIDE 0x01
|
||||
#define WMO_MATERIAL_DETAIL 0x02
|
||||
#define WMO_MATERIAL_NO_COLLISION 0x04
|
||||
#define WMO_MATERIAL_HINT 0x08
|
||||
#define WMO_MATERIAL_RENDER 0x10
|
||||
#define WMO_MATERIAL_COLLIDE_HIT 0x20
|
||||
#define WMO_MATERIAL_WALL_SURFACE 0x40
|
||||
|
||||
class WMOInstance;
|
||||
class WMOManager;
|
||||
class MPQFile;
|
||||
|
||||
/* for whatever reason a certain company just can't stick to one coordinate system... */
|
||||
static inline Vec3D fixCoords(const Vec3D &v){ return Vec3D(v.z, v.x, v.y); }
|
||||
|
||||
class WMORoot
|
||||
{
|
||||
private:
|
||||
std::string filename;
|
||||
public:
|
||||
unsigned int col;
|
||||
uint32 nTextures, nGroups, nP, nLights, nModels, nDoodads, nDoodadSets, RootWMOID, liquidType;
|
||||
float bbcorn1[3];
|
||||
float bbcorn2[3];
|
||||
|
||||
WMORoot(std::string& filename);
|
||||
|
||||
bool open();
|
||||
bool ConvertToVMAPRootWmo(FILE* output);
|
||||
};
|
||||
|
||||
struct WMOLiquidHeader
|
||||
{
|
||||
int xverts, yverts, xtiles, ytiles;
|
||||
float pos_x;
|
||||
float pos_y;
|
||||
float pos_z;
|
||||
short type;
|
||||
};
|
||||
|
||||
struct WMOLiquidVert
|
||||
{
|
||||
uint16 unk1;
|
||||
uint16 unk2;
|
||||
float height;
|
||||
};
|
||||
|
||||
class WMOGroup
|
||||
{
|
||||
private:
|
||||
std::string filename;
|
||||
public:
|
||||
// MOGP
|
||||
|
||||
char* MOPY;
|
||||
uint16* MOVI;
|
||||
uint16* MoviEx;
|
||||
float* MOVT;
|
||||
uint16* MOBA;
|
||||
int* MobaEx;
|
||||
WMOLiquidHeader* hlq;
|
||||
WMOLiquidVert* LiquEx;
|
||||
char* LiquBytes;
|
||||
int groupName, descGroupName;
|
||||
int mogpFlags;
|
||||
float bbcorn1[3];
|
||||
float bbcorn2[3];
|
||||
uint16 moprIdx;
|
||||
uint16 moprNItems;
|
||||
uint16 nBatchA;
|
||||
uint16 nBatchB;
|
||||
uint32 nBatchC, fogIdx, liquidType, groupWMOID;
|
||||
|
||||
int mopy_size, moba_size;
|
||||
int LiquEx_size;
|
||||
unsigned int nVertices; // number when loaded
|
||||
int nTriangles; // number when loaded
|
||||
uint32 liquflags;
|
||||
|
||||
WMOGroup(std::string const& filename);
|
||||
~WMOGroup();
|
||||
|
||||
bool open();
|
||||
int ConvertToVMAPGroupWmo(FILE* output, WMORoot* rootWMO, bool preciseVectorData);
|
||||
};
|
||||
|
||||
class WMOInstance
|
||||
{
|
||||
static std::set<int> ids;
|
||||
public:
|
||||
std::string MapName;
|
||||
int currx;
|
||||
int curry;
|
||||
WMOGroup* wmo;
|
||||
int doodadset;
|
||||
Vec3D pos;
|
||||
Vec3D pos2, pos3, rot;
|
||||
uint32 indx, id, d2, d3;
|
||||
|
||||
WMOInstance(MPQFile&f , char const* WmoInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile);
|
||||
|
||||
static void reset();
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user