diff --git a/PseuWoW.sln b/PseuWoW.sln index 055efb8..11dc846 100644 --- a/PseuWoW.sln +++ b/PseuWoW.sln @@ -39,6 +39,9 @@ Global Release - Fast FPU = Release - Fast FPU Release - Fast FPU DebugInfo = Release - Fast FPU DebugInfo Release - No console = Release - No console + Static lib - Debug = Static lib - Debug + Static lib - Release = Static lib - Release + Static lib - Release - Fast FPU = Static lib - Release - Fast FPU EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Debug.ActiveCfg = Debug|Win32 @@ -53,6 +56,12 @@ Global {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Release - Fast FPU DebugInfo.Build.0 = Release|Win32 {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Release - No console.ActiveCfg = Release noconsole|Win32 {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Release - No console.Build.0 = Release noconsole|Win32 + {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Static lib - Debug.ActiveCfg = Debug|Win32 + {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Static lib - Debug.Build.0 = Debug|Win32 + {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Static lib - Release.ActiveCfg = Release|Win32 + {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Static lib - Release.Build.0 = Release|Win32 + {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Static lib - Release - Fast FPU.ActiveCfg = Release|Win32 + {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Static lib - Release - Fast FPU.Build.0 = Release|Win32 {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug.ActiveCfg = Debug|Win32 {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug.Build.0 = Debug|Win32 {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Relase - Fast FPU.ActiveCfg = Release|Win32 @@ -65,6 +74,12 @@ Global {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release - Fast FPU DebugInfo.Build.0 = Release|Win32 {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release - No console.ActiveCfg = Release|Win32 {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release - No console.Build.0 = Release|Win32 + {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Static lib - Debug.ActiveCfg = Debug|Win32 + {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Static lib - Debug.Build.0 = Debug|Win32 + {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Static lib - Release.ActiveCfg = Release|Win32 + {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Static lib - Release.Build.0 = Release|Win32 + {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Static lib - Release - Fast FPU.ActiveCfg = Release|Win32 + {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Static lib - Release - Fast FPU.Build.0 = Release|Win32 {262199E8-EEDF-4700-A1D1-E9CC901CF480}.Debug.ActiveCfg = Debug|Win32 {262199E8-EEDF-4700-A1D1-E9CC901CF480}.Debug.Build.0 = Debug|Win32 {262199E8-EEDF-4700-A1D1-E9CC901CF480}.Relase - Fast FPU.ActiveCfg = Release|Win32 @@ -77,6 +92,12 @@ Global {262199E8-EEDF-4700-A1D1-E9CC901CF480}.Release - Fast FPU DebugInfo.Build.0 = Release|Win32 {262199E8-EEDF-4700-A1D1-E9CC901CF480}.Release - No console.ActiveCfg = Release|Win32 {262199E8-EEDF-4700-A1D1-E9CC901CF480}.Release - No console.Build.0 = Release|Win32 + {262199E8-EEDF-4700-A1D1-E9CC901CF480}.Static lib - Debug.ActiveCfg = Debug|Win32 + {262199E8-EEDF-4700-A1D1-E9CC901CF480}.Static lib - Debug.Build.0 = Debug|Win32 + {262199E8-EEDF-4700-A1D1-E9CC901CF480}.Static lib - Release.ActiveCfg = Release|Win32 + {262199E8-EEDF-4700-A1D1-E9CC901CF480}.Static lib - Release.Build.0 = Release|Win32 + {262199E8-EEDF-4700-A1D1-E9CC901CF480}.Static lib - Release - Fast FPU.ActiveCfg = Release|Win32 + {262199E8-EEDF-4700-A1D1-E9CC901CF480}.Static lib - Release - Fast FPU.Build.0 = Release|Win32 {F548FC51-24A4-45FF-A381-BEBC39F18270}.Debug.ActiveCfg = Debug|Win32 {F548FC51-24A4-45FF-A381-BEBC39F18270}.Debug.Build.0 = Debug|Win32 {F548FC51-24A4-45FF-A381-BEBC39F18270}.Relase - Fast FPU.ActiveCfg = Release|Win32 @@ -89,6 +110,12 @@ Global {F548FC51-24A4-45FF-A381-BEBC39F18270}.Release - Fast FPU DebugInfo.Build.0 = Release|Win32 {F548FC51-24A4-45FF-A381-BEBC39F18270}.Release - No console.ActiveCfg = Release|Win32 {F548FC51-24A4-45FF-A381-BEBC39F18270}.Release - No console.Build.0 = Release|Win32 + {F548FC51-24A4-45FF-A381-BEBC39F18270}.Static lib - Debug.ActiveCfg = Debug|Win32 + {F548FC51-24A4-45FF-A381-BEBC39F18270}.Static lib - Debug.Build.0 = Debug|Win32 + {F548FC51-24A4-45FF-A381-BEBC39F18270}.Static lib - Release.ActiveCfg = Release|Win32 + {F548FC51-24A4-45FF-A381-BEBC39F18270}.Static lib - Release.Build.0 = Release|Win32 + {F548FC51-24A4-45FF-A381-BEBC39F18270}.Static lib - Release - Fast FPU.ActiveCfg = Release|Win32 + {F548FC51-24A4-45FF-A381-BEBC39F18270}.Static lib - Release - Fast FPU.Build.0 = Release|Win32 {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Debug.ActiveCfg = Debug|Win32 {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Debug.Build.0 = Debug|Win32 {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Relase - Fast FPU.ActiveCfg = Release|Win32 @@ -99,8 +126,14 @@ Global {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Release - Fast FPU.Build.0 = Release|Win32 {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Release - Fast FPU DebugInfo.ActiveCfg = Release|Win32 {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Release - Fast FPU DebugInfo.Build.0 = Release|Win32 - {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Release - No console.ActiveCfg = Release|Win32 - {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Release - No console.Build.0 = Release|Win32 + {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Release - No console.ActiveCfg = Release noconsole|Win32 + {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Release - No console.Build.0 = Release noconsole|Win32 + {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Static lib - Debug.ActiveCfg = Debug|Win32 + {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Static lib - Debug.Build.0 = Debug|Win32 + {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Static lib - Release.ActiveCfg = Release|Win32 + {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Static lib - Release.Build.0 = Release|Win32 + {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Static lib - Release - Fast FPU.ActiveCfg = Release|Win32 + {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Static lib - Release - Fast FPU.Build.0 = Release|Win32 {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug.ActiveCfg = Debug|Win32 {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug.Build.0 = Debug|Win32 {E08E042A-6C45-411B-92BE-3CC31331019F}.Relase - Fast FPU.ActiveCfg = Release - Fast FPU|Win32 @@ -111,8 +144,14 @@ Global {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - Fast FPU.Build.0 = Release - Fast FPU|Win32 {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - Fast FPU DebugInfo.ActiveCfg = Release - Fast FPU|Win32 {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - Fast FPU DebugInfo.Build.0 = Release - Fast FPU|Win32 - {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - No console.ActiveCfg = Release|Win32 - {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - No console.Build.0 = Release|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - No console.ActiveCfg = Release - Fast FPU|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - No console.Build.0 = Release - Fast FPU|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Debug.ActiveCfg = Static lib - Debug|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Debug.Build.0 = Static lib - Debug|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release.ActiveCfg = Static lib - Release|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release.Build.0 = Static lib - Release|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release - Fast FPU.ActiveCfg = Static lib - Release - Fast FPU|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release - Fast FPU.Build.0 = Static lib - Release - Fast FPU|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection diff --git a/src/Client/DefScript/TypeStorage.h b/src/Client/DefScript/TypeStorage.h index 24206ae..4e8ee6a 100644 --- a/src/Client/DefScript/TypeStorage.h +++ b/src/Client/DefScript/TypeStorage.h @@ -16,7 +16,7 @@ public: void DeleteByPtr(T*); T *Get(std::string); T *GetNoCreate(std::string); - void Assign(std::string,T*); + void Assign(std::string,T*,bool overwrite = true); void Unlink(std::string); void UnlinkByPtr(T*); std::string GetNameByPtr(T*); @@ -25,12 +25,26 @@ public: inline unsigned int Size(void) { return _storage.size(); } void Clear(bool keep = false); + void dump(void); + + + private: T *_Create(std::string); _TypeMap _storage; bool _keep; }; +template void TypeStorage::dump(void) +{ + printf("TypeStorage dump, size=%u\n",Size()); + _TypeIter it; + for(it = _storage.begin(); it != _storage.end(); it++) + { + printf("[%s] => 0x%X\n", it->first.c_str(), it->second); + } +} + // check whether an object with this name is already present template bool TypeStorage::Exists(std::string s) { @@ -41,7 +55,7 @@ template bool TypeStorage::Exists(std::string s) template T *TypeStorage::_Create(std::string s) { T *elem = new T; - _storage[s] = elem; + Assign(s,elem); return elem; } @@ -106,12 +120,19 @@ template void TypeStorage::Clear(bool keep) } } -// stores an already existing object's pointer under a specific name; deletes and overwrites old of present -template void TypeStorage::Assign(std::string s,T *elem) +// stores an already existing object's pointer under a specific name; deletes and overwrites old if present +template void TypeStorage::Assign(std::string s,T *elem, bool overwrite /* = true */ ) { - if(Exists(s)) - Delete(s); - _storage[s] = elem; + _TypeIter it = _storage.find(s); + if(it != _storage.end()) + { + if(overwrite) + { + delete it->second; + } + _storage.erase(it); + } + _storage.insert(make_pair(s,elem)); } // removes the pointer from the storage without deleting it diff --git a/src/Client/GUI/CM2MeshFileLoader.cpp b/src/Client/GUI/CM2MeshFileLoader.cpp index f3183f4..cb1ee6f 100644 --- a/src/Client/GUI/CM2MeshFileLoader.cpp +++ b/src/Client/GUI/CM2MeshFileLoader.cpp @@ -1,4 +1,6 @@ #include +#include "MemoryDataHolder.h" +#include "MemoryInterface.h" #include "CM2MeshFileLoader.h" #include "SSkinnedMesh.h" #include "common.h" @@ -56,7 +58,7 @@ DEBUG(logdebug("Trying to open file %s",MeshFile->getFileName())); MeshFile->read(&header,sizeof(ModelHeader)); if (header.version[0] != 8 || header.version[1] != 1 || header.version[2] != 0 || header.version[3] != 0) { - printf("Wrong header! File version doesn't match or file is not a M2 file."); + logerror("M2: [%s] Wrong header! File version doesn't match or file is not a M2 file.",MeshFile->getFileName()); return 0; } else @@ -98,7 +100,7 @@ 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 -io::IReadFile* SkinFile = io::createReadFile(SkinName.c_str()); +io::IReadFile* SkinFile = io::IrrCreateIReadFileBasic(Device, SkinName.c_str()); if (!SkinFile) { logerror("Error! Skin file not found: %s", SkinName.c_str()); diff --git a/src/Client/GUI/CMDHMemoryReadFile.cpp b/src/Client/GUI/CMDHMemoryReadFile.cpp new file mode 100644 index 0000000..fe362cf --- /dev/null +++ b/src/Client/GUI/CMDHMemoryReadFile.cpp @@ -0,0 +1,105 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "MemoryDataHolder.h" +#include "CMDHMemoryReadFile.h" +#include "irrlicht/irrString.h" + +namespace irr +{ +namespace io +{ + + +CMDHReadFile::CMDHReadFile(void* memory, long len, const c8* fileName) +: Buffer(memory), Len(len), Pos(0) +{ + #ifdef _DEBUG + setDebugName("CReadFile"); + #endif + + Filename = fileName; +} + + + +CMDHReadFile::~CMDHReadFile() +{ + // We should not drop the memory here... this model will possibly be loaded more than once + //if(getReferenceCount() <= 1) + // MemoryDataHolder::Delete(getFileName()); +} + + + +//! returns how much was read +irr::s32 CMDHReadFile::read(void* buffer, irr::u32 sizeToRead) +{ + irr::s32 amount = static_cast(sizeToRead); + if (Pos + amount > Len) + amount -= Pos + amount - Len; + + if (amount <= 0) + return 0; + + irr::c8* p = (irr::c8*)Buffer; + memcpy(buffer, p + Pos, amount); + + Pos += amount; + + return amount; +} + + +//! changes position in file, returns true if successful +//! if relativeMovement==true, the pos is changed relative to current pos, +//! otherwise from begin of file +bool CMDHReadFile::seek(long finalPos, bool relativeMovement) +{ + if (relativeMovement) + { + if (Pos + finalPos > Len) + return false; + + Pos += finalPos; + } + else + { + if (finalPos > Len) + return false; + + Pos = finalPos; + } + + return true; +} + + + +//! returns size of file +long CMDHReadFile::getSize() const +{ + return Len; +} + + + +//! returns where in the file we are. +long CMDHReadFile::getPos() const +{ + return Pos; +} + + + +//! returns name of file +const irr::c8* CMDHReadFile::getFileName() const +{ + return Filename.c_str(); +} + + +} +} + diff --git a/src/Client/GUI/CMDHMemoryReadFile.h b/src/Client/GUI/CMDHMemoryReadFile.h new file mode 100644 index 0000000..872fb0f --- /dev/null +++ b/src/Client/GUI/CMDHMemoryReadFile.h @@ -0,0 +1,57 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_MDH_READ_FILE_H_INCLUDED__ +#define __C_MDH_READ_FILE_H_INCLUDED__ + +#include "irrlicht/IReadFile.h" +#include "irrlicht/irrString.h" + +namespace irr +{ +namespace io +{ + +/*! + Class for reading from memory. +*/ +class CMDHReadFile : public IReadFile +{ +public: + + CMDHReadFile(void* memory, long len, const irr::c8* fileName); + + virtual ~CMDHReadFile(); + + //! returns how much was read + virtual irr::s32 read(void* buffer, irr::u32 sizeToRead); + + //! changes position in file, returns true if successful + //! if relativeMovement==true, the pos is changed relative to current pos, + //! otherwise from begin of file + virtual bool seek(long finalPos, bool relativeMovement = false); + + //! returns size of file + virtual long getSize() const; + + //! returns where in the file we are. + virtual long getPos() const; + + //! returns name of file + virtual const c8* getFileName() const; + +private: + + irr::core::stringc Filename; + void *Buffer; + long Len; + long Pos; +}; + + +} +} + +#endif + diff --git a/src/Client/GUI/MemoryInterface.cpp b/src/Client/GUI/MemoryInterface.cpp new file mode 100644 index 0000000..2e10128 --- /dev/null +++ b/src/Client/GUI/MemoryInterface.cpp @@ -0,0 +1,41 @@ +#include "common.h" +#include "MemoryDataHolder.h" +#include "irrlicht/irrlicht.h" +#include "CMDHMemoryReadFile.h" +#include "MemoryInterface.h" + +/* +struct IrrFileLoadedCallback +{ + irr::IrrlichtDevice *device; +}; + +struct IrrTextureLoadedCallback : public IrrFileLoadedCallback +{ + irr::scene::ISceneNode *node; +}; + + +void IrrModelLoadedCallbackFunc(void *ptr,std::string filename, uint32 flags) +{ +} +*/ + +namespace irr +{ +namespace io +{ + + +IReadFile * IrrCreateIReadFileBasic(irr::IrrlichtDevice *device, std::string fn) +{ + MemoryDataHolder::memblock mb = MemoryDataHolder::GetFileBasic(fn); + if(!mb.ptr) + return NULL; + + return new CMDHReadFile(mb.ptr, mb.size, fn.c_str()); +} + + +} +} diff --git a/src/Client/GUI/MemoryInterface.h b/src/Client/GUI/MemoryInterface.h new file mode 100644 index 0000000..ae60473 --- /dev/null +++ b/src/Client/GUI/MemoryInterface.h @@ -0,0 +1,24 @@ +#ifndef MEMORYINTERFACE_H +#define MEMORYINTERFACE_H + + + +namespace irr +{ + +class IrrlichtDevice; + +namespace io +{ + +class IReadFile; + + +IReadFile *IrrCreateIReadFileBasic(IrrlichtDevice*, std::string); + + +} +} + + +#endif diff --git a/src/Client/GUI/SceneWorld.cpp b/src/Client/GUI/SceneWorld.cpp index 6df8a5d..0d35923 100644 --- a/src/Client/GUI/SceneWorld.cpp +++ b/src/Client/GUI/SceneWorld.cpp @@ -308,9 +308,16 @@ void SceneWorld::OnUpdate(s32 timediff) if(eventrecv->key.pressed_once(KEY_HOME)) { _freeCameraMove = !_freeCameraMove; + // TODO: uncomment this as soon as the camera isn't adjusted anymore every single frame //if(!_freeCameraMove) // RelocateCameraBehindChar(); + + //TODO: this will not be needed anymore with the above code uncommented + // make player always visble when switching to freefly mode + scene::ISceneNode *charnode = GetMyCharacterSceneNode(); // NOTE: this call is absolutely not optimized! + if(charnode) + charnode->setVisible(true); } if(eventrecv->key.pressed_once(KEY_BACK)) diff --git a/src/Client/MemoryDataHolder.cpp b/src/Client/MemoryDataHolder.cpp index 99b0c26..2f5594c 100644 --- a/src/Client/MemoryDataHolder.cpp +++ b/src/Client/MemoryDataHolder.cpp @@ -19,7 +19,16 @@ namespace MemoryDataHolder void Init(void) { if(!executor) - executor = new ZThread::PoolExecutor(1); // TODO: fix memleak on shutdown? + executor = new ZThread::PoolExecutor(1); + } + + void Shutdown(void) + { + //ZThread::Guard g(mutex); + logdev("MDH: Interrupting work..."); + executor->cancel(); // stop accepting new threads + executor->interrupt(); // interrupt all working threads + // executor will delete itself automatically } void SetThreadCount(uint32 t) @@ -48,43 +57,54 @@ namespace MemoryDataHolder } ~DataLoaderRunnable() { - logdev("~DataLoaderRunnable(%s)", _name.c_str()); + logdev("~DataLoaderRunnable(%s) 0x%X", _name.c_str(), this); + } + void SetStores(TypeStorage *mem, TypeStorage *ldrs) + { + _storage = mem; + _loaders = ldrs; } // the threaded part void run() - { - const char *name = _name.c_str(); + { memblock *mb = new memblock(); - mb->size = GetFileSize(name); + mb->size = GetFileSize(_name.c_str()); // couldnt open file if size is 0 if(!mb->size) { - logerror("DataLoaderRunnable: Error opening file: '%s'", name); - loaders.Unlink(name); - DoCallbacks(name, MDH_FILE_ERROR); // call callback func, 'false' to indicate file couldnt be loaded + ZThread::Guard 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->alloc(mb->size); std::ifstream fh; - fh.open(name, std::ios_base::in | std::ios_base::binary); + fh.open(_name.c_str(), std::ios_base::in | std::ios_base::binary); if(!fh.is_open()) { - logerror("DataLoaderRunnable: Error opening file: '%s'", name); - loaders.Unlink(name); + { + ZThread::Guard g(_mut); + logerror("DataLoaderRunnable: Error opening file: '%s'", _name.c_str()); + _loaders->Unlink(_name); + } mb->free(); delete mb; - DoCallbacks(name, MDH_FILE_ERROR); + DoCallbacks(_name, MDH_FILE_ERROR); return; } - logdev("DataLoaderRunnable: Reading '%s'... (%s)", name, FilesizeFormat(mb->size).c_str()); + logdev("DataLoaderRunnable: Reading '%s'... (%s)", _name.c_str(), FilesizeFormat(mb->size).c_str()); fh.read((char*)mb->ptr, mb->size); fh.close(); - 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, FilesizeFormat(mb->size).c_str()); - DoCallbacks(name, MDH_FILE_OK | MDH_FILE_JUST_LOADED); + { + ZThread::Guard 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) @@ -121,6 +141,10 @@ namespace MemoryDataHolder CallbackStore _callbacks; bool _threaded; std::string _name; + ZThread::FastMutex _mut; + TypeStorage *_storage; + TypeStorage *_loaders; + }; @@ -133,7 +157,7 @@ namespace MemoryDataHolder // manage reference counter uint32 *refcount = refs.GetNoCreate(s); - if(!refcount || !*refcount) + if(!refcount) { refcount = new uint32; *refcount = ref_counted ? 1 : 0; @@ -149,6 +173,7 @@ namespace MemoryDataHolder if(memblock *mb = storage.GetNoCreate(s)) { + DEBUG(logdev("MDH: Reusing '%s' from memory",s.c_str())); // the file was requested some other time, is still present in memory and the pointer can simply be returned... mutex.release(); // everything ok, mutex can be unloaded safely // execute callback and broadcast condition (must check for MDH_FILE_ALREADY_EXIST in callback func) @@ -161,33 +186,36 @@ namespace MemoryDataHolder } else { - DataLoaderRunnable *r = loaders.GetNoCreate(s); - if(r == NULL) + DataLoaderRunnable *ldr = loaders.GetNoCreate(s); + DEBUG(logdev("MDH: Found Loader 0x%X for '%s'",ldr,s.c_str())); + if(ldr == NULL) { // no loader thread is working on that file... - r = new DataLoaderRunnable(); - loaders.Assign(s,r); - r->AddCallback(func,ptr,cond); // not threadsafe! - r->SetThreaded(threaded); - r->SetName(s); // here we set the filename the thread should load - // the mutex can be released safely now - mutex.release(); + ldr = loaders.Get(s); + ldr->SetStores(&storage,&loaders); + ldr->AddCallback(func,ptr,cond); // not threadsafe! + mutex.release(); // the mutex can be released safely now + ldr->SetThreaded(threaded); + ldr->SetName(s); // here we set the filename the thread should load + if(threaded) { - ZThread::Task task(r); + ZThread::Task task(ldr); executor->execute(task); + } else { - r->run(); // will exit after the whole file is loaded and the callbacks were run - memblock *mb = storage.GetNoCreate(s); - delete r; - return *mb; + ldr->run(); // will exit after the whole file is loaded and the callbacks were run + delete ldr; + memblock *mbret = storage.GetNoCreate(s); + DEBUG(logdev("Non-threaded loader returning memblock at 0x%X",mbret)); + return mbret ? *mbret : memblock(); } } else // if a loader is already existing, add callbacks to that loader. { - r->AddCallback(func,ptr,cond); + ldr->AddCallback(func,ptr,cond); mutex.release(); } } @@ -218,7 +246,7 @@ namespace MemoryDataHolder } else { - if(*refcount) + if(*refcount > 0) (*refcount)--; logdev("MemoryDataHolder::Delete(\"%s\"): refcount dropped to %u", s.c_str(), *refcount); } @@ -227,7 +255,7 @@ namespace MemoryDataHolder refs.Delete(s); if(memblock *mb = storage.GetNoCreate(s)) { - logdev("MemoryDataHolder:: deleting 0x%X (size %u)", mb->ptr, mb->size); + logdev("MemoryDataHolder:: deleting 0x%X (size %s)", mb->ptr, FilesizeFormat(mb->size).c_str()); mb->free(); storage.Delete(s); return true; diff --git a/src/Client/PseuWoW.cpp b/src/Client/PseuWoW.cpp index b304b78..727375e 100644 --- a/src/Client/PseuWoW.cpp +++ b/src/Client/PseuWoW.cpp @@ -65,6 +65,10 @@ PseuInstance::PseuInstance(PseuInstanceRunnable *run) _creaters=false; _error=false; _initialized=false; + for(uint32 i = 0; i < COND_MAX; i++) + { + _condition[i] = new ZThread::Condition(_mutex); + } } @@ -95,6 +99,11 @@ PseuInstance::~PseuInstance() delete _scp; delete _conf; + for(uint32 i = 0; i < COND_MAX; i++) + { + delete _condition[i]; + } + log("--- Instance shut down ---"); } @@ -454,6 +463,15 @@ bool PseuInstance::ConnectToRealm(void) return true; } +void PseuInstance::WaitForCondition(InstanceConditions c, uint32 timeout /* = 0 */) +{ + _mutex.acquire(); + if(timeout) + _condition[c]->wait(timeout); + else + _condition[c]->wait(); + _mutex.release(); +} PseuInstanceConf::PseuInstanceConf() { diff --git a/src/Client/PseuWoW.h b/src/Client/PseuWoW.h index 81a4c7b..f6a13ed 100644 --- a/src/Client/PseuWoW.h +++ b/src/Client/PseuWoW.h @@ -131,6 +131,9 @@ public: void ProcessCliQueue(void); void AddCliCommand(std::string); + void WaitForCondition(InstanceConditions c, uint32 timeout = 0); + inline ZThread::Condition *GetCondition(InstanceConditions c) { return _condition[c]; } + private: PseuInstanceRunnable *_runnable; @@ -153,6 +156,8 @@ private: ZThread::LockedQueue _cliQueue; PseuGUI *_gui; ZThread::Thread *_guithread; + ZThread::Condition *_condition[COND_MAX]; + ZThread::FastRecursiveMutex _mutex; }; diff --git a/src/Client/World/MapMgr.cpp b/src/Client/World/MapMgr.cpp index f365841..bde7a03 100644 --- a/src/Client/World/MapMgr.cpp +++ b/src/Client/World/MapMgr.cpp @@ -1,5 +1,6 @@ #include "common.h" #include "log.h" +#include "MemoryDataHolder.h" #include "MapTile.h" #include "MapMgr.h" @@ -101,8 +102,13 @@ void MapMgr::_LoadTile(uint32 gx, uint32 gy, uint32 m) ADTFile *adt = new ADTFile(); char buf[300]; MakeMapFilename(buf,m,gx,gy); - if(adt->Load(buf)) + MemoryDataHolder::memblock mb = MemoryDataHolder::GetFileBasic(buf); + if(mb.size) { + ByteBuffer bb(mb.size); + bb.append(mb.ptr,mb.size); + MemoryDataHolder::Delete(buf); + adt->LoadMem(bb); logdebug("MAPMGR: Loaded ADT '%s'",buf); MapTile *tile = new MapTile(); tile->ImportFromADT(adt); diff --git a/src/Client/World/WorldSession.cpp b/src/Client/World/WorldSession.cpp index 3603400..ede391a 100644 --- a/src/Client/World/WorldSession.cpp +++ b/src/Client/World/WorldSession.cpp @@ -9,6 +9,8 @@ #include "Channel.h" #include "ObjMgr.h" #include "World.h" +#include "MapMgr.h" +#include "MapTile.h" #include "RealmSession.h" #include "WorldSession.h" #include "MemoryDataHolder.h" @@ -696,11 +698,13 @@ void WorldSession::EnterWorldWithCharacter(std::string name) { logdebug("EnterWorldWithCharacter(%s)",name.c_str()); _myGUID = 0; + CharacterListExt charex; for(CharList::iterator it = _charList.begin(); it != _charList.end(); it++) { if(!stricmp(it->p._name.c_str(), name.c_str())) { _myGUID = it->p._guid; + charex = *it; GetInstance()->GetScripts()->variables.Set("@myguid",DefScriptTools::toString(_myGUID)); GetInstance()->GetScripts()->variables.Set("@myrace",DefScriptTools::toString(it->p._race)); } @@ -711,6 +715,8 @@ void WorldSession::EnterWorldWithCharacter(std::string name) return; } + PreloadDataBeforeEnterWorld(charex.p); + log("Entering World with Character \"%s\"...", name.c_str()); // create the character and add it to the objmgr. @@ -735,6 +741,35 @@ void WorldSession::EnterWorldWithCharacter(std::string name) } } +void WorldSession::PreloadDataBeforeEnterWorld(PlayerEnum& pl) +{ + log("Loading data before entering world..."); + GetWorld()->GetMapMgr()->Update(pl._x, pl._y, pl._mapId); // make it load the map files + + for(uint32 tiley = 0; tiley < 3; tiley++) + { + for(uint32 tilex = 0; tilex < 3; tilex++) + { + MapTile *maptile = GetWorld()->GetMapMgr()->GetNearTile(tilex - 1, tiley - 1); + if(maptile) + { + for(uint32 i = 0; i < maptile->GetDoodadCount(); i++) + { + Doodad *doo = maptile->GetDoodad(i); + + // it is useless to load the file here, since its loaded when irrlicht needs it and kept in the MeshCache for later use + //MemoryDataHolder::BackgroundLoadFile(doo->model); + + // 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"; + MemoryDataHolder::BackgroundLoadFile(skinfile); + } + } + } + } +} + void WorldSession::_HandleSetProficiencyOpcode(WorldPacket& recvPacket) { diff --git a/src/Client/World/WorldSession.h b/src/Client/World/WorldSession.h index 34c70c4..4556ba2 100644 --- a/src/Client/World/WorldSession.h +++ b/src/Client/World/WorldSession.h @@ -90,6 +90,7 @@ public: inline uint32 GetCharsCount(void) { return _charList.size(); } inline CharacterListExt& GetCharFromList(uint32 id) { return _charList[id]; } void EnterWorldWithCharacter(std::string); + void PreloadDataBeforeEnterWorld(PlayerEnum&); // CMSGConstructor diff --git a/src/PseuWoW.vcproj b/src/PseuWoW.vcproj index bc9bdc8..1a07163 100644 --- a/src/PseuWoW.vcproj +++ b/src/PseuWoW.vcproj @@ -504,6 +504,12 @@ + + + + diff --git a/src/dep/src/irrlicht/CD3D8Driver.h b/src/dep/src/irrlicht/CD3D8Driver.h index 0891a94..21b1042 100644 --- a/src/dep/src/irrlicht/CD3D8Driver.h +++ b/src/dep/src/irrlicht/CD3D8Driver.h @@ -22,7 +22,7 @@ #include "CNullDriver.h" #include "IMaterialRendererServices.h" -#include +#include "d3d8.h" namespace irr { diff --git a/src/dep/src/irrlicht/CD3D8MaterialRenderer.h b/src/dep/src/irrlicht/CD3D8MaterialRenderer.h index 6189563..fb1bfb4 100644 --- a/src/dep/src/irrlicht/CD3D8MaterialRenderer.h +++ b/src/dep/src/irrlicht/CD3D8MaterialRenderer.h @@ -9,7 +9,7 @@ #ifdef _IRR_WINDOWS_API_ #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ -#include +#include "d3d8.h" #include "IMaterialRenderer.h" diff --git a/src/dep/src/irrlicht/CD3D8NormalMapRenderer.h b/src/dep/src/irrlicht/CD3D8NormalMapRenderer.h index 9189cf6..4df4c62 100644 --- a/src/dep/src/irrlicht/CD3D8NormalMapRenderer.h +++ b/src/dep/src/irrlicht/CD3D8NormalMapRenderer.h @@ -9,7 +9,7 @@ #ifdef _IRR_WINDOWS_API_ #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ -#include +#include "d3d8.h" #include "CD3D8ShaderMaterialRenderer.h" #include "IShaderConstantSetCallBack.h" diff --git a/src/dep/src/irrlicht/CD3D8ParallaxMapRenderer.h b/src/dep/src/irrlicht/CD3D8ParallaxMapRenderer.h index f06bc32..11a173f 100644 --- a/src/dep/src/irrlicht/CD3D8ParallaxMapRenderer.h +++ b/src/dep/src/irrlicht/CD3D8ParallaxMapRenderer.h @@ -9,7 +9,7 @@ #ifdef _IRR_WINDOWS_API_ #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ -#include +#include "d3d8.h" #include "CD3D8ShaderMaterialRenderer.h" #include "IShaderConstantSetCallBack.h" diff --git a/src/dep/src/irrlicht/CD3D8ShaderMaterialRenderer.cpp b/src/dep/src/irrlicht/CD3D8ShaderMaterialRenderer.cpp index e08d4e1..e581708 100644 --- a/src/dep/src/irrlicht/CD3D8ShaderMaterialRenderer.cpp +++ b/src/dep/src/irrlicht/CD3D8ShaderMaterialRenderer.cpp @@ -6,7 +6,7 @@ #include "IrrCompileConfig.h" #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ -#include +#include "d3d8.h" #include #pragma comment (lib, "d3dx8.lib") diff --git a/src/dep/src/irrlicht/CD3D8ShaderMaterialRenderer.h b/src/dep/src/irrlicht/CD3D8ShaderMaterialRenderer.h index 79a695e..fe7e59c 100644 --- a/src/dep/src/irrlicht/CD3D8ShaderMaterialRenderer.h +++ b/src/dep/src/irrlicht/CD3D8ShaderMaterialRenderer.h @@ -9,7 +9,7 @@ #ifdef _IRR_WINDOWS_API_ #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ -#include +#include "d3d8.h" #include #include "IMaterialRenderer.h" diff --git a/src/dep/src/irrlicht/CD3D8Texture.h b/src/dep/src/irrlicht/CD3D8Texture.h index 21a054e..3947377 100644 --- a/src/dep/src/irrlicht/CD3D8Texture.h +++ b/src/dep/src/irrlicht/CD3D8Texture.h @@ -10,7 +10,7 @@ #include "ITexture.h" #include "IImage.h" -#include +#include "d3d8.h" namespace irr { diff --git a/src/dep/src/irrlicht/CD3D9Driver.h b/src/dep/src/irrlicht/CD3D9Driver.h index 0f9dce5..545a685 100644 --- a/src/dep/src/irrlicht/CD3D9Driver.h +++ b/src/dep/src/irrlicht/CD3D9Driver.h @@ -16,7 +16,7 @@ #include "CNullDriver.h" #include "IMaterialRendererServices.h" -#include +#include "d3d9.h" namespace irr { diff --git a/src/dep/src/irrlicht/CD3D9MaterialRenderer.h b/src/dep/src/irrlicht/CD3D9MaterialRenderer.h index 4ffe952..e85c17d 100644 --- a/src/dep/src/irrlicht/CD3D9MaterialRenderer.h +++ b/src/dep/src/irrlicht/CD3D9MaterialRenderer.h @@ -9,7 +9,7 @@ #ifdef _IRR_WINDOWS_ #ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ -#include +#include "d3d9.h" #include "IMaterialRenderer.h" diff --git a/src/dep/src/irrlicht/CD3D9NormalMapRenderer.h b/src/dep/src/irrlicht/CD3D9NormalMapRenderer.h index f67f6fd..800be4e 100644 --- a/src/dep/src/irrlicht/CD3D9NormalMapRenderer.h +++ b/src/dep/src/irrlicht/CD3D9NormalMapRenderer.h @@ -9,7 +9,7 @@ #ifdef _IRR_WINDOWS_ #ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ -#include +#include "d3d9.h" #include "CD3D9ShaderMaterialRenderer.h" #include "IShaderConstantSetCallBack.h" diff --git a/src/dep/src/irrlicht/CD3D9ParallaxMapRenderer.h b/src/dep/src/irrlicht/CD3D9ParallaxMapRenderer.h index 1074ca7..a9975c6 100644 --- a/src/dep/src/irrlicht/CD3D9ParallaxMapRenderer.h +++ b/src/dep/src/irrlicht/CD3D9ParallaxMapRenderer.h @@ -9,7 +9,7 @@ #ifdef _IRR_WINDOWS_ #ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ -#include +#include "d3d9.h" #include "CD3D9ShaderMaterialRenderer.h" #include "IShaderConstantSetCallBack.h" diff --git a/src/dep/src/irrlicht/CD3D9ShaderMaterialRenderer.h b/src/dep/src/irrlicht/CD3D9ShaderMaterialRenderer.h index 621d82a..e0d8063 100644 --- a/src/dep/src/irrlicht/CD3D9ShaderMaterialRenderer.h +++ b/src/dep/src/irrlicht/CD3D9ShaderMaterialRenderer.h @@ -9,7 +9,7 @@ #ifdef _IRR_WINDOWS_ #ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ -#include +#include "d3d9.h" #include #include "IMaterialRenderer.h" diff --git a/src/dep/src/irrlicht/CD3D9Texture.h b/src/dep/src/irrlicht/CD3D9Texture.h index 3a64a76..b77ab04 100644 --- a/src/dep/src/irrlicht/CD3D9Texture.h +++ b/src/dep/src/irrlicht/CD3D9Texture.h @@ -10,7 +10,7 @@ #include "ITexture.h" #include "IImage.h" -#include +#include "d3d9.h" namespace irr { diff --git a/src/dep/src/irrlicht/Irrlicht7.1.vcproj b/src/dep/src/irrlicht/Irrlicht7.1.vcproj index c9c74a1..f00a578 100644 --- a/src/dep/src/irrlicht/Irrlicht7.1.vcproj +++ b/src/dep/src/irrlicht/Irrlicht7.1.vcproj @@ -12,16 +12,16 @@ + Name="VCLibrarianTool" + OutputFile="./dep/lib/debug/irrlicht.lib"/> - + Name="VCLibrarianTool" + OutputFile="./dep/lib/release/zthread.lib"/> - + Name="VCLibrarianTool" + OutputFile="./dep/lib/release/irrlicht_fastfpu.lib"/> - - - - - - + ATLMinimizesCRunTimeLibraryUsage="FALSE" + CharacterSet="0"> + CompileAs="0"/> - - + Name="VCCustomBuildTool"/> + OutputFile="..\..\lib\Win32-visualstudio\Irrlicht.lib"/> + Name="VCMIDLTool" + PreprocessorDefinitions="_DEBUG" + MkTypLibCompatible="TRUE" + SuppressStartupBanner="TRUE" + TargetEnvironment="1" + TypeLibraryName=".\..\Debug/Irrlicht.tlb"/> + Name="VCPostBuildEventTool"/> + Name="VCPreBuildEventTool"/> + Name="VCPreLinkEventTool"/> + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_DEBUG" + Culture="3079"/> + + + + - - - - - + WholeProgramOptimization="TRUE"> + CompileAs="0"/> - - + Name="VCCustomBuildTool"/> - - - - - - - - - - - + OutputFile="..\..\lib\Win32-visualstudio\Irrlicht.lib"/> + TypeLibraryName=".\..\Release/Irrlicht.tlb"/> + + + + + + + + + + + CompileAs="0"/> - - + Name="VCCustomBuildTool"/> + OutputFile="..\..\lib\Win32-visualstudio\Irrlicht.lib"/> + Name="VCMIDLTool" + PreprocessorDefinitions="NDEBUG" + MkTypLibCompatible="TRUE" + SuppressStartupBanner="TRUE" + TargetEnvironment="1" + TypeLibraryName=".\..\Release/Irrlicht.tlb"/> + Name="VCPostBuildEventTool"/> + Name="VCPreBuildEventTool"/> + Name="VCPreLinkEventTool"/> + Name="VCResourceCompilerTool" + PreprocessorDefinitions="NDEBUG" + Culture="3079"/> + + + + @@ -781,10 +681,10 @@ RelativePath=".\..\..\include\ITextSceneNode.h"> + RelativePath=".\..\..\include\ITriangleSelector.h"> + RelativePath=".\..\..\include\IVolumeLightSceneNode.h"> @@ -805,10 +705,10 @@ RelativePath=".\..\..\include\SMeshBufferTangents.h"> + RelativePath=".\..\..\include\SParticle.h"> + RelativePath=".\..\..\include\SSkinMeshBuffer.h"> @@ -1809,12 +1709,6 @@ - - - - @@ -1830,6 +1724,12 @@ + + + + @@ -1951,18 +1851,18 @@ - - - - + + + + _models[mddf.id])); - // this .mdx -> .m2 transformation is annoying >.< - replace "mdx" and end of string with "m2\0" - memcpy(&d.model[0] + d.model.size() - 3, "m2\0", 3); + // 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"; d.scale = mddf.scale / 1024.0f; if(d.scale < 0.00001f) d.scale = 1; diff --git a/src/shared/common.h b/src/shared/common.h index a20f001..e413e91 100644 --- a/src/shared/common.h +++ b/src/shared/common.h @@ -17,7 +17,9 @@ #include #ifndef _COMMON_SKIP_THREADS +# include "zthread/Condition.h" # include "zthread/FastMutex.h" +# include "zthread/FastRecursiveMutex.h" # include "zthread/LockedQueue.h" # include "zthread/Runnable.h" # include "zthread/Thread.h"