Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,82 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/sound/LowLevelSound.h"
#include "hpl1/engine/sound/SoundEnvironment.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
iLowLevelSound::iLowLevelSound() {
mfVolume = 1;
mfEnvVolume = 0;
mbListenerAttenuation = true;
mbHardwareAcc = false;
mbEnvAudioEnabled = false;
}
//-----------------------------------------------------------------------
iLowLevelSound::~iLowLevelSound() {
STLDeleteAll(mlstSoundEnv);
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
iSoundEnvironment *iLowLevelSound::GetSoundEnvironmentFromFileName(const tString &asName) {
tString sLowName = cString::ToLowerCase(asName);
for (tSoundEnvListIt SEIt = mlstSoundEnv.begin(); SEIt != mlstSoundEnv.end(); ++SEIt) {
iSoundEnvironment *pSoundEnv = *SEIt;
if (sLowName == pSoundEnv->GetFileName())
return pSoundEnv;
}
return NULL;
}
//-----------------------------------------------------------------------
/*void iLowLevelSound::DestroySoundEnvironment( iSoundEnvironment* apSoundEnv)
{
Log(" Destroy %d\n",apSoundEnv);
STLFindAndDelete(mlstSoundEnv,apSoundEnv);
}*/
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,121 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_LOWLEVELSOUND_H
#define HPL_LOWLEVELSOUND_H
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/system/SystemTypes.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
class iSoundData;
class iSoundEnvironment;
// class iSoundFilter;
typedef Common::List<iSoundEnvironment *> tSoundEnvList;
typedef tSoundEnvList::iterator tSoundEnvListIt;
class iLowLevelSound {
public:
iLowLevelSound();
virtual ~iLowLevelSound();
/**
* Get the formats supported
* \param &alstFormats
*/
virtual void GetSupportedFormats(tStringList &alstFormats) = 0;
virtual iSoundData *LoadSoundData(const tString &asName, const tString &asFilePath,
const tString &asType, bool abStream, bool abLoopStream) = 0;
virtual void UpdateSound(float afTimeStep) = 0;
virtual void SetListenerAttributes(const cVector3f &avPos, const cVector3f &avVel,
const cVector3f &avForward, const cVector3f &avUp) = 0;
virtual void SetListenerPosition(const cVector3f &avPos) = 0;
const cMatrixf &GetListenerMatrix() { return m_mtxListener; }
virtual void SetListenerAttenuation(bool abEnabled) = 0;
virtual void SetSetRolloffFactor(float afFactor) = 0;
virtual void SetVolume(float afVolume) = 0;
cVector3f &GetListenerPosition() { return mvListenerPosition; }
cVector3f &GetListenerVelocity() { return mvListenerVelocity; }
cVector3f &GetListenerForward() { return mvListenerForward; }
cVector3f &GetListenerUp() { return mvListenerUp; }
bool GetListenerAttenuation() { return mbListenerAttenuation; }
float GetVolume() { return mfVolume; }
// virtual void LogSoundStatus() {}
virtual void Init(bool abUseHardware, bool abForceGeneric, bool abUseEnvAudio, int alMaxChannels,
int alStreamUpdateFreq, bool abUseThreading, bool abUseVoiceManagement,
int alMaxMonoSourceHint, int alMaxStereoSourceHint,
int alStreamingBufferSize, int alStreamingBufferCount, bool abEnableLowLevelLog, tString asDeviceName) = 0;
bool IsHardwareAccelerated() { return mbHardwareAcc; }
bool IsEnvAudioAvailable() { return mbEnvAudioEnabled; }
virtual void SetEnvVolume(float afVolume) = 0;
float GetEnvVolume() { return mfEnvVolume; }
virtual iSoundEnvironment *LoadSoundEnvironment(const tString &asFilePath) = 0;
virtual void SetSoundEnvironment(iSoundEnvironment *apSoundEnv) = 0;
virtual void FadeSoundEnvironment(iSoundEnvironment *apSourceSoundEnv, iSoundEnvironment *apDestSoundEnv, float afT) = 0;
iSoundEnvironment *GetSoundEnvironmentFromFileName(const tString &asName);
// void DestroySoundEnvironment( iSoundEnvironment* apSoundEnv);
protected:
float mfVolume;
float mfEnvVolume;
bool mbListenerAttenuation;
bool mbHardwareAcc;
bool mbEnvAudioEnabled;
cVector3f mvListenerUp;
cVector3f mvListenerForward;
cVector3f mvListenerRight;
cVector3f mvListenerPosition;
cVector3f mvListenerVelocity;
cMatrixf m_mtxListener;
tSoundEnvList mlstSoundEnv;
};
} // namespace hpl
#endif // HPL_LOWLEVELSOUND_H

View File

@@ -0,0 +1,312 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/sound/MusicHandler.h"
#include "hpl1/debug.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/resources/Resources.h"
#include "hpl1/engine/resources/SoundManager.h"
#include "hpl1/engine/sound/LowLevelSound.h"
#include "hpl1/engine/sound/SoundChannel.h"
#include "hpl1/engine/sound/SoundData.h"
#include "hpl1/engine/system/String.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cMusicHandler::cMusicHandler(iLowLevelSound *apLowLevelSound, cResources *apResources) {
mpLowLevelSound = apLowLevelSound;
mpResources = apResources;
mpMainSong = NULL;
mpLock = NULL;
mbIsPaused = false;
}
//-----------------------------------------------------------------------
cMusicHandler::~cMusicHandler() {
if (mpMainSong) {
hplDelete(mpMainSong->mpStream);
hplDelete(mpMainSong);
}
tMusicEntryListIt it = mlstFadingSongs.begin();
while (it != mlstFadingSongs.end()) {
cMusicEntry *pSong = *it;
hplDelete(pSong->mpStream);
hplDelete(pSong);
it = mlstFadingSongs.erase(it);
// it++;
}
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
bool cMusicHandler::Play(const tString &asFileName, float afVolume, float afFadeStepSize, bool abLoop) {
bool bSongIsPlaying = false;
if (mpLock != NULL) {
mpLock->msFileName = asFileName;
mpLock->mfVolume = afVolume;
mpLock->mbLoop = abLoop;
return true;
}
if (mpMainSong != NULL)
if (asFileName == mpMainSong->msFileName)
bSongIsPlaying = true;
if (!bSongIsPlaying) {
// Put the previous song in the fading queue
if (mpMainSong != NULL) {
mpMainSong->mfVolumeAdd = afFadeStepSize;
mlstFadingSongs.push_back(mpMainSong);
}
// If there the song to be played is in the fade que, stop it.
tMusicEntryListIt it = mlstFadingSongs.begin();
while (it != mlstFadingSongs.end()) {
cMusicEntry *pSong = *it;
if (pSong->msFileName == asFileName) {
pSong->mfVolume = 0;
pSong->mpStream->Stop();
hplDelete(pSong->mpStream);
hplDelete(pSong);
it = mlstFadingSongs.erase(it);
} else {
it++;
}
}
// add it and set its properties
mpMainSong = hplNew(cMusicEntry, ());
if (LoadAndStart(asFileName, mpMainSong, 0, abLoop) == false) {
hplDelete(mpMainSong);
mpMainSong = NULL;
return false;
}
} else {
if (mpMainSong->mfMaxVolume == afVolume)
return true;
}
// Set Properties
mpMainSong->mfMaxVolume = afVolume;
mpMainSong->mbLoop = abLoop;
if (mpMainSong->mfMaxVolume > mpMainSong->mfVolume)
mpMainSong->mfVolumeAdd = afFadeStepSize;
else
mpMainSong->mfVolumeAdd = -afFadeStepSize;
return true;
}
//-----------------------------------------------------------------------
void cMusicHandler::Stop(float afFadeStepSize) {
if (mpMainSong == NULL)
return;
if (afFadeStepSize < 0)
afFadeStepSize = -afFadeStepSize;
mpMainSong->mfVolumeAdd = afFadeStepSize;
if (afFadeStepSize == 0) {
mpMainSong->mpStream->SetVolume(0);
mpMainSong->mpStream->Stop();
mpMainSong->mfVolume = 0;
}
mlstFadingSongs.push_back(mpMainSong);
mpMainSong = NULL;
}
//-----------------------------------------------------------------------
void cMusicHandler::Pause() {
if (mpMainSong != NULL)
mpMainSong->mpStream->SetPaused(true);
tMusicEntryListIt it = mlstFadingSongs.begin();
while (it != mlstFadingSongs.end()) {
(*it)->mpStream->SetPaused(true);
it++;
}
mbIsPaused = true;
}
//-----------------------------------------------------------------------
void cMusicHandler::Resume() {
if (mpMainSong != NULL)
mpMainSong->mpStream->SetPaused(false);
tMusicEntryListIt it = mlstFadingSongs.begin();
while (it != mlstFadingSongs.end()) {
(*it)->mpStream->SetPaused(false);
it++;
}
mbIsPaused = false;
}
//-----------------------------------------------------------------------
void cMusicHandler::Lock(cMusicLock *apLock) {
mpLock = apLock;
}
//-----------------------------------------------------------------------
void cMusicHandler::UnLock() {
mpLock = NULL;
}
//-----------------------------------------------------------------------
tString cMusicHandler::GetCurrentSongName() {
if (mpMainSong != NULL)
return mpMainSong->msFileName;
else
return "";
}
//-----------------------------------------------------------------------
float cMusicHandler::GetCurrentSongVolume() {
if (mpMainSong != NULL)
return mpMainSong->mfVolume;
else
return 0;
}
//-----------------------------------------------------------------------
cMusicEntry *cMusicHandler::GetCurrentSong() {
return mpMainSong;
}
//-----------------------------------------------------------------------
void cMusicHandler::Update(float afTimeStep) {
if (mbIsPaused)
return;
if (mpMainSong != NULL) {
if (mpMainSong->mpStream->IsPlaying() == false) {
hplDelete(mpMainSong->mpStream);
hplDelete(mpMainSong);
mpMainSong = NULL;
} else {
// Update the main song
mpMainSong->mfVolume += mpMainSong->mfVolumeAdd * afTimeStep;
if (mpMainSong->mfVolumeAdd > 0) {
if (mpMainSong->mfVolume >= mpMainSong->mfMaxVolume)
mpMainSong->mfVolume = mpMainSong->mfMaxVolume;
} else {
if (mpMainSong->mfVolume <= mpMainSong->mfMaxVolume)
mpMainSong->mfVolume = mpMainSong->mfMaxVolume;
}
if (mpMainSong->mpStream->GetVolume() != mpMainSong->mfVolume) {
mpMainSong->mpStream->SetVolume(mpMainSong->mfVolume);
}
}
}
// Update the fading songs
tMusicEntryListIt it = mlstFadingSongs.begin();
while (it != mlstFadingSongs.end()) {
cMusicEntry *pSong = *it;
pSong->mfVolume -= pSong->mfVolumeAdd * afTimeStep;
if (pSong->mfVolume <= 0) {
pSong->mfVolume = 0;
pSong->mpStream->Stop();
hplDelete(pSong->mpStream);
hplDelete(pSong);
it = mlstFadingSongs.erase(it);
} else {
pSong->mpStream->SetVolume(pSong->mfVolume);
it++;
}
}
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
bool cMusicHandler::LoadAndStart(const tString &asFileName, cMusicEntry *apSong, float afVolume, bool abLoop) {
iSoundData *pData = mpResources->GetSoundManager()->CreateSoundData(asFileName, true, abLoop);
if (pData == NULL) {
Hpl1::logError(Hpl1::kDebugAudio | Hpl1::kDebugResourceLoading, "Couldn't load music '%s'\n", asFileName.c_str());
return false;
}
iSoundChannel *pStream = pData->CreateChannel(256);
if (pStream == NULL) {
Hpl1::logError(Hpl1::kDebugAudio, "Couldn't stream music '%s'!\n", asFileName.c_str());
return false;
}
apSong->msFileName = asFileName;
apSong->mpStream = pStream;
apSong->mpStream->SetVolume(afVolume);
apSong->mpStream->Play();
apSong->mpStream->SetLooping(abLoop);
return true;
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,130 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_MUSICHANDLER_H
#define HPL_MUSICHANDLER_H
#include "common/list.h"
#include "hpl1/engine/system/SystemTypes.h"
namespace hpl {
class iLowLevelSound;
class iSoundChannel;
////////////////////////////////////////////////////
//////////// MUSIC LOCK ///////////////////////////
////////////////////////////////////////////////////
class cMusicLock {
public:
cMusicLock() : msFileName(""), mfVolume(0) {}
tString msFileName;
float mfVolume;
bool mbLoop;
};
////////////////////////////////////////////////////
//////////// MUSIC ENTRY ///////////////////////////
////////////////////////////////////////////////////
class cMusicEntry {
public:
cMusicEntry() : msFileName(""), mpStream(NULL), mfMaxVolume(1),
mfVolume(0), mfVolumeAdd(0.01f) {}
tString msFileName;
iSoundChannel *mpStream;
float mfMaxVolume;
float mfVolume;
float mfVolumeAdd;
bool mbLoop;
};
typedef Common::List<cMusicEntry *> tMusicEntryList;
typedef tMusicEntryList::iterator tMusicEntryListIt;
////////////////////////////////////////////////////
//////////// MUSIC HANDLER ///////////////////////
////////////////////////////////////////////////////
class cResources;
class cMusicHandler {
public:
cMusicHandler(iLowLevelSound *apLowLevelSound, cResources *apResources);
~cMusicHandler();
/**
* Play a song. Playing a song that is already playing updates it's properties.
* \param asFileName file to be played
* \param afVolume volume to be played at
* \param afFadeStepSize volume increse/decrease per app step when fading to new volume.
* \param abLoop If the music should be looped or not.
* \return
*/
bool Play(const tString &asFileName, float afVolume, float afFadeStepSize, bool abLoop);
/**
* Stop playing the current music.
* \param afFadeStepSize volume increse/decrease per app step when fading volume to 0.
*/
void Stop(float afFadeStepSize);
void Pause();
void Resume();
/**
* No more music can be played when locked. Latest song that has been tried to be palyed is saved in lock.
* \param apLock
*/
void Lock(cMusicLock *apLock);
/**
* Remove lock.
*/
void UnLock();
tString GetCurrentSongName();
float GetCurrentSongVolume();
cMusicEntry *GetCurrentSong();
void Update(float afTimeStep);
private:
iLowLevelSound *mpLowLevelSound;
cResources *mpResources;
tMusicEntryList mlstFadingSongs;
cMusicEntry *mpMainSong;
cMusicLock *mpLock;
bool mbIsPaused;
bool LoadAndStart(const tString &asFileName, cMusicEntry *apSong, float afVolume, bool abLoop);
};
} // namespace hpl
#endif // HPL_MUSICHANDLER_H

View File

@@ -0,0 +1,97 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/sound/Sound.h"
#include "hpl1/engine/resources/Resources.h"
#include "hpl1/engine/sound/LowLevelSound.h"
#include "hpl1/engine/sound/MusicHandler.h"
#include "hpl1/engine/sound/SoundHandler.h"
#include "hpl1/engine/system/low_level_system.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cSound::cSound(iLowLevelSound *apLowLevelSound) : iUpdateable("HPL_Sound") {
mpLowLevelSound = apLowLevelSound;
}
//-----------------------------------------------------------------------
cSound::~cSound() {
Log("Exiting Sound Module\n");
Log("--------------------------------------------------------\n");
hplDelete(mpSoundHandler);
hplDelete(mpMusicHandler);
Log("--------------------------------------------------------\n\n");
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cSound::Update(float afTimeStep) {
mpSoundHandler->Update(afTimeStep);
mpMusicHandler->Update(afTimeStep);
mpLowLevelSound->UpdateSound(afTimeStep);
}
//-----------------------------------------------------------------------
void cSound::Init(cResources *apResources, bool abUseHardware, bool abForceGeneric, bool abUseEnvAudio, int alMaxChannels,
int alStreamUpdateFreq, bool abUseThreading, bool abUseVoiceManagement,
int alMaxMonoSourceHint, int alMaxStereoSourceHint,
int alStreamingBufferSize, int alStreamingBufferCount, bool abEnableLowLevelLog, tString asDeviceName) {
mpResources = apResources;
Log("Initializing Sound Module\n");
Log("--------------------------------------------------------\n");
mpLowLevelSound->Init(abUseHardware, abForceGeneric, abUseEnvAudio, alMaxChannels, alStreamUpdateFreq, abUseThreading,
abUseVoiceManagement, alMaxMonoSourceHint, alMaxStereoSourceHint,
alStreamingBufferSize, alStreamingBufferCount, abEnableLowLevelLog, asDeviceName);
mpSoundHandler = hplNew(cSoundHandler, (mpLowLevelSound, mpResources));
mpMusicHandler = hplNew(cMusicHandler, (mpLowLevelSound, mpResources));
Log("--------------------------------------------------------\n\n");
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,64 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_SOUND_H
#define HPL_SOUND_H
#include "hpl1/engine/game/Updateable.h"
namespace hpl {
class iLowLevelSound;
class cResources;
class cSoundHandler;
class cMusicHandler;
class cSound : public iUpdateable {
public:
cSound(iLowLevelSound *apLowLevelSound);
~cSound();
void Init(cResources *apResources, bool abUseHardware, bool abForceGeneric, bool abUseEnvAudio, int alMaxChannels,
int alStreamUpdateFreq, bool abUseThreading, bool abUseVoiceManagement,
int alMaxMonoSourceHint, int alMaxStereoSourceHint,
int alStreamingBufferSize, int alStreamingBufferCount, bool abEnableLowLevelLog, tString asDeviceName);
void Update(float afTimeStep);
iLowLevelSound *GetLowLevel() { return mpLowLevelSound; }
cSoundHandler *GetSoundHandler() { return mpSoundHandler; }
cMusicHandler *GetMusicHandler() { return mpMusicHandler; }
private:
iLowLevelSound *mpLowLevelSound;
cResources *mpResources;
cSoundHandler *mpSoundHandler;
cMusicHandler *mpMusicHandler;
};
} // namespace hpl
#endif // HPL_SOUND_H

View File

@@ -0,0 +1,189 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_SOUND_CHANNEL_H
#define HPL_SOUND_CHANNEL_H
#include "common/list.h"
#include "hpl1/engine/math/MathTypes.h"
namespace hpl {
class iSoundData;
class cSoundManager;
class iSoundChannelCallback {
public:
virtual ~iSoundChannelCallback() = default;
virtual void OnPriorityRelease() = 0;
};
//--------------------------------------------
class iSoundChannel {
public:
iSoundChannel(iSoundData *apData, cSoundManager *apSoundManger) : mpData(apData) {
mbLooping = false;
mbPaused = true;
mbPositionRelative = false;
mfSpeed = 1;
mfVolume = 1;
mfMaxDistance = 0;
mfMinDistance = 0;
mpSoundManger = apSoundManger;
mvVelocity = cVector3f(0, 0, 0);
mvPosition = cVector3f(0, 0, 0);
mvRelPosition = cVector3f(0, 0, 0);
mbBlockable = false;
mfBlockVolumeMul = 1;
mbAffectedByEnv = false;
mlPriorityModifier = 0;
mbStopUsed = false;
mpCallback = NULL;
mlId = 0;
}
virtual ~iSoundChannel() {}
virtual void Play() = 0;
virtual void Stop() = 0;
virtual void SetPaused(bool abX) = 0;
virtual void SetSpeed(float afSpeed) = 0;
virtual void SetVolume(float afVolume) = 0;
virtual void SetLooping(bool abLoop) = 0;
virtual void SetPan(float afPan) = 0;
virtual void Set3D(bool ab3D) = 0;
virtual void SetPriority(int alX) = 0;
virtual int GetPriority() = 0;
void SetPriorityModifier(int alX) {
mlPriorityModifier = alX;
SetPriority(GetPriority());
}
int GetPriorityModifier() { return mlPriorityModifier; }
virtual void SetPositionRelative(bool abRelative) = 0;
virtual void SetPosition(const cVector3f &avPos) = 0;
void SetRelPosition(const cVector3f &avPos) { mvRelPosition = avPos; }
virtual void SetVelocity(const cVector3f &avVel) = 0;
virtual void SetMinDistance(float fMin) = 0;
virtual void SetMaxDistance(float fMax) = 0;
virtual bool IsPlaying() = 0;
virtual bool IsBufferUnderrun() = 0;
virtual double GetElapsedTime() = 0;
virtual double GetTotalTime() = 0;
bool GetPaused() { return mbPaused; }
float GetSpeed() { return mfSpeed; }
float GetVolume() { return mfVolume; }
bool GetLooping() { return mbLooping; }
float GetPan() { return mfPan; }
bool Get3D() { return mb3D; }
bool GetStopUsed() { return mbStopUsed; }
bool GetBlockable() { return mbBlockable; }
void SetBlockable(bool abX) { mbBlockable = abX; }
void SetBlockVolumeMul(float afX) { mfBlockVolumeMul = afX; }
float GetBlockVolumeMul() { return mfBlockVolumeMul; }
bool GetPositionRelative() { return mbPositionRelative; }
const cVector3f &GetRelPosition() { return mvRelPosition; }
const cVector3f &GetPosition() { return mvPosition; }
const cVector3f &GetVelocity() { return mvVelocity; }
float GetMinDistance() { return mfMinDistance; }
float GetMaxDistance() { return mfMaxDistance; }
iSoundChannelCallback *GetCallBack() { return mpCallback; }
void SetCallBack(iSoundChannelCallback *apCallback) { mpCallback = apCallback; }
int GetId() { return mlId; }
void SetId(int alX) { mlId = alX; }
iSoundData *GetData() { return mpData; }
// virtual void SetFiltering ( iFilter* apFilter, int alFlags ) = 0;
virtual void SetAffectedByEnv(bool abAffected) { mbAffectedByEnv = abAffected; }
virtual void SetFiltering(bool abEnabled, int alFlags) = 0;
virtual void SetFilterGain(float afGain) = 0;
virtual void SetFilterGainHF(float afGainHF) = 0;
protected:
iSoundData *mpData;
cSoundManager *mpSoundManger;
bool mbLooping;
bool mbPaused;
bool mbPositionRelative;
bool mb3D;
float mfSpeed;
float mfVolume;
float mfPan;
float mfMaxDistance;
float mfMinDistance;
cVector3f mvVelocity;
cVector3f mvPosition;
cVector3f mvRelPosition;
bool mbBlockable;
float mfBlockVolumeMul;
bool mbAffectedByEnv;
int mlPriority;
int mlPriorityModifier;
bool mbStopUsed;
int mlId;
iSoundChannelCallback *mpCallback;
};
typedef Common::List<iSoundChannel *> tSoundChannelList;
typedef tSoundChannelList::iterator tSoundChannelListIt;
} // namespace hpl
#endif // HPL_SOUND_CHANNEL_H

View File

@@ -0,0 +1,70 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_SOUND_DATA_H
#define HPL_SOUND_DATA_H
#include "hpl1/engine/resources/ResourceBase.h"
#include "hpl1/engine/system/SystemTypes.h"
namespace hpl {
class cSoundManager;
class iSoundChannel;
class iSoundData : public iResourceBase {
public:
iSoundData(tString asName, bool abStream) : iResourceBase(asName, 0),
mpSoundManger(NULL), mbStream(abStream) {}
virtual ~iSoundData() {}
virtual bool CreateFromFile(const tString &asFile) = 0;
virtual iSoundChannel *CreateChannel(int alPriority) = 0;
bool IsStream() { return mbStream; }
void SetLoopStream(bool abX) { mbLoopStream = abX; }
bool GetLoopStream() { return mbLoopStream; }
bool reload() { return false; }
void unload() {}
void destroy() {}
void SetSoundManager(cSoundManager *apSoundManager) {
mpSoundManger = apSoundManager;
}
protected:
bool mbStream;
bool mbLoopStream;
cSoundManager *mpSoundManger;
};
} // namespace hpl
#endif // HPL_SOUND_DATA_H

View File

@@ -0,0 +1,135 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/sound/SoundEntityData.h"
#include "hpl1/engine/resources/Resources.h"
#include "hpl1/engine/system/String.h"
#include "hpl1/engine/system/low_level_system.h"
#include "hpl1/engine/impl/tinyXML/tinyxml.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cSoundEntityData::cSoundEntityData(tString asName) : iResourceBase(asName, 0) {
msMainSound = "";
msStartSound = "";
msStopSound = "";
mbFadeStart = false;
mbFadeStop = false;
mfVolume = 1;
mfMaxDistance = 0;
mfMinDistance = 0;
mbStream = false;
mbLoop = false;
mbUse3D = true;
mfRandom = 1;
mfInterval = 0;
}
//-----------------------------------------------------------------------
cSoundEntityData::~cSoundEntityData() {
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
bool cSoundEntityData::CreateFromFile(const tString &asFile) {
TiXmlDocument *pDoc = hplNew(TiXmlDocument, ());
if (pDoc->LoadFile(asFile.c_str()) == false) {
Error("Couldn't load '%s'!\n", asFile.c_str());
hplDelete(pDoc);
return false;
}
TiXmlElement *pRootElem = pDoc->FirstChildElement();
////////////////////////////////////////////////
// MAIN
TiXmlElement *pMainElem = pRootElem->FirstChildElement("MAIN");
if (pMainElem == NULL) {
Error("Couldn't find MAIN element in '%s'!\n", asFile.c_str());
hplDelete(pDoc);
return false;
}
msMainSound = cString::ToString(pMainElem->Attribute("MainSound"), "");
msStartSound = cString::ToString(pMainElem->Attribute("StartSound"), "");
msStopSound = cString::ToString(pMainElem->Attribute("StopSound"), "");
////////////////////////////////////////////////
// PROPERTIES
TiXmlElement *pPropElem = pRootElem->FirstChildElement("PROPERTIES");
if (pPropElem == NULL) {
Error("Couldn't find PROPERTIES element in '%s'!\n", asFile.c_str());
hplDelete(pDoc);
return false;
}
mbUse3D = cString::ToBool(pPropElem->Attribute("Use3D"), true);
mbLoop = cString::ToBool(pPropElem->Attribute("Loop"), true);
mbStream = cString::ToBool(pPropElem->Attribute("Stream"), true);
mbBlockable = cString::ToBool(pPropElem->Attribute("Blockable"), false);
mfBlockVolumeMul = cString::ToFloat(pPropElem->Attribute("BlockVolumeMul"), 0.6f);
mfVolume = cString::ToFloat(pPropElem->Attribute("Volume"), 1);
mfMaxDistance = cString::ToFloat(pPropElem->Attribute("MaxDistance"), 1);
mfMinDistance = cString::ToFloat(pPropElem->Attribute("MinDistance"), 1);
mbFadeStart = cString::ToBool(pPropElem->Attribute("FadeStart"), true);
mbFadeStop = cString::ToBool(pPropElem->Attribute("FadeStop"), true);
mfRandom = cString::ToFloat(pPropElem->Attribute("Random"), 1);
mfInterval = cString::ToFloat(pPropElem->Attribute("Interval"), 0);
mlPriority = cString::ToInt(pPropElem->Attribute("Priority"), 0);
hplDelete(pDoc);
return true;
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,116 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_SOUND_ENTITY_DATA_H
#define HPL_SOUND_ENTITY_DATA_H
#include "hpl1/engine/resources/ResourceBase.h"
#include "hpl1/engine/system/SystemTypes.h"
namespace hpl {
class cSoundEntityData : public iResourceBase {
friend class cSoundEntity;
public:
cSoundEntityData(tString asName);
~cSoundEntityData();
bool CreateFromFile(const tString &asFile);
const tString &GetMainSoundName() { return msMainSound; }
void SetMainSoundName(const tString &asName) { msMainSound = asName; }
const tString &GetStartSoundName() { return msStartSound; }
void SetStartSoundName(const tString &asName) { msStartSound = asName; }
const tString &GetStopSoundName() { return msStopSound; }
void SetStopSoundName(const tString &asName) { msStopSound = asName; }
void SetFadeStart(bool abX) { mbFadeStart = abX; }
bool GetFadeStart() { return mbFadeStart; }
void SetFadeStop(bool abX) { mbFadeStop = abX; }
bool GetFadeStop() { return mbFadeStop; }
void SetVolume(float afX) { mfVolume = afX; }
float GetVolume() { return mfVolume; }
void SetMaxDistance(float afX) { mfMaxDistance = afX; }
float GetMaxDistance() { return mfMaxDistance; }
void SetMinDistance(float afX) { mfMinDistance = afX; }
float GetMinDistance() { return mfMinDistance; }
void SetStream(bool abX) { mbStream = abX; }
bool GetStream() { return mbStream; }
void SetLoop(bool abX) { mbLoop = abX; }
bool GetLoop() { return mbLoop; }
void SetUse3D(bool abX) { mbUse3D = abX; }
bool GetUse3D() { return mbUse3D; }
void SetBlockable(bool abX) { mbBlockable = abX; }
bool GetBlockable() { return mbBlockable; }
void SetBlockVolumeMul(float afX) { mfBlockVolumeMul = afX; }
float GetBlockVolumeMul() { return mfBlockVolumeMul; }
void SetRandom(float afX) { mfRandom = afX; }
float GetRandom() { return mfRandom; }
void SetInterval(float afX) { mfInterval = afX; }
float GetInterval() { return mfInterval; }
void SetPriority(int alX) { mlPriority = alX; }
int GetPriority() { return mlPriority; }
// Resource implementation
bool reload() { return false; }
void unload() {}
void destroy() {}
protected:
tString msMainSound;
tString msStartSound;
tString msStopSound;
bool mbFadeStart;
bool mbFadeStop;
float mfVolume;
float mfMaxDistance;
float mfMinDistance;
bool mbStream;
bool mbLoop;
bool mbUse3D;
bool mbBlockable;
float mfBlockVolumeMul;
float mfRandom;
float mfInterval;
int mlPriority;
};
} // namespace hpl
#endif // HPL_SOUND_DATA_H

View File

@@ -0,0 +1,54 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_SOUNDENVIRONMENT_H
#define HPL_SOUNDENVIRONMENT_H
#include "hpl1/engine/system/String.h"
namespace hpl {
class cSoundManager;
class iSoundEnvironment {
public:
iSoundEnvironment() {}
virtual ~iSoundEnvironment() {}
virtual bool CreateFromFile(const tString &asFile) { return false; }
tString &GetName() { return mstrName; }
tString &GetFileName() { return msFileName; }
void SetFileName(const tString &asFileName) { msFileName = asFileName; }
protected:
tString mstrName;
tString msFileName;
};
} // namespace hpl
#endif // HPL_SOUNDENVIRONMENT_H

View File

@@ -0,0 +1,919 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#include "hpl1/engine/sound/SoundHandler.h"
#include "hpl1/engine/math/Math.h"
#include "hpl1/engine/resources/Resources.h"
#include "hpl1/engine/resources/SoundManager.h"
#include "hpl1/engine/sound/LowLevelSound.h"
#include "hpl1/engine/sound/SoundChannel.h"
#include "hpl1/engine/sound/SoundData.h"
#include "hpl1/engine/system/String.h"
#include "hpl1/engine/system/low_level_system.h"
#include "hpl1/engine/physics/PhysicsBody.h"
#include "hpl1/engine/physics/PhysicsWorld.h"
#include "hpl1/engine/scene/World3D.h"
namespace hpl {
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cSoundHandler::cSoundHandler(iLowLevelSound *apLowLevelSound, cResources *apResources) {
mpLowLevelSound = apLowLevelSound;
mpResources = apResources;
mfSpeed = 1;
mfNewSpeed = 1;
mfSpeedRate = 0;
mfVolume = 1;
mfNewVolume = 1;
mfVolumeRate = 0;
mpWorld3D = NULL;
mlCount = 0;
mlIdCount = 0;
mbSilent = false;
mAffectedBySpeed = eSoundDest_World;
mAffectedByVolume = eSoundDest_World;
}
//-----------------------------------------------------------------------
cSoundHandler::~cSoundHandler() {
tSoundEntryListIt it;
it = mlstGuiSounds.begin();
while (it != mlstGuiSounds.end()) {
it->mpSound->Stop();
hplDelete(it->mpSound);
it = mlstGuiSounds.erase(it);
}
it = mlstWorldSounds.begin();
while (it != mlstWorldSounds.end()) {
it->mpSound->Stop();
hplDelete(it->mpSound);
it = mlstWorldSounds.erase(it);
}
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////
void cSoundRayCallback::Reset() {
mbHasCollided = false;
}
bool cSoundRayCallback::BeforeIntersect(iPhysicsBody *pBody) {
if (pBody->GetBlocksSound())
return true;
return false;
}
bool cSoundRayCallback::OnIntersect(iPhysicsBody *pBody, cPhysicsRayParams *apParams) {
mbHasCollided = true;
return false;
}
//-----------------------------------------------------------------------
void cSoundEntry::Update(float afTimeStep) {
if (mfNormalVolumeMul != mfNormalVolumeFadeDest) {
// Log("speed %s: %f\n", msName.c_str(),mfNormalVolumeFadeSpeed);
mfNormalVolumeMul += mfNormalVolumeFadeSpeed * afTimeStep;
if (mfNormalVolumeMul < 0)
mfNormalVolumeMul = 0;
if (mfNormalVolumeMul > 1)
mfNormalVolumeMul = 1;
if (mfNormalVolumeFadeSpeed < 0) {
if (mfNormalVolumeMul <= mfNormalVolumeFadeDest) {
mfNormalVolumeMul = mfNormalVolumeFadeDest;
}
} else {
if (mfNormalVolumeMul >= mfNormalVolumeFadeDest) {
mfNormalVolumeMul = mfNormalVolumeFadeDest;
}
}
}
if (ABS(mfNormalVolumeFadeDest) < 0.001f && ABS(mfNormalVolumeMul) < 0.001f && mfNormalVolumeFadeSpeed <= 0) {
mpSound->Stop();
}
}
//-----------------------------------------------------------------------
iSoundChannel *cSoundHandler::Play(const tString &asName, bool abLoop, float afVolume, const cVector3f &avPos,
float afMinDist, float afMaxDist, eSoundDest mType, bool abRelative, bool ab3D, int alPriorityModifier,
eSoundDest aEffectType) {
if (asName == "")
return NULL;
// Calculate priority
int lPrio = 255;
if (mType == eSoundDest_World && !abRelative) {
lPrio = alPriorityModifier;
float fDist = cMath::Vector3Dist(avPos, mpLowLevelSound->GetListenerPosition());
if (fDist >= afMaxDist)
lPrio += 0;
else if (fDist >= afMinDist)
lPrio += 10;
else
lPrio += 100;
}
// Create sound channel
iSoundChannel *pSound = CreateChannel(asName, lPrio);
if (pSound == NULL) {
Warning("Can't find sound '%s' (may also be due too many sounds playing).\n", asName.c_str());
return NULL;
}
// Set up channel
pSound->SetLooping(abLoop);
pSound->SetMinDistance(afMinDist);
pSound->SetMaxDistance(afMaxDist);
pSound->Set3D(ab3D);
pSound->SetPriority(lPrio);
/////// NEW -- Set sound to use Environment if its a world sound
if (aEffectType == eSoundDest_World)
pSound->SetAffectedByEnv(true);
//////////////////////////////////////////////////////////////////
if (mType == eSoundDest_Gui) {
pSound->SetPositionRelative(true);
// pSound->SetPosition(avPos);
pSound->SetRelPosition(avPos);
cVector3f vPos = cMath::MatrixMul(mpLowLevelSound->GetListenerMatrix(), avPos);
pSound->SetPosition(vPos);
// Needed?
// pSound->SetPosition(mpLowLevelSound->GetListenerPosition() +
// pSound->GetRelPosition());
} else {
pSound->SetPositionRelative(abRelative);
if (abRelative) {
pSound->SetRelPosition(avPos);
cVector3f vPos = cMath::MatrixMul(mpLowLevelSound->GetListenerMatrix(), avPos);
pSound->SetPosition(vPos);
} else {
pSound->SetPosition(avPos);
}
}
pSound->SetId(mlIdCount);
cSoundEntry Entry;
Entry.mpSound = pSound;
Entry.mfNormalVolume = afVolume;
Entry.msName = asName;
Entry.mfNormalSpeed = 1.0f;
Entry.mfBlockFadeDest = 1;
Entry.mfBlockFadeSpeed = 1;
Entry.mfBlockMul = 1;
Entry.mbFirstTime = true;
Entry.mEffectType = aEffectType;
////////////////////////
// Set start volume
// GUI
if (mType == eSoundDest_Gui) {
pSound->SetVolume(afVolume);
}
// World
else {
pSound->SetVolume(0);
// UpdateDistanceVolume3D(&Entry,1.0f/60.0f,false,mType);
}
// If it is silent do everything as normal except stop the sound at start.
if (mbSilent) {
pSound->SetLooping(false);
pSound->Stop();
} else {
pSound->Play();
}
if (mType == eSoundDest_Gui) {
mlstGuiSounds.push_back(Entry);
} else {
mlstWorldSounds.push_back(Entry);
}
// Log("Starting sound '%s' prio: %d\n", pSound->GetData()->GetName().c_str(),
// pSound->GetPriority());
mlIdCount++;
return pSound;
}
//-----------------------------------------------------------------------
iSoundChannel *cSoundHandler::PlayGui(const tString &asName, bool abLoop, float afVolume, const cVector3f &avPos,
eSoundDest aEffectType) {
return Play(asName, abLoop, afVolume, avPos, 1.0f, 1000.0f, eSoundDest_Gui, true, false, 0, aEffectType);
}
//-----------------------------------------------------------------------
iSoundChannel *cSoundHandler::PlayStream(const tString &asFileName, bool abLoop, float afVolume, bool ab3D, eSoundDest aEffectType) {
if (asFileName == "")
return NULL;
iSoundData *pData = mpResources->GetSoundManager()->CreateSoundData(asFileName, true, abLoop);
if (pData == NULL) {
Error("Couldn't load stream '%s'\n", asFileName.c_str());
return nullptr;
}
iSoundChannel *pSound = pData->CreateChannel(256);
if (!pSound) {
Error("Can't create sound channel for '%s'\n", asFileName.c_str());
return NULL;
}
// If it is silent do everything as normal except stop the sound at start.
if (mbSilent) {
// pSound->SetLooping(false);
pSound->Stop();
} else {
pSound->Play();
}
pSound->SetId(mlIdCount);
pSound->Set3D(ab3D);
cSoundEntry Entry;
Entry.mpSound = pSound;
Entry.mfNormalVolume = afVolume;
Entry.msName = asFileName;
Entry.mfNormalSpeed = 1.0f;
Entry.mfBlockFadeDest = 1;
Entry.mfBlockFadeSpeed = 1;
Entry.mfBlockMul = 1;
Entry.mbFirstTime = true;
Entry.mbStream = true;
Entry.mEffectType = aEffectType;
/////////////////////////
// Setup position
pSound->SetPositionRelative(true);
pSound->SetRelPosition(cVector3f(0, 0, 1));
cVector3f vPos = cMath::MatrixMul(mpLowLevelSound->GetListenerMatrix(),
pSound->GetRelPosition());
pSound->SetPosition(vPos);
mlstGuiSounds.push_back(Entry);
mlIdCount++;
return pSound;
}
//-----------------------------------------------------------------------
bool cSoundHandler::Stop(const tString &asName) {
cSoundEntry *pEntry = GetEntry(asName);
if (pEntry) {
pEntry->mpSound->Stop();
} else {
return false;
}
return true;
}
//-----------------------------------------------------------------------
bool cSoundHandler::StopAllExcept(const tString &asName) {
return false;
}
//-----------------------------------------------------------------------
void cSoundHandler::StopAll(tFlag mTypes) {
tSoundEntryListIt it;
if (mTypes & eSoundDest_Gui) {
it = mlstGuiSounds.begin();
while (it != mlstGuiSounds.end()) {
it->mpSound->SetPaused(false);
it->mpSound->Stop();
it++;
}
}
if (mTypes & eSoundDest_World) {
it = mlstWorldSounds.begin();
while (it != mlstWorldSounds.end()) {
// Log("Stopping: %s\n",it->mpSound->GetData()->GetName().c_str());
it->mpSound->SetPaused(false);
it->mpSound->Stop();
it++;
}
}
}
//-----------------------------------------------------------------------
void cSoundHandler::PauseAll(tFlag mTypes) {
tSoundEntryListIt it;
if (mTypes & eSoundDest_Gui) {
it = mlstGuiSounds.begin();
while (it != mlstGuiSounds.end()) {
it->mpSound->SetPaused(true);
it++;
}
}
if (mTypes & eSoundDest_World) {
it = mlstWorldSounds.begin();
while (it != mlstWorldSounds.end()) {
it->mpSound->SetPaused(true);
it++;
}
}
}
//-----------------------------------------------------------------------
void cSoundHandler::ResumeAll(tFlag mTypes) {
tSoundEntryListIt it;
if (mTypes & eSoundDest_Gui) {
it = mlstGuiSounds.begin();
while (it != mlstGuiSounds.end()) {
it->mpSound->SetPaused(false);
it++;
}
}
if (mTypes & eSoundDest_World) {
it = mlstWorldSounds.begin();
while (it != mlstWorldSounds.end()) {
it->mpSound->SetPaused(false);
it++;
}
}
}
//-----------------------------------------------------------------------
bool cSoundHandler::IsPlaying(const tString &asName) {
cSoundEntry *pEntry = GetEntry(asName);
if (pEntry)
return pEntry->mpSound->IsPlaying();
return false;
}
//-----------------------------------------------------------------------
bool cSoundHandler::IsValid(iSoundChannel *apChannel) {
tSoundEntryListIt it;
it = mlstWorldSounds.begin();
while (it != mlstWorldSounds.end()) {
if (it->mpSound == apChannel)
return true;
it++;
}
it = mlstGuiSounds.begin();
while (it != mlstGuiSounds.end()) {
if (it->mpSound == apChannel)
return true;
it++;
}
return false;
}
//-----------------------------------------------------------------------
bool cSoundHandler::IsValidId(iSoundChannel *apChannel, int alId) {
if (apChannel == NULL)
return false;
tSoundEntryListIt it = mlstWorldSounds.begin();
while (it != mlstWorldSounds.end()) {
if (it->mpSound == apChannel && it->mpSound->GetId() == alId)
return true;
it++;
}
it = mlstGuiSounds.begin();
while (it != mlstGuiSounds.end()) {
if (it->mpSound == apChannel && it->mpSound->GetId() == alId)
return true;
it++;
}
return false;
}
//-----------------------------------------------------------------------
void cSoundHandler::Update(float afTimeStep) {
if (mfNewSpeed != mfSpeed) {
mfSpeed += mfSpeedRate;
if (mfSpeedRate < 0 && mfSpeed < mfNewSpeed)
mfSpeed = mfNewSpeed;
if (mfSpeedRate > 0 && mfSpeed > mfNewSpeed)
mfSpeed = mfNewSpeed;
}
if (mfNewVolume != mfVolume) {
mfVolume += mfVolumeRate * afTimeStep;
if (mfVolumeRate < 0 && mfVolume < mfNewVolume)
mfVolume = mfNewVolume;
if (mfVolumeRate > 0 && mfVolume > mfNewVolume)
mfVolume = mfNewVolume;
}
tSoundEntryListIt it;
it = mlstGuiSounds.begin();
while (it != mlstGuiSounds.end()) {
if (UpdateEntry(&(*it), afTimeStep, eSoundDest_Gui) == false) {
it = mlstGuiSounds.erase(it);
} else {
++it;
}
}
it = mlstWorldSounds.begin();
while (it != mlstWorldSounds.end()) {
if (UpdateEntry(&(*it), afTimeStep, eSoundDest_World) == false) {
it = mlstWorldSounds.erase(it);
} else {
++it;
}
}
mlCount++;
}
//-----------------------------------------------------------------------
/**
*
* \todo support types.
* \param afSpeed New speed to run sounds at
* \param afRate Rate by which the current speed transform to the new
* \param mTypes Types affected, not working yet :S
*/
void cSoundHandler::SetSpeed(float afSpeed, float afRate, tFlag aTypes) {
mfNewSpeed = afSpeed;
if (mfNewSpeed > mfSpeed && afRate < 0)
afRate = -afRate;
if (mfNewSpeed < mfSpeed && afRate > 0)
afRate = -afRate;
mfSpeedRate = afRate;
mAffectedBySpeed = aTypes;
if (afRate == 0)
mfSpeed = mfNewSpeed;
}
//-----------------------------------------------------------------------
void cSoundHandler::SetVolume(float afVolume, float afRate, tFlag aTypes) {
mfNewVolume = afVolume;
if (mfNewVolume > mfVolume && afRate < 0)
afRate = -afRate;
if (mfNewVolume < mfVolume && afRate > 0)
afRate = -afRate;
mfVolumeRate = afRate;
mAffectedByVolume = aTypes;
if (afRate == 0)
mfVolume = mfNewVolume;
}
//-----------------------------------------------------------------------
void cSoundHandler::SetWorld3D(cWorld3D *apWorld3D) {
mpWorld3D = apWorld3D;
}
//-----------------------------------------------------------------------
cSoundEntry *cSoundHandler::GetEntryFromSound(iSoundChannel *apSound) {
tSoundEntryListIt it = mlstGuiSounds.begin();
while (it != mlstGuiSounds.end()) {
if (it->mpSound == apSound) {
// Log("returning from GUI %d\n",&(*it));
return &(*it);
}
++it;
}
it = mlstWorldSounds.begin();
while (it != mlstWorldSounds.end()) {
if (it->mpSound == apSound) {
// Log("returning from World %d\n",&(*it));
return &(*it);
}
++it;
}
return NULL;
}
//-----------------------------------------------------------------------
tSoundEntryList *cSoundHandler::GetWorldEntryList() {
return &mlstWorldSounds;
}
tSoundEntryList *cSoundHandler::GetGuiEntryList() {
return &mlstGuiSounds;
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
bool cSoundHandler::UpdateEntry(cSoundEntry *apEntry, float afTimeStep, tFlag aTypes) {
// if(apEntry->mbStream) return;
apEntry->Update(afTimeStep);
/*Log("Updating entry: '%s' vol: %f playing: %d\n",apEntry->msName.c_str(),
apEntry->mpSound->GetVolume(),
apEntry->mpSound->IsPlaying()?1:0);*/
// Log("Pos: %s\n",apEntry->mpSound->GetPosition().ToString().c_str());
if (!apEntry->mpSound->IsPlaying() && !apEntry->mpSound->GetPaused()) {
iSoundChannel *pSound = apEntry->mpSound;
if (pSound->GetStopUsed() == false && pSound->GetCallBack() && pSound->GetLooping() && apEntry->mfNormalVolumeFadeDest != 0) {
pSound->GetCallBack()->OnPriorityRelease();
// Log("On prio release!\n");
}
// Log("Stopping: %s Time: %f / %f\n",pSound->GetData()->GetName().c_str(),
// pSound->GetElapsedTime(),
// pSound->GetTotalTime());
pSound->Stop();
hplDelete(pSound);
return false;
} else {
if (mAffectedBySpeed & apEntry->mEffectType) {
float fSpeed = mfSpeed * apEntry->mfNormalSpeed;
if (apEntry->mpSound->GetSpeed() != fSpeed) {
apEntry->mpSound->SetSpeed(fSpeed);
}
} else {
if (apEntry->mpSound->GetSpeed() != apEntry->mfNormalSpeed) {
apEntry->mpSound->SetSpeed(apEntry->mfNormalSpeed);
}
}
//////////////////////////////
// Update block fade:
if (apEntry->mfBlockMul != apEntry->mfBlockFadeDest) {
apEntry->mfBlockMul += apEntry->mfBlockFadeSpeed * afTimeStep;
if (apEntry->mfBlockFadeSpeed < 0) {
if (apEntry->mfBlockMul < apEntry->mfBlockFadeDest)
apEntry->mfBlockMul = apEntry->mfBlockFadeDest;
} else {
if (apEntry->mfBlockMul > apEntry->mfBlockFadeDest)
apEntry->mfBlockMul = apEntry->mfBlockFadeDest;
}
}
// Update the sound position
// 3D Position!
if (apEntry->mbStream) {
apEntry->mpSound->SetVolume(apEntry->mfNormalVolume * apEntry->mfNormalVolumeMul * mfVolume);
}
// else if(apEntry->mpSound->Get3D())
if (apEntry->mpSound->Get3D()) {
UpdateDistanceVolume3D(apEntry, afTimeStep, apEntry->mbFirstTime ? false : true, aTypes);
}
// 2D Position
else {
if (apEntry->mpSound->GetPositionRelative()) {
iSoundChannel *pSound = apEntry->mpSound;
cVector3f vPos = cMath::MatrixMul(mpLowLevelSound->GetListenerMatrix(), pSound->GetRelPosition());
pSound->SetPosition(vPos);
if (apEntry->mEffectType & mAffectedByVolume) {
pSound->SetVolume(apEntry->mfNormalVolume * apEntry->mfNormalVolumeMul * mfVolume);
} else {
pSound->SetVolume(apEntry->mfNormalVolume * apEntry->mfNormalVolumeMul);
}
} else {
iSoundChannel *pSound = apEntry->mpSound;
float fDX = pSound->GetPosition().x - mpLowLevelSound->GetListenerPosition().x;
float fDY = pSound->GetPosition().y - mpLowLevelSound->GetListenerPosition().y;
float fDist = sqrt(fDX * fDX + fDY * fDY);
if (fDist >= pSound->GetMaxDistance()) {
pSound->SetVolume(0);
} else {
if (fDist < pSound->GetMinDistance()) {
pSound->SetVolume(apEntry->mfNormalVolume); // some other stuff to support volume effects
} else {
float fVolume = 1 - ((fDist - pSound->GetMinDistance()) /
(pSound->GetMaxDistance() - pSound->GetMinDistance()));
fVolume *= apEntry->mfNormalVolume;
pSound->SetVolume(fVolume);
}
float fPan = 1 - (0.5f - 0.4f * (fDX / pSound->GetMaxDistance()));
pSound->SetPan(fPan);
}
}
}
}
apEntry->mbFirstTime = false;
return true;
}
//-----------------------------------------------------------------------
void cSoundHandler::UpdateDistanceVolume3D(cSoundEntry *apEntry, float afTimeStep, bool abFade,
tFlag aTypes) {
if (mpWorld3D == NULL) {
return;
}
if (apEntry->mpSound->GetPositionRelative()) {
iSoundChannel *pSound = apEntry->mpSound;
cVector3f vPos = cMath::MatrixMul(mpLowLevelSound->GetListenerMatrix(),
pSound->GetRelPosition());
pSound->SetPosition(vPos);
// cVector3f vPos = cMath::MatrixMul(mpLowLevelSound->GetListenerMatrix(),
// pSound->GetRelPosition());
// pSound->SetPosition(pSound->GetRelPosition());
if (aTypes & mAffectedByVolume) {
pSound->SetVolume(apEntry->mfNormalVolume * apEntry->mfNormalVolumeMul * mfVolume);
} else {
pSound->SetVolume(apEntry->mfNormalVolume * apEntry->mfNormalVolumeMul);
}
} else {
// Log("%s ",apEntry->msName.c_str());
iSoundChannel *pSound = apEntry->mpSound;
float fDist = cMath::Vector3Dist(pSound->GetPosition(),
mpLowLevelSound->GetListenerPosition());
if (fDist >= pSound->GetMaxDistance()) {
pSound->SetVolume(0);
// Set very low priority
pSound->SetPriority(0);
// Log(" max distance ");
} else {
float fVolume = 0;
// bool bBlocked = false;
////////////////////////////////////////
// Check if sound is blocked.
if (pSound->GetBlockable() && mpWorld3D && mpWorld3D->GetPhysicsWorld() && (apEntry->mlCount % 30) == 0) {
iPhysicsWorld *pPhysicsWorld = mpWorld3D->GetPhysicsWorld();
mSoundRayCallback.Reset();
pPhysicsWorld->CastRay(&mSoundRayCallback, pSound->GetPosition(),
mpLowLevelSound->GetListenerPosition(),
false, false, false, true);
// Log(" from (%s) to (%s) ",pSound->GetPosition().ToString().c_str(),
// mpLowLevelSound->GetListenerPosition().ToString().c_str());
// Log(" callback: %d ",mSoundRayCallback.HasCollided()?1:0);
if (mSoundRayCallback.HasCollided()) {
apEntry->mfBlockFadeDest = 0.0f;
apEntry->mfBlockFadeSpeed = -1.0f / 0.55f;
if (abFade == false) {
apEntry->mfBlockMul = 0.0f;
}
pSound->SetFiltering(true, 0xF);
// bBlocked = true;
} else {
// pSound->SetFiltering(false, 0xF);
apEntry->mfBlockFadeDest = 1;
apEntry->mfBlockFadeSpeed = 1.0f / 0.2f;
if (abFade == false) {
apEntry->mfBlockMul = 1.0f;
}
}
// Log("Blocked: %d ",bBlocked ? 1 : 0);
}
++apEntry->mlCount;
/////////////////////////////////////
// Lower volume according to distance
if (fDist < pSound->GetMinDistance()) {
// Set high priority
pSound->SetPriority(100);
fVolume = apEntry->mfNormalVolume; // some other stuff to support volume effects
} else {
// Set medium priority
pSound->SetPriority(10);
float fDelta = fDist - pSound->GetMinDistance();
float fMaxDelta = pSound->GetMaxDistance() - pSound->GetMinDistance();
fVolume = 1 - (fDelta / fMaxDelta);
float fSqr = fVolume * fVolume;
// Log("Lin: %f Sqr: %f ",fVolume,fSqr);
// fade between normal and square
fVolume = fVolume * apEntry->mfBlockMul + (1.0f - apEntry->mfBlockMul) * fSqr;
// Log("Mix: %f ",fVolume);
fVolume *= apEntry->mfNormalVolume;
}
float fBlock = pSound->GetBlockVolumeMul() +
apEntry->mfBlockMul * (1 - pSound->GetBlockVolumeMul());
if (aTypes & apEntry->mEffectType) {
pSound->SetVolume(fBlock * fVolume * apEntry->mfNormalVolumeMul * mfVolume);
// pSound->SetFilterGainHF(fBlock * fVolume * apEntry->mfNormalVolumeMul * mfVolume);
} else {
pSound->SetVolume(fBlock * fVolume * apEntry->mfNormalVolumeMul);
}
// pSound->SetFilterGainHF(0.1f);
// Log("Vol: %f\n",fBlock * fVolume * apEntry->mfNormalVolumeMul);
// Log("%s Block: %f\n",apEntry->msName.c_str(),apEntry->mfBlockMul);
}
}
}
//-----------------------------------------------------------------------
cSoundEntry *cSoundHandler::GetEntry(const tString &asName) {
tSoundEntryListIt it = mlstGuiSounds.begin();
while (it != mlstGuiSounds.end()) {
if (cString::ToLowerCase(it->msName) == cString::ToLowerCase(asName)) {
return &(*it);
}
it++;
}
it = mlstWorldSounds.begin();
while (it != mlstWorldSounds.end()) {
// Log("'%s' vs '%s'\n", it->msName.c_str(), asName.c_str());
if (cString::ToLowerCase(it->msName) == cString::ToLowerCase(asName)) {
return &(*it);
}
it++;
}
return NULL;
}
//-----------------------------------------------------------------------
iSoundChannel *cSoundHandler::CreateChannel(const tString &asName, int alPriority) {
int lNum = cString::ToInt(cString::GetLastChar(asName).c_str(), 0);
iSoundChannel *pSound = NULL;
iSoundData *pData = NULL;
tString sName;
tString sBaseName = asName;
// Try loading it from the buffer
if (lNum >= 1 && lNum <= 9) {
pData = mpResources->GetSoundManager()->CreateSoundData(asName, false);
} else {
int lCount = 0;
int lLastNum = -1;
// Check what the last sound played was.
tPlayedSoundNumMapIt SoundIt = m_mapPlayedSound.find(sBaseName);
if (SoundIt == m_mapPlayedSound.end()) {
m_mapPlayedSound.insert(tPlayedSoundNumMap::value_type(sBaseName, 0));
SoundIt = m_mapPlayedSound.find(sBaseName);
} else {
lLastNum = SoundIt->second;
}
sName = sBaseName + cString::ToString(lCount + 1);
pData = mpResources->GetSoundManager()->CreateSoundData(sName, false);
while (pData) {
lCount++;
sName = sBaseName + cString::ToString(lCount + 1);
pData = mpResources->GetSoundManager()->CreateSoundData(sName, false);
}
if (lCount > 0) {
int lNum2 = cMath::RandRectl(1, lCount);
if (lCount > 2) {
while (lLastNum == lNum2)
lNum2 = cMath::RandRectl(1, lCount);
}
SoundIt->second = lNum2;
sName = sBaseName + cString::ToString(lNum2);
pData = mpResources->GetSoundManager()->CreateSoundData(sName, false);
} else {
pData = NULL;
}
}
// Try to stream it
if (pData == NULL) {
sName = "stream_" + sBaseName;
pData = mpResources->GetSoundManager()->CreateSoundData(sName, true);
if (pData == NULL) {
Error("Couldn't stream sound '%s'\n", asName.c_str());
return NULL;
}
}
// Create sound channel
pSound = pData->CreateChannel(alPriority);
if (pSound == NULL) {
// Warning("Couldn't play sound '%s'\n",asName.c_str());
}
return pSound;
}
//-----------------------------------------------------------------------
} // namespace hpl

View File

@@ -0,0 +1,210 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of HPL1 Engine.
*/
#ifndef HPL_SOUNDHANDLER_H
#define HPL_SOUNDHANDLER_H
#include "common/list.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/physics/PhysicsWorld.h"
#include "hpl1/engine/system/SystemTypes.h"
namespace hpl {
class iLowLevelSound;
class iSoundChannel;
class cWorld3D;
//----------------------------------------
enum eSoundDest : unsigned int {
eSoundDest_World = eFlagBit_0,
eSoundDest_Gui = eFlagBit_1,
eSoundDest_All = eFlagBit_All
};
//----------------------------------------
class cSoundRayCallback : public iPhysicsRayCallback {
public:
void Reset();
bool HasCollided() { return mbHasCollided; }
bool BeforeIntersect(iPhysicsBody *pBody);
bool OnIntersect(iPhysicsBody *pBody, cPhysicsRayParams *apParams);
private:
bool mbHasCollided;
// int mlCount;
};
//----------------------------------------
////////////////////////////////////////////////////
//////////// SOUND ENTRY ///////////////////////////
////////////////////////////////////////////////////
class cSoundEntry {
public:
cSoundEntry() : mfNormalVolume(1), mfNormalVolumeFadeDest(1),
mfNormalVolumeMul(1), mfNormalVolumeFadeSpeed(0), mbStream(false),
mlCount(0), mpSound(nullptr) {}
void Update(float afTimeStep);
tString msName;
iSoundChannel *mpSound;
float mfNormalVolume;
float mfNormalVolumeMul;
float mfNormalVolumeFadeDest;
float mfNormalVolumeFadeSpeed;
float mfNormalSpeed;
bool mbFirstTime;
float mfBlockMul;
float mfBlockFadeDest;
float mfBlockFadeSpeed;
bool mbStream;
long int mlCount;
eSoundDest mEffectType;
};
typedef Common::List<cSoundEntry> tSoundEntryList;
typedef tSoundEntryList::iterator tSoundEntryListIt;
typedef cSTLIterator<cSoundEntry, tSoundEntryList, tSoundEntryListIt> tSoundEntryIterator;
////////////////////////////////////////////////////
//////////// SOUND HANDLER ///////////////////////
////////////////////////////////////////////////////
//----------------------------------------
typedef Common::StableMap<tString, int> tPlayedSoundNumMap;
typedef tPlayedSoundNumMap::iterator tPlayedSoundNumMapIt;
//----------------------------------------
class cResources;
//----------------------------------------
class cSoundHandler {
public:
cSoundHandler(iLowLevelSound *apLowLevelSound, cResources *apResources);
~cSoundHandler();
iSoundChannel *Play(const tString &asName, bool abLoop, float afVolume, const cVector3f &avPos,
float afMinDist, float afMaxDist, eSoundDest mType, bool abRelative, bool ab3D = false,
int alPriorityModifier = 0, eSoundDest aEffectType = eSoundDest_World);
iSoundChannel *Play3D(const tString &asName, bool abLoop, float afVolume, const cVector3f &avPos,
float afMinDist, float afMaxDist, eSoundDest mType, bool abRelative, int alPriorityModifier = 0,
eSoundDest aEffectType = eSoundDest_World) {
return Play(asName, abLoop, afVolume, avPos, afMinDist, afMaxDist, mType, abRelative, true,
alPriorityModifier, aEffectType);
}
iSoundChannel *PlayStream(const tString &asFileName, bool abLoop, float afVolume, bool ab3D = false,
eSoundDest aEffectType = eSoundDest_Gui);
iSoundChannel *PlayGui(const tString &asName, bool abLoop, float afVolume, const cVector3f &avPos = cVector3f(0, 0, 1),
eSoundDest aEffectType = eSoundDest_Gui);
void SetSilent(bool abX) { mbSilent = abX; }
bool GetSilent() { return mbSilent; }
bool Stop(const tString &asName);
bool StopAllExcept(const tString &asName);
void StopAll(tFlag mTypes);
void PauseAll(tFlag mTypes);
void ResumeAll(tFlag mTypes);
bool IsPlaying(const tString &asName);
bool IsValid(iSoundChannel *apChannel);
bool IsValidId(iSoundChannel *apChannel, int alId);
void Update(float afTimeStep);
void SetSpeed(float afSpeed, float afRate, tFlag mTypes);
void SetVolume(float afVolume, float afRate, tFlag mTypes);
float GetVolume() { return mfVolume; }
void SetWorld3D(cWorld3D *apWorld3D);
cSoundEntry *GetEntryFromSound(iSoundChannel *apSound);
iSoundChannel *CreateChannel(const tString &asName, int alPriority);
tSoundEntryList *GetWorldEntryList();
tSoundEntryList *GetGuiEntryList();
private:
iLowLevelSound *mpLowLevelSound;
cResources *mpResources;
tSoundEntryList mlstGuiSounds;
tSoundEntryList mlstWorldSounds;
bool mbSilent;
float mfSpeed;
float mfNewSpeed;
float mfSpeedRate;
tFlag mAffectedBySpeed;
float mfVolume;
float mfNewVolume;
float mfVolumeRate;
tFlag mAffectedByVolume;
cWorld3D *mpWorld3D;
cSoundRayCallback mSoundRayCallback;
tPlayedSoundNumMap m_mapPlayedSound;
cSoundEntry *GetEntry(const tString &asName);
bool UpdateEntry(cSoundEntry *apEntry, float afTimeStep, tFlag aTypes);
void UpdateDistanceVolume3D(cSoundEntry *apEntry, float afTimeStep, bool abFade, tFlag aTypes);
int mlCount;
int mlIdCount;
};
} // namespace hpl
#endif // HPL_SOUNDHANDLER_H