* Enable loading from MPQ files instead of extracting maps, textures, wmos and sounds

Actually, sounds don't work yet.
StormLib was moved to src/dep because it is now used by the main client, too.
MPQ-related helper files moved to shared.
This commit is contained in:
shlainn 2010-09-13 04:05:54 +02:00
parent fa2ac32d72
commit 126978ff5e
83 changed files with 437 additions and 188 deletions

View File

@ -149,4 +149,7 @@ DumpPackets=1
// Default: 2
DataLoaderThreads=2
// Use MPQ files of the original client for loading
UseMPQ=1

View File

@ -91,10 +91,10 @@ AC_CONFIG_FILES([Makefile
src/dep/src/zlib/Makefile
src/dep/src/zthread/Makefile
src/dep/src/irrKlang/Makefile
src/dep/src/StormLib/Makefile
src/tools/Makefile
src/tools/viewer/Makefile
src/tools/stuffextract/Makefile
src/tools/stuffextract/StormLib/Makefile
src/shared/Makefile
src/shared/Auth/Makefile
src/shared/Network/Makefile

View File

@ -10,7 +10,7 @@ namespace irr
namespace scene
{
CM2MeshFileLoader::CM2MeshFileLoader(IrrlichtDevice* device, c8* texdir):Device(device), Texdir(texdir)
CM2MeshFileLoader::CM2MeshFileLoader(IrrlichtDevice* device):Device(device)
{
Mesh = NULL;
@ -100,7 +100,6 @@ DEBUG(logdebug("Read %u/%u Vertices",M2MVertices.size(),header.nVertices));
std::string SkinName = MeshFile->getFileName();
SkinName = SkinName.substr(0, SkinName.length()-3) + "00.skin"; // FIX ME (and stuffextract) ! as we need more skins
_FixFileName(SkinName);
io::IReadFile* SkinFile = io::IrrCreateIReadFileBasic(Device, SkinName.c_str());
if (!SkinFile)
{
@ -226,11 +225,12 @@ std::string tempTexFileName="";
M2MTextureFiles.reallocate(M2MTextureDef.size());
for(u32 i=0; i<M2MTextureDef.size(); i++)
{
tempTexFileName.reserve(M2MTextureDef[i].texFileLen + 1);
tempTexFileName.resize(M2MTextureDef[i].texFileLen + 1);
MeshFile->seek(M2MTextureDef[i].texFileOfs);
MeshFile->read((void*)tempTexFileName.c_str(),M2MTextureDef[i].texFileLen);
M2MTextureFiles.push_back(tempTexFileName.c_str());
DEBUG(logdebug("Texture: %u (%s)",M2MTextureFiles.size(),M2MTextureFiles[i].c_str()));
MeshFile->read((void*)tempTexFileName.data(),M2MTextureDef[i].texFileLen);
M2MTextureFiles.push_back("");
M2MTextureFiles[i]=tempTexFileName.c_str();
DEBUG(logdebug("Texture: %u %u (%s/%s) @ %u(%u)",i,M2MTextureFiles.size(),M2MTextureFiles[i].c_str(),tempTexFileName.c_str(),M2MTextureDef[i].texFileOfs,M2MTextureDef[i].texFileLen));
}
///////////////////////////////////////
@ -492,13 +492,13 @@ for(u32 i=0; i < currentView.nSub;i++)//
//MeshBuffer->getMaterial().DiffuseColor.set(255,(M2MSubmeshes[i].meshpartId==0?0:255),(M2MSubmeshes[i].meshpartId==0?255:0),0);
for(u32 j=0;j<M2MTextureUnit.size();j++)//Loop through texture units
{
if(M2MTextureUnit[j].submeshIndex1==i)//if a texture unit belongs to this submesh
if(M2MTextureUnit[j].submeshIndex1==i && !M2MTextureFiles[M2MTextureLookup[M2MTextureUnit[j].textureIndex]].empty())//if a texture unit belongs to this submesh
{
std::string TexName=Texdir.c_str();
TexName+="/";
if(i<M2MTextureUnit.size())
TexName+=M2MTextureFiles[M2MTextureLookup[M2MTextureUnit[j].textureIndex]].c_str();
while(TexName.find('\\')<TexName.size())//Replace \ by /
// std::string TexName=Texdir.c_str();
// TexName+="/";
// if(i<M2MTextureUnit.size())
// TexName+=M2MTextureFiles[M2MTextureLookup[M2MTextureUnit[j].textureIndex]].c_str();
/* while(TexName.find('\\')<TexName.size())//Replace \ by /
{
TexName.replace(TexName.find('\\'),1,"/");
}
@ -506,8 +506,18 @@ for(u32 i=0; i < currentView.nSub;i++)//
{
TexName.replace(TexName.find(' '),1,"_");
}
std::transform(TexName.begin(), TexName.end(), TexName.begin(), tolower);
MeshBuffer->getMaterial().setTexture(M2MTextureUnit[j].TextureUnitNumber,Device->getVideoDriver()->getTexture(TexName.c_str()));
std::transform(TexName.begin(), TexName.end(), TexName.begin(), tolower);*/
char buf[1000];
MemoryDataHolder::MakeTextureFilename(buf,M2MTextureFiles[M2MTextureLookup[M2MTextureUnit[j].textureIndex]].c_str());
io::IReadFile* TexFile = io::IrrCreateIReadFileBasic(Device, buf);
// logdebug("Texture %s loading",M2MTextureFiles[M2MTextureLookup[M2MTextureUnit[j].textureIndex]].c_str());
if (!TexFile)
{
logerror("CM2MeshFileLoader: Texture file not found: %s", buf);
continue;
}
// logdebug("Texture %s loaded",M2MTextureFiles[M2MTextureLookup[M2MTextureUnit[j].textureIndex]].c_str());
MeshBuffer->getMaterial().setTexture(M2MTextureUnit[j].TextureUnitNumber,Device->getVideoDriver()->getTexture(TexFile));
DEBUG(logdebug("Render Flags: %u %u",M2MRenderFlags[M2MTextureUnit[j].renderFlagsIndex].flags,M2MRenderFlags[M2MTextureUnit[j].renderFlagsIndex].blending));
MeshBuffer->getMaterial().BackfaceCulling=(M2MRenderFlags[M2MTextureUnit[j].renderFlagsIndex].flags & 0x04)?false:true;

View File

@ -195,7 +195,7 @@ class CM2MeshFileLoader : public IMeshLoader
public:
//! Constructor
CM2MeshFileLoader(IrrlichtDevice* device, c8* texdir);
CM2MeshFileLoader(IrrlichtDevice* device);
//! destructor
virtual ~CM2MeshFileLoader();

View File

@ -24,7 +24,7 @@ namespace irr
namespace scene
{
CWMOMeshFileLoader::CWMOMeshFileLoader(IrrlichtDevice* device, c8* texdir):Device(device), Texdir(texdir)
CWMOMeshFileLoader::CWMOMeshFileLoader(IrrlichtDevice* device):Device(device)
{
Mesh = NULL;
@ -60,7 +60,7 @@ IAnimatedMesh* CWMOMeshFileLoader::createMesh(io::IReadFile* file)
{
char grpfilename[255];
sprintf(grpfilename,"%s_%03u.wmo",filename.substr(0,filename.length()-4).c_str(),i);
logdebug("%s",grpfilename);
logdev("%s",grpfilename);
MeshFile = io::IrrCreateIReadFileBasic(Device,grpfilename);
if(!MeshFile)
{
@ -73,7 +73,7 @@ IAnimatedMesh* CWMOMeshFileLoader::createMesh(io::IReadFile* file)
Device->getSceneManager()->getMeshManipulator()->flipSurfaces(Mesh); //Fix inverted surfaces after the rotation
//Does this crash on windows?
Device->getSceneManager()->getMeshManipulator()->recalculateNormals(Mesh,true);//just to be sure
logdebug("Complete Mesh contains a total of %u submeshes!",Mesh->getMeshBufferCount());
logdev("Complete Mesh contains a total of %u submeshes!",Mesh->getMeshBufferCount());
}
else
{
@ -92,25 +92,24 @@ bool CWMOMeshFileLoader::load(bool _root)
u32 size;
u32 textureOffset;
logdebug("Trying to open file %s",MeshFile->getFileName());
logdev("Trying to open file %s",MeshFile->getFileName());
while(MeshFile->getPos() < MeshFile->getSize())
{
printf("position 0x%lX ",MeshFile->getPos());
MeshFile->read(fourcc,4);
MeshFile->read(&size,4);
flipcc(fourcc);
printf("Reading Chunk: %s size %u\n", (char*)fourcc,size);
logdev("Reading Chunk: %s size %u", (char*)fourcc,size);
if(!strcmp((char*)fourcc,"MVER")){
logdebug("MVER Chunk: %s",(char*)fourcc);
logdev("MVER Chunk: %s",(char*)fourcc);
MeshFile->seek(size,true);
}
//Start root file parsing
else if(!strcmp((char*)fourcc,"MOHD")){
MeshFile->read(&rootHeader,sizeof(RootHeader));
logdebug("Read Root Header: %u Textures, %u Groups, %u Models", rootHeader.nTextures, rootHeader.nGroups, rootHeader.nModels);
logdev("Read Root Header: %u Textures, %u Groups, %u Models", rootHeader.nTextures, rootHeader.nGroups, rootHeader.nModels);
if(!isRootFile)//We should be reading a group file and found a root header, abort
return 0;
}
@ -128,7 +127,7 @@ printf("Reading Chunk: %s size %u\n", (char*)fourcc,size);
MeshFile->read(&tempMOMT,sizeof(MOMT_Data));
WMOMTexDefinition.push_back(tempMOMT);
}
logdebug("Read %u/%u TextureDefinitions",WMOMTexDefinition.size(),(size/sizeof(MOMT_Data)));
logdev("Read %u/%u TextureDefinitions",WMOMTexDefinition.size(),(size/sizeof(MOMT_Data)));
u32 tempOffset = MeshFile->getPos();//Save current position for further reading until texture file names are read.
@ -142,7 +141,7 @@ printf("Reading Chunk: %s size %u\n", (char*)fourcc,size);
texNameSize = WMOMTexDefinition[i].endNameIndex-WMOMTexDefinition[i].startNameIndex; tempTexName.resize(texNameSize);
MeshFile->seek(textureOffset+WMOMTexDefinition[i].startNameIndex);
MeshFile->read((void*)tempTexName.c_str(),WMOMTexDefinition[i].endNameIndex-WMOMTexDefinition[i].startNameIndex);
logdebug("Texture %u: %s",i,tempTexName.c_str());
logdev("Texture %u: %s",i,tempTexName.c_str());
WMOMTextureFiles.push_back(tempTexName.c_str());
}
@ -153,7 +152,7 @@ printf("Reading Chunk: %s size %u\n", (char*)fourcc,size);
//Start Group file parsing
else if(!strcmp((char*)fourcc,"MOGP")){
logdebug("header okay: %s",(char*)fourcc);
logdev("header okay: %s",(char*)fourcc);
MeshFile->seek(68,true);
if(isRootFile)//We should be reading a root file and found a Group header, abort
return 0;
@ -175,7 +174,7 @@ printf("Reading Chunk: %s size %u\n", (char*)fourcc,size);
previous_texid=tempMOPY.textureID;
}
submeshes.push_back(WMOMTexData.size()-1);//last read entry
logdebug("Read %u/%u Texture Informations, counted %u submeshes",WMOMTexData.size(),(size/sizeof(MOPY_Data)),submeshes.size());
logdev("Read %u/%u Texture Informations, counted %u submeshes",WMOMTexData.size(),(size/sizeof(MOPY_Data)),submeshes.size());
}
else if(!strcmp((char*)fourcc,"MOVI")){//Vertex indices (3 per triangle)
@ -188,7 +187,7 @@ printf("Reading Chunk: %s size %u\n", (char*)fourcc,size);
MeshFile->read(&tempWMOIndex,sizeof(u16));
WMOMIndices.push_back(tempWMOIndex);
}
logdebug("Read %u/%u Indices",WMOMIndices.size(),(size/sizeof(u16)));
logdev("Read %u/%u Indices",WMOMIndices.size(),(size/sizeof(u16)));
}
else if(!strcmp((char*)fourcc,"MOVT")){//Vertex coordinates
@ -205,7 +204,7 @@ printf("Reading Chunk: %s size %u\n", (char*)fourcc,size);
tempWMOVertex.Z=tempYZ;
WMOMVertices.push_back(tempWMOVertex);
}
logdebug("Read %u/%u Vertex Coordinates",WMOMVertices.size(),(size/sizeof(core::vector3df)));
logdev("Read %u/%u Vertex Coordinates",WMOMVertices.size(),(size/sizeof(core::vector3df)));
}
else if(!strcmp((char*)fourcc,"MONR")){//Normals
@ -222,7 +221,7 @@ printf("Reading Chunk: %s size %u\n", (char*)fourcc,size);
tempWMONormal.Z=tempYZ;
WMOMNormals.push_back(tempWMONormal);
}
logdebug("Read %u/%u Normal Coordinates",WMOMNormals.size(),(size/sizeof(core::vector3df)));
logdev("Read %u/%u Normal Coordinates",WMOMNormals.size(),(size/sizeof(core::vector3df)));
}
else if(!strcmp((char*)fourcc,"MOTV")){//TexCoord
@ -235,7 +234,7 @@ printf("Reading Chunk: %s size %u\n", (char*)fourcc,size);
MeshFile->read(&tempWMOMTexcoord,sizeof(core::vector2df));
WMOMTexcoord.push_back(tempWMOMTexcoord);
}
logdebug("Read %u/%u Texture Coordinates",WMOMTexcoord.size(),(size/sizeof(core::vector2df)));
logdev("Read %u/%u Texture Coordinates",WMOMTexcoord.size(),(size/sizeof(core::vector2df)));
}
else if(!strcmp((char*)fourcc,"MOCV")){//Vertex colors!! Scaaaary!
@ -249,7 +248,7 @@ printf("Reading Chunk: %s size %u\n", (char*)fourcc,size);
MeshFile->read(&tempWMOMVertexColor,sizeof(WMOColor));
WMOMVertexColor.push_back(video::SColor(tempWMOMVertexColor.a,tempWMOMVertexColor.r,tempWMOMVertexColor.g,tempWMOMVertexColor.b));
}
logdebug("Read %u/%u Vertex colors",WMOMVertexColor.size(),(size/sizeof(WMOColor)));
logdev("Read %u/%u Vertex colors",WMOMVertexColor.size(),(size/sizeof(WMOColor)));
}
//End Group file parsing
@ -288,28 +287,37 @@ for(u32 i=0;i<submeshes.size();i++)//The mesh has to be split into submeshes bec
MeshBuffer->Indices.push_back(WMOMIndices[j*3+2]);
}
}
logdebug("Inserted %u Indices/n",MeshBuffer->Indices.size());
logdev("Inserted %u Indices",MeshBuffer->Indices.size());
for(u32 j=0;j<WMOVertices.size();j++)
{
MeshBuffer->Vertices_Standard.push_back(WMOVertices[j]);
}
logdebug("Inserted %u Vertices/n",MeshBuffer->Vertices_Standard.size());
logdev("Inserted %u Vertices",MeshBuffer->Vertices_Standard.size());
std::string TexName=Texdir.c_str();
TexName+="/";
TexName+=WMOMTextureFiles[WMOMTexData[lastindex].textureID].c_str();
while(TexName.find('\\')<TexName.size())//Replace \ by /
{
TexName.replace(TexName.find('\\'),1,"/");
}
while(TexName.find(' ')<TexName.size())//Replace space by _
{
TexName.replace(TexName.find(' '),1,"_");
}
std::transform(TexName.begin(), TexName.end(), TexName.begin(), tolower);
MeshBuffer->getMaterial().setTexture(0,Device->getVideoDriver()->getTexture(TexName.c_str()));
// std::string TexName=Texdir.c_str();
// TexName+="/";
// TexName+=WMOMTextureFiles[WMOMTexData[lastindex].textureID].c_str();
// while(TexName.find('\\')<TexName.size())//Replace \ by /
// {
// TexName.replace(TexName.find('\\'),1,"/");
// }
// while(TexName.find(' ')<TexName.size())//Replace space by _
// {
// TexName.replace(TexName.find(' '),1,"_");
// }
// std::transform(TexName.begin(), TexName.end(), TexName.begin(), tolower);
char buf[1000];
MemoryDataHolder::MakeTextureFilename(buf,WMOMTextureFiles[WMOMTexData[lastindex].textureID].c_str());
io::IReadFile* TexFile = io::IrrCreateIReadFileBasic(Device, buf);
if (!TexFile)
{
logerror("Error! Texture file not found: %s", buf);
continue;
}
MeshBuffer->getMaterial().setTexture(0,Device->getVideoDriver()->getTexture(TexFile));
if(WMOMTexDefinition[WMOMTexData[lastindex].textureID].blendMode==1)
MeshBuffer->getMaterial().MaterialType=video::EMT_TRANSPARENT_ALPHA_CHANNEL;
MeshBuffer->recalculateBoundingBox();

View File

@ -61,7 +61,7 @@ class CWMOMeshFileLoader : public IMeshLoader
public:
//! Constructor
CWMOMeshFileLoader(IrrlichtDevice* device, c8* texdir);
CWMOMeshFileLoader(IrrlichtDevice* device);
//! destructor
virtual ~CWMOMeshFileLoader();

View File

@ -6,6 +6,8 @@
#include "Player.h"
#include "GameObject.h"
#include "WorldSession.h"
#include "MemoryInterface.h"
#include "MemoryDataHolder.h"
using namespace irr;
@ -24,16 +26,16 @@ DrawObject::DrawObject(irr::IrrlichtDevice *device, Object *obj, PseuInstance *i
DrawObject::~DrawObject()
{
DEBUG( logdebug("~DrawObject() this=0x%X obj=0x%X smgr=%X",this,_obj,_smgr) );
if(cube)
if(node)
{
text->remove();
cube->remove();
node->remove();
}
}
void DrawObject::Unlink(void)
{
cube = NULL;
node = NULL;
text = NULL;
}
@ -46,9 +48,9 @@ void DrawObject::_Init(void)
p->GetRace(),p->GetGender(),p->GetFaceId(),p->GetSkinId(),p->GetFaceTraitsId(),p->GetHairStyleId(),p->GetHairColorId()));
}
if(!cube && _obj->IsWorldObject()) // only world objects have coords and can be drawn
if(!node && _obj->IsWorldObject()) // only world objects have coords and can be drawn
{
std::string modelfile, texture = "";
std::string modelfilename, texturename = "";
uint32 opacity = 255;
if (_obj->IsUnit())
{
@ -56,9 +58,14 @@ void DrawObject::_Init(void)
SCPDatabase *cdi = _instance->dbmgr.GetDB("creaturedisplayinfo");
SCPDatabase *cmd = _instance->dbmgr.GetDB("creaturemodeldata");
uint32 modelid = cdi && displayid ? cdi->GetUint32(displayid,"model") : 0;
modelfile = std::string("data/model/") + (cmd ? cmd->GetString(modelid,"file") : "");
if (cdi && strcmp(cdi->GetString(displayid,"name1"), "") != 0)
texture = std::string("data/texture/") + cdi->GetString(displayid,"name1");
logdebug("modelid = %u, displayid = %u",modelid,displayid);
// modelfilename = std::string("data/model/") + (cmd ? cmd->GetString(modelid,"file") : "");
char buf[1000];
MemoryDataHolder::MakeModelFilename(buf,(cmd ? cmd->GetString(modelid,"mpqfilename") : ""));
modelfilename = buf;
logdebug("Unit %s",cmd->GetString(modelid,"mpqfilename"));
// if (cdi && strcmp(cdi->GetString(displayid,"name1"), "") != 0)
// texturename = std::string("data/texture/") + cdi->GetString(displayid,"name1");
opacity = cdi && displayid ? cdi->GetUint32(displayid,"opacity") : 255;
}
else if (_obj->IsCorpse())
@ -74,7 +81,13 @@ void DrawObject::_Init(void)
if (scpgender)
gendername = scpgender->GetString(gender, "name");
modelfile = std::string("data/model/") + racename + gendername + "DeathSkeleton.m2";
modelfilename = std::string("World\\Generic\\PassiveDoodads\\DeathSkeletons\\") + racename + gendername + "DeathSkeleton.m2";
char buf[1000];
MemoryDataHolder::MakeModelFilename(buf,modelfilename);
modelfilename = buf;
logdebug("Corpse %s",buf);
}
else if (_obj->IsGameObject())
{
@ -97,10 +110,17 @@ void DrawObject::_Init(void)
SCPDatabase *gdi = _instance->dbmgr.GetDB("gameobjectdisplayinfo");
if (gdi && displayid)
{
modelfile = std::string("data/model/") + gdi->GetString(displayid,"model");
std::string texturef = gdi->GetString(displayid,"path");
char buf[1000];
MemoryDataHolder::MakeModelFilename(buf,gdi->GetString(displayid,"mpqfilename"));
modelfilename = buf;
logdebug("Gameobject %s",buf);
if (strcmp(gdi->GetString(displayid,"texture"), "") != 0)
texture = std::string("data/texture/") + gdi->GetString(displayid,"texture");
{
char buf[1000];
MemoryDataHolder::MakeTextureFilename(buf,gdi->GetString(displayid,"texture"));
texturename = buf;
}
}
DEBUG(logdebug("GAMEOBJECT: %u - %u", _obj->GetEntry(), displayid));
@ -108,31 +128,45 @@ void DrawObject::_Init(void)
DEBUG(logdebug("GAMEOBJECT UNKNOWN: %u", _obj->GetEntry()));
}
}
scene::IAnimatedMesh *mesh = _smgr->getMesh(modelfile.c_str());
io::IReadFile* modelfile = io::IrrCreateIReadFileBasic(_device, modelfilename.c_str());
if (!modelfile)
{
logerror("DrawObject: model file not found: %s", modelfilename.c_str());
}
scene::IAnimatedMesh *mesh = _smgr->getMesh(modelfile);
if(mesh)
{
cube = _smgr->addAnimatedMeshSceneNode(mesh);
node = _smgr->addAnimatedMeshSceneNode(mesh);
//video::ITexture *tex = _device->getVideoDriver()->getTexture("data/misc/square.jpg");
//cube->setMaterialTexture(0, tex);
//node->setMaterialTexture(0, tex);
}
else
{
cube = _smgr->addCubeSceneNode(1);
node = _smgr->addCubeSceneNode(1);
}
if (!texture.empty())
cube->setMaterialTexture(0, _device->getVideoDriver()->getTexture(texture.c_str()));
//cube->getMaterial(0).DiffuseColor.setAlpha(opacity);
cube->setName("OBJECT");
if (cube->getMaterialCount())
if (!texturename.empty())
{
cube->getMaterial(0).setFlag(video::EMF_LIGHTING, true);
cube->getMaterial(0).setFlag(video::EMF_FOG_ENABLE, true);
logdebug("%s",texturename.c_str());
io::IReadFile* texturefile = io::IrrCreateIReadFileBasic(_device, texturename.c_str());
if (!texturefile)
{
logerror("DrawObject: texture file not found: %s", texturename.c_str());
}
node->setMaterialTexture(0, _device->getVideoDriver()->getTexture(texturefile));
}
//node->getMaterial(0).DiffuseColor.setAlpha(opacity);
node->setName("OBJECT");
if (node->getMaterialCount())
{
node->getMaterial(0).setFlag(video::EMF_LIGHTING, true);
node->getMaterial(0).setFlag(video::EMF_FOG_ENABLE, true);
}
text=_smgr->addTextSceneNode(_guienv->getBuiltInFont(), L"TestText" , irr::video::SColor(255,255,255,255),cube, irr::core::vector3df(0,5,0));
text=_smgr->addTextSceneNode(_guienv->getBuiltInFont(), L"TestText" , irr::video::SColor(255,255,255,255),node, irr::core::vector3df(0,5,0));
if(_obj->IsPlayer())
{
text->setTextColor(irr::video::SColor(255,255,0,0));
@ -143,7 +177,7 @@ void DrawObject::_Init(void)
}
}
DEBUG(logdebug("initialize DrawObject 0x%X obj: 0x%X "I64FMT,this,_obj,_obj->GetGUID()))
logdebug("initialize DrawObject 0x%X obj: 0x%X "I64FMT,this,_obj,_obj->GetGUID());
_initialized = true;
}
@ -154,19 +188,19 @@ void DrawObject::Draw(void)
_Init();
//printf("DRAW() for pObj 0x%X name '%s' guid "I64FMT"\n", _obj, _obj->GetName().c_str(), _obj->GetGUID());
if(cube)
if(node)
{
WorldPosition pos = ((WorldObject*)_obj)->GetPosition();
cube->setPosition(WPToIrr(pos));
node->setPosition(WPToIrr(pos));
rotation.Y = O_TO_IRR(pos.o);
float s = _obj->GetFloatValue(OBJECT_FIELD_SCALE_X);
if(s <= 0)
s = 1;
cube->setScale(irr::core::vector3df(s,s,s));
cube->setRotation(rotation);
node->setScale(irr::core::vector3df(s,s,s));
node->setRotation(rotation);
//cube->setRotation(irr::core::vector3df(0,RAD_TO_DEG(((WorldObject*)_obj)->GetO()),0));
//node->setRotation(irr::core::vector3df(0,RAD_TO_DEG(((WorldObject*)_obj)->GetO()),0));
irr::core::stringw tmp = L"";
if(_obj->GetName().empty() && !_obj->IsCorpse())
{

View File

@ -14,7 +14,7 @@ public:
~DrawObject();
void Draw(void); // call only in threadsafe environment!! (ensure the obj ptr is still valid!)
void Unlink(void);
inline irr::scene::ISceneNode *GetSceneNode(void) { return cube; }
inline irr::scene::ISceneNode *GetSceneNode(void) { return node; }
// additionally, we dont use a GetObject() func - that would fuck things up if the object was already deleted.
private:
@ -24,7 +24,7 @@ private:
irr::IrrlichtDevice *_device;
irr::scene::ISceneManager *_smgr;
irr::gui::IGUIEnvironment* _guienv;
irr::scene::ISceneNode* cube;
irr::scene::ISceneNode* node;
irr::scene::ITextSceneNode *text;
PseuInstance *_instance;
irr::core::vector3df rotation;

View File

@ -131,9 +131,9 @@ void PseuGUI::_Init(void)
// register external loaders for not supported filetypes
video::CImageLoaderBLP* BLPloader = new video::CImageLoaderBLP();
_driver->addExternalImageLoader(BLPloader);
scene::CM2MeshFileLoader* m2loader = new scene::CM2MeshFileLoader(_device, "./data/texture");
scene::CM2MeshFileLoader* m2loader = new scene::CM2MeshFileLoader(_device);
_smgr->addExternalMeshLoader(m2loader);
scene::CWMOMeshFileLoader* wmoloader = new scene::CWMOMeshFileLoader(_device, "./data/texture");
scene::CWMOMeshFileLoader* wmoloader = new scene::CWMOMeshFileLoader(_device);
_smgr->addExternalMeshLoader(wmoloader);
_throttle=0;
_initialized = true;

View File

@ -15,6 +15,7 @@
#include "MovementMgr.h"
#include "DrawObject.h"
#include "irrKlangSceneNode.h"
#include "MemoryInterface.h"
// TODO: replace this by conf value
#define MAX_CAM_DISTANCE 70
@ -626,7 +627,23 @@ void SceneWorld::UpdateTerrain(void)
Doodad *d = maptile->GetDoodad(i);
if(_doodads.find(d->uniqueid) == _doodads.end()) // only add doodads that dont exist yet
{
scene::IAnimatedMesh *mesh = smgr->getMesh(d->model.c_str());
std::string filename;
if(instance->GetConf()->useMPQ)
{
filename= d->MPQpath.c_str();
}
else
{
filename= d->model.c_str();
}
// logdebug("loading Doodad %s",filename.c_str());
io::IReadFile* modelfile = io::IrrCreateIReadFileBasic(device, filename.c_str());
if (!modelfile)
{
logerror("Error! modelfile not found: %s", d->MPQpath.c_str());
continue;
}
scene::IAnimatedMesh *mesh = smgr->getMesh(modelfile);
if(mesh)
{
scene::IAnimatedMeshSceneNode *doodad = smgr->addAnimatedMeshSceneNode(mesh);
@ -669,7 +686,23 @@ void SceneWorld::UpdateTerrain(void)
WorldMapObject *wmo = maptile->GetWMO(i);
if(_wmos.find(wmo->uniqueid) == _wmos.end()) // only add wmos that dont exist yet
{
scene::IAnimatedMesh *mesh = smgr->getMesh(wmo->model.c_str());
std::string filename;
if(instance->GetConf()->useMPQ)
{
filename= wmo->MPQpath.c_str();
}
else
{
filename= wmo->model.c_str();
}
// logdebug("loading WMO %s",filename.c_str());
io::IReadFile* modelfile = io::IrrCreateIReadFileBasic(device, filename.c_str());
if (!modelfile)
{
logerror("Error! WMO file not found: %s", wmo->MPQpath.c_str());
continue;
}
scene::IAnimatedMesh *mesh = smgr->getMesh(modelfile);
if(mesh)
{
scene::IAnimatedMeshSceneNode *wmo_node = smgr->addAnimatedMeshSceneNode(mesh);

View File

@ -27,6 +27,7 @@ pseuwow_LDADD = ../shared/libshared.a\
$(IRRKLANG_LIB)\
../dep/lib/linux-gcc/libIrrlicht.a\
../dep/src/zlib/libzlib.a\
../dep/src/zthread/libZThread.a
../dep/src/zthread/libZThread.a\
../dep/src/StormLib/libstormlib.a \
-lbz2
pseuwow_LDFLAGS =-pthread

View File

@ -4,6 +4,9 @@
#include "zthread/Condition.h"
#include "zthread/Task.h"
#include "zthread/PoolExecutor.h"
#include "MPQHelper.h"
#include "Locale.h"
#include "tools.h"
namespace MemoryDataHolder
{
@ -15,7 +18,11 @@ namespace MemoryDataHolder
TypeStorage<DataLoaderRunnable> loaders;
TypeStorage<uint32> refs;
bool alwaysSingleThreaded = false;
bool loadFromMPQ = false;
MPQHelper mpq;
void Init(void)
{
if(!executor)
@ -47,6 +54,59 @@ namespace MemoryDataHolder
executor->size(t);
}
}
void SetUseMPQ(std::string loc)
{
loadFromMPQ=true;
SetLocale(loc.c_str());
mpq.Init();
}
void MakeMapFilename(char* fn, uint32 mid, std::string mname, uint32 x, uint32 y)
{
if(loadFromMPQ)
sprintf(fn,"World\\Maps\\%s\\%s_%u_%u.adt",mname.c_str(),mname.c_str(),(uint16)x,(uint16)y);
else
sprintf(fn,"./data/maps/%u_%u_%u.adt",(uint16)mid,(uint16)x,(uint16)y);
}
void MakeWDTFilename(char* fn, uint32 mid, std::string mname)
{
if(loadFromMPQ)
sprintf(fn,"World\\Maps\\%s\\%s.wdt",mname.c_str(),mname.c_str());
else
sprintf(fn,"./data/maps/%u.wdt",(uint16)mid);
}
void MakeTextureFilename(char* fn, std::string fname)
{
if(loadFromMPQ)
sprintf(fn,"%s",fname.c_str());
else
{
NormalizeFilename(fname);
sprintf(fn,"./data/textures/%s",fname.c_str());
}
}
void MakeModelFilename(char* fn, std::string fname)
{
if(loadFromMPQ)
sprintf(fn,"%s",fname.c_str());
else
{
NormalizeFilename(_PathToFileName(fname));
sprintf(fn,"./data/model/%s",fname.c_str());
}
}
bool FileExists(std::string fname)
{
logdebug("%s",fname.c_str());
if(loadFromMPQ)
return mpq.FileExists(fname.c_str());
else
return GetFileSize(fname.c_str());
}
class DataLoaderRunnable : public ZThread::Runnable
{
@ -68,43 +128,83 @@ namespace MemoryDataHolder
void run()
{
memblock *mb = new memblock();
if(loadFromMPQ)
{
if(!mpq.FileExists(_name.c_str()))
{
ZThread::Guard<ZThread::FastMutex> g(_mut);
logerror("DataLoaderRunnable: Error opening file in MPQ: '%s'", _name.c_str());
_loaders->Unlink(_name);
DoCallbacks(_name, MDH_FILE_ERROR); // call callback func, 'false' to indicate file couldnt be loaded
delete mb;
return;
}
logdev("DataLoaderRunnable: Reading From MPQ'%s'... (%s)", _name.c_str(), FilesizeFormat(mb->size).c_str());
const ByteBuffer& bb = mpq.ExtractFile(_name.c_str());
// fh.read((char*)mb->ptr, mb->size);
if(!bb.size())
{
ZThread::Guard<ZThread::FastMutex> g(_mut);
logerror("DataLoaderRunnable: Error opening file in MPQ: '%s'", _name.c_str());
_loaders->Unlink(_name);
DoCallbacks(_name, MDH_FILE_ERROR); // call callback func, 'false' to indicate file couldnt be loaded
delete mb;
return;
}
mb->size = GetFileSize(_name.c_str());
// couldnt open file if size is 0
if(!mb->size)
{
ZThread::Guard<ZThread::FastMutex> g(_mut);
logerror("DataLoaderRunnable: Error opening file: '%s'", _name.c_str());
_loaders->Unlink(_name);
DoCallbacks(_name, MDH_FILE_ERROR); // call callback func, 'false' to indicate file couldnt be loaded
delete mb;
return;
mb->size=bb.size();
mb->alloc(mb->size);
memcpy((char*)mb->ptr,(char*)bb.contents(),bb.size());
{
ZThread::Guard<ZThread::FastMutex> g(_mut);
_storage->Assign(_name, mb);
_loaders->Unlink(_name); // must be unlinked after the file is fully loaded, but before the callbacks are processed!
}
logdev("DataLoaderRunnable: Done with '%s' (%s)", _name.c_str(), FilesizeFormat(mb->size).c_str());
DoCallbacks(_name, MDH_FILE_OK | MDH_FILE_JUST_LOADED);
}
mb->alloc(mb->size);
std::ifstream fh;
fh.open(_name.c_str(), std::ios_base::in | std::ios_base::binary);
if(!fh.is_open())
else
{
_FixFileName(_name);
mb->size = GetFileSize(_name.c_str());
// couldnt open file if size is 0
if(!mb->size)
{
ZThread::Guard<ZThread::FastMutex> g(_mut);
logerror("DataLoaderRunnable: Error opening file: '%s'", _name.c_str());
_loaders->Unlink(_name);
DoCallbacks(_name, MDH_FILE_ERROR); // call callback func, 'false' to indicate file couldnt be loaded
delete mb;
return;
}
mb->free();
delete mb;
DoCallbacks(_name, MDH_FILE_ERROR);
return;
mb->alloc(mb->size);
std::ifstream fh;
fh.open(_name.c_str(), std::ios_base::in | std::ios_base::binary);
if(!fh.is_open())
{
{
ZThread::Guard<ZThread::FastMutex> g(_mut);
logerror("DataLoaderRunnable: Error opening file: '%s'", _name.c_str());
_loaders->Unlink(_name);
}
mb->free();
delete mb;
DoCallbacks(_name, MDH_FILE_ERROR);
return;
}
logdev("DataLoaderRunnable: Reading '%s'... (%s)", _name.c_str(), FilesizeFormat(mb->size).c_str());
fh.read((char*)mb->ptr, mb->size);
fh.close();
{
ZThread::Guard<ZThread::FastMutex> g(_mut);
_storage->Assign(_name, mb);
_loaders->Unlink(_name); // must be unlinked after the file is fully loaded, but before the callbacks are processed!
}
logdev("DataLoaderRunnable: Done with '%s' (%s)", _name.c_str(), FilesizeFormat(mb->size).c_str());
DoCallbacks(_name, MDH_FILE_OK | MDH_FILE_JUST_LOADED);
}
logdev("DataLoaderRunnable: Reading '%s'... (%s)", _name.c_str(), FilesizeFormat(mb->size).c_str());
fh.read((char*)mb->ptr, mb->size);
fh.close();
{
ZThread::Guard<ZThread::FastMutex> g(_mut);
_storage->Assign(_name, mb);
_loaders->Unlink(_name); // must be unlinked after the file is fully loaded, but before the callbacks are processed!
}
logdev("DataLoaderRunnable: Done with '%s' (%s)", _name.c_str(), FilesizeFormat(mb->size).c_str());
DoCallbacks(_name, MDH_FILE_OK | MDH_FILE_JUST_LOADED);
}
inline void AddCallback(callback_func func, void *ptr = NULL, ZThread::Condition *cond = NULL)
@ -137,10 +237,15 @@ namespace MemoryDataHolder
{
_name = n;
}
inline void SetMPQName(std::string n)
{
_MPQname = n;
}
CallbackStore _callbacks;
bool _threaded;
std::string _name;
std::string _MPQname;
ZThread::FastMutex _mut;
TypeStorage<memblock> *_storage;
TypeStorage<DataLoaderRunnable> *_loaders;

View File

@ -46,7 +46,15 @@ namespace MemoryDataHolder
};
void Init(void);
void Shutdown(void);
void SetThreadCount(uint32);
void SetUseMPQ(std::string);
//Helper functions to compensate for directory structure differences between Pseu and MPQ
void MakeMapFilename(char*,uint32,std::string,uint32,uint32);
void MakeWDTFilename(char*,uint32,std::string);
void MakeTextureFilename(char*, std::string);
void MakeModelFilename(char*, std::string);
bool FileExists(std::string);
MemoryDataResult GetFile(std::string s, bool threaded = false, callback_func func = NULL,void *ptr = NULL, ZThread::Condition *cond = NULL, bool ref_counted = true);
inline MemoryDataResult GetFileBasic(std::string s) { return GetFile(s, false, NULL, NULL, NULL, false); }

View File

@ -516,6 +516,7 @@ void PseuInstanceConf::ApplyFromVarSet(VarSet &v)
dumpPackets=(uint8)atoi(v.Get("DUMPPACKETS").c_str());
softquit=(bool)atoi(v.Get("SOFTQUIT").c_str());
dataLoaderThreads=atoi(v.Get("DATALOADERTHREADS").c_str());
useMPQ=(bool)atoi(v.Get("USEMPQ").c_str());
// clientversion is a bit more complicated to add
{
@ -551,6 +552,7 @@ void PseuInstanceConf::ApplyFromVarSet(VarSet &v)
log_setloglevel(debug);
log_setlogtime((bool)atoi(v.Get("LOGTIME").c_str()));
MemoryDataHolder::SetThreadCount(dataLoaderThreads);
MemoryDataHolder::SetUseMPQ(clientlang);
}

View File

@ -71,7 +71,8 @@ class PseuInstanceConf
uint8 dumpPackets;
bool softquit;
uint8 dataLoaderThreads;
bool useMPQ;
// gui related
bool enablegui;
uint32 terrainsectors;

View File

@ -4,25 +4,35 @@
#include "MapTile.h"
#include "MapMgr.h"
void MakeMapFilename(char *fn, uint32 m, uint32 x, uint32 y)
{
sprintf(fn,"./data/maps/%u_%u_%u.adt",(uint16)m,(uint16)x,(uint16)y);
}
bool TileExistsInFile(uint32 m, uint32 x, uint32 y)
{
char buf[50];
/* char buf[50];
MakeMapFilename(buf,m,x,y);
return GetFileSize(buf);
return GetFileSize(buf);*/
return true;
}
char* MapMgr::MapID2Name(uint32 mid)
{
if(!mapdb)
{
mapdb=_instance->dbmgr.GetDB("map");
}
uint32 name_id = mapdb->GetFieldId("name_general");
return mapdb->GetString(mid,name_id);
}
MapMgr::MapMgr()
MapMgr::MapMgr(PseuInstance* _inst)
{
DEBUG(logdebug("Creating MapMgr with TILESIZE=%.3f CHUNKSIZE=%.3f UNITSIZE=%.3f",TILESIZE,CHUNKSIZE,UNITSIZE));
_tiles = new MapTileStorage();
_gridx = _gridy = _mapid = (-1);
_mapsLoaded = false;
_instance = _inst;
mapdb=_instance->dbmgr.GetDB("map");
}
MapMgr::~MapMgr()
@ -36,15 +46,28 @@ void MapMgr::Update(float x, float y, uint32 m)
if(m != _mapid)
{
Flush(); // we teleported to a new map, drop all loaded maps
WDTFile *wdt = new WDTFile();
char buf[100];
sprintf(buf,"data/maps/%lu.wdt",m);
if(!wdt->Load(buf))
char buf[255];
std::string mapname = MapID2Name(m);
MemoryDataHolder::MakeWDTFilename(buf,m,mapname);
// Loading WDT
MemoryDataHolder::MemoryDataResult mdr = MemoryDataHolder::GetFileBasic(buf);
if(mdr.flags & MemoryDataHolder::MDH_FILE_OK && mdr.data.size)
{
logerror("MAPMGR: Could not load WDT file '%s'",buf);
ByteBuffer bb(mdr.data.size);
bb.append(mdr.data.ptr,mdr.data.size);
MemoryDataHolder::Delete(buf);
WDTFile *wdt = new WDTFile();
wdt->LoadMem(bb);
_tiles->ImportTileMap(wdt);
delete wdt;
logdebug("MAPMGR: Loaded WDT '%s'",buf);
}
_tiles->ImportTileMap(wdt);
delete wdt;
else
{
logerror("MAPMGR: Loading WDT '%s' failed!",buf);
}
_mapid = m;
_gridx = _gridy = (-1); // must load tiles now
}
@ -83,10 +106,15 @@ void MapMgr::_LoadNearTiles(uint32 gx, uint32 gy, uint32 m)
void MapMgr::_LoadTile(uint32 gx, uint32 gy, uint32 m)
{
_mapsLoaded = false;
std::string mapname = MapID2Name(m);
logdebug("Mapname: %s",mapname.c_str());
char buf[255];
MemoryDataHolder::MakeMapFilename(buf,m,mapname,gx,gy);
if(!_tiles->TileExists(gx,gy))
{
if(TileExistsInFile(m,gx,gy))
if(MemoryDataHolder::FileExists(buf))
{
logerror("MapMgr: Tile (%u, %u) exists not in WDT, but as file?!",gx,gy);
// continue loading...
@ -100,9 +128,6 @@ void MapMgr::_LoadTile(uint32 gx, uint32 gy, uint32 m)
if( !_tiles->GetTile(gx,gy) )
{
char buf[300];
MakeMapFilename(buf,m,gx,gy);
MemoryDataHolder::MemoryDataResult mdr = MemoryDataHolder::GetFileBasic(buf);
if(mdr.flags & MemoryDataHolder::MDH_FILE_OK && mdr.data.size)
{

View File

@ -1,6 +1,9 @@
#ifndef MAPMGR_H
#define MAPMGR_H
#include "PseuWoW.h"
#include "SCPDatabase.h"
class MapTileStorage;
class MapTile;
@ -15,7 +18,7 @@ struct GridCoordPair
class MapMgr
{
public:
MapMgr();
MapMgr(PseuInstance*);
~MapMgr();
void Update(float,float,uint32);
void Flush(void);
@ -25,6 +28,7 @@ public:
MapTile *GetTile(uint32 xg, uint32 yg, bool forceLoad = false);
MapTile *GetCurrentTile(void);
MapTile *GetNearTile(int32, int32);
char* MapID2Name(uint32);
inline bool Loaded(void) { return _mapsLoaded; }
uint32 GetLoadedMapsCount(void);
std::string GetLoadedTilesString(void);
@ -32,6 +36,8 @@ public:
inline uint32 GetGridY(void) { return _gridy; }
private:
PseuInstance *_instance;
SCPDatabase* mapdb;
MapTileStorage *_tiles;
void _LoadTile(uint32,uint32,uint32);
void _LoadNearTiles(uint32,uint32,uint32);
@ -41,4 +47,4 @@ private:
bool _mapsLoaded;
};
#endif
#endif

View File

@ -12,7 +12,7 @@ World::World(WorldSession *s)
_movemgr = NULL;
if(_session->GetInstance()->GetConf()->useMaps)
{
_mapmgr = new MapMgr();
_mapmgr = new MapMgr(_session->GetInstance());
}
}

View File

@ -758,7 +758,7 @@ void WorldSession::PreloadDataBeforeEnterWorld(PlayerEnum& pl)
// preload additional map data only when the GUI is enabled
// TODO: at some later point we will need the geometry for correct collision calculation, etc...
if(GetInstance()->GetConf()->enablegui)
/* if(GetInstance()->GetConf()->enablegui)
{
for(uint32 tiley = 0; tiley < 3; tiley++)
{
@ -776,15 +776,15 @@ void WorldSession::PreloadDataBeforeEnterWorld(PlayerEnum& pl)
// but we need to preload the .skin files, since they are not held in the MeshCache
// TODO: load *all* necessary skin files, also fix stuffextract for this!
std::string skinfile = doo->model.substr(0, doo->model.length()-3) + "00.skin";
skinfile = GetAbsolutePath(skinfile.c_str());
_FixFileName(skinfile);
MemoryDataHolder::BackgroundLoadFile(skinfile);
// std::string skinfile = doo->MPQpath.substr(0, doo->model.length()-3) + "00.skin";
// skinfile = GetAbsolutePath(skinfile.c_str());
// _FixFileName(skinfile);
// MemoryDataHolder::BackgroundLoadFile(skinfile);
}
}
}
}
}
}*/
}
}

View File

@ -92,7 +92,7 @@ int main(int argc, char* argv[])
std::set_new_handler(_new_handler);
log_prepare("logfile.txt","a");
logcustom(0,LGREEN,"+----------------------------------+");
logcustom(0,LGREEN,"| (C) 2006-2009 Snowstorm Software |");
logcustom(0,LGREEN,"| (C) 2006-2010 Snowstorm Software |");
logcustom(0,LGREEN,"| http://www.mangosclient.org |");
logcustom(0,LGREEN,"+----------------------------------+");
logcustom(0,GREEN,"Platform: %s",PLATFORM_NAME);
@ -111,6 +111,7 @@ int main(int argc, char* argv[])
t.wait();
//...
log_close();
MemoryDataHolder::Shutdown();
_UnhookSignals();
raise(SIGABRT); // this way to terminate is not nice but the only way to quit the CLI thread
raise(SIGQUIT);

View File

@ -1,4 +1,4 @@
## Makefile.am - process this file with automake
AM_CPPFLAGS = -I$(top_builddir)/src/Client -I$(top_builddir)/src/shared -I$(top_builddir)/src/Client/DefScript -I$(top_builddir)/src/Client/World -I$(top_builddir)/src/Client/Realm -Wall
SUBDIRS = irrlicht zlib zthread $(IRRKLANG_DIR)
SUBDIRS = irrlicht zlib zthread StormLib $(IRRKLANG_DIR)
## End Makefile.am

View File

@ -8,7 +8,7 @@ char my_locale[5];
const char *cconf = "WTF/config.wtf";
const char *cconfentry = "SET locale \"";
void SetLocale(char *loc)
void SetLocale(const char *loc)
{
my_locale[4] = 0;
if(loc && strlen(loc))

View File

@ -2,6 +2,6 @@
#define STUFFEXTRACT_LOCALE_H
char *GetLocale(void);
void SetLocale(char*);
void SetLocale(const char*);
#endif

View File

@ -7,7 +7,11 @@
#define DATADIR "Data"
MPQHelper::MPQHelper(const char *archive)
MPQHelper::MPQHelper()
{
}
void MPQHelper::Init()
{
// TODO: check which files are needed and which are not + recheck for correct ordering
std::string dir = "Data/";
@ -16,7 +20,6 @@ MPQHelper::MPQHelper(const char *archive)
// order goes from last opened to first opened file
// ok maybe this is a bit too much but should work fine :)
_patches.push_front(dir+archive+ext); //
_patches.push_front(dir+"common"+ext);
_patches.push_front(dir+"common-2"+ext);
_patches.push_front(dir+"expansion"+ext);
@ -29,11 +32,9 @@ MPQHelper::MPQHelper(const char *archive)
_patches.push_front(buf);
}
_patches.push_front(ldir+"speech-"+GetLocale()+ext);
_patches.push_front(ldir+archive+"-"+GetLocale()+ext);
_patches.push_front(ldir+"locale-"+GetLocale()+ext);
_patches.push_front(ldir+"expansion-speech-"+GetLocale()+ext);
_patches.push_front(ldir+"expansion-locale-"+GetLocale()+ext);
_patches.push_front(ldir+"expansion-"+archive+"-"+GetLocale()+ext);
_patches.push_front(ldir+"lichking-locale-"+GetLocale()+ext);
_patches.push_front(ldir+"patch"+"-"+GetLocale()+ext);

View File

@ -8,8 +8,9 @@ class MPQFile;
class MPQHelper
{
public:
MPQHelper(const char*);
MPQHelper();
~MPQHelper();
void Init();
ByteBuffer ExtractFile(const char*);
bool FileExists(const char*);
private:

View File

@ -1,10 +1,12 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = Auth Network
AM_CPPFLAGS = -I$(top_builddir)/src/Client -I$(top_builddir)/src/shared -I$(top_builddir)/src/Client/DefScript -I$(top_builddir)/src/Client/World -I$(top_builddir)/src/Client/Realm -I$(top_builddir)/src/dep/include -Wall
AM_CPPFLAGS = -I$(top_builddir)/src/Client -I$(top_builddir)/src/shared -I$(top_builddir)/src/Client/DefScript -I$(top_builddir)/src/Client/World -I$(top_builddir)/src/Client/Realm -I$(top_builddir)/src/dep/include -I$(top_builddir)/src/dep/src -Wall
## Build pseuwow
noinst_LIBRARIES = libshared.a
libshared_a_SOURCES = ADTFile.cpp common.h log.h MapTile.h tools.cpp Widen.h\
ADTFile.h DebugStuff.h ProgressBar.cpp tools.h ZCompressor.cpp\
ADTFileStructs.h libshared.a ProgressBar.h WDTFile.cpp ZCompressor.h\
ByteBuffer.h log.cpp MapTile.cpp SysDefs.h WDTFile.h
ByteBuffer.h log.cpp MapTile.cpp SysDefs.h WDTFile.h\
dbcfile.cpp Locale.cpp MPQFile.cpp MPQHelper.cpp

View File

@ -89,6 +89,7 @@ void MapTile::ImportFromADT(ADTFile *adt)
d.oz = mddf.a;
d.flags = mddf.flags;
d.uniqueid = mddf.uniqueid;
d.MPQpath = adt->_models[mddf.id];
d.model = std::string("./data/model/") + NormalizeFilename(_PathToFileName(adt->_models[mddf.id]));
// this .mdx -> .m2 transformation is annoying >.< - replace "mdx" and end of string with "m2"
// d.model = d.model.substr(0, d.model.length() - 3) + "m2";
@ -113,6 +114,7 @@ void MapTile::ImportFromADT(ADTFile *adt)
wmo.oz = modf.oz;
wmo.flags = modf.flags;
wmo.uniqueid = modf.uniqueid;
wmo.MPQpath = adt->_wmos[modf.id];
wmo.model = std::string("./data/wmo/") + NormalizeFilename(_PathToFileName(adt->_wmos[modf.id]));
_wmo_data.push_back(wmo);
}

View File

@ -33,6 +33,7 @@ struct Doodad
float x,y,z,ox,oy,oz,scale;
uint16 flags;
std::string model;
std::string MPQpath;
};
struct WorldMapObject
@ -41,6 +42,7 @@ struct WorldMapObject
float x,y,z,ox,oy,oz;
uint16 flags,doodadset;
std::string model;
std::string MPQpath;
};
// generic map tile class. stores the information previously stored in an ADT file

View File

@ -1,8 +1,7 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = StormLib
AM_CPPFLAGS = -I$(top_builddir)/src/Client -I$(top_builddir)/src/shared -I$(top_builddir)/src/Client/DefScript -I$(top_builddir)/src/Client/World -I$(top_builddir)/src/Client/Realm -I$(top_builddir)/src/dep/include -Wall
AM_CPPFLAGS = -I$(top_builddir)/src/Client -I$(top_builddir)/src/shared -I$(top_builddir)/src/Client/DefScript -I$(top_builddir)/src/Client/World -I$(top_builddir)/src/Client/Realm -I$(top_builddir)/src/dep/include -I$(top_builddir)/src/dep/src -Wall
## Build pseuwow
bin_PROGRAMS = stuffextract
stuffextract_SOURCES = dbcfile.cpp Locale.cpp MPQFile.cpp MPQHelper.cpp StuffExtract.cpp
stuffextract_SOURCES = StuffExtract.cpp
stuffextract_LDADD = StormLib/libstormlib.a ../../shared/Auth/libauth.a ../../shared/libshared.a -lbz2
stuffextract_LDADD = ../../shared/Auth/libauth.a ../../shared/libshared.a ../../dep/src/StormLib/libstormlib.a -lbz2

View File

@ -24,7 +24,7 @@ std::set<NameAndAlt> modelNames;
std::set<NameAndAlt> wmoNames;
std::set<NameAndAlt> wmoGroupNames;
std::set<NameAndAlt> soundFileSet;
MPQHelper mpq;
// default config; SCPs are done always
bool doMaps=true, doSounds=false, doTextures=false, doWmos=false, doWmogroups=false, doModels=false, doMd5=true, doAutoclose=false;
@ -52,7 +52,8 @@ int main(int argc, char *argv[])
printf("Locale \"%s\" seems valid, starting conversion...\n",GetLocale());
CreateDir("extractedstuff");
CreateDir("extractedstuff/data");
ConvertDBC();
mpq.Init();
ConvertDBC();
if(doMaps) ExtractMaps();
if(doTextures || doModels || doWmos || doWmogroups) ExtractMapDependencies();
if(doSounds) ExtractSoundFiles();
@ -278,7 +279,7 @@ bool ConvertDBC(void)
DBCFile EmotesText,EmotesTextData,EmotesTextSound,ChrRaces,SoundEntries,Map,AreaTable,ItemDisplayInfo,
CreatureModelData,CreatureDisplayInfo,NPCSounds,CharSections,GameObjectDisplayInfo, ChrBaseInfo;
printf("Opening DBC archive...\n");
MPQHelper mpq("dbc");
printf("Opening DBC files...\n");
EmotesText.openmem(mpq.ExtractFile("DBFilesClient\\EmotesText.dbc"));
@ -476,8 +477,12 @@ bool ConvertDBC(void)
modelNames.insert(NameAndAlt(value)); // we need to extract model later, store it
std::string fn = _PathToFileName(value);
if(stricmp(fn.c_str()+fn.length()-4, "mdx"))
fn = fn.substr(0,fn.length()-3) + "m2";
{
fn = fn.substr(0,fn.length()-2) + "2";
value = value.substr(0,value.length()-2) + "2";
}
CreatureModelStorage[id].push_back(std::string(CreatureModelDataFieldNames[field]) + "=" + fn);
CreatureModelStorage[id].push_back("mpqfilename=" + value);
}
}
}
@ -541,17 +546,21 @@ bool ConvertDBC(void)
//Interestingly, some of the files referenced here have MDL extension - WTF?
std::string fn = _PathToFileName(value);
if(!stricmp(fn.c_str()+fn.length()-3, "mdx") || !stricmp(fn.c_str()+fn.length()-3, "mdl"))
fn = fn.substr(0,fn.length()-3) + "m2";
{
fn = fn.substr(0,fn.length()-2) + "2";
value = value.substr(0,value.length()-2) + "2";
}
else
printf("This should be a WMO: %s\n",fn.c_str());
GameObjectDisplayInfoStorage[id].push_back(std::string(GameObjectDisplayInfoFieldNames[field]) + "=" + fn);
GameObjectDisplayInfoStorage[id].push_back("mpqfilename=" + value);
std::string texture = value.substr(0,value.length()-3) + "blp";
if (mpq.FileExists((char*)texture.c_str()))
{
if(doTextures)
texNames.insert(NameAndAlt(texture));
GameObjectDisplayInfoStorage[id].push_back("texture=" + NormalizeFilename(texture));
GameObjectDisplayInfoStorage[id].push_back("texture=" + texture);
}
}
}
@ -640,7 +649,6 @@ void ExtractMaps(void)
char namebuf[200];
char outbuf[2000];
uint32 extr,extrtotal=0;
MPQHelper mpq("terrain");
MD5FileMap md5map;
CreateDir("extractedstuff/data/maps");
for(std::map<uint32,std::string>::iterator it = mapNames.begin(); it != mapNames.end(); it++)
@ -724,9 +732,6 @@ void ExtractMapDependencies(void)
barGoLink *bar;
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 = "extractedstuff/data";
std::string pathtex = path + "/texture";
std::string pathmodel = path + "/model";
@ -750,14 +755,14 @@ void ExtractMapDependencies(void)
altfn = i->alt;
if(altfn.empty())
altfn = mpqfn;
if(!mpqwmo.FileExists((char*)mpqfn.c_str()))
if(!mpq.FileExists((char*)mpqfn.c_str()))
continue;
realfn = pathwmo + "/" + NormalizeFilename(_PathToFileName(altfn));
std::fstream fh;
fh.open(realfn.c_str(),std::ios_base::out | std::ios_base::binary);
if(fh.is_open())
{
const ByteBuffer& bb = mpqwmo.ExtractFile((char*)mpqfn.c_str());
const ByteBuffer& bb = mpq.ExtractFile((char*)mpqfn.c_str());
fh.write((const char*)bb.contents(),bb.size());
//Extract number of group files, Texture file names and M2s from WMO
if(doWmogroups || doTextures || doModels) WMO_Parse_Data(bb,mpqfn.c_str(),doWmogroups,doTextures,doModels);
@ -793,14 +798,14 @@ void ExtractMapDependencies(void)
altfn = i->alt;
if(altfn.empty())
altfn = mpqfn;
if(!mpqwmo.FileExists((char*)mpqfn.c_str()))
if(!mpq.FileExists((char*)mpqfn.c_str()))
continue;
realfn = pathwmo + "/" + NormalizeFilename(_PathToFileName(altfn));
std::fstream fh;
fh.open(realfn.c_str(),std::ios_base::out | std::ios_base::binary);
if(fh.is_open())
{
const ByteBuffer& bb = mpqwmo.ExtractFile((char*)mpqfn.c_str());
const ByteBuffer& bb = mpq.ExtractFile((char*)mpqfn.c_str());
fh.write((const char*)bb.contents(),bb.size());
if(doMd5)
{
@ -837,10 +842,10 @@ void ExtractMapDependencies(void)
// 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()))
if(!mpq.FileExists((char*)mpqfn.c_str()))
{
std::string alt = mpqfn.substr(0,mpqfn.length()-3) + "m2";
if(!mpqmodel.FileExists((char*)alt.c_str()))
std::string alt = mpqfn.substr(0,mpqfn.length()-2) + "2";
if(!mpq.FileExists((char*)alt.c_str()))
{
printf("Failed to extract model: '%s'\n",alt.c_str());
continue;
@ -858,7 +863,7 @@ void ExtractMapDependencies(void)
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());
ByteBuffer bb = mpq.ExtractFile((char*)mpqfn.c_str());
fh.write((const char*)bb.contents(),bb.size());
if(doMd5)
@ -883,13 +888,13 @@ void ExtractMapDependencies(void)
std::string skin = mpqfn.substr(0,mpqfn.length()-3) + "00.skin";
std::string skinrealfn = pathmodel + "/" + NormalizeFilename(_PathToFileName(skin));
if (mpqmodel.FileExists((char*)skin.c_str()))
if (mpq.FileExists((char*)skin.c_str()))
{
std::fstream fhs;
fhs.open(skinrealfn.c_str(),std::ios_base::out | std::ios_base::binary);
if(fhs.is_open())
{
ByteBuffer bbs = mpqmodel.ExtractFile((char*)skin.c_str());
ByteBuffer bbs = mpq.ExtractFile((char*)skin.c_str());
fhs.write((const char*)bbs.contents(),bbs.size());
}
else
@ -922,7 +927,7 @@ void ExtractMapDependencies(void)
altfn = i->alt;
if(altfn.empty())
altfn = mpqfn;
if(!mpqtex.FileExists((char*)mpqfn.c_str()))
if(!mpq.FileExists((char*)mpqfn.c_str()))
continue;
// prepare lowercased and "underlined" path for file
@ -946,7 +951,7 @@ void ExtractMapDependencies(void)
fh.open(realfn.c_str(),std::ios_base::out | std::ios_base::binary);
if(fh.is_open())
{
const ByteBuffer& bb = mpqtex.ExtractFile((char*)mpqfn.c_str());
const ByteBuffer& bb = mpq.ExtractFile((char*)mpqfn.c_str());
fh.write((const char*)bb.contents(),bb.size());
if(doMd5)
{
@ -978,13 +983,12 @@ void ExtractSoundFiles(void)
uint32 done = 0;
printf("\nExtracting game audio files, %u found in DBC...\n",soundFileSet.size());
CreateDir(SOUNDDIR);
MPQHelper smpq("sound");
std::string outfn, altfn;
barGoLink bar(soundFileSet.size(),true);
for(std::set<NameAndAlt>::iterator i = soundFileSet.begin(); i != soundFileSet.end(); i++)
{
bar.step();
if(!smpq.FileExists((char*)i->name.c_str()))
if(!mpq.FileExists((char*)i->name.c_str()))
{
DEBUG( printf("MPQ: File not found: '%s'\n",i->name.c_str()) );
continue;
@ -996,7 +1000,7 @@ void ExtractSoundFiles(void)
fh.open(outfn.c_str(), std::ios_base::out | std::ios_base::binary);
if(fh.is_open())
{
const ByteBuffer& bb = smpq.ExtractFile((char*)i->name.c_str());
const ByteBuffer& bb = mpq.ExtractFile((char*)i->name.c_str());
if(bb.size())
{
fh.write((const char*)bb.contents(),bb.size());

View File

@ -7,5 +7,6 @@ viewer_SOURCES = main.cpp\
viewer_LDADD = ../../dep/lib/linux-gcc/libIrrlicht.a\
../../Client/GUI/libgui.a\
$(top_builddir)/src/shared/libshared.a\
../../dep/src/zthread/libZThread.a
viewer_LDFLAGS =-pthread
../../dep/src/zthread/libZThread.a\
../../dep/src/StormLib/libstormlib.a
viewer_LDFLAGS =-pthread -lbz2

View File

@ -672,9 +672,9 @@ int main(int argc, char* argv[])
// register external loaders for not supported filetypes
video::CImageLoaderBLP* BLPloader = new video::CImageLoaderBLP();
driver->addExternalImageLoader(BLPloader);
scene::CM2MeshFileLoader* m2loader = new scene::CM2MeshFileLoader(Device, "../../../bin/data/texture");
scene::CM2MeshFileLoader* m2loader = new scene::CM2MeshFileLoader(Device);
smgr->addExternalMeshLoader(m2loader);
scene::CWMOMeshFileLoader* wmoloader = new scene::CWMOMeshFileLoader(Device, "../../../bin/data/texture");
scene::CWMOMeshFileLoader* wmoloader = new scene::CWMOMeshFileLoader(Device);
smgr->addExternalMeshLoader(wmoloader);
driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true);