Commits

Anonymous committed 6705411

added sound preloader, sound effects

Comments (0)

Files changed (17)

 		return ()
 	endif()
 
-	FIND_LIBRARY(OGG Ogg)
-	FIND_LIBRARY(VORBIS Vorbis)
+	FIND_LIBRARY(OGG Ogg REQUIRED)
+	FIND_LIBRARY(VORBIS Vorbis REQIRED)
 	set(OGG_LIBRARIES ${OGG})
 	set(VORBIS_LIBRARIES ${VORBIS})
 	

dependencies/OgreOggSound/CMakeLists.txt

                     ${OGG_INCLUDE_DIRS}
                     ${VORBIS_INCLUDE_DIRS})
 
-LINK_LIBRARIES(${OGRE_LIBRARIES}
-               ${OPENAL_LIBRARIES}
-               ${OGG_LIBRARIES}
-               ${VORBIS_LIBRARIES})
+ADD_LIBRARY(OgreOggSound SHARED ${OGREOGGSOUND_SRCS})
 
-ADD_LIBRARY(${PROJECT_NAME} SHARED ${OGREOGGSOUND_SRCS})
+TARGET_LINK_LIBRARIES(OgreOggSound
+					  ${OGRE_LIBRARIES}
+              		  ${OPENAL_LIBRARIES}
+               		  ${OGG_LIBRARIES}
+               		  ${VORBIS_LIBRARIES})
+
+IF (WIN32)
+	SET_TARGET_PROPERTIES(Game PROPERTIES DEBUG_POSTFIX _d)
+ENDIF()

media/audio/README.txt

+thunder2_.wav: By RHumphries (http://www.freesound.org/usersViewSingle.php?id=1112)
+				rbh thunder_04 Distorted.wav (http://www.freesound.org/samplesViewSingle.php?id=2526)
+thunder.wav: By ljudman (http://www.freesound.org/usersViewSingle.php?id=65091)
+				oska.wav (http://www.freesound.org/samplesViewSingle.php?id=33246)
+rain.ogg: By acclivity (http://www.freesound.org/usersViewSingle.php?id=37876)
+			Rain30s.mp3 (http://www.freesound.org/samplesViewSingle.php?id=22037)

media/audio/preload.cfg

+# Config File for Audio Initialization process
+
+[PreloadAudio]
+# Specify here which audio files to preload
+# Format: [AudioName] = "[FileName]"
+# optional settings:
+# [AudioName].stream = ([true]/false)
+# [AudioName].loop = (true/[false])
+# [AudioName].prebuffer = (true/[false])
+# [AudioName].volume = [volume]
+# volume has to be float between 0.0 and 1.0, default is 1.0
+
+bgmusic = "rain.ogg"
+bgmusic.stream = false
+bgmusic.loop = true
+bgmusic.prebuffer = true
+bgmusic.volume = 1.0
+
+thunder = "thunder.wav"
+thunder.stream = false
+thunder.loop = false
+thunder.prebuffer = true
+thunder.volume = 0.75
+
+thunder2 = "thunder2_.wav"
+thunder2.stream = false
+thunder2.loop = false
+thunder2.prebuffer = true
+thunder2.volume = 0.75

media/audio/rain.ogg

Binary file added.

media/audio/thunder.wav

Binary file added.

media/audio/thunder2_.wav

Binary file added.

src/CMakeLists.txt

 	Tasks/CTimerTask.h
 	Tasks/CInputTask.h
 	Tasks/CVideoTask.h
-	Tasks/CStateTask.h	
+	Tasks/CStateTask.h
+	Tasks/CSoundTask.h		
 	States/CLoadingState.h
 	States/CMainMenuState.h
 	States/CGameState.h
 	Tasks/CInputTask.cpp
 	Tasks/CVideoTask.cpp
 	Tasks/CStateTask.cpp
+	Tasks/CSoundTask.cpp
 	States/CLoadingState.cpp
 	States/CMainMenuState.cpp
 	States/CGameState.cpp

src/Core/CSettingsManager.cpp

 
 }
 
+std::vector<std::string> CSettingsManager::EnumerateSection(const std::string& SectionName) {
+	// find section, return empty container if not exists
+	if (settings.find(SectionName) == settings.end())
+		return std::vector<std::string>();
+
+	// return all keys in section
+	std::vector<std::string> results;
+	std::map<std::string, boost::any>& section = settings[SectionName];
+	std::map<std::string, boost::any>::iterator it;
+	for (it = section.begin(); it != section.end(); ++it) {
+		results.push_back(it->first);
+	}
+
+	return results;
+}
+
 Ogre::NameValuePairList CSettingsManager::getVideoOptions(){
 	return this->videoOptions;
 }

src/Core/CSettingsManager.h

 	float getFloat(std::string group, std::string key, float defaultValue);
 	bool getBool(std::string group, std::string key, bool defaultValue);
 
+	std::vector<std::string> EnumerateSection(const std::string& SectionName);
+
 	Ogre::NameValuePairList getVideoOptions();
 
 };

src/States/CGameState.cpp

 }
 
 bool CGameState::Start() {
+	// play music
+	OgreOggSound::OgreOggSoundManager::getSingleton().getSound("bgmusic")->play();
+
 	// remove old scene
 	CVideoTask::ogreRenderWindow->removeAllViewports();
 
 	ogreScene->clearScene();
 	CVideoTask::ogreRoot->destroySceneManager(ogreScene);
 	CVideoTask::ogreRenderWindow->removeAllViewports();
+
+	OgreOggSound::OgreOggSoundManager::getSingleton().getSound("bgmusic")->stop();
 }
 
 void CGameState::Pause() {
 		boost::uniform_int<int> distrib(0, static_cast<int>(round(CTimerTask::FPS*2.5f)));
 		boost::variate_generator<boost::mt19937&, boost::uniform_int<int> > random_number(engine, distrib);
 		if (random_number() == 1) {
+			boost::uniform_int<int> distrib2(1, 2);
+			boost::variate_generator<boost::mt19937&, boost::uniform_int<int> > random_number2(engine, distrib2);
+
+			if (OgreOggSound::OgreOggSoundManager::getSingleton().getSound("thunder2")->isPlaying() || random_number2() == 1) {
+				OgreOggSound::OgreOggSoundManager::getSingleton().getSound("thunder")->setPlayPosition(0.0f);
+				OgreOggSound::OgreOggSoundManager::getSingleton().getSound("thunder")->play();
+			} else {
+				OgreOggSound::OgreOggSoundManager::getSingleton().getSound("thunder2")->setPlayPosition(0.0f);
+				OgreOggSound::OgreOggSoundManager::getSingleton().getSound("thunder2")->play();
+			}
 			lLightningStarted = thisFrameIndex;
 			bLightning = true;
 			ogreScene->setAmbientLight(Ogre::ColourValue(0.8, 0.8, 1.0));

src/States/CGameState.h

 #include "../GameObjects/CLevelData.h"
 #include "../GameObjects/LevelDataReader.h"
 #include "Ogre.h"
+#include "OgreOggSound.h"
+
 #include "boost/smart_ptr.hpp"
-
 #include "boost/random/uniform_int.hpp"
 #include "boost/random/variate_generator.hpp"
 #include "boost/random/mersenne_twister.hpp"

src/States/CLoadingState.cpp

 
 namespace Game {
 
+CLoadingState::StringStringMap CLoadingState::AudioNames;
+CLoadingState::StringBoolMap CLoadingState::AudioStream;
+CLoadingState::StringBoolMap CLoadingState::AudioLoop;
+CLoadingState::StringBoolMap CLoadingState::AudioPrebuffer;
+CLoadingState::StringFloatMap CLoadingState::AudioVolume;
+boost::mutex CLoadingState::AudioMutex;
+bool CLoadingState::bAudioThreadFinished;
+GameObjects::PProgressBar CLoadingState::goProgressBar;
+
 CLoadingState::CLoadingState()
 	: ogreScene(NULL),
 	  ogreViewport(NULL),
 
 		// create progress bar
 		goProgressBar = GameObjects::CProgressBar::Create("Boot/ProgressBar", "pbar");
-		goProgressBar->Setup(ResourceGroups.size(), ResourceGroups.size(), 0.7);
+		goProgressBar->Setup(ResourceGroups.size()+1, ResourceGroups.size()+1, 0.7);
 		goProgressBar->SetProgress(0.0);
 
 		Ogre::ResourceGroupManager::getSingleton().addResourceGroupListener(goProgressBar.get());
 		panel->add2D(blackLayer);
 		panel->show();
 
+		// gather sound preload information
+		CSettingsManager::GetSingleton().readConfig("media/audio/preload.cfg");
+		SetupAudioPreload();
+		bLoadAudioStarted = false;
+
 		// start loading stuff
 		for (GroupListItor it = ResourceGroups.begin(); it != ResourceGroups.end(); ++it) {
 			Ogre::ResourceGroupManager::getSingleton().initialiseResourceGroup(*it);
 	CVideoTask::ogreRenderWindow->removeAllViewports();
 }
 
+void CLoadingState::SetupAudioPreload() {
+	CSettingsManager& sm = CSettingsManager::GetSingleton();
+	std::vector<std::string> preloadKeys;
+	std::vector<std::string> configKeys = sm.EnumerateSection("PreloadAudio");
+
+	AudioNames.clear();
+	AudioLoop.clear();
+	AudioStream.clear();
+	AudioPrebuffer.clear();
+
+	if (configKeys.empty()) return;
+
+
+	// remove all keys with dot
+	std::vector<std::string>::iterator it;
+	for (it = configKeys.begin(); it != configKeys.end(); ++it) {
+		if (it->find(".") == std::string::npos && *it != "")
+			preloadKeys.push_back(*it);
+	}
+
+	// load settings for each key
+	for (it = preloadKeys.begin(); it != preloadKeys.end(); ++it) {
+		std::string key = *it;
+		std::string filename = sm.get<std::string>("PreloadAudio", key, "");
+
+		if (filename == "") continue;
+
+		bool bLoop = sm.get<bool>("PreloadAudio", key + ".loop", false);
+		bool bStream = sm.get<bool>("PreloadAudio", key + ".stream", true);
+		bool bPrebuffer = sm.get<bool>("PreloadAudio", key + ".prebuffer", false);
+		float fVolume = sm.get<float>("PreloadAudio", key + ".volume", 1.0f);
+
+		AudioNames[key] = filename;
+		AudioLoop[key] = bLoop;
+		AudioStream[key] = bStream;
+		AudioPrebuffer[key] = bPrebuffer;
+		AudioVolume[key] = fVolume;
+	}
+}
+
+void CLoadingState::AudioThreadMain() {
+	float fProgressStep = (1 - goProgressBar->GetProgress()) / (float)AudioNames.size();
+
+	for (StringStringMap::iterator it = AudioNames.begin(); it != AudioNames.end(); ++it) {
+		goProgressBar->SetComment(it->first);
+
+		std::string AudioName = it->first;
+		std::string filename = it->second;
+		bool bLoop = AudioLoop[AudioName];
+		bool bStream = AudioStream[AudioName];
+		bool bPrebuffer = AudioPrebuffer[AudioName];
+		float fVolume = AudioVolume[AudioName];
+
+		if (OgreOggSound::OgreOggSoundManager::getSingleton().createSound(AudioName, filename, bStream, bLoop, bPrebuffer))
+			OgreOggSound::OgreOggSoundManager::getSingleton().getSound(AudioName)->setVolume(fVolume);
+
+		goProgressBar->SetProgress(goProgressBar->GetProgress() + fProgressStep);
+	}
+
+	goProgressBar->SetProgress(1.0f);
+
+	{
+		boost::mutex::scoped_lock lock(AudioMutex);
+		bAudioThreadFinished = true;
+	}
+}
+
 void CLoadingState::Update() {
 	// does acutally nothing until loading is finished
 
-	if (!bFadeOut && goProgressBar->LoadingEnded()) {
-		lTimeStart = CTimerTask::thisFrameIndex;
-		bFadeOut = true;
+	// load audio when ogre loading is finishes
+	if (!bLoadAudioStarted && goProgressBar->LoadingEnded()) {
+		bLoadAudioStarted = true;
+		bAudioThreadFinished = false;
+
+		AudioThread = boost::thread(&CLoadingState::AudioThreadMain);
+		AudioThread.detach();
+	}
+
+
+	{
+		boost::mutex::scoped_lock lock(AudioMutex);
+		if (!bFadeOut && bLoadAudioStarted && bAudioThreadFinished) {
+			lTimeStart = CTimerTask::thisFrameIndex;
+			bFadeOut = true;
+		}
 	}
 
 	// fade out

src/States/CLoadingState.h

 #include "../Core/CTaskManager.h"
 #include "../Core/CLog.h"
 #include "../GameObjects/CProgressBar.h"
+#include "../Core/CSettingsManager.h"
 
 #include "CMainMenuState.h"
 
 #include "OgreFontManager.h"
 #include "OgreBorderPanelOverlayElement.h"
 #include "OgreTextAreaOverlayElement.h"
+#include "OgreOggSound.h"
 
 #include <vector>
 #include "boost/smart_ptr.hpp"
+#include "boost/thread/thread.hpp"
+#include "boost/thread/mutex.hpp"
 
 namespace Game {
 
 	GroupList ResourceGroups;
 private:
 	CLoadingState();
+	void SetupAudioPreload();
 
 	Ogre::SceneManager* ogreScene;
 	Ogre::Viewport* ogreViewport;
 	std::string sNextState;
 	PState pNextState;
 
-	GameObjects::PProgressBar goProgressBar;
+	static GameObjects::PProgressBar goProgressBar;
+
+	typedef std::map<std::string, std::string> StringStringMap;
+	typedef std::map<std::string, bool> StringBoolMap;
+	typedef std::map<std::string, float> StringFloatMap;
+
+	static StringStringMap AudioNames;
+	static StringBoolMap AudioStream;
+	static StringBoolMap AudioLoop;
+	static StringBoolMap AudioPrebuffer;
+	static StringFloatMap AudioVolume;
+	boost::thread AudioThread;
+	static boost::mutex AudioMutex;
+	static void AudioThreadMain();
+	bool bLoadAudioStarted;
+	static bool bAudioThreadFinished;
 };
 
 }

src/Tasks/CSoundTask.cpp

+/*
+ * CSoundTask.cpp
+ *
+ *  Created on: Sep 3, 2010
+ *      Author: crt
+ */
+
+#include "CSoundTask.h"
+
+namespace Game {
+
+CSoundTask::CSoundTask() {
+}
+
+CSoundTask::~CSoundTask() {
+}
+
+bool CSoundTask::Start() {
+	return OgreOggSound::OgreOggSoundManager::getSingleton().init();
+}
+
+void CSoundTask::Update() {
+	OgreOggSound::OgreOggSoundManager::getSingleton().update(CTimerTask::dT);
+}
+
+void CSoundTask::Stop() {
+	OgreOggSound::OgreOggSoundManager::getSingleton().stopAllSounds();
+	// Note: destructs automatically
+}
+
+}

src/Tasks/CSoundTask.h

+/*
+ * CSoundTask.h
+ *
+ *  Created on: Sep 3, 2010
+ *      Author: crt
+ */
+
+#ifndef CSOUNDTASK_H_
+#define CSOUNDTASK_H_
+
+#include "../Core/ITask.h"
+#include "../Core/CLog.h"
+
+#include "CTimerTask.h"
+
+#include "OgreOggSound.h"
+
+#include "boost/smart_ptr.hpp"
+
+namespace Game {
+
+class CSoundTask: public Game::ITask {
+public:
+	CSoundTask();
+	virtual ~CSoundTask();
+
+	virtual bool Start();
+	virtual void Update();
+	virtual void Stop();
+};
+
+typedef boost::shared_ptr<CSoundTask> PSoundTask;
+
+}
+
+#endif /* CSOUNDTASK_H_ */
 #include "Tasks/CTimerTask.h"
 #include "Tasks/CInputTask.h"
 #include "Tasks/CVideoTask.h"
+#include "Tasks/CSoundTask.h"
 #include "Tasks/CStateTask.h"
 #include "Core/CSettingsManager.h"
 
 	PVideoTask VideoTask(new CVideoTask());
 	PInputTask InputTask(new CInputTask());
 	PStateTask StateTask(new CStateTask());
+	PSoundTask SoundTask(new CSoundTask());
 
 	if (!TimerTask->Start()) {
 		CLog::Get().Write("TimerTask::Start failed.", CLog::logDebug);
 		return 0;
 	}
 
+	if (!SoundTask->Start()) {
+		CLog::Get().Write("SoundTask::Start failed.", CLog::logDebug);
+		return 0;
+	}
+
 	// add resource groups
 	Ogre::ResourceGroupManager::getSingleton().addResourceLocation("media/main", "FileSystem", "Main", true);
 	Ogre::ResourceGroupManager::getSingleton().addResourceLocation("media/editor", "FileSystem", "Editor", true);
 	CTaskManager::GetSingleton().AddTask(TimerTask, 10);
 	CTaskManager::GetSingleton().AddTask(InputTask, 100);
 	CTaskManager::GetSingleton().AddTask(StateTask, 500);
+	CTaskManager::GetSingleton().AddTask(SoundTask, 750);
 	CTaskManager::GetSingleton().AddTask(VideoTask, 1000);
 
 	CTaskManager::GetSingleton().Run();