forked from teamnwah/openmw-tes3coop
Added file_finder component. Used by sound system.
This commit is contained in:
parent
104f3fdd50
commit
3127602c57
6 changed files with 188 additions and 13 deletions
|
@ -50,6 +50,14 @@ set(TO_UTF8_HEADER
|
|||
${COMP_DIR}/to_utf8/to_utf8.hpp)
|
||||
source_group(components\\to_utf8 FILES ${TO_UTF8} ${TO_UTF8_HEADER})
|
||||
|
||||
set(FILE_FINDER
|
||||
${COMP_DIR}/file_finder/search.cpp)
|
||||
set(FILE_FINDER_HEADER
|
||||
${COMP_DIR}/file_finder/file_finder.hpp
|
||||
${COMP_DIR}/file_finder/filename_less.hpp
|
||||
${COMP_DIR}/file_finder/search.hpp)
|
||||
source_group(components\\file_finder FILES ${FILE_FINDER} ${FILE_FINDER_HEADER})
|
||||
|
||||
set(ESM_STORE
|
||||
${COMP_DIR}/esm_store/store.cpp)
|
||||
set(ESM_STORE_HEADER
|
||||
|
@ -82,10 +90,10 @@ file(GLOB INTERPRETER_HEADER ${COMP_DIR}/interpreter/*.hpp)
|
|||
source_group(components\\interpreter FILES ${INTERPRETER} ${INTERPRETER_HEADER})
|
||||
|
||||
set(COMPONENTS ${BSA} ${NIF} ${NIFOGRE} ${ESM_STORE} ${MISC} ${TO_UTF8}
|
||||
${COMPILER} ${INTERPRETER} ${ESM})
|
||||
${COMPILER} ${INTERPRETER} ${ESM} ${FILE_FINDER})
|
||||
set(COMPONENTS_HEADER ${BSA_HEADER} ${NIF_HEADER} ${NIFOGRE_HEADER} ${ESM_STORE_HEADER}
|
||||
${ESM_HEADER} ${MISC_HEADER} ${COMPILER_HEADER} ${TO_UTF8_HEADER}
|
||||
${INTERPRETER_HEADER})
|
||||
${INTERPRETER_HEADER} ${FILE_FINDER_HEADER})
|
||||
|
||||
# source directory: libs
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
#include "soundmanager.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
@ -8,6 +7,7 @@ using namespace std;
|
|||
#include <mangle/sound/clients/ogre_listener_mover.hpp>
|
||||
#include <mangle/sound/clients/ogre_output_updater.hpp>
|
||||
|
||||
#include <components/file_finder/file_finder.hpp>
|
||||
#include <components/esm_store/store.hpp>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
@ -74,12 +74,17 @@ namespace MWSound
|
|||
Mangle::Sound::OgreListenerMover cameraTracker;
|
||||
|
||||
const ESMS::ESMStore &store;
|
||||
std::string dir;
|
||||
|
||||
typedef std::map<std::string,Mangle::Sound::WSoundPtr> IDMap;
|
||||
typedef std::map<MWWorld::Ptr,IDMap> PtrMap;
|
||||
PtrMap sounds;
|
||||
|
||||
// This is used for case insensitive and slash-type agnostic file
|
||||
// finding. It takes DOS paths (any case, \\ slashes or / slashes)
|
||||
// relative to the sound dir, and translates them into full paths
|
||||
// of existing files in the filesystem, if they exist.
|
||||
FileFinder::FileFinder files;
|
||||
|
||||
SoundImpl(Ogre::Root *root, Ogre::Camera *camera,
|
||||
const ESMS::ESMStore &str,
|
||||
const std::string &soundDir)
|
||||
|
@ -87,6 +92,7 @@ namespace MWSound
|
|||
, updater(mgr)
|
||||
, cameraTracker(mgr)
|
||||
, store(str)
|
||||
, files(soundDir)
|
||||
{
|
||||
cout << "Sound output: " << SOUND_OUT << endl;
|
||||
cout << "Sound decoder: " << SOUND_IN << endl;
|
||||
|
@ -96,21 +102,20 @@ namespace MWSound
|
|||
|
||||
// Tell Ogre to update the sound system each frame
|
||||
root->addFrameListener(&updater);
|
||||
}
|
||||
|
||||
dir = soundDir + "/";
|
||||
bool hasFile(const std::string &str)
|
||||
{
|
||||
return files.has(str);
|
||||
}
|
||||
|
||||
// Convert a Morrowind sound path (eg. Fx\funny.wav) to full path
|
||||
// with proper slash conversion (eg. datadir/Sound/Fx/funny.wav)
|
||||
std::string convertPath(const std::string &str)
|
||||
{
|
||||
std::string file = dir + str;
|
||||
#ifndef WIN32
|
||||
// Actually / path separators should work in Windows too, they
|
||||
// just aren't necessary.
|
||||
std::replace(file.begin(), file.end(), '\\', '/');
|
||||
#endif
|
||||
return file;
|
||||
if(hasFile(str))
|
||||
return files.lookup(str);
|
||||
return "";
|
||||
}
|
||||
|
||||
// Convert a soundId to file name, and modify the volume
|
||||
|
@ -277,7 +282,10 @@ namespace MWSound
|
|||
{
|
||||
// The range values are not tested
|
||||
if(!mData) return;
|
||||
mData->add(mData->convertPath(filename), ptr, "_say_sound", 1, 1, 100, 10000, false);
|
||||
if(mData->hasFile(filename))
|
||||
mData->add(mData->convertPath(filename), ptr, "_say_sound", 1, 1, 100, 10000, false);
|
||||
else
|
||||
cout << "Sound file " << filename << " not found, skipping.\n";
|
||||
}
|
||||
|
||||
bool SoundManager::sayDone (MWWorld::Ptr ptr) const
|
||||
|
|
62
components/file_finder/file_finder.hpp
Normal file
62
components/file_finder/file_finder.hpp
Normal file
|
@ -0,0 +1,62 @@
|
|||
#ifndef FILE_FINDER_MAIN_H
|
||||
#define FILE_FINDER_MAIN_H
|
||||
|
||||
#include "search.hpp"
|
||||
#include "filename_less.hpp"
|
||||
#include <map>
|
||||
|
||||
namespace FileFinder
|
||||
{
|
||||
|
||||
class FileFinder
|
||||
{
|
||||
std::map<std::string, std::string, path_less> table;
|
||||
|
||||
struct Inserter : ReturnPath
|
||||
{
|
||||
FileFinder *owner;
|
||||
int cut;
|
||||
|
||||
void add(const boost::filesystem::path &pth)
|
||||
{
|
||||
std::string file = pth.file_string();
|
||||
std::string key = file.substr(cut);
|
||||
owner->table[key] = file;
|
||||
}
|
||||
};
|
||||
|
||||
Inserter inserter;
|
||||
|
||||
public:
|
||||
FileFinder(const boost::filesystem::path &path, bool recurse=true)
|
||||
{
|
||||
inserter.owner = this;
|
||||
|
||||
// Remember the original path length, so we can cut it away from
|
||||
// the relative paths used as keys
|
||||
std::string pstring = path.file_string();
|
||||
inserter.cut = pstring.size();
|
||||
|
||||
// If the path does not end in a slash, then boost will add one
|
||||
// later, which means one more character we have to remove.
|
||||
char last = pstring[pstring.size()-1];
|
||||
if(last != '\\' && last != '/')
|
||||
inserter.cut++;
|
||||
|
||||
// Fill the map
|
||||
find(path, inserter, recurse);
|
||||
}
|
||||
|
||||
bool has(const std::string& file) const
|
||||
{
|
||||
return table.find(file) != table.end();
|
||||
}
|
||||
|
||||
// Find the full path from a relative path.
|
||||
const std::string &lookup(const std::string& file) const
|
||||
{
|
||||
return table.find(file)->second;
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
49
components/file_finder/filename_less.hpp
Normal file
49
components/file_finder/filename_less.hpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
#ifndef FILE_FINDER_LESS_H
|
||||
#define FILE_FINDER_LESS_H
|
||||
|
||||
#include <libs/platform/strings.h>
|
||||
#include <string>
|
||||
|
||||
namespace FileFinder{
|
||||
|
||||
// Used for maps of file paths. Compares file paths, but ignores case
|
||||
// AND treats \ and / as the same character.
|
||||
struct path_less
|
||||
{
|
||||
int compareChar(char a, char b) const
|
||||
{
|
||||
if(a>b) return 1;
|
||||
else if(a<b) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int comparePathChar(char a, char b) const
|
||||
{
|
||||
if(a >= 'a' && a <= 'z') a += 'A'-'a';
|
||||
else if(a == '\\') a = '/';
|
||||
if(b >= 'a' && b <= 'z') b += 'A'-'a';
|
||||
else if(b == '\\') b = '/';
|
||||
return compareChar(a,b);
|
||||
}
|
||||
|
||||
int compareString(const char *a, const char *b) const
|
||||
{
|
||||
while(*a && *b)
|
||||
{
|
||||
int i = comparePathChar(*a,*b);
|
||||
if(i != 0) return i;
|
||||
a++; b++;
|
||||
}
|
||||
// At this point, one or both of the chars is a null terminator.
|
||||
// Normal char comparison will get the correct final result here.
|
||||
return compareChar(*a,*b);
|
||||
}
|
||||
|
||||
bool operator() (const std::string& a, const std::string& b) const
|
||||
{
|
||||
return compareString(a.c_str(), b.c_str()) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
28
components/file_finder/search.cpp
Normal file
28
components/file_finder/search.cpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#include "search.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost::filesystem;
|
||||
|
||||
void FileFinder::find(const path & dir_path, ReturnPath &ret, bool recurse)
|
||||
{
|
||||
if ( !exists( dir_path ) )
|
||||
{
|
||||
cout << "Path " << dir_path << " not found\n";
|
||||
return;
|
||||
}
|
||||
|
||||
directory_iterator end_itr; // default construction yields past-the-end
|
||||
for ( directory_iterator itr(dir_path);
|
||||
itr != end_itr;
|
||||
++itr )
|
||||
{
|
||||
if ( is_directory( *itr ) )
|
||||
{
|
||||
if(recurse) find(*itr, ret);
|
||||
}
|
||||
else
|
||||
ret.add(*itr);
|
||||
}
|
||||
}
|
20
components/file_finder/search.hpp
Normal file
20
components/file_finder/search.hpp
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef FILE_FINDER_SEARCH_H
|
||||
#define FILE_FINDER_SEARCH_H
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace FileFinder
|
||||
{
|
||||
struct ReturnPath
|
||||
{
|
||||
virtual void add(const boost::filesystem::path &pth) = 0;
|
||||
};
|
||||
|
||||
/** Search the given path and return all file paths through 'ret'. If
|
||||
recurse==true, all files in subdirectories are returned as well.
|
||||
*/
|
||||
void find(const boost::filesystem::path & dir_path, ReturnPath &ret, bool recurse=true);
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue