about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/engine/client/sound.cpp19
-rw-r--r--src/engine/client/sound.h2
-rw-r--r--src/engine/shared/config_variables.h1
-rw-r--r--src/engine/sound.h6
-rw-r--r--src/game/client/components/menus.cpp4
-rw-r--r--src/game/client/components/menus_settings.cpp17
-rw-r--r--src/game/client/components/sounds.cpp46
-rw-r--r--src/game/client/components/sounds.h9
-rw-r--r--src/game/client/gameclient.cpp2
9 files changed, 83 insertions, 23 deletions
diff --git a/src/engine/client/sound.cpp b/src/engine/client/sound.cpp
index 55ca2939..4678bb8a 100644
--- a/src/engine/client/sound.cpp
+++ b/src/engine/client/sound.cpp
@@ -157,8 +157,12 @@ static void Mix(short *pFinalOut, unsigned Frames)
 			
 			// free voice if not used any more
 			if(v->m_Tick == v->m_pSample->m_NumFrames)
-				v->m_pSample = 0;
-			
+			{
+				if(v->m_Flags&ISound::FLAG_LOOP)
+					v->m_Tick = 0;
+				else
+					v->m_pSample = 0;
+			}
 		}
 	}
 	
@@ -410,7 +414,7 @@ void CSound::SetListenerPos(float x, float y)
 	m_CenterX = (int)x;
 	m_CenterY = (int)y;
 }
-	
+
 
 void CSound::SetChannel(int ChannelID, float Vol, float Pan)
 {
@@ -463,11 +467,16 @@ int CSound::Play(int ChannelID, int SampleID, int Flags)
 	return Play(ChannelID, SampleID, Flags, 0, 0);
 }
 
-void CSound::Stop(int VoiceID)
+void CSound::Stop(int SampleID)
 {
 	// TODO: a nice fade out
 	lock_wait(m_SoundLock);
-	m_aVoices[VoiceID].m_pSample = 0;
+	CSample *pSample = &m_aSamples[SampleID];
+	for(int i = 0; i < NUM_VOICES; i++)
+	{
+		if(m_aVoices[i].m_pSample == pSample)
+			m_aVoices[i].m_pSample = 0;
+	}
 	lock_release(m_SoundLock);
 }
 
diff --git a/src/engine/client/sound.h b/src/engine/client/sound.h
index 0c45f1ab..3cc84d4d 100644
--- a/src/engine/client/sound.h
+++ b/src/engine/client/sound.h
@@ -31,7 +31,7 @@ public:
 	int Play(int ChannelID, int SampleID, int Flags, float x, float y);
 	virtual int PlayAt(int ChannelID, int SampleID, int Flags, float x, float y);
 	virtual int Play(int ChannelID, int SampleID, int Flags);
-	virtual void Stop(int VoiceID);
+	virtual void Stop(int SampleID);
 	virtual void StopAll();
 };
 
diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h
index c30edeaf..85749405 100644
--- a/src/engine/shared/config_variables.h
+++ b/src/engine/shared/config_variables.h
@@ -47,6 +47,7 @@ MACRO_CONFIG_INT(BrMaxRequests, br_max_requests, 25, 0, 1000, CFGFLAG_SAVE|CFGFL
 MACRO_CONFIG_INT(SndBufferSize, snd_buffer_size, 512, 0, 0, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Sound buffer size")
 MACRO_CONFIG_INT(SndRate, snd_rate, 48000, 0, 0, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Sound mixing rate")
 MACRO_CONFIG_INT(SndEnable, snd_enable, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Sound enable")
+MACRO_CONFIG_INT(SndMusic, snd_enable_music, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Play background music")
 MACRO_CONFIG_INT(SndVolume, snd_volume, 100, 0, 100, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Sound volume")
 MACRO_CONFIG_INT(SndDevice, snd_device, -1, 0, 0, CFGFLAG_SAVE|CFGFLAG_CLIENT, "(deprecated) Sound device to use")
 
diff --git a/src/engine/sound.h b/src/engine/sound.h
index 8f5dab24..ac4aeaf5 100644
--- a/src/engine/sound.h
+++ b/src/engine/sound.h
@@ -21,9 +21,9 @@ public:
 	virtual void SetChannel(int ChannelID, float Volume, float Panning) = 0;
 	virtual void SetListenerPos(float x, float y) = 0;
 	
-	virtual int PlayAt(int ChannelID, int SoundID, int Flags, float x, float y) = 0;
-	virtual int Play(int ChannelID, int SoundID, int Flags) = 0;
-	virtual void Stop(int VoiceID) = 0;
+	virtual int PlayAt(int ChannelID, int SampleID, int Flags, float x, float y) = 0;
+	virtual int Play(int ChannelID, int SampleID, int Flags) = 0;
+	virtual void Stop(int SampleID) = 0;
 	virtual void StopAll() = 0;
 };
 
diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp
index 8bed34c1..060384ec 100644
--- a/src/game/client/components/menus.cpp
+++ b/src/game/client/components/menus.cpp
@@ -8,6 +8,7 @@
 
 #include <engine/config.h>
 #include <engine/editor.h>
+#include <engine/engine.h>
 #include <engine/friends.h>
 #include <engine/graphics.h>
 #include <engine/keys.h>
@@ -20,6 +21,7 @@
 #include <game/generated/protocol.h>
 
 #include <game/generated/client_data.h>
+#include <game/client/components/sounds.h>
 #include <game/client/gameclient.h>
 #include <game/client/lineinput.h>
 #include <game/localization.h>
@@ -769,6 +771,7 @@ int CMenus::Render()
 			ServerBrowser()->Refresh(IServerBrowser::TYPE_LAN);
 		else if(g_Config.m_UiPage == PAGE_FAVORITES)
 			ServerBrowser()->Refresh(IServerBrowser::TYPE_FAVORITES);
+		m_pClient->m_pSounds->Enqueue(CSounds::CHN_MUSIC, SOUND_MENU);
 		s_First = false;
 	}
 	
@@ -1332,6 +1335,7 @@ void CMenus::OnStateChange(int NewState, int OldState)
 
 	if(NewState == IClient::STATE_OFFLINE)
 	{
+		m_pClient->m_pSounds->Play(CSounds::CHN_MUSIC, SOUND_MENU, 1.0f, vec2(0, 0));
 		m_Popup = POPUP_NONE;
 		if(Client()->ErrorString() && Client()->ErrorString()[0] != 0)
 		{
diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp
index 688f7695..959af2f3 100644
--- a/src/game/client/components/menus_settings.cpp
+++ b/src/game/client/components/menus_settings.cpp
@@ -3,7 +3,7 @@
 
 #include <base/math.h>
 
-
+#include <engine/engine.h>
 #include <engine/graphics.h>
 #include <engine/storage.h>
 #include <engine/textrender.h>
@@ -13,6 +13,7 @@
 #include <game/generated/protocol.h>
 #include <game/generated/client_data.h>
 
+#include <game/client/components/sounds.h>
 #include <game/client/ui.h>
 #include <game/client/render.h>
 #include <game/client/gameclient.h>
@@ -755,6 +756,10 @@ void CMenus::RenderSettingsSound(CUIRect MainView)
 	if(DoButton_CheckBox(&g_Config.m_SndEnable, Localize("Use sounds"), g_Config.m_SndEnable, &Button))
 	{
 		g_Config.m_SndEnable ^= 1;
+		if(g_Config.m_SndEnable)
+			m_pClient->m_pSounds->Play(CSounds::CHN_MUSIC, SOUND_MENU, 1.0f, vec2(0, 0));
+		else
+			m_pClient->m_pSounds->Stop(SOUND_MENU);
 		m_NeedRestartSound = g_Config.m_SndEnable && (!s_SndEnable || s_SndRate != g_Config.m_SndRate);
 	}
 
@@ -762,6 +767,16 @@ void CMenus::RenderSettingsSound(CUIRect MainView)
 		return;
 
 	MainView.HSplitTop(20.0f, &Button, &MainView);
+	if(DoButton_CheckBox(&g_Config.m_SndMusic, Localize("Play background music"), g_Config.m_SndMusic, &Button))
+	{
+		g_Config.m_SndMusic ^= 1;
+		if(g_Config.m_SndMusic)
+			m_pClient->m_pSounds->Play(CSounds::CHN_MUSIC, SOUND_MENU, 1.0f, vec2(0, 0));
+		else
+			m_pClient->m_pSounds->Stop(SOUND_MENU);
+	}
+
+	MainView.HSplitTop(20.0f, &Button, &MainView);
 	if(DoButton_CheckBox(&g_Config.m_SndNonactiveMute, Localize("Mute when not active"), g_Config.m_SndNonactiveMute, &Button))
 		g_Config.m_SndNonactiveMute ^= 1;
 
diff --git a/src/game/client/components/sounds.cpp b/src/game/client/components/sounds.cpp
index f481b494..24bd0ebf 100644
--- a/src/game/client/components/sounds.cpp
+++ b/src/game/client/components/sounds.cpp
@@ -72,8 +72,13 @@ void CSounds::OnReset()
 void CSounds::OnRender()
 {
 	// check for sound initialisation
-	if(m_WaitForSoundJob && m_SoundJob.Status() == CJob::STATE_DONE)
-		m_WaitForSoundJob = false;
+	if(m_WaitForSoundJob)
+	{
+		if(m_SoundJob.Status() == CJob::STATE_DONE)
+			m_WaitForSoundJob = false;
+		else
+			return;
+	}
 
 	// set listner pos
 	Sound()->SetListenerPos(m_pClient->m_pCamera->m_Center.x, m_pClient->m_pCamera->m_Center.y);
@@ -84,10 +89,10 @@ void CSounds::OnRender()
 		int64 Now =  time_get();
 		if(m_QueueWaitTime <= Now)
 		{
-			Play(CHN_GLOBAL, m_aQueue[0], 1.0f, vec2(0,0));
+			Play(m_aQueue[0].m_Channel, m_aQueue[0].m_SetId, 1.0f, vec2(0,0));
 			m_QueueWaitTime = Now+time_freq()*3/10; // wait 300ms before playing the next one
 			if(--m_QueuePos > 0)
-				mem_move(m_aQueue, m_aQueue+1, m_QueuePos*sizeof(int));
+				mem_move(m_aQueue, m_aQueue+1, m_QueuePos*sizeof(QueueEntry));
 		}
 	}
 }
@@ -99,11 +104,17 @@ void CSounds::ClearQueue()
 	m_QueueWaitTime = time_get();
 }
 
-void CSounds::Enqueue(int SetId)
+void CSounds::Enqueue(int Channel, int SetId)
 {
 	// add sound to the queue
-	if(!g_Config.m_ClEditor && m_QueuePos < QUEUE_SIZE)
-		m_aQueue[m_QueuePos++] = SetId;
+	if(m_QueuePos < QUEUE_SIZE)
+	{
+		if(Channel == CHN_MUSIC || !g_Config.m_ClEditor)
+		{
+			m_aQueue[m_QueuePos].m_Channel = Channel;
+			m_aQueue[m_QueuePos++].m_SetId = SetId;
+		}
+	}
 }
 
 void CSounds::PlayAndRecord(int Chn, int SetId, float Vol, vec2 Pos)
@@ -117,17 +128,21 @@ void CSounds::PlayAndRecord(int Chn, int SetId, float Vol, vec2 Pos)
 
 void CSounds::Play(int Chn, int SetId, float Vol, vec2 Pos)
 {
-	if(m_WaitForSoundJob || SetId < 0 || SetId >= g_pData->m_NumSounds)
+	if(!g_Config.m_SndEnable || (Chn == CHN_MUSIC && !g_Config.m_SndMusic) || m_WaitForSoundJob || SetId < 0 || SetId >= g_pData->m_NumSounds)
 		return;
 
 	SOUNDSET *pSet = &g_pData->m_aSounds[SetId];
 
 	if(!pSet->m_NumSounds)
 		return;
+	
+	int Flags = 0;
+	if(Chn == CHN_MUSIC)
+		Flags = ISound::FLAG_LOOP;
 
 	if(pSet->m_NumSounds == 1)
 	{
-		Sound()->PlayAt(Chn, pSet->m_aSounds[0].m_Id, 0, Pos.x, Pos.y);
+		Sound()->PlayAt(Chn, pSet->m_aSounds[0].m_Id, Flags, Pos.x, Pos.y);
 		return;
 	}
 
@@ -138,6 +153,17 @@ void CSounds::Play(int Chn, int SetId, float Vol, vec2 Pos)
 		Id = rand() % pSet->m_NumSounds;
 	}
 	while(Id == pSet->m_Last);
-	Sound()->PlayAt(Chn, pSet->m_aSounds[Id].m_Id, 0, Pos.x, Pos.y);
+	Sound()->PlayAt(Chn, pSet->m_aSounds[Id].m_Id, Flags, Pos.x, Pos.y);
 	pSet->m_Last = Id;
 }
+
+void CSounds::Stop(int SetId)
+{
+	if(m_WaitForSoundJob || SetId < 0 || SetId >= g_pData->m_NumSounds)
+		return;
+	
+	SOUNDSET *pSet = &g_pData->m_aSounds[SetId];
+	
+	for(int i = 0; i < pSet->m_NumSounds; i++)
+		Sound()->Stop(pSet->m_aSounds[i].m_Id);
+}
diff --git a/src/game/client/components/sounds.h b/src/game/client/components/sounds.h
index 0e782442..ca8cfd77 100644
--- a/src/game/client/components/sounds.h
+++ b/src/game/client/components/sounds.h
@@ -10,7 +10,11 @@ class CSounds : public CComponent
 	{
 		QUEUE_SIZE = 32,
 	};
-	int m_aQueue[QUEUE_SIZE];
+	struct QueueEntry
+	{
+		int m_Channel;
+		int m_SetId;
+	} m_aQueue[QUEUE_SIZE];
 	int m_QueuePos;
 	int64 m_QueueWaitTime;
 	class CJob m_SoundJob;
@@ -31,9 +35,10 @@ public:
 	virtual void OnRender();
 	
 	void ClearQueue();
-	void Enqueue(int SetId);
+	void Enqueue(int Channel, int SetId);
 	void Play(int Channel, int SetId, float Vol, vec2 Pos);
 	void PlayAndRecord(int Channel, int SetId, float Vol, vec2 Pos);
+	void Stop(int SetId);
 };
 
 
diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp
index 28fdb31e..1a35895e 100644
--- a/src/game/client/gameclient.cpp
+++ b/src/game/client/gameclient.cpp
@@ -551,7 +551,7 @@ void CGameClient::OnMessage(int MsgId, CUnpacker *pUnpacker)
 		if(pMsg->m_SoundID == SOUND_CTF_DROP || pMsg->m_SoundID == SOUND_CTF_RETURN ||
 			pMsg->m_SoundID == SOUND_CTF_CAPTURE || pMsg->m_SoundID == SOUND_CTF_GRAB_EN ||
 			pMsg->m_SoundID == SOUND_CTF_GRAB_PL)
-			g_GameClient.m_pSounds->Enqueue(pMsg->m_SoundID);
+			g_GameClient.m_pSounds->Enqueue(CSounds::CHN_GLOBAL, pMsg->m_SoundID);
 		else
 			g_GameClient.m_pSounds->Play(CSounds::CHN_GLOBAL, pMsg->m_SoundID, 1.0f, vec2(0,0));
 	}