From: <wel...@us...> - 2011-06-13 20:19:25
|
Revision: 7406 http://planeshift.svn.sourceforge.net/planeshift/?rev=7406&view=rev Author: weltall2 Date: 2011-06-13 20:19:19 +0000 (Mon, 13 Jun 2011) Log Message: ----------- other missing end lines. why msvc doesn't add those? Modified Paths: -------------- trunk/src/plugins/common/soundmanager/soundmanager.cpp trunk/src/plugins/common/soundmanager/soundmanager.h Modified: trunk/src/plugins/common/soundmanager/soundmanager.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/soundmanager.cpp 2011-06-13 20:18:08 UTC (rev 7405) +++ trunk/src/plugins/common/soundmanager/soundmanager.cpp 2011-06-13 20:19:19 UTC (rev 7406) @@ -967,4 +967,4 @@ sectorData.DeleteAll(); isSectorLoaded = false; -} \ No newline at end of file +} Modified: trunk/src/plugins/common/soundmanager/soundmanager.h =================================================================== --- trunk/src/plugins/common/soundmanager/soundmanager.h 2011-06-13 20:18:08 UTC (rev 7405) +++ trunk/src/plugins/common/soundmanager/soundmanager.h 2011-06-13 20:19:19 UTC (rev 7406) @@ -197,4 +197,4 @@ }; -#endif // __SOUNDMANAGER_H__ \ No newline at end of file +#endif // __SOUNDMANAGER_H__ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wha...@us...> - 2011-12-12 03:15:14
|
Revision: 7808 http://planeshift.svn.sourceforge.net/planeshift/?rev=7808&view=rev Author: whacko88 Date: 2011-12-12 03:15:07 +0000 (Mon, 12 Dec 2011) Log Message: ----------- Various fixes to SoundData - fixed cache and better memory usage - fixed coding standards - updated doc - renamed to SoundDataCache Modified Paths: -------------- trunk/src/plugins/common/soundmanager/data.cpp trunk/src/plugins/common/soundmanager/data.h trunk/src/plugins/common/soundmanager/handle.cpp trunk/src/plugins/common/soundmanager/instrument.cpp trunk/src/plugins/common/soundmanager/manager.cpp trunk/src/plugins/common/soundmanager/manager.h Modified: trunk/src/plugins/common/soundmanager/data.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/data.cpp 2011-12-12 00:10:28 UTC (rev 7807) +++ trunk/src/plugins/common/soundmanager/data.cpp 2011-12-12 03:15:07 UTC (rev 7808) @@ -27,67 +27,47 @@ #include <iutil/cfgmgr.h> -SoundFile::SoundFile(const char* newname, const char* newfilename) +SoundFile::SoundFile(const char* newName, const char* newFileName) { - name = csString(newname); - filename = csString(newfilename); - loaded = false; - snddata = NULL; - lasttouch = csGetTicks(); + name = csString(newName); + fileName = csString(newFileName); + sndData = 0; + lastTouch = csGetTicks(); } -SoundFile::SoundFile(SoundFile* const ©that) +SoundFile::SoundFile(SoundFile* const ©SoundFile) { - name = csString(copythat->name); - filename = csString(copythat->filename); - loaded = false; - snddata = NULL; - lasttouch = csGetTicks(); + name = csString(copySoundFile->name); + fileName = csString(copySoundFile->fileName); + sndData = 0; + lastTouch = csGetTicks(); } SoundFile::~SoundFile() { } -/* - * SndData is a set of functions to help us load and unload sounds - * simple interface - */ -SoundData::SoundData() +//-------------------------------------------------- + + +SoundDataCache::SoundDataCache() { } -SoundData::~SoundData() +SoundDataCache::~SoundDataCache() { - csArray<SoundFile*> allsoundfiles; - - allsoundfiles = soundfiles.GetAll(); - - for(size_t i = 0; i < allsoundfiles.GetSize(); i++) - { - delete allsoundfiles[i]; - } - - soundfiles.DeleteAll(); - UnloadSoundLib(); } -/* - * Initializes a loader and vfs - * if one of both fails it will return false - */ - -bool SoundData::Initialize(iObjectRegistry* objectReg) +bool SoundDataCache::Initialize(iObjectRegistry* objectReg) { - if(!(sndloader = csQueryRegistry<iSndSysLoader>(objectReg))) + if(!(sndLoader = csQueryRegistry<iSndSysLoader>(objectReg))) { Error1("Failed to locate Sound loader!"); return false; } - if(!(vfs = csQueryRegistry<iVFS>(objectReg))) { Error1("psSndSourceMngr: Could not initialize. Cannot find iVFS"); @@ -98,7 +78,7 @@ csRef<iConfigManager> configManager = csQueryRegistry<iConfigManager>(objectReg); if(configManager != 0) { - cacheTime = configManager->GetInt("Planeshift.Sound.DataCacheTime", DEFAULT_SOUNDFILE_CACHETIME); + cacheTime = configManager->GetInt("PlaneShift.Sound.DataCacheTime", DEFAULT_SOUNDFILE_CACHETIME); } else { @@ -108,147 +88,127 @@ return true; } -/* - * Loads a soundfile into a given buffer - * it checks if we have the resource and loads it if its not already loaded - */ - -bool SoundData::LoadSoundFile(const char* name, csRef<iSndSysData> &snddata) +bool SoundDataCache::GetSoundData(const char* name, csRef<iSndSysData> &sndData) { - SoundFile* snd; - csRef<iDataBuffer> soundbuf; + SoundFile* soundFile; - if((snd = GetSound(name)) != NULL) + // check if it's cached and load it if it's not + soundFile = loadedSoundFiles.Get(name, 0); + if(soundFile == 0) { - /* Sound exists in "known or loaded state - * get the sound with GetSound - * check if its already loaded .. - * return true if it is - * if not load it and mark it loaded - */ - if(snd->loaded == true) - { - snddata = snd->snddata; - return true; - } + soundFile = LoadSoundFile(name); } - else - { - // maybe this is a dynamic file create a handle and push it into our array - snd = new SoundFile(name, name); - PutSound(snd); - } - /* load the sounddata into a buffer */ - if(!(soundbuf = vfs->ReadFile(snd->filename))) + // the file doesn't exist + if(soundFile == 0) { - Error2("Can't load file '%s'!", name); /* FIXME */ return false; } - /* extract sound from data */ - if(!(snddata = sndloader->LoadSound(soundbuf))) - { - Error2("Can't load sound '%s'!", name); - return false; - } + // update lastTouch to keep the SoundFile in the cache + soundFile->lastTouch = csGetTicks(); - snd->loaded = true; - snd->snddata = snddata; + sndData = soundFile->sndData; return true; } -/* - * This method unloads the given soundname - * it DOES it. It doesnt care if its still used or not! - */ - -void SoundData::UnloadSoundFile(const char* name) +void SoundDataCache::UnloadSoundFile(const char* name) { - // do *not* use GetSound here as it potentially creates - // a new sound, why would we want to create a new one - // upon deletion? - SoundFile* sound = soundfiles.Get(csHashCompute(name), NULL); - if(sound) + SoundFile* soundFile = loadedSoundFiles.Get(name, 0); + if(soundFile != 0) { - DeleteSound(sound); + // this decrement the reference of csRef and delete if it's 0 + soundFile->sndData.Invalidate(); + loadedSoundFiles.Delete(name, soundFile); } - - return; } -/* - * Returns the requested sound if it exists in our library or cache - * NULL if it doesnt - */ - -SoundFile* SoundData::GetSound(const char* name) +SoundFile* SoundDataCache::LoadSoundFile(const char* name) { - SoundFile* sound; + SoundFile* soundFile; + csRef<iDataBuffer> soundBuf; + bool error = false; + bool isDynamic = false; - sound = soundfiles.Get(csHashCompute(name), NULL); + // checking the sound library + soundFile = libSoundFiles.Get(name, 0); + if(soundFile == 0) // maybe this is a dynamic file + { + soundFile = new SoundFile(name, name); + isDynamic = true; + } - // sound is null when theres no cached SoundFile - if(sound == NULL) + // checking if the file is already loaded + if(soundFile->sndData.IsValid()) { - // we go search the library .. maybe it has it - if(libsoundfiles.Contains(csHashCompute(name))) + return soundFile; + } + + // loading the data into a buffer + soundBuf = vfs->ReadFile(soundFile->fileName); + if(soundBuf != 0) + { + // extracting sound data from the buffer + soundFile->sndData = sndLoader->LoadSound(soundBuf); + if(!soundFile->sndData.IsValid()) { - // SoundFile is in our library, copy it - sound = new SoundFile(libsoundfiles.Get(csHashCompute(name), NULL)); - PutSound(sound); + Error2("Can't load sound '%s'!", name); + error = true; } - else + } + else + { + Error2("Can't load file '%s'!", name); + error = true; + } + + // handling errors + if(error) + { + if(isDynamic) // file is not in the library { - // no such SoundFile ;( return NULL - return NULL; + delete soundFile; } + + return 0; } - // update lasttouch to keep that SoundFile in memory - sound->lasttouch = csGetTicks(); - return sound; -} + // keeping track of the loaded files + loadedSoundFiles.Put(name, soundFile); + if(isDynamic) // new file in the library + { + libSoundFiles.Put(name, soundFile); + } -void SoundData::PutSound(SoundFile* &sound) -{ - // i know theres PutUnique but i have a bad feeling about overwriting - soundfiles.Put(csHashCompute((const char*) sound->name), sound); + return soundFile; } -void SoundData::DeleteSound(SoundFile* &sound) +void SoundDataCache::Update() { - // do *not* delete all, but only the *specific* one as we don't check - // for an existing key upon putting by maybe deleting a duplicate - // deleting all here may result in a memory leak - soundfiles.Delete(csHashCompute((const char*)sound->name), sound); - delete sound; -} - -void SoundData::Update() -{ csTicks now; - csArray<SoundFile*> allsoundfiles; - SoundFile* sound; + SoundFile* soundFile; + csArray<SoundFile*> allSoundFiles; // FIXME csticks now = csGetTicks(); - allsoundfiles = soundfiles.GetAll(); + allSoundFiles = loadedSoundFiles.GetAll(); - for(size_t i = 0; i < allsoundfiles.GetSize(); i++) + for(size_t i = 0; i < allSoundFiles.GetSize(); i++) { - sound = allsoundfiles[i]; + soundFile = allSoundFiles[i]; - if((sound->lasttouch + cacheTime) <= now - && sound->loaded == true - && sound->snddata->GetRefCount() == 1) + // checking if SoundDataCache is the only one that reference to the data + if(soundFile->sndData->GetRefCount() == 1) { - // UnloadSoundFile takes "names" as arguments and works on our hash - UnloadSoundFile(sound->name); + // checking if the cache time has elapsed + if(soundFile->lastTouch + cacheTime <= now) + { + UnloadSoundFile(soundFile->name); + } } - else + else // data is still in use { - sound->lasttouch = csGetTicks(); + soundFile->lastTouch = csGetTicks(); } } } @@ -256,16 +216,10 @@ //----------- code below needs its own class --------------------// /* - * loads soundlib.xml get all the names and filenames - * store them in the hash "soundfiles" - * - * i think we could load all the sounds right now but i fear that this - * could eat a lot of memory - * reload should be possible but im too lazy right now - * + * Reads the xml sound library, gets all the names and paths and store them in the + * hash "libSoundFiles". Files will be loaded only if needed. */ - -bool SoundData::LoadSoundLib(const char* filename, iObjectRegistry* objectReg) +bool SoundDataCache::LoadSoundLib(const char* fileName, iObjectRegistry* objectReg) { csRef<iDocumentSystem> xml; /* try get existing Document System or create one*/ csRef<iDataBuffer> buff; /* buffer for reading the xml */ @@ -280,7 +234,7 @@ if(!(xml = csQueryRegistry<iDocumentSystem>(objectReg))) xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem); - buff = vfs->ReadFile(filename); + buff = vfs->ReadFile(fileName); if(!buff || !buff->GetSize()) { @@ -292,7 +246,7 @@ error = doc->Parse(buff); if(error) { - Error3("Parsing file %s gave error %s", filename, error); + Error3("Parsing file %s gave error %s", fileName, error); return false; } @@ -324,23 +278,26 @@ snd = new SoundFile(node->GetAttributeValue("name"), node->GetAttributeValue("file")); - libsoundfiles.Put(csHashCompute((const char*) snd->name), snd); - } + libSoundFiles.Put(snd->name, snd); + } } return true; } -void SoundData::UnloadSoundLib() +void SoundDataCache::UnloadSoundLib() { - csArray<SoundFile*> allsoundfiles; + // deleting sound files + csHash<SoundFile*, csString>::GlobalIterator soundFileIter(libSoundFiles.GetIterator()); + SoundFile* soundFile; - allsoundfiles = libsoundfiles.GetAll(); - - for(size_t i = 0; i < allsoundfiles.GetSize(); i++) + while(soundFileIter.HasNext()) { - delete allsoundfiles[i]; + soundFile = soundFileIter.Next(); + delete soundFile; } - - libsoundfiles.DeleteAll(); + + // unloading sound library + libSoundFiles.DeleteAll(); + loadedSoundFiles.DeleteAll(); } Modified: trunk/src/plugins/common/soundmanager/data.h =================================================================== --- trunk/src/plugins/common/soundmanager/data.h 2011-12-12 00:10:28 UTC (rev 7807) +++ trunk/src/plugins/common/soundmanager/data.h 2011-12-12 03:15:07 UTC (rev 7808) @@ -21,73 +21,9 @@ * */ -#ifndef _SOUND_DATA_H_ -#define _SOUND_DATA_H_ +#ifndef _SOUND_DATA_CACHE_H_ +#define _SOUND_DATA_CACHE_H_ -/* - * i still have to make this doxygen compatible .. please dont mock me - * but i need to get this story out of my head and into this file - * - * How SoundData works: (Birth till Death) - * - * Birth: - * - * On Initialization it aquires references to vfs and a loader. - * It returns false if it fails and no further checking is done. - * - * On succes the very first thing that may happen is that LoadSoundLib is called. - * It fills libsoundfiles with the data it found in soundlib.xml - * Even if not called we can still process requests for filenames within our vfs. - * - * We assume LoadSoundLib has been called and the library is filled. - * - * Now Someone calls LoadSoundFile to load a named resource or file - * the one that calls expects a pointer to the SoundFile he requested - * depending on how succesfull this is LoadSoundFile will fill it in and return - * true or false. - * - * GetSound is called and GetSound will search if theres a cached - * SoundFile or if theres a unloaded resource in our soundlib. - * if its cached then it will return that one. Thats best case - * because LoadSoundFile can return a pointer to the cached data. - * If its in our soundlib, then GetSound will make a copy and put that into our cache - * (using PutSound) on succes it will return a Pointer to a valid SoundFile - * on failure it will return NULL. - * - * GetSound may return NULL. In that case LoadSoundfile creates a new SoundFile - * (object) with the given name as filename to check if we got a (dynamic) - * file as name. - * That happens if we are playing voicefiles. Those are downloaded from the server - * and thus do not exist in our libraray. PutSound is used to add it to the cache. - * - * However theres always a valid SoundFile (object) for our loader - * Now LoadSoundFile tries to load that file (finally). - * There are two cases: - * 1) file exists and is loadable (succes .. return true) - * 2) file doesnt exist or ISNT loadable (failure .. return false) - * - * case 1) means that loaded (a bool) is set to true and snddata valid - * case 2) loaded remains false and snddata is invalid / NULL - * - * LoadSoundFile has returned and the caller - * might now do whatever he wanted todo with that snddata. - * - * Death: - * - * SoundData has a Update method that checks if there are expired SoundFiles - * there's a default caching time of 300 seconds. After 300 seconds it will - * check if there are still references on the snddata our SoundFile provides. - * If theres only one then its the SoundFile object itself. - * That means we go ahead and delete that object using DeleteSound. - * - * Now sometimes it isnt that easy ;) Maybe thats a looping background sound - * in that case our RefCount is at last higher then one. - * We set lasttouch to current ticks .. and check again .. in 300 seconds ;) - * - * Anyway UnloadSound is a public method and thus someone may call it for any - * reason. Be aware! - * It will crash your program if you unload data which is still in use ;) - */ //==================================================================================== // Crystal Space Includes @@ -102,121 +38,148 @@ #define DEFAULT_SOUNDFILE_CACHETIME 300000 + /** - * Class that contains the most important informations about a soundfile - * It contains the name, filename and if loaded the data. - * its used by @see SoundData to manage our SoundFile(s). + * This struct keeps the information about a sound file. + * @see SoundDataCache, the class that uses this struct. */ - -class SoundFile +struct SoundFile { public: - csString name; ///< name of this file/resource MUST be unique - csString filename; ///< filename in our vfs (maybe not unique) - csRef<iSndSysData> snddata; ///< data in suitable format - bool loaded; ///< true if snddata is loaded, false if not - csTicks lasttouch; ///< last time when this SoundFile was used/touched + csString name; ///< Identifier of this file/resource. MUST be unique. + csString fileName; ///< File's name in our vfs. It doesn't need to be unique. + csRef<iSndSysData> sndData; ///< Data in suitable format. + csTicks lastTouch; ///< Last time when this SoundFile was used/touched. /** * Constructs a SoundFile. - * @param newname name of this SoundFile (must be unique) - * @param newfilename filename this SoundFile is using + * @param newName identifier of this SoundFile (must be unique). + * @param newFileName file's name this SoundFile is using. */ - SoundFile(const char* newname, const char* newfilename); + SoundFile(const char* newName, const char* newFileName); + /** - * Copy Constructor. - * Copys the whole SoundFile. + * Copy constructor. It copies the whole SoundFile. + * @param copySoundFile SoundFile to copy. */ - SoundFile(SoundFile* const ©that); + SoundFile(SoundFile* const ©SoundFile); + /** * Destructor. */ ~SoundFile(); }; + +//-------------------------------------------------- + + /** - * SoundData is the datakeeper of @see SoundSystemManager. - * It loads and unloads all Soundfiles and provides a simple caching - * mechanism. + * SoundDataCache is the data-keeper of SoundSystemManager. It loads and unloads all + * sound files and provides a simple caching mechanism. + * + * Birth: + * After the object creation, it should be called the method Initialize in order to + * aquire references to the virtual file system and the CS sound loader. If a sound + * library is present it should be loaded with LoadSoundLib. + * + * Usage: + * Sounds can be retrieved with GetSoundData. The provided iSndSysData should always + * be used with a csRef since the reference counting is checked to determine if the + * sound is still in use or not. Referencing the sound data with a normal pointer + * could cause the application to crash by ending up with pointing to an object that + * the cache has destroyed. + * + * Cache: + * The data is cached and unloaded when it is not referenced anymore and the time + * given in the configuration option "PlaneShift.Sound.DataCacheTime" has elapsed. + * One can force the cache to unload a sound with UnloadSoundFile if it is known + * that the sound won't be used again. + * + * Death: + * It is not necessary to call UnloadSoundLib. The destructor takes care of it too. */ - -class SoundData +class SoundDataCache { public: /** - * Constructor .. empty. - * Initialization is done via Initialize because its not guaranteed - * that its successful. + * Constructor. Initialization is done via Initialize because it's not guaranteed + * that it's successful. */ - SoundData(); + SoundDataCache(); + /** - * Deconstructor. - * Unloads everything and destroys all SoundFile object. + * Deconstructor. Unloads everything and destroys all SoundFile objects. */ - ~SoundData(); + ~SoundDataCache(); + /** - * Initializes Loader and VFS. - * Will return true on success and false if not. - * @param objectReg objectReg to get references to iVFS and iSndSysLoader + * Initializes CS iSndSysLoader and look for the VFS. + * @param objectReg iObjectRegistry to get references to iVFS and iSndSysLoader. + * @return true on success, false otherwise. */ bool Initialize(iObjectRegistry* objectReg); + /** - * Reads soundlib.xml and creates reference SoundFile objects. - * It fills the private hash with unloaded SoundFile objects. - * Those will be copied and loaded if needed - * @param filename filename to load - * @param objectReg ps objectreg because we need iDocumentSystem + * Reads information contained in the given sound library XML file. + * @param fileName the path to the XML sound library file. + * @param objectReg ps iObjectRegistry because we need iDocumentSystem. + * @return true on success, false otherwise. */ - bool LoadSoundLib(const char* filename, iObjectRegistry* objectReg); + bool LoadSoundLib(const char* fileName, iObjectRegistry* objectReg); + /** - * Unloads everything LoadSoundLib created. - * Will purge the hash and delete all reference SoundFile objects. + * Unloads everything LoadSoundLib created and clean the cache. */ void UnloadSoundLib(); + /** - * Loads a soundfile out of the vfs. - * The file given by name will be loaded into a iSndSysData object. - * @param name filename to load - * @param snddata iSndSysData object to write the data into + * Fetches a sound data from the cache and loads it from the VFS if necessary. If + * the sound is not in the sound library then it considers the parameter "name" as + * a path in the VFS and it tries to load the data from there. + * @attention always use the provided iSndSysData with a csRef since the reference + * counting is used to determine if the sound is still in use or not. Referencing + * the sound data with a normal pointer could cause the application to crash by + * ending up with pointing to an object that the cache has destroyed. + * @param name the name of the sound to fetch (or its path if it is not in the + * library. + * @param sndData object that will contain the sound data at the end. + * @return true on success, false if the sound data couldn't be retrieved. */ - bool LoadSoundFile(const char* name, csRef<iSndSysData> &snddata); + bool GetSoundData(const char* name, csRef<iSndSysData> &sndData); + /** - * Unloads a soundfile and deletes its snddata object. - * The Soundfile given by name will be unloaded. Be careful with this one! - * It doesnt check if its still in use. - * @param name SoundFile by name + * Forces the cache to unload and delete the data of the given sound from the + * memory, no matter if it's still in use or not. + * @param namethe name of the sound to unload. */ void UnloadSoundFile(const char* name); + /** - * Checks usage of all SoundFile objects and unloads them if appropriate. - * Each SoundFile has a Timestamp and a Refcount that help to determine - * if it can be freed. Unload happens if its Cachetime is expired if its - * RefCount is 1. RefCount 1 means were the one that holds it. + * Checks the reference counting to sounds to determine if they are still in use + * or not. Unloads the sound data that has not been used for the time specified + * in the configuration option "PlaneShift.Sound.DataCacheTime". */ void Update(); private: - csRef<iSndSysLoader> sndloader; ///< Crystalspace soundloader - csHash<SoundFile*> soundfiles; ///< Hash of loaded SoundFiles - csHash<SoundFile*> libsoundfiles; ///< Hash of Resources soundlib.xml provides - csRef<iVFS> vfs; ///< vfs where were reading from - - uint cacheTime; ///< number of milliseconds a file remains cached + uint cacheTime; ///< Number of milliseconds a file remains cached. + csRef<iVFS> vfs; ///< VFS used to retrieve the sound library. + csRef<iSndSysLoader> sndLoader; ///< Crystal Space sound loader. + csHash<SoundFile*, csString> libSoundFiles; ///< Maps the sounds' identifiers with their data. + csHash<SoundFile*, csString> loadedSoundFiles; ///< Hash of loaded SoundFiles. /** - * Fetches a SoundFile object out of our cache. - * @param name Name of the SoundFile we are searching. + * Load the sound data into a SoundFile from the VFS (if not already loaded). If + * the sound is not in libSoundFiles then it considers the parameter "name" as a + * path in the VFS and it tries to load the data from there. This is useful for + * dynamically generated sounds (downloaded from the server for example). + * @param name the name of the sound we are searching (or its path if it is not + * in the library. + * @return a pointer to the loaded SoundFile or 0 if the data couldn't be loaded. */ - SoundFile* GetSound(const char* name); - /** - * Adds a SoundFile object to our cache. - */ - void PutSound(SoundFile* &sound); - /** - * Delete a SoundFile and deletes it from our hash. - */ - void DeleteSound(SoundFile* &sound); + SoundFile* LoadSoundFile(const char* name); }; -#endif /*_SOUND_DATA_H_*/ +#endif // _SOUND_DATA_CACHE_H_ Modified: trunk/src/plugins/common/soundmanager/handle.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/handle.cpp 2011-12-12 00:10:28 UTC (rev 7807) +++ trunk/src/plugins/common/soundmanager/handle.cpp 2011-12-12 03:15:07 UTC (rev 7808) @@ -98,14 +98,14 @@ { csRef<iSndSysData> snddata; - if(!SoundSystemManager::GetSingleton().GetSoundData()->LoadSoundFile(resname, snddata)) + if(!SoundSystemManager::GetSingleton().GetSoundDataCache()->GetSoundData(resname, snddata)) { return false; } if(!SoundSystemManager::GetSingleton().GetSoundSystem()->CreateStream(snddata, loop, type, sndstream)) { - SoundSystemManager::GetSingleton().GetSoundData()->UnloadSoundFile(resname); + SoundSystemManager::GetSingleton().GetSoundDataCache()->UnloadSoundFile(resname); return false; } Modified: trunk/src/plugins/common/soundmanager/instrument.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/instrument.cpp 2011-12-12 00:10:28 UTC (rev 7807) +++ trunk/src/plugins/common/soundmanager/instrument.cpp 2011-12-12 03:15:07 UTC (rev 7808) @@ -257,7 +257,7 @@ } // loading data - if(!SoundSystemManager::GetSingleton().GetSoundData()->LoadSoundFile(fileName, noteData)) + if(!SoundSystemManager::GetSingleton().GetSoundDataCache()->GetSoundData(fileName, noteData)) { return false; } Modified: trunk/src/plugins/common/soundmanager/manager.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/manager.cpp 2011-12-12 00:10:28 UTC (rev 7807) +++ trunk/src/plugins/common/soundmanager/manager.cpp 2011-12-12 03:15:07 UTC (rev 7808) @@ -67,17 +67,17 @@ playerPosition.Set(0.0); playerVelocity.Set(0.0); - // Create a new SoundSystem, SoundData Instance and the main SoundControl + // Create a new SoundSystem, SoundDataCache Instance and the main SoundControl soundSystem = new SoundSystem; - soundData = new SoundData; + soundDataCache = new SoundDataCache; mainSndCtrl = new SoundControl(-1, iSoundControl::NORMAL); defaultSndCtrl = new SoundControl(-1, iSoundControl::NORMAL); if(soundSystem->Initialize(objectReg) - && soundData->Initialize(objectReg)) + && soundDataCache->Initialize(objectReg)) { // FIXME what if soundlib.xml doesnt exist? - soundData->LoadSoundLib(soundLib, objectReg); + soundDataCache->LoadSoundLib(soundLib, objectReg); LastUpdateTime = csGetTicks(); Initialised = true; } @@ -116,7 +116,7 @@ delete mainSndCtrl; delete defaultSndCtrl; delete soundSystem; - delete soundData; + delete soundDataCache; } @@ -142,7 +142,7 @@ { UpdateSound(); // make a update on sounddata to check if there are sounds to unload - soundData->Update(); + soundDataCache->Update(); } } Modified: trunk/src/plugins/common/soundmanager/manager.h =================================================================== --- trunk/src/plugins/common/soundmanager/manager.h 2011-12-12 00:10:28 UTC (rev 7807) +++ trunk/src/plugins/common/soundmanager/manager.h 2011-12-12 03:15:07 UTC (rev 7808) @@ -35,7 +35,7 @@ #include "util/singleton.h" class SoundSystem; -class SoundData; +class SoundDataCache; class SoundHandle; class SoundControl; @@ -77,7 +77,7 @@ /** * Constructor initializes this SoundSystemManager. - * Also initializes a @see SoundSystem and a @see SoundData object. + * Also initializes a @see SoundSystem and a @see SoundDataCache object. * Loads soundlib if presend and set Initialised to true or false (based on success) * You can always assume that this Interface works. BUT Play*Sound functions * will return false if its not Initialised. Be prepared to handle such Error conditions @@ -86,7 +86,7 @@ SoundSystemManager(iObjectRegistry* objectReg); /** * Destructor will remove everything this SoundManager created. - * It will stop and delete all Handles, removes @see SoundData and @see SoundSystem. + * It will stop and delete all Handles, removes @see SoundDataCache and @see SoundSystem. * All Pointers to objects within this Manager becoming invalid (handles SoundControls etc). * Make Sure that you dont use them after destruction. */ @@ -106,7 +106,7 @@ /** * Plays a 2D sound (Cannot be converted to 3D). - * @param name name of the resource you want to play @see SoundData for details + * @param name name of the resource you want to play @see SoundDataCache for details * @param loop LOOP or DONT_LOOP * @param loopstart startframe when looping * @param loopend when reach it will jump to startframe @@ -122,7 +122,7 @@ /** * Plays a 3D sound. - * @param name name of the resource you want to play @see SoundData for details + * @param name name of the resource you want to play @see SoundDataCache for details * @param loop LOOP or DONT_LOOP * @param loopstart startframe when looping * @param loopend when reach it will jump to startframe @@ -187,7 +187,7 @@ /** * Updates this SoundManager and everything its driving. * Consider this as its Mainloop. It does ten updates per second. - * It calls UpdateSound and updates SoundData. + * It calls UpdateSound and updates SoundDataCache. */ void Update(); /** @@ -201,11 +201,11 @@ SoundControl* GetSoundControl(int ctrlID) const; SoundSystem* GetSoundSystem() { return soundSystem; } - SoundData* GetSoundData() { return soundData; } + SoundDataCache* GetSoundDataCache() { return soundDataCache; } private: SoundSystem* soundSystem; - SoundData* soundData; + SoundDataCache* soundDataCache; csHash<SoundHandle*, uint> soundHandles; ///< hash which contains all SoundHandles by id csHash<SoundControl*, int> soundControllers; ///< hash which contains all SoundControls by id @@ -246,7 +246,7 @@ /** * Create a SoundHandle if the given one is null and it initializes it. * - * @param name name of the resource you want to play @see SoundData for details + * @param name name of the resource you want to play @see SoundDataCache for details * @param loop LOOP or DONT_LOOP * @param loopstart startframe when looping * @param loopend when reach it will jump to startframe This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wha...@us...> - 2011-12-12 03:17:37
|
Revision: 7809 http://planeshift.svn.sourceforge.net/planeshift/?rev=7809&view=rev Author: whacko88 Date: 2011-12-12 03:17:31 +0000 (Mon, 12 Dec 2011) Log Message: ----------- fixed couple of warnings fixed memory leak Modified Paths: -------------- trunk/src/plugins/common/soundmanager/instrument.cpp trunk/src/plugins/common/soundmanager/soundctrl.cpp trunk/src/plugins/common/soundmanager/soundmanager.h Modified: trunk/src/plugins/common/soundmanager/instrument.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/instrument.cpp 2011-12-12 03:15:07 UTC (rev 7808) +++ trunk/src/plugins/common/soundmanager/instrument.cpp 2011-12-12 03:17:31 UTC (rev 7809) @@ -274,7 +274,7 @@ } // creating the decoded stream - noteStream = noteData->CreateStream(format, CS_SND3D_ABSOLUTE); + noteStream.AttachNew(noteData->CreateStream(format, CS_SND3D_ABSOLUTE)); noteStream->SetLoopState(CS_SNDSYS_STREAM_DONTLOOP); streamSize = noteStream->GetFrameCount() * (format->Bits / 8) * format->Channels; Modified: trunk/src/plugins/common/soundmanager/soundctrl.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/soundctrl.cpp 2011-12-12 03:15:07 UTC (rev 7808) +++ trunk/src/plugins/common/soundmanager/soundctrl.cpp 2011-12-12 03:17:31 UTC (rev 7809) @@ -114,7 +114,7 @@ { if(volumeDamp > dampPercent) { - volumeDamp -= 0.05; + volumeDamp -= 0.05f; } else { @@ -125,7 +125,7 @@ { if(volumeDamp < 1.0) { - volumeDamp += 0.01; + volumeDamp += 0.01f; } else { Modified: trunk/src/plugins/common/soundmanager/soundmanager.h =================================================================== --- trunk/src/plugins/common/soundmanager/soundmanager.h 2011-12-12 03:15:07 UTC (rev 7808) +++ trunk/src/plugins/common/soundmanager/soundmanager.h 2011-12-12 03:17:31 UTC (rev 7809) @@ -45,7 +45,7 @@ #define DEFAULT_INSTRUMENTS_PATH "/planeshift/art/instruments.xml" #define DEFAULT_AREAS_PATH "/planeshift/soundlib/areas/" #define DEFAULT_COMMON_SECTOR_NAME "common" -#define DEFAULT_DAMPENING_PERCENT 0.1 +#define DEFAULT_DAMPENING_PERCENT 0.1f #define DEFAULT_DAMPENING_CONTROLS "music" /** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wha...@us...> - 2011-12-26 23:26:37
|
Revision: 7916 http://planeshift.svn.sourceforge.net/planeshift/?rev=7916&view=rev Author: whacko88 Date: 2011-12-26 23:26:31 +0000 (Mon, 26 Dec 2011) Log Message: ----------- cleaner initialization of the sound plugin, this should solve once for all crushes when something in the initialization goes wrong cleaned code in SoundSystem fixed coding standards and doc in SoundSystem Modified Paths: -------------- trunk/src/plugins/common/soundmanager/data.cpp trunk/src/plugins/common/soundmanager/handle.cpp trunk/src/plugins/common/soundmanager/songhandle.cpp trunk/src/plugins/common/soundmanager/system.cpp trunk/src/plugins/common/soundmanager/system.h Modified: trunk/src/plugins/common/soundmanager/data.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/data.cpp 2011-12-26 23:22:47 UTC (rev 7915) +++ trunk/src/plugins/common/soundmanager/data.cpp 2011-12-26 23:26:31 UTC (rev 7916) @@ -130,6 +130,12 @@ bool error = false; bool isDynamic = false; + // checking if this has been initialized correctly + if(!sndLoader.IsValid() || !vfs.IsValid()) + { + return 0; + } + // checking the sound library soundFile = libSoundFiles.Get(name, 0); if(soundFile == 0) // maybe this is a dynamic file @@ -231,6 +237,12 @@ csRef<iDocumentNode> node; /* yet another node .... */ SoundFile* snd; ///< soundfile + // checking if this has been initialized correctly + if(!vfs.IsValid()) + { + return false; + } + if(!(xml = csQueryRegistry<iDocumentSystem>(objectReg))) xml = csPtr<iDocumentSystem>(new csTinyDocumentSystem); Modified: trunk/src/plugins/common/soundmanager/handle.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/handle.cpp 2011-12-26 23:22:47 UTC (rev 7915) +++ trunk/src/plugins/common/soundmanager/handle.cpp 2011-12-26 23:26:31 UTC (rev 7916) @@ -109,7 +109,11 @@ return false; } - SoundSystemManager::GetSingleton().GetSoundSystem()->CreateSource(sndstream, sndsource); + if(!SoundSystemManager::GetSingleton().GetSoundSystem()->CreateSource(sndstream, sndsource)) + { + return false; + } + preset_volume = volume_preset; sndCtrl = ctrl; name = csString(resname); @@ -180,13 +184,13 @@ { maxDistance = maxdist; - SoundSystemManager::GetSingleton().GetSoundSystem()->Create3dSource(sndsource, sndsource3d, mindist, maxdist, + SoundSystemManager::GetSingleton().GetSoundSystem()->Create3DSource(sndsource, sndsource3d, mindist, maxdist, pos); /* create a directional source if rad > 0 */ if(rad > 0) { - SoundSystemManager::GetSingleton().GetSoundSystem()->CreateDirectional3dSource(sndsource3d, sndsourcedir, + SoundSystemManager::GetSingleton().GetSoundSystem()->CreateDirectional3DSource(sndsource3d, sndsourcedir, dir, rad); } } Modified: trunk/src/plugins/common/soundmanager/songhandle.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/songhandle.cpp 2011-12-26 23:22:47 UTC (rev 7915) +++ trunk/src/plugins/common/soundmanager/songhandle.cpp 2011-12-26 23:26:31 UTC (rev 7916) @@ -68,7 +68,11 @@ } static_cast<SndSysSongStream*>(&(*sndstream))->SetErrorRate(errorRate); - SoundSystemManager::GetSingleton().GetSoundSystem()->CreateSource(sndstream, sndsource); + if(!SoundSystemManager::GetSingleton().GetSoundSystem()->CreateSource(sndstream, sndsource)) + { + return false; + } + preset_volume = volumePreset; sndCtrl = ctrl; Modified: trunk/src/plugins/common/soundmanager/system.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/system.cpp 2011-12-26 23:22:47 UTC (rev 7915) +++ trunk/src/plugins/common/soundmanager/system.cpp 2011-12-26 23:26:31 UTC (rev 7916) @@ -27,22 +27,19 @@ #include <iutil/cfgmgr.h> -/* - * Get a renderer und returns false or true - */ bool SoundSystem::Initialize(iObjectRegistry* objectReg) { float rollOff; - sndrenderer = csQueryRegistry<iSndSysRenderer>(objectReg); - if(!sndrenderer.IsValid()) + sndRenderer = csQueryRegistry<iSndSysRenderer>(objectReg); + if(!sndRenderer.IsValid()) { Error1("Failed to locate Sound renderer!"); return false; } - listener = sndrenderer->GetListener(); + listener = sndRenderer->GetListener(); if(!listener.IsValid()) { Error1("Failed to get a sound global listener!"); @@ -64,125 +61,129 @@ return true; } -/* - * create a _paused_ stream using a iSndSysData handle - * loop >= 1 .. make it loop - * type can be one of those: - * - * CS_SND3D_DISABLE=0 - * CS_SND3D_RELATIVE=1 - * CS_SND3D_ABSOLUTE=2 - * - * modifications are done on objects to caller gave is - * returns false or true - */ - -bool SoundSystem::CreateStream(csRef<iSndSysData> &snddata, int loop, - int type, csRef<iSndSysStream> &sndstream) +bool SoundSystem::CreateStream(csRef<iSndSysData> &sndData, bool loop, + int type, csRef<iSndSysStream> &sndStream) { - if(!(sndstream = sndrenderer->CreateStream(snddata, type))) + // checking that SoundSystem has been correctly initialized + if(!sndRenderer.IsValid()) { - Error2("Can't create stream for '%s'!", - snddata->GetDescription()); return false; } + // the sound renderer must create the stream and keep track of it + sndStream = sndRenderer->CreateStream(sndData, type); + if(!sndStream.IsValid()) + { + Error2("Can't create stream for '%s'!", sndData->GetDescription()); + return false; + } + // make it loop if requested - if(loop >= 1) + if(loop) { - sndstream->SetLoopState(CS_SNDSYS_STREAM_LOOP); + sndStream->SetLoopState(CS_SNDSYS_STREAM_LOOP); } else { - sndstream->SetLoopState(CS_SNDSYS_STREAM_DONTLOOP); + sndStream->SetLoopState(CS_SNDSYS_STREAM_DONTLOOP); } return true; } -/* - * Removes the given stream - */ +void SoundSystem::RemoveStream(csRef<iSndSysStream> &sndStream) +{ + // checking that SoundSystem has been correctly initialized + if(!sndRenderer.IsValid()) + { + return; + } -void SoundSystem::RemoveStream(csRef<iSndSysStream> &sndstream) -{ - sndrenderer->RemoveStream(sndstream); + // making sound renderer remove the stream from the system + sndRenderer->RemoveStream(sndStream); } -/* - * Creates a source - * if its 2D or 3D depends on the stream - * volume is 1 by default - we set it to 0 - ALWAYS - */ +bool SoundSystem::CreateSource(csRef<iSndSysStream> &sndStream, + csRef<iSndSysSource> &sndSource) +{ + // checking that SoundSystem has been correctly initialized + if(!sndRenderer.IsValid()) + { + return false; + } -bool SoundSystem::CreateSource(csRef<iSndSysStream> &sndstream, - csRef<iSndSysSource> &sndsource) -{ - sndsource = sndrenderer->CreateSource(sndstream); - sndsource->SetVolume(0); + // the sound renderer must create the source and keep track of it + sndSource = sndRenderer->CreateSource(sndStream); + if(!sndSource.IsValid()) + { + Error2("Can't create source for '%s'!", sndStream->GetDescription()); + return false; + } + + // default volume is 1, we set to 0 + sndSource->SetVolume(0); + return true; } -/* - * removeing the source doesnt remove the stream! - * this is important! - */ +void SoundSystem::RemoveSource(csRef<iSndSysSource> &sndSource) +{ + // checking that SoundSystem has been correctly initialized + if(!sndRenderer.IsValid()) + { + return; + } -void SoundSystem::RemoveSource(csRef<iSndSysSource> &sndsource) -{ - sndrenderer->RemoveSource(sndsource); + // making sound renderer remove the source from the system + sndRenderer->RemoveSource(sndSource); } +void SoundSystem::Create3DSource(csRef<iSndSysSource> &sndSource, + csRef<iSndSysSource3D> &sndSource3D, + float minDist, float maxDist, csVector3 pos) +{ + // the renderer keep track of only one source; if the 2D source has been + // created with type != CS_SND3D_DISABLE the it will have this interface + sndSource3D = scfQueryInterface<iSndSysSource3D>(sndSource); -/* - * this creates the 3d source out of an normal source - * we need distance and positional parameters as well as volume - * this thing doesnt make a sound .. yet .. because the stream is still paused - * doesnt need a special remove functions because this is within openal - * use RemoveSource to remove it - */ - -void SoundSystem::Create3dSource(csRef<iSndSysSource> &sndsource, - csRef<iSndSysSource3D> &sndsource3d, - float mindist, float maxdist, csVector3 pos) -{ - sndsource3d = scfQueryInterface<iSndSysSource3D>(sndsource); - sndsource3d->SetMinimumDistance(mindist); - sndsource3d->SetMaximumDistance(maxdist); - sndsource3d->SetPosition(pos); + // setting parameters + sndSource3D->SetMinimumDistance(minDist); + sndSource3D->SetMaximumDistance(maxDist); + sndSource3D->SetPosition(pos); } /* - * create a directional source out of a 3d source - * we need the direction its sending to and the radius(?) of the cone it creates into + * We need the direction its sending to and the radius(?) of the cone it creates into * that direction - experimental - * doesnt need a special remove functions because this is within openal - * use RemoveSource to remove it */ - -void SoundSystem::CreateDirectional3dSource - (csRef<iSndSysSource3D>& /*sndsource3d*/, - csRef<iSndSysSource3DDirectionalSimple> &sndsourcedir, +void SoundSystem::CreateDirectional3DSource + (csRef<iSndSysSource3D>& /*sndSource3D*/, + csRef<iSndSysSource3DDirectionalSimple> &sndSourceDir, csVector3 direction, float rad) { - sndsourcedir->SetDirection(direction); - sndsourcedir->SetDirectionalRadiation(rad); + sndSourceDir->SetDirection(direction); + sndSourceDir->SetDirectionalRadiation(rad); } -/* - * Updates the listener position - * v is position - * f is front - * t is top - */ - void SoundSystem::UpdateListener(csVector3 v, csVector3 f, csVector3 t) { + // checking that SoundSystem has been correctly initialized + if(!listener.IsValid()) + { + return; + } + listener->SetPosition(v); listener->SetDirection(f,t); } -const csVector3& SoundSystem::GetListenerPosition() const +csVector3 SoundSystem::GetListenerPosition() const { + // checking that SoundSystem has been correctly initialized + if(!listener.IsValid()) + { + return csVector3(0, 0, 0); + } + return listener->GetPosition(); } Modified: trunk/src/plugins/common/soundmanager/system.h =================================================================== --- trunk/src/plugins/common/soundmanager/system.h 2011-12-26 23:22:47 UTC (rev 7915) +++ trunk/src/plugins/common/soundmanager/system.h 2011-12-26 23:26:31 UTC (rev 7916) @@ -30,93 +30,104 @@ #define DEFAULT_LISTENER_ROLL_OFF 1.0 + /** - * This is an Interface Class to the Crystalspace Soundrenderer. - * It works like a Wrapper and has some additional functionalities but - * no own data/objects. All it does is simplifying access to the Soundrenderer. + * This is an interface class to the CrystalSpace sound renderer. It works like a + * wrapper and has some additional functionalities but at the moment it hasn't own + * data/objects. All it does is simplifying access to the sound renderer. In the + * future this will be the class that controls the number of active sources. */ - class SoundSystem { public: /** - * initializes this object and tries to load the soundrenderer. - * returns true or false - * @param objectReg ps objectreg where we find our soundrenderer + * Initializes this object by loading the CS sound renderer and creating a + * global listener. + * @param objectReg ps iObjectRegistry used to get the sound renderer. + * @return true on success, false otherwise. */ bool Initialize(iObjectRegistry* objectReg); /** - * Creates a stream out of the given snddata. - * @param snddata valid iSndSysData object - * @param loop LOOP or DONT_LOOP - * @param type 3dtype of this sound CS_SND3D_DISABLE=0 CS_SND3D_RELATIVE=1 or CS_SND3D_ABSOLUTE=2 - * @param sndstream your iSndSysStream object + * Creates a stream out of the given sound data. + * @param sndData valid iSndSysData object. + * @param loop true if the sound must loop, false otherwise. + * @param type 3D type of this sound; it can have these values CS_SND3D_DISABLE=0, + * CS_SND3D_RELATIVE=1 or CS_SND3D_ABSOLUTE=2. + * @param sndStream the iSndSysStream object that will contain the stream. + * @return true on success, false if SoundSystem hasn't been initialized correctly. */ - bool CreateStream(csRef<iSndSysData> &snddata, int loop, int type, - csRef<iSndSysStream> &sndstream); + bool CreateStream(csRef<iSndSysData> &sndData, bool loop, int type, + csRef<iSndSysStream> &sndStream); /** - * Removes a stream. - * @param sndstream iSndSysStream object to remove + * Removes a stream from the sound renderer. + * @param sndStream iSndSysStream object to remove. */ - void RemoveStream(csRef<iSndSysStream> &sndstream); + void RemoveStream(csRef<iSndSysStream> &sndStream); /** - * Create a Source associated to your Stream. - * @param sndstream your iSndSysStream object - * @param sndsource your iSndSysSource object + * Create a source associated to your stream with volume 0. + * @param sndStream your iSndSysStream object. + * @param sndSource the iSndSysSource object that will contain the source. + * @return true on success, false if SoundSystem hasn't been initialized correctly. */ - bool CreateSource(csRef<iSndSysStream> &sndstream, - csRef<iSndSysSource> &sndsource); + bool CreateSource(csRef<iSndSysStream> &sndStream, + csRef<iSndSysSource> &sndSource); /** - * Removes a Source. - * @param sndsource iSndSysSource object to remove + * Removes a source from the sound renderer. + * @attention removing the source doesn't remove its stream! Call RemoveStream for + * that. + * @param sndSource iSndSysSource object to remove. */ - void RemoveSource(csRef<iSndSysSource> &sndsource); + void RemoveSource(csRef<iSndSysSource> &sndSource); /** - * Creates a 3d Source on top of a 2d source. - * Doesnt work of your stream type is CS_SND3D_DISABLE - * @param sndsource your iSndSysSource object - * @param sndsource3d your iSndSysSource3D object - * @param mindist distance when volume is at max - * @param maxdist distance when volume is at min - * @param pos 3d position of this source + * Creates a 3D source on top of a 2D source. It doesn't work if your stream type + * is CS_SND3D_DISABLE. To remove the 3D source it is enough to remove the original + * 2D source. + * @param sndSource your 2D iSndSysSource object. + * @param sndSource3D the iSndSysSource3D that will contain the 3D source. + * @param minDist greatest distance at which the sound is played at maximum volume. + * @param maxDist maximum distance at which the sound can be heard. + * @param pos 3D position of this source. */ - void Create3dSource(csRef<iSndSysSource> &sndsource, - csRef<iSndSysSource3D> &sndsource3d, - float mindist, float maxdist, csVector3 pos); + void Create3DSource(csRef<iSndSysSource> &sndSource, + csRef<iSndSysSource3D> &sndSource3D, + float minDist, float maxDist, csVector3 pos); /** - * Creates a directional source on top of a 3d source. - * @param sndsource3d your iSndSysSource3D object - * @param sndsourcedir your iSndSysSource3DDirectionalSimple object - * @param direction direction this source is emitting to - * @param rad radiation of the directional cone + * Creates a directional source on top of a 3D source. To remove the 3D source it + * is enough to remove the original 2D source. + * @param sndSource3D your iSndSysSource3D object. + * @param sndSourceDir the iSndSysSource3DDirectionalSimple object that will contain + * the directional source. + * @param direction direction this source emits to. + * @param rad radiation of the directional cone. */ - void CreateDirectional3dSource(csRef<iSndSysSource3D> &sndsource3d, - csRef<iSndSysSource3DDirectionalSimple> &sndsourcedir, + void CreateDirectional3DSource(csRef<iSndSysSource3D> &sndSource3D, + csRef<iSndSysSource3DDirectionalSimple> &sndSourceDir, csVector3 direction, float rad); /** - * Updates listener position - * @param v viewpoint or for that matter hearpoint - * @param f front - * @param t top + * Updates listener's position. + * @param v viewpoint or for that matter hearpoint. + * @param f front. + * @param t top. */ void UpdateListener(csVector3 v, csVector3 f, csVector3 t); /** - * Gets the current listener position. - * @return a vector containing the listener position. + * Gets the current listener's position. + * @return a vector containing the listener position. If SoundSystem has not been + * initialized correctly it returns a null vector (0, 0, 0). */ - const csVector3& GetListenerPosition() const; + csVector3 GetListenerPosition() const; private: - csRef<iSndSysRenderer> sndrenderer; ///< soundrenderer were using - csRef<iSndSysListener> listener; ///< our listener object + csRef<iSndSysRenderer> sndRenderer; ///< CrystalSpace sound renderer + csRef<iSndSysListener> listener; ///< global listener }; #endif /*_SOUND_SYSTEM_H_*/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wha...@us...> - 2011-12-26 23:28:24
|
Revision: 7917 http://planeshift.svn.sourceforge.net/planeshift/?rev=7917&view=rev Author: whacko88 Date: 2011-12-26 23:28:18 +0000 (Mon, 26 Dec 2011) Log Message: ----------- expanded entity syntax to deal with more than a sound per state Modified Paths: -------------- trunk/src/plugins/common/soundmanager/psentity.cpp trunk/src/plugins/common/soundmanager/psentity.h trunk/src/plugins/common/soundmanager/pssoundsector.cpp trunk/src/plugins/common/soundmanager/pssoundsector.h Modified: trunk/src/plugins/common/soundmanager/psentity.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/psentity.cpp 2011-12-26 23:26:31 UTC (rev 7916) +++ trunk/src/plugins/common/soundmanager/psentity.cpp 2011-12-26 23:28:18 UTC (rev 7917) @@ -24,47 +24,51 @@ #include "pssound.h" +#include "soundmanager.h" -psEntity::psEntity() +psEntity::psEntity(bool isFactory, const char* name) { - active = false; + isFactoryEntity = isFactory; + entityName = name; + + isActive = false; when = 0; state = 1; id = 0; handle = 0; - minMinRange = 0.0f; - maxMaxRange = 0.0f; + minRange = 0.0f; + maxRange = 0.0f; minTimeOfDayStart = 25; maxTimeOfDayEnd = -1; } psEntity::psEntity(psEntity* const& entity) { - factoryName = entity->factoryName; - meshName = entity->meshName; + isFactoryEntity = entity->isFactoryEntity; + entityName = entity->entityName; - statePar = csHash<StateParameters*, int>(entity->statePar); + states = csHash<EntityState*, int>(entity->states); - // updating statePar references - csHash<StateParameters*, int>::GlobalIterator statIter(statePar.GetIterator()); - StateParameters* sp; + // updating states references + csHash<EntityState*, int>::GlobalIterator statIter(states.GetIterator()); + EntityState* entityState; while(statIter.HasNext()) { - sp = statIter.Next(); - sp->references++; + entityState = statIter.Next(); + entityState->references++; } - active = entity->active; + isActive = entity->isActive; when = entity->when; state = entity->state; id = entity->id; handle = 0; - minMinRange = entity->minMinRange; - maxMaxRange = entity->maxMaxRange; + minRange = entity->minRange; + maxRange = entity->maxRange; minTimeOfDayStart = entity->minTimeOfDayStart; maxTimeOfDayEnd = entity->maxTimeOfDayEnd; } @@ -77,38 +81,66 @@ } // removing state parameters but only if there are no more references - csHash<StateParameters*, int>::GlobalIterator statIter(statePar.GetIterator()); - StateParameters* sp; + csHash<EntityState*, int>::GlobalIterator statIter(states.GetIterator()); + EntityState* entityState; while(statIter.HasNext()) { - sp = statIter.Next(); + entityState = statIter.Next(); - if(sp->references == 1) + if(entityState->references == 1) { - delete sp; + delete entityState; } else { - sp->references--; + entityState->references--; } } - statePar.DeleteAll(); + states.DeleteAll(); } +void psEntity::SetAsMeshEntity(const char* meshName) +{ + if(meshName == 0) + { + return; + } + + isFactoryEntity = false; + entityName = meshName; +} + +void psEntity::SetAsFactoryEntity(const char* factoryName) +{ + if(factoryName == 0) + { + return; + } + + isFactoryEntity = true; + entityName = factoryName; +} + +void psEntity::SetRange(float minDistance, float maxDistance) +{ + minRange = minDistance; + maxRange = maxDistance; +} + float psEntity::GetProbability() const { - StateParameters* sp; + EntityState* entityState; if(state < 0) { return 0.0f; } - sp = statePar.Get(state, 0); + entityState = states.Get(state, 0); - return sp->probability; + return entityState->probability; } uint psEntity::GetMeshID() const @@ -121,52 +153,75 @@ id = identifier; } -bool psEntity::DefineState(int state, const char* resource, const char* startResource, - float volume, float minRange, float maxRange, float probability, - int timeOfDayStart, int timeOfDayEnd, int delayAfter) +bool psEntity::DefineState(csRef<iDocumentNode> stateNode) { - StateParameters* sp; + int stateID; - sp = statePar.Get(state, 0); + EntityState* entityState; + csRef<iDocumentNodeIterator> resourceItr; - if(sp != 0) + // checking if the state ID is legal + stateID = stateNode->GetAttributeValueAsInt("STATE", -1); + if(stateID < 0) { return false; } - - sp = new StateParameters(); - sp->resource = resource; - sp->startResource = startResource; + // initializing the EntityState + entityState = states.Get(state, 0); - sp->volume = volume; - sp->minRange = minRange; - sp->maxRange = maxRange; - sp->probability = probability; - sp->timeOfDayStart = timeOfDayStart; - sp->timeOfDayEnd = timeOfDayEnd; - sp->delayAfter = delayAfter; + if(entityState != 0) // already defined + { + return false; + } + + entityState = new EntityState(); - sp->references = 1; + // initializing resources + resourceItr = stateNode->GetNodes("RESOURCE"); + while(resourceItr->HasNext()) + { + const char* resourceName = resourceItr->Next()->GetAttributeValue("NAME", 0); + if(resourceName == 0) + { + continue; + } + entityState->resources.PushSmart(resourceName); + } - statePar.Put(state, sp); - - // updating variables that keep track of the extremes values - if(minRange < minMinRange) + // checking if there is at least one resource + if(entityState->resources.IsEmpty()) { - minMinRange = minRange; + delete entityState; + return false; } - if(maxRange > maxMaxRange) + + // setting all the other parameters + entityState->probability = stateNode->GetAttributeValueAsFloat("PROBABILITY", 1.0); + entityState->volume = stateNode->GetAttributeValueAsFloat("VOLUME", VOLUME_NORM); + entityState->delay = stateNode->GetAttributeValueAsInt("DELAY", 0); + entityState->timeOfDayStart = stateNode->GetAttributeValueAsInt("TIME_START", 0); + entityState->timeOfDayEnd = stateNode->GetAttributeValueAsInt("TIME_END", 24); + entityState->fallbackState = stateNode->GetAttributeValueAsInt("FALLBACK_STATE", -1); + entityState->fallbackProbability = stateNode->GetAttributeValueAsFloat("FALLBACK_PROBABILITY", 1.0); + entityState->references = 1; + + // adjusting the probability on the update time + if(entityState->probability < 1.0) { - maxMaxRange = maxRange; + entityState->probability = entityState->probability / 1000 * SoundManager::updateTime; } - if(timeOfDayStart < minTimeOfDayStart) + + states.Put(stateID, entityState); + + // updating variables that keep track of the extremes values + if(entityState->timeOfDayStart < minTimeOfDayStart) { - minTimeOfDayStart = timeOfDayStart; + minTimeOfDayStart = entityState->timeOfDayStart; } - if(timeOfDayEnd > maxTimeOfDayEnd) + if(entityState->timeOfDayEnd > maxTimeOfDayEnd) { - maxTimeOfDayEnd = timeOfDayEnd; + maxTimeOfDayEnd = entityState->timeOfDayEnd; } return true; @@ -192,7 +247,7 @@ bool psEntity::IsReadyToPlay(int time, float range) const { - StateParameters* sp; + EntityState* entityState; // checking if it is in the undefined state if(state < 0) @@ -200,14 +255,14 @@ return true; } - sp = statePar.Get(state, 0); + entityState = states.Get(state, 0); // checking time, range and delay - if(range < sp->minRange || range > sp->maxRange) + if(range < minRange || range > maxRange) { return false; } - else if(time < sp->timeOfDayStart || sp->timeOfDayEnd < time) + else if(time < entityState->timeOfDayStart || entityState->timeOfDayEnd < time) { return false; } @@ -222,7 +277,7 @@ bool psEntity::CheckTimeAndRange(int time, float range) const { - if(range < minMinRange || range > maxMaxRange) + if(range < minRange || range > maxRange) { return false; } @@ -236,7 +291,7 @@ void psEntity::SetState(int stat, SoundControl* ctrl, csVector3 entityPosition, bool forceChange) { - StateParameters* sp; + EntityState* entityState; // check if it's already in this state or if it's defined if(state == stat) @@ -253,8 +308,8 @@ } // setting state - sp = statePar.Get(stat, 0); - if(sp == 0) + entityState = states.Get(stat, 0); + if(entityState == 0) { if(forceChange) { @@ -265,23 +320,11 @@ } state = stat; - - // playing the starting sound - if(!(sp->startResource.IsEmpty())) - { - if(SoundSystemManager::GetSingleton().Play3DSound(sp->startResource, DONT_LOOP, 0, 0, - sp->volume, ctrl, entityPosition, 0, sp->minRange, sp->maxRange, - VOLUME_ZERO, CS_SND3D_ABSOLUTE, handle)) - { - when = sp->delayAfter * 1000; - handle->SetCallback(this, &StopCallback); - } - } } bool psEntity::Play(SoundControl* &ctrl, csVector3 entityPosition) { - StateParameters* sp; + EntityState* entityState; // checking if a sound is still playing if(handle != NULL) @@ -295,15 +338,15 @@ return false; } - sp = statePar.Get(state, 0); + entityState = states.Get(state, 0); - if(!(sp->resource.IsEmpty())) + if(!(entityState->resources.IsEmpty())) { - if(SoundSystemManager::GetSingleton().Play3DSound(sp->resource, DONT_LOOP, 0, 0, - sp->volume, ctrl, entityPosition, 0, sp->minRange, sp->maxRange, + if(SoundSystemManager::GetSingleton().Play3DSound(entityState->resources[0], DONT_LOOP, 0, 0, + entityState->volume, ctrl, entityPosition, 0, minRange, maxRange, VOLUME_ZERO, CS_SND3D_ABSOLUTE, handle)) { - when = sp->delayAfter * 1000; + when = entityState->delay * 1000; handle->SetCallback(this, &StopCallback); return true; } Modified: trunk/src/plugins/common/soundmanager/psentity.h =================================================================== --- trunk/src/plugins/common/soundmanager/psentity.h 2011-12-26 23:26:31 UTC (rev 7916) +++ trunk/src/plugins/common/soundmanager/psentity.h 2011-12-26 23:28:18 UTC (rev 7917) @@ -26,25 +26,23 @@ #ifndef _PSENTITY_H_ #define _PSENTITY_H_ + /** - * This object represents a planeshift entity sound. + * This object represents a planeshift entity sound. It can be a mesh entity, if it is + * associated to a mesh object, or a factory entity if it is associated to a mesh factory. * * @see psSoundSector psEntity main user. */ - class psEntity { public: - csString factoryName; ///< name of this entity's factory - csString meshName; ///< name of this entity's mesh - - bool active; ///< is this psEntity active, used for caching purposes - - /** - * Create an empty psEntity. The initial state is set to 1. + * Create a new psEntity. The initial state is set to 1. + * @param isFactoryEntity true if this is associated to a factory, false if this is + * associated to a mesh. + * @param entityName the name of the factory or the mesh. */ - psEntity(); + psEntity(bool isFactoryEntity, const char* entityName); /** * Destructor. When destroyed the sounds is not stopped and it is removed @@ -61,6 +59,44 @@ psEntity(psEntity* const &entity); /** + * Return true if this is a factory entity. + * @return true if this is a factory entity, false otherwise. + */ + bool IsFactoryEntity() const { return isFactoryEntity; } + + /** + * Gets the entity name associated to this object. Use IsFactoryEntity() to check + * if this name is a mesh name or a factory name. + * @return the entity name. + */ + const csString &GetEntityName() const { return entityName; } + + /** + * Sets this object as a mesh entity. + * @param meshName the name of the mesh associated to this object. + */ + void SetAsMeshEntity(const char* meshName); + + /** + * Sets this object as a factory entity. + * @param factoryName the name of the factory associated to this object. + */ + void SetAsFactoryEntity(const char* factoryName); + + /** + * Gets the maximum distance at which this entity can be heard. + * @return the maximum distance at which this entity can be heard. + */ + float GetMaxRange() const { return maxRange; } + + /** + * Sets the range for this entity. + * @param minRange maximum distance at which this entity is heard at maximum volume. + * @param maxRange maximum distance at which this entity can be heard. + */ + void SetRange(float minRange, float maxRange); + + /** * Gets the probability to play a sound in the current state. * return the probability to play a sound. */ @@ -79,27 +115,9 @@ void SetMeshID(uint id); /** - * Define a new state and its parameters. If the same state has already been - * defined the method do nothing and returns false. * - * @param state the state id. - * @param resource the sound to be played when in this state. - * @param startResource the sound to be played when the entity change its - * state into this one. - * @param volume the volume at which this sound is played. - * @param minRange minimum distance at which the sound is heard. - * @param maxRange maximum distance at which the sound is heard - * @param probability the probability that resource is played when in this - * state. - * @param timeOfDayStart time when this entity starts playing in hours. - * @param timeOfDayEnd timewhen this entity stops playing in hours. - * @param delayAfter how much time this entity waits before playing again - * from the moment the sound ends in seconds. - * @return true if the state has been defined, false if already exists. */ - bool DefineState(int state, const char* resource, const char* startResource, - float volume, float minRange, float maxRange, float probability, - int timeOfDayStart, int timeOfDayEnd, int delayAfter); + bool DefineState(csRef<iDocumentNode> stateNode); /** * Decrease by the given interval the time that this entity have to wait @@ -109,6 +127,18 @@ void ReduceDelay(int interval); /** + * Check if this entity is active. + * @return true if this is active, false otherwise. + */ + bool IsActive() const { return isActive; } + + /** + * Activate or deactivate this entity. + * @param toggle true to activate this entity, false to deactivate it. + */ + void SetActive(bool toggle) { isActive = toggle; } + + /** * Used to determine if this is a temporary entity associated to a specific mesh * object or if it is a factory/mesh entity that is not associated to any mesh. * @return true if this entity is temporary, false otherwise. @@ -176,32 +206,40 @@ bool Play(SoundControl* &ctrl, csVector3 entityPosition); private: - struct StateParameters + /** + * Keeps all the parameters of an entity state. + */ + struct EntityState { - csString resource; ///< resource name of the sound associated to the state - csString startResource; ///< resource to be played when the entity state chage - float volume; ///< volume of the sound - float minRange; ///< minimum distance at which the sound is heard - float maxRange; ///< maximum distance at which the sound is heard - float probability; ///< how high is the probability that this entity makes this sound - int timeOfDayStart; ///< time when this entity starts playing - int timeOfDayEnd; ///< time when this entity stops. - int delayAfter; ///< number of seconds till played again + csStringArray resources; ///< resource names of the sounds associated to the state. + float volume; ///< volume of the sound. + float probability; ///< how high is the probability that this entity makes this sound. + int delay; ///< number of seconds till played again. + int timeOfDayStart; ///< time when this entity starts playing. + int timeOfDayEnd; ///< time when this entity stops. - int references; ///< how many psEntity point to this StateParameters + int fallbackState; ///< the stateID that is activated after this one. + float fallbackProbability; ///< the probability per second that the fallbackState is activated. + + int references; ///< how many psEntity point to this EntityState. }; - csHash<StateParameters*, int> statePar; ///< all the parameters associated to their state - SoundHandle* handle; ///< pointer to the SoundHandle if playing - int state; ///< current state of this entity. A negative value means that this entity is in an undefined state. - int when; ///< counter to keep track when it has been played - zero means i may play at any time (in ms) - uint id; ///< the id of the mesh object whose sound is controlled by this entity. + bool isActive; ///< true if this psEntity is active - float minMinRange; ///< minimum minRange between all the defined state of this entity - float maxMaxRange; ///< maximum maxRange between all the defined state of this entity - int minTimeOfDayStart; ///< minimum timeOfDayStart between all the defined state of this entity - int maxTimeOfDayEnd; ///< maximum timeOfDayEnd between all the defined state of this entity + bool isFactoryEntity; ///< true if this is a factory entity, false if it's a mesh entity. + csString entityName; ///< name of the entity associated to this object. + int state; ///< current state of this entity. A negative value means that this entity is in an undefined state. + int when; ///< counter to keep track when it has been played - zero means i may play at any time (in ms) + uint id; ///< the id of the mesh object whose sound is controlled by this entity. + float minRange; ///< minimum distance at which this entity can be heard + float maxRange; ///< maximum distance at which this entity can be heard + int minTimeOfDayStart; ///< minimum timeOfDayStart between all the defined state of this entity + int maxTimeOfDayEnd; ///< maximum timeOfDayEnd between all the defined state of this entity + + SoundHandle* handle; ///< pointer to the SoundHandle if playing + csHash<EntityState*, int> states; ///< entity states hash mapped by their ID. + /** * The Callback gets called if the SoundHandle is destroyed. * It sets handle to NULL. Modified: trunk/src/plugins/common/soundmanager/pssoundsector.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/pssoundsector.cpp 2011-12-26 23:26:31 UTC (rev 7916) +++ trunk/src/plugins/common/soundmanager/pssoundsector.cpp 2011-12-26 23:28:18 UTC (rev 7917) @@ -319,46 +319,38 @@ delete emitter; } -void psSoundSector::AddEntity(csRef<iDocumentNode> Node) +void psSoundSector::AddEntity(csRef<iDocumentNode> entityNode) { - const char* factoryName; - const char* meshName; - int state; - const char* resource; - const char* startResource; - float volume; float minRange; float maxRange; - float prob; - int timeOfDayStart; - int timeOfDayEnd; - int delayAfter; + const char* meshName; + const char* factoryName; + psEntity* entity; + csRef<iDocumentNodeIterator> stateItr; - factoryName = Node->GetAttributeValue("FACTORY"); - meshName = Node->GetAttributeValue("MESH"); - state = Node->GetAttributeValueAsInt("STATE", -1); - resource = Node->GetAttributeValue("RESOURCE"); - startResource = Node->GetAttributeValue("STARTING_RESOURCE"); - maxRange = Node->GetAttributeValueAsFloat("MAX_RANGE", -1.0); - prob = Node->GetAttributeValueAsFloat("PROBABILITY", -1.0); - - // checking that all mandatory parameters are present - if((factoryName == 0 && meshName == 0) - || (factoryName != 0 && meshName != 0)) + // determining if this is a mesh entity or a factory entity + meshName = entityNode->GetAttributeValue("MESH", 0); + if(meshName == 0) // this isn't a mesh entity we need the factory { - return; + factoryName = entityNode->GetAttributeValue("FACTORY", 0); + + // this is nor a factory entity + if(factoryName == 0) + { + return; + } } - if(state < 0 || prob < 0.0 || maxRange < 0.0) + + // getting range parameters + maxRange = entityNode->GetAttributeValueAsFloat("MAX_RANGE", 0); + if(maxRange <= 0) // the entity will never play a sound { return; } - if(resource == 0 && startResource == 0) - { - return; - } + minRange = entityNode->GetAttributeValueAsFloat("MIN_RANGE", 0); - // check if an entity with the same name is already defined + // checking if an entity with the same name is already defined if(meshName == 0) { entity = factories.Get(factoryName, 0); @@ -371,36 +363,27 @@ // if it doesn't exist create it otherwise check the state if(entity == 0) { - entity = new psEntity(); - - // handle mesh/factory entities - if(meshName == 0) + if(meshName == 0) // factory entity { - entity->factoryName = factoryName; + entity = new psEntity(true, factoryName); factories.Put(factoryName, entity); } - else + else // mesh entity { - entity->meshName = meshName; + entity = new psEntity(false, meshName); meshes.Put(meshName, entity); } } - // set all parameters - volume = Node->GetAttributeValueAsFloat("VOLUME", VOLUME_NORM); - minRange = Node->GetAttributeValueAsFloat("MIN_RANGE"); - delayAfter = Node->GetAttributeValueAsInt("DELAY_AFTER"); - timeOfDayStart = Node->GetAttributeValueAsInt("TIME_START", -1); - timeOfDayEnd = Node->GetAttributeValueAsInt("TIME_END", 25); + // setting range + entity->SetRange(minRange, maxRange); - // adjusting the probability on the update time - if(prob < 1.0) + // creating all the states for this entity + stateItr = entityNode->GetNodes("STATE"); + while(stateItr->HasNext()) { - prob = prob / 1000 * SoundManager::updateTime; + entity->DefineState(stateItr->Next()); } - - entity->DefineState(state, resource, startResource, volume, - minRange, maxRange, prob, timeOfDayStart, timeOfDayEnd, delayAfter); } void psSoundSector::UpdateEntity(SoundControl* &ctrl, psSoundSector* commonSector) @@ -486,9 +469,9 @@ { entity = tempEnt[i]; - if(entity->active == true) + if(entity->IsActive()) { - entity->active = false; + entity->SetActive(false); } else { @@ -511,13 +494,13 @@ { tempEntities.Delete(entity->GetMeshID(), entity); } - else if(entity->meshName.IsEmpty()) + else if(entity->IsFactoryEntity()) { - factories.Delete(entity->factoryName, entity); + factories.Delete(entity->GetEntityName(), entity); } else { - meshes.Delete(entity->meshName, entity); + meshes.Delete(entity->GetEntityName(), entity); } delete entity; @@ -630,7 +613,7 @@ if(entity->IsPlaying()) { - entity->active = true; + entity->SetActive(true); return; } @@ -656,6 +639,6 @@ entity->Play(ctrl, mesh->GetMovable()->GetFullPosition()); } - entity->active = true; + entity->SetActive(true); } } Modified: trunk/src/plugins/common/soundmanager/pssoundsector.h =================================================================== --- trunk/src/plugins/common/soundmanager/pssoundsector.h 2011-12-26 23:26:31 UTC (rev 7916) +++ trunk/src/plugins/common/soundmanager/pssoundsector.h 2011-12-26 23:28:18 UTC (rev 7917) @@ -74,7 +74,7 @@ void AddEmitter(csRef<iDocumentNode> Node); void UpdateEmitter(SoundControl* &ctrl); void DeleteEmitter(psEmitter* &emitter); - void AddEntity(csRef<iDocumentNode> Node); + void AddEntity(csRef<iDocumentNode> entityNode); void UpdateEntity(SoundControl* &ctrl, psSoundSector* commonSector); void DeleteEntity(psEntity* &entity); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wha...@us...> - 2011-12-27 00:49:20
|
Revision: 7920 http://planeshift.svn.sourceforge.net/planeshift/?rev=7920&view=rev Author: whacko88 Date: 2011-12-27 00:49:13 +0000 (Tue, 27 Dec 2011) Log Message: ----------- fixed sound entity XML syntax implemented random selection among more the resources of a sound entity Modified Paths: -------------- trunk/src/plugins/common/soundmanager/manager.h trunk/src/plugins/common/soundmanager/psentity.cpp trunk/src/plugins/common/soundmanager/psentity.h trunk/src/plugins/common/soundmanager/pssoundsector.cpp trunk/src/plugins/common/soundmanager/pssoundsector.h Modified: trunk/src/plugins/common/soundmanager/manager.h =================================================================== --- trunk/src/plugins/common/soundmanager/manager.h 2011-12-26 23:54:49 UTC (rev 7919) +++ trunk/src/plugins/common/soundmanager/manager.h 2011-12-27 00:49:13 UTC (rev 7920) @@ -200,8 +200,9 @@ void RemoveSoundControl(SoundControl* sndCtrl); SoundControl* GetSoundControl(int ctrlID) const; - SoundSystem* GetSoundSystem() { return soundSystem; } - SoundDataCache* GetSoundDataCache() { return soundDataCache; } + csRandomGen &GetRandomGen() { return randomGen; } + SoundSystem* GetSoundSystem() const { return soundSystem; } + SoundDataCache* GetSoundDataCache() const { return soundDataCache; } private: SoundSystem* soundSystem; Modified: trunk/src/plugins/common/soundmanager/psentity.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/psentity.cpp 2011-12-26 23:54:49 UTC (rev 7919) +++ trunk/src/plugins/common/soundmanager/psentity.cpp 2011-12-27 00:49:13 UTC (rev 7920) @@ -161,7 +161,7 @@ csRef<iDocumentNodeIterator> resourceItr; // checking if the state ID is legal - stateID = stateNode->GetAttributeValueAsInt("STATE", -1); + stateID = stateNode->GetAttributeValueAsInt("ID", -1); if(stateID < 0) { return false; @@ -212,6 +212,9 @@ entityState->probability = entityState->probability / 1000 * SoundManager::updateTime; } + // in XML delay is given in seconds, converting delay into milliseconds + entityState->delay = entityState->delay * 1000; + states.Put(stateID, entityState); // updating variables that keep track of the extremes values @@ -340,13 +343,16 @@ entityState = states.Get(state, 0); + // picking up randomly among resources if(!(entityState->resources.IsEmpty())) { - if(SoundSystemManager::GetSingleton().Play3DSound(entityState->resources[0], DONT_LOOP, 0, 0, + int resourceNumber = SoundSystemManager::GetSingleton().GetRandomGen().Get() * entityState->resources.GetSize(); + + if(SoundSystemManager::GetSingleton().Play3DSound(entityState->resources[resourceNumber], DONT_LOOP, 0, 0, entityState->volume, ctrl, entityPosition, 0, minRange, maxRange, VOLUME_ZERO, CS_SND3D_ABSOLUTE, handle)) { - when = entityState->delay * 1000; + when = entityState->delay; handle->SetCallback(this, &StopCallback); return true; } Modified: trunk/src/plugins/common/soundmanager/psentity.h =================================================================== --- trunk/src/plugins/common/soundmanager/psentity.h 2011-12-26 23:54:49 UTC (rev 7919) +++ trunk/src/plugins/common/soundmanager/psentity.h 2011-12-27 00:49:13 UTC (rev 7920) @@ -214,7 +214,7 @@ csStringArray resources; ///< resource names of the sounds associated to the state. float volume; ///< volume of the sound. float probability; ///< how high is the probability that this entity makes this sound. - int delay; ///< number of seconds till played again. + int delay; ///< number of milliseconds till played again. int timeOfDayStart; ///< time when this entity starts playing. int timeOfDayEnd; ///< time when this entity stops. Modified: trunk/src/plugins/common/soundmanager/pssoundsector.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/pssoundsector.cpp 2011-12-26 23:54:49 UTC (rev 7919) +++ trunk/src/plugins/common/soundmanager/pssoundsector.cpp 2011-12-27 00:49:13 UTC (rev 7920) @@ -295,7 +295,7 @@ continue; } - if(rng.Get() <= emitter->probability) + if(SoundSystemManager::GetSingleton().GetRandomGen().Get() <= emitter->probability) { if(!emitter->Play(ctrl)) { @@ -634,7 +634,7 @@ // Check if it can play if(entity->IsReadyToPlay(timeofday, range) - && rng.Get() <= entity->GetProbability()) + && SoundSystemManager::GetSingleton().GetRandomGen().Get() <= entity->GetProbability()) { entity->Play(ctrl, mesh->GetMovable()->GetFullPosition()); } Modified: trunk/src/plugins/common/soundmanager/pssoundsector.h =================================================================== --- trunk/src/plugins/common/soundmanager/pssoundsector.h 2011-12-26 23:54:49 UTC (rev 7919) +++ trunk/src/plugins/common/soundmanager/pssoundsector.h 2011-12-27 00:49:13 UTC (rev 7920) @@ -45,8 +45,6 @@ csVector3 listenerPos; ///< current listener position int timeofday; ///< sector time of day - csRandomGen rng; ///< random number generator - /** * Create an empty psSoundSector with no musics, ambients, emitters and entities. * @param name the psSoundSector's name This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wha...@us...> - 2012-01-16 02:06:21
|
Revision: 8008 http://planeshift.svn.sourceforge.net/planeshift/?rev=8008&view=rev Author: whacko88 Date: 2012-01-16 02:06:14 +0000 (Mon, 16 Jan 2012) Log Message: ----------- implemented sound entities fallback state fixed some bugs fixed headers in SoundManager Modified Paths: -------------- trunk/src/plugins/common/soundmanager/manager.cpp trunk/src/plugins/common/soundmanager/manager.h trunk/src/plugins/common/soundmanager/psentity.cpp trunk/src/plugins/common/soundmanager/psentity.h trunk/src/plugins/common/soundmanager/psmusic.h trunk/src/plugins/common/soundmanager/pssoundsector.cpp trunk/src/plugins/common/soundmanager/pssoundsector.h trunk/src/plugins/common/soundmanager/songstream.cpp trunk/src/plugins/common/soundmanager/songstream.h trunk/src/plugins/common/soundmanager/soundmanager.cpp trunk/src/plugins/common/soundmanager/soundmanager.h Modified: trunk/src/plugins/common/soundmanager/manager.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/manager.cpp 2012-01-15 14:46:41 UTC (rev 8007) +++ trunk/src/plugins/common/soundmanager/manager.cpp 2012-01-16 02:06:14 UTC (rev 8008) @@ -22,6 +22,8 @@ */ #include "manager.h" + +#include "soundmanager.h" #include "handle.h" #include "soundctrl.h" #include "system.h" @@ -416,7 +418,7 @@ do { - handleID = randomGen.Get(10000); + handleID = SoundManager::randomGen.Get(10000); } while(soundHandles.Get(handleID, 0) != 0 || handleID == 0); Modified: trunk/src/plugins/common/soundmanager/manager.h =================================================================== --- trunk/src/plugins/common/soundmanager/manager.h 2012-01-15 14:46:41 UTC (rev 8007) +++ trunk/src/plugins/common/soundmanager/manager.h 2012-01-16 02:06:14 UTC (rev 8008) @@ -200,7 +200,6 @@ void RemoveSoundControl(SoundControl* sndCtrl); SoundControl* GetSoundControl(int ctrlID) const; - csRandomGen &GetRandomGen() { return randomGen; } SoundSystem* GetSoundSystem() const { return soundSystem; } SoundDataCache* GetSoundDataCache() const { return soundDataCache; } @@ -220,8 +219,6 @@ uint speedOfSound; ///< the speed of sound for doppler effect float dopplerFactor; ///< the doppler factor that multiplies the change of frequency - csRandomGen randomGen; ///< random number generator - /** * Finds a unique ID > 0 for a SoundHandle. * @return the unique ID for the SoundHandle. Modified: trunk/src/plugins/common/soundmanager/psentity.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/psentity.cpp 2012-01-15 14:46:41 UTC (rev 8007) +++ trunk/src/plugins/common/soundmanager/psentity.cpp 2012-01-16 02:06:14 UTC (rev 8008) @@ -34,14 +34,12 @@ isActive = false; when = 0; - state = 1; + state = DEFAULT_ENTITY_STATE; id = 0; handle = 0; minRange = 0.0f; maxRange = 0.0f; - minTimeOfDayStart = 25; - maxTimeOfDayEnd = -1; } psEntity::psEntity(psEntity* const& entity) @@ -69,13 +67,11 @@ minRange = entity->minRange; maxRange = entity->maxRange; - minTimeOfDayStart = entity->minTimeOfDayStart; - maxTimeOfDayEnd = entity->maxTimeOfDayEnd; } psEntity::~psEntity() { - if(handle != 0) + if(IsPlaying()) { handle->RemoveCallback(); } @@ -129,20 +125,6 @@ maxRange = maxDistance; } -float psEntity::GetProbability() const -{ - EntityState* entityState; - - if(state < 0) - { - return 0.0f; - } - - entityState = states.Get(state, 0); - - return entityState->probability; -} - uint psEntity::GetMeshID() const { return id; @@ -168,7 +150,7 @@ } // initializing the EntityState - entityState = states.Get(state, 0); + entityState = states.Get(stateID, 0); if(entityState != 0) // already defined { @@ -203,41 +185,27 @@ entityState->timeOfDayStart = stateNode->GetAttributeValueAsInt("TIME_START", 0); entityState->timeOfDayEnd = stateNode->GetAttributeValueAsInt("TIME_END", 24); entityState->fallbackState = stateNode->GetAttributeValueAsInt("FALLBACK_STATE", -1); - entityState->fallbackProbability = stateNode->GetAttributeValueAsFloat("FALLBACK_PROBABILITY", 1.0); + entityState->fallbackProbability = stateNode->GetAttributeValueAsFloat("FALLBACK_PROBABILITY", 0.0); entityState->references = 1; - // adjusting the probability on the update time + // adjusting the probabilities on the update time if(entityState->probability < 1.0) { - entityState->probability = entityState->probability / 1000 * SoundManager::updateTime; + entityState->probability *= SoundManager::updateTime / 1000.0; } + if(entityState->fallbackProbability < 1.0) + { + entityState->fallbackProbability *= SoundManager::updateTime / 1000.0; + } // in XML delay is given in seconds, converting delay into milliseconds entityState->delay = entityState->delay * 1000; states.Put(stateID, entityState); - // updating variables that keep track of the extremes values - if(entityState->timeOfDayStart < minTimeOfDayStart) - { - minTimeOfDayStart = entityState->timeOfDayStart; - } - if(entityState->timeOfDayEnd > maxTimeOfDayEnd) - { - maxTimeOfDayEnd = entityState->timeOfDayEnd; - } - return true; } -void psEntity::ReduceDelay(int interval) -{ - if(when > 0) - { - when -= 50; - } -} - bool psEntity::IsTemporary() const { return (id != 0); @@ -248,18 +216,17 @@ return (handle != 0); } -bool psEntity::IsReadyToPlay(int time, float range) const +bool psEntity::CanPlay(int time, float range) const { EntityState* entityState; // checking if it is in the undefined state - if(state < 0) + entityState = states.Get(state, 0); + if(entityState == 0) { - return true; + return false; } - entityState = states.Get(state, 0); - // checking time, range and delay if(range < minRange || range > maxRange) { @@ -277,23 +244,8 @@ return false; } -bool psEntity::CheckTimeAndRange(int time, float range) const +void psEntity::SetState(int stat, bool forceChange) { - - if(range < minRange || range > maxRange) - { - return false; - } - if(minTimeOfDayStart <= time && time <= maxTimeOfDayEnd) - { - return true; - } - - return false; -} - -void psEntity::SetState(int stat, SoundControl* ctrl, csVector3 entityPosition, bool forceChange) -{ EntityState* entityState; // check if it's already in this state or if it's defined @@ -303,7 +255,7 @@ } // stopping previous sound if any - if(handle != 0) + if(IsPlaying()) { handle->RemoveCallback(); SoundSystemManager::GetSingleton().StopSound(handle->GetID()); @@ -346,7 +298,7 @@ // picking up randomly among resources if(!(entityState->resources.IsEmpty())) { - int resourceNumber = SoundSystemManager::GetSingleton().GetRandomGen().Get() * entityState->resources.GetSize(); + int resourceNumber = SoundManager::randomGen.Get() * entityState->resources.GetSize(); if(SoundSystemManager::GetSingleton().Play3DSound(entityState->resources[resourceNumber], DONT_LOOP, 0, 0, entityState->volume, ctrl, entityPosition, 0, minRange, maxRange, @@ -361,7 +313,55 @@ return false; } +void psEntity::Update(int time, float distance, int interval, SoundControl* &ctrl, + csVector3 entityPosition) +{ + EntityState* currentState = states.Get(state, 0); + if(IsPlaying()) + { + isActive = true; + } + else if(when > 0) // surely !IsPlaying() is true + { + // reducing delay time + isActive = true; + when -= interval; + } + else if(currentState != 0 && CanPlay(time, distance)) + { + float prob; + + isActive = true; + prob = SoundManager::randomGen.Get(); + if(prob <= currentState->probability) + { + Play(ctrl, entityPosition); + } + } + else if(state != DEFAULT_ENTITY_STATE) + { + // if the state is different than DEFAULT_ENTITY_STATE this information + // should be kept + isActive = true; + } + else + { + isActive = false; + } + + // the state goes to fallback even if the sound is still playing otherwise + // it will never fallback when entity->probability == 1 + if(currentState != 0) + { + float prob = SoundManager::randomGen.Get(); + if(prob <= currentState->fallbackProbability) + { + SetState(currentState->fallbackState, true); + } + } +} + void psEntity::StopCallback(void* object) { psEntity* which = (psEntity*) object; Modified: trunk/src/plugins/common/soundmanager/psentity.h =================================================================== --- trunk/src/plugins/common/soundmanager/psentity.h 2012-01-15 14:46:41 UTC (rev 8007) +++ trunk/src/plugins/common/soundmanager/psentity.h 2012-01-16 02:06:14 UTC (rev 8008) @@ -27,6 +27,8 @@ #define _PSENTITY_H_ +#define DEFAULT_ENTITY_STATE 0 + /** * This object represents a planeshift entity sound. It can be a mesh entity, if it is * associated to a mesh object, or a factory entity if it is associated to a mesh factory. @@ -37,7 +39,7 @@ { public: /** - * Create a new psEntity. The initial state is set to 1. + * Create a new psEntity. The initial state is set to DEFAULT_ENTITY_STATE. * @param isFactoryEntity true if this is associated to a factory, false if this is * associated to a mesh. * @param entityName the name of the factory or the mesh. @@ -97,12 +99,6 @@ void SetRange(float minRange, float maxRange); /** - * Gets the probability to play a sound in the current state. - * return the probability to play a sound. - */ - float GetProbability() const; - - /** * Get the ID of the mesh associated to this entity. * @return the ID of the mesh. */ @@ -115,18 +111,13 @@ void SetMeshID(uint id); /** - * + * Create a new state from an XML <state> node. + * @param stateNode the state node. + * @return true if the state could be created, false otherwise. */ bool DefineState(csRef<iDocumentNode> stateNode); /** - * Decrease by the given interval the time that this entity have to wait - * before play again. - * @param interval the time elapsed in milliseconds. - */ - void ReduceDelay(int interval); - - /** * Check if this entity is active. * @return true if this is active, false otherwise. */ @@ -162,24 +153,11 @@ * window and if the distance is between the minimum and maximum * range. False otherwise. */ - bool IsReadyToPlay(int time, float range) const; - - /** - * Check if time is within this entity's timewindow and if the distance - * is between the minimum and maximum range in any defined state. This - * control for only the current state is performed by IsReadyToPlay(). - * - * @param time <24 && >0 is resonable but can be any valid int. - * @param range the distance to test. - * @return true if conditions are satisfied for at least one defined - * state, false otherwise. - */ - bool CheckTimeAndRange(int time, float range) const; + bool CanPlay(int time, float range) const; /** - * Set the new state for the entity and play the start resource (if any) - * with the given SoundControl. If it is already playing a sound, it is - * stopped. + * Set the new state for the entity. If it is already playing a sound, + * it is stopped. * * If the given state is undefined for this entity the change of state * is not forced, the state does not change. On the other hand if the @@ -188,14 +166,12 @@ * * @param state the new state >= 0 for this entity. For negative value the * function is not defined. - * @param ctrl the SoundControl for playing the starting sound. - * @param entityPosition the position of the starting sound to play. * @param forceChange true to force the state change, false otherwise. */ - void SetState(int state, SoundControl* ctrl, csVector3 entityPostion, bool forceChange); + void SetState(int state, bool forceChange); /** - * Play this entity sound. + * Force this entity to play the sound associated to its current state. * You need to supply a SoundControl and the position for this sound. * * @param ctrl the SoundControl to control this sound. @@ -205,6 +181,19 @@ */ bool Play(SoundControl* &ctrl, csVector3 entityPosition); + /** + * Update the entity's activation status, play the sound associated with + * the current state if all condition are satisfied, update the delay + * and fallback in the new state if necessary. + * @param time the time of the day, <24 && >0 is resonable but can be any + * valid int. + * @param distance the distance from the listener. + * @param ctrl the SoundControl to play the sound with. + * @param entityPosition the position of the player. + */ + void Update(int time, float distance, int interval, SoundControl* &ctrl, + csVector3 entityPosition); + private: /** * Keeps all the parameters of an entity state. @@ -234,8 +223,6 @@ uint id; ///< the id of the mesh object whose sound is controlled by this entity. float minRange; ///< minimum distance at which this entity can be heard float maxRange; ///< maximum distance at which this entity can be heard - int minTimeOfDayStart; ///< minimum timeOfDayStart between all the defined state of this entity - int maxTimeOfDayEnd; ///< maximum timeOfDayEnd between all the defined state of this entity SoundHandle* handle; ///< pointer to the SoundHandle if playing csHash<EntityState*, int> states; ///< entity states hash mapped by their ID. Modified: trunk/src/plugins/common/soundmanager/psmusic.h =================================================================== --- trunk/src/plugins/common/soundmanager/psmusic.h 2012-01-15 14:46:41 UTC (rev 8007) +++ trunk/src/plugins/common/soundmanager/psmusic.h 2012-01-16 02:06:14 UTC (rev 8008) @@ -24,6 +24,12 @@ #ifndef _PSMUSIC_H_ #define _PSMUSIC_H_ +//------------------------------------------------------------------------------------ +// Forward Declarations +//------------------------------------------------------------------------------------ +class SoundHandle; + + /** * This object represents a planeshift Soundtrack. * It maybe an ambient or a real soundtrack they are very similiar. Modified: trunk/src/plugins/common/soundmanager/pssoundsector.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/pssoundsector.cpp 2012-01-15 14:46:41 UTC (rev 8007) +++ trunk/src/plugins/common/soundmanager/pssoundsector.cpp 2012-01-16 02:06:14 UTC (rev 8008) @@ -23,6 +23,13 @@ #include <psconfig.h> #include <crystalspace.h> +#include "pssoundsector.h" + +#include "manager.h" +#include "psmusic.h" +#include "psentity.h" +#include "psemitter.h" +#include "soundctrl.h" #include "soundmanager.h" psSoundSector::psSoundSector(const char* sectorName, iObjectRegistry* objReg) @@ -295,7 +302,7 @@ continue; } - if(SoundSystemManager::GetSingleton().GetRandomGen().Get() <= emitter->probability) + if(SoundManager::randomGen.Get() <= emitter->probability) { if(!emitter->Play(ctrl)) { @@ -386,15 +393,11 @@ } } -void psSoundSector::UpdateEntity(SoundControl* &ctrl, psSoundSector* commonSector) +void psSoundSector::UpdateEntity(SoundControl* &ctrl) { csRef<iEngine> engine; iMeshList* entities; psEntity* entity; - iMeshWrapper* mesh; - uint meshID; - const char* meshName; - const char* factoryName = 0; engine = csQueryRegistry<iEngine>(objectReg); @@ -408,57 +411,44 @@ for(int a = 0; a < entities->GetCount(); a++) { - if((mesh = entities->Get(a)) == 0) + uint meshID; + float range; + csVector3 rangeVec; + iMeshWrapper* mesh; + + mesh = entities->Get(a); + if(mesh == 0) { continue; } - // checking if we already have a temporary entity for the mesh - // here we don't check the common sector because the common do - // not have temporary entities - meshID = mesh->QueryObject()->GetID(); - if((entity = tempEntities.Get(meshID, 0)) != 0) + // retrieving the entity associated to the mesh (if any) + entity = GetAssociatedEntity(mesh); + if(entity == 0) { - UpdateEntityValues(ctrl, entity, mesh); continue; } + // if this isn't a temporary entity, create one only if it can + // actually play something + rangeVec = mesh->GetMovable()->GetFullPosition() - listenerPos; + range = rangeVec.Norm(); - // check if the factory is defined for this mesh - meshName = mesh->QueryObject()->GetName(); - iMeshFactoryWrapper* mfw = mesh->GetFactory(); - if(mfw != 0) + if(!entity->IsTemporary() && entity->CanPlay(timeofday, range)) { - factoryName = mfw->QueryObject()->GetName(); + entity = new psEntity(entity); + entity->SetMeshID(mesh->QueryObject()->GetID()); + tempEntities.Put(entity->GetMeshID(), entity); } - // first it look in the meshes and factories of this sector - if((entity = meshes.Get(meshName, 0)) != 0) + // this update the delay and fallback state, play if it can and + // set itself as active when appropriate. Only temporary entities + // should be updated + if(entity->IsTemporary()) { - UpdateEntityValues(ctrl, entity, mesh); - continue; + csVector3 entityPosition = mesh->GetMovable()->GetFullPosition(); + entity->Update(timeofday, range, SoundManager::updateTime, ctrl, entityPosition); } - else if(factoryName != 0) - { - if((entity = factories.Get(factoryName, 0)) != 0) - { - UpdateEntityValues(ctrl, entity, mesh); - continue; - } - } - - // nothing found here: look in the commonSector - if((entity = commonSector->meshes.Get(meshName, 0)) != 0) - { - UpdateEntityValues(ctrl, entity, mesh); - } - else if(factoryName != 0) - { - if((entity = commonSector->factories.Get(factoryName, 0)) != 0) - { - UpdateEntityValues(ctrl, entity, mesh); - } - } } // Cleaning up temporary entities (common sector doesn't have them) @@ -471,6 +461,8 @@ if(entity->IsActive()) { + // by setting here the entity as unactive we can check if the + // entity has been touched or not in the next update entity->SetActive(false); } else @@ -479,13 +471,7 @@ delete entity; continue; } - - if(!(entity->IsPlaying())) - { - entity->ReduceDelay(SoundManager::updateTime); - } } - } void psSoundSector::DeleteEntity(psEntity* &entity) @@ -506,16 +492,39 @@ delete entity; } -void psSoundSector::SetEntityState(int state, SoundControl* ctrl, iMeshWrapper* mesh, bool forceChange) +void psSoundSector::SetEntityState(int state, iMeshWrapper* mesh, bool forceChange) { - psEntity* entity = tempEntities.Get(mesh->QueryObject()->GetID(), 0); + uint meshID; + bool isTemporary; + psEntity* entity; + entity = GetAssociatedEntity(mesh); if(entity == 0) { return; } - entity->SetState(state, ctrl, mesh->GetMovable()->GetFullPosition(), forceChange); + meshID = mesh->QueryObject()->GetID(); + isTemporary = entity->IsTemporary(); + + // if the new state isn't DEFAULT_ENTITY_STATE, a new entity must be created so that + // when it will satisfies the conditions to play (for example when the distance from + // the player gets enough short), the entity's state will be the correct one. If the + // new state is DEFAULT_ENTITY_STATE, the entity will be created only when conditions + // will be satisfied. + if(!isTemporary && state != DEFAULT_ENTITY_STATE) + { + entity = new psEntity(entity); + entity->SetMeshID(meshID); + tempEntities.Put(meshID, entity); + } + + // applying state change only if it's a temporary entity + if(isTemporary) + { + entity->SetState(state, forceChange); + return; + } } void psSoundSector::Load(csRef<iDocumentNode> sector) @@ -606,39 +615,56 @@ tempEntities.DeleteAll(); } -void psSoundSector::UpdateEntityValues(SoundControl* &ctrl, psEntity* entity, iMeshWrapper* mesh) +psEntity* psSoundSector::GetAssociatedEntity(iMeshWrapper* mesh) const { - csVector3 rangeVec; - float range; + uint meshID; + psEntity* entity; - if(entity->IsPlaying()) + // checking if there is have a temporary entity for the mesh + // here the common sector is not checked because it don't have temporary entities + meshID = mesh->QueryObject()->GetID(); + entity = tempEntities.Get(meshID, 0); + + if(entity == 0) { - entity->SetActive(true); - return; - } + const char* meshName; + const char* factoryName; - rangeVec = mesh->GetMovable()->GetFullPosition() - listenerPos; - range = rangeVec.Norm(); + // getting mesh name + meshName = mesh->QueryObject()->GetName(); - if(active && entity->CheckTimeAndRange(timeofday, range)) - { - // we need to create the entity even if it won't play anything - // so that the entity will be ready to play a sound when it change - // to a state with an higher maxRange for example - if(!(entity->IsTemporary())) + // checking mesh entities + entity = meshes.Get(meshName, 0); + if(entity == 0) { - entity = new psEntity(entity); - entity->SetMeshID(mesh->QueryObject()->GetID()); - tempEntities.Put(entity->GetMeshID(), entity); + // getting factory name + iMeshFactoryWrapper* factory = mesh->GetFactory(); + if(factory != 0) + { + factoryName = factory->QueryObject()->GetName(); + } + else + { + factoryName = 0; + } + + // checking factory entities + if(factoryName != 0) + { + entity = factories.Get(factoryName, 0); + } } - // Check if it can play - if(entity->IsReadyToPlay(timeofday, range) - && SoundSystemManager::GetSingleton().GetRandomGen().Get() <= entity->GetProbability()) + // if nothing has been found check in common sector + if(entity == 0) { - entity->Play(ctrl, mesh->GetMovable()->GetFullPosition()); + entity = SoundManager::commonSector->meshes.Get(meshName, 0); + if(entity == 0 && factoryName != 0) + { + entity = SoundManager::commonSector->factories.Get(factoryName, 0); + } } + } - entity->SetActive(true); - } + return entity; } Modified: trunk/src/plugins/common/soundmanager/pssoundsector.h =================================================================== --- trunk/src/plugins/common/soundmanager/pssoundsector.h 2012-01-15 14:46:41 UTC (rev 8007) +++ trunk/src/plugins/common/soundmanager/pssoundsector.h 2012-01-16 02:06:14 UTC (rev 8008) @@ -23,6 +23,13 @@ #ifndef _PSSOUNDSECTOR_H_ #define _PSSOUNDSECTOR_H_ +//------------------------------------------------------------------------------------ +// Forward Declarations +//------------------------------------------------------------------------------------ +class psMusic; +class psEntity; +class psEmitter; +class SoundControl; /** * work in progress - Looks like a mishap. I hope find a object where i @@ -38,7 +45,7 @@ csArray<psMusic*> ambientarray; ///< array of available ambients csArray<psMusic*> musicarray; ///< array of available musics csArray<psEmitter*> emitterarray; ///< array of emitters - csHash<psEntity*, csString> factories; ///< hash of factory entities (i.e. with meshName empty) + csHash<psEntity*, csString> factories; ///< hash of factory entities csHash<psEntity*, csString> meshes; ///< hash of mesh entities csHash<psEntity*, uint> tempEntities; ///< hash of all the temporary psEntites (i.e. associated to a specific mesh) @@ -73,23 +80,21 @@ void UpdateEmitter(SoundControl* &ctrl); void DeleteEmitter(psEmitter* &emitter); void AddEntity(csRef<iDocumentNode> entityNode); - void UpdateEntity(SoundControl* &ctrl, psSoundSector* commonSector); + void UpdateEntity(SoundControl* &ctrl); void DeleteEntity(psEntity* &entity); /** - * Sets the new state for the entity associated to the given mesh and - * plays the start resource (if defined). If it is already playing a - * sound, it is stopped. + * Sets the new state for the entity associated to the given mesh. If + * it is already playing a sound, it is stopped. * * @param state the new state >= 0 for the entity. For negative value * the function is not defined. - * @param ctrl the sound control used to play the start resource. * @param mesh the mesh associated to the entity. * @param forceChange if it is false the entity does not change its * state if the new one is not defined. If it is true the entity stops * play any sound until a new valid state is defined. */ - void SetEntityState(int state, SoundControl* ctrl, iMeshWrapper* mesh, bool forceChange); + void SetEntityState(int state, iMeshWrapper* mesh, bool forceChange); void Load(csRef<iDocumentNode> sector); void Reload(csRef<iDocumentNode> sector); void Delete(); @@ -97,7 +102,15 @@ private: csRef<iObjectRegistry> objectReg; - void UpdateEntityValues(SoundControl* &ctrl, psEntity* entity, iMeshWrapper* mesh); + /** + * Helper function that retrieve the entity associated to a mesh. It checks + * in temporary, mesh and factory entities in both this and common sector + * with the priority temporary > this->meshes > this->factories > common->meshes > + * > common->factories. + * @param mesh the mesh associated to the entity. + * @return the entity associated to the mesh or 0 if it cannot be found. + */ + psEntity* GetAssociatedEntity(iMeshWrapper* mesh) const; }; #endif /*_PSSOUNDSECTOR_H_*/ Modified: trunk/src/plugins/common/soundmanager/songstream.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/songstream.cpp 2012-01-15 14:46:41 UTC (rev 8007) +++ trunk/src/plugins/common/soundmanager/songstream.cpp 2012-01-16 02:06:14 UTC (rev 8008) @@ -27,6 +27,7 @@ //==================================================================================== // Local Includes //==================================================================================== +#include "soundmanager.h" #include "songdata.h" #include "instrument.h" @@ -601,7 +602,7 @@ } // handling error - randError = randomGen.Get(); + randError = SoundManager::randomGen.Get(); errorDiff = noteErrorRate - randError; if(errorDiff >= 0) Modified: trunk/src/plugins/common/soundmanager/songstream.h =================================================================== --- trunk/src/plugins/common/soundmanager/songstream.h 2012-01-15 14:46:41 UTC (rev 8007) +++ trunk/src/plugins/common/soundmanager/songstream.h 2012-01-16 02:06:14 UTC (rev 8008) @@ -85,8 +85,6 @@ int conversionFactor; ///< the multiplier used to get the data size from the data's format to the stream's one. bool conversionNeeded; ///< true if the data from the instrument must be converted into the stream's format. - csRandomGen randomGen; ///< random number generator - /** * Check if m_bPlaybackReadComplete must be set to true and if it must it does * it. This function should be called everytime CopyBufferBytes() is used. Modified: trunk/src/plugins/common/soundmanager/soundmanager.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/soundmanager.cpp 2012-01-15 14:46:41 UTC (rev 8007) +++ trunk/src/plugins/common/soundmanager/soundmanager.cpp 2012-01-16 02:06:14 UTC (rev 8008) @@ -17,13 +17,20 @@ * */ + //==================================================================================== // Crystal Space Includes //==================================================================================== #include <cssysdef.h> + #include <iutil/objreg.h> #include <iutil/plugin.h> +#include <iutil/cfgmgr.h> +#include <iutil/eventq.h> +#include <iutil/event.h> +#include <csutil/eventnames.h> + //==================================================================================== // Project Includes //==================================================================================== @@ -33,11 +40,23 @@ // Local Includes //==================================================================================== #include "soundmanager.h" + +#include "queue.h" +#include "handle.h" +#include "manager.h" +#include "psmusic.h" +#include "psemitter.h" +#include "soundctrl.h" +#include "pssoundsector.h" #include "instrumentmngr.h" SCF_IMPLEMENT_FACTORY(SoundManager) +csRandomGen SoundManager::randomGen; + +psSoundSector* SoundManager::commonSector = 0; + uint SoundManager::updateTime = DEFAULT_SECTOR_UPDATE_TIME; SoundManager::SoundManager(iBase* parent): scfImplementationType(this, parent) @@ -46,9 +65,7 @@ mainSndCtrl = 0; ambientSndCtrl = 0; musicSndCtrl = 0; - activeSector = 0; - commonSector = 0; sndSysMgr = 0; instrMgr = 0; @@ -487,7 +504,7 @@ { if(activeSector != 0) { - activeSector->SetEntityState(state, ambientSndCtrl, mesh, forceChange); + activeSector->SetEntityState(state, mesh, forceChange); } } @@ -681,7 +698,7 @@ if(activeSector != 0) { activeSector->UpdateEmitter(ambientSndCtrl); - activeSector->UpdateEntity(ambientSndCtrl, commonSector); + activeSector->UpdateEntity(ambientSndCtrl); } } lastUpdateTime = csGetTicks(); @@ -918,7 +935,7 @@ if(mesh->GetFactory() == factory) { - if(rng.Get() <= factoryemitter->factory_prob) + if(SoundManager::randomGen.Get() <= factoryemitter->factory_prob) { emitter = new psEmitter; @@ -979,7 +996,7 @@ sector->UpdateMusic(loopBGM.GetToggle(), combat, musicSndCtrl); sector->UpdateAmbient(weather, ambientSndCtrl); sector->UpdateEmitter(ambientSndCtrl); - sector->UpdateEntity(ambientSndCtrl, commonSector); + sector->UpdateEntity(ambientSndCtrl); } @@ -1105,7 +1122,7 @@ } else if(csStrCaseCmp(sectorName, commonName) == 0) { - commonSector = new psSoundSector(sector, objectReg); + SoundManager::commonSector = new psSoundSector(sector, objectReg); } else { @@ -1117,11 +1134,11 @@ } // checking if a common sector could be found - if(commonSector == 0) + if(SoundManager::commonSector == 0) { - commonSector = new psSoundSector(commonName, objectReg); + SoundManager::commonSector = new psSoundSector(commonName, objectReg); } - commonSector->active = true; // commonSector must always be active + SoundManager::commonSector->active = true; // commonSector must always be active isSectorLoaded = true; return true; @@ -1156,7 +1173,7 @@ } sectorData.DeleteAll(); - delete commonSector; + delete SoundManager::commonSector; isSectorLoaded = false; } Modified: trunk/src/plugins/common/soundmanager/soundmanager.h =================================================================== --- trunk/src/plugins/common/soundmanager/soundmanager.h 2012-01-15 14:46:41 UTC (rev 8007) +++ trunk/src/plugins/common/soundmanager/soundmanager.h 2012-01-16 02:06:14 UTC (rev 8008) @@ -24,23 +24,26 @@ // Crystal Space Includes //==================================================================================== #include <iutil/comp.h> +#include <iutil/eventh.h> //==================================================================================== // Project Includes //==================================================================================== #include <isoundmngr.h> +#include <util/pstoggle.h> -//==================================================================================== -// Local Includes -//==================================================================================== -#include "pssound.h" - //------------------------------------------------------------------------------------ // Forward Declarations //------------------------------------------------------------------------------------ struct iObjectRegistry; +class SoundQueue; +class csRandomGen; +class SoundControl; +class psSoundSector; class InstrumentManager; +class SoundSystemManager; + #define DEFAULT_SECTOR_UPDATE_TIME 50 #define DEFAULT_INSTRUMENTS_PATH "/planeshift/art/instruments.xml" #define DEFAULT_AREAS_PATH "/planeshift/soundlib/areas/" @@ -55,7 +58,10 @@ class SoundManager: public scfImplementation3<SoundManager, iSoundManager, iComponent, iEventHandler> { public: - static uint updateTime; ///< update throttle in milliseconds + // TODO this should be moved inside a ConfigManager + static uint updateTime; ///< update throttle in milliseconds. + static csRandomGen randomGen; ///< random number generator. + static psSoundSector* commonSector; ///< sector that keeps features common to all sectors. SoundManager(iBase* parent); virtual ~SoundManager(); @@ -146,15 +152,12 @@ csArray<psSoundSector*> sectorData; ///< array which contains all sector xmls - parsed psSoundSector* activeSector; ///< points to our active sector - psSoundSector* commonSector; ///< sector that keeps features common to all sectors int weather; ///< current weather state from weather.h int combat; ///< current stance float volumeDampPercent; ///< configured percent of dampening. csArray<int> dampenCtrls; ///< The controls to dampened. - csRandomGen rng; ///< random generator - csEventID evSystemOpen; ///< ID of the 'Open' event fired on system startup /** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wha...@us...> - 2012-01-16 11:44:46
|
Revision: 8009 http://planeshift.svn.sourceforge.net/planeshift/?rev=8009&view=rev Author: whacko88 Date: 2012-01-16 11:44:37 +0000 (Mon, 16 Jan 2012) Log Message: ----------- fixed couple of bugs of sound entities Modified Paths: -------------- trunk/src/plugins/common/soundmanager/psentity.cpp trunk/src/plugins/common/soundmanager/psentity.h Modified: trunk/src/plugins/common/soundmanager/psentity.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/psentity.cpp 2012-01-16 02:06:14 UTC (rev 8008) +++ trunk/src/plugins/common/soundmanager/psentity.cpp 2012-01-16 11:44:37 UTC (rev 8009) @@ -47,10 +47,10 @@ isFactoryEntity = entity->isFactoryEntity; entityName = entity->entityName; - states = csHash<EntityState*, int>(entity->states); + states = csHash<EntityState*, uint>(entity->states); // updating states references - csHash<EntityState*, int>::GlobalIterator statIter(states.GetIterator()); + csHash<EntityState*, uint>::GlobalIterator statIter(states.GetIterator()); EntityState* entityState; while(statIter.HasNext()) @@ -77,7 +77,7 @@ } // removing state parameters but only if there are no more references - csHash<EntityState*, int>::GlobalIterator statIter(states.GetIterator()); + csHash<EntityState*, uint>::GlobalIterator statIter(states.GetIterator()); EntityState* entityState; while(statIter.HasNext()) @@ -244,37 +244,34 @@ return false; } -void psEntity::SetState(int stat, bool forceChange) +/* + * If the entity is still playing the sound is not stopped so that states that change + * to a fallback state with probability 1.0 won't play a new sound until the previous + * one has been done. + */ +void psEntity::SetState(uint newState, bool forceChange) { EntityState* entityState; // check if it's already in this state or if it's defined - if(state == stat) + if(state == newState) { return; } - - // stopping previous sound if any - if(IsPlaying()) - { - handle->RemoveCallback(); - SoundSystemManager::GetSingleton().StopSound(handle->GetID()); - handle = 0; - } // setting state - entityState = states.Get(stat, 0); + entityState = states.Get(newState, 0); if(entityState == 0) { if(forceChange) { - state = -1; // undefined state + state = UNDEFINED_ENTITY_STATE; } return; } - state = stat; + state = newState; } bool psEntity::Play(SoundControl* &ctrl, csVector3 entityPosition) @@ -282,21 +279,20 @@ EntityState* entityState; // checking if a sound is still playing - if(handle != NULL) + if(IsPlaying()) { return false; } // checking if the state is defined - if(state < 0) + entityState = states.Get(state, 0); + if(entityState == 0) { return false; } - entityState = states.Get(state, 0); - // picking up randomly among resources - if(!(entityState->resources.IsEmpty())) + if(!entityState->resources.IsEmpty()) { int resourceNumber = SoundManager::randomGen.Get() * entityState->resources.GetSize(); Modified: trunk/src/plugins/common/soundmanager/psentity.h =================================================================== --- trunk/src/plugins/common/soundmanager/psentity.h 2012-01-16 02:06:14 UTC (rev 8008) +++ trunk/src/plugins/common/soundmanager/psentity.h 2012-01-16 11:44:37 UTC (rev 8009) @@ -28,6 +28,7 @@ #define DEFAULT_ENTITY_STATE 0 +#define UNDEFINED_ENTITY_STATE -1 /** * This object represents a planeshift entity sound. It can be a mesh entity, if it is @@ -156,19 +157,15 @@ bool CanPlay(int time, float range) const; /** - * Set the new state for the entity. If it is already playing a sound, - * it is stopped. + * Set the new state for the entity. If the given state is undefined for + * this entity the change of state is not forced, the state does not change. + * On the other hand if the change is forced the entity's state becomes + * UNDEFINED_ENTITY_STATE. In this state psEntity cannot play anything. * - * If the given state is undefined for this entity the change of state - * is not forced, the state does not change. On the other hand if the - * change is forced the entity goes in a special "undefined state". In - * this state psEntity cannot play anything. - * - * @param state the new state >= 0 for this entity. For negative value the - * function is not defined. + * @param state the new state for this entity. * @param forceChange true to force the state change, false otherwise. */ - void SetState(int state, bool forceChange); + void SetState(uint state, bool forceChange); /** * Force this entity to play the sound associated to its current state. @@ -218,14 +215,14 @@ bool isFactoryEntity; ///< true if this is a factory entity, false if it's a mesh entity. csString entityName; ///< name of the entity associated to this object. - int state; ///< current state of this entity. A negative value means that this entity is in an undefined state. + uint state; ///< current state of this entity. A negative value means that this entity is in an undefined state. int when; ///< counter to keep track when it has been played - zero means i may play at any time (in ms) uint id; ///< the id of the mesh object whose sound is controlled by this entity. float minRange; ///< minimum distance at which this entity can be heard float maxRange; ///< maximum distance at which this entity can be heard SoundHandle* handle; ///< pointer to the SoundHandle if playing - csHash<EntityState*, int> states; ///< entity states hash mapped by their ID. + csHash<EntityState*, uint> states; ///< entity states hash mapped by their ID. /** * The Callback gets called if the SoundHandle is destroyed. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wha...@us...> - 2012-02-06 00:26:53
|
Revision: 8062 http://planeshift.svn.sourceforge.net/planeshift/?rev=8062&view=rev Author: whacko88 Date: 2012-02-06 00:26:47 +0000 (Mon, 06 Feb 2012) Log Message: ----------- fixed instruments' noise with 16 bits samples fixed fading Modified Paths: -------------- trunk/src/plugins/common/soundmanager/handle.cpp trunk/src/plugins/common/soundmanager/instrument.cpp Modified: trunk/src/plugins/common/soundmanager/handle.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/handle.cpp 2012-02-05 16:56:02 UTC (rev 8061) +++ trunk/src/plugins/common/soundmanager/handle.cpp 2012-02-06 00:26:47 UTC (rev 8062) @@ -159,8 +159,6 @@ void SoundHandle::Fade(float volume, int time, int direction) { - volume = volume * sndCtrl->GetVolume() * SoundSystemManager::GetSingleton().mainSndCtrl->GetVolume(); - // setting new steady state volume if(direction == FADE_UP) { @@ -173,6 +171,16 @@ fadeSteps = -time / FADE_TIMESTEP; } + // checking boundaries + if(currentVolume < VOLUME_ZERO) + { + currentVolume = VOLUME_ZERO; + } + else if(currentVolume > VOLUME_MAX) + { + currentVolume = VOLUME_MAX; + } + // there must be at least one step or the volume don't change if(fadeSteps == 0) { Modified: trunk/src/plugins/common/soundmanager/instrument.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/instrument.cpp 2012-02-05 16:56:02 UTC (rev 8061) +++ trunk/src/plugins/common/soundmanager/instrument.cpp 2012-02-06 00:26:47 UTC (rev 8062) @@ -105,6 +105,12 @@ // * number of bytes per sample * number of channels requestedBytes = format->Freq * duration * (format->Bits / 8) * format->Channels; + // if the frame has 16 bits we must return an even number of bytes + if(requestedBytes % 2 != 0 && format->Bits / 8 == 2) + { + requestedBytes--; + } + // checking if this note is defined or if it's a rest if((oct = notes.Get(octave, 0)) != 0) { @@ -180,8 +186,21 @@ // #bytes = sample frequency * duration of the note * // * number of bytes per sample * number of channels requestedBytes = format->Freq * duration * (format->Bits / 8) * format->Channels; - phaseShift = format->Freq * 0.3 * (format->Bits / 8) * format->Channels; + phaseShift = format->Freq * 0.3 * (format->Bits / 8) * format->Channels; + // if the frame has 16 bits we must return an even number of bytes + if(format->Bits / 8 == 2) + { + if(requestedBytes % 2 != 0) + { + requestedBytes--; + } + if(phaseShift % 2 != 0) + { + phaseShift--; + } + } + // selecting the note switch(alter) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wha...@us...> - 2012-03-18 12:01:47
|
Revision: 8117 http://planeshift.svn.sourceforge.net/planeshift/?rev=8117&view=rev Author: whacko88 Date: 2012-03-18 12:01:40 +0000 (Sun, 18 Mar 2012) Log Message: ----------- forgot sector manager in the previous commit Added Paths: ----------- trunk/src/plugins/common/soundmanager/sectormngr.cpp trunk/src/plugins/common/soundmanager/sectormngr.h Added: trunk/src/plugins/common/soundmanager/sectormngr.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/sectormngr.cpp (rev 0) +++ trunk/src/plugins/common/soundmanager/sectormngr.cpp 2012-03-18 12:01:40 UTC (rev 8117) @@ -0,0 +1,560 @@ +/* + * sectormngr.cpp, Author: Andrea Rizzi <88w...@gm...> + * + * Copyright (C) 2001-2012 Atomic Blue (in...@pl..., http://www.atomicblue.org) + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation (version 2 of the License) + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include "sectormngr.h" + +//==================================================================================== +// Crystal Space Includes +//==================================================================================== +#include <iutil/cfgmgr.h> +#include <iutil/stringarray.h> + +#include <iengine/engine.h> +#include <iengine/sector.h> +#include <iengine/mesh.h> +#include <iengine/movable.h> + +//==================================================================================== +// Project Includes +//==================================================================================== +#include <util/psxmlparser.h> + +//==================================================================================== +// Local Includes +//==================================================================================== +#include "soundmanager.h" +#include "manager.h" +#include "psmusic.h" +#include "psemitter.h" +#include "pssoundsector.h" + +//------------------------------------------------------------------------------------ +// Forward Declarations +//------------------------------------------------------------------------------------ +#define DEFAULT_AREAS_PATH "/planeshift/soundlib/areas/" +#define DEFAULT_COMMON_SECTOR_NAME "common" + + +SoundSectorManager::SoundSectorManager() +{ + // subscribing to sound ambients and music control events + musicSndCtrl = SoundSystemManager::GetSingleton().GetSoundControl(iSoundManager::MUSIC_SNDCTRL); + ambientSndCtrl = SoundSystemManager::GetSingleton().GetSoundControl(iSoundManager::AMBIENT_SNDCTRL); + musicSndCtrl->Subscribe(this); + ambientSndCtrl->Subscribe(this); + + weather = 1; // 1 is sunshine + timeOfDay = 0; + combatStance = iSoundManager::PEACE; + loopBGM = true; + isCombatMusicOn = true; + + areSectorsLoaded = false; + activeSector = 0; + commonSector = 0; +} + +SoundSectorManager::~SoundSectorManager() +{ + UnloadSectors(); +} + +bool SoundSectorManager::Initialize(iObjectRegistry* objReg) +{ + objectReg = objReg; + + return LoadSectors(); +} + +bool SoundSectorManager::LoadSectors() +{ + csString commonName; + const char* areasPath; + csRef<iVFS> vfs; + csRef<iStringArray> files; + csRef<iDataBuffer> expandedPath; + + // check if sectors have been already loaded + if(areSectorsLoaded) + { + return true; + } + + // loading configuration + csRef<iConfigManager> configManager = csQueryRegistry<iConfigManager>(objectReg); + if(configManager != 0) + { + areasPath = configManager->GetStr("Planeshift.Sound.AreasPath", DEFAULT_AREAS_PATH); + commonName = configManager->GetStr("Planeshift.Sound.CommonSector", DEFAULT_COMMON_SECTOR_NAME); + } + else + { + areasPath = DEFAULT_AREAS_PATH; + commonName = DEFAULT_COMMON_SECTOR_NAME; + } + + // retrieving all definition files + vfs = csQueryRegistry<iVFS>(objectReg); + if(vfs == 0) + { + return false; + } + + expandedPath = vfs->ExpandPath(areasPath); + files = vfs->FindFiles(expandedPath->GetData()); + + if(files == 0) + { + return false; + } + + // the common sector is always initialized and must always be active + commonSector = new psSoundSector(objectReg); + commonSector->name = commonName; + commonSector->active = true; + + // parsing files + for(size_t i = 0; i < files->GetSize(); i++) + { + csString fileName = files->Get(i); + csRef<iDocument> doc; + csRef<iDocumentNode> rootNode; + csRef<iDocumentNode> mapNode; + csRef<iDocumentNodeIterator> sectorIter; + + // getting root + doc = ParseFile(objectReg, fileName); + if(doc == 0) + { + continue; + } + + rootNode = doc->GetRoot(); + if(rootNode == 0) + { + continue; + } + + mapNode = rootNode->GetNode("MAP_SOUNDS"); + if(mapNode == 0) + { + continue; + } + + // parsing sectors + sectorIter = mapNode->GetNodes("SECTOR"); + while(sectorIter->HasNext()) + { + psSoundSector* sector; + csRef<iDocumentNode> sectorNode = sectorIter->Next(); + csString sectorName = sectorNode->GetAttributeValue("NAME"); + + // the common sector is not kept together with the others + if(sectorName == commonName) + { + // common sector has been already initialized + sector = commonSector; + } + else + { + sector = FindSector(sectorName); + } + + // create new sector or append new definition + if(sector == 0) + { + sector = new psSoundSector(sectorNode, objectReg); + sectors.Push(sector); + } + else + { + sector->Load(sectorNode); + } + } + } + + areSectorsLoaded = true; + return true; +} + +/** + * Delete both the sectors and commonSector + */ +void SoundSectorManager::UnloadSectors() +{ + if(!areSectorsLoaded) + { + return; + } + + for(size_t i = 0; i < sectors.GetSize(); i++) + { + delete sectors[i]; + } + sectors.DeleteAll(); + + delete commonSector; + + // updating state + commonSector = 0; + activeSector = 0; + areSectorsLoaded = false; +} + +bool SoundSectorManager::ReloadSectors() +{ + csString currentSector; + + if(!areSectorsLoaded) + { + return false; + } + + currentSector = activeSector->name; + UnloadSectors(); + LoadSectors(); + SetActiveSector(currentSector); + + return areSectorsLoaded; +} + +void SoundSectorManager::Update() +{ + if(activeSector == 0) + { + return; + } + + activeSector->UpdateEmitter(ambientSndCtrl); + activeSector->UpdateEntity(ambientSndCtrl); +} + +void SoundSectorManager::SetLoopBGMToggle(bool toggle) +{ + loopBGM = toggle; + + if(activeSector != 0) + { + activeSector->UpdateMusic(loopBGM, combatStance, musicSndCtrl); + } +} + +void SoundSectorManager::SetCombatMusicToggle(bool toggle) +{ + isCombatMusicOn = toggle; + + // this updates puts the combat stance to PEACE if combat music + // has been disabled and updates the music + SetCombatStance(combatStance); +} + +/* + * FACTORY Emitters are converted to real EMITTERS (if not already done) + * it also moves background and ambient music into the new sector + * if they are not changing and are already playing + * unused music and sounds will be unloaded + */ +bool SoundSectorManager::SetActiveSector(const char* sectorName) +{ + psSoundSector* oldSector; + psSoundSector* newSector; + + if(!areSectorsLoaded) + { + return false; + } + + // checking if the new active sector is already active + if(activeSector != 0) + { + if(activeSector->name == sectorName) + { + return true; + } + } + + // if the new active sector doesn't exist fail + newSector = FindSector(sectorName); + if(newSector == 0) + { + return false; + } + + oldSector = activeSector; + activeSector = newSector; + activeSector->active = true; + + /* works only on loaded sectors! */ + ConvertFactoriesToEmitter(activeSector); + + if(oldSector != NULL) + { + /* + * hijack active ambient and music if they are played in the new sector + * in the old sector there MUST be only ONE of each + */ + + TransferHandles(oldSector, activeSector); + + /* set old sector to inactive and make a update (will stop all sounds) */ + oldSector->active = false; + UpdateSector(oldSector); + + } + + /* + * Call Update start sound in the new sector + */ + + UpdateSector(activeSector); + return true; +} + +psSoundSector* SoundSectorManager::FindSector(const csString §orName) const +{ + for(size_t i = 0; i< sectors.GetSize(); i++) + { + if(sectorName == sectors[i]->name) + { + return sectors[i]; + } + } + + return 0; +} + +void SoundSectorManager::UpdateSector(psSoundSector* sector) +{ + sector->UpdateMusic(loopBGM, combatStance, musicSndCtrl); + sector->UpdateAmbient(weather, ambientSndCtrl); + sector->UpdateEmitter(ambientSndCtrl); + sector->UpdateEntity(ambientSndCtrl); +} + +void SoundSectorManager::ConvertFactoriesToEmitter(psSoundSector* sndSector) +{ + psEmitter* newEmitter; + psEmitter* factoryEmitter; + + iMeshList* meshes; + iMeshWrapper* mesh; + iMeshFactoryWrapper* factory; + iSector* engineSector; + csRef<iEngine> engine; + + + engine = csQueryRegistry<iEngine>(objectReg); + if(!engine) + { + Error1("No iEngine plugin!"); + return; + } + + /* + * convert emitters with factory attributes to real emitters + * positions are random but are only generated once + */ + + for(size_t j = 0; j< sndSector->emitterarray.GetSize(); j++) + { + factoryEmitter = sndSector->emitterarray[j]; + + if(factoryEmitter->factory.IsEmpty()) + { + // this is not a factory emitter + continue; + } + + engineSector = engine->FindSector(sndSector->name, 0); + if(engineSector == 0) + { + Error2("sector %s not found\n", (const char*)sndSector); + continue; + } + + factory = engine->GetMeshFactories()->FindByName(factoryEmitter->factory); + if(factory == 0) + { + Error2("Could not find factory name %s", (const char*)factoryEmitter->factory); + continue; + } + + // creating an emitter for each mesh of that factory + meshes = engineSector->GetMeshes(); + for(int k = 0; k < meshes->GetCount(); k++) + { + mesh = meshes->Get(k); + + if(mesh->GetFactory() == factory) + { + if(SoundManager::randomGen.Get() <= factoryEmitter->factory_prob) + { + newEmitter = new psEmitter; + + newEmitter->resource = csString(factoryEmitter->resource); + newEmitter->minvol = factoryEmitter->minvol; + newEmitter->maxvol = factoryEmitter->maxvol; + newEmitter->maxrange = factoryEmitter->maxrange; + newEmitter->position = mesh->GetMovable()->GetPosition(); + newEmitter->active = false; + + sndSector->emitterarray.Push(newEmitter); + } + } + } + + // the factory emitter is not needed anymore + sndSector->DeleteEmitter(factoryEmitter); + } +} + +/* +* Transfer ambient/music Handles from oldSector to newSector if needed +* if loopBGM is false then the handle might be invalid +* this is no problem because we dont touch it +* all we do is copy the address +*/ +void SoundSectorManager::TransferHandles(psSoundSector* oldSector, + psSoundSector* newSector) +{ + for(size_t j = 0; j< newSector->musicarray.GetSize(); j++) + { + if(oldSector->activemusic == NULL) + { + break; + } + + if(csStrCaseCmp(newSector->musicarray[j]->resource, + oldSector->activemusic->resource) == 0) + { + /* yay active resource with the same name - steal the handle*/ + newSector->musicarray[j]->handle = oldSector->activemusic->handle; + /* set handle to NULL */ + oldSector->activemusic->handle = NULL; + newSector->activemusic = newSector->musicarray[j]; + /* set the sound to active */ + newSector->musicarray[j]->active = true; + /* set it to inactive to prevent damage on the handle */ + oldSector->activemusic->active = false; + /* set it to NULL to avoid problems */ + oldSector->activemusic = NULL; + /* update callback */ + newSector->activemusic->UpdateHandleCallback(); + } + } + + for(size_t j = 0; j< activeSector->ambientarray.GetSize(); j++) + { + if(oldSector->activeambient == NULL) + { + break; + } + + if(csStrCaseCmp(newSector->ambientarray[j]->resource, + oldSector->activeambient->resource) == 0) + { + /* yay active resource with the same name - steal the handle*/ + newSector->ambientarray[j]->handle = oldSector->activeambient->handle; + /* set handle to NULL */ + oldSector->activeambient->handle = NULL; + newSector->activeambient = newSector->ambientarray[j]; + /* set the sound to active */ + newSector->ambientarray[j]->active = true; + /* set it to inactive to prevent damage on the handle */ + oldSector->activeambient->active = false; + /* set it to NULL to avoid problems */ + oldSector->activeambient = NULL; + /* update callback */ + newSector->activeambient->UpdateHandleCallback(); + } + } +} + +void SoundSectorManager::SetCombatStance(int newCombatStance) +{ + if(isCombatMusicOn) + { + combatStance = newCombatStance; + } + else + { + combatStance = iSoundManager::PEACE; + } + + if(activeSector != 0) + { + activeSector->UpdateMusic(loopBGM, combatStance, musicSndCtrl); + } +} + +void SoundSectorManager::SetTimeOfDay(int newTimeOfDay) +{ + timeOfDay = newTimeOfDay; + + if(activeSector != 0) + { + // ambient and music are not touched at every update + activeSector->UpdateAmbient(weather, ambientSndCtrl); + activeSector->UpdateMusic(loopBGM, combatStance, musicSndCtrl); + } +} + +void SoundSectorManager::SetWeather(int newWeather) +{ + // Engine calls SetWeather every frame, update is + // only called if weather is changing + if(weather != newWeather) + { + weather = newWeather; + + if(activeSector != 0) + { + activeSector->UpdateAmbient(weather, ambientSndCtrl); + } + } +} + +void SoundSectorManager::SetEntityState(int state, iMeshWrapper* mesh, bool forceChange) +{ + if(activeSector != 0) + { + activeSector->SetEntityState(state, mesh, forceChange); + } +} + +//---------------------------- +// FROM iSoundControlListener +//---------------------------- + +void SoundSectorManager::OnSoundChange(SoundControl* sndCtrl) +{ + if(activeSector == 0) + { + return; + } + + if(sndCtrl == musicSndCtrl) + { + activeSector->UpdateMusic(loopBGM, combatStance, musicSndCtrl); + } + else if(sndCtrl == ambientSndCtrl) + { + activeSector->UpdateAmbient(weather, ambientSndCtrl); + } +} \ No newline at end of file Property changes on: trunk/src/plugins/common/soundmanager/sectormngr.cpp ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:eol-style + native Added: trunk/src/plugins/common/soundmanager/sectormngr.h =================================================================== --- trunk/src/plugins/common/soundmanager/sectormngr.h (rev 0) +++ trunk/src/plugins/common/soundmanager/sectormngr.h 2012-03-18 12:01:40 UTC (rev 8117) @@ -0,0 +1,237 @@ +/* + * sectormngr.h, Author: Andrea Rizzi <88w...@gm...> + * + * Copyright (C) 2001-2012 Atomic Blue (in...@pl..., http://www.atomicblue.org) + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation (version 2 of the License) + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef SND_SECTOR_MNGR_H +#define SND_SECTOR_MNGR_H + + +//==================================================================================== +// Crystal Space Includes +//==================================================================================== +#include <cssysdef.h> + +//==================================================================================== +// Project Includes +//==================================================================================== +#include "util/singleton.h" + +//==================================================================================== +// Local Includes +//==================================================================================== +#include "soundctrl.h" + +//------------------------------------------------------------------------------------ +// Forward Declarations +//------------------------------------------------------------------------------------ +class csString; +class SoundControl; +class psSoundSector; +struct iMeshWrapper; +struct iObjectRegistry; + +/** + * This class handles every sound defined in a sector. It basically controls all + * sounds that comes from the 3D world. + */ +class SoundSectorManager: public iSoundControlListener, public Singleton<SoundSectorManager> +{ +public: + + /** + * Constructor. + */ + SoundSectorManager(); + + /** + * Destructor. + */ + ~SoundSectorManager(); + + /** + * Load all sound sectors defined in XML files stored in the areas folder. Its + * path is defined in the option Planeshift.Sound.AreasPath of the configuration + * file. + * @param objectReg the object registry. + * @return true if sectors could be loaded, false otherwise. + */ + bool Initialize(iObjectRegistry* objectReg); + + /** + * Unload all sound sectors. + */ + void UnloadSectors(); + + /** + * Reload all sound sectors from XML definition. If SoundSectorManager has not + * been already initialized nothing happens. + * @return true if sectors could be loaded again, false otherwise. + */ + bool ReloadSectors(); + + /** + * Update the active sector. + */ + void Update(); + + /** + * Checks if the background music loop is allowed. + * @return true if the background music loop is allowed, false otherwise. + */ + bool IsLoopBGMOn() const { return loopBGM; } + + /** + * Toggles the background music. + * @param toggle true to make the background music to loop. + */ + void SetLoopBGMToggle(bool toggle); + + /** + * Checks if the combat music is activated. + * @return true if the combat music is activated, false otherwise. + */ + bool IsCombatMusicOn() const { return isCombatMusicOn; } + + /** + * Toggles the combat music. + * @param toggle true to activate the combat music. + */ + void SetCombatMusicToggle(bool toggle); + + /** + * Gets the common sector. + * @return the common sector. + */ + psSoundSector* GetCommonSector() { return commonSector; } + + /** + * Sets the current active sector to the one with the given name and deactivate + * the previous one (if any). If no sound sector with that name is found, nothing + * change. + * @return true if the given sector exists, false otherwise. + */ + bool SetActiveSector(const char* sectorName); + + /** + * Gets the current combat stance. + * @return the current combat stance. + */ + int GetCombatStance() const { return combatStance; } + + /** + * Sets the current combat stance. + * @param newCombatStance the new combat stance. + */ + void SetCombatStance(int newCombatStance); + + /** + * Gets the time of the day. + * @return the time of the day. + */ + int GetTimeOfDay() const { return timeOfDay; } + + /** + * Sets the current time of the day. + * @param newTimeOfDay the new time of the day. + */ + void SetTimeOfDay(int newTimeOfDay); + + /** + * Sets the current weather. + * @param newWeather the new weather. + */ + void SetWeather(int newWeather); + + /** + * Sets the new state for the entity associated to the given mesh. If + * it is already playing a sound, it is stopped. + * + * @param state the new state >= 0 for the entity. For negative value + * the function is not defined. + * @param mesh the mesh associated to the entity. + * @param forceChange if it is false the entity does not change its + * state if the new one is not defined. If it is true the entity stops + * play any sound until a new valid state is defined. + */ + void SetEntityState(int state, iMeshWrapper* mesh, bool forceChange); + + + // From iSoundControlListener + //----------------------------- + virtual void OnSoundChange(SoundControl* sndCtrl); + +private: + csRef<iObjectRegistry> objectReg; ///< object registry. + + int weather; ///< current weather state (from weather.h). + int timeOfDay; ///< time of the day. + int combatStance; ///< current combat stance. + + bool loopBGM; ///< true if background music should loop. + bool isCombatMusicOn; ///< true if combat music is active. + + SoundControl* musicSndCtrl; ///< cache of SoundControl for music. + SoundControl* ambientSndCtrl; ///< cache of SoundControl for ambient sounds. + + bool areSectorsLoaded; ///< true if the sectors are already loaded. + psSoundSector* activeSector; ///< current active sector. + psSoundSector* commonSector; ///< sector that keeps features common to all sectors. + csArray<psSoundSector*> sectors; ///< array which contains all sectors. + + /** + * Load all sectors from the XML definition; areasPath and commonName must + * have been initialized before calling this method. If a sector is defined + * twice, the new definition is "appended" to the old one so it is possible + * to split a sector definition in more than a file. + * @return true if the loading was successful, false otherwise. + */ + bool LoadSectors(); + + /** + * Find sector by name. + * @param sectorName name of the sector to search. + * @return the sector or 0 if it could not be found. + */ + psSoundSector* FindSector(const csString §orName) const; + + /** + * Update a whole sector. + * @param sector SoundSector to update. + */ + void UpdateSector(psSoundSector* sector); + + /** + * Converts the sector's factory emitters to real emitters. After + * conversion the factory emitters are removed. + * @param sector the sound sector that needs the conversion. + */ + void ConvertFactoriesToEmitter(psSoundSector* sector); + + /** + * Transfers handle from a psSoundSector to a another psSoundSector + * Moves SoundHandle and takes care that everything remains valid. + * Good example on what is possible with all those interfaces. + * @param oldSector sector to move from + * @param newSector sector to move to + */ + void TransferHandles(psSoundSector* oldSector, psSoundSector* newSector); + +}; + +#endif /* SND_SECTOR_MNGR_H */ + Property changes on: trunk/src/plugins/common/soundmanager/sectormngr.h ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wha...@us...> - 2012-04-11 23:18:05
|
Revision: 8204 http://planeshift.svn.sourceforge.net/planeshift/?rev=8204&view=rev Author: whacko88 Date: 2012-04-11 23:17:59 +0000 (Wed, 11 Apr 2012) Log Message: ----------- moved header include into cpp fixed setting state of entities Modified Paths: -------------- trunk/src/plugins/common/soundmanager/psentity.cpp trunk/src/plugins/common/soundmanager/psentity.h trunk/src/plugins/common/soundmanager/pssoundsector.cpp Modified: trunk/src/plugins/common/soundmanager/psentity.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/psentity.cpp 2012-04-11 15:14:42 UTC (rev 8203) +++ trunk/src/plugins/common/soundmanager/psentity.cpp 2012-04-11 23:17:59 UTC (rev 8204) @@ -25,7 +25,9 @@ #include "pssound.h" #include "soundmanager.h" +#include "util/log.h" + psEntity::psEntity(bool isFactory, const char* name) { isFactoryEntity = isFactory; Modified: trunk/src/plugins/common/soundmanager/psentity.h =================================================================== --- trunk/src/plugins/common/soundmanager/psentity.h 2012-04-11 15:14:42 UTC (rev 8203) +++ trunk/src/plugins/common/soundmanager/psentity.h 2012-04-11 23:17:59 UTC (rev 8204) @@ -26,7 +26,6 @@ #ifndef _PSENTITY_H_ #define _PSENTITY_H_ -#include "util/log.h" #define DEFAULT_ENTITY_STATE 0 #define UNDEFINED_ENTITY_STATE -1 Modified: trunk/src/plugins/common/soundmanager/pssoundsector.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/pssoundsector.cpp 2012-04-11 15:14:42 UTC (rev 8203) +++ trunk/src/plugins/common/soundmanager/pssoundsector.cpp 2012-04-11 23:17:59 UTC (rev 8204) @@ -422,7 +422,7 @@ const csPDelArray<GEMClientObject>& entities = psengine->GetCelClient()->GetEntities(); - for(int a = 0; a < entities.GetSize(); a++) + for(size_t a = 0; a < entities.GetSize(); a++) { // filter actors only GEMClientObject* object = entities[a]; @@ -513,7 +513,6 @@ void psSoundSector::SetEntityState(int state, GEMClientActor* actor, bool forceChange) { uint meshID; - bool isTemporary; psEntity* entity; Debug3(LOG_SOUND, 0, "psSoundSector::SetEntityState START state: %d meshid: %u",state, actor->GetMesh()->QueryObject()->GetID()); @@ -524,29 +523,25 @@ } meshID = actor->GetMesh()->QueryObject()->GetID(); - isTemporary = entity->IsTemporary(); // if the new state isn't DEFAULT_ENTITY_STATE, a new entity must be created so that // when it will satisfies the conditions to play (for example when the distance from // the player gets enough short), the entity's state will be the correct one. If the // new state is DEFAULT_ENTITY_STATE, the entity will be created only when conditions // will be satisfied. - if(!isTemporary && state != DEFAULT_ENTITY_STATE) + if(!entity->IsTemporary() && state != DEFAULT_ENTITY_STATE) { entity = new psEntity(entity); entity->SetMeshID(meshID); tempEntities.Put(meshID, entity); } - // Talad: I commented out this piece as I don't understand it and - // was preventing monsters to play anything. To be discussed with Lucubro. - // applying state change only if it's a temporary entity - //if(isTemporary) - //{ + if(entity->IsTemporary()) + { entity->SetState(state, forceChange); return; - //} + } } void psSoundSector::Load(csRef<iDocumentNode> sectorNode) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <lpa...@us...> - 2012-05-31 22:18:46
|
Revision: 8342 http://planeshift.svn.sourceforge.net/planeshift/?rev=8342&view=rev Author: lpancallo Date: 2012-05-31 22:18:40 +0000 (Thu, 31 May 2012) Log Message: ----------- Fixed debug messages to be less spammy. Ready to test! Modified Paths: -------------- trunk/src/plugins/common/soundmanager/psentity.cpp trunk/src/plugins/common/soundmanager/psentity.h trunk/src/plugins/common/soundmanager/pssoundsector.cpp Modified: trunk/src/plugins/common/soundmanager/psentity.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/psentity.cpp 2012-05-31 22:09:20 UTC (rev 8341) +++ trunk/src/plugins/common/soundmanager/psentity.cpp 2012-05-31 22:18:40 UTC (rev 8342) @@ -231,26 +231,27 @@ entityState = states.Get(state, 0); if(entityState == 0) { - Debug2(LOG_SOUND, 0, "psEntity::CanPlay %s undefined state.", entityName.GetData()); + Debug3(LOG_SOUND, 0, "psEntity::CanPlay %s meshid: %u undefined state.", entityName.GetData(), GetMeshID()); return false; } // checking time, range and delay if(range < minRange || range > maxRange) { - Debug5(LOG_SOUND, 0, "psEntity::CanPlay %s range %f %f %f", entityName.GetData(),minRange, range, maxRange); + Debug6(LOG_SOUND, 0, "psEntity::CanPlay %s meshid: %u range %f %f %f", entityName.GetData(),GetMeshID(), minRange, range, maxRange); return false; } else if(time < entityState->timeOfDayStart || entityState->timeOfDayEnd < time) { - Debug5(LOG_SOUND, 0, "psEntity::CanPlay %s time of day %d %d %d", entityName.GetData(),entityState->timeOfDayStart,time,entityState->timeOfDayEnd); + Debug6(LOG_SOUND, 0, "psEntity::CanPlay %s meshid: %u time of day %d %d %d", entityName.GetData(),GetMeshID(), entityState->timeOfDayStart,time,entityState->timeOfDayEnd); return false; } else if(when <= 0) { - Debug3(LOG_SOUND, 0, "psEntity::CanPlay TRUE %s when <0 : %d", entityName.GetData(),when); + Debug4(LOG_SOUND, 0, "psEntity::CanPlay TRUE %s meshid: %u when <0 : %d", entityName.GetData(),GetMeshID(), when); return true; } + Debug4(LOG_SOUND, 0, "psEntity::CanPlay %s meshid: %u when : %d", entityName.GetData(),GetMeshID(), when); return false; } @@ -264,14 +265,14 @@ { EntityState* entityState; - Debug3(LOG_SOUND, 0, "psEntity::SetState entity: %s state: %u",entityName.GetData(),newState); - // check if it's already in this state or if it's defined if(state == newState) { return; } + Debug3(LOG_SOUND, 0, "psEntity::SetState entity: %s state: %u",entityName.GetData(),newState); + // setting state entityState = states.Get(newState, 0); if(entityState == 0) @@ -309,7 +310,7 @@ { int resourceNumber = SoundManager::randomGen.Get() * entityState->resources.GetSize(); - Debug3(LOG_SOUND, 0, "psEntity::Play() PLAYS! %s",entityName.GetData(),entityState->resources[resourceNumber]); + Debug4(LOG_SOUND, 0, "psEntity::Play() %s PLAYS %s meshid: %u",entityName.GetData(),entityState->resources[resourceNumber],GetMeshID()); if(SoundSystemManager::GetSingleton().Play3DSound(entityState->resources[resourceNumber], DONT_LOOP, 0, 0, entityState->volume, ctrl, entityPosition, 0, minRange, maxRange, Modified: trunk/src/plugins/common/soundmanager/psentity.h =================================================================== --- trunk/src/plugins/common/soundmanager/psentity.h 2012-05-31 22:09:20 UTC (rev 8341) +++ trunk/src/plugins/common/soundmanager/psentity.h 2012-05-31 22:18:40 UTC (rev 8342) @@ -180,6 +180,14 @@ bool CanPlay(int time, float range) const; /** + * Gets the state of the entity + */ + uint GetState() + { + return state; + }; + + /** * Set the new state for the entity. If the given state is undefined for * this entity the change of state is not forced, the state does not change. * On the other hand if the change is forced the entity's state becomes Modified: trunk/src/plugins/common/soundmanager/pssoundsector.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/pssoundsector.cpp 2012-05-31 22:09:20 UTC (rev 8341) +++ trunk/src/plugins/common/soundmanager/pssoundsector.cpp 2012-05-31 22:18:40 UTC (rev 8342) @@ -342,7 +342,6 @@ float range; csVector3 rangeVec; - iMeshWrapper* mesh; rangeVec = entity->GetPosition() - listenerPos; range = rangeVec.Norm(); @@ -554,13 +553,15 @@ uint meshID; psEntity* entity; - Debug3(LOG_SOUND, 0, "psSoundSector::SetEntityState START state: %d meshid: %u",state, mesh->QueryObject()->GetID()); entity = GetAssociatedEntity(mesh, actorName); if(entity == 0) { return; } + if(state!=entity->GetState()) + Debug4(LOG_SOUND, 0, "psSoundSector::SetEntityState %s state: %d meshid: %u",entity->GetEntityName().GetData(),state, mesh->QueryObject()->GetID()); + meshID = mesh->QueryObject()->GetID(); // if the new state isn't DEFAULT_ENTITY_STATE, a new entity must be created so that @@ -590,7 +591,7 @@ // if the sector is already defined the name is overwritten name = sectorNode->GetAttributeValue("NAME"); - Debug2(LOG_SOUND, 0, "Loading sector data for %s",name.GetData()); + Debug2(LOG_SOUND, 0, "Loading sound sector data for %s",name.GetData()); nodeIter = sectorNode->GetNodes("AMBIENT"); while(nodeIter->HasNext()) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wha...@us...> - 2012-11-01 17:57:44
|
Revision: 8476 http://planeshift.svn.sourceforge.net/planeshift/?rev=8476&view=rev Author: whacko88 Date: 2012-11-01 17:57:37 +0000 (Thu, 01 Nov 2012) Log Message: ----------- fixed psEntity bug when resource is not found SetEntityState now interrupt previous sounds Modified Paths: -------------- trunk/src/plugins/common/soundmanager/manager.cpp trunk/src/plugins/common/soundmanager/psentity.cpp trunk/src/plugins/common/soundmanager/psentity.h trunk/src/plugins/common/soundmanager/pssoundsector.cpp Modified: trunk/src/plugins/common/soundmanager/manager.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/manager.cpp 2012-10-28 14:13:07 UTC (rev 8475) +++ trunk/src/plugins/common/soundmanager/manager.cpp 2012-11-01 17:57:37 UTC (rev 8476) @@ -436,6 +436,7 @@ if(!handle->Init(name, loop, volume_preset, type3d, sndCtrl, dopplerEffect)) { delete handle; + handle = 0; return false; } Modified: trunk/src/plugins/common/soundmanager/psentity.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/psentity.cpp 2012-10-28 14:13:07 UTC (rev 8475) +++ trunk/src/plugins/common/soundmanager/psentity.cpp 2012-11-01 17:57:37 UTC (rev 8476) @@ -256,12 +256,7 @@ return false; } -/* - * If the entity is still playing the sound is not stopped so that states that change - * to a fallback state with probability 1.0 won't play a new sound until the previous - * one has been done. - */ -void psEntity::SetState(uint newState, bool forceChange) +void psEntity::SetState(uint newState, bool forceChange, bool setReady) { EntityState* entityState; @@ -271,8 +266,14 @@ return; } - Debug3(LOG_SOUND, 0, "psEntity::SetState entity: %s state: %u",entityName.GetData(),newState); + Debug3(LOG_SOUND, 0, "psEntity::SetState entity: %s state: %u", entityName.GetData(), newState); + if(setReady) + { + Stop(); + when = 0; // resetting delay + } + // setting state entityState = states.Get(newState, 0); if(entityState == 0) @@ -325,6 +326,16 @@ return false; } +void psEntity::Stop() +{ + if(IsPlaying()) + { + handle->RemoveCallback(); + SoundSystemManager::GetSingleton().StopSound(handle->GetID()); + handle = 0; + } +} + void psEntity::Update(int time, float distance, int interval, SoundControl* &ctrl, csVector3 entityPosition) { @@ -370,7 +381,10 @@ float prob = SoundManager::randomGen.Get(); if(prob <= currentState->fallbackProbability) { - SetState(currentState->fallbackState, true); + // If the entity is still playing the sound is not stopped so that + // states that change to a fallback state with probability 1.0 won't + // play a new sound until the previous one has been done. + SetState(currentState->fallbackState, true, false); } } } @@ -378,6 +392,6 @@ void psEntity::StopCallback(void* object) { psEntity* which = (psEntity*) object; - which->handle = NULL; + which->handle = 0; } Modified: trunk/src/plugins/common/soundmanager/psentity.h =================================================================== --- trunk/src/plugins/common/soundmanager/psentity.h 2012-10-28 14:13:07 UTC (rev 8475) +++ trunk/src/plugins/common/soundmanager/psentity.h 2012-11-01 17:57:37 UTC (rev 8476) @@ -195,8 +195,11 @@ * * @param state the new state for this entity. * @param forceChange true to force the state change, false otherwise. + * @param setReady when set to true this set the entity in the condition to + * play the new state sounds by stopping any eventual playing sound and + * resetting the delay. */ - void SetState(uint state, bool forceChange); + void SetState(uint state, bool forceChange, bool setReady); /** * Force this entity to play the sound associated to its current state. @@ -210,6 +213,11 @@ bool Play(SoundControl* &ctrl, csVector3 entityPosition); /** + * If this entity is playing, this method forces this to stop the sound. + */ + void Stop(); + + /** * Update the entity's activation status, play the sound associated with * the current state if all condition are satisfied, update the delay * and fallback in the new state if necessary. Modified: trunk/src/plugins/common/soundmanager/pssoundsector.cpp =================================================================== --- trunk/src/plugins/common/soundmanager/pssoundsector.cpp 2012-10-28 14:13:07 UTC (rev 8475) +++ trunk/src/plugins/common/soundmanager/pssoundsector.cpp 2012-11-01 17:57:37 UTC (rev 8476) @@ -435,7 +435,7 @@ } // entities have a default state as idle - entity->SetState(psModeMessage::PEACE,1); + entity->SetState(psModeMessage::PEACE, true, true); } void psSoundSector::AddObjectEntity(iMeshWrapper* mesh, const char* meshName) @@ -579,7 +579,7 @@ // applying state change only if it's a temporary entity if(entity->IsTemporary()) { - entity->SetState(state, forceChange); + entity->SetState(state, forceChange, true); return; } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |