1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-22 08:53:54 +00:00

Merge branch 'master' into occlusionquery

This commit is contained in:
scrawl 2012-03-28 21:04:42 +02:00
commit 29acb057b3
10 changed files with 216 additions and 180 deletions

View file

@ -4,9 +4,6 @@ if (APPLE)
set(APP_BUNDLE_NAME "${CMAKE_PROJECT_NAME}.app") set(APP_BUNDLE_NAME "${CMAKE_PROJECT_NAME}.app")
set(APP_BUNDLE_DIR "${OpenMW_BINARY_DIR}/${APP_BUNDLE_NAME}") set(APP_BUNDLE_DIR "${OpenMW_BINARY_DIR}/${APP_BUNDLE_NAME}")
# using 10.6 sdk
set(CMAKE_OSX_SYSROOT "/Developer/SDKs/MacOSX10.6.sdk")
endif (APPLE) endif (APPLE)
# Macros # Macros
@ -259,7 +256,16 @@ endif (APPLE)
# Compiler settings # Compiler settings
if (CMAKE_COMPILER_IS_GNUCC) if (CMAKE_COMPILER_IS_GNUCC)
add_definitions (-Wall -Wextra -Wno-unused-parameter -Wno-unused-but-set-parameter -Wno-reorder) add_definitions (-Wall -Wextra -Wno-unused-parameter -Wno-reorder)
# Silence warnings in OGRE headers. Remove once OGRE got fixed!
add_definitions (-Wno-ignored-qualifiers)
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
OUTPUT_VARIABLE GCC_VERSION)
if ("${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6)
add_definitions (-Wno-unused-but-set-parameter)
endif("${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6)
endif (CMAKE_COMPILER_IS_GNUCC) endif (CMAKE_COMPILER_IS_GNUCC)
if(DPKG_PROGRAM) if(DPKG_PROGRAM)
@ -319,6 +325,7 @@ if(WIN32)
FILE(GLOB files "${OpenMW_BINARY_DIR}/Release/*.*") FILE(GLOB files "${OpenMW_BINARY_DIR}/Release/*.*")
INSTALL(FILES ${files} DESTINATION ".") INSTALL(FILES ${files} DESTINATION ".")
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg") INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg")
INSTALL(FILES "${OpenMW_SOURCE_DIR}/readme.txt" DESTINATION ".")
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".") INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".")
SET(CPACK_GENERATOR "NSIS") SET(CPACK_GENERATOR "NSIS")
@ -329,6 +336,7 @@ if(WIN32)
SET(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINO}) SET(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINO})
SET(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE}) SET(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE})
SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW;esmtool;Esmtool;omwlauncher;OpenMW Launcher") SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW;esmtool;Esmtool;omwlauncher;OpenMW Launcher")
set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Readme.lnk' '\$INSTDIR\\\\readme.txt'")
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${OpenMW_SOURCE_DIR}/readme.txt") SET(CPACK_PACKAGE_DESCRIPTION_FILE "${OpenMW_SOURCE_DIR}/readme.txt")
SET(CPACK_RESOURCE_FILE_LICENSE "${OpenMW_SOURCE_DIR}/GPL3.txt") SET(CPACK_RESOURCE_FILE_LICENSE "${OpenMW_SOURCE_DIR}/GPL3.txt")
SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ".") SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
@ -471,6 +479,7 @@ if (APPLE)
install(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" RENAME "openmw.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) install(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" RENAME "openmw.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
install(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) install(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
install(FILES "${OpenMW_BINARY_DIR}/launcher.qss" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
set(CPACK_GENERATOR "DragNDrop") set(CPACK_GENERATOR "DragNDrop")
set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION}) set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION})

View file

@ -225,7 +225,7 @@ void DataFilesPage::setupDataFiles()
msgBox.setIcon(QMessageBox::Warning); msgBox.setIcon(QMessageBox::Warning);
msgBox.setStandardButtons(QMessageBox::Cancel); msgBox.setStandardButtons(QMessageBox::Cancel);
msgBox.setText(tr("<br><b>Could not find the Data Files location</b><br><br> \ msgBox.setText(tr("<br><b>Could not find the Data Files location</b><br><br> \
The directory containing the Data Files was not found.<br><br> \ The directory containing the data files was not found.<br><br> \
Press \"Browse...\" to specify the location manually.<br>")); Press \"Browse...\" to specify the location manually.<br>"));
QAbstractButton *dirSelectButton = QAbstractButton *dirSelectButton =
@ -1057,16 +1057,8 @@ void DataFilesPage::writeConfig(QString profile)
return; return;
} }
// Prepare the OpenMW config // Open the OpenMW config as a QFile
QString config = QString::fromStdString((mCfgMgr.getLocalPath() / "openmw.cfg").string()); QFile file(QString::fromStdString((mCfgMgr.getUserPath() / "openmw.cfg").string()));
QFile file(config);
if (!file.exists()) {
config = QString::fromStdString((mCfgMgr.getUserPath() / "openmw.cfg").string());
}
// Open the config as a QFile
file.setFileName(config);
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) { if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
// File cannot be opened or created // File cannot be opened or created

View file

@ -194,6 +194,7 @@ void MainDialog::play()
QDir dir(QCoreApplication::applicationDirPath()); QDir dir(QCoreApplication::applicationDirPath());
QString game = dir.absoluteFilePath("openmw"); QString game = dir.absoluteFilePath("openmw");
QFile file(game); QFile file(game);
game = "\"" + game + "\"";
#else #else
QString game = "./openmw"; QString game = "./openmw";
QFile file(game); QFile file(game);

View file

@ -89,6 +89,7 @@ public:
virtual void stop(); virtual void stop();
virtual bool isPlaying(); virtual bool isPlaying();
virtual void setVolume(float volume);
virtual void update(const float *pos); virtual void update(const float *pos);
void play(); void play();
@ -254,6 +255,13 @@ bool OpenAL_SoundStream::isPlaying()
return !mIsFinished; return !mIsFinished;
} }
void OpenAL_SoundStream::setVolume(float volume)
{
alSourcef(mSource, AL_GAIN, volume*mBaseVolume);
throwALerror();
mVolume = volume;
}
void OpenAL_SoundStream::update(const float *pos) void OpenAL_SoundStream::update(const float *pos)
{ {
alSource3f(mSource, AL_POSITION, pos[0], pos[2], -pos[1]); alSource3f(mSource, AL_POSITION, pos[0], pos[2], -pos[1]);
@ -331,6 +339,7 @@ public:
virtual void stop(); virtual void stop();
virtual bool isPlaying(); virtual bool isPlaying();
virtual void setVolume(float volume);
virtual void update(const float *pos); virtual void update(const float *pos);
}; };
@ -363,6 +372,13 @@ bool OpenAL_Sound::isPlaying()
return state==AL_PLAYING; return state==AL_PLAYING;
} }
void OpenAL_Sound::setVolume(float volume)
{
alSourcef(mSource, AL_GAIN, volume*mBaseVolume);
throwALerror();
mVolume = volume;
}
void OpenAL_Sound::update(const float *pos) void OpenAL_Sound::update(const float *pos)
{ {
alSource3f(mSource, AL_POSITION, pos[0], pos[2], -pos[1]); alSource3f(mSource, AL_POSITION, pos[0], pos[2], -pos[1]);
@ -417,24 +433,27 @@ void OpenAL_Output::init(const std::string &devname)
alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED); alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
throwALerror(); throwALerror();
ALCint maxmono, maxstereo; ALCint maxmono=0, maxstereo=0;
alcGetIntegerv(mDevice, ALC_MONO_SOURCES, 1, &maxmono); alcGetIntegerv(mDevice, ALC_MONO_SOURCES, 1, &maxmono);
alcGetIntegerv(mDevice, ALC_STEREO_SOURCES, 1, &maxstereo); alcGetIntegerv(mDevice, ALC_STEREO_SOURCES, 1, &maxstereo);
throwALCerror(mDevice); throwALCerror(mDevice);
mFreeSources.resize(std::min(maxmono+maxstereo, 256)); try
for(size_t i = 0;i < mFreeSources.size();i++)
{ {
ALuint src; ALCuint maxtotal = std::min<ALCuint>(maxmono+maxstereo, 256);
alGenSources(1, &src); for(size_t i = 0;i < maxtotal;i++)
if(alGetError() != AL_NO_ERROR)
{ {
mFreeSources.resize(i); ALuint src = 0;
break; alGenSources(1, &src);
throwALerror();
mFreeSources.push_back(src);
} }
mFreeSources[i] = src;
} }
if(mFreeSources.size() == 0) catch(std::exception &e)
{
std::cout <<"Error: "<<e.what()<<", trying to continue"<< std::endl;
}
if(mFreeSources.empty())
fail("Could not allocate any sources"); fail("Could not allocate any sources");
} }
@ -442,10 +461,10 @@ void OpenAL_Output::deinit()
{ {
mStreamThread->removeAll(); mStreamThread->removeAll();
if(!mFreeSources.empty()) while(!mFreeSources.empty())
{ {
alDeleteSources(mFreeSources.size(), mFreeSources.data()); alDeleteSources(1, &mFreeSources.front());
mFreeSources.clear(); mFreeSources.pop_front();
} }
mBufferRefs.clear(); mBufferRefs.clear();
@ -561,17 +580,17 @@ void OpenAL_Output::bufferFinished(ALuint buf)
} }
Sound* OpenAL_Output::playSound(const std::string &fname, float volume, float pitch, bool loop) SoundPtr OpenAL_Output::playSound(const std::string &fname, float volume, float pitch, bool loop)
{ {
throwALerror(); throwALerror();
std::auto_ptr<OpenAL_Sound> sound; boost::shared_ptr<OpenAL_Sound> sound;
ALuint src=0, buf=0; ALuint src=0, buf=0;
if(mFreeSources.empty()) if(mFreeSources.empty())
fail("No free sources"); fail("No free sources");
src = mFreeSources.back(); src = mFreeSources.front();
mFreeSources.pop_back(); mFreeSources.pop_front();
try try
{ {
@ -606,21 +625,21 @@ Sound* OpenAL_Output::playSound(const std::string &fname, float volume, float pi
alSourcePlay(src); alSourcePlay(src);
throwALerror(); throwALerror();
return sound.release(); return sound;
} }
Sound* OpenAL_Output::playSound3D(const std::string &fname, const float *pos, float volume, float pitch, SoundPtr OpenAL_Output::playSound3D(const std::string &fname, const float *pos, float volume, float pitch,
float min, float max, bool loop) float min, float max, bool loop)
{ {
throwALerror(); throwALerror();
std::auto_ptr<OpenAL_Sound> sound; boost::shared_ptr<OpenAL_Sound> sound;
ALuint src=0, buf=0; ALuint src=0, buf=0;
if(mFreeSources.empty()) if(mFreeSources.empty())
fail("No free sources"); fail("No free sources");
src = mFreeSources.back(); src = mFreeSources.front();
mFreeSources.pop_back(); mFreeSources.pop_front();
try try
{ {
@ -655,21 +674,21 @@ Sound* OpenAL_Output::playSound3D(const std::string &fname, const float *pos, fl
alSourcePlay(src); alSourcePlay(src);
throwALerror(); throwALerror();
return sound.release(); return sound;
} }
Sound* OpenAL_Output::streamSound(const std::string &fname, float volume, float pitch) SoundPtr OpenAL_Output::streamSound(const std::string &fname, float volume, float pitch)
{ {
throwALerror(); throwALerror();
std::auto_ptr<OpenAL_SoundStream> sound; boost::shared_ptr<OpenAL_SoundStream> sound;
ALuint src; ALuint src;
if(mFreeSources.empty()) if(mFreeSources.empty())
fail("No free sources"); fail("No free sources");
src = mFreeSources.back(); src = mFreeSources.front();
mFreeSources.pop_back(); mFreeSources.pop_front();
try try
{ {
@ -699,21 +718,21 @@ Sound* OpenAL_Output::streamSound(const std::string &fname, float volume, float
throwALerror(); throwALerror();
sound->play(); sound->play();
return sound.release(); return sound;
} }
Sound* OpenAL_Output::streamSound3D(const std::string &fname, const float *pos, float volume, float pitch, SoundPtr OpenAL_Output::streamSound3D(const std::string &fname, const float *pos, float volume, float pitch,
float min, float max) float min, float max)
{ {
throwALerror(); throwALerror();
std::auto_ptr<OpenAL_SoundStream> sound; boost::shared_ptr<OpenAL_SoundStream> sound;
ALuint src; ALuint src;
if(mFreeSources.empty()) if(mFreeSources.empty())
fail("No free sources"); fail("No free sources");
src = mFreeSources.back(); src = mFreeSources.front();
mFreeSources.pop_back(); mFreeSources.pop_front();
try try
{ {
@ -743,7 +762,7 @@ Sound* OpenAL_Output::streamSound3D(const std::string &fname, const float *pos,
throwALerror(); throwALerror();
sound->play(); sound->play();
return sound.release(); return sound;
} }

View file

@ -21,8 +21,9 @@ namespace MWSound
ALCdevice *mDevice; ALCdevice *mDevice;
ALCcontext *mContext; ALCcontext *mContext;
typedef std::vector<ALuint> IDVec; typedef std::deque<ALuint> IDDq;
IDVec mFreeSources; IDDq mFreeSources;
IDDq mUnusedBuffers;
typedef std::map<std::string,ALuint> NameMap; typedef std::map<std::string,ALuint> NameMap;
NameMap mBufferCache; NameMap mBufferCache;
@ -30,9 +31,6 @@ namespace MWSound
typedef std::map<ALuint,ALuint> IDRefMap; typedef std::map<ALuint,ALuint> IDRefMap;
IDRefMap mBufferRefs; IDRefMap mBufferRefs;
typedef std::deque<ALuint> IDDq;
IDDq mUnusedBuffers;
uint64_t mBufferCacheMemSize; uint64_t mBufferCacheMemSize;
ALuint getBuffer(const std::string &fname); ALuint getBuffer(const std::string &fname);
@ -42,13 +40,13 @@ namespace MWSound
virtual void init(const std::string &devname=""); virtual void init(const std::string &devname="");
virtual void deinit(); virtual void deinit();
virtual Sound *playSound(const std::string &fname, float volume, float pitch, bool loop); virtual SoundPtr playSound(const std::string &fname, float volume, float pitch, bool loop);
virtual Sound *playSound3D(const std::string &fname, const float *pos, float volume, float pitch, virtual SoundPtr playSound3D(const std::string &fname, const float *pos, float volume, float pitch,
float min, float max, bool loop); float min, float max, bool loop);
virtual Sound *streamSound(const std::string &fname, float volume, float pitch); virtual SoundPtr streamSound(const std::string &fname, float volume, float pitch);
virtual Sound *streamSound3D(const std::string &fname, const float *pos, float volume, float pitch, virtual SoundPtr streamSound3D(const std::string &fname, const float *pos, float volume, float pitch,
float min, float max); float min, float max);
virtual void updateListener(const float *pos, const float *atdir, const float *updir); virtual void updateListener(const float *pos, const float *atdir, const float *updir);

View file

@ -5,15 +5,27 @@ namespace MWSound
{ {
class Sound class Sound
{ {
virtual void stop() = 0;
virtual bool isPlaying() = 0;
virtual void update(const float *pos) = 0; virtual void update(const float *pos) = 0;
Sound& operator=(const Sound &rhs); Sound& operator=(const Sound &rhs);
Sound(const Sound &rhs); Sound(const Sound &rhs);
protected:
float mVolume; /* NOTE: Real volume = mVolume*mBaseVolume */
float mBaseVolume;
float mMinDistance;
float mMaxDistance;
public: public:
Sound() { } virtual void stop() = 0;
virtual bool isPlaying() = 0;
virtual void setVolume(float volume) = 0;
Sound() : mVolume(1.0f)
, mBaseVolume(1.0f)
, mMinDistance(20.0f) /* 1 * min_range_scale */
, mMaxDistance(12750.0f) /* 255 * max_range_scale */
{ }
virtual ~Sound() { } virtual ~Sound() { }
friend class OpenAL_Output; friend class OpenAL_Output;

View file

@ -4,6 +4,8 @@
#include <string> #include <string>
#include <memory> #include <memory>
#include "soundmanager.hpp"
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
namespace MWSound namespace MWSound
@ -20,12 +22,12 @@ namespace MWSound
virtual void init(const std::string &devname="") = 0; virtual void init(const std::string &devname="") = 0;
virtual void deinit() = 0; virtual void deinit() = 0;
virtual Sound *playSound(const std::string &fname, float volume, float pitch, bool loop) = 0; virtual SoundPtr playSound(const std::string &fname, float volume, float pitch, bool loop) = 0;
virtual Sound *playSound3D(const std::string &fname, const float *pos, float volume, float pitch, virtual SoundPtr playSound3D(const std::string &fname, const float *pos, float volume, float pitch,
float min, float max, bool loop) = 0; float min, float max, bool loop) = 0;
virtual Sound *streamSound(const std::string &fname, float volume, float pitch) = 0; virtual SoundPtr streamSound(const std::string &fname, float volume, float pitch) = 0;
virtual Sound *streamSound3D(const std::string &fname, const float *pos, float volume, float pitch, virtual SoundPtr streamSound3D(const std::string &fname, const float *pos, float volume, float pitch,
float min, float max) = 0; float min, float max) = 0;
virtual void updateListener(const float *pos, const float *atdir, const float *updir) = 0; virtual void updateListener(const float *pos, const float *atdir, const float *updir) = 0;

View file

@ -69,7 +69,6 @@ namespace MWSound
SoundManager::~SoundManager() SoundManager::~SoundManager()
{ {
mLooseSounds.clear();
mActiveSounds.clear(); mActiveSounds.clear();
mMusic.reset(); mMusic.reset();
mOutput.reset(); mOutput.reset();
@ -115,15 +114,14 @@ namespace MWSound
bool SoundManager::isPlaying(MWWorld::Ptr ptr, const std::string &id) const bool SoundManager::isPlaying(MWWorld::Ptr ptr, const std::string &id) const
{ {
SoundMap::const_iterator snditer = mActiveSounds.find(ptr); SoundMap::const_iterator snditer = mActiveSounds.begin();
if(snditer == mActiveSounds.end()) while(snditer != mActiveSounds.end())
return false; {
if(snditer->second.first == ptr && snditer->second.second == id)
IDMap::const_iterator iditer = snditer->second.find(id); return snditer->first->isPlaying();
if(iditer == snditer->second.end()) snditer++;
return false; }
return false;
return true;
} }
@ -141,7 +139,8 @@ namespace MWSound
{ {
if(mMusic) if(mMusic)
mMusic->stop(); mMusic->stop();
mMusic.reset(mOutput->streamSound(filename, 0.4f, 1.0f)); mMusic = mOutput->streamSound(filename, 0.4f, 1.0f);
mMusic->mBaseVolume = 0.4f;
} }
catch(std::exception &e) catch(std::exception &e)
{ {
@ -182,11 +181,15 @@ namespace MWSound
try try
{ {
// The range values are not tested // The range values are not tested
const ESM::Position &pos = ptr.getCellRef().pos; float basevol = 1.0f; /* TODO: volume settings */
std::string filePath = std::string("Sound/")+filename; std::string filePath = std::string("Sound/")+filename;
const ESM::Position &pos = ptr.getCellRef().pos;
SoundPtr sound(mOutput->playSound3D(filePath, pos.pos, 1.0f, 1.0f, 100.0f, 20000.0f, false)); SoundPtr sound = mOutput->playSound3D(filePath, pos.pos, basevol, 1.0f,
mActiveSounds[ptr]["_say_sound"] = sound; 20.0f, 12750.0f, false);
sound->mBaseVolume = basevol;
mActiveSounds[sound] = std::make_pair(ptr, std::string("_say_sound"));
} }
catch(std::exception &e) catch(std::exception &e)
{ {
@ -200,86 +203,98 @@ namespace MWSound
} }
void SoundManager::playSound(const std::string& soundId, float volume, float pitch, bool loop) SoundPtr SoundManager::playSound(const std::string& soundId, float volume, float pitch, bool loop)
{ {
float min, max; SoundPtr sound;
try try
{ {
std::string file = lookup(soundId, volume, min, max); float basevol = 1.0f; /* TODO: volume settings */
Sound *sound = mOutput->playSound(file, volume, pitch, loop); float min, max;
mLooseSounds[soundId] = SoundPtr(sound); std::string file = lookup(soundId, basevol, min, max);
sound = mOutput->playSound(file, volume*basevol, pitch, loop);
sound->mVolume = volume;
sound->mBaseVolume = basevol;
sound->mMinDistance = min;
sound->mMaxDistance = max;
mActiveSounds[sound] = std::make_pair(MWWorld::Ptr(), soundId);
} }
catch(std::exception &e) catch(std::exception &e)
{ {
std::cout <<"Sound Error: "<<e.what()<< std::endl; std::cout <<"Sound Error: "<<e.what()<< std::endl;
} }
return sound;
} }
void SoundManager::playSound3D(MWWorld::Ptr ptr, const std::string& soundId, SoundPtr SoundManager::playSound3D(MWWorld::Ptr ptr, const std::string& soundId,
float volume, float pitch, bool loop, bool untracked) float volume, float pitch, bool loop,
bool untracked)
{ {
float min, max; SoundPtr sound;
try try
{ {
// Look up the sound in the ESM data // Look up the sound in the ESM data
float basevol = 1.0f; /* TODO: volume settings */
float min, max;
std::string file = lookup(soundId, basevol, min, max);
const ESM::Position &pos = ptr.getCellRef().pos; const ESM::Position &pos = ptr.getCellRef().pos;
std::string file = lookup(soundId, volume, min, max);
SoundPtr sound(mOutput->playSound3D(file, pos.pos, volume, pitch, min, max, loop)); sound = mOutput->playSound3D(file, pos.pos, volume*basevol, pitch, min, max, loop);
if(untracked) mLooseSounds[soundId] = sound; sound->mVolume = volume;
else mActiveSounds[ptr][soundId] = sound; sound->mBaseVolume = basevol;
sound->mMinDistance = min;
sound->mMaxDistance = max;
mActiveSounds[sound] = (!untracked ? std::make_pair(ptr, soundId) :
std::make_pair(MWWorld::Ptr(), soundId));
} }
catch(std::exception &e) catch(std::exception &e)
{ {
std::cout <<"Sound Error: "<<e.what()<< std::endl; std::cout <<"Sound Error: "<<e.what()<< std::endl;
} }
return sound;
} }
void SoundManager::stopSound3D(MWWorld::Ptr ptr, const std::string& soundId) void SoundManager::stopSound3D(MWWorld::Ptr ptr, const std::string& soundId)
{ {
// Stop a sound and remove it from the list. If soundId="" then
// stop all its sounds.
SoundMap::iterator snditer = mActiveSounds.find(ptr);
if(snditer == mActiveSounds.end())
return;
if(!soundId.empty())
{
IDMap::iterator iditer = snditer->second.find(soundId);
if(iditer != snditer->second.end())
{
iditer->second->stop();
snditer->second.erase(iditer);
if(snditer->second.empty())
mActiveSounds.erase(snditer);
}
}
else
{
IDMap::iterator iditer = snditer->second.begin();
while(iditer != snditer->second.end())
{
iditer->second->stop();
iditer++;
}
mActiveSounds.erase(snditer);
}
}
void SoundManager::stopSound(MWWorld::Ptr::CellStore *cell)
{
// Remove all references to objects belonging to a given cell
SoundMap::iterator snditer = mActiveSounds.begin(); SoundMap::iterator snditer = mActiveSounds.begin();
while(snditer != mActiveSounds.end()) while(snditer != mActiveSounds.end())
{ {
if(snditer->first.getCell() == cell) if(snditer->second.first == ptr && snditer->second.second == soundId)
{ {
IDMap::iterator iditer = snditer->second.begin(); snditer->first->stop();
while(iditer != snditer->second.end()) mActiveSounds.erase(snditer++);
{ }
iditer->second->stop(); else
iditer++; snditer++;
} }
}
void SoundManager::stopSound3D(MWWorld::Ptr ptr)
{
SoundMap::iterator snditer = mActiveSounds.begin();
while(snditer != mActiveSounds.end())
{
if(snditer->second.first == ptr)
{
snditer->first->stop();
mActiveSounds.erase(snditer++);
}
else
snditer++;
}
}
void SoundManager::stopSound(const MWWorld::Ptr::CellStore *cell)
{
SoundMap::iterator snditer = mActiveSounds.begin();
while(snditer != mActiveSounds.end())
{
if(snditer->second.first != MWWorld::Ptr() &&
snditer->second.first.getCell() == cell)
{
snditer->first->stop();
mActiveSounds.erase(snditer++); mActiveSounds.erase(snditer++);
} }
else else
@ -289,11 +304,17 @@ namespace MWSound
void SoundManager::stopSound(const std::string& soundId) void SoundManager::stopSound(const std::string& soundId)
{ {
IDMap::iterator iditer = mLooseSounds.find(soundId); SoundMap::iterator snditer = mActiveSounds.begin();
if(iditer != mLooseSounds.end()) while(snditer != mActiveSounds.end())
{ {
iditer->second->stop(); if(snditer->second.first == MWWorld::Ptr() &&
mLooseSounds.erase(iditer); snditer->second.second == soundId)
{
snditer->first->stop();
mActiveSounds.erase(snditer++);
}
else
snditer++;
} }
} }
@ -304,16 +325,13 @@ namespace MWSound
void SoundManager::updateObject(MWWorld::Ptr ptr) void SoundManager::updateObject(MWWorld::Ptr ptr)
{ {
SoundMap::iterator snditer = mActiveSounds.find(ptr);
if(snditer == mActiveSounds.end())
return;
const ESM::Position &pos = ptr.getCellRef().pos; const ESM::Position &pos = ptr.getCellRef().pos;
IDMap::iterator iditer = snditer->second.begin(); SoundMap::iterator snditer = mActiveSounds.begin();
while(iditer != snditer->second.end()) while(snditer != mActiveSounds.end())
{ {
iditer->second->update(pos.pos); if(snditer->second.first == ptr)
iditer++; snditer->first->update(pos.pos);
snditer++;
} }
} }
@ -402,28 +420,11 @@ namespace MWSound
SoundMap::iterator snditer = mActiveSounds.begin(); SoundMap::iterator snditer = mActiveSounds.begin();
while(snditer != mActiveSounds.end()) while(snditer != mActiveSounds.end())
{ {
IDMap::iterator iditer = snditer->second.begin(); if(!snditer->first->isPlaying())
while(iditer != snditer->second.end())
{
if(!iditer->second->isPlaying())
snditer->second.erase(iditer++);
else
iditer++;
}
if(snditer->second.empty())
mActiveSounds.erase(snditer++); mActiveSounds.erase(snditer++);
else else
snditer++; snditer++;
} }
IDMap::iterator iditer = mLooseSounds.begin();
while(iditer != mLooseSounds.end())
{
if(!iditer->second->isPlaying())
mLooseSounds.erase(iditer++);
else
iditer++;
}
} }
void SoundManager::update(float duration) void SoundManager::update(float duration)

View file

@ -2,11 +2,11 @@
#define GAME_SOUND_SOUNDMANAGER_H #define GAME_SOUND_SOUNDMANAGER_H
#include <string> #include <string>
#include <utility>
#include <map>
#include <OgreResourceGroupManager.h> #include <OgreResourceGroupManager.h>
#include <components/files/filelibrary.hpp>
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
@ -28,6 +28,7 @@ namespace MWSound
class Sound; class Sound;
typedef boost::shared_ptr<Sound_Decoder> DecoderPtr; typedef boost::shared_ptr<Sound_Decoder> DecoderPtr;
typedef boost::shared_ptr<Sound> SoundPtr;
class SoundManager class SoundManager
{ {
@ -40,11 +41,9 @@ namespace MWSound
boost::shared_ptr<Sound> mMusic; boost::shared_ptr<Sound> mMusic;
std::string mCurrentPlaylist; std::string mCurrentPlaylist;
typedef boost::shared_ptr<Sound> SoundPtr; typedef std::pair<MWWorld::Ptr,std::string> PtrIDPair;
typedef std::map<std::string,SoundPtr> IDMap; typedef std::map<SoundPtr,PtrIDPair> SoundMap;
typedef std::map<MWWorld::Ptr,IDMap> SoundMap;
SoundMap mActiveSounds; SoundMap mActiveSounds;
IDMap mLooseSounds;
std::string lookup(const std::string &soundId, std::string lookup(const std::string &soundId,
float &volume, float &min, float &max); float &volume, float &min, float &max);
@ -88,19 +87,21 @@ namespace MWSound
bool sayDone(MWWorld::Ptr reference) const; bool sayDone(MWWorld::Ptr reference) const;
///< Is actor not speaking? ///< Is actor not speaking?
void playSound(const std::string& soundId, float volume, float pitch, bool loop=false); SoundPtr playSound(const std::string& soundId, float volume, float pitch, bool loop=false);
///< Play a sound, independently of 3D-position ///< Play a sound, independently of 3D-position
void playSound3D(MWWorld::Ptr reference, const std::string& soundId, SoundPtr playSound3D(MWWorld::Ptr reference, const std::string& soundId,
float volume, float pitch, bool loop, float volume, float pitch, bool loop,
bool untracked=false); bool untracked=false);
///< Play a sound from an object ///< Play a sound from an object
void stopSound3D(MWWorld::Ptr reference, const std::string& soundId=""); void stopSound3D(MWWorld::Ptr reference, const std::string& soundId);
///< Stop the given object from playing the given sound, If no soundId is given, ///< Stop the given object from playing the given sound,
/// all sounds for this reference will stop.
void stopSound(MWWorld::Ptr::CellStore *cell); void stopSound3D(MWWorld::Ptr reference);
///< Stop the given object from playing all sounds.
void stopSound(const MWWorld::Ptr::CellStore *cell);
///< Stop all sounds for the given cell. ///< Stop all sounds for the given cell.
void stopSound(const std::string& soundId); void stopSound(const std::string& soundId);

View file

@ -148,6 +148,7 @@ Bug #207: Ogre.log not written
Bug #209: Sounds do not play Bug #209: Sounds do not play
Bug #210: Ogre crash at Dren plantation Bug #210: Ogre crash at Dren plantation
Bug #214: Unsupported file format version Bug #214: Unsupported file format version
Bug #222: Launcher is writing openmw.cfg file to wrong location
Feature #9: NPC Dialogue Window Feature #9: NPC Dialogue Window
Feature #16/42: New sky/weather implementation Feature #16/42: New sky/weather implementation
Feature #40: Fading Feature #40: Fading