diff --git a/CMakeLists.txt b/CMakeLists.txt
index 204efce9a6..3273cfe0a2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,9 +4,6 @@ if (APPLE)
set(APP_BUNDLE_NAME "${CMAKE_PROJECT_NAME}.app")
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)
# Macros
@@ -163,7 +160,7 @@ endif (APPLE)
# Dependencies
-# Fix for not visible pthreads functions for linker with glibc 2.15
+# Fix for not visible pthreads functions for linker with glibc 2.15
if (UNIX AND NOT APPLE)
find_package (Threads)
endif()
@@ -258,7 +255,16 @@ endif (APPLE)
# Compiler settings
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)
if(DPKG_PROGRAM)
@@ -318,6 +324,7 @@ if(WIN32)
FILE(GLOB files "${OpenMW_BINARY_DIR}/Release/*.*")
INSTALL(FILES ${files} DESTINATION ".")
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 ".")
SET(CPACK_GENERATOR "NSIS")
@@ -328,6 +335,7 @@ if(WIN32)
SET(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINO})
SET(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE})
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_RESOURCE_FILE_LICENSE "${OpenMW_SOURCE_DIR}/GPL3.txt")
SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
@@ -470,6 +478,7 @@ if (APPLE)
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}/launcher.qss" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
set(CPACK_GENERATOR "DragNDrop")
set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION})
diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp
index c96fc2c7b6..c15274e749 100644
--- a/apps/launcher/datafilespage.cpp
+++ b/apps/launcher/datafilespage.cpp
@@ -225,7 +225,7 @@ void DataFilesPage::setupDataFiles()
msgBox.setIcon(QMessageBox::Warning);
msgBox.setStandardButtons(QMessageBox::Cancel);
msgBox.setText(tr("
Could not find the Data Files location
\
- The directory containing the Data Files was not found.
\
+ The directory containing the data files was not found.
\
Press \"Browse...\" to specify the location manually.
"));
QAbstractButton *dirSelectButton =
@@ -1057,16 +1057,8 @@ void DataFilesPage::writeConfig(QString profile)
return;
}
- // Prepare the OpenMW config
- QString config = QString::fromStdString((mCfgMgr.getLocalPath() / "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);
+ // Open the OpenMW config as a QFile
+ QFile file(QString::fromStdString((mCfgMgr.getUserPath() / "openmw.cfg").string()));
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
// File cannot be opened or created
diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp
index ef9cfa8519..8bb618dd66 100644
--- a/apps/launcher/maindialog.cpp
+++ b/apps/launcher/maindialog.cpp
@@ -194,6 +194,7 @@ void MainDialog::play()
QDir dir(QCoreApplication::applicationDirPath());
QString game = dir.absoluteFilePath("openmw");
QFile file(game);
+ game = "\"" + game + "\"";
#else
QString game = "./openmw";
QFile file(game);
diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt
index 2e9191e810..6dc9382d03 100644
--- a/apps/openmw/CMakeLists.txt
+++ b/apps/openmw/CMakeLists.txt
@@ -89,7 +89,7 @@ target_link_libraries(openmw
${SOUND_INPUT_LIBRARY}
${BULLET_LIBRARIES}
${MYGUI_LIBRARIES}
- MyGUI.OgrePlatform #TODO MyGUI ogre platform is not added by the find script
+ ${MYGUI_PLATFORM_LIBRARIES}
components
)
diff --git a/apps/openmw/mwgui/layouts.cpp b/apps/openmw/mwgui/layouts.cpp
index 9c49c62ac3..dbd6154b7c 100644
--- a/apps/openmw/mwgui/layouts.cpp
+++ b/apps/openmw/mwgui/layouts.cpp
@@ -15,6 +15,22 @@ using namespace MWGui;
HUD::HUD(int width, int height, int fpsLevel)
: Layout("openmw_hud_layout.xml")
+ , health(NULL)
+ , magicka(NULL)
+ , stamina(NULL)
+ , weapImage(NULL)
+ , spellImage(NULL)
+ , weapStatus(NULL)
+ , spellStatus(NULL)
+ , effectBox(NULL)
+ , effect1(NULL)
+ , minimap(NULL)
+ , compass(NULL)
+ , crosshair(NULL)
+ , fpsbox(NULL)
+ , fpscounter(NULL)
+ , trianglecounter(NULL)
+ , batchcounter(NULL)
{
setCoord(0,0, width, height);
diff --git a/apps/openmw/mwgui/messagebox.hpp b/apps/openmw/mwgui/messagebox.hpp
index bf3307accf..33155b2a00 100644
--- a/apps/openmw/mwgui/messagebox.hpp
+++ b/apps/openmw/mwgui/messagebox.hpp
@@ -7,6 +7,7 @@
#include "window_base.hpp"
#include "window_manager.hpp"
+#undef MessageBox
namespace MWGui
{
diff --git a/apps/openmw/mwgui/stats_window.cpp b/apps/openmw/mwgui/stats_window.cpp
index 243b6272a5..12b0dcc793 100644
--- a/apps/openmw/mwgui/stats_window.cpp
+++ b/apps/openmw/mwgui/stats_window.cpp
@@ -13,9 +13,22 @@ const int StatsWindow::lineHeight = 18;
StatsWindow::StatsWindow (WindowManager& parWindowManager)
: WindowBase("openmw_stats_window_layout.xml", parWindowManager)
+ , skillAreaWidget(NULL)
+ , skillClientWidget(NULL)
+ , skillScrollerWidget(NULL)
, lastPos(0)
+ , clientHeight(0)
+ , majorSkills()
+ , minorSkills()
+ , miscSkills()
+ , skillValues()
+ , skillWidgetMap()
+ , factionWidgetMap()
+ , factions()
+ , birthSignId()
, reputation(0)
, bounty(0)
+ , skillWidgets()
{
setCoord(0,0,498, 342);
diff --git a/apps/openmw/mwgui/widgets.hpp b/apps/openmw/mwgui/widgets.hpp
index 4d31ad5219..a7916285eb 100644
--- a/apps/openmw/mwgui/widgets.hpp
+++ b/apps/openmw/mwgui/widgets.hpp
@@ -7,6 +7,9 @@
#include "../mwmechanics/stat.hpp"
+#undef MYGUI_EXPORT
+#define MYGUI_EXPORT
+
/*
This file contains various custom widgets used in OpenMW.
*/
diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp
index fa6dedc77e..a04e2dcb8b 100644
--- a/apps/openmw/mwgui/window_manager.cpp
+++ b/apps/openmw/mwgui/window_manager.cpp
@@ -22,15 +22,40 @@ using namespace MWGui;
WindowManager::WindowManager(MWWorld::Environment& environment,
const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string logpath)
- : environment(environment)
+ : mGuiManager(NULL)
+ , environment(environment)
+ , hud(NULL)
+ , map(NULL)
+ , menu(NULL)
+ , stats(NULL)
+ , mMessageBoxManager(NULL)
+ , console(NULL)
+ , mJournal(NULL)
, dialogueWindow(nullptr)
+ , mCharGen(NULL)
+ , playerClass()
+ , playerName()
+ , playerRaceId()
+ , playerBirthSignId()
+ , playerAttributes()
+ , playerMajorSkills()
+ , playerMinorSkills()
+ , playerSkillValues()
+ , playerHealth()
+ , playerMagicka()
+ , playerFatigue()
+ , gui(NULL)
, mode(GM_Game)
, nextMode(GM_Game)
, needModeChange(false)
+ , garbageDialogs()
, shown(GW_ALL)
, allowed(newGame ? GW_None : GW_ALL)
+ , showFPSLevel(fpsLevel)
+ , mFPS(0.0f)
+ , mTriangleCount(0)
+ , mBatchCount(0)
{
- showFPSLevel = fpsLevel;
// Set up the GUI system
mGuiManager = new OEngine::GUI::MyGUIManager(mOgre->getWindow(), mOgre->getScene(), false, logpath);
diff --git a/apps/openmw/mwrender/actors.cpp b/apps/openmw/mwrender/actors.cpp
index d8ca78e3a5..6eb4a182bd 100644
--- a/apps/openmw/mwrender/actors.cpp
+++ b/apps/openmw/mwrender/actors.cpp
@@ -8,6 +8,15 @@ using namespace Ogre;
using namespace MWRender;
using namespace NifOgre;
+Actors::~Actors(){
+
+ std::map::iterator it = mAllActors.begin();
+ for (; it != mAllActors.end(); ++it) {
+ delete it->second;
+ it->second = NULL;
+ }
+}
+
void Actors::setMwRoot(Ogre::SceneNode* root){
mMwRoot = root;
}
@@ -61,6 +70,7 @@ void Actors::insertCreature (const MWWorld::Ptr& ptr){
insertBegin(ptr, true, true);
CreatureAnimation* anim = new MWRender::CreatureAnimation(ptr, mEnvironment, mRend);
//mAllActors.insert(std::pair(ptr,anim));
+ delete mAllActors[ptr];
mAllActors[ptr] = anim;
//mAllActors.push_back(&anim);*/
}
diff --git a/apps/openmw/mwrender/actors.hpp b/apps/openmw/mwrender/actors.hpp
index 7179c08fb4..d49c6e0f8d 100644
--- a/apps/openmw/mwrender/actors.hpp
+++ b/apps/openmw/mwrender/actors.hpp
@@ -30,7 +30,7 @@ namespace MWRender{
public:
Actors(OEngine::Render::OgreRenderer& _rend, MWWorld::Environment& _env): mRend(_rend), mEnvironment(_env){}
- ~Actors(){}
+ ~Actors();
void setMwRoot(Ogre::SceneNode* root);
void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_);
void insertCreature (const MWWorld::Ptr& ptr);
diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp
index 7b0d7015c0..f3a8f64d55 100644
--- a/apps/openmw/mwrender/animation.cpp
+++ b/apps/openmw/mwrender/animation.cpp
@@ -4,7 +4,30 @@
namespace MWRender{
std::map Animation::mUniqueIDs;
- Animation::~Animation(){
+ Animation::Animation(MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend)
+ : insert(NULL)
+ , mRend(_rend)
+ , mEnvironment(_env)
+ , vecRotPos()
+ , shapeparts()
+ , time(0.0f)
+ , startTime(0.0f)
+ , stopTime(0.0f)
+ , animate(0)
+ , rindexI()
+ , tindexI()
+ , shapeNumber(0)
+ , shapeIndexI()
+ , shapes(NULL)
+ , entityparts()
+ , transformations(NULL)
+ , textmappings(NULL)
+ , base(NULL)
+ {
+ }
+
+ Animation::~Animation()
+ {
}
std::string Animation::getUniqueID(std::string mesh){
diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp
index d1e8071f06..7692c71283 100644
--- a/apps/openmw/mwrender/animation.hpp
+++ b/apps/openmw/mwrender/animation.hpp
@@ -60,14 +60,14 @@ class Animation{
std::string getUniqueID(std::string mesh);
public:
- Animation(MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend): mRend(_rend), mEnvironment(_env), animate(0){};
- virtual void runAnimation(float timepassed) = 0;
- void startScript(std::string groupname, int mode, int loops);
- void stopScript();
-
-
- virtual ~Animation();
+ Animation(MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend);
+ virtual void runAnimation(float timepassed) = 0;
+ void startScript(std::string groupname, int mode, int loops);
+ void stopScript();
+
+
+ virtual ~Animation();
};
}
-#endif
\ No newline at end of file
+#endif
diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp
index b83a982204..ed218dc97d 100644
--- a/apps/openmw/mwrender/localmap.cpp
+++ b/apps/openmw/mwrender/localmap.cpp
@@ -29,11 +29,6 @@ LocalMap::~LocalMap()
void LocalMap::deleteBuffers()
{
- for (std::map::iterator it=mBuffers.begin();
- it != mBuffers.end(); ++it)
- {
- delete it->second;
- }
mBuffers.clear();
}
@@ -202,16 +197,16 @@ void LocalMap::render(const float x, const float y,
TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
// create a buffer to use for dynamic operations
- uint32* buffer = new uint32[sFogOfWarResolution*sFogOfWarResolution];
+ std::vector buffer;
+ buffer.resize(sFogOfWarResolution*sFogOfWarResolution);
// initialize to (0, 0, 0, 1)
- uint32* pointer = buffer;
for (int p=0; pgetBuffer()->lock(HardwareBuffer::HBL_DISCARD), buffer, sFogOfWarResolution*sFogOfWarResolution*4);
+ memcpy(tex2->getBuffer()->lock(HardwareBuffer::HBL_DISCARD), &buffer[0], sFogOfWarResolution*sFogOfWarResolution*4);
tex2->getBuffer()->unlock();
mBuffers[texture] = buffer;
@@ -288,25 +283,23 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3&
{
// get its buffer
if (mBuffers.find(texName) == mBuffers.end()) return;
- uint32* buffer = mBuffers[texName];
- uint32* pointer = buffer;
+ int i=0;
for (int texV = 0; texV> 24);
alpha = std::min( alpha, (uint8) (std::max(0.f, std::min(1.f, (sqrDist/sqrExploreRadius)))*255) );
- *((uint32*)pointer) = (alpha << 24);
+ mBuffers[texName][i] = (uint32) (alpha << 24);
- // move to next texel
- ++pointer;
+ ++i;
}
}
// copy to the texture
- memcpy(tex->getBuffer()->lock(HardwareBuffer::HBL_DISCARD), buffer, sFogOfWarResolution*sFogOfWarResolution*4);
+ memcpy(tex->getBuffer()->lock(HardwareBuffer::HBL_DISCARD), &mBuffers[texName][0], sFogOfWarResolution*sFogOfWarResolution*4);
tex->getBuffer()->unlock();
}
}
diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp
index 3bef475ea9..efbccf8848 100644
--- a/apps/openmw/mwrender/localmap.hpp
+++ b/apps/openmw/mwrender/localmap.hpp
@@ -86,7 +86,7 @@ namespace MWRender
// a buffer for the "fog of war" texture of the current cell.
// interior cells could be divided into multiple textures,
// so we store in a map.
- std::map mBuffers;
+ std::map > mBuffers;
void deleteBuffers();
diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp
index 5e85780022..a41bc21e0f 100644
--- a/apps/openmw/mwrender/sky.cpp
+++ b/apps/openmw/mwrender/sky.cpp
@@ -254,7 +254,7 @@ void SkyManager::ModVertexAlpha(Entity* ent, unsigned int meshType)
// Get a pointer to the vertex colour
ves_diffuse->baseVertexPointerToElement( pData, ¤tVertex );
- unsigned char alpha;
+ unsigned char alpha=0;
if (meshType == 0) alpha = i%2 ? 0 : 255; // this is a cylinder, so every second vertex belongs to the bottom-most row
else if (meshType == 1)
{
@@ -292,10 +292,40 @@ void SkyManager::ModVertexAlpha(Entity* ent, unsigned int meshType)
ent->getMesh()->getSubMesh(0)->vertexData->vertexBufferBinding->getBuffer(ves_diffuse->getSource())->unlock();
}
-SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera, MWWorld::Environment* env) :
- mGlareFade(0), mGlareEnabled(false)
+SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera, MWWorld::Environment* env)
+ : mEnvironment(env)
+ , mHour(0.0f)
+ , mDay(0)
+ , mMonth(0)
+ , mSun(NULL)
+ , mSunGlare(NULL)
+ , mMasser(NULL)
+ , mSecunda(NULL)
+ , mViewport(NULL)
+ , mRootNode(NULL)
+ , mSceneMgr(NULL)
+ , mAtmosphereDay(NULL)
+ , mAtmosphereNight(NULL)
+ , mCloudMaterial()
+ , mAtmosphereMaterial()
+ , mCloudFragmentShader()
+ , mClouds()
+ , mNextClouds()
+ , mCloudBlendFactor(0.0f)
+ , mCloudOpacity(0.0f)
+ , mCloudSpeed(0.0f)
+ , mStarsOpacity(0.0f)
+ , mThunderOverlay(NULL)
+ , mThunderTextureUnit(NULL)
+ , mRemainingTransitionTime(0.0f)
+ , mGlareFade(0.0f)
+ , mEnabled(true)
+ , mGlareEnabled(true)
+ , mSunEnabled(true)
+ , mMasserEnabled(true)
+ , mSecundaEnabled(true)
{
- mEnvironment = env;
+
mViewport = pCamera->getViewport();
mSceneMgr = pMwRoot->getCreator();
mRootNode = pCamera->getParentSceneNode()->createChildSceneNode();
diff --git a/apps/openmw/mwsound/mpgsnd_decoder.cpp b/apps/openmw/mwsound/mpgsnd_decoder.cpp
index f576833a82..9b91b4e74e 100644
--- a/apps/openmw/mwsound/mpgsnd_decoder.cpp
+++ b/apps/openmw/mwsound/mpgsnd_decoder.cpp
@@ -213,7 +213,13 @@ void MpgSnd_Decoder::rewind()
}
}
-MpgSnd_Decoder::MpgSnd_Decoder() : mSndFile(NULL), mMpgFile(NULL)
+MpgSnd_Decoder::MpgSnd_Decoder()
+ : mSndInfo()
+ , mSndFile(NULL)
+ , mMpgFile(NULL)
+ , mDataStream()
+ , mChanConfig(ChannelConfig_Stereo)
+ , mSampleRate(0)
{
static bool initdone = false;
if(!initdone)
diff --git a/apps/openmw/mwsound/openal_output.cpp b/apps/openmw/mwsound/openal_output.cpp
index c069474034..5122b3a5a5 100644
--- a/apps/openmw/mwsound/openal_output.cpp
+++ b/apps/openmw/mwsound/openal_output.cpp
@@ -65,7 +65,7 @@ static ALenum getALFormat(ChannelConfig chans, SampleType type)
class OpenAL_SoundStream : public Sound
{
static const ALuint sNumBuffers = 6;
- static const ALfloat sBufferLength = 0.125f;
+ static const ALfloat sBufferLength;
OpenAL_Output &mOutput;
@@ -89,12 +89,15 @@ public:
virtual void stop();
virtual bool isPlaying();
+ virtual void setVolume(float volume);
virtual void update(const float *pos);
void play();
bool process();
};
+const ALfloat OpenAL_SoundStream::sBufferLength = 0.125f;
+
//
// A background streaming thread (keeps active streams processed)
//
@@ -252,6 +255,13 @@ bool OpenAL_SoundStream::isPlaying()
return !mIsFinished;
}
+void OpenAL_SoundStream::setVolume(float volume)
+{
+ alSourcef(mSource, AL_GAIN, volume*mBaseVolume);
+ throwALerror();
+ mVolume = volume;
+}
+
void OpenAL_SoundStream::update(const float *pos)
{
alSource3f(mSource, AL_POSITION, pos[0], pos[2], -pos[1]);
@@ -329,6 +339,7 @@ public:
virtual void stop();
virtual bool isPlaying();
+ virtual void setVolume(float volume);
virtual void update(const float *pos);
};
@@ -361,6 +372,13 @@ bool OpenAL_Sound::isPlaying()
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)
{
alSource3f(mSource, AL_POSITION, pos[0], pos[2], -pos[1]);
@@ -415,24 +433,27 @@ void OpenAL_Output::init(const std::string &devname)
alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
throwALerror();
- ALCint maxmono, maxstereo;
+ ALCint maxmono=0, maxstereo=0;
alcGetIntegerv(mDevice, ALC_MONO_SOURCES, 1, &maxmono);
alcGetIntegerv(mDevice, ALC_STEREO_SOURCES, 1, &maxstereo);
throwALCerror(mDevice);
- mFreeSources.resize(std::min(maxmono+maxstereo, 256));
- for(size_t i = 0;i < mFreeSources.size();i++)
+ try
{
- ALuint src;
- alGenSources(1, &src);
- if(alGetError() != AL_NO_ERROR)
+ ALCuint maxtotal = std::min(maxmono+maxstereo, 256);
+ for(size_t i = 0;i < maxtotal;i++)
{
- mFreeSources.resize(i);
- break;
+ ALuint src = 0;
+ alGenSources(1, &src);
+ throwALerror();
+ mFreeSources.push_back(src);
}
- mFreeSources[i] = src;
}
- if(mFreeSources.size() == 0)
+ catch(std::exception &e)
+ {
+ std::cout <<"Error: "<removeAll();
- if(!mFreeSources.empty())
+ while(!mFreeSources.empty())
{
- alDeleteSources(mFreeSources.size(), mFreeSources.data());
- mFreeSources.clear();
+ alDeleteSources(1, &mFreeSources.front());
+ mFreeSources.pop_front();
}
mBufferRefs.clear();
@@ -559,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();
- std::auto_ptr sound;
+ boost::shared_ptr sound;
ALuint src=0, buf=0;
if(mFreeSources.empty())
fail("No free sources");
- src = mFreeSources.back();
- mFreeSources.pop_back();
+ src = mFreeSources.front();
+ mFreeSources.pop_front();
try
{
@@ -604,21 +625,21 @@ Sound* OpenAL_Output::playSound(const std::string &fname, float volume, float pi
alSourcePlay(src);
throwALerror();
- return sound.release();
+ return sound;
}
-Sound* OpenAL_Output::playSound3D(const std::string &fname, const float *pos, float volume, float pitch,
- float min, float max, bool loop)
+SoundPtr OpenAL_Output::playSound3D(const std::string &fname, const float *pos, float volume, float pitch,
+ float min, float max, bool loop)
{
throwALerror();
- std::auto_ptr sound;
+ boost::shared_ptr sound;
ALuint src=0, buf=0;
if(mFreeSources.empty())
fail("No free sources");
- src = mFreeSources.back();
- mFreeSources.pop_back();
+ src = mFreeSources.front();
+ mFreeSources.pop_front();
try
{
@@ -653,21 +674,21 @@ Sound* OpenAL_Output::playSound3D(const std::string &fname, const float *pos, fl
alSourcePlay(src);
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();
- std::auto_ptr sound;
+ boost::shared_ptr sound;
ALuint src;
if(mFreeSources.empty())
fail("No free sources");
- src = mFreeSources.back();
- mFreeSources.pop_back();
+ src = mFreeSources.front();
+ mFreeSources.pop_front();
try
{
@@ -697,21 +718,21 @@ Sound* OpenAL_Output::streamSound(const std::string &fname, float volume, float
throwALerror();
sound->play();
- return sound.release();
+ return sound;
}
-Sound* OpenAL_Output::streamSound3D(const std::string &fname, const float *pos, float volume, float pitch,
- float min, float max)
+SoundPtr OpenAL_Output::streamSound3D(const std::string &fname, const float *pos, float volume, float pitch,
+ float min, float max)
{
throwALerror();
- std::auto_ptr sound;
+ boost::shared_ptr sound;
ALuint src;
if(mFreeSources.empty())
fail("No free sources");
- src = mFreeSources.back();
- mFreeSources.pop_back();
+ src = mFreeSources.front();
+ mFreeSources.pop_front();
try
{
@@ -741,7 +762,7 @@ Sound* OpenAL_Output::streamSound3D(const std::string &fname, const float *pos,
throwALerror();
sound->play();
- return sound.release();
+ return sound;
}
diff --git a/apps/openmw/mwsound/openal_output.hpp b/apps/openmw/mwsound/openal_output.hpp
index e8154e9063..d288a62f39 100644
--- a/apps/openmw/mwsound/openal_output.hpp
+++ b/apps/openmw/mwsound/openal_output.hpp
@@ -21,8 +21,9 @@ namespace MWSound
ALCdevice *mDevice;
ALCcontext *mContext;
- typedef std::vector IDVec;
- IDVec mFreeSources;
+ typedef std::deque IDDq;
+ IDDq mFreeSources;
+ IDDq mUnusedBuffers;
typedef std::map NameMap;
NameMap mBufferCache;
@@ -30,9 +31,6 @@ namespace MWSound
typedef std::map IDRefMap;
IDRefMap mBufferRefs;
- typedef std::deque IDDq;
- IDDq mUnusedBuffers;
-
uint64_t mBufferCacheMemSize;
ALuint getBuffer(const std::string &fname);
@@ -42,13 +40,13 @@ namespace MWSound
virtual void init(const std::string &devname="");
virtual void deinit();
- virtual Sound *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,
- float min, float max, bool loop);
+ virtual SoundPtr playSound(const std::string &fname, float volume, float pitch, bool loop);
+ virtual SoundPtr playSound3D(const std::string &fname, const float *pos, float volume, float pitch,
+ float min, float max, bool loop);
- virtual Sound *streamSound(const std::string &fname, float volume, float pitch);
- virtual Sound *streamSound3D(const std::string &fname, const float *pos, float volume, float pitch,
- float min, float max);
+ virtual SoundPtr streamSound(const std::string &fname, float volume, float pitch);
+ virtual SoundPtr streamSound3D(const std::string &fname, const float *pos, float volume, float pitch,
+ float min, float max);
virtual void updateListener(const float *pos, const float *atdir, const float *updir);
diff --git a/apps/openmw/mwsound/sound.hpp b/apps/openmw/mwsound/sound.hpp
index f9e7ab4278..2cbd48d961 100644
--- a/apps/openmw/mwsound/sound.hpp
+++ b/apps/openmw/mwsound/sound.hpp
@@ -5,15 +5,27 @@ namespace MWSound
{
class Sound
{
- virtual void stop() = 0;
- virtual bool isPlaying() = 0;
virtual void update(const float *pos) = 0;
Sound& operator=(const Sound &rhs);
Sound(const Sound &rhs);
+ protected:
+ float mVolume; /* NOTE: Real volume = mVolume*mBaseVolume */
+ float mBaseVolume;
+ float mMinDistance;
+ float mMaxDistance;
+
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() { }
friend class OpenAL_Output;
diff --git a/apps/openmw/mwsound/sound_output.hpp b/apps/openmw/mwsound/sound_output.hpp
index 1722165e49..794383591b 100644
--- a/apps/openmw/mwsound/sound_output.hpp
+++ b/apps/openmw/mwsound/sound_output.hpp
@@ -4,6 +4,8 @@
#include
#include
+#include "soundmanager.hpp"
+
#include "../mwworld/ptr.hpp"
namespace MWSound
@@ -20,12 +22,12 @@ namespace MWSound
virtual void init(const std::string &devname="") = 0;
virtual void deinit() = 0;
- virtual Sound *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,
- float min, float max, bool loop) = 0;
- virtual Sound *streamSound(const std::string &fname, float volume, float pitch) = 0;
- virtual Sound *streamSound3D(const std::string &fname, const float *pos, float volume, float pitch,
- float min, float max) = 0;
+ virtual SoundPtr playSound(const std::string &fname, float volume, float pitch, bool loop) = 0;
+ virtual SoundPtr playSound3D(const std::string &fname, const float *pos, float volume, float pitch,
+ float min, float max, bool loop) = 0;
+ virtual SoundPtr streamSound(const std::string &fname, float volume, float pitch) = 0;
+ virtual SoundPtr streamSound3D(const std::string &fname, const float *pos, float volume, float pitch,
+ float min, float max) = 0;
virtual void updateListener(const float *pos, const float *atdir, const float *updir) = 0;
diff --git a/apps/openmw/mwsound/soundmanager.cpp b/apps/openmw/mwsound/soundmanager.cpp
index f626ec1584..ad9e47f729 100644
--- a/apps/openmw/mwsound/soundmanager.cpp
+++ b/apps/openmw/mwsound/soundmanager.cpp
@@ -69,7 +69,6 @@ namespace MWSound
SoundManager::~SoundManager()
{
- mLooseSounds.clear();
mActiveSounds.clear();
mMusic.reset();
mOutput.reset();
@@ -115,15 +114,14 @@ namespace MWSound
bool SoundManager::isPlaying(MWWorld::Ptr ptr, const std::string &id) const
{
- SoundMap::const_iterator snditer = mActiveSounds.find(ptr);
- if(snditer == mActiveSounds.end())
- return false;
-
- IDMap::const_iterator iditer = snditer->second.find(id);
- if(iditer == snditer->second.end())
- return false;
-
- return true;
+ SoundMap::const_iterator snditer = mActiveSounds.begin();
+ while(snditer != mActiveSounds.end())
+ {
+ if(snditer->second.first == ptr && snditer->second.second == id)
+ return snditer->first->isPlaying();
+ snditer++;
+ }
+ return false;
}
@@ -141,7 +139,8 @@ namespace MWSound
{
if(mMusic)
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)
{
@@ -182,11 +181,15 @@ namespace MWSound
try
{
// 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;
+ const ESM::Position &pos = ptr.getCellRef().pos;
- SoundPtr sound(mOutput->playSound3D(filePath, pos.pos, 1.0f, 1.0f, 100.0f, 20000.0f, false));
- mActiveSounds[ptr]["_say_sound"] = sound;
+ SoundPtr sound = mOutput->playSound3D(filePath, pos.pos, basevol, 1.0f,
+ 20.0f, 12750.0f, false);
+ sound->mBaseVolume = basevol;
+
+ mActiveSounds[sound] = std::make_pair(ptr, std::string("_say_sound"));
}
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
{
- std::string file = lookup(soundId, volume, min, max);
- Sound *sound = mOutput->playSound(file, volume, pitch, loop);
- mLooseSounds[soundId] = SoundPtr(sound);
+ float basevol = 1.0f; /* TODO: volume settings */
+ float min, max;
+ 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)
{
std::cout <<"Sound Error: "<playSound3D(file, pos.pos, volume, pitch, min, max, loop));
- if(untracked) mLooseSounds[soundId] = sound;
- else mActiveSounds[ptr][soundId] = sound;
+ sound = mOutput->playSound3D(file, pos.pos, volume*basevol, pitch, min, max, loop);
+ sound->mVolume = volume;
+ 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)
{
std::cout <<"Sound Error: "<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();
while(snditer != mActiveSounds.end())
{
- if(snditer->first.getCell() == cell)
+ if(snditer->second.first == ptr && snditer->second.second == soundId)
{
- IDMap::iterator iditer = snditer->second.begin();
- while(iditer != snditer->second.end())
- {
- iditer->second->stop();
- iditer++;
- }
+ snditer->first->stop();
+ mActiveSounds.erase(snditer++);
+ }
+ else
+ 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++);
}
else
@@ -289,11 +304,17 @@ namespace MWSound
void SoundManager::stopSound(const std::string& soundId)
{
- IDMap::iterator iditer = mLooseSounds.find(soundId);
- if(iditer != mLooseSounds.end())
+ SoundMap::iterator snditer = mActiveSounds.begin();
+ while(snditer != mActiveSounds.end())
{
- iditer->second->stop();
- mLooseSounds.erase(iditer);
+ if(snditer->second.first == MWWorld::Ptr() &&
+ snditer->second.second == soundId)
+ {
+ snditer->first->stop();
+ mActiveSounds.erase(snditer++);
+ }
+ else
+ snditer++;
}
}
@@ -304,16 +325,13 @@ namespace MWSound
void SoundManager::updateObject(MWWorld::Ptr ptr)
{
- SoundMap::iterator snditer = mActiveSounds.find(ptr);
- if(snditer == mActiveSounds.end())
- return;
-
const ESM::Position &pos = ptr.getCellRef().pos;
- IDMap::iterator iditer = snditer->second.begin();
- while(iditer != snditer->second.end())
+ SoundMap::iterator snditer = mActiveSounds.begin();
+ while(snditer != mActiveSounds.end())
{
- iditer->second->update(pos.pos);
- iditer++;
+ if(snditer->second.first == ptr)
+ snditer->first->update(pos.pos);
+ snditer++;
}
}
@@ -402,28 +420,11 @@ namespace MWSound
SoundMap::iterator snditer = mActiveSounds.begin();
while(snditer != mActiveSounds.end())
{
- IDMap::iterator iditer = snditer->second.begin();
- while(iditer != snditer->second.end())
- {
- if(!iditer->second->isPlaying())
- snditer->second.erase(iditer++);
- else
- iditer++;
- }
- if(snditer->second.empty())
+ if(!snditer->first->isPlaying())
mActiveSounds.erase(snditer++);
else
snditer++;
}
-
- IDMap::iterator iditer = mLooseSounds.begin();
- while(iditer != mLooseSounds.end())
- {
- if(!iditer->second->isPlaying())
- mLooseSounds.erase(iditer++);
- else
- iditer++;
- }
}
void SoundManager::update(float duration)
diff --git a/apps/openmw/mwsound/soundmanager.hpp b/apps/openmw/mwsound/soundmanager.hpp
index b7c883a130..3ab1e881c3 100644
--- a/apps/openmw/mwsound/soundmanager.hpp
+++ b/apps/openmw/mwsound/soundmanager.hpp
@@ -2,11 +2,11 @@
#define GAME_SOUND_SOUNDMANAGER_H
#include
+#include
+#include