diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 4f149efa14..e6296ab962 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/apps/openmw/mwbase/soundmanager.hpp b/apps/openmw/mwbase/soundmanager.hpp index 0c706ab496..5d396fac07 100644 --- a/apps/openmw/mwbase/soundmanager.hpp +++ b/apps/openmw/mwbase/soundmanager.hpp @@ -84,7 +84,7 @@ namespace MWBase ///< Start playing music from the selected folder /// \param name of the folder that contains the playlist - virtual void say(MWWorld::Ptr reference, const std::string& filename) = 0; + virtual void say(const MWWorld::Ptr &reference, const std::string& filename) = 0; ///< Make an actor say some text. /// \param filename name of a sound file in "Sound/" in the data directory. @@ -92,10 +92,10 @@ namespace MWBase ///< Say some text, without an actor ref /// \param filename name of a sound file in "Sound/" in the data directory. - virtual bool sayDone(MWWorld::Ptr reference=MWWorld::Ptr()) const = 0; + virtual bool sayDone(const MWWorld::Ptr &reference=MWWorld::Ptr()) const = 0; ///< Is actor not speaking? - virtual void stopSay(MWWorld::Ptr reference=MWWorld::Ptr()) = 0; + virtual void stopSay(const MWWorld::Ptr &reference=MWWorld::Ptr()) = 0; ///< Stop an actor speaking virtual SoundPtr playTrack(const MWSound::DecoderPtr& decoder, PlayType type) = 0; @@ -105,14 +105,14 @@ namespace MWBase PlayMode mode=Play_Normal) = 0; ///< Play a sound, independently of 3D-position - virtual SoundPtr playSound3D(MWWorld::Ptr reference, const std::string& soundId, + virtual SoundPtr playSound3D(const MWWorld::Ptr &reference, const std::string& soundId, float volume, float pitch, PlayMode mode=Play_Normal) = 0; ///< Play a sound from an object - virtual void stopSound3D(MWWorld::Ptr reference, const std::string& soundId) = 0; + virtual void stopSound3D(const MWWorld::Ptr &reference, const std::string& soundId) = 0; ///< Stop the given object from playing the given sound, - virtual void stopSound3D(MWWorld::Ptr reference) = 0; + virtual void stopSound3D(const MWWorld::Ptr &reference) = 0; ///< Stop the given object from playing all sounds. virtual void stopSound(const MWWorld::CellStore *cell) = 0; @@ -121,7 +121,7 @@ namespace MWBase virtual void stopSound(const std::string& soundId) = 0; ///< Stop a non-3d looping sound - virtual bool getSoundPlaying(MWWorld::Ptr reference, const std::string& soundId) const = 0; + virtual bool getSoundPlaying(const MWWorld::Ptr &reference, const std::string& soundId) const = 0; ///< Is the given sound currently playing on the given object? virtual void pauseSounds(int types=Play_TypeMask) = 0; diff --git a/apps/openmw/mwrender/actors.cpp b/apps/openmw/mwrender/actors.cpp index ec7c9d0732..c36248aafa 100644 --- a/apps/openmw/mwrender/actors.cpp +++ b/apps/openmw/mwrender/actors.cpp @@ -16,31 +16,31 @@ namespace MWRender { using namespace Ogre; -Actors::~Actors(){ - std::map::iterator it = mAllActors.begin(); - for (; it != mAllActors.end(); ++it) { +Actors::~Actors() +{ + PtrAnimationMap::iterator it = mAllActors.begin(); + for(;it != mAllActors.end();++it) + { delete it->second; it->second = NULL; } } -void Actors::setMwRoot(Ogre::SceneNode* root){ - mMwRoot = root; -} +void Actors::setMwRoot(Ogre::SceneNode* root) +{ mMwRoot = root; } -void Actors::insertBegin (const MWWorld::Ptr& ptr) +void Actors::insertBegin(const MWWorld::Ptr &ptr) { Ogre::SceneNode* cellnode; - if(mCellSceneNodes.find(ptr.getCell()) == mCellSceneNodes.end()) + CellSceneNodeMap::const_iterator celliter = mCellSceneNodes.find(ptr.getCell()); + if(celliter != mCellSceneNodes.end()) + cellnode = celliter->second; + else { //Create the scenenode and put it in the map cellnode = mMwRoot->createChildSceneNode(); mCellSceneNodes[ptr.getCell()] = cellnode; } - else - { - cellnode = mCellSceneNodes[ptr.getCell()]; - } Ogre::SceneNode* insert = cellnode->createChildSceneNode(); const float *f = ptr.getRefData().getPosition().pos; @@ -51,13 +51,13 @@ void Actors::insertBegin (const MWWorld::Ptr& ptr) f = ptr.getCellRef().mPos.rot; // Rotate around X axis - Quaternion xr(Radian(-f[0]), Vector3::UNIT_X); + Ogre::Quaternion xr(Ogre::Radian(-f[0]), Ogre::Vector3::UNIT_X); // Rotate around Y axis - Quaternion yr(Radian(-f[1]), Vector3::UNIT_Y); + Ogre::Quaternion yr(Ogre::Radian(-f[1]), Ogre::Vector3::UNIT_Y); // Rotate around Z axis - Quaternion zr(Radian(-f[2]), Vector3::UNIT_Z); + Ogre::Quaternion zr(Ogre::Radian(-f[2]), Ogre::Vector3::UNIT_Z); // Rotates first around z, then y, then x insert->setOrientation(xr*yr*zr); @@ -83,20 +83,21 @@ bool Actors::deleteObject (const MWWorld::Ptr& ptr) { delete mAllActors[ptr]; mAllActors.erase(ptr); - if (Ogre::SceneNode *base = ptr.getRefData().getBaseNode()) + + if(Ogre::SceneNode *base=ptr.getRefData().getBaseNode()) { - Ogre::SceneNode *parent = base->getParentSceneNode(); - - for (std::map::const_iterator iter ( - mCellSceneNodes.begin()); iter!=mCellSceneNodes.end(); ++iter) - if (iter->second==parent) + CellSceneNodeMap::const_iterator iter(mCellSceneNodes.begin()); + for(;iter != mCellSceneNodes.end();++iter) + { + if(iter->second == parent) { base->removeAndDestroyAllChildren(); mRend.getScene()->destroySceneNode (base); ptr.getRefData().setBaseNode (0); return true; } + } return false; } @@ -104,57 +105,68 @@ bool Actors::deleteObject (const MWWorld::Ptr& ptr) return true; } -void Actors::removeCell(MWWorld::Ptr::CellStore* store){ - if(mCellSceneNodes.find(store) != mCellSceneNodes.end()) +void Actors::removeCell(MWWorld::Ptr::CellStore* store) +{ + for(PtrAnimationMap::iterator iter = mAllActors.begin();iter != mAllActors.end();) { - Ogre::SceneNode* base = mCellSceneNodes[store]; - base->removeAndDestroyAllChildren(); - mCellSceneNodes.erase(store); - mRend.getScene()->destroySceneNode(base); - base = 0; - } - for(std::map::iterator iter = mAllActors.begin(); iter != mAllActors.end(); ) - { - if(iter->first.getCell() == store){ + if(iter->first.getCell() == store) + { delete iter->second; mAllActors.erase(iter++); } else ++iter; } + CellSceneNodeMap::iterator celliter = mCellSceneNodes.find(store); + if(celliter != mCellSceneNodes.end()) + { + Ogre::SceneNode *base = celliter->second; + base->removeAndDestroyAllChildren(); + mRend.getScene()->destroySceneNode(base); + mCellSceneNodes.erase(celliter); + } } -void Actors::playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number){ - if(mAllActors.find(ptr) != mAllActors.end()) - mAllActors[ptr]->playGroup(groupName, mode, number); +void Actors::playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number) +{ + PtrAnimationMap::const_iterator iter = mAllActors.find(ptr); + if(iter != mAllActors.end()) + iter->second->playGroup(groupName, mode, number); } -void Actors::skipAnimation (const MWWorld::Ptr& ptr){ - if(mAllActors.find(ptr) != mAllActors.end()) - mAllActors[ptr]->skipAnim(); +void Actors::skipAnimation (const MWWorld::Ptr& ptr) +{ + PtrAnimationMap::const_iterator iter = mAllActors.find(ptr); + if(iter != mAllActors.end()) + iter->second->skipAnim(); } -void Actors::update (float duration){ - for(std::map::iterator iter = mAllActors.begin(); iter != mAllActors.end(); iter++) +void Actors::update (float duration) +{ + for(PtrAnimationMap::const_iterator iter = mAllActors.begin();iter != mAllActors.end();iter++) iter->second->runAnimation(duration); } -void -Actors::updateObjectCell(const MWWorld::Ptr &ptr) +void Actors::updateObjectCell(const MWWorld::Ptr &ptr) { Ogre::SceneNode *node; MWWorld::CellStore *newCell = ptr.getCell(); - if(mCellSceneNodes.find(newCell) == mCellSceneNodes.end()) { + CellSceneNodeMap::const_iterator celliter = mCellSceneNodes.find(newCell); + if(celliter != mCellSceneNodes.end()) + node = celliter->second; + else + { node = mMwRoot->createChildSceneNode(); mCellSceneNodes[newCell] = node; - } else { - node = mCellSceneNodes[newCell]; } node->addChild(ptr.getRefData().getBaseNode()); - if (mAllActors.find(ptr) != mAllActors.end()) { + + PtrAnimationMap::iterator iter = mAllActors.find(ptr); + if(iter != mAllActors.end()) + { /// \note Update key (Ptr's are compared only with refdata so mCell /// on key is outdated), maybe redundant - Animation *anim = mAllActors[ptr]; - mAllActors.erase(ptr); + Animation *anim = iter->second; + mAllActors.erase(iter); mAllActors[ptr] = anim; } } diff --git a/apps/openmw/mwrender/actors.hpp b/apps/openmw/mwrender/actors.hpp index 6ea6a81377..53829000ca 100644 --- a/apps/openmw/mwrender/actors.hpp +++ b/apps/openmw/mwrender/actors.hpp @@ -16,14 +16,19 @@ namespace MWRender class Actors { + typedef std::map CellSceneNodeMap; + typedef std::map PtrAnimationMap; + OEngine::Render::OgreRenderer &mRend; - std::map mCellSceneNodes; Ogre::SceneNode* mMwRoot; - std::map mAllActors; + + CellSceneNodeMap mCellSceneNodes; + PtrAnimationMap mAllActors; public: Actors(OEngine::Render::OgreRenderer& _rend): mRend(_rend) {} ~Actors(); + void setMwRoot(Ogre::SceneNode* root); void insertBegin (const MWWorld::Ptr& ptr); void insertCreature (const MWWorld::Ptr& ptr); diff --git a/apps/openmw/mwscript/userextensions.hpp b/apps/openmw/mwscript/userextensions.hpp index 3642eb5f49..4bc3b46ec0 100644 --- a/apps/openmw/mwscript/userextensions.hpp +++ b/apps/openmw/mwscript/userextensions.hpp @@ -13,7 +13,7 @@ namespace Interpreter namespace MWScript { - /// \brief Temporaty script functionality limited to the console + /// \brief Temporary script functionality limited to the console namespace User { void registerExtensions (Compiler::Extensions& extensions); diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index 8a69fc96bc..c502906808 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -160,7 +160,7 @@ namespace MWSound return volume; } - bool SoundManager::isPlaying(MWWorld::Ptr ptr, const std::string &id) const + bool SoundManager::isPlaying(const MWWorld::Ptr &ptr, const std::string &id) const { SoundMap::const_iterator snditer = mActiveSounds.begin(); while(snditer != mActiveSounds.end()) @@ -229,7 +229,7 @@ namespace MWSound startRandomTitle(); } - void SoundManager::say(MWWorld::Ptr ptr, const std::string& filename) + void SoundManager::say(const MWWorld::Ptr &ptr, const std::string& filename) { if(!mOutput->isInitialized()) return; @@ -269,12 +269,12 @@ namespace MWSound } } - bool SoundManager::sayDone(MWWorld::Ptr ptr) const + bool SoundManager::sayDone(const MWWorld::Ptr &ptr) const { return !isPlaying(ptr, "_say_sound"); } - void SoundManager::stopSay(MWWorld::Ptr ptr) + void SoundManager::stopSay(const MWWorld::Ptr &ptr) { SoundMap::iterator snditer = mActiveSounds.begin(); while(snditer != mActiveSounds.end()) @@ -328,7 +328,7 @@ namespace MWSound return sound; } - MWBase::SoundPtr SoundManager::playSound3D(MWWorld::Ptr ptr, const std::string& soundId, + MWBase::SoundPtr SoundManager::playSound3D(const MWWorld::Ptr &ptr, const std::string& soundId, float volume, float pitch, PlayMode mode) { MWBase::SoundPtr sound; @@ -356,7 +356,7 @@ namespace MWSound return sound; } - void SoundManager::stopSound3D(MWWorld::Ptr ptr, const std::string& soundId) + void SoundManager::stopSound3D(const MWWorld::Ptr &ptr, const std::string& soundId) { SoundMap::iterator snditer = mActiveSounds.begin(); while(snditer != mActiveSounds.end()) @@ -371,7 +371,7 @@ namespace MWSound } } - void SoundManager::stopSound3D(MWWorld::Ptr ptr) + void SoundManager::stopSound3D(const MWWorld::Ptr &ptr) { SoundMap::iterator snditer = mActiveSounds.begin(); while(snditer != mActiveSounds.end()) @@ -418,7 +418,7 @@ namespace MWSound } } - bool SoundManager::getSoundPlaying(MWWorld::Ptr ptr, const std::string& soundId) const + bool SoundManager::getSoundPlaying(const MWWorld::Ptr &ptr, const std::string& soundId) const { return isPlaying(ptr, soundId); } diff --git a/apps/openmw/mwsound/soundmanagerimp.hpp b/apps/openmw/mwsound/soundmanagerimp.hpp index b475449d90..2af26d3dbb 100644 --- a/apps/openmw/mwsound/soundmanagerimp.hpp +++ b/apps/openmw/mwsound/soundmanagerimp.hpp @@ -14,8 +14,6 @@ #include "../mwbase/soundmanager.hpp" -#include "../mwworld/ptr.hpp" - namespace MWSound { class Sound_Output; @@ -57,7 +55,7 @@ namespace MWSound std::string lookup(const std::string &soundId, float &volume, float &min, float &max); void streamMusicFull(const std::string& filename); - bool isPlaying(MWWorld::Ptr ptr, const std::string &id) const; + bool isPlaying(const MWWorld::Ptr &ptr, const std::string &id) const; void updateSounds(float duration); void updateRegionSound(float duration); @@ -93,7 +91,7 @@ namespace MWSound ///< Start playing music from the selected folder /// \param name of the folder that contains the playlist - virtual void say(MWWorld::Ptr reference, const std::string& filename); + virtual void say(const MWWorld::Ptr &reference, const std::string& filename); ///< Make an actor say some text. /// \param filename name of a sound file in "Sound/" in the data directory. @@ -101,10 +99,10 @@ namespace MWSound ///< Say some text, without an actor ref /// \param filename name of a sound file in "Sound/" in the data directory. - virtual bool sayDone(MWWorld::Ptr reference=MWWorld::Ptr()) const; + virtual bool sayDone(const MWWorld::Ptr &reference=MWWorld::Ptr()) const; ///< Is actor not speaking? - virtual void stopSay(MWWorld::Ptr reference=MWWorld::Ptr()); + virtual void stopSay(const MWWorld::Ptr &reference=MWWorld::Ptr()); ///< Stop an actor speaking virtual MWBase::SoundPtr playTrack(const DecoderPtr& decoder, PlayType type); @@ -113,14 +111,14 @@ namespace MWSound virtual MWBase::SoundPtr playSound(const std::string& soundId, float volume, float pitch, PlayMode mode=Play_Normal); ///< Play a sound, independently of 3D-position - virtual MWBase::SoundPtr playSound3D(MWWorld::Ptr reference, const std::string& soundId, + virtual MWBase::SoundPtr playSound3D(const MWWorld::Ptr &reference, const std::string& soundId, float volume, float pitch, PlayMode mode=Play_Normal); ///< Play a sound from an object - virtual void stopSound3D(MWWorld::Ptr reference, const std::string& soundId); + virtual void stopSound3D(const MWWorld::Ptr &reference, const std::string& soundId); ///< Stop the given object from playing the given sound, - virtual void stopSound3D(MWWorld::Ptr reference); + virtual void stopSound3D(const MWWorld::Ptr &reference); ///< Stop the given object from playing all sounds. virtual void stopSound(const MWWorld::CellStore *cell); @@ -129,7 +127,7 @@ namespace MWSound virtual void stopSound(const std::string& soundId); ///< Stop a non-3d looping sound - virtual bool getSoundPlaying(MWWorld::Ptr reference, const std::string& soundId) const; + virtual bool getSoundPlaying(const MWWorld::Ptr &reference, const std::string& soundId) const; ///< Is the given sound currently playing on the given object? virtual void pauseSounds(int types=Play_TypeMask); diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 2368ada6a0..e116dca579 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -1,5 +1,6 @@ #include "scene.hpp" +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" /// FIXME diff --git a/components/bsa/bsa_archive.cpp b/components/bsa/bsa_archive.cpp index 9913fb8aab..5274564a63 100644 --- a/components/bsa/bsa_archive.cpp +++ b/components/bsa/bsa_archive.cpp @@ -31,150 +31,30 @@ #include "../files/constrainedfiledatastream.hpp" -namespace -{ - using namespace Ogre; -using namespace Bsa; - -struct PathPatternMatcher -{ - PathPatternMatcher (char const * pattern) : pattern (pattern) - { - } - - bool operator () (char const * input) - { - char const * p = pattern; - char const * i = input; - - while (*p && *i) - { - if (*p == '*') - { - ++p; - - while (*i && *i != *p && *i != '/' && *i != '\\') - ++i; - } - else - if (*p == '?') - { - if (*i == '/' || *i == '\\') - break; - - ++i, ++p; - } - if (*p == '/' || *p == '\\') - { - if (*i != '/' && *i != '\\') - break; - - ++i, ++p; - } - else - { - if (*i != *p) - break; - - ++i, ++p; - } - } - - return *p == 0 && *i == 0; - } - -private: - char const * pattern; -}; - -struct FileNameGatherer -{ - StringVectorPtr ptr; - - FileNameGatherer (StringVectorPtr ptr) : ptr (ptr) - { - } - - void operator () (std::string const & filename) const - { - ptr->push_back (filename); - } -}; - -struct FileInfoGatherer -{ - Archive const * archive; - FileInfoListPtr ptr; - - FileInfoGatherer (Archive const * archive, FileInfoListPtr ptr) : - archive (archive), ptr (ptr) - { - } - - void operator () (std::string filename) const - { - FileInfo fi; - - std::size_t pt = filename.rfind ('/'); - if (pt == std::string::npos) - pt = 0; - - fi.archive = const_cast (archive); - fi.path = filename.substr (0, pt); - fi.filename = filename.substr (pt); - fi.compressedSize = fi.uncompressedSize = 0; - - ptr->push_back(fi); - } -}; - -template -void matchFiles (bool recursive, std::string const & pattern, file_iterator begin, file_iterator end, filename_extractor filenameExtractor, match_handler matchHandler) -{ - if (recursive && pattern == "*") - { - for (file_iterator i = begin; i != end; ++i) - matchHandler (filenameExtractor (*i)); - } - else - { - PathPatternMatcher matcher (pattern.c_str ()); - - if (recursive) - { - for (file_iterator i = begin; i != end; ++i) - { - char const * filename = filenameExtractor (*i); - char const * matchable_part = filename; - - for (char const * j = matchable_part; *j; ++j) - { - if (*j == '/' || *j == '\\') - matchable_part = j + 1; - } - - if (matcher (matchable_part)) - matchHandler (filename); - } - } - else - { - for (file_iterator i = begin; i != end; ++i) - { - char const * filename = filenameExtractor (*i); - - if (matcher (filename)) - matchHandler (filename); - } - } - } -} - - static bool fsstrict = false; +static char strict_normalize_char(char ch) +{ + return ch == '\\' ? '/' : ch; +} + +static char nonstrict_normalize_char(char ch) +{ + return ch == '\\' ? '/' : std::tolower(ch); +} + +template +static std::string normalize_path(T1 begin, T2 end) +{ + std::string normalized; + normalized.reserve(std::distance(begin, end)); + char (*normalize_char)(char) = fsstrict ? &strict_normalize_char : &nonstrict_normalize_char; + std::transform(begin, end, std::back_inserter(normalized), normalize_char); + return normalized; +} + /// An OGRE Archive wrapping a BSAFile archive class DirArchive: public Ogre::Archive { @@ -182,37 +62,12 @@ class DirArchive: public Ogre::Archive index mIndex; - static char strict_normalize_char(char ch) - { - return ch == '\\' ? '/' : ch; - } - - static char nonstrict_normalize_char(char ch) - { - return ch == '\\' ? '/' : std::tolower (ch); - } - - static std::string normalize_path (std::string::const_iterator begin, std::string::const_iterator end) - { - std::string normalized; - normalized.reserve (end-begin); - char (*normalize_char) (char) = fsstrict ? &strict_normalize_char : &nonstrict_normalize_char; - std::transform (begin, end, std::back_inserter (normalized), normalize_char); - return normalized; - } - index::const_iterator lookup_filename (std::string const & filename) const { std::string normalized = normalize_path (filename.begin (), filename.end ()); - return mIndex.find (normalized); } - static char const * extractFilename (index::value_type const & entry) - { - return entry.first.c_str (); - } - public: DirArchive(const String& name) @@ -273,15 +128,20 @@ public: StringVectorPtr find(const String& pattern, bool recursive = true, bool dirs = false) { - std::string normalizedPattern = normalize_path (pattern.begin (), pattern.end ()); + std::string normalizedPattern = normalize_path(pattern.begin(), pattern.end()); StringVectorPtr ptr = StringVectorPtr(new StringVector()); - matchFiles (recursive, normalizedPattern, mIndex.begin (), mIndex.end (), extractFilename, FileNameGatherer (ptr)); + for(index::const_iterator iter = mIndex.begin();iter != mIndex.end();iter++) + { + if(Ogre::StringUtil::match(iter->first, normalizedPattern) || + (recursive && Ogre::StringUtil::match(iter->first, "*/"+normalizedPattern))) + ptr->push_back(iter->first); + } return ptr; } bool exists(const String& filename) { - return lookup_filename (filename) != mIndex.end (); + return lookup_filename(filename) != mIndex.end (); } time_t getModifiedTime(const String&) { return 0; } @@ -289,21 +149,44 @@ public: FileInfoListPtr findFileInfo(const String& pattern, bool recursive = true, bool dirs = false) const { + std::string normalizedPattern = normalize_path(pattern.begin(), pattern.end()); FileInfoListPtr ptr = FileInfoListPtr(new FileInfoList()); - FileInfoGatherer gatherer (this, ptr); - std::string normalizedPattern = normalize_path (pattern.begin (), pattern.end ()); - - index::const_iterator i = mIndex.find (normalizedPattern); - - if (i != mIndex.end ()) + index::const_iterator i = mIndex.find(normalizedPattern); + if(i != mIndex.end()) { - gatherer (i->first); + std::string::size_type pt = i->first.rfind('/'); + if(pt == std::string::npos) + pt = 0; + + FileInfo fi; + fi.archive = const_cast(this); + fi.path = i->first.substr(0, pt); + fi.filename = i->first.substr((i->first[pt]=='/') ? pt+1 : pt); + fi.compressedSize = fi.uncompressedSize = 0; + + ptr->push_back(fi); } else { + for(index::const_iterator iter = mIndex.begin();iter != mIndex.end();iter++) + { + if(Ogre::StringUtil::match(iter->first, normalizedPattern) || + (recursive && Ogre::StringUtil::match(iter->first, "*/"+normalizedPattern))) + { + std::string::size_type pt = iter->first.rfind('/'); + if(pt == std::string::npos) + pt = 0; - matchFiles (recursive, normalizedPattern, mIndex.begin (), mIndex.end (), extractFilename, gatherer); + FileInfo fi; + fi.archive = const_cast(this); + fi.path = iter->first.substr(0, pt); + fi.filename = iter->first.substr((iter->first[pt]=='/') ? pt+1 : pt); + fi.compressedSize = fi.uncompressedSize = 0; + + ptr->push_back(fi); + } + } } return ptr; @@ -312,9 +195,9 @@ public: class BSAArchive : public Archive { - BSAFile arc; + Bsa::BSAFile arc; - static char const * extractFilename (BSAFile::FileStruct const & entry) + static const char *extractFilename(const Bsa::BSAFile::FileStruct &entry) { return entry.name; } @@ -330,13 +213,13 @@ public: void load() {} void unload() {} - DataStreamPtr open(const String& filename, bool recursive = true) const + DataStreamPtr open(const String& filename, bool readonly = true) const { // Get a non-const reference to arc. This is a hack and it's all // OGRE's fault. You should NOT expect an open() command not to // have any side effects on the archive, and hence this function // should not have been declared const in the first place. - BSAFile *narc = const_cast(&arc); + Bsa::BSAFile *narc = const_cast(&arc); // Open the file return narc->getFile(filename.c_str()); @@ -360,32 +243,51 @@ public: return findFileInfo ("*", recursive, dirs); } - // After load() is called, find("*") is called once. It doesn't seem - // to matter that we return an empty list, exists() gets called on - // the correct files anyway. - StringVectorPtr find(const String& pattern, bool recursive = true, - bool dirs = false) - { + StringVectorPtr find(const String& pattern, bool recursive = true, + bool dirs = false) + { + std::string normalizedPattern = normalize_path(pattern.begin(), pattern.end()); + const Bsa::BSAFile::FileList &filelist = arc.getList(); StringVectorPtr ptr = StringVectorPtr(new StringVector()); - matchFiles (recursive, pattern, arc.getList ().begin (), arc.getList ().end (), extractFilename, FileNameGatherer (ptr)); + for(Bsa::BSAFile::FileList::const_iterator iter = filelist.begin();iter != filelist.end();iter++) + { + std::string ent = normalize_path(iter->name, iter->name+std::strlen(iter->name)); + if(Ogre::StringUtil::match(ent, normalizedPattern) || + (recursive && Ogre::StringUtil::match(ent, "*/"+normalizedPattern))) + ptr->push_back(iter->name); + } return ptr; - } + } - /* Gets called once for each of the ogre formats, *.program, - *.material etc. We ignore all these. + FileInfoListPtr findFileInfo(const String& pattern, bool recursive = true, + bool dirs = false) const + { + std::string normalizedPattern = normalize_path(pattern.begin(), pattern.end()); + FileInfoListPtr ptr = FileInfoListPtr(new FileInfoList()); + const Bsa::BSAFile::FileList &filelist = arc.getList(); - However, it's also called by MyGUI to find individual textures, - and we can't ignore these since many of the GUI textures are - located in BSAs. So instead we channel it through exists() and - set up a single-element result list if the file is found. - */ - FileInfoListPtr findFileInfo(const String& pattern, bool recursive = true, - bool dirs = false) const - { - FileInfoListPtr ptr = FileInfoListPtr(new FileInfoList()); - matchFiles (recursive, pattern, arc.getList ().begin (), arc.getList ().end (), extractFilename, FileInfoGatherer (this, ptr)); - return ptr; - } + for(Bsa::BSAFile::FileList::const_iterator iter = filelist.begin();iter != filelist.end();iter++) + { + std::string ent = normalize_path(iter->name, iter->name+std::strlen(iter->name)); + if(Ogre::StringUtil::match(ent, normalizedPattern) || + (recursive && Ogre::StringUtil::match(ent, "*/"+normalizedPattern))) + { + std::string::size_type pt = ent.rfind('/'); + if(pt == std::string::npos) + pt = 0; + + FileInfo fi; + fi.archive = const_cast(this); + fi.path = std::string(iter->name, pt); + fi.filename = std::string(iter->name + ((ent[pt]=='/') ? pt+1 : pt)); + fi.compressedSize = fi.uncompressedSize = iter->fileSize; + + ptr->push_back(fi); + } + } + + return ptr; + } }; // An archive factory for BSA archives @@ -445,7 +347,6 @@ static void insertDirFactory() } } -} namespace Bsa {