2010-11-20 10:37:14 +00:00
|
|
|
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
|
|
|
|
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
2011-02-27 16:56:03 +00:00
|
|
|
#include <engine/engine.h>
|
2010-05-29 07:25:38 +00:00
|
|
|
#include <engine/sound.h>
|
2010-09-21 22:51:32 +00:00
|
|
|
#include <engine/shared/config.h>
|
2010-05-29 07:25:38 +00:00
|
|
|
#include <game/generated/client_data.h>
|
|
|
|
#include <game/client/gameclient.h>
|
|
|
|
#include <game/client/components/camera.h>
|
2011-02-27 16:56:03 +00:00
|
|
|
#include <game/client/components/menus.h>
|
2010-05-29 07:25:38 +00:00
|
|
|
#include "sounds.h"
|
2008-08-29 05:34:18 +00:00
|
|
|
|
2011-02-27 16:56:03 +00:00
|
|
|
|
|
|
|
struct CUserData
|
|
|
|
{
|
|
|
|
CGameClient *m_pGameClient;
|
|
|
|
bool m_Render;
|
|
|
|
} g_UserData;
|
|
|
|
|
|
|
|
static int LoadSoundsThread(void *pUser)
|
|
|
|
{
|
|
|
|
CUserData *pData = static_cast<CUserData *>(pUser);
|
|
|
|
|
|
|
|
for(int s = 0; s < g_pData->m_NumSounds; s++)
|
|
|
|
{
|
|
|
|
for(int i = 0; i < g_pData->m_aSounds[s].m_NumSounds; i++)
|
|
|
|
{
|
|
|
|
int Id = pData->m_pGameClient->Sound()->LoadWV(g_pData->m_aSounds[s].m_aSounds[i].m_pFilename);
|
|
|
|
g_pData->m_aSounds[s].m_aSounds[i].m_Id = Id;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(pData->m_Render)
|
|
|
|
pData->m_pGameClient->m_pMenus->RenderLoading();
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2010-05-29 07:25:38 +00:00
|
|
|
void CSounds::OnInit()
|
2008-08-29 05:34:18 +00:00
|
|
|
{
|
|
|
|
// setup sound channels
|
2010-05-29 07:25:38 +00:00
|
|
|
Sound()->SetChannel(CSounds::CHN_GUI, 1.0f, 0.0f);
|
|
|
|
Sound()->SetChannel(CSounds::CHN_MUSIC, 1.0f, 0.0f);
|
|
|
|
Sound()->SetChannel(CSounds::CHN_WORLD, 0.9f, 1.0f);
|
|
|
|
Sound()->SetChannel(CSounds::CHN_GLOBAL, 1.0f, 0.0f);
|
2008-08-30 08:01:29 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
Sound()->SetListenerPos(0.0f, 0.0f);
|
|
|
|
|
|
|
|
ClearQueue();
|
2011-02-27 16:56:03 +00:00
|
|
|
|
|
|
|
// load sounds
|
|
|
|
if(g_Config.m_ClThreadsoundloading)
|
|
|
|
{
|
|
|
|
g_UserData.m_pGameClient = m_pClient;
|
|
|
|
g_UserData.m_Render = false;
|
|
|
|
m_pClient->Engine()->AddJob(&m_SoundJob, LoadSoundsThread, &g_UserData);
|
|
|
|
m_WaitForSoundJob = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_UserData.m_pGameClient = m_pClient;
|
|
|
|
g_UserData.m_Render = true;
|
|
|
|
LoadSoundsThread(&g_UserData);
|
|
|
|
m_WaitForSoundJob = false;
|
|
|
|
}
|
2010-05-29 07:25:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CSounds::OnReset()
|
|
|
|
{
|
|
|
|
Sound()->StopAll();
|
|
|
|
ClearQueue();
|
2008-08-29 05:34:18 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CSounds::OnRender()
|
2008-08-29 05:34:18 +00:00
|
|
|
{
|
2011-02-27 16:56:03 +00:00
|
|
|
// check for sound initialisation
|
|
|
|
if(m_WaitForSoundJob && m_SoundJob.Status() == CJob::STATE_DONE)
|
|
|
|
m_WaitForSoundJob = false;
|
|
|
|
|
2008-08-29 05:34:18 +00:00
|
|
|
// set listner pos
|
2010-05-29 07:25:38 +00:00
|
|
|
Sound()->SetListenerPos(m_pClient->m_pCamera->m_Center.x, m_pClient->m_pCamera->m_Center.y);
|
|
|
|
|
|
|
|
// play sound from queue
|
|
|
|
if(m_QueuePos > 0)
|
|
|
|
{
|
|
|
|
int64 Now = time_get();
|
|
|
|
if(m_QueueWaitTime <= Now)
|
|
|
|
{
|
|
|
|
Play(CHN_GLOBAL, m_aQueue[0], 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));
|
|
|
|
}
|
|
|
|
}
|
2008-08-29 05:34:18 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CSounds::ClearQueue()
|
2009-01-11 15:51:43 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
mem_zero(m_aQueue, sizeof(m_aQueue));
|
|
|
|
m_QueuePos = 0;
|
|
|
|
m_QueueWaitTime = time_get();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSounds::Enqueue(int SetId)
|
|
|
|
{
|
|
|
|
// add sound to the queue
|
2010-09-21 22:51:32 +00:00
|
|
|
if(!g_Config.m_ClEditor && m_QueuePos < QUEUE_SIZE)
|
2010-05-29 07:25:38 +00:00
|
|
|
m_aQueue[m_QueuePos++] = SetId;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSounds::PlayAndRecord(int Chn, int SetId, float Vol, vec2 Pos)
|
|
|
|
{
|
|
|
|
CNetMsg_Sv_SoundGlobal Msg;
|
2011-02-12 10:40:36 +00:00
|
|
|
Msg.m_SoundID = SetId;
|
2010-05-29 07:25:38 +00:00
|
|
|
Client()->SendPackMsg(&Msg, MSGFLAG_NOSEND|MSGFLAG_RECORD);
|
2009-01-11 15:51:43 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
Play(Chn, SetId, Vol, Pos);
|
2009-01-11 15:51:43 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CSounds::Play(int Chn, int SetId, float Vol, vec2 Pos)
|
2008-08-29 05:34:18 +00:00
|
|
|
{
|
2011-02-27 16:56:03 +00:00
|
|
|
if(m_WaitForSoundJob || SetId < 0 || SetId >= g_pData->m_NumSounds)
|
2010-05-29 07:25:38 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
SOUNDSET *pSet = &g_pData->m_aSounds[SetId];
|
2008-08-29 05:34:18 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(!pSet->m_NumSounds)
|
2008-08-29 05:34:18 +00:00
|
|
|
return;
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(pSet->m_NumSounds == 1)
|
2008-08-29 05:34:18 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
Sound()->PlayAt(Chn, pSet->m_aSounds[0].m_Id, 0, Pos.x, Pos.y);
|
2008-08-29 05:34:18 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// play a random one
|
2011-02-27 16:56:03 +00:00
|
|
|
int Id;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
Id = rand() % pSet->m_NumSounds;
|
|
|
|
}
|
|
|
|
while(Id == pSet->m_Last);
|
|
|
|
Sound()->PlayAt(Chn, pSet->m_aSounds[Id].m_Id, 0, Pos.x, Pos.y);
|
|
|
|
pSet->m_Last = Id;
|
2008-08-29 05:34:18 +00:00
|
|
|
}
|