diff --git a/src/engine/client/sound.cpp b/src/engine/client/sound.cpp index 601354160..0fd39918b 100644 --- a/src/engine/client/sound.cpp +++ b/src/engine/client/sound.cpp @@ -538,6 +538,22 @@ void CSound::StopAll() lock_release(m_SoundLock); } +bool CSound::IsPlaying(CSampleHandle SampleID) +{ + bool Ret = false; + lock_wait(m_SoundLock); + CSample *pSample = &m_aSamples[SampleID.Id()]; + for(int i = 0; i < NUM_VOICES; i++) + { + if(m_aVoices[i].m_pSample == pSample) + { + Ret = true; + } + } + lock_release(m_SoundLock); + return Ret; +} + IOHANDLE CSound::ms_File = 0; IEngineSound *CreateEngineSound() { return new CSound; } diff --git a/src/engine/client/sound.h b/src/engine/client/sound.h index b776d5dfd..1d951a8e7 100644 --- a/src/engine/client/sound.h +++ b/src/engine/client/sound.h @@ -37,6 +37,7 @@ public: virtual int Play(int ChannelID, CSampleHandle SampleID, int Flags); virtual void Stop(CSampleHandle SampleID); virtual void StopAll(); + virtual bool IsPlaying(CSampleHandle SampleID); }; #endif diff --git a/src/engine/sound.h b/src/engine/sound.h index 120d43084..b83a4e089 100644 --- a/src/engine/sound.h +++ b/src/engine/sound.h @@ -40,6 +40,7 @@ public: virtual int Play(int ChannelID, CSampleHandle Sound, int Flags) = 0; virtual void Stop(CSampleHandle Sound) = 0; virtual void StopAll() = 0; + virtual bool IsPlaying(CSampleHandle Sound) = 0; protected: inline CSampleHandle CreateSampleHandle(int Index) diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index 0c3ad2cee..24ae6abdf 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -1561,6 +1561,7 @@ void CMenus::OnInit() Console()->Chain("remove_favorite", ConchainServerbrowserUpdate, this); Console()->Chain("add_friend", ConchainFriendlistUpdate, this); Console()->Chain("remove_friend", ConchainFriendlistUpdate, this); + Console()->Chain("snd_enable_music", ConchainToggleMusic, this); m_TextureBlob = Graphics()->LoadTexture("blob.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0); @@ -2505,3 +2506,25 @@ void CMenus::RenderBackground() {CUIRect Screen = *UI()->Screen(); Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h);} } + +void CMenus::ConchainToggleMusic(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData) +{ + pfnCallback(pResult, pCallbackUserData); + CMenus *pSelf = (CMenus *)pUserData; + if(pResult->NumArguments()) + { + pSelf->ToggleMusic(); + } +} + +void CMenus::ToggleMusic() +{ + if(Client()->State() == IClient::STATE_OFFLINE) + { + if(g_Config.m_SndMusic && !m_pClient->m_pSounds->IsPlaying(SOUND_MENU)) + m_pClient->m_pSounds->Play(CSounds::CHN_MUSIC, SOUND_MENU, 1.0f); + else if(!g_Config.m_SndMusic && m_pClient->m_pSounds->IsPlaying(SOUND_MENU)) + m_pClient->m_pSounds->Stop(SOUND_MENU); + } +} + diff --git a/src/game/client/components/menus.h b/src/game/client/components/menus.h index 2d71bc243..416223a51 100644 --- a/src/game/client/components/menus.h +++ b/src/game/client/components/menus.h @@ -448,6 +448,7 @@ class CMenus : public CComponent void RenderServerbrowser(CUIRect MainView); static void ConchainFriendlistUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); static void ConchainServerbrowserUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); + static void ConchainToggleMusic(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); void SetOverlay(int Type, float x, float y, const void *pData); // found in menus_settings.cpp @@ -480,6 +481,8 @@ class CMenus : public CComponent static int PopupFilter(CMenus *pMenus, CUIRect View); IGraphics::CTextureHandle m_TextureBlob; + + void ToggleMusic(); public: void RenderBackground(); diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index 493321b65..f7a1aca58 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -1543,13 +1543,7 @@ void CMenus::RenderSettingsSound(CUIRect MainView) if(DoButton_CheckBox(&s_ButtonSndMusic, Localize("Play background music"), g_Config.m_SndMusic, &Button)) { g_Config.m_SndMusic ^= 1; - if(Client()->State() == IClient::STATE_OFFLINE) - { - if(g_Config.m_SndMusic) - m_pClient->m_pSounds->Play(CSounds::CHN_MUSIC, SOUND_MENU, 1.0f); - else - m_pClient->m_pSounds->Stop(SOUND_MENU); - } + ToggleMusic(); } Sound.HSplitTop(Spacing, 0, &Sound); diff --git a/src/game/client/components/sounds.cpp b/src/game/client/components/sounds.cpp index 9af1d8aeb..d0f1c7b51 100644 --- a/src/game/client/components/sounds.cpp +++ b/src/game/client/components/sounds.cpp @@ -192,3 +192,17 @@ void CSounds::Stop(int SetId) for(int i = 0; i < pSet->m_NumSounds; i++) Sound()->Stop(pSet->m_aSounds[i].m_Id); } + +bool CSounds::IsPlaying(int SetId) +{ + if(m_WaitForSoundJob || SetId < 0 || SetId >= g_pData->m_NumSounds) + return false; + + CDataSoundset *pSet = &g_pData->m_aSounds[SetId]; + for(int i = 0; i < pSet->m_NumSounds; i++) + { + if(Sound()->IsPlaying(pSet->m_aSounds[i].m_Id)) + return true; + } + return false; +} diff --git a/src/game/client/components/sounds.h b/src/game/client/components/sounds.h index bb1ca5bf6..54319858f 100644 --- a/src/game/client/components/sounds.h +++ b/src/game/client/components/sounds.h @@ -44,6 +44,7 @@ public: void Play(int Channel, int SetId, float Vol); void PlayAt(int Channel, int SetId, float Vol, vec2 Pos); void Stop(int SetId); + bool IsPlaying(int SetId); };