diff --git a/modules/client/client.lua b/modules/client/client.lua index 8c140a08..64e84946 100644 --- a/modules/client/client.lua +++ b/modules/client/client.lua @@ -34,10 +34,16 @@ function Client.init() g_window.setTitle('OTClient') g_window.setIcon(resolvepath('clienticon.png')) + -- show the only window after the first frame is rendered scheduleEvent(function() scheduleEvent(function() g_window.show() + + -- play startup music + g_sounds.playMusic("startup.ogg", 3) + connect(g_game, { onGameStart = function() g_sounds.stopMusic(3) end }) + connect(g_game, { onGameEnd= function() g_sounds.playMusic("startup.ogg", 3) end }) end, 0) end, 0) end diff --git a/modules/client/startup.ogg b/modules/client/startup.ogg new file mode 100644 index 00000000..3897dfb1 Binary files /dev/null and b/modules/client/startup.ogg differ diff --git a/src/framework/luafunctions.cpp b/src/framework/luafunctions.cpp index 97428298..81090987 100644 --- a/src/framework/luafunctions.cpp +++ b/src/framework/luafunctions.cpp @@ -32,6 +32,7 @@ #include #include #include +#include void Application::registerLuaFunctions() { @@ -531,6 +532,19 @@ void Application::registerLuaFunctions() g_lua.bindClassStaticFunction("g_fonts", "fontExists", std::bind(&FontManager::fontExists, &g_fonts, std::placeholders::_1)); g_lua.bindClassStaticFunction("g_fonts", "setDefaultFont", std::bind(&FontManager::setDefaultFont, &g_fonts, std::placeholders::_1)); + // SoundManager + g_lua.registerStaticClass("g_sounds"); + g_lua.bindClassStaticFunction("g_sounds", "preload", std::bind(&SoundManager::preload, &g_sounds, std::placeholders::_1)); + g_lua.bindClassStaticFunction("g_sounds", "enableSound", std::bind(&SoundManager::enableSound, &g_sounds, std::placeholders::_1)); + g_lua.bindClassStaticFunction("g_sounds", "play", std::bind(&SoundManager::play, &g_sounds, std::placeholders::_1)); + g_lua.bindClassStaticFunction("g_sounds", "enableMusic", std::bind(&SoundManager::enableMusic, &g_sounds, std::placeholders::_1)); + g_lua.bindClassStaticFunction("g_sounds", "playMusic", std::bind(&SoundManager::playMusic, &g_sounds, std::placeholders::_1, std::placeholders::_2)); + g_lua.bindClassStaticFunction("g_sounds", "stopMusic", std::bind(&SoundManager::stopMusic, &g_sounds, std::placeholders::_1)); + g_lua.bindClassStaticFunction("g_sounds", "isMusicEnabled", std::bind(&SoundManager::isMusicEnabled, &g_sounds)); + g_lua.bindClassStaticFunction("g_sounds", "isSoundEnabled", std::bind(&SoundManager::isSoundEnabled, &g_sounds)); + g_lua.bindClassStaticFunction("g_sounds", "isAudioEnabled", std::bind(&SoundManager::isAudioEnabled, &g_sounds)); + g_lua.bindClassStaticFunction("g_sounds", "getCurrentMusic", std::bind(&SoundManager::getCurrentMusic, &g_sounds)); + // EventDispatcher g_lua.registerStaticClass("g_eventDispatcher"); g_lua.bindClassStaticFunction("g_eventDispatcher", "addEvent", std::bind(&EventDispatcher::addEvent, &g_eventDispatcher, std::placeholders::_1, std::placeholders::_2)); diff --git a/src/framework/sound/combinedsoundsource.cpp b/src/framework/sound/combinedsoundsource.cpp index eacc86d3..6babe2a3 100644 --- a/src/framework/sound/combinedsoundsource.cpp +++ b/src/framework/sound/combinedsoundsource.cpp @@ -94,6 +94,12 @@ void CombinedSoundSource::setVelocity(const Point& velocity) source->setVelocity(velocity); } +void CombinedSoundSource::setFading(SoundSource::FadeState state, float fadetime) +{ + for(const SoundSourcePtr& source : m_sources) + source->setFading(state, fadetime); +} + void CombinedSoundSource::update() { for(const SoundSourcePtr& source : m_sources) diff --git a/src/framework/sound/combinedsoundsource.h b/src/framework/sound/combinedsoundsource.h index 3b7ab9cf..f814e372 100644 --- a/src/framework/sound/combinedsoundsource.h +++ b/src/framework/sound/combinedsoundsource.h @@ -44,6 +44,7 @@ public: void setPitch(float pitch); void setPosition(const Point& pos); void setVelocity(const Point& velocity); + void setFading(FadeState state, float fadetime); protected: virtual void update(); diff --git a/src/framework/sound/soundmanager.cpp b/src/framework/sound/soundmanager.cpp index 8b64e21a..c29ee291 100644 --- a/src/framework/sound/soundmanager.cpp +++ b/src/framework/sound/soundmanager.cpp @@ -49,12 +49,6 @@ void SoundManager::init() m_musicEnabled = true; m_soundEnabled = true; - - /* - g_eventDispatcher.scheduleEvent([this] { - play("/1.ogg"); - }, 10); - */ } void SoundManager::terminate() @@ -160,12 +154,12 @@ void SoundManager::enableMusic(bool enable) m_musicEnabled = enable; if(enable) - playMusic(m_currentMusic); + playMusic(m_currentMusic, 3.0f); else m_musicSource = nullptr; } -void SoundManager::playMusic(const std::string& filename, bool fade) +void SoundManager::playMusic(const std::string& filename, float fadetime) { if(m_currentMusic == filename && m_musicSource) return; @@ -178,11 +172,31 @@ void SoundManager::playMusic(const std::string& filename, bool fade) m_musicSource = nullptr; return; } + + m_musicSource = createSoundSource(filename); + if(!m_musicSource) { + logError("unable to play '", filename, "'"); + return; + } + + m_musicSource->setRelative(true); + + if(fadetime > 0) { + m_musicSource->setGain(0); + m_musicSource->setFading(StreamSoundSource::FadingOn, fadetime); + } + + m_musicSource->play(); } void SoundManager::stopMusic(float fadetime) { - + if(m_musicSource) { + if(fadetime > 0) + m_musicSource->setFading(StreamSoundSource::FadingOff, 3.0f); + else + m_musicSource->stop(); + } } SoundSourcePtr SoundManager::createSoundSource(const std::string& filename) diff --git a/src/framework/sound/soundmanager.h b/src/framework/sound/soundmanager.h index 5e449076..a8748d18 100644 --- a/src/framework/sound/soundmanager.h +++ b/src/framework/sound/soundmanager.h @@ -29,22 +29,20 @@ class SoundManager { enum { MAX_CACHE_SIZE = 100000, - POLL_DELAY = 300 + POLL_DELAY = 100 }; public: void init(); void terminate(); - void poll(); void preload(const std::string& filename); - void enableSound(bool enable); void play(const std::string& filename); void enableMusic(bool enable); - void playMusic(const std::string& filename, bool fade = false); + void playMusic(const std::string& filename, float fadetime); void stopMusic(float fadetime = 0); bool isMusicEnabled() { return m_musicEnabled; } @@ -53,12 +51,13 @@ public: std::string getCurrentMusic() { return m_currentMusic; } private: + StreamSoundSourcePtr createStreamSoundSource(const std::string& filename); SoundSourcePtr createSoundSource(const std::string& filename); ALuint loadFileIntoBuffer(const SoundFilePtr& soundFile); std::map m_buffers; std::vector m_sources; - StreamSoundSourcePtr m_musicSource; + SoundSourcePtr m_musicSource; ALCdevice *m_device; ALCcontext *m_context; Boolean m_musicEnabled; diff --git a/src/framework/sound/soundsource.cpp b/src/framework/sound/soundsource.cpp index bc73865b..c03156da 100644 --- a/src/framework/sound/soundsource.cpp +++ b/src/framework/sound/soundsource.cpp @@ -23,9 +23,15 @@ #include "soundsource.h" #include "soundbuffer.h" +#include + SoundSource::SoundSource() { m_sourceId = 0; + m_fadeState = NoFading; + m_fadeTime = 0; + m_fadeStartTime = 0; + alGenSources(1, &m_sourceId); assert(alGetError() == AL_NO_ERROR); setReferenceDistance(128); @@ -105,3 +111,43 @@ void SoundSource::setVelocity(const Point& velocity) { alSource3f(m_sourceId, AL_VELOCITY, velocity.x, velocity.y, 0); } + +void SoundSource::setFading(FadeState state, float fadeTime) +{ + float now = g_clock.time(); + if(m_fadeState != NoFading) { + float elapsed = now - m_fadeStartTime; + float add; + if(m_fadeState == FadingOn) + add = -(1-(elapsed / m_fadeTime))*fadeTime; + else + add = -(elapsed / m_fadeTime)*fadeTime; + m_fadeStartTime = now + add; + } else + m_fadeStartTime = now; + + m_fadeState = state; + m_fadeTime = fadeTime; +} + +void SoundSource::update() +{ + float now = g_clock.time(); + if(m_fadeState == FadingOn) { + float elapsed = now - m_fadeStartTime; + if(elapsed >= m_fadeTime) { + setGain(1.0); + m_fadeState = NoFading; + } else { + setGain(elapsed / m_fadeTime); + } + } else if(m_fadeState == FadingOff) { + float time = now - m_fadeStartTime; + if(time >= m_fadeTime) { + stop(); + m_fadeState = NoFading; + } else { + setGain((m_fadeTime - time) / m_fadeTime); + } + } +} diff --git a/src/framework/sound/soundsource.h b/src/framework/sound/soundsource.h index ef00f8c3..b65c63cd 100644 --- a/src/framework/sound/soundsource.h +++ b/src/framework/sound/soundsource.h @@ -31,6 +31,8 @@ protected: SoundSource(ALuint sourceId) : m_sourceId(sourceId) { } public: + enum FadeState { NoFading, FadingOn, FadingOff }; + SoundSource(); virtual ~SoundSource(); @@ -45,16 +47,20 @@ public: virtual void setPitch(float pitch); virtual void setPosition(const Point& pos); virtual void setVelocity(const Point& velocity); + virtual void setFading(FadeState state, float fadetime); protected: void setBuffer(const SoundBufferPtr& buffer); - virtual void update() { } + virtual void update(); friend class SoundManager; friend class CombinedSoundSource; ALuint m_sourceId; SoundBufferPtr m_buffer; + FadeState m_fadeState; + float m_fadeStartTime; + float m_fadeTime; }; #endif diff --git a/src/framework/sound/streamsoundsource.cpp b/src/framework/sound/streamsoundsource.cpp index 87e407a3..1cfa8dc1 100644 --- a/src/framework/sound/streamsoundsource.cpp +++ b/src/framework/sound/streamsoundsource.cpp @@ -25,13 +25,11 @@ #include "soundfile.h" #include -#include StreamSoundSource::StreamSoundSource() { for(auto& buffer : m_buffers) buffer = SoundBufferPtr(new SoundBuffer); - m_fadeState = NoFading; m_downMix = NoDownMix; } @@ -85,6 +83,8 @@ void StreamSoundSource::unqueueBuffers() void StreamSoundSource::update() { + SoundSource::update(); + ALint processed = 0; alGetSourcei(m_sourceId, AL_BUFFERS_PROCESSED, &processed); for(ALint i = 0; i < processed; ++i) { @@ -103,25 +103,6 @@ void StreamSoundSource::update() logTraceError("restarting audio source because of buffer underrun"); play(); } - - float realTime = g_clock.asyncTime(); - if(m_fadeState == FadingOn) { - float time = realTime - m_fadeStartTime; - if(time >= m_fadeTime) { - setGain(1.0); - m_fadeState = NoFading; - } else { - setGain(time / m_fadeTime); - } - } else if(m_fadeState == FadingOff) { - float time = realTime - m_fadeStartTime; - if(time >= m_fadeTime) { - stop(); - m_fadeState = NoFading; - } else { - setGain((m_fadeTime - time) / m_fadeTime); - } - } } bool StreamSoundSource::fillBufferAndQueue(ALuint buffer) @@ -187,10 +168,3 @@ void StreamSoundSource::downMix(StreamSoundSource::DownMix downMix) m_downMix = downMix; } - -void StreamSoundSource::setFading(FadeState state, float fadeTime) -{ - m_fadeState = state; - m_fadeTime = fadeTime; - m_fadeStartTime = g_clock.asyncTime(); -} diff --git a/src/framework/sound/streamsoundsource.h b/src/framework/sound/streamsoundsource.h index 56646bd7..5c756706 100644 --- a/src/framework/sound/streamsoundsource.h +++ b/src/framework/sound/streamsoundsource.h @@ -35,7 +35,6 @@ class StreamSoundSource : public SoundSource public: enum DownMix { NoDownMix, DownMixLeft, DownMixRight }; - enum FadeState { NoFading, FadingOn, FadingOff }; StreamSoundSource(); virtual ~StreamSoundSource(); @@ -46,8 +45,6 @@ public: void setSoundFile(const SoundFilePtr& soundFile); void downMix(DownMix downMix); - void setFading(FadeState state, float fadetime); - FadeState getFadeState() { return m_fadeState; } void update(); @@ -59,9 +56,6 @@ private: SoundFilePtr m_soundFile; std::array m_buffers; DownMix m_downMix; - FadeState m_fadeState; - float m_fadeStartTime; - float m_fadeTime; Boolean m_looping; }; diff --git a/tools/lua-binding-generator/generate_lua_bindings.lua b/tools/lua-binding-generator/generate_lua_bindings.lua index 3a14bbd9..304acd5e 100755 --- a/tools/lua-binding-generator/generate_lua_bindings.lua +++ b/tools/lua-binding-generator/generate_lua_bindings.lua @@ -78,7 +78,7 @@ for line in io.lines(cppclassheader) do bindline = ' g_lua.bindClassStaticFunction("' .. luaclassname .. '", "' .. funcname .. '", ' .. 'std::bind(&' .. cppclassname .. "::" .. funcname .. ', &' .. cppclassinstance for i=1,numargs do - bindline = bindline .. ', _' .. i + bindline = bindline .. ', std::placeholders::_' .. i end bindline = bindline .. '));' else