From e6ea253eacddcb5482394e2af56e07d499473c6d Mon Sep 17 00:00:00 2001 From: D-AIRY <admin@ds-servers.com> Date: Tue, 1 Dec 2020 12:45:36 +0300 Subject: [PATCH] Added sound_emitter; some refactor; small bugfix --- proj/sxgame/vs2013/sxgame.vcxproj | 2 + proj/sxgame/vs2013/sxgame.vcxproj.filters | 6 ++ source/core/TaskManager.cpp | 18 ++-- source/core/TaskManager.h | 10 +- source/game/SoundEmitter.cpp | 116 ++++++++++++++++++++++ source/game/SoundEmitter.h | 59 +++++++++++ source/game/SoundPlayer.cpp | 9 +- source/terrax/terrax.cpp | 2 +- source/xEngine/Engine.cpp | 4 +- source/xSound/SoundEmitter.cpp | 12 +-- source/xSound/SoundLayer.cpp | 19 ++-- source/xSound/SoundLayer.h | 16 +-- source/xSound/SoundLoader.cpp | 2 +- source/xcommon/IXSoundSystem.h | 4 +- 14 files changed, 233 insertions(+), 46 deletions(-) create mode 100644 source/game/SoundEmitter.cpp create mode 100644 source/game/SoundEmitter.h diff --git a/proj/sxgame/vs2013/sxgame.vcxproj b/proj/sxgame/vs2013/sxgame.vcxproj index 6bf851a5f..d0f399efe 100644 --- a/proj/sxgame/vs2013/sxgame.vcxproj +++ b/proj/sxgame/vs2013/sxgame.vcxproj @@ -236,6 +236,7 @@ <ClCompile Include="..\..\..\source\game\BaseTool.cpp" /> <ClCompile Include="..\..\..\source\game\BaseWeapon.cpp" /> <ClCompile Include="..\..\..\source\game\SettingsWriter.cpp" /> + <ClCompile Include="..\..\..\source\game\SoundEmitter.cpp" /> <ClCompile Include="..\..\..\source\game\SoundPlayer.cpp" /> <ClCompile Include="..\..\..\source\game\sxgame_dll.cpp" /> <ClCompile Include="..\..\..\source\game\Player.cpp" /> @@ -310,6 +311,7 @@ <ClInclude Include="..\..\..\source\game\BaseTool.h" /> <ClInclude Include="..\..\..\source\game\BaseWeapon.h" /> <ClInclude Include="..\..\..\source\game\SettingsWriter.h" /> + <ClInclude Include="..\..\..\source\game\SoundEmitter.h" /> <ClInclude Include="..\..\..\source\game\SoundPlayer.h" /> <ClInclude Include="..\..\..\source\game\sxgame.h" /> <ClInclude Include="..\..\..\source\game\Player.h" /> diff --git a/proj/sxgame/vs2013/sxgame.vcxproj.filters b/proj/sxgame/vs2013/sxgame.vcxproj.filters index 88b980f7f..1e55d43a3 100644 --- a/proj/sxgame/vs2013/sxgame.vcxproj.filters +++ b/proj/sxgame/vs2013/sxgame.vcxproj.filters @@ -306,6 +306,9 @@ <ClCompile Include="..\..\..\source\game\EnvSkybox.cpp"> <Filter>Source Files\ents\env</Filter> </ClCompile> + <ClCompile Include="..\..\..\source\game\SoundEmitter.cpp"> + <Filter>Source Files\ents\sound</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\..\source\game\sxgame.h"> @@ -530,6 +533,9 @@ <ClInclude Include="..\..\..\source\game\EnvSkybox.h"> <Filter>Header Files\ents\env</Filter> </ClInclude> + <ClInclude Include="..\..\..\source\game\SoundEmitter.h"> + <Filter>Header Files\ents\sound</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ResourceCompile Include="..\..\..\source\game\sxgame.rc"> diff --git a/source/core/TaskManager.cpp b/source/core/TaskManager.cpp index f91def794..de83a5665 100644 --- a/source/core/TaskManager.cpp +++ b/source/core/TaskManager.cpp @@ -12,12 +12,12 @@ See the license in LICENSE extern CPerfMon *g_pPerfMon; #if defined(_WINDOWS) -static void SetThreadName(DWORD dwThreadID, const char *threadName) +static void SetThreadName(HANDLE hThread, const char *threadName) { THREADNAME_INFO info; info.dwType = 0x1000; info.szName = threadName; - info.dwThreadID = dwThreadID; + info.dwThreadID = GetThreadId(hThread); info.dwFlags = 0; #pragma warning(push) #pragma warning(disable: 6320 6322) @@ -171,14 +171,14 @@ void CTaskManager::start() std::thread * t = new std::thread(std::bind(&CTaskManager::workerMain, this)); #if defined(_WINDOWS) sprintf(name, "Worker #%u", i); - SetThreadName(GetThreadId(t->native_handle()), name); + SetThreadName(t->native_handle(), name); #endif m_aThreads.push_back(t); } m_pIOThread = new std::thread(std::bind(&CTaskManager::workerIOMain, this)); #if defined(_WINDOWS) sprintf(name, "Worker IO"); - SetThreadName(GetThreadId(m_pIOThread->native_handle()), name); + SetThreadName(m_pIOThread->native_handle(), name); #endif sheduleNextBunch(); @@ -245,7 +245,7 @@ void CTaskManager::synchronize() void CTaskManager::sheduleNextBunch() { - std::unique_lock<std::mutex> lock(m_mutexSync); + std::unique_lock<mutex> lock(m_mutexSync); while(m_iNumTasksToWaitFor > 0) { @@ -294,7 +294,9 @@ void CTaskManager::stop() void CTaskManager::execute(TaskPtr t) { + // save time task started t->run(); + // save time task ended if(t->getFlags() & CORE_TASK_FLAG_REPEATING) { @@ -344,7 +346,7 @@ void CTaskManager::worker(bool bOneRun) if(task->getFlags() & (CORE_TASK_FLAG_FRAME_SYNC/* | CORE_TASK_FLAG_ON_SYNC*/)) { { - std::lock_guard<std::mutex> lock(m_mutexSync); + ScopedLock lock(m_mutexSync); m_iNumTasksToWaitFor -= 1; } @@ -354,7 +356,7 @@ void CTaskManager::worker(bool bOneRun) if(task->getFlags() & CORE_TASK_FLAG_FOR_LOOP) { { - std::lock_guard<std::mutex> lock(m_mutexFor); + ScopedLock lock(m_mutexFor); m_aiNumWaitFor[((CTaskForLoop*)task)->getID()] -= 1; //m_aiNumWaitFor[std::static_pointer_cast<CTaskForLoop, ITask>(task)->getID()] -= 1; } @@ -421,7 +423,7 @@ ID CTaskManager::forLoop(int iStart, int iEnd, const IParallelForBody *pBody, in ID id = -1; { - std::lock_guard<std::mutex> lock(m_mutexFor); + ScopedLock lock(m_mutexFor); id = m_aiNumWaitFor.size(); m_aiNumWaitFor.push_back(iTaskCount); } diff --git a/source/core/TaskManager.h b/source/core/TaskManager.h index 1d96eb863..a94efdda8 100644 --- a/source/core/TaskManager.h +++ b/source/core/TaskManager.h @@ -83,14 +83,14 @@ private: unsigned int m_iWriteList; typedef std::condition_variable Condition; - typedef std::lock_guard<std::mutex> ScopedLock; + typedef std::lock_guard<mutex> ScopedLock; - mutable std::mutex m_mutexSync; - mutable std::mutex m_mutexFor; - mutable std::mutex m_mutexIOThread; + mutable mutex m_mutexSync; + mutable mutex m_mutexFor; + mutable mutex m_mutexIOThread; Condition m_Condition; Condition m_ConditionIOThread; - mutable std::mutex m_mutexWorker; + mutable SpinLock m_mutexWorker; Condition m_ConditionWorker; Condition m_ConditionFor; int m_iNumTasksToWaitFor; diff --git a/source/game/SoundEmitter.cpp b/source/game/SoundEmitter.cpp new file mode 100644 index 000000000..1ec6f3fc6 --- /dev/null +++ b/source/game/SoundEmitter.cpp @@ -0,0 +1,116 @@ + +#include "SoundEmitter.h" + +//########################################################################## + +/*! \skydocent sound_emitter + +*/ + +//########################################################################## + +BEGIN_PROPTABLE(CSoundEmitter) + + //! Звуковой файл + DEFINE_FIELD_STRINGFN(m_szPathSound, 0, "file", "Sound file", setSound, EDITOR_SOUND) + + //! Громкость + DEFINE_FIELD_FLOAT(m_fVolume, 0, "volume", "Volume", EDITOR_TEXTFIELD) + + //! Дистанция слышимости + DEFINE_FIELD_FLOAT(m_fDist, 0, "distance", "Hearing distance", EDITOR_TEXTFIELD) + + //! Включить + DEFINE_INPUT(play, "play", "Play", PDF_NONE) + + //! При включении + DEFINE_OUTPUT(m_onTurnOn, "OnTurnOn", "On Turn On") +// //! При выключении +// DEFINE_OUTPUT(m_onTurnOff, "OnTurnOff", "On Turn Off") + + //! Тип фонового звука + DEFINE_FLAG(SND_EMITTER_TYPE_AMBIENT, "Ambient") + +END_PROPTABLE() + +//************************************************************************** + +REGISTER_ENTITY(CSoundEmitter, sound_emitter); + +//########################################################################## + +CSoundEmitter::CSoundEmitter(CEntityManager *pMgr): + BaseClass(pMgr) +{ + +} + +CSoundEmitter::~CSoundEmitter() +{ + mem_release(m_pEmitter); +} + +//########################################################################## + +void CSoundEmitter::setSound(const char *szSound) +{ + if(!m_pEmitter || fstrcmp(m_pEmitter->getName(), szSound) != 0) + { + mem_release(m_pEmitter); + IXSoundSystem *pSound = (IXSoundSystem*)(Core_GetIXCore()->getPluginManager()->getInterface(IXSOUNDSYSTEM_GUID)); + IXSoundLayer *pGameLayer = pSound->findLayer("xGame"); + + SOUND_SPACE space = (getFlags() & SND_EMITTER_TYPE_AMBIENT ? SOUND_SPACE_2D : SOUND_SPACE_3D); + m_pEmitter = pGameLayer->newSoundEmitter(szSound, space); + + if(m_pEmitter) + { + _setStrVal(&m_szPathSound, szSound); + m_pEmitter->setVolume(m_fVolume); + } + } +} + +//########################################################################## + +void CSoundEmitter::onSync() +{ + BaseClass::onSync(); + if(!m_pEmitter) + return; + + float3 vPos = getPos(); + m_pEmitter->setWorldPos(vPos); + + m_pEmitter->setVolume(m_fVolume); +} + +//########################################################################## + +void CSoundEmitter::play(inputdata_t * pInputdata) +{ + if(m_pEmitter) + { + m_pEmitter->play(); + } + FIRE_OUTPUT(m_onTurnOn, pInputdata->pInflictor); +} + +//########################################################################## + +void CSoundEmitter::updateFlags() +{ + BaseClass::updateFlags(); + + if(!m_pEmitter) + return; + + if (getFlags() & SND_EMITTER_TYPE_AMBIENT) + { + m_pEmitter->setSpace(SOUND_SPACE_2D); + } + else + { + m_pEmitter->setSpace(SOUND_SPACE_3D); + } +} diff --git a/source/game/SoundEmitter.h b/source/game/SoundEmitter.h new file mode 100644 index 000000000..c96e49165 --- /dev/null +++ b/source/game/SoundEmitter.h @@ -0,0 +1,59 @@ +/***************************************************** +Copyright © DogmaNet Team, 2020 +Site: dogmanet.ru +See the license in LICENSE +*****************************************************/ + +/*! + \file + Класс звукового эмиттера +*/ +#ifndef __SOUND_EMITTER_H +#define __SOUND_EMITTER_H + +#include "PointEntity.h" +#include <xcommon/IXSoundSystem.h> + +//########################################################################## + +//! Флаг установки ambient типа звуку +#define SND_EMITTER_TYPE_AMBIENT ENT_FLAG_1 + +//########################################################################## + +/*! Класс звукового плеера + \ingroup cpointentity +*/ +class CSoundEmitter: public CPointEntity +{ + DECLARE_CLASS(CSoundEmitter, CPointEntity); + DECLARE_PROPTABLE(); +public: + CSoundEmitter(CEntityManager * pMgr); + ~CSoundEmitter(); + + virtual void setSound(const char *szSound); + + void onSync() override; + +protected: + + void updateFlags() override; + + void play(inputdata_t *pInputdata); + + //######################################################################## + + output_t m_onTurnOn; +// output_t m_onTurnOff; + + IXSoundEmitter *m_pEmitter = NULL; + const char *m_szPathSound = ""; + + float m_fDist = 10.f; + float m_fVolume = 1.f; + + //int m_iType = SOUND_DTYPE_3D; +}; + +#endif diff --git a/source/game/SoundPlayer.cpp b/source/game/SoundPlayer.cpp index 241eb03fb..50c83755b 100644 --- a/source/game/SoundPlayer.cpp +++ b/source/game/SoundPlayer.cpp @@ -52,8 +52,7 @@ REGISTER_ENTITY(CSoundPlayer, sound_player); //########################################################################## CSoundPlayer::CSoundPlayer(CEntityManager *pMgr): - BaseClass(pMgr), - m_pPlayer(NULL) + BaseClass(pMgr) { } @@ -67,7 +66,7 @@ CSoundPlayer::~CSoundPlayer() void CSoundPlayer::setSound(const char *szSound) { - if (!m_pPlayer || fstrcmp(m_pPlayer->getName(), szSound) != 0) + if(!m_pPlayer || fstrcmp(m_pPlayer->getName(), szSound) != 0) { mem_release(m_pPlayer); IXSoundSystem *pSound = (IXSoundSystem*)(Core_GetIXCore()->getPluginManager()->getInterface(IXSOUNDSYSTEM_GUID)); @@ -76,13 +75,13 @@ void CSoundPlayer::setSound(const char *szSound) SOUND_SPACE space = (getFlags() & SND_PLAYER_TYPE_AMBIENT ? SOUND_SPACE_2D : SOUND_SPACE_3D); m_pPlayer = pGameLayer->newSoundPlayer(szSound, space); - if (m_pPlayer) + if(m_pPlayer) { _setStrVal(&m_szPathSound, szSound); m_pPlayer->setLoop((SOUND_LOOP)m_iLoop); m_pPlayer->setVolume(m_fVolume); - if (getFlags() & SND_PLAYER_START_PLAYED) + if(getFlags() & SND_PLAYER_START_PLAYED) m_pPlayer->play(); } } diff --git a/source/terrax/terrax.cpp b/source/terrax/terrax.cpp index 6d8ac6c61..309c93c7c 100644 --- a/source/terrax/terrax.cpp +++ b/source/terrax/terrax.cpp @@ -1669,7 +1669,7 @@ bool XSaveLevel(const char *szNewName, bool bForcePrompt) return(true); } - if(!bForcePrompt && g_sLevelName[0]) + if(!bForcePrompt && g_sLevelName.length()) { // g_sLevelName can changed during save process, so pointer will be broken String tmp = g_sLevelName; diff --git a/source/xEngine/Engine.cpp b/source/xEngine/Engine.cpp index 4d521ed2d..1a3e9087d 100644 --- a/source/xEngine/Engine.cpp +++ b/source/xEngine/Engine.cpp @@ -177,8 +177,8 @@ bool XMETHODCALLTYPE CEngine::initGraphics(XWINDOW_OS_HANDLE hWindow, IXEngineCa IXSoundSystem *pSound = (IXSoundSystem*)(m_pCore->getPluginManager()->getInterface(IXSOUNDSYSTEM_GUID)); IXSoundLayer *pMasterLayer = pSound->createMasterLayer(&oAudioDesc, "master"); pMasterLayer->play(true); - IXSoundLayer *pGameLayer = pMasterLayer->newSoundLayer(&oAudioDesc, "xGame"); - IXSoundLayer *pGuiLayer = pMasterLayer->newSoundLayer(&oAudioDesc, "xGUI"); + IXSoundLayer *pGameLayer = pMasterLayer->newSoundLayer("xGame"); + IXSoundLayer *pGuiLayer = pMasterLayer->newSoundLayer("xGUI"); pSound->update(float3(), float3(), float3()); pGameLayer->play(false); pGuiLayer->play(false); diff --git a/source/xSound/SoundEmitter.cpp b/source/xSound/SoundEmitter.cpp index 27bf9a7b2..f53200789 100644 --- a/source/xSound/SoundEmitter.cpp +++ b/source/xSound/SoundEmitter.cpp @@ -38,13 +38,13 @@ CSoundBase* CSoundEmitter::newInstance() { CSoundEmitter *pEmitter = new CSoundEmitter(); - pEmitter->m_aInstances[0]->pAB = m_aInstances[0]->pAB->newInstance(); - pEmitter->m_space = this->m_space; + pEmitter->m_aInstances.push_back(new Instance(m_aInstances[0]->pAB->newInstance())); + pEmitter->m_space = m_space; pEmitter->m_state = SOUND_STATE_STOP; - pEmitter->m_sName = this->m_sName; - pEmitter->m_pLayer = this->m_pLayer; - pEmitter->m_fDist = this->m_fDist; - pEmitter->m_vWorldPos = this->m_vWorldPos; + pEmitter->m_sName = m_sName; + pEmitter->m_pLayer = m_pLayer; + pEmitter->m_fDist = m_fDist; + pEmitter->m_vWorldPos = m_vWorldPos; return pEmitter; } diff --git a/source/xSound/SoundLayer.cpp b/source/xSound/SoundLayer.cpp index 377096b69..c21e89c02 100644 --- a/source/xSound/SoundLayer.cpp +++ b/source/xSound/SoundLayer.cpp @@ -167,7 +167,7 @@ IXSoundLayer* XMETHODCALLTYPE CSoundLayer::findLayer(const char *szName) return this; IXSoundLayer *pFound = NULL; - + // TODO use plain array for iteration for(MapLayer::Iterator i = m_mapLayers.begin(); i; ++i) { if(!i.second) @@ -195,14 +195,19 @@ IAudioBuffer* CSoundLayer::createAudioBuffer(AB_TYPE type, const AudioRawDesc *p //########################################################################## -IXSoundLayer* XMETHODCALLTYPE CSoundLayer::newSoundLayer(const AudioRawDesc *pDesc, const char *szName) +IXSoundLayer* XMETHODCALLTYPE CSoundLayer::newSoundLayer(const char *szName, const AudioRawDesc *pDesc) { + AudioRawDesc desc; if(!pDesc) - return NULL; - - if(!matchPrimaryLayer(pDesc)) - return NULL; - + { + pDesc = &desc; + m_pPrimaryBuffer->getDesc(&desc); + } + else if(!matchPrimaryLayer(pDesc)) + { + return(NULL); + } + CSoundLayer *pLayer = new CSoundLayer(); pLayer->init(m_pSoundSystem, this, pDesc, szName); diff --git a/source/xSound/SoundLayer.h b/source/xSound/SoundLayer.h index 3c0cf7561..d5a542073 100644 --- a/source/xSound/SoundLayer.h +++ b/source/xSound/SoundLayer.h @@ -21,17 +21,17 @@ class CSoundLayer: public IXUnknownImplementation<IXSoundLayer> public: ~CSoundLayer(); - virtual void XMETHODCALLTYPE play(bool canPlay) override; - virtual bool XMETHODCALLTYPE isPlaying() const override; - virtual const char* XMETHODCALLTYPE getName() const override; + void XMETHODCALLTYPE play(bool canPlay) override; + bool XMETHODCALLTYPE isPlaying() const override; + const char* XMETHODCALLTYPE getName() const override; - virtual IXSoundLayer* XMETHODCALLTYPE findLayer(const char *szName) override; + IXSoundLayer* XMETHODCALLTYPE findLayer(const char *szName) override; - virtual IXSoundLayer* XMETHODCALLTYPE newSoundLayer(const AudioRawDesc *pDesc, const char *szName) override; - virtual IXSoundEmitter* XMETHODCALLTYPE newSoundEmitter(const char *szName, SOUND_SPACE space) override; - virtual IXSoundPlayer* XMETHODCALLTYPE newSoundPlayer(const char *szName, SOUND_SPACE space) override; + IXSoundLayer* XMETHODCALLTYPE newSoundLayer(const char *szName, const AudioRawDesc *pDesc = NULL) override; + IXSoundEmitter* XMETHODCALLTYPE newSoundEmitter(const char *szName, SOUND_SPACE space) override; + IXSoundPlayer* XMETHODCALLTYPE newSoundPlayer(const char *szName, SOUND_SPACE space) override; - virtual void XMETHODCALLTYPE getDesc(AudioRawDesc *pDesc) const override; + void XMETHODCALLTYPE getDesc(AudioRawDesc *pDesc) const override; //######################################################################## diff --git a/source/xSound/SoundLoader.cpp b/source/xSound/SoundLoader.cpp index df11da859..1b624b545 100644 --- a/source/xSound/SoundLoader.cpp +++ b/source/xSound/SoundLoader.cpp @@ -7,7 +7,7 @@ bool CSoundLoader::can() const { - return (bool)m_pCodecTarget; + return(m_pCodecTarget != NULL); } void CSoundLoader::init(CSoundSystem *pSoundSystem) diff --git a/source/xcommon/IXSoundSystem.h b/source/xcommon/IXSoundSystem.h index cab070821..2bc35b5b2 100644 --- a/source/xcommon/IXSoundSystem.h +++ b/source/xcommon/IXSoundSystem.h @@ -8,14 +8,12 @@ See the license in LICENSE #define __IXSOUNDSYSTEM_H #include <gdefines.h> -#include <common/math.h> #include <common/AudioRawDesc.h> //########################################################################## // {8FF4F913-5EA1-4EE6-8C06-73D8A49EBC22} #define IXSOUNDSYSTEM_GUID DEFINE_XGUID(0x8ff4f913, 0x5ea1, 0x4ee6, 0x8c, 0x6, 0x73, 0xd8, 0xa4, 0x9e, 0xbc, 0x22) - #define IXSOUNDSYSTEM_VERSION 2 //########################################################################## @@ -107,7 +105,7 @@ public: virtual IXSoundLayer* XMETHODCALLTYPE findLayer(const char *szName) = 0; - virtual IXSoundLayer* XMETHODCALLTYPE newSoundLayer(const AudioRawDesc *pDesc, const char *szName) = 0; + virtual IXSoundLayer* XMETHODCALLTYPE newSoundLayer(const char *szName, const AudioRawDesc *pDesc = NULL) = 0; virtual IXSoundEmitter* XMETHODCALLTYPE newSoundEmitter(const char *szName, SOUND_SPACE space) = 0; virtual IXSoundPlayer* XMETHODCALLTYPE newSoundPlayer(const char *szName, SOUND_SPACE space) = 0; -- GitLab