summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client.cpp2
-rw-r--r--src/game.cpp4
-rw-r--r--src/sound.cpp59
-rw-r--r--src/sound.h28
4 files changed, 81 insertions, 12 deletions
diff --git a/src/client.cpp b/src/client.cpp
index 2590813f..336abfbd 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -568,6 +568,8 @@ int Client::exec()
if (game)
game->logic();
+ sound.logic();
+
++lastTickTime;
}
diff --git a/src/game.cpp b/src/game.cpp
index 7f1def50..d2d2ecfd 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -982,9 +982,9 @@ void Game::changeMap(const std::string &mapPath)
if (newMusic != oldMusic)
{
if (newMusic.empty())
- sound.stopMusic();
+ sound.fadeOutMusic();
else
- sound.playMusic(newMusic);
+ sound.fadeOutAndPlayMusic(newMusic);
}
delete mCurrentMap;
diff --git a/src/sound.cpp b/src/sound.cpp
index c64e10d8..636da7c7 100644
--- a/src/sound.cpp
+++ b/src/sound.cpp
@@ -29,16 +29,37 @@
#include "resources/resourcemanager.h"
#include "resources/soundeffect.h"
+/**
+ * This will be set to true, when a music can be freed after a fade out
+ * Currently used by fadeOutCallBack()
+ */
+static bool sFadingOutEnded = false;
+
+/**
+ * Callback used at end of fadeout.
+ * It is called by Mix_MusicFadeFinished().
+ */
+static void fadeOutCallBack()
+{
+ sFadingOutEnded = true;
+}
+
Sound::Sound():
mInstalled(false),
mSfxVolume(100),
mMusicVolume(60),
mMusic(NULL)
{
+ // This set up our callback function used to
+ // handle fade outs endings.
+ sFadingOutEnded = false;
+ Mix_HookMusicFinished(fadeOutCallBack);
}
Sound::~Sound()
{
+ // Unlink the callback function.
+ Mix_HookMusicFinished(NULL);
}
void Sound::init()
@@ -118,11 +139,6 @@ void Sound::info()
logger->log("Sound::info() Channels: %i", channels);
}
-int Sound::getMaxVolume() const
-{
- return MIX_MAX_VOLUME;
-}
-
void Sound::setMusicVolume(int volume)
{
mMusicVolume = volume;
@@ -223,8 +239,37 @@ void Sound::fadeOutMusic(int ms)
if (mMusic)
{
Mix_FadeOutMusic(ms);
- Mix_FreeMusic(mMusic);
- mMusic = NULL;
+ // Note: The fadeOutCallBack handler will take care about freeing
+ // the music file at fade out ending.
+ }
+ else
+ {
+ sFadingOutEnded = true;
+ }
+}
+
+void Sound::fadeOutAndPlayMusic(const std::string &path, int ms)
+{
+ mNextMusicPath = path;
+ fadeOutMusic(ms);
+}
+
+void Sound::logic()
+{
+ if (sFadingOutEnded)
+ {
+ if (mMusic)
+ {
+ Mix_FreeMusic(mMusic);
+ mMusic = NULL;
+ }
+ sFadingOutEnded = false;
+
+ if (!mNextMusicPath.empty())
+ {
+ playMusic(mNextMusicPath);
+ mNextMusicPath.clear();
+ }
}
}
diff --git a/src/sound.h b/src/sound.h
index bfb3837b..1dee55e7 100644
--- a/src/sound.h
+++ b/src/sound.h
@@ -68,16 +68,25 @@ class Sound
* @param path The full path to the music file.
* @param ms Duration of fade-in effect (ms)
*/
- void fadeInMusic(const std::string &path, int ms = 2000);
+ void fadeInMusic(const std::string &path, int ms = 1000);
/**
* Fades out currently running background music track.
*
* @param ms Duration of fade-out effect (ms)
*/
- void fadeOutMusic(int ms);
+ void fadeOutMusic(int ms = 1000);
- int getMaxVolume() const;
+ /**
+ * Fades out a background music and play a new one.
+ *
+ * @param path The full path to the fade in music file.
+ * @param ms Duration of fade-out effect (ms)
+ */
+ void fadeOutAndPlayMusic(const std::string &path, int ms = 1000);
+
+ int getMaxVolume() const
+ { return MIX_MAX_VOLUME; }
void setMusicVolume(int volume);
void setSfxVolume(int volume);
@@ -91,6 +100,13 @@ class Sound
*/
void playSfx(const std::string &path, int x = 0, int y = 0);
+ /**
+ * The sound logic.
+ * Currently used to check whether the music file can be freed after
+ * a fade out, and whether new music has to be played.
+ */
+ void logic();
+
private:
/** Logs various info about sound device. */
void info();
@@ -98,6 +114,12 @@ class Sound
/** Halts and frees currently playing music. */
void haltMusic();
+ /**
+ * When calling fadeOutAndPlayMusic(),
+ * the music file below will then be played
+ */
+ std::string mNextMusicPath;
+
bool mInstalled;
int mSfxVolume;