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 #include -#include - #include "../mwworld/ptr.hpp" @@ -24,10 +24,11 @@ namespace MWWorld namespace MWSound { class Sound_Output; - class Sound_Decoder; + struct Sound_Decoder; class Sound; typedef boost::shared_ptr DecoderPtr; + typedef boost::shared_ptr SoundPtr; class SoundManager { @@ -40,11 +41,9 @@ namespace MWSound boost::shared_ptr mMusic; std::string mCurrentPlaylist; - typedef boost::shared_ptr SoundPtr; - typedef std::map IDMap; - typedef std::map SoundMap; + typedef std::pair PtrIDPair; + typedef std::map SoundMap; SoundMap mActiveSounds; - IDMap mLooseSounds; std::string lookup(const std::string &soundId, float &volume, float &min, float &max); @@ -88,19 +87,21 @@ namespace MWSound bool sayDone(MWWorld::Ptr reference) const; ///< 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 - void playSound3D(MWWorld::Ptr reference, const std::string& soundId, - float volume, float pitch, bool loop, - bool untracked=false); + SoundPtr playSound3D(MWWorld::Ptr reference, const std::string& soundId, + float volume, float pitch, bool loop, + bool untracked=false); ///< Play a sound from an object - void stopSound3D(MWWorld::Ptr reference, const std::string& soundId=""); - ///< Stop the given object from playing the given sound, If no soundId is given, - /// all sounds for this reference will stop. + void stopSound3D(MWWorld::Ptr reference, const std::string& soundId); + ///< Stop the given object from playing the given sound, - 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. void stopSound(const std::string& soundId); diff --git a/cmake/FindFFMPEG.cmake b/cmake/FindFFMPEG.cmake index ff6d0c598d..2e755d047d 100644 --- a/cmake/FindFFMPEG.cmake +++ b/cmake/FindFFMPEG.cmake @@ -9,9 +9,23 @@ SET( FFMPEG_FOUND "NO" ) +FIND_PATH( FFMPEG_general_INCLUDE_DIR libavcodec/avcodec.h libavformat/avformat.h + HINTS + PATHS + /usr/include + /usr/local/include + /usr/include/ffmpeg + /usr/local/include/ffmpeg + /usr/include/ffmpeg/libavcodec + /usr/local/include/ffmpeg/libavcodec + /usr/include/libavcodec + /usr/local/include/libavcodec + ) + FIND_PATH( FFMPEG_avcodec_INCLUDE_DIR avcodec.h HINTS PATHS + ${FFMPEG_general_INCLUDE_DIR}/libavcodec /usr/include /usr/local/include /usr/include/ffmpeg @@ -25,6 +39,7 @@ FIND_PATH( FFMPEG_avcodec_INCLUDE_DIR avcodec.h FIND_PATH( FFMPEG_avformat_INCLUDE_DIR avformat.h HINTS PATHS + ${FFMPEG_general_INCLUDE_DIR}/libavformat /usr/include /usr/local/include /usr/include/ffmpeg @@ -35,7 +50,7 @@ FIND_PATH( FFMPEG_avformat_INCLUDE_DIR avformat.h /usr/local/include/libavformat ) -set(FFMPEG_INCLUDE_DIR ${FFMPEG_avcodec_INCLUDE_DIR} ${FFMPEG_avformat_INCLUDE_DIR}) +set(FFMPEG_INCLUDE_DIR ${FFMPEG_general_INCLUDE_DIR} ${FFMPEG_avcodec_INCLUDE_DIR} ${FFMPEG_avformat_INCLUDE_DIR}) IF( FFMPEG_INCLUDE_DIR ) diff --git a/cmake/FindMyGUI.cmake b/cmake/FindMyGUI.cmake index 339f494ddb..cc97992084 100644 --- a/cmake/FindMyGUI.cmake +++ b/cmake/FindMyGUI.cmake @@ -19,57 +19,57 @@ include(FindPkgMacros) IF (WIN32) #Windows MESSAGE(STATUS "Looking for MyGUI") - SET(MYGUISDK $ENV{MYGUI_HOME}) +SET(MYGUISDK $ENV{MYGUI_HOME}) IF (MYGUISDK) - findpkg_begin ( "MYGUI" ) +findpkg_begin ( "MYGUI" ) MESSAGE(STATUS "Using MyGUI in OGRE SDK") - STRING(REGEX REPLACE "[\\]" "/" MYGUISDK "${MYGUISDK}" ) +STRING(REGEX REPLACE "[\\]" "/" MYGUISDK "${MYGUISDK}" ) - find_path ( MYGUI_INCLUDE_DIRS - MyGUI.h - "${MYGUISDK}/MyGUIEngine/include" - NO_DEFAULT_PATH ) - - find_path ( MYGUI_PLATFORM_INCLUDE_DIRS - MyGUI_OgrePlatform.h - "${MYGUISDK}/Platforms/Ogre/OgrePlatform/include" - NO_DEFAULT_PATH ) +find_path ( MYGUI_INCLUDE_DIRS +MyGUI.h +"${MYGUISDK}/MyGUIEngine/include" +NO_DEFAULT_PATH ) - SET ( MYGUI_LIB_DIR ${MYGUISDK}/*/lib ) - - find_library ( MYGUI_LIBRARIES_REL NAMES - MyGUIEngine.lib - MyGUI.OgrePlatform.lib - HINTS - ${MYGUI_LIB_DIR} - PATH_SUFFIXES "" release relwithdebinfo minsizerel ) +find_path ( MYGUI_PLATFORM_INCLUDE_DIRS +MyGUI_OgrePlatform.h +"${MYGUISDK}/Platforms/Ogre/OgrePlatform/include" +NO_DEFAULT_PATH ) - find_library ( MYGUI_LIBRARIES_DBG NAMES - MyGUIEngine_d.lib - MyGUI.OgrePlatform_d.lib - HINTS - ${MYGUI_LIB_DIR} - PATH_SUFFIXES "" debug ) +SET ( MYGUI_LIB_DIR ${MYGUISDK}/*/lib ) - find_library ( MYGUI_PLATFORM_LIBRARIES_REL NAMES - MyGUI.OgrePlatform.lib - HINTS - ${MYGUI_LIB_DIR} - PATH_SUFFIXES "" release relwithdebinfo minsizerel ) +find_library ( MYGUI_LIBRARIES_REL NAMES +MyGUIEngine.lib +MyGUI.OgrePlatform.lib +HINTS +${MYGUI_LIB_DIR} +PATH_SUFFIXES "" release relwithdebinfo minsizerel ) - find_library ( MYGUI_PLATFORM_LIBRARIES_DBG NAMES - MyGUI.OgrePlatform_d.lib - HINTS - ${MYGUI_LIB_DIR} - PATH_SUFFIXES "" debug ) - - make_library_set ( MYGUI_LIBRARIES ) - make_library_set ( MYGUI_PLATFORM_LIBRARIES ) - - MESSAGE ("${MYGUI_LIBRARIES}") - MESSAGE ("${MYGUI_PLATFORM_LIBRARIES}") +find_library ( MYGUI_LIBRARIES_DBG NAMES +MyGUIEngine_d.lib +MyGUI.OgrePlatform_d.lib +HINTS +${MYGUI_LIB_DIR} +PATH_SUFFIXES "" debug ) - findpkg_finish ( "MYGUI" ) +find_library ( MYGUI_PLATFORM_LIBRARIES_REL NAMES +MyGUI.OgrePlatform.lib +HINTS +${MYGUI_LIB_DIR} +PATH_SUFFIXES "" release relwithdebinfo minsizerel ) + +find_library ( MYGUI_PLATFORM_LIBRARIES_DBG NAMES +MyGUI.OgrePlatform_d.lib +HINTS +${MYGUI_LIB_DIR} +PATH_SUFFIXES "" debug ) + +make_library_set ( MYGUI_LIBRARIES ) +make_library_set ( MYGUI_PLATFORM_LIBRARIES ) + +MESSAGE ("${MYGUI_LIBRARIES}") +MESSAGE ("${MYGUI_PLATFORM_LIBRARIES}") + +findpkg_finish ( "MYGUI" ) ENDIF (MYGUISDK) IF (OGRESOURCE) @@ -87,9 +87,11 @@ ELSE (WIN32) #Unix SET(MYGUI_INCLUDE_DIRS ${MYGUI_INCLUDE_DIRS}) SET(MYGUI_LIB_DIR ${MYGUI_LIBDIR}) SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "") + SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") ELSE (MYGUI_INCLUDE_DIRS) FIND_PATH(MYGUI_INCLUDE_DIRS MyGUI.h PATHS /usr/local/include /usr/include PATH_SUFFIXES MyGUI MYGUI) FIND_LIBRARY(MYGUI_LIBRARIES mygui PATHS /usr/lib /usr/local/lib) + SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") SET(MYGUI_LIB_DIR ${MYGUI_LIBRARIES}) STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}") STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}") @@ -103,7 +105,7 @@ SEPARATE_ARGUMENTS(MYGUI_PLATFORM_LIBRARIES) SET(MYGUI_INCLUDE_DIRS ${MYGUI_INCLUDE_DIRS} CACHE PATH "") SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "") -SET(MYGUI_LIBRARIES ${MYGUI_PLATFORM_LIBRARIES} CACHE STRING "") +SET(MYGUI_PLATFORM_LIBRARIES ${MYGUI_PLATFORM_LIBRARIES} CACHE STRING "") SET(MYGUI_LIB_DIR ${MYGUI_LIB_DIR} CACHE PATH "") IF (MYGUI_INCLUDE_DIRS AND MYGUI_LIBRARIES) @@ -111,7 +113,7 @@ IF (MYGUI_INCLUDE_DIRS AND MYGUI_LIBRARIES) ENDIF (MYGUI_INCLUDE_DIRS AND MYGUI_LIBRARIES) IF (MYGUI_FOUND) - MARK_AS_ADVANCED(MYGUI_LIB_DIR) +MARK_AS_ADVANCED(MYGUI_LIB_DIR) IF (NOT MYGUI_FIND_QUIETLY) MESSAGE(STATUS " libraries : ${MYGUI_LIBRARIES} from ${MYGUI_LIB_DIR}") MESSAGE(STATUS " includes : ${MYGUI_INCLUDE_DIRS}") @@ -122,4 +124,4 @@ ELSE (MYGUI_FOUND) ENDIF (MYGUI_FIND_REQUIRED) ENDIF (MYGUI_FOUND) -CMAKE_POLICY(POP) \ No newline at end of file +CMAKE_POLICY(POP) diff --git a/components/bsa/bsa_archive.cpp b/components/bsa/bsa_archive.cpp index 72d15944d5..80d92dd521 100644 --- a/components/bsa/bsa_archive.cpp +++ b/components/bsa/bsa_archive.cpp @@ -256,8 +256,12 @@ public: return DataStreamPtr(new Mangle2OgreStream(strm)); } +bool exists(const String& filename) { + return cexists(filename); +} + // Check if the file exists. - bool exists(const String& filename) { + bool cexists(const String& filename) const { String passed = filename; if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<' || filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':' @@ -308,6 +312,29 @@ return arc.exists(passed.c_str()); located in BSAs. So instead we channel it through exists() and set up a single-element result list if the file is found. */ + FileInfoListPtr findFileInfo(const String& pattern, bool recursive = true, + bool dirs = false) const + { + FileInfoListPtr ptr = FileInfoListPtr(new FileInfoList()); + + // Check if the file exists (only works for single files - wild + // cards and recursive search isn't implemented.) + if(cexists(pattern)) + { + FileInfo fi; + fi.archive = this; + fi.filename = pattern; + // It apparently doesn't matter that we return bogus + // information + fi.path = ""; + fi.compressedSize = fi.uncompressedSize = 0; + + ptr->push_back(fi); + } + + return ptr; + } + FileInfoListPtr findFileInfo(const String& pattern, bool recursive = true, bool dirs = false) { @@ -315,7 +342,7 @@ return arc.exists(passed.c_str()); // Check if the file exists (only works for single files - wild // cards and recursive search isn't implemented.) - if(exists(pattern)) + if(cexists(pattern)) { FileInfo fi; fi.archive = this; diff --git a/components/bsa/bsa_file.cpp b/components/bsa/bsa_file.cpp index 95358a3628..f19606703c 100644 --- a/components/bsa/bsa_file.cpp +++ b/components/bsa/bsa_file.cpp @@ -148,9 +148,9 @@ void BSAFile::readHeader() } /// Get the index of a given file name, or -1 if not found -int BSAFile::getIndex(const char *str) +int BSAFile::getIndex(const char *str) const { - Lookup::iterator it; + Lookup::const_iterator it; it = lookup.find(str); if(it == lookup.end()) return -1; diff --git a/components/bsa/bsa_file.hpp b/components/bsa/bsa_file.hpp index f54a64d2af..95fac0f4d7 100644 --- a/components/bsa/bsa_file.hpp +++ b/components/bsa/bsa_file.hpp @@ -93,7 +93,7 @@ class BSAFile void readHeader(); /// Get the index of a given file name, or -1 if not found - int getIndex(const char *str); + int getIndex(const char *str) const; public: @@ -119,7 +119,7 @@ class BSAFile */ /// Check if a file exists - bool exists(const char *file) { return getIndex(file) != -1; } + bool exists(const char *file) const { return getIndex(file) != -1; } /** Open a file contained in the archive. Throws an exception if the file doesn't exist. diff --git a/components/nifbullet/bullet_nif_loader.cpp b/components/nifbullet/bullet_nif_loader.cpp index 82e9d7adc5..e9aa626dbe 100644 --- a/components/nifbullet/bullet_nif_loader.cpp +++ b/components/nifbullet/bullet_nif_loader.cpp @@ -51,7 +51,11 @@ using namespace Mangle::VFS; using namespace NifBullet; -//==================================================================================================== +ManualBulletShapeLoader::~ManualBulletShapeLoader() +{ + delete vfs; +} + Ogre::Matrix3 ManualBulletShapeLoader::getMatrix(Nif::Transformation* tr) { Ogre::Matrix3 rot(tr->rotation.v[0].array[0],tr->rotation.v[0].array[1],tr->rotation.v[0].array[2], @@ -135,7 +139,21 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) handleNode(node,0,Ogre::Matrix3::IDENTITY,Ogre::Vector3::ZERO,1,hasCollisionNode,false,true); } - currentShape = new btBvhTriangleMeshShape(mTriMesh,true); + struct TriangleMeshShape : public btBvhTriangleMeshShape + { + TriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression) + : btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression) + { + } + + virtual ~TriangleMeshShape() + { + delete getTriangleInfoMap(); + delete m_meshInterface; + } + }; + + currentShape = new TriangleMeshShape(mTriMesh,true); cShape->Shape = currentShape; } diff --git a/components/nifbullet/bullet_nif_loader.hpp b/components/nifbullet/bullet_nif_loader.hpp index 1fa2b6aa5f..ed3aceac46 100644 --- a/components/nifbullet/bullet_nif_loader.hpp +++ b/components/nifbullet/bullet_nif_loader.hpp @@ -69,7 +69,7 @@ class ManualBulletShapeLoader : public BulletShapeLoader public: ManualBulletShapeLoader():resourceGroup("General"){vfs = 0;} - virtual ~ManualBulletShapeLoader() {} + virtual ~ManualBulletShapeLoader(); void warn(std::string msg) { diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index 2e68cfe905..f943231d0d 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -509,7 +509,8 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std datamod[index+1] = original.y; datamod[index+2] = original.z; } - vbuf->writeData(0, vbuf->getSizeInBytes(), datamod, false); + vbuf->writeData(0, vbuf->getSizeInBytes(), datamod, false); + delete [] datamod; } else { @@ -550,6 +551,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std datamod[index+2] = original.z; } vbuf->writeData(0, vbuf->getSizeInBytes(), datamod, false); + delete [] datamod; } else { @@ -601,6 +603,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std datamod[i + 1] =y; } vbuf->writeData(0, vbuf->getSizeInBytes(), datamod, false); + delete [] datamod; } else vbuf->writeData(0, vbuf->getSizeInBytes(), data->uvlist.ptr, false); @@ -644,15 +647,13 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std index += 3; } - ibuf->writeData(0, ibuf->getSizeInBytes(), datamod, false); + ibuf->writeData(0, ibuf->getSizeInBytes(), datamod, false); + delete [] datamod; } else - ibuf->writeData(0, ibuf->getSizeInBytes(), data->triangles.ptr, false); + ibuf->writeData(0, ibuf->getSizeInBytes(), data->triangles.ptr, false); sub->indexData->indexBuffer = ibuf; - - - } // Set material if one was given diff --git a/libs/openengine/bullet/BulletShapeLoader.cpp b/libs/openengine/bullet/BulletShapeLoader.cpp index 48b87e1e8c..59a414f301 100644 --- a/libs/openengine/bullet/BulletShapeLoader.cpp +++ b/libs/openengine/bullet/BulletShapeLoader.cpp @@ -22,6 +22,7 @@ Ogre::Resource(creator, name, handle, group, isManual, loader) BulletShape::~BulletShape() { + deleteShape(Shape); } // farm out to BulletShapeLoader @@ -62,17 +63,17 @@ size_t BulletShape::calculateSize() const //============================================================================================================= -template<> BulletShapeManager *Ogre::Singleton::ms_Singleton = 0; +template<> BulletShapeManager *Ogre::Singleton::msSingleton = 0; BulletShapeManager *BulletShapeManager::getSingletonPtr() { - return ms_Singleton; + return msSingleton; } BulletShapeManager &BulletShapeManager::getSingleton() { - assert(ms_Singleton); - return(*ms_Singleton); + assert(msSingleton); + return(*msSingleton); } BulletShapeManager::BulletShapeManager() diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 07bad30535..8b9f3dfecb 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -134,10 +134,15 @@ namespace Physic RigidBody::RigidBody(btRigidBody::btRigidBodyConstructionInfo& CI,std::string name) - :btRigidBody(CI),mName(name) + : btRigidBody(CI) + , mName(name) { + } - }; + RigidBody::~RigidBody() + { + delete getMotionState(); + } @@ -155,8 +160,7 @@ namespace Physic // The actual physics solver solver = new btSequentialImpulseConstraintSolver; - //TODO: memory leak? - btOverlappingPairCache* pairCache = new btSortedOverlappingPairCache(); + pairCache = new btSortedOverlappingPairCache(); //pairCache->setInternalGhostPairCallback( new btGhostPairCallback() ); broadphase = new btDbvtBroadphase(pairCache); @@ -173,6 +177,7 @@ namespace Physic mShapeLoader = shapeLoader; isDebugCreated = false; + mDebugDrawer = NULL; } void PhysicEngine::createDebugRendering() @@ -202,11 +207,41 @@ namespace Physic PhysicEngine::~PhysicEngine() { + + RigidBodyContainer::iterator rb_it = RigidBodyMap.begin(); + for (; rb_it != RigidBodyMap.end(); ++rb_it) + { + if (rb_it->second != NULL) + { + dynamicsWorld->removeRigidBody(rb_it->second); + + delete rb_it->second; + rb_it->second = NULL; + } + } + + PhysicActorContainer::iterator pa_it = PhysicActorMap.begin(); + for (; pa_it != PhysicActorMap.end(); ++pa_it) + { + if (pa_it->second != NULL) + { + dynamicsWorld->removeCollisionObject(pa_it->second->externalGhostObject); + dynamicsWorld->removeCollisionObject(pa_it->second->internalGhostObject); + dynamicsWorld->removeAction(pa_it->second->mCharacter); + + delete pa_it->second; + pa_it->second = NULL; + } + } + + delete mDebugDrawer; + delete dynamicsWorld; delete solver; delete collisionConfiguration; delete dispatcher; delete broadphase; + delete pairCache; delete mShapeLoader; } @@ -239,32 +274,39 @@ namespace Physic dynamicsWorld->addRigidBody(body,COL_WORLD,COL_NOTHING); } body->setActivationState(DISABLE_DEACTIVATION); + RigidBody* oldBody = RigidBodyMap[body->mName]; + if (oldBody != NULL) + { + dynamicsWorld->removeRigidBody(oldBody); + delete oldBody; + } + RigidBodyMap[body->mName] = body; } void PhysicEngine::removeRigidBody(std::string name) { - std::map::iterator it = RigidBodyMap.find(name); + RigidBodyContainer::iterator it = RigidBodyMap.find(name); if (it != RigidBodyMap.end() ) { RigidBody* body = it->second; if(body != NULL) { // broadphase->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(body->getBroadphaseProxy(),dispatcher); - /*std::map::iterator it2 = PhysicActorMap.begin(); + /*PhysicActorContainer::iterator it2 = PhysicActorMap.begin(); for(;it2!=PhysicActorMap.end();it++) { it2->second->internalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(body->getBroadphaseProxy(),dispatcher); it2->second->externalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(body->getBroadphaseProxy(),dispatcher); }*/ - dynamicsWorld->removeRigidBody(RigidBodyMap[name]); + dynamicsWorld->removeRigidBody(body); } } } void PhysicEngine::deleteRigidBody(std::string name) { - std::map::iterator it = RigidBodyMap.find(name); + RigidBodyContainer::iterator it = RigidBodyMap.find(name); if (it != RigidBodyMap.end() ) { RigidBody* body = it->second; @@ -293,6 +335,10 @@ namespace Physic void PhysicEngine::addCharacter(std::string name) { + // Remove character with given name, so we don't make memory + // leak when character would be added twice + removeCharacter(name); + PhysicActor* newActor = new PhysicActor(name); dynamicsWorld->addCollisionObject( newActor->externalGhostObject, COL_ACTOR_EXTERNAL, COL_WORLD |COL_ACTOR_EXTERNAL ); dynamicsWorld->addCollisionObject( newActor->internalGhostObject, COL_ACTOR_INTERNAL, COL_WORLD |COL_ACTOR_INTERNAL ); @@ -303,7 +349,7 @@ namespace Physic void PhysicEngine::removeCharacter(std::string name) { //std::cout << "remove"; - std::map::iterator it = PhysicActorMap.find(name); + PhysicActorContainer::iterator it = PhysicActorMap.find(name); if (it != PhysicActorMap.end() ) { PhysicActor* act = it->second; @@ -311,7 +357,7 @@ namespace Physic { /*broadphase->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->externalGhostObject->getBroadphaseHandle(),dispatcher); broadphase->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->internalGhostObject->getBroadphaseHandle(),dispatcher); - std::map::iterator it2 = PhysicActorMap.begin(); + PhysicActorContainer::iterator it2 = PhysicActorMap.begin(); for(;it2!=PhysicActorMap.end();it++) { it->second->internalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->externalGhostObject->getBroadphaseHandle(),dispatcher); diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index 88e3699aee..57ffe91305 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -42,6 +42,8 @@ namespace Physic :btPairCachingGhostObject(),mName(name) { } + virtual ~PairCachingGhostObject(){} + std::string mName; }; @@ -106,6 +108,7 @@ namespace Physic { public: RigidBody(btRigidBody::btRigidBodyConstructionInfo& CI,std::string name); + virtual ~RigidBody(); std::string mName; //is this body used for raycasting only? @@ -208,6 +211,7 @@ namespace Physic std::list PEventList; //Bullet Stuff + btOverlappingPairCache* pairCache; btBroadphaseInterface* broadphase; btDefaultCollisionConfiguration* collisionConfiguration; btSequentialImpulseConstraintSolver* solver; @@ -217,8 +221,11 @@ namespace Physic //the NIF file loader. BulletShapeLoader* mShapeLoader; - std::map RigidBodyMap; - std::map PhysicActorMap; + typedef std::map RigidBodyContainer; + RigidBodyContainer RigidBodyMap; + + typedef std::map PhysicActorContainer; + PhysicActorContainer PhysicActorMap; //debug rendering BtOgre::DebugDrawer* mDebugDrawer; diff --git a/libs/openengine/ogre/renderer.hpp b/libs/openengine/ogre/renderer.hpp index 6516b0a80c..179515aa92 100644 --- a/libs/openengine/ogre/renderer.hpp +++ b/libs/openengine/ogre/renderer.hpp @@ -44,27 +44,51 @@ namespace Render Ogre::SceneManager *mScene; Ogre::Camera *mCamera; Ogre::Viewport *mView; - #ifdef ENABLE_PLUGIN_CgProgramManager +#ifdef ENABLE_PLUGIN_CgProgramManager Ogre::CgPlugin* mCgPlugin; - #endif - #ifdef ENABLE_PLUGIN_OctreeSceneManager +#endif +#ifdef ENABLE_PLUGIN_OctreeSceneManager Ogre::OctreePlugin* mOctreePlugin; - #endif - #ifdef ENABLE_PLUGIN_ParticleFX +#endif +#ifdef ENABLE_PLUGIN_ParticleFX Ogre::ParticleFXPlugin* mParticleFXPlugin; - #endif - #ifdef ENABLE_PLUGIN_GL +#endif +#ifdef ENABLE_PLUGIN_GL Ogre::GLPlugin* mGLPlugin; - #endif - #ifdef ENABLE_PLUGIN_Direct3D9 +#endif +#ifdef ENABLE_PLUGIN_Direct3D9 Ogre::D3D9Plugin* mD3D9Plugin; - #endif +#endif Fader* mFader; bool logging; public: OgreRenderer() - : mRoot(NULL), mWindow(NULL), mScene(NULL), mFader(NULL) {} + : mRoot(NULL) + , mWindow(NULL) + , mScene(NULL) + , mCamera(NULL) + , mView(NULL) +#ifdef ENABLE_PLUGIN_CgProgramManager + , mCgPlugin(NULL) +#endif +#ifdef ENABLE_PLUGIN_OctreeSceneManager + , mOctreePlugin(NULL) +#endif +#ifdef ENABLE_PLUGIN_ParticleFX + , mParticleFXPlugin(NULL) +#endif +#ifdef ENABLE_PLUGIN_GL + , mGLPlugin(NULL) +#endif +#ifdef ENABLE_PLUGIN_Direct3D9 + , mD3D9Plugin(NULL) +#endif + , mFader(NULL) + , logging(false) + { + } + ~OgreRenderer() { cleanup(); } /** Configure the renderer. This will load configuration files and diff --git a/readme.txt b/readme.txt index 36a7320154..17806172f0 100644 --- a/readme.txt +++ b/readme.txt @@ -148,6 +148,7 @@ Bug #207: Ogre.log not written Bug #209: Sounds do not play Bug #210: Ogre crash at Dren plantation Bug #214: Unsupported file format version +Bug #222: Launcher is writing openmw.cfg file to wrong location Feature #9: NPC Dialogue Window Feature #16/42: New sky/weather implementation Feature #40: Fading