* implemented partial(=faster) ADT texture, model & wmo loading.
* stuffextract does now extract all files referenced in ADTs. * some adt loading fixes to be able to load expansion maps at least partially. * fixed typos
This commit is contained in:
parent
d50ea1c7a2
commit
de2614fa80
@ -257,7 +257,7 @@ bool ADTFile::LoadMem(ByteBuffer& buf)
|
||||
else
|
||||
{
|
||||
DEBUG(printf("ADT: MCNK: '%s' block unhandled, skipping %u bytes\n",mfcc,msize));
|
||||
if(strcmp((char*)mfcc,"MCRF"))
|
||||
if(!(isalnum(mfcc[0]) && isalnum(mfcc[1]) && isalnum(mfcc[2]) && isalnum(mfcc[3])))
|
||||
{
|
||||
printf("Error loading ADT file (chunk %u error).\n",mcnkid);
|
||||
return false; // dont care about those few mem leaks
|
||||
@ -271,9 +271,9 @@ bool ADTFile::LoadMem(ByteBuffer& buf)
|
||||
mcnkid++;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
DEBUG(printf("ADT: '%s' block unhandled, skipping %u bytes\n",fourcc,size));
|
||||
if(strcmp((char*)fourcc,"MWID") && strcmp((char*)fourcc,"MMID"))
|
||||
if(!(isalnum(fourcc[0]) && isalnum(fourcc[1]) && isalnum(fourcc[2]) && isalnum(fourcc[3])))
|
||||
{
|
||||
printf("Error loading ADT file.\n");
|
||||
return false; // dont care about those few mem leaks
|
||||
@ -288,3 +288,48 @@ bool ADTFile::LoadMem(ByteBuffer& buf)
|
||||
m_loaded = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ADT_ExportStringSetByOffset(const uint8* data, uint32 off, std::set<std::string>& st, char* stop)
|
||||
{
|
||||
data += ((uint32*)data)[off]; // seek to correct absolute offset
|
||||
data += 28; // move ptr to real start of data
|
||||
uint32 offset=0;
|
||||
std::string s;
|
||||
char c;
|
||||
while(memcmp(data+offset,stop,4))
|
||||
{
|
||||
c = data[offset];
|
||||
if(!c)
|
||||
{
|
||||
if(s.length())
|
||||
{
|
||||
DEBUG(printf("DEP: %s\n",s.c_str()));
|
||||
st.insert(s);
|
||||
s.clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
s += c;
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
|
||||
void ADT_FillTextureData(const uint8* data,std::set<std::string>& st)
|
||||
{
|
||||
ADT_ExportStringSetByOffset(data,OFFSET_TEXTURES,st,"XDMM");
|
||||
}
|
||||
|
||||
void ADT_FillWMOData(const uint8* data,std::set<std::string>& st)
|
||||
{
|
||||
ADT_ExportStringSetByOffset(data,OFFSET_WMOS,st,"DIWM");
|
||||
}
|
||||
|
||||
void ADT_FillModelData(const uint8* data,std::set<std::string>& st)
|
||||
{
|
||||
ADT_ExportStringSetByOffset(data,OFFSET_MODELS,st,"DIMM");
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
#ifndef ADTFILE_H
|
||||
#define ADTFILE_H
|
||||
|
||||
#include <set>
|
||||
|
||||
#define CHUNKS_PER_TILE 256
|
||||
|
||||
#include "ADTFileStructs.h"
|
||||
@ -26,5 +28,9 @@ public:
|
||||
bool m_loaded;
|
||||
};
|
||||
|
||||
void ADT_ExportStringSetByOffset(const uint8*, uint32, std::set<std::string>&, char*);
|
||||
void ADT_FillTextureData(const uint8*,std::set<std::string>&);
|
||||
void ADT_FillWMOData(const uint8*,std::set<std::string>&);
|
||||
void ADT_FillModelData(const uint8*,std::set<std::string>&);
|
||||
|
||||
#endif
|
||||
|
||||
@ -3,6 +3,10 @@
|
||||
#ifndef ADTFILESTRUCTS_H
|
||||
#define ADTFILESTRUCTS_H
|
||||
|
||||
#define OFFSET_TEXTURES 7
|
||||
#define OFFSET_MODELS 8
|
||||
#define OFFSET_WMOS 10
|
||||
|
||||
struct MHDR_chunk
|
||||
{
|
||||
uint32 pad;
|
||||
@ -10,8 +14,8 @@ struct MHDR_chunk
|
||||
uint32 offsTex;
|
||||
uint32 offsModels;
|
||||
uint32 offsModelsIds;
|
||||
uint32 offsMapObejcts;
|
||||
uint32 offsMapObejctsIds;
|
||||
uint32 offsMapObjects;
|
||||
uint32 offsMapObjectsIds;
|
||||
uint32 offsDoodsDef;
|
||||
uint32 offsObjectsDef;
|
||||
uint32 pad1;
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#include <fstream>
|
||||
#include <set>
|
||||
#define _COMMON_NO_THREADS
|
||||
#include "common.h"
|
||||
#include "MPQHelper.h"
|
||||
@ -9,6 +10,9 @@
|
||||
#include "Locale.h"
|
||||
|
||||
std::vector<std::string> mapNames;
|
||||
std::set<std::string> texNames;
|
||||
std::set<std::string> modelNames;
|
||||
std::set<std::string> wmoNames;
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@ -27,6 +31,7 @@ int main(int argc, char *argv[])
|
||||
CreateDir("stuffextract/data");
|
||||
ConvertDBC();
|
||||
ExtractMaps();
|
||||
ExtractMapDependencies();
|
||||
//...
|
||||
printf("\n -- finished, press enter to exit --\n");
|
||||
}
|
||||
@ -252,6 +257,8 @@ void ExtractMaps(void)
|
||||
{
|
||||
for(uint32 y=0;y<64; y++)
|
||||
{
|
||||
uint32 olddeps;
|
||||
uint32 depdiff;
|
||||
sprintf(namebuf,"World\\Maps\\%s\\%s_%u_%u.adt",mapNames[it].c_str(),mapNames[it].c_str(),x,y);
|
||||
sprintf(outbuf,MAPSDIR"/%s_%u_%u.adt",mapNames[it].c_str(),x,y);
|
||||
if(mpq.FileExists(namebuf))
|
||||
@ -269,23 +276,140 @@ void ExtractMaps(void)
|
||||
}
|
||||
fh.write((char*)bb.contents(),bb.size());
|
||||
fh.close();
|
||||
ADTFile *adt = new ADTFile();
|
||||
adt->LoadMem(bb);
|
||||
delete adt;
|
||||
olddeps = texNames.size() + modelNames.size() + wmoNames.size();
|
||||
ADT_FillTextureData(bb.contents(),texNames);
|
||||
ADT_FillModelData(bb.contents(),modelNames);
|
||||
ADT_FillWMOData(bb.contents(),wmoNames);
|
||||
depdiff = texNames.size() + modelNames.size() + wmoNames.size() - olddeps;
|
||||
extr++;
|
||||
printf("[%u/%u]: %s; %u new deps.\n",it+1,mapNames.size(),namebuf,depdiff);
|
||||
}
|
||||
}
|
||||
printf("Map [%u/%u]: %s: %u\r",it+1,mapNames.size(),mapNames[it].c_str(),extr);
|
||||
}
|
||||
}
|
||||
extrtotal+=extr;
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf("\nDONE - %u maps extracted.\n",extrtotal);
|
||||
printf("\nDONE - %u maps extracted, %u total dependencies.\n",extrtotal, texNames.size() + modelNames.size() + wmoNames.size());
|
||||
}
|
||||
|
||||
void DoNothingDummy(void)
|
||||
void ExtractMapDependencies(void)
|
||||
{
|
||||
delete [] new uint8[50];
|
||||
printf("\nExtracting map dependencies...\n\n");
|
||||
printf("- Preparing to read MPQ arcives...\n");
|
||||
MPQHelper mpqmodel("model");
|
||||
MPQHelper mpqtex("texture");
|
||||
MPQHelper mpqwmo("wmo");
|
||||
std::string path = "stuffextract/data";
|
||||
std::string pathtex = path + "/texture";
|
||||
std::string pathmodel = path + "/model";
|
||||
std::string pathwmo = path + "/wmo";
|
||||
std::string mpqfn,realfn;
|
||||
CreateDir(pathtex.c_str());
|
||||
CreateDir(pathmodel.c_str());
|
||||
CreateDir(pathwmo.c_str());
|
||||
uint32 wmosdone=0,texdone=0,mdone=0;
|
||||
|
||||
for(std::set<std::string>::iterator i = texNames.begin(); i != texNames.end(); i++)
|
||||
{
|
||||
mpqfn = *i;
|
||||
if(!mpqtex.FileExists((char*)mpqfn.c_str()))
|
||||
continue;
|
||||
realfn = pathtex + "/" + _PathToFileName(mpqfn);
|
||||
std::fstream fh;
|
||||
fh.open(realfn.c_str(),std::ios_base::out | std::ios_base::binary);
|
||||
if(fh.is_open())
|
||||
{
|
||||
ByteBuffer& bb = mpqtex.ExtractFile((char*)mpqfn.c_str());
|
||||
fh.write((const char*)bb.contents(),bb.size());
|
||||
texdone++;
|
||||
printf("- textures... %u\r",texdone);
|
||||
}
|
||||
else
|
||||
printf("Could not write texture %s\n",realfn.c_str());
|
||||
fh.close();
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
for(std::set<std::string>::iterator i = modelNames.begin(); i != modelNames.end(); i++)
|
||||
{
|
||||
mpqfn = *i;
|
||||
// no idea what bliz intended by this. the ADT files refer to .mdx models,
|
||||
// however there are only .m2 files in the MPQ archives.
|
||||
// so we just need to check if there is a .m2 file instead of the .mdx file, and load that one.
|
||||
if(!mpqmodel.FileExists((char*)mpqfn.c_str()))
|
||||
{
|
||||
std::string alt = i->substr(0,i->length()-3) + "m2";
|
||||
DEBUG(printf("MDX model not found, trying M2 file."));
|
||||
if(!mpqmodel.FileExists((char*)alt.c_str()))
|
||||
{
|
||||
DEBUG(printf(" fail.\n"));
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
mpqfn = alt;
|
||||
DEBUG(printf(" success.\n"));
|
||||
}
|
||||
}
|
||||
realfn = pathmodel + "/" + _PathToFileName(mpqfn);
|
||||
std::fstream fh;
|
||||
fh.open(realfn.c_str(),std::ios_base::out | std::ios_base::binary);
|
||||
if(fh.is_open())
|
||||
{
|
||||
ByteBuffer& bb = mpqmodel.ExtractFile((char*)mpqfn.c_str());
|
||||
fh.write((const char*)bb.contents(),bb.size());
|
||||
mdone++;
|
||||
printf("- models... %u\r",mdone);
|
||||
}
|
||||
else
|
||||
printf("Could not write model %s\n",realfn.c_str());
|
||||
fh.close();
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
for(std::set<std::string>::iterator i = wmoNames.begin(); i != wmoNames.end(); i++)
|
||||
{
|
||||
mpqfn = *i;
|
||||
if(!mpqwmo.FileExists((char*)mpqfn.c_str()))
|
||||
continue;
|
||||
realfn = pathwmo + "/" + _PathToFileName(mpqfn);
|
||||
std::fstream fh;
|
||||
fh.open(realfn.c_str(),std::ios_base::out | std::ios_base::binary);
|
||||
if(fh.is_open())
|
||||
{
|
||||
ByteBuffer& bb = mpqwmo.ExtractFile((char*)mpqfn.c_str());
|
||||
fh.write((const char*)bb.contents(),bb.size());
|
||||
wmosdone++;
|
||||
printf("- WMOs... %u\r",wmosdone);
|
||||
}
|
||||
else
|
||||
printf("Could not write WMO %s\n",realfn.c_str());
|
||||
fh.close();
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
}
|
||||
|
||||
// fix filenames for linux ( '/' instead of windows '\')
|
||||
void _FixFileName(std::string& str)
|
||||
{
|
||||
for(uint32 i = 0; i < str.length(); i++)
|
||||
if(str[i]=='\\')
|
||||
str[i]='/';
|
||||
}
|
||||
|
||||
std::string _PathToFileName(std::string str)
|
||||
{
|
||||
uint32 pathend = str.find_last_of("/\\");
|
||||
if(pathend != std::string::npos)
|
||||
{
|
||||
return str.substr(pathend+1);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -16,6 +16,9 @@ int main(int argc, char *argv[]);
|
||||
void OutSCP(char*, SCPStorageMap&);
|
||||
bool ConvertDBC(void);
|
||||
void ExtractMaps(void);
|
||||
void ExtractMapDependencies(void);
|
||||
void _FixFileName(std::string&);
|
||||
std::string _PathToFileName(std::string);
|
||||
|
||||
|
||||
#endif
|
||||
Loading…
x
Reference in New Issue
Block a user