diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index a78b1a6d1..8ef5e59d0 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -55,6 +55,8 @@ namespace MWGui , mWorldMouseOver(false) , mEnemyHealthTimer(0) , mIsDrowning(false) + , mWeaponSpellTimer(0.f) + , mDrowningFlashTheta(0.f) { setCoord(0,0, width, height); diff --git a/apps/openmw/mwgui/messagebox.cpp b/apps/openmw/mwgui/messagebox.cpp index 671845552..378e76e46 100644 --- a/apps/openmw/mwgui/messagebox.cpp +++ b/apps/openmw/mwgui/messagebox.cpp @@ -16,6 +16,15 @@ namespace MWGui mLastButtonPressed = -1; } + MessageBoxManager::~MessageBoxManager () + { + std::vector::iterator it(mMessageBoxes.begin()); + for (; it != mMessageBoxes.end(); ++it) + { + delete *it; + } + } + void MessageBoxManager::onFrame (float frameDuration) { std::vector::iterator it; diff --git a/apps/openmw/mwgui/messagebox.hpp b/apps/openmw/mwgui/messagebox.hpp index aac4704fa..0288f366c 100644 --- a/apps/openmw/mwgui/messagebox.hpp +++ b/apps/openmw/mwgui/messagebox.hpp @@ -23,6 +23,7 @@ namespace MWGui { public: MessageBoxManager (); + ~MessageBoxManager (); void onFrame (float frameDuration); void createMessageBox (const std::string& message, bool stat = false); void removeStaticMessageBox (); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 3d65a56ee..90ced66d3 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -323,6 +323,7 @@ namespace MWGui delete mSoulgemDialog; delete mCursorManager; delete mRecharge; + delete mCompanionWindow; cleanupGarbage(); diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 62242ee8c..5b51c0600 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -537,6 +537,16 @@ namespace MWMechanics Actors::Actors() {} + Actors::~Actors() + { + PtrControllerMap::iterator it(mActors.begin()); + for (; it != mActors.end(); ++it) + { + delete it->second; + it->second = NULL; + } + } + void Actors::addActor (const MWWorld::Ptr& ptr) { // erase previous death events since we are currently only tracking them while in an active cell diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index b03b68e89..83aff63e3 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -48,6 +48,7 @@ namespace MWMechanics public: Actors(); + ~Actors(); /// Update magic effects for an actor. Usually done automatically once per frame, but if we're currently /// paused we may want to do it manually (after equipping permanent enchantment) diff --git a/apps/openmw/mwmechanics/objects.cpp b/apps/openmw/mwmechanics/objects.cpp index 694987855..41d6b4ffa 100644 --- a/apps/openmw/mwmechanics/objects.cpp +++ b/apps/openmw/mwmechanics/objects.cpp @@ -14,6 +14,16 @@ Objects::Objects() { } +Objects::~Objects() +{ + PtrControllerMap::iterator it(mObjects.begin()); + for (; it != mObjects.end();++it) + { + delete it->second; + it->second = NULL; + } +} + void Objects::addObject(const MWWorld::Ptr& ptr) { removeObject(ptr); diff --git a/apps/openmw/mwmechanics/objects.hpp b/apps/openmw/mwmechanics/objects.hpp index 5cdcdaa0a..32432c130 100644 --- a/apps/openmw/mwmechanics/objects.hpp +++ b/apps/openmw/mwmechanics/objects.hpp @@ -21,6 +21,7 @@ namespace MWMechanics public: Objects(); + ~Objects(); void addObject (const MWWorld::Ptr& ptr); ///< Register an animated object diff --git a/apps/openmw/mwrender/camera.cpp b/apps/openmw/mwrender/camera.cpp index 8f54be3f8..bf71505bc 100644 --- a/apps/openmw/mwrender/camera.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -19,25 +19,27 @@ namespace MWRender Camera::Camera (Ogre::Camera *camera) : mCamera(camera), mCameraNode(NULL), + mAnimation(NULL), mFirstPersonView(true), mPreviewMode(false), mFreeLook(true), - mHeight(128.f), - mCameraDistance(300.f), - mDistanceAdjusted(false), - mAnimation(NULL), mNearest(30.f), mFurthest(800.f), mIsNearest(false), mIsFurthest(false), + mHeight(128.f), + mCameraDistance(300.f), + mDistanceAdjusted(false), mVanityToggleQueued(false), mViewModeToggleQueued(false) { mVanity.enabled = false; mVanity.allowed = true; + mPreviewCam.pitch = 0.f; mPreviewCam.yaw = 0.f; mPreviewCam.offset = 400.f; + mMainCam.pitch = 0.f; mMainCam.yaw = 0.f; mMainCam.offset = 400.f; } diff --git a/apps/openmw/mwrender/videoplayer.cpp b/apps/openmw/mwrender/videoplayer.cpp index 88bc6d8ac..adf20dc63 100644 --- a/apps/openmw/mwrender/videoplayer.cpp +++ b/apps/openmw/mwrender/videoplayer.cpp @@ -949,9 +949,25 @@ void VideoState::init(const std::string& resourceName) this->format_ctx->pb = ioCtx; // Open video file - /// \todo leak here, ffmpeg or valgrind bug ? + /// + /// format_ctx->pb->buffer must be freed by hand, + /// if not, valgrind will show memleak, see: + /// + /// https://trac.ffmpeg.org/ticket/1357 + /// if(!this->format_ctx || avformat_open_input(&this->format_ctx, resourceName.c_str(), NULL, NULL)) { + if (this->format_ctx != NULL) + { + if (this->format_ctx->pb != NULL) + { + av_free(this->format_ctx->pb->buffer); + this->format_ctx->pb->buffer = NULL; + + av_free(this->format_ctx->pb); + this->format_ctx->pb = NULL; + } + } // "Note that a user-supplied AVFormatContext will be freed on failure." this->format_ctx = NULL; av_free(ioCtx); @@ -1009,9 +1025,21 @@ void VideoState::deinit() if(this->format_ctx) { - AVIOContext *ioContext = this->format_ctx->pb; + /// + /// format_ctx->pb->buffer must be freed by hand, + /// if not, valgrind will show memleak, see: + /// + /// https://trac.ffmpeg.org/ticket/1357 + /// + if (this->format_ctx->pb != NULL) + { + av_free(this->format_ctx->pb->buffer); + this->format_ctx->pb->buffer = NULL; + + av_free(this->format_ctx->pb); + this->format_ctx->pb = NULL;; + } avformat_close_input(&this->format_ctx); - av_free(ioContext); } } diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 082551f37..0a4db30e9 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -292,6 +292,7 @@ Water::~Water() delete mReflection; delete mRefraction; + delete mSimulation; } void Water::changeCell(const ESM::Cell* cell) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 9e024f872..cf533451c 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -127,7 +127,6 @@ op 0x200007e-0x2000084: Enable Controls op 0x2000085-0x200008b: Disable Controls op 0x200008c: Unlock op 0x200008d: Unlock, explicit reference -op 0x200008e: COE op 0x200008e-0x20000a8: GetSkill op 0x20000a9-0x20000c3: GetSkill, explicit reference op 0x20000c4-0x20000de: SetSkill @@ -358,5 +357,6 @@ op 0x2000222: GetLineOfSight op 0x2000223: GetLineOfSightExplicit op 0x2000224: ToggleAI op 0x2000225: ToggleAIExplicit +op 0x2000226: COE -opcodes 0x2000226-0x3ffffff unused +opcodes 0x2000227-0x3ffffff unused diff --git a/apps/openmw/mwsound/ffmpeg_decoder.cpp b/apps/openmw/mwsound/ffmpeg_decoder.cpp index d5c382a41..c83697442 100644 --- a/apps/openmw/mwsound/ffmpeg_decoder.cpp +++ b/apps/openmw/mwsound/ffmpeg_decoder.cpp @@ -158,6 +158,16 @@ void FFmpeg_Decoder::open(const std::string &fname) mFormatCtx->pb = avio_alloc_context(NULL, 0, 0, this, readPacket, writePacket, seek); if(!mFormatCtx->pb || avformat_open_input(&mFormatCtx, fname.c_str(), NULL, NULL) != 0) { + if (mFormatCtx->pb != NULL) + { + if (mFormatCtx->pb->buffer != NULL) + { + av_free(mFormatCtx->pb->buffer); + mFormatCtx->pb->buffer = NULL; + } + av_free(mFormatCtx->pb); + mFormatCtx->pb = NULL; + } avformat_free_context(mFormatCtx); mFormatCtx = NULL; fail("Failed to allocate input stream"); @@ -195,6 +205,14 @@ void FFmpeg_Decoder::open(const std::string &fname) } catch(std::exception &e) { + if (mFormatCtx->pb->buffer != NULL) + { + av_free(mFormatCtx->pb->buffer); + mFormatCtx->pb->buffer = NULL; + } + av_free(mFormatCtx->pb); + mFormatCtx->pb = NULL; + avformat_close_input(&mFormatCtx); throw; } @@ -211,9 +229,22 @@ void FFmpeg_Decoder::close() if(mFormatCtx) { - AVIOContext* context = mFormatCtx->pb; + if (mFormatCtx->pb != NULL) + { + // mFormatCtx->pb->buffer must be freed by hand, + // if not, valgrind will show memleak, see: + // + // https://trac.ffmpeg.org/ticket/1357 + // + if (mFormatCtx->pb->buffer != NULL) + { + av_free(mFormatCtx->pb->buffer); + mFormatCtx->pb->buffer = NULL; + } + av_free(mFormatCtx->pb); + mFormatCtx->pb = NULL; + } avformat_close_input(&mFormatCtx); - av_free(context); } mDataStream.setNull(); diff --git a/components/compiler/opcodes.hpp b/components/compiler/opcodes.hpp index a885a373d..b7d44a851 100644 --- a/components/compiler/opcodes.hpp +++ b/components/compiler/opcodes.hpp @@ -25,7 +25,7 @@ namespace Compiler const int opcodeAiFollowExplicit = 0x20023; const int opcodeAiFollowCell = 0x20024; const int opcodeAiFollowCellExplicit = 0x20025; - const int opcodeSetHello = 0x200015e; + const int opcodeSetHello = 0x200015c; const int opcodeSetHelloExplicit = 0x200015d; const int opcodeSetFight = 0x200015e; const int opcodeSetFightExplicit = 0x200015f; @@ -69,7 +69,7 @@ namespace Compiler { const int opcodeCellChanged = 0x2000000; const int opcodeCOC = 0x2000026; - const int opcodeCOE = 0x200008e; + const int opcodeCOE = 0x2000226; const int opcodeGetInterior = 0x2000131; const int opcodeGetPCCell = 0x2000136; const int opcodeGetWaterLevel = 0x2000141; diff --git a/components/interpreter/interpreter.cpp b/components/interpreter/interpreter.cpp index 10937e6bc..ea1e9fc91 100644 --- a/components/interpreter/interpreter.cpp +++ b/components/interpreter/interpreter.cpp @@ -166,31 +166,37 @@ namespace Interpreter void Interpreter::installSegment0 (int code, Opcode1 *opcode) { + assert(mSegment0.find(code) == mSegment0.end()); mSegment0.insert (std::make_pair (code, opcode)); } void Interpreter::installSegment1 (int code, Opcode2 *opcode) { + assert(mSegment1.find(code) == mSegment1.end()); mSegment1.insert (std::make_pair (code, opcode)); } void Interpreter::installSegment2 (int code, Opcode1 *opcode) { + assert(mSegment2.find(code) == mSegment2.end()); mSegment2.insert (std::make_pair (code, opcode)); } void Interpreter::installSegment3 (int code, Opcode1 *opcode) { + assert(mSegment3.find(code) == mSegment3.end()); mSegment3.insert (std::make_pair (code, opcode)); } void Interpreter::installSegment4 (int code, Opcode2 *opcode) { + assert(mSegment4.find(code) == mSegment4.end()); mSegment4.insert (std::make_pair (code, opcode)); } void Interpreter::installSegment5 (int code, Opcode0 *opcode) { + assert(mSegment5.find(code) == mSegment5.end()); mSegment5.insert (std::make_pair (code, opcode)); } diff --git a/components/terrain/quadtreenode.cpp b/components/terrain/quadtreenode.cpp index e16ae55dd..02225cb02 100644 --- a/components/terrain/quadtreenode.cpp +++ b/components/terrain/quadtreenode.cpp @@ -140,17 +140,19 @@ namespace } QuadTreeNode::QuadTreeNode(World* terrain, ChildDirection dir, float size, const Ogre::Vector2 ¢er, QuadTreeNode* parent) - : mSize(size) - , mCenter(center) - , mParent(parent) - , mDirection(dir) + : mMaterialGenerator(NULL) + , mIsActive(false) , mIsDummy(false) - , mSceneNode(NULL) - , mTerrain(terrain) - , mChunk(NULL) - , mMaterialGenerator(NULL) + , mSize(size) + , mLodLevel(Log2(mSize)) , mBounds(Ogre::AxisAlignedBox::BOX_NULL) , mWorldBounds(Ogre::AxisAlignedBox::BOX_NULL) + , mDirection(dir) + , mCenter(center) + , mSceneNode(NULL) + , mParent(parent) + , mTerrain(terrain) + , mChunk(NULL) { mBounds.setNull(); for (int i=0; i<4; ++i) @@ -168,8 +170,6 @@ QuadTreeNode::QuadTreeNode(World* terrain, ChildDirection dir, float size, const pos = mCenter - pos; mSceneNode->setPosition(Ogre::Vector3(pos.x*8192, pos.y*8192, 0)); - mLodLevel = Log2(mSize); - mMaterialGenerator = new MaterialGenerator(mTerrain->getShadersEnabled()); } diff --git a/libs/openengine/ogre/renderer.hpp b/libs/openengine/ogre/renderer.hpp index f45f09b01..767e7cf99 100644 --- a/libs/openengine/ogre/renderer.hpp +++ b/libs/openengine/ogre/renderer.hpp @@ -74,8 +74,9 @@ namespace OEngine , mScene(NULL) , mCamera(NULL) , mView(NULL) - , mWindowListener(NULL) + , mOgreInit(NULL) , mFader(NULL) + , mWindowListener(NULL) { }