[Scummvm-git-logs] scummvm master -> 2cc79fe9c800c2f6e711d135e2039461af7e199e

sev- sev at scummvm.org
Sat Nov 18 22:35:50 CET 2017


This automated email contains information about 59 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
076667dc00 COMMON: Add limited support for custom deleters to ScopedPtr
92f5718e2b FULLPIPE: Fix illegal C-style cast to incompatible type
8f1d76d261 FULLPIPE: Improve memory safety and typing of NGIArchive
72a4292727 FULLPIPE: Improve memory safety and fix leaks in sound code
136223026e FULLPIPE: Remove illegal C-style cast to incompatible type
88a2eaba93 FULLPIPE: Make dimensions/coordinate getters pure functions
8e0c53de18 FULLPIPE: Fix whitespace errors
0cc0b1932e FULLPIPE: Fix memory leaks, ownership issues, and endianness issues in graphics code
cc905d7f9a FULLPIPE: Make TODO labelled so it is picked up by tools
f41074b930 FULLPIPE: Improve memory ownership in Motion
a49b6648c8 FULLPIPE: Fix leaks of MGMSubItem
a25246bebe FULLPIPE: Remove unnecessary extra allocation for RNG
926bcb6740 FULLPIPE: Handle quit/RTL events correctly
ac593e045e FULLPIPE: Fix memory leaks in ModalVideoPlayer
5ab7a12779 FULLPIPE: Fix memory leaks of inventory icons and items
6f8a65c739 FULLPIPE: Fix memory leak & unnecessary heap allocation of Rects
ff96db23df FULLPIPE: Fix leaks and unnecessary extra allocations in FullpipeEngine
5c89c39325 FULLPIPE: Fix memory leak of save game thumbnail
8e8932f38d FULLPIPE: Remove unnecessary and illegal C-style casts
1337f04122 FULLPIPE: Fix memory leaks of SceneTag
c85f409a0b FULLPIPE: Remove memory leaks and manual memory management in Scene
350ddcee10 FULLPIPE: Take references instead of pointers for required arguments in statics, remove unnecessary Picture allocation
b90f21597a FULLPIPE: Use bool literals instead of ints for bool properties
7514c5289b FULLPIPE: Remove manual memory management of streams
14a6ff0810 FULLPIPE: Fix memory leaks of MovTable and remove unnecessary extra class
7c66ffe5c8 FULLPIPE: Fix memory leak of MGMItem
384d68b679 FULLPIPE: Correctly fix Bitmap leaks
d07e9a0cf1 FULLPIPE: Fix memory leaks and ownership problems with Behavior objects
0e28f2be47 FULLPIPE: Remove unused gap data from EntranceInfo
073692fd52 FULLPIPE: Reduce chance of Scene leaks, remove unused SceneTag member
39ea2f66ac FULLPIPE: Fix deleted queue leaks & clarify flags
e2367f3ed2 FULLPIPE: Remove unnecessary and unsafe C-style casts
c2dcb27e35 FULLPIPE: Fix memory leaks in ModalMainMenu
ca5a86e703 FULLPIPE: Fix memory leak of global message queues
bb26bf7994 FULLPIPE: Fix memory leaks and unnecessary indirect allocations in Motion and Sc2
d2249a1bed FULLPIPE: Annotate ownership rule of MfcArchive::readClass
6a13592633 FULLPIPE: Disable some unused code paths
715d4bd76a FULLPIPE: Fix memory leaks, ownership issues with various point lists
a475cec2aa FULLPIPE: Remove unnecessary constructors
7232f67fe9 FULLPIPE: Fix memory leak of graph nodes and lists
a2e2569347 FULLPIPE: Use flag enum
4cc64c4139 FULLPIPE: Fix memory leaks in PictureObject, Background
a6fc77ec65 FULLPIPE: Clarify ownership of pointer arrays in StaticANIObject
c7b1f6b26c FULLPIPE: Clarify ownership of DynamicPhase::_exCommand
cef4d77877 FULLPIPE: Fix memory leaks of MctlItems in MctlCompound
a8b635e4cd FULLPIPE: Fix leaks of DynamicPhases
54f8cf55ea FULLPIPE: Fix memory leaks of InventoryPoolItem
7323bef77b FULLPIPE: Remove manual memory management of use list
c9327f2985 FULLPIPE: Fix memory leaks of PreloadItems
51b19e97c8 FULLPIPE: Fix memory leaks of Interactions
bd07925134 FULLPIPE: Fix leaks of MessageQueues
dcf8f588c7 FULLPIPE: Remove unnecessary member array clear in destructor
0cc3d8f05d FULLPIPE: Fix leaks of ExCommands loaded from an archive
2be96457b9 FULLPIPE: Make list item ownership comments more consistent
8808817d56 FULLPIPE: Fix memory leaks of MessageQueues when clearing GlobalMessageQueueList
d0efcb7ad5 FULLPIPE: Fix use-after-free in ModalMainMenu
a5060cf378 FULLPIPE: Remove manual memory management and fix in-game save/load
e40b4a348a FULLPIPE: Fix memory leaks of arcade keys
2cc79fe9c8 FULLPIPE: Fix memory leaks restoring save games


Commit: 076667dc0064432a3d4e3cf696d6688ee01a17a9
    https://github.com/scummvm/scummvm/commit/076667dc0064432a3d4e3cf696d6688ee01a17a9
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
COMMON: Add limited support for custom deleters to ScopedPtr

Custom deleters of ScopedPtr are not currently fully conforming to
C++11's support for custom deleters in std::unique_ptr for the
sake of simplicity of implementation. Unlike in the standard
library, plain functions and lvalue references are not supported,
nor may custom deleters be passed to the constructor at runtime.
This can be improved in the future, if necessary, by doing what
standard library implementations usually do and creating a Pair
class that uses the Empty Base Optimization idiom to avoid extra
storage overhead of the deleter instance when it is not needed, as
in typical standard library implementations, plus some additional
type traits to support the necessary metaprogramming for the
different type overloads.

Changed paths:
    common/ptr.h
    engines/savestate.cpp
    graphics/surface.h
    test/common/ptr.h


diff --git a/common/ptr.h b/common/ptr.h
index 510fec1..f592beb 100644
--- a/common/ptr.h
+++ b/common/ptr.h
@@ -40,12 +40,7 @@ class SharedPtrDeletionImpl : public SharedPtrDeletionInternal {
 public:
 	SharedPtrDeletionImpl(T *ptr) : _ptr(ptr) {}
 	~SharedPtrDeletionImpl() {
-		// Checks if the supplied type is not just a plain
-		// forward definition, taken from boost::checked_delete
-		// This makes the user really aware what he tries to do
-		// when using this with an incomplete type.
-		typedef char completeCheck[sizeof(T) ? 1 : -1];
-		(void)sizeof(completeCheck);
+		STATIC_ASSERT(sizeof(T) > 0, SharedPtr_cannot_delete_incomplete_type);
 		delete _ptr;
 	}
 private:
@@ -223,8 +218,16 @@ private:
 	PointerType _pointer;
 };
 
-template<typename T>
-class ScopedPtr : private NonCopyable, public SafeBool<ScopedPtr<T> > {
+template <typename T>
+struct DefaultDeleter {
+	inline void operator()(T *object) {
+		STATIC_ASSERT(sizeof(T) > 0, cannot_delete_incomplete_type);
+		delete object;
+	}
+};
+
+template<typename T, class D = DefaultDeleter<T> >
+class ScopedPtr : private NonCopyable, public SafeBool<ScopedPtr<T, D> > {
 public:
 	typedef T ValueType;
 	typedef T *PointerType;
@@ -242,14 +245,14 @@ public:
 	bool operator_bool() const { return _pointer != nullptr; }
 
 	~ScopedPtr() {
-		delete _pointer;
+		D()(_pointer);
 	}
 
 	/**
 	 * Resets the pointer with the new value. Old object will be destroyed
 	 */
 	void reset(PointerType o = 0) {
-		delete _pointer;
+		D()(_pointer);
 		_pointer = o;
 	}
 
@@ -276,9 +279,8 @@ private:
 	PointerType _pointer;
 };
 
-
-template<typename T>
-class DisposablePtr : private NonCopyable, public SafeBool<DisposablePtr<T> > {
+template<typename T, class D = DefaultDeleter<T> >
+class DisposablePtr : private NonCopyable, public SafeBool<DisposablePtr<T, D> > {
 public:
 	typedef T  ValueType;
 	typedef T *PointerType;
@@ -287,7 +289,7 @@ public:
 	explicit DisposablePtr(PointerType o, DisposeAfterUse::Flag dispose) : _pointer(o), _dispose(dispose) {}
 
 	~DisposablePtr() {
-		if (_dispose) delete _pointer;
+		if (_dispose) D()(_pointer);
 	}
 
 	ReferenceType operator*() const { return *_pointer; }
diff --git a/engines/savestate.cpp b/engines/savestate.cpp
index 20a3758..92c1eaf 100644
--- a/engines/savestate.cpp
+++ b/engines/savestate.cpp
@@ -39,7 +39,7 @@ void SaveStateDescriptor::setThumbnail(Graphics::Surface *t) {
 	if (_thumbnail.get() == t)
 		return;
 
-	_thumbnail = Common::SharedPtr<Graphics::Surface>(t, Graphics::SharedPtrSurfaceDeleter());
+	_thumbnail = Common::SharedPtr<Graphics::Surface>(t, Graphics::SurfaceDeleter());
 }
 
 void SaveStateDescriptor::setSaveDate(int year, int month, int day) {
diff --git a/graphics/surface.h b/graphics/surface.h
index 87c5f52..19107b8 100644
--- a/graphics/surface.h
+++ b/graphics/surface.h
@@ -334,7 +334,7 @@ public:
  *
  * This deleter assures Surface::free is called on deletion.
  */
-struct SharedPtrSurfaceDeleter {
+struct SurfaceDeleter {
 	void operator()(Surface *ptr) {
 		if (ptr) {
 			ptr->free();
diff --git a/test/common/ptr.h b/test/common/ptr.h
index ebd9789..0c871a7 100644
--- a/test/common/ptr.h
+++ b/test/common/ptr.h
@@ -5,6 +5,14 @@
 class PtrTestSuite : public CxxTest::TestSuite {
 	public:
 
+	struct A {
+		int a;
+	};
+
+	struct B : public A {
+		int b;
+	};
+
 	// A simple class which keeps track of all its instances
 	class InstanceCountingClass {
 	public:
@@ -26,6 +34,61 @@ class PtrTestSuite : public CxxTest::TestSuite {
 		TS_ASSERT_EQUALS(InstanceCountingClass::count, 0);
 	}
 
+	struct CustomDeleter {
+		static bool invoked;
+		void operator()(int *object) {
+			invoked = true;
+			delete object;
+		}
+	};
+
+	void test_scoped_deleter() {
+		CustomDeleter::invoked = false;
+
+		{
+			Common::ScopedPtr<int, CustomDeleter> a(new int(0));
+			TS_ASSERT(!CustomDeleter::invoked);
+		}
+
+		TS_ASSERT(CustomDeleter::invoked);
+	}
+
+	void test_disposable_deleter() {
+		CustomDeleter::invoked = false;
+
+		{
+			Common::DisposablePtr<int, CustomDeleter> a1(new int, DisposeAfterUse::YES);
+			TS_ASSERT(!CustomDeleter::invoked);
+		}
+
+		TS_ASSERT(CustomDeleter::invoked);
+		CustomDeleter::invoked = false;
+
+		int *a = new int;
+		{
+			Common::DisposablePtr<int, CustomDeleter> a2(a, DisposeAfterUse::NO);
+		}
+
+		TS_ASSERT(!CustomDeleter::invoked);
+		delete a;
+	}
+
+	void test_scoped_deref() {
+		A *raw = new A();
+		raw->a = 123;
+		Common::ScopedPtr<A> a(raw);
+		TS_ASSERT_EQUALS(&*a, &*raw);
+		TS_ASSERT_EQUALS(a->a, raw->a);
+	}
+
+	void test_disposable_deref() {
+		A *raw = new A();
+		raw->a = 123;
+		Common::DisposablePtr<A> a(raw, DisposeAfterUse::YES);
+		TS_ASSERT_EQUALS(&*a, &*raw);
+		TS_ASSERT_EQUALS(a->a, raw->a);
+	}
+
 	void test_assign() {
 		Common::SharedPtr<int> p1(new int(1));
 		TS_ASSERT(p1.unique());
@@ -88,14 +151,6 @@ class PtrTestSuite : public CxxTest::TestSuite {
 		TS_ASSERT(!p1);
 	}
 
-	struct A {
-		int a;
-	};
-
-	struct B : public A {
-		int b;
-	};
-
 	void test_cast() {
 		Common::SharedPtr<B> b(new B);
 		Common::SharedPtr<A> a(b);
@@ -104,3 +159,4 @@ class PtrTestSuite : public CxxTest::TestSuite {
 };
 
 int PtrTestSuite::InstanceCountingClass::count = 0;
+bool PtrTestSuite::CustomDeleter::invoked = false;


Commit: 92f5718e2b5a28a6c6a0b9a221079e7fd2d42438
    https://github.com/scummvm/scummvm/commit/92f5718e2b5a28a6c6a0b9a221079e7fd2d42438
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix illegal C-style cast to incompatible type

Changed paths:
    engines/fullpipe/interaction.cpp


diff --git a/engines/fullpipe/interaction.cpp b/engines/fullpipe/interaction.cpp
index 8a95926..f13d826 100644
--- a/engines/fullpipe/interaction.cpp
+++ b/engines/fullpipe/interaction.cpp
@@ -518,12 +518,11 @@ bool Interaction::canInteract(GameObject *obj1, GameObject *obj2, int invId) {
 }
 
 bool Interaction::isOverlapping(StaticANIObject *subj, GameObject *obj) {
-	StaticANIObject *ani = (StaticANIObject *)obj;
-
 	if (abs(_xOffs + obj->_ox - subj->_ox) <= 1
 		&& abs(obj->_oy + _yOffs - subj->_oy) <= 1) {
 		if (!_staticsId2 || (subj->_statics != 0 && subj->_statics->_staticsId == _staticsId2)) {
-			if (!_staticsId1 || !(_flags & 1) || (ani->_statics != 0 && ani->_statics->_staticsId == _staticsId1))
+			StaticANIObject *ani = dynamic_cast<StaticANIObject *>(obj);
+			if (!_staticsId1 || !(_flags & 1) || (ani && ani->_statics != 0 && ani->_statics->_staticsId == _staticsId1))
 				return true;
 		}
 	}


Commit: 8f1d76d2616489924f472815f91107cd46d479de
    https://github.com/scummvm/scummvm/commit/8f1d76d2616489924f472815f91107cd46d479de
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Improve memory safety and typing of NGIArchive

Changed paths:
    engines/fullpipe/ngiarchive.cpp
    engines/fullpipe/ngiarchive.h
    engines/fullpipe/sound.cpp


diff --git a/engines/fullpipe/ngiarchive.cpp b/engines/fullpipe/ngiarchive.cpp
index 7d75dc2e7..e69307a 100644
--- a/engines/fullpipe/ngiarchive.cpp
+++ b/engines/fullpipe/ngiarchive.cpp
@@ -70,7 +70,6 @@ NGIArchive::NGIArchive(const Common::String &filename) : _ngiFilename(filename)
 	}
 
 	NgiHeader header;
-	NgiHeader *head;
 
 	for (uint i = 0; i < count; i++) {
 		memcpy(header.filename, &fat[i * 32], 12);
@@ -84,9 +83,7 @@ NGIArchive::NGIArchive(const Common::String &filename) : _ngiFilename(filename)
 			warning("File has flags: %.8x\n", header.flags & 0x1e0);
 		}
 
-		head = new NgiHeader(header);
-
-		_headers[header.filename] = head;
+		_headers[header.filename].reset(new NgiHeader(header));
 	}
 
 	free(fat);
@@ -98,19 +95,14 @@ NGIArchive::NGIArchive(const Common::String &filename) : _ngiFilename(filename)
 
 NGIArchive::~NGIArchive() {
 	debugC(0, kDebugLoading, "NGIArchive Destructor Called");
-	NgiHeadersMap::iterator it = _headers.begin();
-	for ( ; it != _headers.end(); ++it) {
-		delete it->_value;
-	}
-
-	g_fp->_currArchive = 0;
+	g_fp->_currArchive = nullptr;
 }
 
 bool NGIArchive::hasFile(const Common::String &name) const {
 	return _headers.contains(name);
 }
 
-	int NGIArchive::listMembers(Common::ArchiveMemberList &list) const {
+int NGIArchive::listMembers(Common::ArchiveMemberList &list) const {
 	int matches = 0;
 
 	NgiHeadersMap::const_iterator it = _headers.begin();
@@ -134,7 +126,7 @@ Common::SeekableReadStream *NGIArchive::createReadStreamForMember(const Common::
 		return 0;
 	}
 
-	NgiHeader *hdr = _headers[name];
+	NgiHeader *hdr = _headers[name].get();
 
 	Common::File archiveFile;
 	archiveFile.open(_ngiFilename);
@@ -149,7 +141,7 @@ Common::SeekableReadStream *NGIArchive::createReadStreamForMember(const Common::
 	return new Common::MemoryReadStream(data, hdr->size, DisposeAfterUse::YES);
 }
 
-Common::Archive *makeNGIArchive(const Common::String &name) {
+NGIArchive *makeNGIArchive(const Common::String &name) {
 	return new NGIArchive(name);
 }
 
diff --git a/engines/fullpipe/ngiarchive.h b/engines/fullpipe/ngiarchive.h
index a5b05a2..18646fa 100644
--- a/engines/fullpipe/ngiarchive.h
+++ b/engines/fullpipe/ngiarchive.h
@@ -23,6 +23,7 @@
 #ifndef FULLPIPE_NGIARCHIVE_H
 #define FULLPIPE_NGIARCHIVE_H
 
+#include "common/ptr.h"
 #include "common/str.h"
 
 namespace Fullpipe {
@@ -39,7 +40,7 @@ struct NgiHeader {
 	char  filename[NGI_FILENAME_MAX];
 };
 
-typedef Common::HashMap<Common::String, NgiHeader*, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> NgiHeadersMap;
+typedef Common::HashMap<Common::String, Common::ScopedPtr<NgiHeader>, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> NgiHeadersMap;
 
 class NGIArchive : public Common::Archive {
 	NgiHeadersMap _headers;
@@ -62,7 +63,7 @@ public:
  *
  * May return 0 in case of a failure.
  */
-Common::Archive *makeNGIArchive(const Common::String &name);
+NGIArchive *makeNGIArchive(const Common::String &name);
 
 } // End of namespace Fullpipe
 
diff --git a/engines/fullpipe/sound.cpp b/engines/fullpipe/sound.cpp
index 77112cb..4ab6520 100644
--- a/engines/fullpipe/sound.cpp
+++ b/engines/fullpipe/sound.cpp
@@ -57,7 +57,7 @@ bool SoundList::load(MfcArchive &file, const Common::String &fname) {
 	_soundItems = (Sound **)calloc(_soundItemsCount, sizeof(Sound *));
 
 	if (!fname.empty()) {
-	  _libHandle = (NGIArchive *)makeNGIArchive(fname);
+		_libHandle = makeNGIArchive(fname);
 	} else {
 		_libHandle = 0;
 	}


Commit: 72a42927279a8b740cd0bb5a8053def4a465f2dd
    https://github.com/scummvm/scummvm/commit/72a42927279a8b740cd0bb5a8053def4a465f2dd
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Improve memory safety and fix leaks in sound code

Changed paths:
    engines/fullpipe/messagehandlers.cpp
    engines/fullpipe/modal.cpp
    engines/fullpipe/modal.h
    engines/fullpipe/scene.cpp
    engines/fullpipe/scenes.cpp
    engines/fullpipe/sound.cpp
    engines/fullpipe/sound.h


diff --git a/engines/fullpipe/messagehandlers.cpp b/engines/fullpipe/messagehandlers.cpp
index bd75e01..a172184 100644
--- a/engines/fullpipe/messagehandlers.cpp
+++ b/engines/fullpipe/messagehandlers.cpp
@@ -345,7 +345,7 @@ int global_messageHandler2(ExCommand *cmd) {
 			SoundList *s = g_fp->_currSoundList1[snd];
 			int ms = s->getCount();
 			for (int i = 0; i < ms; i++) {
-				s->getSoundByIndex(i)->setPanAndVolumeByStaticAni();
+				s->getSoundByIndex(i).setPanAndVolumeByStaticAni();
 			}
 		}
 	}
diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp
index 3faa035..6589ba6 100644
--- a/engines/fullpipe/modal.cpp
+++ b/engines/fullpipe/modal.cpp
@@ -1504,11 +1504,11 @@ void ModalMainMenu::updateVolume() {
 	}
 }
 
-void ModalMainMenu::updateSoundVolume(Sound *snd) {
-	if (!snd->_objectId)
+void ModalMainMenu::updateSoundVolume(Sound &snd) {
+	if (!snd._objectId)
 		return;
 
-	StaticANIObject *ani = g_fp->_currentScene->getStaticANIObject1ById(snd->_objectId, -1);
+	StaticANIObject *ani = g_fp->_currentScene->getStaticANIObject1ById(snd._objectId, -1);
 	if (!ani)
 		return;
 
@@ -1522,7 +1522,7 @@ void ModalMainMenu::updateSoundVolume(Sound *snd) {
 
 			if (ani->_oy <= _screct.bottom) {
 				if (ani->_oy >= _screct.top) {
-					snd->setPanAndVolume(g_fp->_sfxVolume, 0);
+					snd.setPanAndVolume(g_fp->_sfxVolume, 0);
 
 					return;
 				}
@@ -1534,7 +1534,7 @@ void ModalMainMenu::updateSoundVolume(Sound *snd) {
 			par = 0;
 
 			if (dx > 800) {
-				snd->setPanAndVolume(-3500, 0);
+				snd.setPanAndVolume(-3500, 0);
 				return;
 			}
 
@@ -1545,7 +1545,7 @@ void ModalMainMenu::updateSoundVolume(Sound *snd) {
 			int dx = ani->_ox - _screct.right;
 
 			if (dx > 800) {
-				snd->setPanAndVolume(-3500, 0);
+				snd.setPanAndVolume(-3500, 0);
 				return;
 			}
 
@@ -1557,7 +1557,7 @@ void ModalMainMenu::updateSoundVolume(Sound *snd) {
 
 		int32 pp = b * a;
 
-		snd->setPanAndVolume(pan + pp / 800, par);
+		snd.setPanAndVolume(pan + pp / 800, par);
 
 		return;
 	}
@@ -1570,9 +1570,9 @@ void ModalMainMenu::updateSoundVolume(Sound *snd) {
 		if (p > g_fp->_sfxVolume)
 			p = g_fp->_sfxVolume;
 
-		snd->setPanAndVolume(p, dx * (-3500) / 800);
+		snd.setPanAndVolume(p, dx * (-3500) / 800);
 	} else {
-		snd->setPanAndVolume(-3500, 0);
+		snd.setPanAndVolume(-3500, 0);
 	}
 }
 
diff --git a/engines/fullpipe/modal.h b/engines/fullpipe/modal.h
index ba88808..6cd4581 100644
--- a/engines/fullpipe/modal.h
+++ b/engines/fullpipe/modal.h
@@ -228,7 +228,7 @@ private:
 	void enableDebugMenu(char c);
 	int checkHover(Common::Point &point);
 	void updateVolume();
-	void updateSoundVolume(Sound *snd);
+	void updateSoundVolume(Sound &snd);
 	void updateSliderPos();
 	bool isOverArea(PictureObject *obj, Common::Point *point);
 };
diff --git a/engines/fullpipe/scene.cpp b/engines/fullpipe/scene.cpp
index 74a824f..3d39683 100644
--- a/engines/fullpipe/scene.cpp
+++ b/engines/fullpipe/scene.cpp
@@ -342,7 +342,7 @@ void Scene::setPictureObjectsFlag4() {
 
 void Scene::stopAllSounds() {
 	for (int i = 0; i < _soundList->getCount(); i++)
-		_soundList->getSoundByIndex(i)->stop();
+		_soundList->getSoundByIndex(i).stop();
 }
 
 PictureObject *Scene::getPictureObjectById(int objId, int flags) {
diff --git a/engines/fullpipe/scenes.cpp b/engines/fullpipe/scenes.cpp
index bb141d9..7825a1e 100644
--- a/engines/fullpipe/scenes.cpp
+++ b/engines/fullpipe/scenes.cpp
@@ -577,7 +577,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
 			_currSoundList1[1] = scene->_soundList;
 
 			for (int i = 0; i < scene->_soundList->getCount(); i++) {
-				scene->_soundList->getSoundByIndex(i)->updateVolume();
+				scene->_soundList->getSoundByIndex(i).updateVolume();
 			}
 		} else {
 			_currSoundListCount = 1;
diff --git a/engines/fullpipe/sound.cpp b/engines/fullpipe/sound.cpp
index 4ab6520..44dbe56 100644
--- a/engines/fullpipe/sound.cpp
+++ b/engines/fullpipe/sound.cpp
@@ -38,39 +38,23 @@
 
 namespace Fullpipe {
 
-SoundList::SoundList() {
-	_soundItems = 0;
-	_soundItemsCount = 0;
-	_libHandle = 0;
-}
-
-SoundList::~SoundList() {
-	for (int i = 0; i < _soundItemsCount; i++)
-		delete _soundItems[i];
-	free(_soundItems);
-}
-
 bool SoundList::load(MfcArchive &file, const Common::String &fname) {
 	debugC(5, kDebugLoading, "SoundList::load()");
 
-	_soundItemsCount = file.readUint32LE();
-	_soundItems = (Sound **)calloc(_soundItemsCount, sizeof(Sound *));
+	uint32 count = file.readUint32LE();
+	_soundItems.resize(count);
 
 	if (!fname.empty()) {
-		_libHandle = makeNGIArchive(fname);
+		_libHandle.reset(makeNGIArchive(fname));
 	} else {
-		_libHandle = 0;
+		_libHandle.reset();
 	}
 
-	for (int i = 0; i < _soundItemsCount; i++) {
-		Sound *snd = new Sound();
-
-		_soundItems[i] = snd;
-		snd->load(file, _libHandle);
+	for (uint i = 0; i < count; i++) {
+		_soundItems[i].load(file, _libHandle.get());
 	}
 
 	return true;
-
 }
 
 bool SoundList::loadFile(const Common::String &fname, const Common::String &libname) {
@@ -85,26 +69,21 @@ bool SoundList::loadFile(const Common::String &fname, const Common::String &libn
 }
 
 Sound *SoundList::getSoundItemById(int id) {
-	if (_soundItemsCount == 0) {
-		return _soundItems[0]->getId() != id ? 0 : _soundItems[0];
-	}
-
-	for (int i = 0; i < _soundItemsCount; i++) {
-		if (_soundItems[i]->getId() == id)
-			return _soundItems[i];
+	for (uint i = 0; i < _soundItems.size(); ++i) {
+		if (_soundItems[i].getId() == id)
+			return &_soundItems[i];
 	}
-	return NULL;
+	return nullptr;
 }
 
-Sound::Sound() {
-	_id = 0;
-	_directSoundBuffer = 0;
-	_soundData = 0;
-	_objectId = 0;
-	memset(_directSoundBuffers, 0, sizeof(_directSoundBuffers));
-	_volume = 100;
-	_handle = new Audio::SoundHandle();
-}
+Sound::Sound() :
+	_id(0),
+	_directSoundBuffer(0),
+	_directSoundBuffers(),
+	_soundData(nullptr),
+	_handle(new Audio::SoundHandle()),
+	_volume(100),
+	_objectId(0) {}
 
 Sound::~Sound() {
 	freeSound();
@@ -389,7 +368,7 @@ void FullpipeEngine::playOggSound(const Common::String &trackName, Audio::SoundH
 void FullpipeEngine::stopAllSounds() {
 	for (int i = 0; i < _currSoundListCount; i++)
 		for (int j = 0; j < _currSoundList1[i]->getCount(); j++) {
-			_currSoundList1[i]->getSoundByIndex(j)->stop();
+			_currSoundList1[i]->getSoundByIndex(j).stop();
 		}
 }
 
@@ -542,7 +521,7 @@ void FullpipeEngine::updateSoundVolume() {
 
 	for (int i = 0; i < _currSoundListCount; i++)
 		for (int j = 0; j < _currSoundList1[i]->getCount(); j++) {
-			_currSoundList1[i]->getSoundByIndex(j)->setPanAndVolume(_sfxVolume, 0);
+			_currSoundList1[i]->getSoundByIndex(j).setPanAndVolume(_sfxVolume, 0);
 		}
 }
 
diff --git a/engines/fullpipe/sound.h b/engines/fullpipe/sound.h
index bccf2a7..6058416 100644
--- a/engines/fullpipe/sound.h
+++ b/engines/fullpipe/sound.h
@@ -23,6 +23,9 @@
 #ifndef FULLPIPE_SOUND_H
 #define FULLPIPE_SOUND_H
 
+#include "common/array.h"
+#include "common/ptr.h"
+
 namespace Audio {
 class SoundHandle;
 }
@@ -60,19 +63,16 @@ public:
 };
 
 class SoundList : public CObject {
-	Sound **_soundItems;
-	int _soundItemsCount;
-	NGIArchive *_libHandle;
+	Common::Array<Sound> _soundItems;
+	Common::ScopedPtr<NGIArchive> _libHandle;
 
  public:
-	SoundList();
-	~SoundList();
 	virtual bool load(MfcArchive &file, const Common::String &fname);
 	virtual bool load(MfcArchive &file) { assert(0); return false; } // Disable base class
 	bool loadFile(const Common::String &fname, const Common::String &libname);
 
-	int getCount() { return _soundItemsCount; }
-	Sound *getSoundByIndex(int idx) { return _soundItems[idx]; }
+	int getCount() { return _soundItems.size(); }
+	Sound &getSoundByIndex(int idx) { return _soundItems[idx]; }
 	Sound *getSoundItemById(int id);
 };
 


Commit: 136223026ecb4569bbd425ed586eb7de42979c9f
    https://github.com/scummvm/scummvm/commit/136223026ecb4569bbd425ed586eb7de42979c9f
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Remove illegal C-style cast to incompatible type

Changed paths:
    engines/fullpipe/statics.cpp


diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index 993e776..21b9ba8 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -1954,7 +1954,7 @@ void Movement::loadPixelData() {
 		mov = mov->_currMovement;
 
 	for (uint i = 0; i < mov->_dynamicPhases.size(); i++) {
-		if ((Statics *)mov->_dynamicPhases[i] != mov->_staticsObj2 || !(mov->_staticsObj2->_staticsId & 0x4000))
+		if (mov->_dynamicPhases[i] != mov->_staticsObj2 || !(mov->_staticsObj2->_staticsId & 0x4000))
 			mov->_dynamicPhases[i]->getPixelData();
 	}
 


Commit: 88a2eaba93a454562b99bd59f797533b9f6b4848
    https://github.com/scummvm/scummvm/commit/88a2eaba93a454562b99bd59f797533b9f6b4848
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Make dimensions/coordinate getters pure functions

Changed paths:
    engines/fullpipe/anihandler.cpp
    engines/fullpipe/anihandler.h
    engines/fullpipe/gfx.cpp
    engines/fullpipe/gfx.h
    engines/fullpipe/input.cpp
    engines/fullpipe/inventory.cpp
    engines/fullpipe/modal.cpp
    engines/fullpipe/motion.cpp
    engines/fullpipe/scene.cpp
    engines/fullpipe/scenes.cpp
    engines/fullpipe/scenes/scene04.cpp
    engines/fullpipe/scenes/scene06.cpp
    engines/fullpipe/scenes/scene08.cpp
    engines/fullpipe/scenes/scene25.cpp
    engines/fullpipe/scenes/sceneDbg.cpp
    engines/fullpipe/statics.cpp
    engines/fullpipe/statics.h


diff --git a/engines/fullpipe/anihandler.cpp b/engines/fullpipe/anihandler.cpp
index 0600479..7c91f8f 100644
--- a/engines/fullpipe/anihandler.cpp
+++ b/engines/fullpipe/anihandler.cpp
@@ -77,7 +77,7 @@ MessageQueue *AniHandler::makeQueue(StaticANIObject *ani, int staticsIndex, int
 	do {
 		subidx = startidx + endidx * _items[idx]->statics.size();
 
-		_items[idx]->subItems[subidx]->movement->calcSomeXY(point, 0, -1);
+		point = _items[idx]->subItems[subidx]->movement->calcSomeXY(0, -1);
 
 		if (pointArr) {
 			int sz;
@@ -254,9 +254,7 @@ MessageQueue *AniHandler::makeRunQueue(MakeQueueStruct *mkQueue) {
 	int n1x = mkQueue->x1 - mkQueue->x2 - sub1->x - sub2->x;
 	int n1y = mkQueue->y1 - mkQueue->y2 - sub1->y - sub2->y;
 
-	Common::Point point1;
-
-	mov->calcSomeXY(point1, 0, -1);
+	const Common::Point point1 = mov->calcSomeXY(0, -1);
 
 	int n2x = point1.x;
 	int n2y = point1.y;
@@ -269,7 +267,7 @@ MessageQueue *AniHandler::makeRunQueue(MakeQueueStruct *mkQueue) {
 		n2x *= mult;
 		n2y *= mult;
 	} else {
-		getNumCycles(&point, mov, n1x, n1y, &mult, &len, 1);
+		point = getNumCycles(mov, n1x, n1y, &mult, &len, 1);
 		n2x = point.x;
 		n2y = point.y;
 	}
@@ -435,9 +433,7 @@ void AniHandler::putObjectToStatics(StaticANIObject *ani, int staticsId) {
 	}
 
 	if (ani->_statics) {
-		Common::Point point;
-
-		getTransitionSize(&point, ani->_id, ani->_statics->_staticsId, staticsId);
+		const Common::Point point = getTransitionSize(ani->_id, ani->_statics->_staticsId, staticsId);
 
 		ani->setOXY(ani->_ox + point.x, ani->_oy + point.y);
 
@@ -445,47 +441,41 @@ void AniHandler::putObjectToStatics(StaticANIObject *ani, int staticsId) {
 	}
 }
 
-Common::Point *AniHandler::getTransitionSize(Common::Point *point, int objectId, int staticsId1, int staticsId2) {
-	debugC(4, kDebugPathfinding, "AniHandler::getTransitionSize([%d, %d], %d, %d, %d)", point->x, point->y, objectId, staticsId1, staticsId2);
+Common::Point AniHandler::getTransitionSize(int objectId, int staticsId1, int staticsId2) {
+	debugC(4, kDebugPathfinding, "AniHandler::getTransitionSize(%d, %d, %d)", objectId, staticsId1, staticsId2);
 
 	int idx = getIndex(objectId);
 
 	if (idx == -1) {
-		point->x = -1;
-		point->y = -1;
-	} else {
-		int st1idx = getStaticsIndexById(idx, staticsId1);
-		int st2idx = getStaticsIndexById(idx, staticsId2);
+		return Common::Point(-1, -1);
+	}
 
-		if (st1idx == st2idx) {
-			point->x = 0;
-			point->y = 0;
-		} else {
-			int subidx = st1idx + st2idx * _items[idx]->statics.size();
+	int st1idx = getStaticsIndexById(idx, staticsId1);
+	int st2idx = getStaticsIndexById(idx, staticsId2);
 
-			if (!_items[idx]->subItems[subidx]->movement) {
-				clearVisitsList(idx);
-				seekWay(idx, st1idx, st2idx, false, true);
+	if (st1idx == st2idx) {
+		return Common::Point(0, 0);
+	}
 
-				if (!_items[idx]->subItems[subidx]->movement) {
-					clearVisitsList(idx);
-					seekWay(idx, st1idx, st2idx, true, false);
-				}
-			}
+	int subidx = st1idx + st2idx * _items[idx]->statics.size();
 
-			MGMSubItem *sub = _items[idx]->subItems[subidx];
+	if (!_items[idx]->subItems[subidx]->movement) {
+		clearVisitsList(idx);
+		seekWay(idx, st1idx, st2idx, false, true);
 
-			if (sub->movement) {
-				point->x = sub->x;
-				point->y = sub->y;
-			} else {
-				point->x = 0;
-				point->y = 0;
-			}
+		if (!_items[idx]->subItems[subidx]->movement) {
+			clearVisitsList(idx);
+			seekWay(idx, st1idx, st2idx, true, false);
 		}
 	}
 
-	return point;
+	const MGMSubItem *sub = _items[idx]->subItems[subidx];
+
+	if (!sub->movement) {
+		return Common::Point(0, 0);
+	}
+
+	return Common::Point(sub->x, sub->y);
 }
 
 int AniHandler::getStaticsIndexById(int idx, int16 id) {
@@ -565,7 +555,7 @@ int AniHandler::seekWay(int idx, int st1idx, int st2idx, bool flip, bool flop) {
 				item->subItems[subIdx]->field_8 = recalc + 1;
 				item->subItems[subIdx]->field_C = newsz;
 
-				mov->calcSomeXY(point, 0, -1);
+				point = mov->calcSomeXY(0, -1);
 
 				item->subItems[subIdx]->x = item->subItems[stidx + st2idx * _items[idx]->statics.size()]->x + point.x;
 				item->subItems[subIdx]->y = item->subItems[stidx + st2idx * _items[idx]->statics.size()]->y + point.y;
@@ -594,7 +584,7 @@ int AniHandler::seekWay(int idx, int st1idx, int st2idx, bool flip, bool flop) {
 
 				item->subItems[subIdx]->field_C = sz + item->subItems[stidx + st2idx * _items[idx]->statics.size()]->field_C;
 
-				mov->calcSomeXY(point, 0, -1);
+				point = mov->calcSomeXY(0, -1);
 
 				item->subItems[subIdx]->x = item->subItems[stidx + st2idx * _items[idx]->statics.size()]->x - point.x;
 				item->subItems[subIdx]->y = item->subItems[stidx + st2idx * _items[idx]->statics.size()]->y - point.y;
@@ -631,20 +621,18 @@ int AniHandler::getNumMovements(int objectId, int idx1, int idx2) {
 	return idx;
 }
 
-Common::Point *AniHandler::getNumCycles(Common::Point *pRes, Movement *mov, int x, int y, int *mult, int *len, int flag) {
-	Common::Point point;
-
-	mov->calcSomeXY(point, 0, -1);
+Common::Point AniHandler::getNumCycles(Movement *mov, int x, int y, int *mult, int *len, int flag) {
+	Common::Point point = mov->calcSomeXY(0, -1);
 	int p1x = point.x;
 	int p1y = point.y;
 
 	int newmult = 0;
 
 	if (abs(p1y) > abs(p1x)) {
-		if (mov->calcSomeXY(point, 0, -1)->y)
-			newmult = (int)((double)y / mov->calcSomeXY(point, 0, -1)->y);
-	} else if (mov->calcSomeXY(point, 0, -1)->x) {
-		newmult = (int)((double)x / mov->calcSomeXY(point, 0, -1)->x);
+		if (mov->calcSomeXY(0, -1).y)
+			newmult = (int)((double)y / mov->calcSomeXY(0, -1).y);
+	} else if (mov->calcSomeXY(0, -1).x) {
+		newmult = (int)((double)x / mov->calcSomeXY(0, -1).x);
 	}
 
 	if (newmult < 0)
@@ -657,7 +645,7 @@ Common::Point *AniHandler::getNumCycles(Common::Point *pRes, Movement *mov, int
 
 	if (flag) {
 		if (abs(p1y) > abs(p1x)) {
-			while (abs(p1y * newmult + mov->calcSomeXY(point, 0, phase)->y) < abs(y)) {
+			while (abs(p1y * newmult + mov->calcSomeXY(0, phase).y) < abs(y)) {
 				sz = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size();
 
 				if (phase > sz)
@@ -666,7 +654,7 @@ Common::Point *AniHandler::getNumCycles(Common::Point *pRes, Movement *mov, int
 				phase++;
 			}
 		} else {
-			while (abs(p1x * newmult + mov->calcSomeXY(point, 0, phase)->x) < abs(x)) {
+			while (abs(p1x * newmult + mov->calcSomeXY(0, phase).x) < abs(x)) {
 				sz = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size();
 
 				if (phase >= sz)
@@ -690,7 +678,7 @@ Common::Point *AniHandler::getNumCycles(Common::Point *pRes, Movement *mov, int
 	if (*len > 0) {
 		++*mult;
 
-		mov->calcSomeXY(point, 0, *len);
+		point = mov->calcSomeXY(0, *len);
 		p2x = point.x;
 		p2y = point.y;
 
@@ -700,10 +688,7 @@ Common::Point *AniHandler::getNumCycles(Common::Point *pRes, Movement *mov, int
 			p2y = p1y;
 	}
 
-	pRes->x = p2x + p1x * newmult;
-	pRes->y = p2y + p1y * newmult;
-
-	return pRes;
+	return Common::Point(p2x + p1x * newmult, p2y + p1y * newmult);
 }
 
 ExCommand2 *AniHandler::createCommand(Movement *mov, int objId, int x1, int y1, Common::Point *x2, Common::Point *y2, int len) {
diff --git a/engines/fullpipe/anihandler.h b/engines/fullpipe/anihandler.h
index ae16f91..6807629 100644
--- a/engines/fullpipe/anihandler.h
+++ b/engines/fullpipe/anihandler.h
@@ -78,12 +78,12 @@ public:
 
 	MessageQueue *makeRunQueue(MakeQueueStruct *mkQueue);
 	void putObjectToStatics(StaticANIObject *ani, int staticsId);
-	Common::Point *getTransitionSize(Common::Point *point, int aniId, int staticsId1, int staticsId2);
+	Common::Point getTransitionSize(int aniId, int staticsId1, int staticsId2);
 	int getStaticsIndexById(int idx, int16 id);
 	int getStaticsIndex(int idx, Statics *st);
 	void clearVisitsList(int idx);
 	int seekWay(int idx, int st1idx, int st2idx, bool flip, bool flop);
-	Common::Point *getNumCycles(Common::Point *point, Movement *mov, int x, int y, int *mult, int *len, int flag);
+	Common::Point getNumCycles(Movement *mov, int x, int y, int *mult, int *len, int flag);
 	ExCommand2 *createCommand(Movement *mov, int objId, int x1, int y1, Common::Point *x2, Common::Point *y2, int len);
 	MessageQueue *makeQueue(StaticANIObject *ani, int staticsIndex, int staticsId, int *resStatId, Common::Point **pointArr);
 	int getFramesCount(int idx, int subIdx, int subOffset, int flag);
diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp
index 7153ae7..95609a3 100644
--- a/engines/fullpipe/gfx.cpp
+++ b/engines/fullpipe/gfx.cpp
@@ -168,12 +168,6 @@ bool PictureObject::load(MfcArchive &file, bool bigPicture) {
 	return true;
 }
 
-Common::Point *PictureObject::getDimensions(Common::Point *p) {
-	_picture->getDimensions(p);
-
-	return p;
-}
-
 void PictureObject::draw() {
 	if (_flags & 1)
 		_picture->draw(_ox, _oy, 2, 0);
@@ -562,13 +556,6 @@ void Picture::init() {
 	_bitmap->_flags |= 0x1000000;
 }
 
-Common::Point *Picture::getDimensions(Common::Point *p) {
-	p->x = _width;
-	p->y = _height;
-
-	return p;
-}
-
 void Picture::getDibInfo() {
 	int off = _dataSize & ~0xf;
 
@@ -635,14 +622,13 @@ void Picture::draw(int x, int y, int style, int angle) {
 		pal = g_fp->_globalPalette;
 	}
 
-	Common::Point point;
-
 	switch (style) {
-	case 1:
+	case 1: {
 		//flip
-		getDimensions(&point);
-		_bitmap->flipVertical()->drawShaded(1, x1, y1 + 30 + point.y, pal, _alpha);
+		const Dims dims = getDimensions();
+		_bitmap->flipVertical()->drawShaded(1, x1, y1 + 30 + dims.y, pal, _alpha);
 		break;
+	}
 	case 2:
 		//vrtSetFadeRatio(g_vrtDrawHandle, 0.34999999);
 		//vrtSetFadeTable(g_vrtDrawHandle, &unk_477F88, 1.0, 1000.0, 0, 0);
@@ -1214,18 +1200,16 @@ void Shadows::initMovement(Movement *mov) {
 	_items.clear();
 	_items.resize(num);
 
-	Common::Point point;
-
-	_items[0].dynPhase = (DynamicPhase *)mov->_staticsObj1;
-	_items[0].dynPhase->getDimensions(&point);
-	_items[0].width = point.x;
-	_items[0].height = point.y;
+	_items[0].dynPhase = mov->_staticsObj1;
+	Dims dims = _items[0].dynPhase->getDimensions();
+	_items[0].width = dims.x;
+	_items[0].height = dims.y;
 
 	for (uint i = 1; i < num; i++) {
 		_items[i].dynPhase = mov->getDynamicPhaseByIndex(i - 1);
-		_items[i].dynPhase->getDimensions(&point);
-		_items[i].width = point.x;
-		_items[i].height = point.y;
+		dims = _items[i].dynPhase->getDimensions();
+		_items[i].width = dims.x;
+		_items[i].height = dims.y;
 	}
 }
 
diff --git a/engines/fullpipe/gfx.h b/engines/fullpipe/gfx.h
index 13f4464..41214ee 100644
--- a/engines/fullpipe/gfx.h
+++ b/engines/fullpipe/gfx.h
@@ -34,6 +34,8 @@ class DynamicPhase;
 class Movement;
 struct PicAniInfo;
 
+typedef Common::Point Dims;
+
 struct Bitmap {
 	int _x;
 	int _y;
@@ -105,7 +107,7 @@ class Picture : public MemoryObject {
 	byte getAlpha() { return (byte)_alpha; }
 	void setAlpha(byte alpha) { _alpha = alpha; }
 
-	Common::Point *getDimensions(Common::Point *p);
+	Dims getDimensions() const { return Dims(_width, _height); }
 	bool isPointInside(int x, int y);
 	bool isPixelHitAtPos(int x, int y);
 	int getPixelAtPos(int x, int y);
@@ -171,7 +173,7 @@ class PictureObject : public GameObject {
 	virtual bool load(MfcArchive &file, bool bigPicture);
 	virtual bool load(MfcArchive &file) { assert(0); return false; } // Disable base class
 
-	Common::Point *getDimensions(Common::Point *p);
+	Dims getDimensions() const { return _picture->getDimensions(); }
 	void draw();
 	void drawAt(int x, int y);
 
diff --git a/engines/fullpipe/input.cpp b/engines/fullpipe/input.cpp
index 4bcc2ac..0448c1b 100644
--- a/engines/fullpipe/input.cpp
+++ b/engines/fullpipe/input.cpp
@@ -72,12 +72,10 @@ void setInputDisabled(bool state) {
 
 void InputController::addCursor(CursorInfo *cursor) {
 	CursorInfo *newc = new CursorInfo(cursor);
-	Common::Point p;
+	const Dims dims = cursor->picture->getDimensions();
 
-	cursor->picture->getDimensions(&p);
-
-	newc->width = p.x;
-	newc->height = p.y;
+	newc->width = dims.x;
+	newc->height = dims.y;
 
 	newc->picture->_x = -1;
 	newc->picture->_y = -1;
@@ -331,20 +329,18 @@ void FullpipeEngine::processArcade(ExCommand *cmd) {
 }
 
 void FullpipeEngine::setArcadeOverlay(int picId) {
-	Common::Point point;
-	Common::Point point2;
-
 	_arcadeOverlayX = 800;
 	_arcadeOverlayY = 545;
 
 	_arcadeOverlayHelper = accessScene(SC_INV)->getPictureObjectById(PIC_CSR_HELPERBGR, 0);
 	_arcadeOverlay = accessScene(SC_INV)->getPictureObjectById(picId, 0);
 
-	_arcadeOverlay->getDimensions(&point);
-	_arcadeOverlayHelper->getDimensions(&point2);
+	const Dims dims = _arcadeOverlay->getDimensions();
+	const Dims dims2 = _arcadeOverlayHelper->getDimensions();
 
-	_arcadeOverlayMidX = (point2.x - point.x) / 2;
-	_arcadeOverlayMidY = abs(point2.y - point.y) / 2;
+	// TODO: Only Y gets abs?
+	_arcadeOverlayMidX = (dims2.x - dims.x) / 2;
+	_arcadeOverlayMidY = abs(dims2.y - dims.y) / 2;
 }
 
 int FullpipeEngine::drawArcadeOverlay(int adjust) {
diff --git a/engines/fullpipe/inventory.cpp b/engines/fullpipe/inventory.cpp
index 345a02c..9d6152d 100644
--- a/engines/fullpipe/inventory.cpp
+++ b/engines/fullpipe/inventory.cpp
@@ -256,8 +256,6 @@ void Inventory2::rebuildItemRects() {
 	}
 
 	for (uint i = 0; i < _inventoryItems.size(); i++) {
-		Common::Point point;
-
 		int idx = getInventoryPoolItemIndexById(_inventoryItems[i]->itemId);
 
 		InventoryIcon *icn = new InventoryIcon();
@@ -268,19 +266,19 @@ void Inventory2::rebuildItemRects() {
 		icn->pictureObjectHover = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectHover, 0);
 		icn->pictureObjectSelected = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectSelected, 0);
 
-		icn->pictureObjectNormal->getDimensions(&point);
+		const Dims dims = icn->pictureObjectNormal->getDimensions();
 
 		if (_itemsPool[idx]->flags & 0x10000) {
 			icn->x1 = 730;
 			icn->y1 = itemY;
-			icn->x2 = point.x + 730;
-			icn->y2 = point.y + itemY + 10;
+			icn->x2 = dims.x + 730;
+			icn->y2 = dims.y + itemY + 10;
 		} else {
 			icn->x1 = itemX;
 			icn->y1 = itemY;
-			icn->x2 = itemX + point.x;
+			icn->x2 = itemX + dims.x;
 			itemX = icn->x2 + 1;
-			icn->y2 = point.y + itemY + 10;
+			icn->y2 = dims.y + itemY + 10;
 		}
 
 		_inventoryIcons.push_back(icn);
diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp
index 6589ba6..68f0455 100644
--- a/engines/fullpipe/modal.cpp
+++ b/engines/fullpipe/modal.cpp
@@ -525,12 +525,10 @@ bool ModalMap::init2(int counterdiff) {
 
 				g_fp->playSound(SND_CMN_070, 0);
 			} else {
-				Common::Point p1, p2;
+				const Dims d1 = _picI03->getDimensions();
+				const Dims d2 = _highlightedPic->getDimensions();
 
-				_picI03->getDimensions(&p1);
-				_highlightedPic->getDimensions(&p2);
-
-				_picI03->setOXY(_highlightedPic->_ox + p2.x / 2 - p1.x / 2, _highlightedPic->_oy + p2.y / 2 - p1.y / 2);
+				_picI03->setOXY(_highlightedPic->_ox + d2.x / 2 - d1.x / 2, _highlightedPic->_oy + d2.y / 2 - d1.y / 2);
 				_picI03->_flags |= 4;
 			}
 		}
@@ -644,14 +642,12 @@ void ModalMap::initMap() {
 
 	pic = getScenePicture(g_fp->_currentScene->_sceneId);
 
-	Common::Point point;
-	Common::Point point2;
-
 	if (pic) {
-		pic->getDimensions(&point);
+		const Dims dims = pic->getDimensions();
+		Dims dims2;
 
-		_rect2.left = point.x / 2 + pic->_ox - 400;
-		_rect2.top = point.y / 2 + pic->_oy - 300;
+		_rect2.left = dims.x / 2 + pic->_ox - 400;
+		_rect2.top = dims.y / 2 + pic->_oy - 300;
 		_rect2.right = _rect2.left + 800;
 		_rect2.bottom = _rect2.top + 600;
 
@@ -660,15 +656,15 @@ void ModalMap::initMap() {
 		_mapScene->updateScrolling2();
 
 		_pic = _mapScene->getPictureObjectById(PIC_MAP_I02, 0);
-		_pic->getDimensions(&point2);
+		dims2 = _pic->getDimensions();
 
-		_pic->setOXY(pic->_ox + point.x / 2 - point2.x / 2, point.y - point2.y / 2 + pic->_oy - 24);
+		_pic->setOXY(pic->_ox + dims.x / 2 - dims2.x / 2, dims.y - dims2.y / 2 + pic->_oy - 24);
 		_pic->_flags |= 4;
 
 		_pic = _mapScene->getPictureObjectById(PIC_MAP_I01, 0);
-		_pic->getDimensions(&point2);
+		dims2 = _pic->getDimensions();
 
-		_pic->setOXY(pic->_ox + point.x / 2 - point2.x / 2, point.y - point2.y / 2 + pic->_oy - 25);
+		_pic->setOXY(pic->_ox + dims.x / 2 - dims2.x / 2, dims.y - dims2.y / 2 + pic->_oy - 25);
 		_pic->_flags |= 4;
 	}
 
@@ -1134,8 +1130,6 @@ void ModalFinal::update() {
 }
 
 ModalCredits::ModalCredits() {
-	Common::Point point;
-
 	_sceneTitles = g_fp->accessScene(SC_TITLES);
 
 	_creditsPic = _sceneTitles->getPictureObjectById(PIC_TTL_CREDITS, 0);
@@ -1144,15 +1138,15 @@ ModalCredits::ModalCredits() {
 	_fadeIn = true;
 	_fadeOut = false;
 
-	_creditsPic->getDimensions(&point);
+	const Dims dims = _creditsPic->getDimensions();
 
-	_countdown = point.y / 2 + 470;
+	_countdown = dims.y / 2 + 470;
 	_sfxVolume = g_fp->_sfxVolume;
 
 	_currY = 630;
-	_maxY = -1000 - point.y;
+	_maxY = -1000 - dims.y;
 
-	_currX = 400 - point.x / 2;
+	_currX = 400 - dims.x / 2;
 
 	_creditsPic->setOXY(_currX, _currY);
 }
@@ -1641,16 +1635,14 @@ int ModalMainMenu::checkHover(Common::Point &point) {
 }
 
 bool ModalMainMenu::isOverArea(PictureObject *obj, Common::Point *point) {
-	Common::Point p;
-
-	obj->getDimensions(&p);
+	const Dims dims = obj->getDimensions();
 
 	int left = point->x - 8;
 	int right = point->x + 12;
 	int down = point->y - 11;
 	int up = point->y + 9;
 
-	if (left >= obj->_ox && right < obj->_ox + p.x && down >= obj->_oy && up < obj->_oy + p.y)
+	if (left >= obj->_ox && right < obj->_ox + dims.x && down >= obj->_oy && up < obj->_oy + dims.y)
 		return true;
 
 	return false;
@@ -2091,9 +2083,7 @@ void ModalSaveGame::setup(Scene *sc, int mode) {
 	_arrayL.push_back(sc->getPictureObjectById(PIC_MSV_SPACE_D, 0));
 	_arrayD.push_back(sc->getPictureObjectById(PIC_MSV_SPACE_L, 0));
 
-	Common::Point point;
-
-	int x = _bgr->_ox + _bgr->getDimensions(&point)->x / 2;
+	int x = _bgr->_ox + _bgr->getDimensions().x / 2;
 	int y = _bgr->_oy + 90;
 	int w;
 	FileInfo *fileinfo;
@@ -2106,20 +2096,19 @@ void ModalSaveGame::setup(Scene *sc, int mode) {
 
 		if (!getFileInfo(i, fileinfo)) {
 			fileinfo->empty = true;
-			w = _emptyD->getDimensions(&point)->x;
+			w = _emptyD->getDimensions().x;
 		} else {
 			w = 0;
 
 			for (uint j = 0; j < _arrayL.size(); j++) {
-				_arrayL[j]->getDimensions(&point);
-				w += point.x + 2;
+				w += _arrayL[j]->getDimensions().x + 2;
 			}
 		}
 
 		fileinfo->fx1 = x - w / 2;
 		fileinfo->fx2 = x + w / 2;
 		fileinfo->fy1 = y;
-		fileinfo->fy2 = y + _emptyD->getDimensions(&point)->y;
+		fileinfo->fy2 = y + _emptyD->getDimensions().y;
 
 		_files.push_back(fileinfo);
 
@@ -2200,8 +2189,6 @@ void ModalSaveGame::update() {
 
 	g_fp->setCursor(g_fp->_cursorId);
 
-	Common::Point point;
-
 	for (uint i = 0; i < _files.size(); i++) {
 		if (g_fp->_mouseScreenPos.x < _files[i]->fx1 || g_fp->_mouseScreenPos.x > _files[i]->fx2 ||
 			g_fp->_mouseScreenPos.y < _files[i]->fy1 || g_fp->_mouseScreenPos.y > _files[i]->fy2 ) {
@@ -2215,7 +2202,7 @@ void ModalSaveGame::update() {
 					_arrayL[_files[i]->date[j]]->setOXY(x + 1, _files[i]->fy1);
 					_arrayL[_files[i]->date[j]]->draw();
 
-					x += _arrayL[_files[i]->date[j]]->getDimensions(&point)->x + 2;
+					x += _arrayL[_files[i]->date[j]]->getDimensions().x + 2;
 				}
 			}
 		} else {
@@ -2229,7 +2216,7 @@ void ModalSaveGame::update() {
 					_arrayD[_files[i]->date[j]]->setOXY(x + 1, _files[i]->fy1);
 					_arrayD[_files[i]->date[j]]->draw();
 
-					x += _arrayD[_files[i]->date[j]]->getDimensions(&point)->x + 2;
+					x += _arrayD[_files[i]->date[j]]->getDimensions().x + 2;
 				}
 			}
 		}
diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp
index 5297b9e..eedd266 100644
--- a/engines/fullpipe/motion.cpp
+++ b/engines/fullpipe/motion.cpp
@@ -495,7 +495,7 @@ MessageQueue *MctlLadder::makeQueue(StaticANIObject *ani, int xpos, int ypos, in
 		int ox = ani->_ox;
 		int oy = ani->_oy;
 
-		ani->_movement->calcSomeXY(point, 1, ani->_someDynamicPhaseIndex);
+		point = ani->_movement->calcSomeXY(1, ani->_someDynamicPhaseIndex);
 		ani->_statics = ani->_movement->_staticsObj2;
 		ani->_movement = 0;
 		ani->setOXY(point.x + ox, point.y + oy);
@@ -545,7 +545,7 @@ MessageQueue *MctlLadder::makeQueue(StaticANIObject *ani, int xpos, int ypos, in
 		int ox = ani->_ox;
 		int oy = ani->_oy;
 
-		ani->getMovementById(_ladmovements[pos]->movVars->varUpStop)->calcSomeXY(point, 0, -1);
+		point = ani->getMovementById(_ladmovements[pos]->movVars->varUpStop)->calcSomeXY(0, -1);
 
 		mkQueue.ani = ani;
 
@@ -583,7 +583,7 @@ MessageQueue *MctlLadder::makeQueue(StaticANIObject *ani, int xpos, int ypos, in
 		int nx = ani->_ox;
 		int ny = ani->_oy;
 
-		_aniHandler.getTransitionSize(&point, ani->_id, ani->_statics->_staticsId, _ladmovements[pos]->staticIds[0]);
+		point = _aniHandler.getTransitionSize(ani->_id, ani->_statics->_staticsId, _ladmovements[pos]->staticIds[0]);
 
 		nx += point.x;
 		ny += point.y;
@@ -609,7 +609,7 @@ MessageQueue *MctlLadder::makeQueue(StaticANIObject *ani, int xpos, int ypos, in
 		int nx = ani->_ox;
 		int ny = ani->_oy;
 
-		ani->getMovementById(_ladmovements[pos]->movVars->varDownStop)->calcSomeXY(point, 0, -1);
+		point = ani->getMovementById(_ladmovements[pos]->movVars->varDownStop)->calcSomeXY(0, -1);
 
 		nx += point.x;
 		ny += point.y;
@@ -1796,7 +1796,7 @@ bool MctlGraph::fillData(StaticANIObject *obj, MctlAni *item) {
 
 			item->_subItems[dir]._walk[act]._mov = mov;
 			if (mov) {
-				mov->calcSomeXY(point, 0, -1);
+				point = mov->calcSomeXY(0, -1);
 				item->_subItems[dir]._walk[act]._mx = point.x;
 				item->_subItems[dir]._walk[act]._my = point.y;
 			}
@@ -1826,7 +1826,7 @@ bool MctlGraph::fillData(StaticANIObject *obj, MctlAni *item) {
 
 			item->_subItems[dir]._turn[act]._mov = mov;
 			if (mov) {
-				mov->calcSomeXY(point, 0, -1);
+				point = mov->calcSomeXY(0, -1);
 				item->_subItems[dir]._turn[act]._mx = point.x;
 				item->_subItems[dir]._turn[act]._my = point.y;
 			}
@@ -1856,7 +1856,7 @@ bool MctlGraph::fillData(StaticANIObject *obj, MctlAni *item) {
 
 			item->_subItems[dir]._turnS[act]._mov = mov;
 			if (mov) {
-				mov->calcSomeXY(point, 0, -1);
+				point = mov->calcSomeXY(0, -1);
 				item->_subItems[dir]._turnS[act]._mx = point.x;
 				item->_subItems[dir]._turnS[act]._my = point.y;
 			}
@@ -2242,7 +2242,7 @@ MessageQueue *MctlGraph::makeQueue(StaticANIObject *obj, int xpos, int ypos, int
 			newx = obj->_ox;
 			newy = obj->_oy;
 		} else {
-			obj->_movement->calcSomeXY(point, 0, picAniInfo.dynamicPhaseIndex);
+			point = obj->_movement->calcSomeXY(0, picAniInfo.dynamicPhaseIndex);
 			newx = obj->_movement->_ox - point.x;
 			newy = obj->_movement->_oy - point.y;
 			if (idxsub != 1 && idxsub) {
@@ -2540,7 +2540,7 @@ MessageQueue *MctlGraph::makeLineQueue(MctlMQ *info) {
 	int a2 = 0;
 	int mgmLen;
 
-	_aniHandler.getNumCycles(&point, _items2[info->index]->_subItems[info->subIndex]._walk[1]._mov, x, y, &mgmLen, &a2, info->flags & 1);
+	point = _aniHandler.getNumCycles(_items2[info->index]->_subItems[info->subIndex]._walk[1]._mov, x, y, &mgmLen, &a2, info->flags & 1);
 
 	int x1 = point.x;
 	int y1 = point.y;
diff --git a/engines/fullpipe/scene.cpp b/engines/fullpipe/scene.cpp
index 3d39683..5e92c5f 100644
--- a/engines/fullpipe/scene.cpp
+++ b/engines/fullpipe/scene.cpp
@@ -591,13 +591,11 @@ void Scene::updateScrolling() {
 
 void Scene::updateScrolling2() {
 	if (_picObjList.size()) {
-		Common::Point point;
 		int offsetY = 0;
 		int offsetX = 0;
 
-		((PictureObject *)_picObjList[0])->getDimensions(&point);
-
-		int flags = ((PictureObject *)_picObjList[0])->_flags;
+		const Dims dims = _picObjList[0]->getDimensions();
+		const int flags = _picObjList[0]->_flags;
 
 		if (g_fp->_sceneRect.left < 0 && !(flags & 2))
 			offsetX = -g_fp->_sceneRect.left;
@@ -605,11 +603,11 @@ void Scene::updateScrolling2() {
 		if (g_fp->_sceneRect.top < 0 && !(flags & 0x20))
 			offsetY = -g_fp->_sceneRect.top;
 
-		if (g_fp->_sceneRect.right > point.x - 1 && g_fp->_sceneRect.left > 0 && !(flags & 2))
-			offsetX = point.x - g_fp->_sceneRect.right - 1;
+		if (g_fp->_sceneRect.right > dims.x - 1 && g_fp->_sceneRect.left > 0 && !(flags & 2))
+			offsetX = dims.x - g_fp->_sceneRect.right - 1;
 
-		if (g_fp->_sceneRect.bottom > point.y - 1 && g_fp->_sceneRect.top > 0 && !(flags & 0x20))
-			offsetY = point.y - g_fp->_sceneRect.bottom - 1;
+		if (g_fp->_sceneRect.bottom > dims.y - 1 && g_fp->_sceneRect.top > 0 && !(flags & 0x20))
+			offsetY = dims.y - g_fp->_sceneRect.bottom - 1;
 
 		g_fp->_sceneRect.translate(offsetX, offsetY);
 	}
@@ -694,35 +692,35 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
 
 	debugC(1, kDebugDrawing, "-> Scene::drawContent(>%d, <%d, %d)", minPri, maxPri, drawBg);
 
-	Common::Point point;
+	Dims dims;
 
 	debugC(1, kDebugDrawing, "_bigPict: %d objlist: %d", _bigPictureArray1Count, _picObjList.size());
 
 	if (drawBg && _bigPictureArray1Count && _picObjList.size()) {
 
-		_bigPictureArray[0][0]->getDimensions(&point);
+		dims = _bigPictureArray[0][0]->getDimensions();
 
-		int width = point.x;
-		int height = point.y;
+		int width = dims.x;
+		int height = dims.y;
 
 		debugC(8, kDebugDrawing, "w: %d h:%d", width, height);
 
-		((PictureObject *)_picObjList[0])->getDimensions(&point);
+		dims = _picObjList[0]->getDimensions();
 
-		debugC(8, kDebugDrawing, "w2: %d h2:%d", point.x, point.y);
+		debugC(8, kDebugDrawing, "w2: %d h2:%d", dims.x, dims.y);
 
-		int bgStX = g_fp->_sceneRect.left % point.x;
+		int bgStX = g_fp->_sceneRect.left % dims.x;
 
 		if (bgStX < 0)
-			bgStX += point.x;
+			bgStX += dims.x;
 
 		int bgNumX = bgStX / width;
 		int bgOffsetX = bgStX % width;
 
-		int bgStY = g_fp->_sceneRect.top % point.y;
+		int bgStY = g_fp->_sceneRect.top % dims.y;
 
 		if (bgStY < 0)
-			bgStY += point.y;
+			bgStY += dims.y;
 
 		int bgNumY = bgStY / height;
 		int bgOffsetY = bgStY % height;
@@ -735,7 +733,7 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
 				for (int y = g_fp->_sceneRect.top - bgOffsetY; y < g_fp->_sceneRect.bottom - 1;) {
 					BigPicture *v27 = _bigPictureArray[bgNumX][v25];
 					v27->draw(bgPosX, y, 0, 0);
-					y += v27->getDimensions(&point)->y;
+					y += v27->getDimensions().y;
 					v25++;
 
 					if (v25 >= _bigPictureArray2Count) {
@@ -744,9 +742,9 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
 						v25 = 0;
 					}
 				}
-				_bigPictureArray[bgNumX][0]->getDimensions(&point);
-				int oldx = point.x + bgPosX;
-				bgPosX += point.x;
+				dims = _bigPictureArray[bgNumX][0]->getDimensions();
+				int oldx = dims.x + bgPosX;
+				bgPosX += dims.x;
 				bgNumX++;
 
 				if (bgNumX >= _bigPictureArray1Count) {
@@ -772,10 +770,10 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
 
 		debugC(8, kDebugDrawing, "obj: %d %d", objX, objY);
 
-		obj->getDimensions(&point);
+		dims = obj->getDimensions();
 
-		int width = point.x;
-		int height = point.y;
+		int width = dims.x;
+		int height = dims.y;
 
 		if (obj->_flags & 8) {
 			while (objX > g_fp->_sceneRect.right) {
diff --git a/engines/fullpipe/scenes.cpp b/engines/fullpipe/scenes.cpp
index 7825a1e..896ea5a 100644
--- a/engines/fullpipe/scenes.cpp
+++ b/engines/fullpipe/scenes.cpp
@@ -539,7 +539,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
 	if (!scene)
 		return 0;
 
-	((PictureObject *)scene->_picObjList.front())->getDimensions(&sceneDim);
+	sceneDim = scene->_picObjList.front()->getDimensions();
 	_sceneWidth = sceneDim.x;
 	_sceneHeight = sceneDim.y;
 
diff --git a/engines/fullpipe/scenes/scene04.cpp b/engines/fullpipe/scenes/scene04.cpp
index 0e50400..228fc77 100644
--- a/engines/fullpipe/scenes/scene04.cpp
+++ b/engines/fullpipe/scenes/scene04.cpp
@@ -1003,9 +1003,7 @@ void sceneHandler04_springWobble() {
 		}
 	}
 
-	Common::Point point;
-
-	int oldpos = g_vars->scene04_spring->getCurrDimensions(point)->y - oldDynIndex;
+	int oldpos = g_vars->scene04_spring->getCurrDimensions().y - oldDynIndex;
 
 	if (g_vars->scene04_dynamicPhaseIndex) {
 		if (!g_vars->scene04_spring->_movement)
@@ -1017,7 +1015,7 @@ void sceneHandler04_springWobble() {
 	}
 
 	if (g_vars->scene04_dynamicPhaseIndex != oldDynIndex) {
-		sceneHandler04_bottleUpdateObjects(oldpos - (g_vars->scene04_spring->getCurrDimensions(point)->y - g_vars->scene04_dynamicPhaseIndex));
+		sceneHandler04_bottleUpdateObjects(oldpos - (g_vars->scene04_spring->getCurrDimensions().y - g_vars->scene04_dynamicPhaseIndex));
 	}
 }
 
@@ -1316,8 +1314,6 @@ void sceneHandler04_testPlank(ExCommand *ex) {
 }
 
 void sceneHandler04_updateBottle() {
-	Common::Point point;
-
 	int yoff;
 
 	if (g_vars->scene04_hand->_movement)
@@ -1325,7 +1321,7 @@ void sceneHandler04_updateBottle() {
 	else
 		yoff = g_vars->scene04_hand->_oy;
 
-	int newy = g_vars->scene04_hand->getSomeXY(point)->y + yoff + 140;
+	int newy = g_vars->scene04_hand->getSomeXY().y + yoff + 140;
 
 	sceneHandler04_bottleUpdateObjects(newy - g_vars->scene04_spring->_oy);
 
diff --git a/engines/fullpipe/scenes/scene06.cpp b/engines/fullpipe/scenes/scene06.cpp
index a6d93b6..4e003c6 100644
--- a/engines/fullpipe/scenes/scene06.cpp
+++ b/engines/fullpipe/scenes/scene06.cpp
@@ -437,23 +437,23 @@ void sceneHandler06_catchBall() {
 
 			if (g_vars->scene06_mumsy->_movement->_id == MV_MOM_JUMPFW) {
 				if (g_vars->scene06_mumsy->_movement->_currDynamicPhaseIndex <= 5) {
-					g_vars->scene06_mumsy->_movement->calcSomeXY(point, 0, g_vars->scene06_mumsy->_movement->_currDynamicPhaseIndex);
+					point = g_vars->scene06_mumsy->_movement->calcSomeXY(0, g_vars->scene06_mumsy->_movement->_currDynamicPhaseIndex);
 
 					point.x = -point.x;
 					point.y = -point.y;
 				} else {
-					g_vars->scene06_mumsy->_movement->calcSomeXY(point, 1, -1);
+					point = g_vars->scene06_mumsy->_movement->calcSomeXY(1, -1);
 
 					g_vars->scene06_mumsyPos++;
 				}
 			} else if (g_vars->scene06_mumsy->_movement->_id == MV_MOM_JUMPBK) {
 				if (g_vars->scene06_mumsy->_movement->_currDynamicPhaseIndex <= 4) {
-					g_vars->scene06_mumsy->_movement->calcSomeXY(point, 0, g_vars->scene06_mumsy->_movement->_currDynamicPhaseIndex);
+					point = g_vars->scene06_mumsy->_movement->calcSomeXY(0, g_vars->scene06_mumsy->_movement->_currDynamicPhaseIndex);
 
 					point.x = -point.x;
 					point.y = -point.y;
 				} else {
-					g_vars->scene06_mumsy->_movement->calcSomeXY(point, 1, -1);
+					point = g_vars->scene06_mumsy->_movement->calcSomeXY(1, -1);
 
 					g_vars->scene06_mumsyPos--;
 				}
diff --git a/engines/fullpipe/scenes/scene08.cpp b/engines/fullpipe/scenes/scene08.cpp
index 24b23c1..00f8f93 100644
--- a/engines/fullpipe/scenes/scene08.cpp
+++ b/engines/fullpipe/scenes/scene08.cpp
@@ -193,9 +193,7 @@ int sceneHandler08_calcOffset(int off, int flag) {
 }
 
 void sceneHandler08_pushCallback(int *par) {
-	Common::Point point;
-
-	int y = g_fp->_aniMan->_oy + g_fp->_aniMan->getSomeXY(point)->y;
+	int y = g_fp->_aniMan->_oy + g_fp->_aniMan->getSomeXY().y;
 
 	if (g_fp->_aniMan->_statics && g_fp->_aniMan->_statics->_staticsId == ST_MAN8_FLYDOWN)
 		y -= 25;
@@ -253,7 +251,7 @@ void sceneHandler08_airMoves() {
 		int y = g_fp->_aniMan->_oy;
 		Common::Point point;
 
-		if (703 - g_fp->_aniMan->getSomeXY(point)->y - y < 150) {
+		if (703 - g_fp->_aniMan->getSomeXY().y - y < 150) {
 			if (g_fp->_aniMan->_statics) {
 				if (g_fp->_aniMan->_statics->_staticsId == ST_MAN8_FLYDOWN) {
 					y -= 25;
@@ -358,7 +356,7 @@ void sceneHandler08_calcFlight() {
 	if (g_vars->scene08_manOffsetY < g_vars->scene08_stairsOffset)
 		g_vars->scene08_manOffsetY = g_vars->scene08_stairsOffset;
 
-	y = y + g_fp->_aniMan->getSomeXY(point)->y;
+	y = y + g_fp->_aniMan->getSomeXY().y;
 
 	if (g_fp->_aniMan->_statics && g_fp->_aniMan->_statics->_staticsId == ST_MAN8_FLYDOWN)
 		y -= 25;
diff --git a/engines/fullpipe/scenes/scene25.cpp b/engines/fullpipe/scenes/scene25.cpp
index 83a0ee0..8323e3d 100644
--- a/engines/fullpipe/scenes/scene25.cpp
+++ b/engines/fullpipe/scenes/scene25.cpp
@@ -441,7 +441,7 @@ void sceneHandler25_walkOnLadder(StaticANIObject *ani, Common::Point *pnt, Messa
 
 	if (flag) {
 		if (ani->_movement) {
-			ani->_movement->calcSomeXY(point, 0, ani->_movement->_currDynamicPhaseIndex);
+			point = ani->_movement->calcSomeXY(0, ani->_movement->_currDynamicPhaseIndex);
 			newx = point.x;
 			aniY = ani->_oy - point.y;
 		}
@@ -478,7 +478,7 @@ void sceneHandler25_walkOnLadder(StaticANIObject *ani, Common::Point *pnt, Messa
 				newy = pnty;
 			}
 
-			ani->getMovementById(ex->_messageNum)->calcSomeXY(point, 0, -1);
+			point = ani->getMovementById(ex->_messageNum)->calcSomeXY(0, -1);
 			pntx += point.x;
 			pnty += point.y;
 		}
diff --git a/engines/fullpipe/scenes/sceneDbg.cpp b/engines/fullpipe/scenes/sceneDbg.cpp
index 2ba5977..4d061e6 100644
--- a/engines/fullpipe/scenes/sceneDbg.cpp
+++ b/engines/fullpipe/scenes/sceneDbg.cpp
@@ -48,11 +48,8 @@ GameObject *sceneHandlerDbgMenu_getObjectAtXY(int x, int y) {
 		PictureObject *pic = (PictureObject *)g_fp->_currentScene->_picObjList[i];
 
 		if (x >= pic->_ox && y >= pic->_oy) {
-			Common::Point point;
-
-			pic->getDimensions(&point);
-
-			if (x <= pic->_ox + point.x && y <= pic->_oy + point.y && pic != g_vars->selector)
+			const Dims dims = pic->getDimensions();
+			if (x <= pic->_ox + dims.x && y <= pic->_oy + dims.y && pic != g_vars->selector)
 				return pic;
 		}
 	}
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index 21b9ba8..98854f9 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -64,30 +64,27 @@ void StepArray::clear() {
 	}
 }
 
-Common::Point *StepArray::getCurrPoint(Common::Point *point) {
+Common::Point StepArray::getCurrPoint() const {
 	if (_isEos || _points == 0) {
-		point->x = 0;
-		point->y = 0;
-	} else {
-		point->x = _points[_currPointIndex]->x;
-		point->y = _points[_currPointIndex]->y;
+		return Common::Point();
 	}
-	return point;
+
+	return Common::Point(_points[_currPointIndex]->x,
+						 _points[_currPointIndex]->y);
 }
 
-Common::Point *StepArray::getPoint(Common::Point *point, int index, int offset) {
+Common::Point StepArray::getPoint(int index, int offset) const {
 	if (index == -1)
 		index = _currPointIndex;
 
 	if (index + offset > _maxPointIndex - 1)
 		offset = _maxPointIndex - index;
 
-	point->x = 0;
-	point->y = 0;
+	Common::Point point;
 
 	while (offset >= 1) {
-		point->x += _points[index]->x;
-		point->y += _points[index]->y;
+		point.x += _points[index]->x;
+		point.y += _points[index]->y;
 
 		index++;
 		offset--;
@@ -240,7 +237,7 @@ bool StaticANIObject::load(MfcArchive &file) {
 
 	Common::Point pt;
 	if (count) { // We have movements
-		_movements[0]->getCurrDynamicPhaseXY(pt);
+		pt = _movements[0]->getCurrDynamicPhaseXY();
 	} else {
 		pt.x = pt.y = 100;
 	}
@@ -476,7 +473,6 @@ bool StaticANIObject::getPixelAtPos(int x, int y, uint32 *pixel, bool hitOnly) {
 	int ongoing;
 	int xani, yani;
 	int oxani, oyani;
-	Common::Point point;
 
 	if (_movement)
 		ongoing = _movement->_currMovement != 0;
@@ -484,13 +480,13 @@ bool StaticANIObject::getPixelAtPos(int x, int y, uint32 *pixel, bool hitOnly) {
 		ongoing = _statics->_staticsId & 0x4000;
 
 	if (_movement) {
-		_movement->getCurrDynamicPhaseXY(point);
+		const Common::Point point = _movement->getCurrDynamicPhaseXY();
 		xani = point.x;
 		yani = point.y;
 		oxani = _movement->_ox;
 		oyani = _movement->_oy;
 	} else {
-		_statics->getSomeXY(point);
+		const Common::Point point = _statics->getSomeXY();
 		xani = point.x;
 		yani = point.y;
 		oxani = _ox;
@@ -501,7 +497,7 @@ bool StaticANIObject::getPixelAtPos(int x, int y, uint32 *pixel, bool hitOnly) {
 	int ytarget = y - (oyani - yani);
 
 	if (ongoing && _movement)
-		xtarget = pic->getDimensions(&point)->x - xtarget;
+		xtarget = pic->getDimensions().x - xtarget;
 
 	x = pic->_x;
 	y = pic->_y;
@@ -527,9 +523,7 @@ bool StaticANIObject::getPixelAtPos(int x, int y, uint32 *pixel, bool hitOnly) {
 void Movement::draw(bool flipFlag, int angle) {
 	debugC(3, kDebugDrawing, "Movement::draw(%d, %d)", flipFlag, angle);
 
-	Common::Point point;
-
-	getCurrDynamicPhaseXY(point);
+	Common::Point point = getCurrDynamicPhaseXY();
 
 	int x = _ox - point.x;
 	int y = _oy - point.y;
@@ -601,13 +595,12 @@ void StaticANIObject::draw() {
 	if ((_flags & 4) == 0)
 		return;
 
-	Common::Point point;
 	Common::Rect rect;
 
 	debugC(6, kDebugDrawing, "StaticANIObject::draw() (%s) [%d] [%d, %d]", transCyrillic(_objectName), _id, _ox, _oy);
 
 	if (_shadowsOn && g_fp->_currentScene && g_fp->_currentScene->_shadows
-		&& (getCurrDimensions(point)->x != 1 || getCurrDimensions(point)->y != 1)) {
+		&& (getCurrDimensions().x != 1 || getCurrDimensions().y != 1)) {
 
 		DynamicPhase *dyn;
 
@@ -626,16 +619,16 @@ void StaticANIObject::draw() {
 
 			DynamicPhase *shd = g_fp->_currentScene->_shadows->findSize(rect.width(), rect.height());
 			if (shd) {
-				shd->getDimensions(&point);
-				int midx = _ox - point.x / 2 - dyn->_someX;
-				int midy = _oy - point.y / 2 - dyn->_someY + rect.bottom - 3;
-				int shdw =  point.y;
+				const Dims dims = shd->getDimensions();
+				int midx = _ox - dims.x / 2 - dyn->_someX;
+				int midy = _oy - dims.y / 2 - dyn->_someY + rect.bottom - 3;
+				int shdw =  dims.y;
 
 				int px;
 				if (!_movement || (_flags & 0x20))
-					px = _statics->getCenter(&point)->x;
+					px = _statics->getCenter().x;
 				else
-					px = _movement->getCenter(&point)->x;
+					px = _movement->getCenter().x;
 
 				if (_shadowsOn != 1)
 					midy = _shadowsOn - shdw / 2;
@@ -654,7 +647,7 @@ void StaticANIObject::draw() {
 	}
 
 	if (!_movement || (_flags & 0x20)) {
-		_statics->getSomeXY(point);
+		const Common::Point point = _statics->getSomeXY();
 		_statics->_x = _ox - point.x;
 		_statics->_y = _oy - point.y;
 		_statics->draw(_statics->_x, _statics->_y, 0, angle);
@@ -670,10 +663,7 @@ void StaticANIObject::draw2() {
 		if (_movement) {
 			_movement->draw(1, 0);
 		} else {
-			Common::Point point;
-
-			_statics->getSomeXY(point);
-
+			const Common::Point point = _statics->getSomeXY();
 			_statics->draw(_ox - point.x, _oy - point.y, 1, 0);
 		}
 	}
@@ -751,7 +741,7 @@ void StaticANIObject::preloadMovements(MovTable *mt) {
 	}
 }
 
-Common::Point *StaticANIObject::getCurrDimensions(Common::Point &p) {
+Dims StaticANIObject::getCurrDimensions() const {
 	Picture *pic;
 
 	if (_movement)
@@ -760,30 +750,21 @@ Common::Point *StaticANIObject::getCurrDimensions(Common::Point &p) {
 		pic = _statics;
 
 	if (pic) {
-		Common::Point point;
-
-		pic->getDimensions(&point);
-		p.x = point.x;
-		p.y = point.y;
-	} else {
-		p.x = 0;
-		p.y = 0;
+		return pic->getDimensions();
 	}
 
-	return &p;
+	return Dims();
 }
 
-Common::Point *StaticANIObject::getSomeXY(Common::Point &p) {
+Common::Point StaticANIObject::getSomeXY() const {
 	if (_movement) {
-		_movement->getCurrDynamicPhaseXY(p);
-
-		return &p;
+		return _movement->getCurrDynamicPhaseXY();
 	}
 
 	if (_statics)
-		_statics->getSomeXY(p);
+		return _statics->getSomeXY();
 
-	return &p;
+	error("No someXY found");
 }
 
 void StaticANIObject::update(int counterdiff) {
@@ -804,7 +785,6 @@ void StaticANIObject::update(int counterdiff) {
 		return;
 	}
 
-	Common::Point point;
 	ExCommand *ex, *newex;
 
 	if (_movement) {
@@ -870,7 +850,7 @@ void StaticANIObject::update(int counterdiff) {
 			if (!_movement)
 				return;
 
-			_stepArray.getCurrPoint(&point);
+			const Common::Point point = _stepArray.getCurrPoint();
 			setOXY(point.x + _ox, point.y + _oy);
 			_stepArray.gotoNextPoint();
 			if (_someDynamicPhaseIndex == _movement->_currDynamicPhaseIndex)
@@ -880,10 +860,9 @@ void StaticANIObject::update(int counterdiff) {
 			_flags |= 1;
 
 			_movement->gotoFirstFrame();
-			_movement->getCurrDynamicPhaseXY(point);
 
-			Common::Point pointS;
-			_statics->getSomeXY(pointS);
+			const Common::Point point = _movement->getCurrDynamicPhaseXY();
+			const Common::Point pointS = _statics->getSomeXY();
 			_movement->setOXY(_ox + point.x + _movement->_mx - pointS.x,
 							  _oy + point.y + _movement->_my - pointS.y);
 		}
@@ -908,11 +887,11 @@ void StaticANIObject::updateStepPos() {
 	int ox = _movement->_ox;
 	int oy = _movement->_oy;
 
-	_movement->calcSomeXY(point, 1, _someDynamicPhaseIndex);
+	point = _movement->calcSomeXY(1, _someDynamicPhaseIndex);
 	int x = point.x;
 	int y = point.y;
 
-	_stepArray.getPoint(&point, -1, _stepArray.getPointsCount());
+	point = _stepArray.getPoint(-1, _stepArray.getPointsCount());
 	x += point.x;
 	y += point.y;
 
@@ -930,9 +909,7 @@ Common::Point *StaticANIObject::calcNextStep(Common::Point *pRes) {
 		return pRes;
 	}
 
-	Common::Point point;
-
-	_movement->calcSomeXY(point, 1, _someDynamicPhaseIndex);
+	Common::Point point = _movement->calcSomeXY(1, _someDynamicPhaseIndex);
 
 	int resX = point.x;
 	int resY = point.y;
@@ -948,7 +925,7 @@ Common::Point *StaticANIObject::calcNextStep(Common::Point *pRes) {
 	}
 
 	if (pointN >= 0) {
-		_stepArray.getPoint(&point, pointN, offset);
+		point = _stepArray.getPoint(pointN, offset);
 
 		resX += point.x;
 		resY += point.y;
@@ -981,18 +958,18 @@ void StaticANIObject::stopAnim_maybe() {
 					goto L11;
 L8:
 				_statics = _movement->_staticsObj1;
-				_movement->getCurrDynamicPhaseXY(point);
+				point = _movement->getCurrDynamicPhaseXY();
 				_ox -= point.x;
 				_oy -= point.y;
 
 				_ox -= _movement->_mx;
 				_oy -= _movement->_my;
 
-				_statics->getSomeXY(point);
+				point = _statics->getSomeXY();
 				if (_movement->_currMovement) {
 					_oy += point.y;
 					_ox -= point.x;
-					_ox += _statics->getDimensions(&point)->x;
+					_ox += _statics->getDimensions().x;
 				} else {
 					_ox += point.x;
 					_oy += point.y;
@@ -1005,7 +982,7 @@ L8:
 L11:
 		_statics = _movement->_staticsObj2;
 L12:
-		_statics->getSomeXY(point);
+		point = _statics->getSomeXY();
 
 		_statics->_x = _ox - point.x;
 		_statics->_y = _oy - point.y;
@@ -1036,11 +1013,11 @@ void StaticANIObject::adjustSomeXY() {
 	if (_movement) {
 		Common::Point point;
 
-		_movement->calcSomeXY(point, 0, -1);
+		point = _movement->calcSomeXY(0, -1);
 
 		int diff = abs(point.y) - abs(point.x);
 
-		_movement->calcSomeXY(point, 1, -1);
+		point = _movement->calcSomeXY(1, -1);
 
 		if (diff > 0)
 			_ox += point.x;
@@ -1131,9 +1108,7 @@ void StaticANIObject::show1(int x, int y, int movId, int mqId) {
 
 	_statics = mov->_staticsObj1;
 
-	Common::Point point;
-
-	mov->_staticsObj1->getSomeXY(point);
+	const Common::Point point = mov->_staticsObj1->getSomeXY();
 	_statics->_x = x - point.x;
 	_statics->_y = y - point.y;
 
@@ -1173,13 +1148,11 @@ void StaticANIObject::show2(int x, int y, int movementId, int mqId) {
 			mov->setOXY(x, y);
 			mov->gotoFirstFrame();
 
-			Common::Point point;
-
-			mov->getCurrDynamicPhaseXY(point);
+			Common::Point point = mov->getCurrDynamicPhaseXY();
 			_statics->_x = mov->_ox - point.x - mov->_mx;
 			_statics->_y = mov->_oy - point.y - mov->_my;
 
-			_statics->getSomeXY(point);
+			point = _statics->getSomeXY();
 			_flags |= 4;
 			_ox = _statics->_x + point.x;
 			_oy = _statics->_y + point.y;
@@ -1227,9 +1200,7 @@ void StaticANIObject::startAnimSteps(int movementId, int messageQueueId, int x,
 	if (_movement || !_statics)
 		return;
 
-	Common::Point point;
-
-	_statics->getSomeXY(point);
+	Common::Point point = _statics->getSomeXY();
 
 	int newx = _ox - point.x;
 	int newy = _oy - point.y;
@@ -1246,7 +1217,7 @@ void StaticANIObject::startAnimSteps(int movementId, int messageQueueId, int x,
 
 	if (!(_flags & 0x40)) {
 		if (!_movement->_currDynamicPhaseIndex) {
-			_stepArray.getCurrPoint(&point);
+			point = _stepArray.getCurrPoint();
 			newx += point.x + _movement->_mx;
 			newy += point.y + _movement->_my;
 			_stepArray.gotoNextPoint();
@@ -1264,7 +1235,7 @@ void StaticANIObject::startAnimSteps(int movementId, int messageQueueId, int x,
 		}
 	}
 
-	_movement->getCurrDynamicPhaseXY(point);
+	point = _movement->getCurrDynamicPhaseXY();
 	setOXY(point.x + newx, point.y + newy);
 
 	if ((_movement->_staticsObj2->_staticsId >> 8) & 0x40)
@@ -1332,13 +1303,13 @@ bool StaticANIObject::startAnim(int movementId, int messageQueueId, int dynPhase
 	Common::Point point;
 
 	if (_movement) {
-		_movement->getCurrDynamicPhaseXY(point);
+		point = _movement->getCurrDynamicPhaseXY();
 
 		newx -= point.x;
 		newy -= point.y;
 
 	} else if (_statics) {
-		_statics->getSomeXY(point);
+		point = _statics->getSomeXY();
 
 		newx -= point.x;
 		newy -= point.y;
@@ -1355,7 +1326,7 @@ bool StaticANIObject::startAnim(int movementId, int messageQueueId, int dynPhase
 
 	if (!(_flags & 0x40)) {
 		if (!_movement->_currDynamicPhaseIndex) {
-			_stepArray.getCurrPoint(&point);
+			point = _stepArray.getCurrPoint();
 			newx += point.x + _movement->_mx;
 			newy += point.y + _movement->_my;
 
@@ -1372,7 +1343,7 @@ bool StaticANIObject::startAnim(int movementId, int messageQueueId, int dynPhase
 		}
 	}
 
-	_movement->getCurrDynamicPhaseXY(point);
+	point = _movement->getCurrDynamicPhaseXY();
 	setOXY(point.x + newx, point.y + newy);
 
 	if (_movement->_staticsObj2->_staticsId & 0x4000)
@@ -1405,7 +1376,7 @@ Common::Point *StaticANIObject::calcStepLen(Common::Point *p) {
 	if (_movement) {
 		Common::Point point;
 
-		_movement->calcSomeXY(point, 0, _movement->_currDynamicPhaseIndex);
+		point = _movement->calcSomeXY(0, _movement->_currDynamicPhaseIndex);
 
 		p->x = point.x;
 		p->y = point.y;
@@ -1413,8 +1384,7 @@ Common::Point *StaticANIObject::calcStepLen(Common::Point *p) {
 		int idx = _stepArray.getCurrPointIndex() - _movement->_currDynamicPhaseIndex - 1;
 
 		if (idx >= 0) {
-			_stepArray.getPoint(&point, idx, _movement->_currDynamicPhaseIndex + 2);
-
+			point = _stepArray.getPoint(idx, _movement->_currDynamicPhaseIndex + 2);
 			p->x += point.x;
 			p->y += point.y;
 		}
@@ -1479,29 +1449,22 @@ void Statics::init() {
 	}
 }
 
-Common::Point *Statics::getSomeXY(Common::Point &p) {
-	p.x = _someX;
-	p.y = _someY;
-
-	return &p;
+Common::Point Statics::getSomeXY() const {
+	return Common::Point(_someX, _someY);
 }
 
-Common::Point *Statics::getCenter(Common::Point *p) {
+Common::Point Statics::getCenter() const {
 	Common::Rect rect;
 
 	rect = *_rect;
 
 	if (_staticsId & 0x4000) {
-		Common::Point point;
-
-		getDimensions(&point);
-		rect.moveTo(point.x - _rect->right, _rect->top);
+		const Dims dims = getDimensions();
+		rect.moveTo(dims.x - _rect->right, _rect->top);
 	}
 
-	p->x = rect.left + _rect->width() / 2;
-	p->y = rect.top + _rect->height() / 2;
-
-	return p;
+	return Common::Point(rect.left + _rect->width() / 2,
+						 rect.top + _rect->height() / 2);
 }
 
 Movement::Movement() {
@@ -1766,14 +1729,11 @@ bool Movement::load(MfcArchive &file, StaticANIObject *ani) {
 	return true;
 }
 
-Common::Point *Movement::getCurrDynamicPhaseXY(Common::Point &p) {
-	p.x = _currDynamicPhase->_someX;
-	p.y = _currDynamicPhase->_someY;
-
-	return &p;
+Common::Point Movement::getCurrDynamicPhaseXY() const {
+	return Common::Point(_currDynamicPhase->_someX, _currDynamicPhase->_someY);
 }
 
-Common::Point *Movement::calcSomeXY(Common::Point &p, int idx, int dynidx) {
+Common::Point Movement::calcSomeXY(int idx, int dynidx) {
 	int oldox = _ox;
 	int oldoy = _oy;
 	int oldidx = _currDynamicPhaseIndex;
@@ -1782,9 +1742,7 @@ Common::Point *Movement::calcSomeXY(Common::Point &p, int idx, int dynidx) {
 	int y = 0;
 
 	if (!idx) {
-		Common::Point point;
-
-		_staticsObj1->getSomeXY(point);
+		const Common::Point point = _staticsObj1->getSomeXY();
 		int x1 = _mx - point.x;
 		int y1 = _my - point.y;
 
@@ -1799,13 +1757,12 @@ Common::Point *Movement::calcSomeXY(Common::Point &p, int idx, int dynidx) {
 	while (_currDynamicPhaseIndex != dynidx && gotoNextFrame(0, 0))
 		;
 
-	p.x = _ox;
-	p.y = _oy;
+	Common::Point p(_ox, _oy);
 
 	setDynamicPhaseIndex(oldidx);
 	setOXY(oldox, oldoy);
 
-	return &p;
+	return p;
 }
 
 void Movement::setAlpha(int alpha) {
@@ -1819,7 +1776,7 @@ void Movement::setAlpha(int alpha) {
 		}
 }
 
-Common::Point *Movement::getDimensionsOfPhase(Common::Point *p, int phaseIndex) {
+Dims Movement::getDimensionsOfPhase(int phaseIndex) const {
 	int idx = phaseIndex;
 
 	if (idx == -1)
@@ -1832,13 +1789,7 @@ Common::Point *Movement::getDimensionsOfPhase(Common::Point *p, int phaseIndex)
 	else
 		dyn = _dynamicPhases[idx];
 
-	Common::Point point;
-
-	dyn->getDimensions(&point);
-
-	*p = point;
-
-	return p;
+	return dyn->getDimensions();
 }
 
 void Movement::initStatics(StaticANIObject *ani) {
@@ -1857,9 +1808,9 @@ void Movement::initStatics(StaticANIObject *ani) {
 
 	Common::Point point;
 
-	int x1 = _currMovement->_staticsObj1->getDimensions(&point)->x - _mx;
+	int x1 = _currMovement->_staticsObj1->getDimensions().x - _mx;
 
-	_mx = x1 - _currMovement->_currDynamicPhase->getDimensions(&point)->x;
+	_mx = x1 - _currMovement->_currDynamicPhase->getDimensions().x;
 
 	_currMovement->setDynamicPhaseIndex(_currMovement->_currDynamicPhaseIndex);
 
@@ -1867,8 +1818,8 @@ void Movement::initStatics(StaticANIObject *ani) {
 	_m2y = _currMovement->_m2y;
 	_currMovement->gotoLastFrame();
 
-	x1 = _currMovement->_staticsObj2->getDimensions(&point)->x;
-	_m2x = _currMovement->_currDynamicPhase->getDimensions(&point)->x - _m2x - x1;
+	x1 = _currMovement->_staticsObj2->getDimensions().x;
+	_m2x = _currMovement->_currDynamicPhase->getDimensions().x - _m2x - x1;
 }
 
 void Movement::updateCurrDynamicPhase() {
@@ -2011,16 +1962,14 @@ bool Movement::gotoNextFrame(void (*callback1)(int, Common::Point *point, int, i
 		return true;
 	}
 
-	Common::Point point;
-
-	getCurrDynamicPhaseXY(point);
+	Common::Point point = getCurrDynamicPhaseXY();
 	_ox -= point.x;
 	_oy -= point.y;
 
 	int deltax = 0;
 
 	if (_currMovement)
-		deltax = _currMovement->getDimensionsOfPhase(&point, _currDynamicPhaseIndex)->x;
+		deltax = _currMovement->getDimensionsOfPhase(_currDynamicPhaseIndex).x;
 
 	int oldDynIndex = _currDynamicPhaseIndex;
 
@@ -2048,25 +1997,25 @@ bool Movement::gotoNextFrame(void (*callback1)(int, Common::Point *point, int, i
 				_ox += deltax - point.x;
 				_oy += point.y;
 
-				_ox -= _currMovement->getDimensionsOfPhase(&point, _currDynamicPhaseIndex)->x;
+				_ox -= _currMovement->getDimensionsOfPhase(_currDynamicPhaseIndex).x;
 			} else if (oldDynIndex >= _currDynamicPhaseIndex) {
 				while (oldDynIndex > _currDynamicPhaseIndex) {
 					_ox += deltax;
-					deltax = _currMovement->getDimensionsOfPhase(&point, oldDynIndex)->x;
+					deltax = _currMovement->getDimensionsOfPhase(oldDynIndex).x;
 
 					_ox += _currMovement->_framePosOffsets[oldDynIndex]->x;
 					_oy -= _currMovement->_framePosOffsets[oldDynIndex]->y;
 					oldDynIndex--;
 
-					_ox -= _currMovement->getDimensionsOfPhase(&point, oldDynIndex)->x;
+					_ox -= _currMovement->getDimensionsOfPhase(oldDynIndex).x;
 				}
 			} else {
 				for (int i = oldDynIndex + 1; i <= _currDynamicPhaseIndex; i++) {
 					_ox += deltax;
-					deltax = _currMovement->getDimensionsOfPhase(&point, i)->x;
+					deltax = _currMovement->getDimensionsOfPhase(i).x;
 					_ox -= _currMovement->_framePosOffsets[i]->x;
 					_oy += _currMovement->_framePosOffsets[i]->y;
-					_ox -= _currMovement->getDimensionsOfPhase(&point, i)->x;
+					_ox -= _currMovement->getDimensionsOfPhase(i).x;
 				}
 			}
 		}
@@ -2103,7 +2052,7 @@ bool Movement::gotoNextFrame(void (*callback1)(int, Common::Point *point, int, i
 	}
 
 	updateCurrDynamicPhase();
-	getCurrDynamicPhaseXY(point);
+	point = getCurrDynamicPhaseXY();
 	_ox += point.x;
 	_oy += point.y;
 
@@ -2120,16 +2069,14 @@ bool Movement::gotoPrevFrame() {
 		return false;
 	}
 
-	Common::Point point;
-
-	getCurrDynamicPhaseXY(point);
+	Common::Point point = getCurrDynamicPhaseXY();
 
 	_ox -= point.x;
 	_oy -= point.y;
 
 	if (_currMovement) {
 		if (_currMovement->_framePosOffsets) {
-			_ox += _currMovement->getDimensionsOfPhase(&point, _currDynamicPhaseIndex)->x;
+			_ox += _currMovement->getDimensionsOfPhase(_currDynamicPhaseIndex).x;
 			_ox += _currMovement->_framePosOffsets[_currDynamicPhaseIndex]->x;
 			_oy -= _currMovement->_framePosOffsets[_currDynamicPhaseIndex]->y;
 		}
@@ -2138,7 +2085,7 @@ bool Movement::gotoPrevFrame() {
 		if (_currDynamicPhaseIndex < 0)
 			_currDynamicPhaseIndex = _currMovement->_dynamicPhases.size() - 1;
 
-		_ox -= _currMovement->getDimensionsOfPhase(&point, _currDynamicPhaseIndex)->x;
+		_ox -= _currMovement->getDimensionsOfPhase(_currDynamicPhaseIndex).x;
 	} else {
 		if (_framePosOffsets) {
 			_ox -= _framePosOffsets[_currDynamicPhaseIndex]->x;
@@ -2151,7 +2098,7 @@ bool Movement::gotoPrevFrame() {
 	}
 
 	updateCurrDynamicPhase();
-	getCurrDynamicPhaseXY(point);
+	point = getCurrDynamicPhaseXY();
 
 	_ox += point.x;
 	_oy += point.y;
@@ -2180,23 +2127,18 @@ void Movement::gotoLastFrame() {
 	}
 }
 
-Common::Point *Movement::getCenter(Common::Point *p) {
+Common::Point Movement::getCenter() const {
 	Common::Rect rect;
 
 	rect = *_currDynamicPhase->_rect;
 
 	if (_currMovement) {
-		Common::Point point;
-
-		_currMovement->getDimensionsOfPhase(&point, _currDynamicPhaseIndex);
-
-		rect.moveTo(point.x - _currDynamicPhase->_rect->right, _currDynamicPhase->_rect->top);
+		const Dims dims = _currMovement->getDimensionsOfPhase(_currDynamicPhaseIndex);
+		rect.moveTo(dims.x - _currDynamicPhase->_rect->right, _currDynamicPhase->_rect->top);
 	}
 
-	p->x = rect.left + _currDynamicPhase->_rect->width() / 2;
-	p->y = rect.top + _currDynamicPhase->_rect->height() / 2;
-
-	return p;
+	return Common::Point(rect.left + _currDynamicPhase->_rect->width() / 2,
+						 rect.top + _currDynamicPhase->_rect->height() / 2);
 }
 
 DynamicPhase::DynamicPhase() {
diff --git a/engines/fullpipe/statics.h b/engines/fullpipe/statics.h
index f19d981..71137dd 100644
--- a/engines/fullpipe/statics.h
+++ b/engines/fullpipe/statics.h
@@ -44,8 +44,8 @@ class StepArray : public CObject {
 	int getCurrPointIndex() { return _currPointIndex; }
 	int getPointsCount() { return _maxPointIndex; }
 
-	Common::Point *getCurrPoint(Common::Point *point);
-	Common::Point *getPoint(Common::Point *point, int index, int offset);
+	Common::Point getCurrPoint() const;
+	Common::Point getPoint(int index, int offset) const;
 	bool gotoNextPoint();
 	void insertPoints(Common::Point **points, int pointsCount);
 };
@@ -101,8 +101,8 @@ class Statics : public DynamicPhase {
 	virtual void init();
 	Statics *getStaticsById(int itemId);
 
-	Common::Point *getSomeXY(Common::Point &p);
-	Common::Point *getCenter(Common::Point *p);
+	Common::Point getSomeXY() const;
+	Common::Point getCenter() const;
 };
 
 class StaticANIObject;
@@ -142,11 +142,11 @@ class Movement : public GameObject {
 	virtual bool load(MfcArchive &file);
 	bool load(MfcArchive &file, StaticANIObject *ani);
 
-	Common::Point *getCurrDynamicPhaseXY(Common::Point &p);
-	Common::Point *getCenter(Common::Point *p);
-	Common::Point *getDimensionsOfPhase(Common::Point *p, int phaseIndex);
+	Common::Point getCurrDynamicPhaseXY() const;
+	Common::Point getCenter() const;
+	Dims getDimensionsOfPhase(int phaseIndex) const;
 
-	Common::Point *calcSomeXY(Common::Point &p, int idx, int dynidx);
+	Common::Point calcSomeXY(int idx, int dynidx);
 
 	void initStatics(StaticANIObject *ani);
 	void updateCurrDynamicPhase();
@@ -208,9 +208,9 @@ public:
 	Movement *getMovementById(int id);
 	int getMovementIdById(int itemId);
 	Movement *getMovementByName(const Common::String &name);
-	Common::Point *getCurrDimensions(Common::Point &p);
+	Common::Point getCurrDimensions() const;
 
-	Common::Point *getSomeXY(Common::Point &p);
+	Common::Point getSomeXY() const;
 
 	void clearFlags();
 	void setFlags40(bool state);


Commit: 8e0c53de180d2e0de613934f1dedbfd4aa5fdf7c
    https://github.com/scummvm/scummvm/commit/8e0c53de180d2e0de613934f1dedbfd4aa5fdf7c
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix whitespace errors

Changed paths:
    engines/fullpipe/gfx.cpp
    engines/fullpipe/statics.cpp
    engines/fullpipe/utils.h


diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp
index 95609a3..f227e13 100644
--- a/engines/fullpipe/gfx.cpp
+++ b/engines/fullpipe/gfx.cpp
@@ -512,7 +512,7 @@ bool Picture::load(MfcArchive &file) {
 		setAOIDs();
 	}
 
-	assert (g_fp->_gameProjectVersion >= 12);
+	assert(g_fp->_gameProjectVersion >= 12);
 
 	_alpha = file.readUint32LE() & 0xff;
 
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index 98854f9..a78131d 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -1497,7 +1497,7 @@ Movement::~Movement() {
 	for (uint i = 0; i < _dynamicPhases.size(); i++)
 		delete _framePosOffsets[i];
 
-	if (!_currMovement ) {
+	if (!_currMovement) {
 		if (_updateFlag1) {
 			_dynamicPhases[0]->freePixelData();
 			_dynamicPhases.remove_at(0);
diff --git a/engines/fullpipe/utils.h b/engines/fullpipe/utils.h
index d19def6..2b97ab6 100644
--- a/engines/fullpipe/utils.h
+++ b/engines/fullpipe/utils.h
@@ -107,7 +107,7 @@ public:
 };
 
 class ObList : public Common::List<CObject *>, public CObject {
- public:
+public:
 	virtual bool load(MfcArchive &file);
 };
 


Commit: 0cc0b1932e7feb97b15810ed9748a55a20947763
    https://github.com/scummvm/scummvm/commit/0cc0b1932e7feb97b15810ed9748a55a20947763
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix memory leaks, ownership issues, and endianness issues in graphics code

Changed paths:
    engines/fullpipe/fullpipe.cpp
    engines/fullpipe/fullpipe.h
    engines/fullpipe/gfx.cpp
    engines/fullpipe/gfx.h
    engines/fullpipe/scene.cpp
    engines/fullpipe/statics.cpp


diff --git a/engines/fullpipe/fullpipe.cpp b/engines/fullpipe/fullpipe.cpp
index ad9b6a4..122b685 100644
--- a/engines/fullpipe/fullpipe.cpp
+++ b/engines/fullpipe/fullpipe.cpp
@@ -76,7 +76,6 @@ FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc)
 	_pictureScale = 8;
 	_scrollSpeed = 0;
 	_currSoundListCount = 0;
-	_globalPalette = 0;
 
 	_updateTicks = 0;
 	_lastInputTicks = 0;
@@ -290,6 +289,7 @@ Common::Error FullpipeEngine::run() {
 	_console = new Console(this);
 
 	initialize();
+	_globalPalette = &_defaultPalette;
 
 	_isSaveAllowed = false;
 
@@ -338,6 +338,7 @@ Common::Error FullpipeEngine::run() {
 			freeGameLoader();
 			_currentScene = 0;
 			_updateTicks = 0;
+			_globalPalette = &_defaultPalette;
 
 			loadGam("fullpipe.gam");
 			_needRestart = false;
diff --git a/engines/fullpipe/fullpipe.h b/engines/fullpipe/fullpipe.h
index 0a76381..d5aa730 100644
--- a/engines/fullpipe/fullpipe.h
+++ b/engines/fullpipe/fullpipe.h
@@ -83,6 +83,7 @@ class Scene;
 class SoundList;
 class StaticANIObject;
 class Vars;
+typedef Common::Array<int32> Palette;
 
 int global_messageHandler1(ExCommand *cmd);
 int global_messageHandler2(ExCommand *cmd);
@@ -151,7 +152,8 @@ public:
 	Scene *_scene3;
 	StaticANIObject *_aniMan;
 	StaticANIObject *_aniMan2;
-	byte *_globalPalette;
+	Palette _defaultPalette;
+	const Palette *_globalPalette;
 
 	InputController *_inputController;
 	bool _inputDisabled;
diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp
index f227e13..75366f5 100644
--- a/engines/fullpipe/gfx.cpp
+++ b/engines/fullpipe/gfx.cpp
@@ -41,7 +41,6 @@ Background::Background() {
 	_bigPictureArray1Count = 0;
 	_bigPictureArray2Count = 0;
 	_bigPictureArray = 0;
-	_palette = 0;
 }
 
 Background::~Background() {
@@ -432,35 +431,17 @@ bool GameObject::setPicAniInfo(PicAniInfo *picAniInfo) {
 	return false;
 }
 
-Picture::Picture() {
-	_x = 0;
-	_y = 0;
-	_field_44 = 0;
-	_field_54 = 0;
-	_bitmap = 0;
-	_alpha = -1;
-	_paletteData = 0;
-	_convertedBitmap = 0;
-	_memoryObject2 = 0;
-	_width = 0;
-	_height = 0;
-}
+Picture::Picture() :
+	_x(0),
+	_y(0),
+	_field_44(0),
+	_field_54(0),
+	_alpha(-1),
+	_width(0),
+	_height(0) {}
 
 Picture::~Picture() {
 	freePicture();
-
-	_bitmap = 0;
-
-	if (_memoryObject2)
-		delete _memoryObject2;
-
-	if (_paletteData)
-		free(_paletteData);
-
-	if (_convertedBitmap) {
-		delete _convertedBitmap;
-		_convertedBitmap = 0;
-	}
 }
 
 void Picture::freePicture() {
@@ -469,20 +450,12 @@ void Picture::freePicture() {
 	if (_bitmap) {
 		if (testFlags() && !_field_54) {
 			freeData();
-			delete _bitmap;
-			_bitmap = 0;
 		}
+		_bitmap.reset();
+		_data = nullptr;
 	}
 
-	if (_bitmap) {
-		_bitmap = 0;
-		_data = 0;
-	}
-
-	if (_convertedBitmap) {
-		delete _convertedBitmap;
-		_convertedBitmap = 0;
-	}
+	_convertedBitmap.reset();
 }
 
 void Picture::freePixelData() {
@@ -505,7 +478,7 @@ bool Picture::load(MfcArchive &file) {
 
 	_mflags |= 1;
 
-	_memoryObject2 = new MemoryObject2;
+	_memoryObject2.reset(new MemoryObject2);
 	_memoryObject2->load(file);
 
 	if (_memoryObject2->_data) {
@@ -519,8 +492,10 @@ bool Picture::load(MfcArchive &file) {
 	int havePal = file.readUint32LE();
 
 	if (havePal > 0) {
-		_paletteData = (byte *)calloc(1024, 1);
-		file.read(_paletteData, 1024);
+		_paletteData.reserve(256);
+		for (int i = 0; i < 256; ++i) {
+			_paletteData.push_back(file.readUint32LE());
+		}
 	}
 
 	getData();
@@ -549,7 +524,7 @@ void Picture::init() {
 
 	MemoryObject::getData();
 
-	_bitmap = new Bitmap();
+	_bitmap = BitmapPtr(new Bitmap());
 
 	getDibInfo();
 
@@ -583,14 +558,14 @@ void Picture::getDibInfo() {
 	_bitmap->load(s);
 	delete s;
 
-	_bitmap->decode(_data, (int32 *)(_paletteData ? _paletteData : g_fp->_globalPalette));
+	_bitmap->decode(_data, _paletteData.size() ? _paletteData : *g_fp->_globalPalette);
 }
 
-Bitmap *Picture::getPixelData() {
+const Bitmap *Picture::getPixelData() {
 	if (!_bitmap)
 		init();
 
-	return _bitmap;
+	return _bitmap.get();
 }
 
 void Picture::draw(int x, int y, int style, int angle) {
@@ -615,9 +590,10 @@ void Picture::draw(int x, int y, int style, int angle) {
 		debugC(7, kDebugDrawing, "Picture:draw: alpha = %0x", _alpha);
 	}
 
-	byte *pal = _paletteData;
-
-	if (!pal) {
+	const Palette *pal;
+	if (_paletteData.size()) {
+		pal = &_paletteData;
+	} else {
 		//warning("Picture:draw: using global palette");
 		pal = g_fp->_globalPalette;
 	}
@@ -626,13 +602,13 @@ void Picture::draw(int x, int y, int style, int angle) {
 	case 1: {
 		//flip
 		const Dims dims = getDimensions();
-		_bitmap->flipVertical()->drawShaded(1, x1, y1 + 30 + dims.y, pal, _alpha);
+		_bitmap->flipVertical()->drawShaded(1, x1, y1 + 30 + dims.y, *pal, _alpha);
 		break;
 	}
 	case 2:
 		//vrtSetFadeRatio(g_vrtDrawHandle, 0.34999999);
 		//vrtSetFadeTable(g_vrtDrawHandle, &unk_477F88, 1.0, 1000.0, 0, 0);
-		_bitmap->drawShaded(2, x1, y1, pal, _alpha);
+		_bitmap->drawShaded(2, x1, y1, *pal, _alpha);
 		//vrtSetFadeRatio(g_vrtDrawHandle, 0.0);
 		//vrtSetFadeTable(g_vrtDrawHandle, &unk_477F90, 1.0, 1000.0, 0, 0);
 		break;
@@ -640,7 +616,7 @@ void Picture::draw(int x, int y, int style, int angle) {
 		if (angle)
 			drawRotated(x1, y1, angle);
 		else {
-			_bitmap->putDib(x1, y1, (int32 *)pal, _alpha);
+			_bitmap->putDib(x1, y1, *pal, _alpha);
 		}
 	}
 }
@@ -680,13 +656,11 @@ void Picture::displayPicture() {
 	}
 }
 
-void Picture::setPaletteData(byte *pal) {
-	if (_paletteData)
-		free(_paletteData);
-
-	if (pal) {
-		_paletteData = (byte *)malloc(1024);
-		memcpy(_paletteData, pal, 1024);
+void Picture::setPaletteData(const Palette &pal) {
+	if (pal.size()) {
+		_paletteData = pal;
+	} else {
+		_paletteData.clear();
 	}
 }
 
@@ -750,29 +724,26 @@ Bitmap::Bitmap() {
 	_type = 0;
 	_dataSize = 0;
 	_flags = 0;
-	_surface = 0;
 	_flipping = Graphics::FLIP_NONE;
-	_copied_surface = false;
 }
 
-Bitmap::Bitmap(Bitmap *src) {
-	_x = src->_x;
-	_y = src->_y;
-	_flags = src->_flags;
-	_dataSize = src->_dataSize;
-	_type = src->_type;
-	_width = src->_width;
-	_height = src->_height;
-	_surface = new Graphics::TransparentSurface(*src->_surface);
-	_copied_surface = true;
-	_flipping = src->_flipping;
+Bitmap::Bitmap(const Bitmap &src) {
+	_x = src._x;
+	_y = src._y;
+	_flags = src._flags;
+	_dataSize = src._dataSize;
+	_type = src._type;
+	_width = src._width;
+	_height = src._height;
+	_surface = TransSurfacePtr(src._surface);
+	_flipping = src._flipping;
 }
 
 Bitmap::~Bitmap() {
-	if (!_copied_surface)
+	// TODO: This is a hack because Graphics::Surface has terrible resource
+	// management
+	if (_surface.unique())
 		_surface->free();
-	delete _surface;
-	_surface = 0;
 }
 
 void Bitmap::load(Common::ReadStream *s) {
@@ -801,8 +772,8 @@ bool Bitmap::isPixelHitAtPos(int x, int y) {
 	return ((*((int32 *)_surface->getBasePtr(x - _x, y - _y)) & 0xff) != 0);
 }
 
-void Bitmap::decode(byte *pixels, int32 *palette) {
-	_surface = new Graphics::TransparentSurface;
+void Bitmap::decode(byte *pixels, const Palette &palette) {
+	_surface = TransSurfacePtr(new Graphics::TransparentSurface);
 
 	_surface->create(_width, _height, Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
 
@@ -812,7 +783,7 @@ void Bitmap::decode(byte *pixels, int32 *palette) {
 		putDibCB(pixels, palette);
 }
 
-void Bitmap::putDib(int x, int y, int32 *palette, byte alpha) {
+void Bitmap::putDib(int x, int y, const Palette &palette, byte alpha) {
 	debugC(7, kDebugDrawing, "Bitmap::putDib(%d, %d)", x, y);
 
 	int x1 = x - g_fp->_sceneRect.left;
@@ -841,7 +812,7 @@ void Bitmap::putDib(int x, int y, int32 *palette, byte alpha) {
 	g_fp->_system->copyRectToScreen(g_fp->_backgroundSurface->getBasePtr(x1, y1), g_fp->_backgroundSurface->pitch, x1, y1, sub.width(), sub.height());
 }
 
-bool Bitmap::putDibRB(byte *pixels, int32 *palette) {
+bool Bitmap::putDibRB(byte *pixels, const Palette &palette) {
 	uint32 *curDestPtr;
 	int endy;
 	int x;
@@ -852,7 +823,7 @@ bool Bitmap::putDibRB(byte *pixels, int32 *palette) {
 	uint16 *srcPtr2;
 	uint16 *srcPtr;
 
-	if (!palette) {
+	if (!palette.size()) {
 		debugC(2, kDebugDrawing, "Bitmap::putDibRB(): Both global and local palettes are empty");
 		return false;
 	}
@@ -934,7 +905,7 @@ bool Bitmap::putDibRB(byte *pixels, int32 *palette) {
 
 				if (y <= endy) {
 					curDestPtr = (uint32 *)_surface->getBasePtr(start1, y);
-					paletteFill(curDestPtr, (byte *)srcPtr2, fillLen, (int32 *)palette);
+					paletteFill(curDestPtr, (byte *)srcPtr2, fillLen, palette);
 				}
 			}
 		}
@@ -943,7 +914,7 @@ bool Bitmap::putDibRB(byte *pixels, int32 *palette) {
 	return false;
 }
 
-void Bitmap::putDibCB(byte *pixels, int32 *palette) {
+void Bitmap::putDibCB(byte *pixels, const Palette &palette) {
 	uint32 *curDestPtr;
 	int endx;
 	int endy;
@@ -956,7 +927,7 @@ void Bitmap::putDibCB(byte *pixels, int32 *palette) {
 
 	cb05_format = (_type == MKTAG('C', 'B', '\05', 'e'));
 
-	if (!palette && !cb05_format)
+	if (!palette.size() && !cb05_format)
 		error("Bitmap::putDibCB(): Both global and local palettes are empty");
 
 	bpp = cb05_format ? 2 : 1;
@@ -973,12 +944,12 @@ void Bitmap::putDibCB(byte *pixels, int32 *palette) {
 	if (_flags & 0x1000000) {
 		for (int y = starty; y <= endy; srcPtr -= pitch, y++) {
 			curDestPtr = (uint32 *)_surface->getBasePtr(startx, y);
-			copierKeyColor(curDestPtr, srcPtr, endx - startx + 1, _flags & 0xff, (int32 *)palette, cb05_format);
+			copierKeyColor(curDestPtr, srcPtr, endx - startx + 1, _flags & 0xff, palette, cb05_format);
 		}
 	} else {
 		for (int y = starty; y <= endy; srcPtr -= pitch, y++) {
 			curDestPtr = (uint32 *)_surface->getBasePtr(startx, y);
-			copier(curDestPtr, srcPtr, endx - startx + 1, (int32 *)palette, cb05_format);
+			copier(curDestPtr, srcPtr, endx - startx + 1, palette, cb05_format);
 		}
 	}
 }
@@ -1004,7 +975,7 @@ void Bitmap::colorFill(uint32 *dest, int len, int32 color) {
 		*dest++ = c;
 }
 
-void Bitmap::paletteFill(uint32 *dest, byte *src, int len, int32 *palette) {
+void Bitmap::paletteFill(uint32 *dest, byte *src, int len, const Palette &palette) {
 #if 0
 	if (blendMode) {
 		if (blendMode != 1)
@@ -1025,7 +996,7 @@ void Bitmap::paletteFill(uint32 *dest, byte *src, int len, int32 *palette) {
 	}
 }
 
-void Bitmap::copierKeyColor(uint32 *dest, byte *src, int len, int keyColor, int32 *palette, bool cb05_format) {
+void Bitmap::copierKeyColor(uint32 *dest, byte *src, int len, int keyColor, const Palette &palette, bool cb05_format) {
 #if 0
 	if (blendMode) {
 		if (blendMode == 1) {
@@ -1070,7 +1041,7 @@ void Bitmap::copierKeyColor(uint32 *dest, byte *src, int len, int keyColor, int3
 	}
 }
 
-void Bitmap::copier(uint32 *dest, byte *src, int len, int32 *palette, bool cb05_format) {
+void Bitmap::copier(uint32 *dest, byte *src, int len, const Palette &palette, bool cb05_format) {
 #if 0
 	if (blendMode) {
 		if (blendMode == 1) {
@@ -1106,8 +1077,8 @@ void Bitmap::copier(uint32 *dest, byte *src, int len, int32 *palette, bool cb05_
 	}
 }
 
-Bitmap *Bitmap::reverseImage(bool flip) {
-	Bitmap *b = new Bitmap(this);
+Bitmap *Bitmap::reverseImage(bool flip) const {
+	Bitmap *b = new Bitmap(*this);
 
 	if (flip)
 		b->_flipping ^= Graphics::FLIP_H;
@@ -1115,25 +1086,25 @@ Bitmap *Bitmap::reverseImage(bool flip) {
 	return b;
 }
 
-Bitmap *Bitmap::flipVertical() {
-	Bitmap *b = new Bitmap(this);
+Bitmap *Bitmap::flipVertical() const {
+	Bitmap *b = new Bitmap(*this);
 
 	b->_flipping ^= Graphics::FLIP_V;
 
 	return b;
 }
 
-void Bitmap::drawShaded(int type, int x, int y, byte *palette, int alpha) {
+void Bitmap::drawShaded(int type, int x, int y, const Palette &palette, int alpha) {
 	if (alpha != 255)
 		warning("STUB: Bitmap::drawShaded(%d, %d, %d, %d)", type, x, y, alpha);
 
-	putDib(x, y, (int32 *)palette, alpha);
+	putDib(x, y, palette, alpha);
 }
 
-void Bitmap::drawRotated(int x, int y, int angle, byte *palette, int alpha) {
+void Bitmap::drawRotated(int x, int y, int angle, const Palette &palette, int alpha) {
 	warning("STUB: Bitmap::drawRotated(%d, %d, %d, %d)", x, y, angle, alpha);
 
-	putDib(x, y, (int32 *)palette, alpha);
+	putDib(x, y, palette, alpha);
 }
 
 bool BigPicture::load(MfcArchive &file) {
@@ -1159,7 +1130,7 @@ void BigPicture::draw(int x, int y, int style, int angle) {
 		if (y != -1)
 			ny = y;
 
-		_bitmap->putDib(nx, ny, 0, _alpha);
+		_bitmap->putDib(nx, ny, Palette(), _alpha);
 	}
 }
 
diff --git a/engines/fullpipe/gfx.h b/engines/fullpipe/gfx.h
index 41214ee..b92e94b 100644
--- a/engines/fullpipe/gfx.h
+++ b/engines/fullpipe/gfx.h
@@ -23,6 +23,8 @@
 #ifndef FULLPIPE_GFX_H
 #define FULLPIPE_GFX_H
 
+#include "common/ptr.h"
+
 namespace Graphics {
 	struct Surface;
 	struct TransparentSurface;
@@ -34,8 +36,11 @@ class DynamicPhase;
 class Movement;
 struct PicAniInfo;
 
+typedef Common::Array<int32> Palette;
 typedef Common::Point Dims;
 
+typedef Common::SharedPtr<Graphics::TransparentSurface> TransSurfacePtr;
+
 struct Bitmap {
 	int _x;
 	int _y;
@@ -44,52 +49,42 @@ struct Bitmap {
 	int _type;
 	int _dataSize;
 	int _flags;
-	Graphics::TransparentSurface *_surface;
 	int _flipping;
-	bool _copied_surface;
+	TransSurfacePtr _surface;
 
 	Bitmap();
-	Bitmap(Bitmap *src);
+	Bitmap(const Bitmap &src);
 	~Bitmap();
 
 	void load(Common::ReadStream *s);
-	void decode(byte *pixels, int32 *palette);
-	void putDib(int x, int y, int32 *palette, byte alpha);
-	bool putDibRB(byte *pixels, int32 *palette);
-	void putDibCB(byte *pixels, int32 *palette);
+	void decode(byte *pixels, const Palette &palette);
+	void putDib(int x, int y, const Palette &palette, byte alpha);
+	bool putDibRB(byte *pixels, const Palette &palette);
+	void putDibCB(byte *pixels, const Palette &palette);
 
 	void colorFill(uint32 *dest, int len, int32 color);
-	void paletteFill(uint32 *dest, byte *src, int len, int32 *palette);
-	void copierKeyColor(uint32 *dest, byte *src, int len, int keyColor, int32 *palette, bool cb05_format);
-	void copier(uint32 *dest, byte *src, int len, int32 *palette, bool cb05_format);
+	void paletteFill(uint32 *dest, byte *src, int len, const Palette &palette);
+	void copierKeyColor(uint32 *dest, byte *src, int len, int keyColor, const Palette &palette, bool cb05_format);
+	void copier(uint32 *dest, byte *src, int len, const Palette &palette, bool cb05_format);
 
-	Bitmap *reverseImage(bool flip = true);
-	Bitmap *flipVertical();
+	/** ownership of returned object is transferred to caller */
+	Bitmap *reverseImage(bool flip = true) const;
+	/** ownership of returned object is transferred to caller */
+	Bitmap *flipVertical() const;
 
-	void drawShaded(int type, int x, int y, byte *palette, int alpha);
-	void drawRotated(int x, int y, int angle, byte *palette, int alpha);
+	void drawShaded(int type, int x, int y, const Palette &palette, int alpha);
+	void drawRotated(int x, int y, int angle, const Palette &palette, int alpha);
 
 	bool isPixelHitAtPos(int x, int y);
-};
 
-class Picture : public MemoryObject {
- public:
-	Common::Rect _rect;
-	Bitmap *_convertedBitmap;
-	int _x;
-	int _y;
-	int _field_44;
-	int _width;
-	int _height;
-	Bitmap *_bitmap;
-	int _field_54;
-	MemoryObject2 *_memoryObject2;
-	int _alpha;
-	byte *_paletteData;
+private:
+	Bitmap operator=(const Bitmap &);
+};
 
-	void displayPicture();
+typedef Common::SharedPtr<Bitmap> BitmapPtr;
 
-  public:
+class Picture : public MemoryObject {
+public:
 	Picture();
 	virtual ~Picture();
 
@@ -100,7 +95,7 @@ class Picture : public MemoryObject {
 	void setAOIDs();
 	virtual void init();
 	void getDibInfo();
-	Bitmap *getPixelData();
+	const Bitmap *getPixelData();
 	virtual void draw(int x, int y, int style, int angle);
 	void drawRotated(int x, int y, int angle);
 
@@ -113,10 +108,27 @@ class Picture : public MemoryObject {
 	int getPixelAtPos(int x, int y);
 	int getPixelAtPosEx(int x, int y);
 
-	byte *getPaletteData() { return _paletteData; }
-	void setPaletteData(byte *pal);
+	const Bitmap *getConvertedBitmap() const { return _convertedBitmap.get(); }
+	const Palette &getPaletteData() const { return _paletteData; }
+	void setPaletteData(const Palette &pal);
 
 	void copyMemoryObject2(Picture *src);
+
+	int _x, _y;
+
+protected:
+	Common::Rect _rect;
+	Common::ScopedPtr<Bitmap> _convertedBitmap;
+	int _field_44;
+	int _width;
+	int _height;
+	BitmapPtr _bitmap;
+	int _field_54;
+	Common::ScopedPtr<MemoryObject2> _memoryObject2;
+	int _alpha;
+	Palette _paletteData;
+
+	void displayPicture();
 };
 
 class BigPicture : public Picture {
@@ -191,7 +203,7 @@ class Background : public CObject {
 	int _x;
 	int _y;
 	int16 _messageQueueId;
-	MemoryObject *_palette;
+	Palette _palette;
 	int _bigPictureArray1Count;
 	int _bigPictureArray2Count;
 	BigPicture ***_bigPictureArray;
diff --git a/engines/fullpipe/scene.cpp b/engines/fullpipe/scene.cpp
index 5e92c5f..ee0e5e5 100644
--- a/engines/fullpipe/scene.cpp
+++ b/engines/fullpipe/scene.cpp
@@ -129,7 +129,6 @@ Scene::Scene() {
 Scene::~Scene() {
 	delete _soundList;
 	delete _shadows;
-	delete _palette;
 
 	// _faObjlist is not used
 
@@ -216,10 +215,16 @@ bool Scene::load(MfcArchive &file) {
 		Common::strlcpy(fname, _bgname.c_str(), 260);
 		Common::strlcpy(strrchr(fname, '.') + 1, "col", 260);
 
-		MemoryObject *col = new MemoryObject();
+		Common::ScopedPtr<MemoryObject> col(new MemoryObject());
 		col->loadFile(fname);
-
-		_palette = col;
+		if (col->getDataSize()) {
+			assert(col->getDataSize() == 256 * sizeof(uint32));
+			const byte *data = col->getData();
+			for (int i = 0; i < 256; ++i) {
+				_palette.push_back(READ_LE_UINT32(data));
+				data += sizeof(uint32);
+			}
+		}
 	}
 
 	Common::String shdname = genFileName(0, _sceneId, "shd");
@@ -670,8 +675,8 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
 	if (!_picObjList.size() && !_bigPictureArray1Count)
 		return;
 
-	if (_palette) {
-		g_fp->_globalPalette = _palette->_data;
+	if (_palette.size()) {
+		g_fp->_globalPalette = &_palette;
 	}
 
 	debugC(1, kDebugDrawing, "Scene::drawContent(>%d, <%d, %d)", minPri, maxPri, drawBg);
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index a78131d..6b7dbbb 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -528,41 +528,41 @@ void Movement::draw(bool flipFlag, int angle) {
 	int x = _ox - point.x;
 	int y = _oy - point.y;
 
-	if (_currDynamicPhase->getPaletteData())
-		g_fp->_globalPalette = _currDynamicPhase->getPaletteData();
+	if (_currDynamicPhase->getPaletteData().size())
+		g_fp->_globalPalette = &_currDynamicPhase->getPaletteData();
 
-	Bitmap *bmp;
+	Common::ScopedPtr<Bitmap> bmp;
 	if (_currMovement) {
-		bmp = _currDynamicPhase->getPixelData()->reverseImage();
+		bmp.reset(_currDynamicPhase->getPixelData()->reverseImage());
 	} else {
-		bmp = _currDynamicPhase->getPixelData()->reverseImage(false);
+		bmp.reset(_currDynamicPhase->getPixelData()->reverseImage(false));
 	}
 
 	if (flipFlag) {
-		bmp->flipVertical()->drawShaded(1, x, y + 30 + _currDynamicPhase->_rect->bottom, _currDynamicPhase->_paletteData, _currDynamicPhase->_alpha);
+		bmp->flipVertical()->drawShaded(1, x, y + 30 + _currDynamicPhase->_rect->bottom, _currDynamicPhase->getPaletteData(), _currDynamicPhase->getAlpha());
 	} else if (angle) {
-		bmp->drawRotated(x, y, angle, _currDynamicPhase->_paletteData, _currDynamicPhase->_alpha);
+		bmp->drawRotated(x, y, angle, _currDynamicPhase->getPaletteData(), _currDynamicPhase->getAlpha());
 	} else {
-		bmp->putDib(x, y, (int32 *)_currDynamicPhase->_paletteData, _currDynamicPhase->_alpha);
+		bmp->putDib(x, y, _currDynamicPhase->getPaletteData(), _currDynamicPhase->getAlpha());
 	}
-	//Prevent memory leak after new was used to create bmp in reverseImage()
-	delete bmp;
 
 	if (_currDynamicPhase->_rect->top) {
-		if (!_currDynamicPhase->_convertedBitmap) {
+		if (!_currDynamicPhase->getConvertedBitmap()) {
 			//v12 = Picture_getPixelData(v5);
 			//v13 = Bitmap_convertTo16Bit565(v12, (unsigned int *)&_currDynamicPhase->rect);
 			//_currDynamicPhase->convertedBitmap = v13;
 		}
 
-		if (_currDynamicPhase->_convertedBitmap) {
+		if (_currDynamicPhase->getConvertedBitmap()) {
 			if (_currMovement) {
 				//vrtSetAlphaBlendMode(g_vrtDrawHandle, 1, LOBYTE(_currDynamicPhase->rect.top));
-				_currDynamicPhase->_convertedBitmap->reverseImage()->putDib(x, y, (int32 *)_currDynamicPhase->_paletteData, _currDynamicPhase->_alpha);
+				bmp.reset(_currDynamicPhase->getConvertedBitmap()->reverseImage());
+				bmp->putDib(x, y, _currDynamicPhase->getPaletteData(), _currDynamicPhase->getAlpha());
 				//vrtSetAlphaBlendMode(g_vrtDrawHandle, 0, 255);
 			} else {
 				//vrtSetAlphaBlendMode(g_vrtDrawHandle, 1, LOBYTE(_currDynamicPhase->rect.top));
-				_currDynamicPhase->_convertedBitmap->reverseImage(false)->putDib(x, y, (int32 *)_currDynamicPhase->_paletteData, _currDynamicPhase->_alpha);
+				bmp.reset(_currDynamicPhase->getConvertedBitmap()->reverseImage(false));
+				bmp->putDib(x, y, _currDynamicPhase->getPaletteData(), _currDynamicPhase->getAlpha());
 				//vrtSetAlphaBlendMode(g_vrtDrawHandle, 0, 255);
 			}
 		}
@@ -1441,11 +1441,7 @@ void Statics::init() {
 	Picture::init();
 
 	if (_staticsId & 0x4000) {
-		Bitmap *reversed = _bitmap->reverseImage();
-		// TODO: properly dispose old _bitmap
-		// Enabling the call below causes corruption in flipped bitmaps
-		//freePixelData();
-		_bitmap = reversed;
+		_bitmap = BitmapPtr(_bitmap->reverseImage());
 	}
 }
 
@@ -2166,7 +2162,7 @@ DynamicPhase::DynamicPhase(DynamicPhase *src, bool reverse) {
 		if (!src->_bitmap)
 			src->init();
 
-		_bitmap = src->_bitmap->reverseImage();
+		_bitmap = BitmapPtr(src->_bitmap->reverseImage());
 		_dataSize = src->_dataSize;
 
 		if (g_fp->_currArchive) {
@@ -2188,11 +2184,9 @@ DynamicPhase::DynamicPhase(DynamicPhase *src, bool reverse) {
 		_mfield_10 = src->_mfield_10;
 		_libHandle = src->_libHandle;
 
-		_bitmap = src->_bitmap;
-		if (_bitmap) {
+		if (src->_bitmap) {
 			_field_54 = 1;
-
-			_bitmap = src->_bitmap->reverseImage(false);
+			_bitmap = BitmapPtr(src->_bitmap->reverseImage(false));
 		}
 
 		_someX = src->_someX;


Commit: cc905d7f9a4be668c3fc1e8090cb996feea9b8f3
    https://github.com/scummvm/scummvm/commit/cc905d7f9a4be668c3fc1e8090cb996feea9b8f3
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Make TODO labelled so it is picked up by tools

Changed paths:
    engines/fullpipe/gfx.cpp


diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp
index 75366f5..d41505e 100644
--- a/engines/fullpipe/gfx.cpp
+++ b/engines/fullpipe/gfx.cpp
@@ -707,7 +707,7 @@ int Picture::getPixelAtPosEx(int x, int y) {
 
 	warning("STUB: Picture::getPixelAtPosEx(%d, %d)", x, y);
 
-	// It looks like this doesn't really work. TODO. FIXME
+	// TODO: It looks like this doesn't really work.
 	if (x < (g_fp->_pictureScale + _width - 1) / g_fp->_pictureScale &&
 			y < (g_fp->_pictureScale + _height - 1) / g_fp->_pictureScale &&
 			_memoryObject2 != 0 && _memoryObject2->_rows != 0)


Commit: f41074b9309b39204b56032ea3562f6323dcac62
    https://github.com/scummvm/scummvm/commit/f41074b9309b39204b56032ea3562f6323dcac62
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Improve memory ownership in Motion

Changed paths:
    engines/fullpipe/messagehandlers.cpp
    engines/fullpipe/motion.cpp
    engines/fullpipe/motion.h


diff --git a/engines/fullpipe/messagehandlers.cpp b/engines/fullpipe/messagehandlers.cpp
index a172184..f72ae98 100644
--- a/engines/fullpipe/messagehandlers.cpp
+++ b/engines/fullpipe/messagehandlers.cpp
@@ -754,7 +754,7 @@ int global_messageHandler4(ExCommand *cmd) {
 	return 1;
 }
 
-int MovGraph_messageHandler(ExCommand *cmd) {
+int MovGraph::messageHandler(ExCommand *cmd) {
 	if (cmd->_messageKind != 17)
 		return 0;
 
diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp
index eedd266..cfe9ecb 100644
--- a/engines/fullpipe/motion.cpp
+++ b/engines/fullpipe/motion.cpp
@@ -41,13 +41,13 @@ void MotionController::enableLinks(const char *linkName, bool enable) {
 	if (_objtype != kObjTypeMctlCompound)
 		return;
 
-	MctlCompound *obj = (MctlCompound *)this;
+	MctlCompound *obj = static_cast<MctlCompound *>(this);
 
 	for (uint i = 0;  i < obj->getMotionControllerCount(); i++) {
 		MotionController *con = obj->getMotionController(i);
 
 		if (con->_objtype == kObjTypeMovGraph) {
-			MovGraph *gr = (MovGraph *)con;
+			MovGraph *gr = static_cast<MovGraph *>(con);
 
 			for (ObList::iterator l = gr->_links.begin(); l != gr->_links.end(); ++l) {
 				assert(((CObject *)*l)->_objtype == kObjTypeMovGraphLink);
@@ -792,8 +792,6 @@ void MovGraphItem::free() {
 	mi_movitems = 0;
 }
 
-int MovGraph_messageHandler(ExCommand *cmd);
-
 MovArr *movGraphCallback(StaticANIObject *ani, Common::Array<MovItem *> *items, signed int counter) {
 	int residx = 0;
 	int itemidx = 0;
@@ -812,7 +810,7 @@ MovArr *movGraphCallback(StaticANIObject *ani, Common::Array<MovItem *> *items,
 MovGraph::MovGraph() {
 	_callback1 = movGraphCallback;
 	_field_44 = 0;
-	insertMessageHandler(MovGraph_messageHandler, getMessageHandlersCount() - 1, 129);
+	insertMessageHandler(MovGraph::messageHandler, getMessageHandlersCount() - 1, 129);
 
 	_objtype = kObjTypeMovGraph;
 }
@@ -843,14 +841,12 @@ void MovGraph::attachObject(StaticANIObject *obj) {
 	_aniHandler.attachObject(obj->_id);
 
 	for (uint i = 0; i < _items.size(); i++)
-		if (_items[i]->ani == obj)
+		if (_items[i].ani == obj)
 			return;
 
-	MovGraphItem *item = new MovGraphItem();
-
-	item->ani = obj;
-
-	_items.push_back(item);
+	_items.push_back(MovGraphItem());
+	MovGraphItem &item = _items.back();
+	item.ani = obj;
 
 	_aniHandler.attachObject(obj->_id); // FIXME: Is it really needed?
 }
@@ -865,9 +861,9 @@ void MovGraph::detachAllObjects() {
 	debugC(4, kDebugPathfinding, "MovGraph::detachAllObjects()");
 
 	for (uint i = 0; i < _items.size(); i++) {
-		_items[i]->free();
+		_items[i].free();
 
-		_items[i]->movarr._movSteps.clear();
+		_items[i].movarr._movSteps.clear();
 	}
 
 	_items.clear();
@@ -883,30 +879,30 @@ Common::Array<MovItem *> *MovGraph::getPaths(StaticANIObject *ani, int x, int y,
 
 	uint idx = 0;
 
-	while (_items[idx]->ani != ani) {
+	while (_items[idx].ani != ani) {
 		idx++;
 
 		if (idx >= _items.size())
 			return 0;
 	}
-	_items[idx]->free();
+	_items[idx].free();
 
 	recalcLinkParams();
 
-	_items[idx]->movarr._movSteps.clear();
+	_items[idx].movarr._movSteps.clear();
 
 	Common::Point point;
 
 	point.x = ani->_ox;
 	point.y = ani->_oy;
 
-	if (!getHitPoint(idx, ani->_ox, ani->_oy, &_items[idx]->movarr, 0))
-		getNearestPoint(idx, &point, &_items[idx]->movarr);
+	if (!getHitPoint(idx, ani->_ox, ani->_oy, &_items[idx].movarr, 0))
+		getNearestPoint(idx, &point, &_items[idx].movarr);
 
-	_items[idx]->count = 0;
+	_items[idx].count = 0;
 
-	delete _items[idx]->mi_movitems;
-	_items[idx]->mi_movitems = 0;
+	delete _items[idx].mi_movitems;
+	_items[idx].mi_movitems = 0;
 
 	int arrSize;
 	Common::Array<MovArr *> *movarr = getHitPoints(x, y, &arrSize, flag1, 0);
@@ -914,12 +910,12 @@ Common::Array<MovItem *> *MovGraph::getPaths(StaticANIObject *ani, int x, int y,
 	if (movarr) {
 		for (int i = 0; i < arrSize; i++) {
 			int sz;
-			Common::Array<MovItem *> *movitems = getPaths(&_items[idx]->movarr, (*movarr)[i], &sz);
+			Common::Array<MovItem *> *movitems = getPaths(&_items[idx].movarr, (*movarr)[i], &sz);
 
 			if (sz > 0) {
-				_items[idx]->mi_movitems = new Common::Array<MovItem *>;
+				_items[idx].mi_movitems = new Common::Array<MovItem *>;
 				for (int j = 0; j < sz; j++)
-					_items[idx]->mi_movitems->push_back(movitems[j]);
+					_items[idx].mi_movitems->push_back(movitems[j]);
 			}
 
 			delete movitems;
@@ -928,10 +924,10 @@ Common::Array<MovItem *> *MovGraph::getPaths(StaticANIObject *ani, int x, int y,
 		delete movarr;
 	}
 
-	if (_items[idx]->count) {
-		*rescount = _items[idx]->count;
+	if (_items[idx].count) {
+		*rescount = _items[idx].count;
 
-		return _items[idx]->mi_movitems;
+		return _items[idx].mi_movitems;
 	}
 
 	return 0;
@@ -949,7 +945,7 @@ MessageQueue *MovGraph::startMove(StaticANIObject *ani, int xpos, int ypos, int
 		if (!_items.size())
 			return 0;
 
-		ani = _items[0]->ani;
+		ani = _items[0].ani;
 	}
 
 	if (ABS(ani->_ox - xpos) < 50 && ABS(ani->_oy - ypos) < 50)
@@ -1010,8 +1006,8 @@ MessageQueue *MovGraph::startMove(StaticANIObject *ani, int xpos, int ypos, int
 		getPaths(ani, xpos, ypos, fuzzyMatch, &count2);
 
 		int idx = getObjectIndex(ani);
-		count = _items[idx]->count;
-		movitems = _items[idx]->mi_movitems;
+		count = _items[idx].count;
+		movitems = _items[idx].mi_movitems;
 	}
 
 	return method50(ani, _callback1(ani, movitems, count), staticsId);
@@ -1099,8 +1095,8 @@ MessageQueue *MovGraph::makeQueue(StaticANIObject *subj, int xpos, int ypos, int
 		MovArr *goal = _callback1(subj, movitem, ss);
 		int idx = getObjectIndex(subj);
 
-		for (int i = 0; i < _items[idx]->count; i++) {
-			if ((*_items[idx]->mi_movitems)[i]->movarr == goal) {
+		for (int i = 0; i < _items[idx].count; i++) {
+			if ((*_items[idx].mi_movitems)[i]->movarr == goal) {
 				if (subj->_movement) {
 					Common::Point point;
 
@@ -1127,25 +1123,25 @@ MessageQueue *MovGraph::makeQueue(StaticANIObject *subj, int xpos, int ypos, int
 		MovArr *goal = _callback1(subj, movitem, ss);
 		int idx = getObjectIndex(subj);
 
-		if (_items[idx]->count > 0) {
+		if (_items[idx].count > 0) {
 			int arridx = 0;
 
-			while ((*_items[idx]->mi_movitems)[arridx]->movarr != goal) {
+			while ((*_items[idx].mi_movitems)[arridx]->movarr != goal) {
 				arridx++;
 
-				if (arridx >= _items[idx]->count) {
+				if (arridx >= _items[idx].count) {
 					subj->setPicAniInfo(&picAniInfo);
 					return 0;
 				}
 			}
 
-			_items[idx]->movarr._movSteps.clear();
-			_items[idx]->movarr = *(*_items[idx]->mi_movitems)[arridx]->movarr;
-			_items[idx]->movarr._movSteps = (*_items[idx]->mi_movitems)[arridx]->movarr->_movSteps;
-			_items[idx]->movarr._afield_8 = -1;
-			_items[idx]->movarr._link = 0;
+			_items[idx].movarr._movSteps.clear();
+			_items[idx].movarr = *(*_items[idx].mi_movitems)[arridx]->movarr;
+			_items[idx].movarr._movSteps = (*_items[idx].mi_movitems)[arridx]->movarr->_movSteps;
+			_items[idx].movarr._afield_8 = -1;
+			_items[idx].movarr._link = 0;
 
-			MessageQueue *mq = makeWholeQueue(_items[idx]->ani, &_items[idx]->movarr, staticsId);
+			MessageQueue *mq = makeWholeQueue(_items[idx].ani, &_items[idx].movarr, staticsId);
 			if (mq) {
 				ExCommand *ex = new ExCommand();
 				ex->_messageKind = 17;
@@ -1191,18 +1187,18 @@ MessageQueue *MovGraph::sub1(StaticANIObject *ani, int x, int y, int stid, int x
 	MovArr *goal = _callback1(ani, movitems, rescount);
 	int idx = getObjectIndex(ani);
 
-	MovGraphItem *movgitem = _items[idx];
-	int cnt = movgitem->count;
+	MovGraphItem &movgitem = _items[idx];
+	int cnt = movgitem.count;
 
 	for (int nidx = 0; nidx < cnt; nidx++) {
-		if ((*movgitem->mi_movitems)[nidx]->movarr == goal) {
-			movgitem->movarr._movSteps.clear();
-			_items[idx]->movarr = *(*movgitem->mi_movitems)[nidx]->movarr;
-			_items[idx]->movarr._movSteps = (*movgitem->mi_movitems)[nidx]->movarr->_movSteps;
-			_items[idx]->movarr._afield_8 = -1;
-			_items[idx]->movarr._link = 0;
+		if ((*movgitem.mi_movitems)[nidx]->movarr == goal) {
+			movgitem.movarr._movSteps.clear();
+			_items[idx].movarr = *(*movgitem.mi_movitems)[nidx]->movarr;
+			_items[idx].movarr._movSteps = (*movgitem.mi_movitems)[nidx]->movarr->_movSteps;
+			_items[idx].movarr._afield_8 = -1;
+			_items[idx].movarr._link = 0;
 
-			res = makeWholeQueue(_items[idx]->ani, &_items[idx]->movarr, stid2);
+			res = makeWholeQueue(_items[idx].ani, &_items[idx].movarr, stid2);
 
 			break;
 		}
@@ -1315,15 +1311,15 @@ MessageQueue *MovGraph::method50(StaticANIObject *ani, MovArr *movarr, int stati
 		if (idx == _items.size())
 			return 0;
 
-		if (_items[idx]->ani == ani) {
-			if (!_items[idx]->mi_movitems)
+		if (_items[idx].ani == ani) {
+			if (!_items[idx].mi_movitems)
 				return 0;
 
-			if (_items[idx]->count < 1)
+			if (_items[idx].count < 1)
 				return 0;
 
-			for (movidx = 0; movidx < _items[idx]->count; movidx++) {
-				if ((*_items[idx]->mi_movitems)[movidx]->movarr == movarr) {
+			for (movidx = 0; movidx < _items[idx].count; movidx++) {
+				if ((*_items[idx].mi_movitems)[movidx]->movarr == movarr) {
 					done = true;
 
 					break;
@@ -1332,13 +1328,13 @@ MessageQueue *MovGraph::method50(StaticANIObject *ani, MovArr *movarr, int stati
 		}
 	}
 
-	_items[idx]->movarr._movSteps.clear();
-	_items[idx]->movarr = *(*_items[idx]->mi_movitems)[movidx]->movarr;
-	_items[idx]->movarr._movSteps = (*_items[idx]->mi_movitems)[movidx]->movarr->_movSteps;
-	_items[idx]->movarr._afield_8 = -1;
-	_items[idx]->movarr._link = 0;
+	_items[idx].movarr._movSteps.clear();
+	_items[idx].movarr = *(*_items[idx].mi_movitems)[movidx]->movarr;
+	_items[idx].movarr._movSteps = (*_items[idx].mi_movitems)[movidx]->movarr->_movSteps;
+	_items[idx].movarr._afield_8 = -1;
+	_items[idx].movarr._link = 0;
 
-	MessageQueue *mq = makeWholeQueue(_items[idx]->ani, &_items[idx]->movarr, 0);
+	MessageQueue *mq = makeWholeQueue(_items[idx].ani, &_items[idx].movarr, 0);
 
 	if (!mq)
 		return 0;
@@ -1469,7 +1465,7 @@ bool MovGraph::getNearestPoint(int unusedArg, Common::Point *p, MovArr *movarr)
 
 int MovGraph::getObjectIndex(StaticANIObject *ani) {
 	for (uint i = 0; i < _items.size(); i++)
-		if (_items[i]->ani == ani)
+		if (_items[i].ani == ani)
 			return i;
 
 	return -1;
@@ -1620,13 +1616,13 @@ void MovGraph::genMovItem(MovItem *movitem, MovGraphLink *grlink, MovArr *movarr
 bool MovGraph::getHitPoint(int idx, int x, int y, MovArr *arr, int a6) {
 	int staticsId;
 
-	if (_items[idx]->ani->_statics) {
-		staticsId = _items[idx]->ani->_statics->_staticsId;
+	if (_items[idx].ani->_statics) {
+		staticsId = _items[idx].ani->_statics->_staticsId;
 	} else {
-		if (!_items[idx]->ani->_movement->_staticsObj2)
+		if (!_items[idx].ani->_movement->_staticsObj2)
 			return 0;
 
-		staticsId = _items[idx]->ani->_movement->_staticsObj2->_staticsId;
+		staticsId = _items[idx].ani->_movement->_staticsObj2->_staticsId;
 	}
 
 	int arrSize;
@@ -1642,14 +1638,14 @@ bool MovGraph::getHitPoint(int idx, int x, int y, MovArr *arr, int a6) {
 	int offmin = 100;
 
 	for (int i = 0; i < arrSize; i++) {
-		int off = _aniHandler.getNumMovements(_items[idx]->ani->_id, staticsId, (*movarr)[i]->_link->_dwordArray2[_field_44]);
+		int off = _aniHandler.getNumMovements(_items[idx].ani->_id, staticsId, (*movarr)[i]->_link->_dwordArray2[_field_44]);
 
 		if (off < offmin) {
 			offmin = off;
 			idxmin = i;
 		}
 
-		off = _aniHandler.getNumMovements(_items[idx]->ani->_id, staticsId, (*movarr)[i]->_link->_dwordArray2[_field_44 + 1]);
+		off = _aniHandler.getNumMovements(_items[idx].ani->_id, staticsId, (*movarr)[i]->_link->_dwordArray2[_field_44 + 1]);
 		if (off < offmin) {
 			offmin = off;
 			idxmin = i;
diff --git a/engines/fullpipe/motion.h b/engines/fullpipe/motion.h
index 7c25080..c08d56f 100644
--- a/engines/fullpipe/motion.h
+++ b/engines/fullpipe/motion.h
@@ -276,11 +276,14 @@ struct MovGraphItem {
 };
 
 class MovGraph : public MotionController {
-public:
+friend class MctlCompound;
+friend class MctlGraph;
+friend class MotionController;
+private:
 	ObList _nodes;
 	ObList _links;
 	int _field_44;
-	Common::Array<MovGraphItem *> _items;
+	Common::Array<MovGraphItem> _items;
 	MovArr *(*_callback1)(StaticANIObject *ani, Common::Array<MovItem *> *items, signed int counter);
 	AniHandler _aniHandler;
 
@@ -288,6 +291,8 @@ public:
 	MovGraph();
 	virtual ~MovGraph();
 
+	static int messageHandler(ExCommand *cmd);
+
 	virtual bool load(MfcArchive &file);
 
 	virtual void attachObject(StaticANIObject *obj);


Commit: a49b6648c83145acc6ca576865af08ce63665b1f
    https://github.com/scummvm/scummvm/commit/a49b6648c83145acc6ca576865af08ce63665b1f
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix leaks of MGMSubItem

Changed paths:
    engines/fullpipe/anihandler.cpp
    engines/fullpipe/anihandler.h


diff --git a/engines/fullpipe/anihandler.cpp b/engines/fullpipe/anihandler.cpp
index 7c91f8f..3c13a70 100644
--- a/engines/fullpipe/anihandler.cpp
+++ b/engines/fullpipe/anihandler.cpp
@@ -61,12 +61,12 @@ MessageQueue *AniHandler::makeQueue(StaticANIObject *ani, int staticsIndex, int
 	int endidx = getStaticsIndexById(idx, staticsIndex);
 	int subidx = startidx + endidx * _items[idx]->statics.size();
 
-	if (!_items[idx]->subItems[subidx]->movement) {
+	if (!_items[idx]->subItems[subidx].movement) {
 		clearVisitsList(idx);
 		seekWay(idx, startidx, endidx, 0, 1);
 	}
 
-	if (!_items[idx]->subItems[subidx]->movement)
+	if (!_items[idx]->subItems[subidx].movement)
 		return 0;
 
 	MessageQueue *mq = new MessageQueue(g_fp->_globalMessageQueueList->compact());
@@ -77,21 +77,21 @@ MessageQueue *AniHandler::makeQueue(StaticANIObject *ani, int staticsIndex, int
 	do {
 		subidx = startidx + endidx * _items[idx]->statics.size();
 
-		point = _items[idx]->subItems[subidx]->movement->calcSomeXY(0, -1);
+		point = _items[idx]->subItems[subidx].movement->calcSomeXY(0, -1);
 
 		if (pointArr) {
 			int sz;
 
-			if (_items[idx]->subItems[subidx]->movement->_currMovement)
-				sz = _items[idx]->subItems[subidx]->movement->_currMovement->_dynamicPhases.size();
+			if (_items[idx]->subItems[subidx].movement->_currMovement)
+				sz = _items[idx]->subItems[subidx].movement->_currMovement->_dynamicPhases.size();
 			else
-				sz = _items[idx]->subItems[subidx]->movement->_dynamicPhases.size();
+				sz = _items[idx]->subItems[subidx].movement->_dynamicPhases.size();
 
 			ex = new ExCommand2(20, ani->_id, &pointArr[i], sz);
 
-			ex->_messageNum = _items[idx]->subItems[subidx]->movement->_id;
+			ex->_messageNum = _items[idx]->subItems[subidx].movement->_id;
 		} else {
-			ex = new ExCommand(ani->_id, 1, _items[idx]->subItems[subidx]->movement->_id, 0, 0, 0, 1, 0, 0, 0);
+			ex = new ExCommand(ani->_id, 1, _items[idx]->subItems[subidx].movement->_id, 0, 0, 0, 1, 0, 0, 0);
 		}
 
 		ex->_param = ani->_odelay;
@@ -101,16 +101,16 @@ MessageQueue *AniHandler::makeQueue(StaticANIObject *ani, int staticsIndex, int
 		mq->addExCommandToEnd(ex);
 
 		if (resStatId)
-			*resStatId = _items[idx]->subItems[subidx]->movement->_id;
+			*resStatId = _items[idx]->subItems[subidx].movement->_id;
 
-		startidx = _items[idx]->subItems[subidx]->staticsIndex;
+		startidx = _items[idx]->subItems[subidx].staticsIndex;
 
 		uint step;
 
-		if (_items[idx]->subItems[subidx]->movement->_currMovement)
-			step = _items[idx]->subItems[subidx]->movement->_currMovement->_dynamicPhases.size();
+		if (_items[idx]->subItems[subidx].movement->_currMovement)
+			step = _items[idx]->subItems[subidx].movement->_currMovement->_dynamicPhases.size();
 		else
-			step = _items[idx]->subItems[subidx]->movement->_dynamicPhases.size();
+			step = _items[idx]->subItems[subidx].movement->_dynamicPhases.size();
 
 		i += step;
 	} while (startidx != endidx);
@@ -166,7 +166,7 @@ void AniHandler::resetData(int objId) {
 		_items[idx]->statics.push_back((Statics *)obj->_staticsList[i]);
 
 		for (uint j = 0; j < obj->_staticsList.size(); j++) // Yes, square
-			_items[idx]->subItems.push_back(new MGMSubItem);
+			_items[idx]->subItems.push_back(MGMSubItem());
 	}
 
 	for (uint i = 0; i < obj->_movements.size(); i++) {
@@ -242,17 +242,17 @@ MessageQueue *AniHandler::makeRunQueue(MakeQueueStruct *mkQueue) {
 	clearVisitsList(itemIdx);
 	seekWay(itemIdx, st1idx, subOffset, 0, 1);
 
-	MGMSubItem *sub1 = _items[itemIdx]->subItems[subIdx + st2idx * _items[itemIdx]->statics.size()];
-	MGMSubItem *sub2 = _items[itemIdx]->subItems[st1idx + subOffset * _items[itemIdx]->statics.size()];
+	const MGMSubItem &sub1 = _items[itemIdx]->subItems[subIdx + st2idx * _items[itemIdx]->statics.size()];
+	const MGMSubItem &sub2 = _items[itemIdx]->subItems[st1idx + subOffset * _items[itemIdx]->statics.size()];
 
-	if (subIdx != st2idx && !sub1->movement)
+	if (subIdx != st2idx && !sub1.movement)
 		return 0;
 
-	if (st1idx != subOffset && !sub2->movement)
+	if (st1idx != subOffset && !sub2.movement)
 		return 0;
 
-	int n1x = mkQueue->x1 - mkQueue->x2 - sub1->x - sub2->x;
-	int n1y = mkQueue->y1 - mkQueue->y2 - sub1->y - sub2->y;
+	int n1x = mkQueue->x1 - mkQueue->x2 - sub1.x - sub2.x;
+	int n1y = mkQueue->y1 - mkQueue->y2 - sub1.y - sub2.y;
 
 	const Common::Point point1 = mov->calcSomeXY(0, -1);
 
@@ -276,20 +276,20 @@ MessageQueue *AniHandler::makeRunQueue(MakeQueueStruct *mkQueue) {
 		len = -1;
 		n2x = mult * point1.x;
 		n1x = mult * point1.x;
-		mkQueue->x1 = mkQueue->x2 + mult * point1.x + sub1->x + sub2->x;
+		mkQueue->x1 = mkQueue->x2 + mult * point1.x + sub1.x + sub2.x;
 	}
 
 	if (!(mkQueue->flags & 4)) {
 		n2y = mult * point1.y;
 		n1y = mult * point1.y;
 		len = -1;
-		mkQueue->y1 = mkQueue->y2 + mult * point1.y + sub1->y + sub2->y;
+		mkQueue->y1 = mkQueue->y2 + mult * point1.y + sub1.y + sub2.y;
 	}
 
 	int px = 0;
 	int py = 0;
 
-	if (sub1->movement) {
+	if (sub1.movement) {
 		px = getFramesCount(itemIdx, subIdx, st2idx, 1);
 		py = getFramesCount(itemIdx, subIdx, st2idx, 2);
 	}
@@ -304,7 +304,7 @@ MessageQueue *AniHandler::makeRunQueue(MakeQueueStruct *mkQueue) {
 		py += mov->countPhasesWithFlag(len, 2);
 	}
 
-	if (sub2->movement) {
+	if (sub2.movement) {
 		px += getFramesCount(itemIdx, st1idx, subOffset, 1);
 		py += getFramesCount(itemIdx, st1idx, subOffset, 2);
 	}
@@ -344,15 +344,15 @@ MessageQueue *AniHandler::makeRunQueue(MakeQueueStruct *mkQueue) {
 	ExCommand2 *ex2;
 
 	for (int i = subIdx; i != st2idx;) {
-		MGMSubItem *s = _items[itemIdx]->subItems[i + st2idx * _items[itemIdx]->statics.size()];
+		const MGMSubItem &s = _items[itemIdx]->subItems[i + st2idx * _items[itemIdx]->statics.size()];
 
-		ex2 = createCommand(s->movement, mkQueue->ani->_id, x1, y1, &x2, &y2, -1);
+		ex2 = createCommand(s.movement, mkQueue->ani->_id, x1, y1, &x2, &y2, -1);
 		ex2->_parId = mq->_id;
 		ex2->_param = mkQueue->ani->_odelay;
 
 		mq->addExCommandToEnd(ex2);
 
-		i = s->staticsIndex;
+		i = s.staticsIndex;
 	}
 
 	for (int i = 0; i < mult; ++i) {
@@ -371,15 +371,15 @@ MessageQueue *AniHandler::makeRunQueue(MakeQueueStruct *mkQueue) {
 	}
 
 	for (int j = st1idx; j != subOffset;) {
-		MGMSubItem *s = _items[itemIdx]->subItems[j + subOffset * _items[itemIdx]->statics.size()];
+		const MGMSubItem &s = _items[itemIdx]->subItems[j + subOffset * _items[itemIdx]->statics.size()];
 
-		ex2 = createCommand(s->movement, mkQueue->ani->_id, x1, y1, &x2, &y2, -1);
+		ex2 = createCommand(s.movement, mkQueue->ani->_id, x1, y1, &x2, &y2, -1);
 		ex2->_parId = mq->_id;
 		ex2->_param = mkQueue->ani->_odelay;
 
 		mq->addExCommandToEnd(ex2);
 
-		j = s->staticsIndex;
+		j = s.staticsIndex;
 	}
 
 	ExCommand *ex = new ExCommand(mkQueue->ani->_id, 5, -1, mkQueue->x1, mkQueue->y1, 0, 1, 0, 0, 0);
@@ -406,9 +406,9 @@ int AniHandler::getFramesCount(int idx, int subIdx, int endIdx, int flag) {
 		if (subIdx < 0)
 			break;
 
-		res += _items[idx]->subItems[subIdx + endIdx * _items[idx]->statics.size()]->movement->countPhasesWithFlag(0xffffffff, flag);
+		res += _items[idx]->subItems[subIdx + endIdx * _items[idx]->statics.size()].movement->countPhasesWithFlag(0xffffffff, flag);
 
-		subIdx = _items[idx]->subItems[subIdx + endIdx * _items[idx]->statics.size()]->staticsIndex;
+		subIdx = _items[idx]->subItems[subIdx + endIdx * _items[idx]->statics.size()].staticsIndex;
 	}
 
 	return res;
@@ -459,23 +459,23 @@ Common::Point AniHandler::getTransitionSize(int objectId, int staticsId1, int st
 
 	int subidx = st1idx + st2idx * _items[idx]->statics.size();
 
-	if (!_items[idx]->subItems[subidx]->movement) {
+	if (!_items[idx]->subItems[subidx].movement) {
 		clearVisitsList(idx);
 		seekWay(idx, st1idx, st2idx, false, true);
 
-		if (!_items[idx]->subItems[subidx]->movement) {
+		if (!_items[idx]->subItems[subidx].movement) {
 			clearVisitsList(idx);
 			seekWay(idx, st1idx, st2idx, true, false);
 		}
 	}
 
-	const MGMSubItem *sub = _items[idx]->subItems[subidx];
+	const MGMSubItem &sub = _items[idx]->subItems[subidx];
 
-	if (!sub->movement) {
+	if (!sub.movement) {
 		return Common::Point(0, 0);
 	}
 
-	return Common::Point(sub->x, sub->y);
+	return Common::Point(sub.x, sub.y);
 }
 
 int AniHandler::getStaticsIndexById(int idx, int16 id) {
@@ -518,12 +518,12 @@ int AniHandler::seekWay(int idx, int st1idx, int st2idx, bool flip, bool flop) {
 	debugC(2, kDebugPathfinding, "AniHandler::seekWay(%d, %d, %d, %d, %d)", idx, st1idx, st2idx, flip, flop);
 
 	if (st1idx == st2idx) {
-		memset(item->subItems[subIdx], 0, sizeof(*(item->subItems[subIdx])));
+		memset(&item->subItems[subIdx], 0, sizeof(item->subItems[subIdx]));
 		return 0;
 	}
 
-	if (item->subItems[subIdx]->movement)
-		return item->subItems[subIdx]->field_8;
+	if (item->subItems[subIdx].movement)
+		return item->subItems[subIdx].field_8;
 
 	Common::Point point;
 
@@ -543,22 +543,22 @@ int AniHandler::seekWay(int idx, int st1idx, int st2idx, bool flip, bool flop) {
 			int sz = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size();
 			debugC(1, kDebugPathfinding, "AniHandler::seekWay, want idx: %d, off: %d (%d + %d), sz: %d", idx, stidx + st2idx * _items[idx]->statics.size(), stidx, st2idx, item->subItems.size());
 
-			int newsz = sz + item->subItems[stidx + st2idx * _items[idx]->statics.size()]->field_C;
+			int newsz = sz + item->subItems[stidx + st2idx * _items[idx]->statics.size()].field_C;
 
 			if (recalc < 0)
 				continue;
 
-			if (!item->subItems[subIdx]->movement || item->subItems[subIdx]->field_8 > recalc + 1 ||
-				(item->subItems[subIdx]->field_8 == recalc + 1 && item->subItems[subIdx]->field_C > newsz)) {
-				item->subItems[subIdx]->movement = mov;
-				item->subItems[subIdx]->staticsIndex = stidx;
-				item->subItems[subIdx]->field_8 = recalc + 1;
-				item->subItems[subIdx]->field_C = newsz;
+			if (!item->subItems[subIdx].movement || item->subItems[subIdx].field_8 > recalc + 1 ||
+				(item->subItems[subIdx].field_8 == recalc + 1 && item->subItems[subIdx].field_C > newsz)) {
+				item->subItems[subIdx].movement = mov;
+				item->subItems[subIdx].staticsIndex = stidx;
+				item->subItems[subIdx].field_8 = recalc + 1;
+				item->subItems[subIdx].field_C = newsz;
 
 				point = mov->calcSomeXY(0, -1);
 
-				item->subItems[subIdx]->x = item->subItems[stidx + st2idx * _items[idx]->statics.size()]->x + point.x;
-				item->subItems[subIdx]->y = item->subItems[stidx + st2idx * _items[idx]->statics.size()]->y + point.y;
+				item->subItems[subIdx].x = item->subItems[stidx + st2idx * _items[idx]->statics.size()].x + point.x;
+				item->subItems[subIdx].y = item->subItems[stidx + st2idx * _items[idx]->statics.size()].y + point.y;
 			}
 		} else if (flip) {
 			if (mov->_staticsObj2 != item->statics[st1idx])
@@ -575,25 +575,25 @@ int AniHandler::seekWay(int idx, int st1idx, int st2idx, bool flip, bool flop) {
 			if (recalc < 0)
 				continue;
 
-			if (!item->subItems[subIdx]->movement || item->subItems[subIdx]->field_8 > recalc + 1) {
-				item->subItems[subIdx]->movement = mov;
-				item->subItems[subIdx]->staticsIndex = stidx;
-				item->subItems[subIdx]->field_8 = recalc + 1;
+			if (!item->subItems[subIdx].movement || item->subItems[subIdx].field_8 > recalc + 1) {
+				item->subItems[subIdx].movement = mov;
+				item->subItems[subIdx].staticsIndex = stidx;
+				item->subItems[subIdx].field_8 = recalc + 1;
 
 				int sz = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size();
 
-				item->subItems[subIdx]->field_C = sz + item->subItems[stidx + st2idx * _items[idx]->statics.size()]->field_C;
+				item->subItems[subIdx].field_C = sz + item->subItems[stidx + st2idx * _items[idx]->statics.size()].field_C;
 
 				point = mov->calcSomeXY(0, -1);
 
-				item->subItems[subIdx]->x = item->subItems[stidx + st2idx * _items[idx]->statics.size()]->x - point.x;
-				item->subItems[subIdx]->y = item->subItems[stidx + st2idx * _items[idx]->statics.size()]->y - point.y;
+				item->subItems[subIdx].x = item->subItems[stidx + st2idx * _items[idx]->statics.size()].x - point.x;
+				item->subItems[subIdx].y = item->subItems[stidx + st2idx * _items[idx]->statics.size()].y - point.y;
 			}
 		}
 	}
 
-	if (item->subItems[subIdx]->movement)
-		return item->subItems[subIdx]->field_8;
+	if (item->subItems[subIdx].movement)
+		return item->subItems[subIdx].field_8;
 
 	return -1;
 }
@@ -608,10 +608,10 @@ int AniHandler::getNumMovements(int objectId, int idx1, int idx2) {
 		int to = getStaticsIndexById(idx, idx2);
 
 		debugC(1, kDebugPathfinding, "WWW 6, want idx: %d, off: %d", idx, from + to * _items[idx]->statics.size());
-		MGMSubItem *sub = _items[idx]->subItems[from + to * _items[idx]->statics.size()];
+		const MGMSubItem &sub = _items[idx]->subItems[from + to * _items[idx]->statics.size()];
 
-		if (sub->movement) {
-			idx = sub->field_8;
+		if (sub.movement) {
+			idx = sub.field_8;
 		} else {
 			clearVisitsList(idx);
 			idx = seekWay(idx, from, to, 0, 1);
diff --git a/engines/fullpipe/anihandler.h b/engines/fullpipe/anihandler.h
index 6807629..73f96c3 100644
--- a/engines/fullpipe/anihandler.h
+++ b/engines/fullpipe/anihandler.h
@@ -42,7 +42,7 @@ struct MGMSubItem {
 
 struct MGMItem {
 	int16 objId;
-	Common::Array<MGMSubItem *> subItems;
+	Common::Array<MGMSubItem> subItems;
 	Common::Array<Statics *> statics;
 	Common::Array<Movement *> movements1;
 	Common::Array<int> movements2;


Commit: a25246bebe860aa7057e4c8901234c9d5f52b814
    https://github.com/scummvm/scummvm/commit/a25246bebe860aa7057e4c8901234c9d5f52b814
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Remove unnecessary extra allocation for RNG

Changed paths:
    engines/fullpipe/behavior.cpp
    engines/fullpipe/floaters.cpp
    engines/fullpipe/fullpipe.cpp
    engines/fullpipe/fullpipe.h
    engines/fullpipe/scenes/scene02.cpp
    engines/fullpipe/scenes/scene04.cpp
    engines/fullpipe/scenes/scene05.cpp
    engines/fullpipe/scenes/scene06.cpp
    engines/fullpipe/scenes/scene12.cpp
    engines/fullpipe/scenes/scene15.cpp
    engines/fullpipe/scenes/scene17.cpp
    engines/fullpipe/scenes/scene18and19.cpp
    engines/fullpipe/scenes/scene20.cpp
    engines/fullpipe/scenes/scene25.cpp
    engines/fullpipe/scenes/scene27.cpp
    engines/fullpipe/scenes/scene28.cpp
    engines/fullpipe/scenes/scene29.cpp
    engines/fullpipe/scenes/scene34.cpp
    engines/fullpipe/scenes/scene35.cpp
    engines/fullpipe/scenes/scene38.cpp


diff --git a/engines/fullpipe/behavior.cpp b/engines/fullpipe/behavior.cpp
index 8c0bf91..61327c2 100644
--- a/engines/fullpipe/behavior.cpp
+++ b/engines/fullpipe/behavior.cpp
@@ -139,7 +139,7 @@ void BehaviorManager::updateBehavior(BehaviorInfo *behaviorInfo, BehaviorAnim *e
 				mq->sendNextCommand();
 
 				bhi->_flags &= 0xFFFFFFFD;
-			} else if (behaviorInfo->_counter >= bhi->_delay && bhi->_percent && g_fp->_rnd->getRandomNumber(32767) <= entry->_behaviorMoves[i]->_percent) {
+			} else if (behaviorInfo->_counter >= bhi->_delay && bhi->_percent && g_fp->_rnd.getRandomNumber(32767) <= entry->_behaviorMoves[i]->_percent) {
 				MessageQueue *mq = new MessageQueue(bhi->_messageQueue, 0, 1);
 
 				mq->sendNextCommand();
@@ -156,7 +156,7 @@ void BehaviorManager::updateStaticAniBehavior(StaticANIObject *ani, int delay, B
 	MessageQueue *mq = 0;
 
 	if (bhe->_flags & 1) {
-		uint rnd = g_fp->_rnd->getRandomNumber(32767);
+		uint rnd = g_fp->_rnd.getRandomNumber(32767);
 		uint runPercent = 0;
 		for (int i = 0; i < bhe->_movesCount; i++) {
 			if (!(bhe->_behaviorMoves[i]->_flags & 1) && bhe->_behaviorMoves[i]->_percent) {
@@ -171,7 +171,7 @@ void BehaviorManager::updateStaticAniBehavior(StaticANIObject *ani, int delay, B
 		for (int i = 0; i < bhe->_movesCount; i++) {
 			if (!(bhe->_behaviorMoves[i]->_flags & 1) && delay >= bhe->_behaviorMoves[i]->_delay) {
 				if (bhe->_behaviorMoves[i]->_percent) {
-					if (g_fp->_rnd->getRandomNumber(32767) <= bhe->_behaviorMoves[i]->_percent) {
+					if (g_fp->_rnd.getRandomNumber(32767) <= bhe->_behaviorMoves[i]->_percent) {
 						mq = new MessageQueue(bhe->_behaviorMoves[i]->_messageQueue, 0, 1);
 						break;
 					}
diff --git a/engines/fullpipe/floaters.cpp b/engines/fullpipe/floaters.cpp
index aaeefb2..01afa24 100644
--- a/engines/fullpipe/floaters.cpp
+++ b/engines/fullpipe/floaters.cpp
@@ -111,7 +111,7 @@ void Floaters::genFlies(Scene *sc, int x, int y, int priority, int flags) {
 	else
 		nummoves = ani->_movement->_dynamicPhases.size();
 
-	ani->_movement->setDynamicPhaseIndex(g_fp->_rnd->getRandomNumber(nummoves - 1));
+	ani->_movement->setDynamicPhaseIndex(g_fp->_rnd.getRandomNumber(nummoves - 1));
 
 	FloaterArray2 *arr2 = new FloaterArray2;
 
@@ -165,7 +165,7 @@ void Floaters::update() {
 				if (_array2[i]->val4 == _array2[i]->val2 && _array2[i]->val5 == _array2[i]->val3) {
 					_array2[i]->val9 = 0.0;
 
-					_array2[i]->val13 = g_fp->_rnd->getRandomNumber(200) + 20;
+					_array2[i]->val13 = g_fp->_rnd.getRandomNumber(200) + 20;
 
 					if (_array2[i]->fflags & 1) {
 						g_fp->_currentScene->deleteStaticANIObject(_array2[i]->ani);
@@ -190,7 +190,7 @@ void Floaters::update() {
 					_array2[i]->val3 = _array2[i]->val7;
 				} else {
 					if (_array2[i]->fflags & 2) {
-						int idx1 = g_fp->_rnd->getRandomNumber(_array1.size() - 1);
+						int idx1 = g_fp->_rnd.getRandomNumber(_array1.size() - 1);
 
 						_array2[i]->val2 = _array1[idx1]->val1;
 						_array2[i]->val3 = _array1[idx1]->val2;
@@ -202,8 +202,8 @@ void Floaters::update() {
 
 						_hRgn->getBBox(&rect);
 
-						int x2 = rect.left + g_fp->_rnd->getRandomNumber(rect.right - rect.left);
-						int y2 = rect.top + g_fp->_rnd->getRandomNumber(rect.bottom - rect.top);
+						int x2 = rect.left + g_fp->_rnd.getRandomNumber(rect.right - rect.left);
+						int y2 = rect.top + g_fp->_rnd.getRandomNumber(rect.bottom - rect.top);
 
 						if (_hRgn->pointInRegion(x2, y2)) {
 							int dx = _array2[i]->val2 - x2;
diff --git a/engines/fullpipe/fullpipe.cpp b/engines/fullpipe/fullpipe.cpp
index 122b685..4bcdac7 100644
--- a/engines/fullpipe/fullpipe.cpp
+++ b/engines/fullpipe/fullpipe.cpp
@@ -48,7 +48,10 @@ namespace Fullpipe {
 FullpipeEngine *g_fp = 0;
 Vars *g_vars = 0;
 
-FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
+FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc) :
+	Engine(syst),
+	_gameDescription(gameDesc),
+	_rnd("fullpipe") {
 	DebugMan.addDebugChannel(kDebugPathfinding, "path", "Pathfinding");
 	DebugMan.addDebugChannel(kDebugDrawing, "drawing", "Drawing");
 	DebugMan.addDebugChannel(kDebugLoading, "loading", "Scene loading");
@@ -69,7 +72,6 @@ FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc)
 	_sfxVolume = ConfMan.getInt("sfx_volume") * 39 - 10000;
 	_musicVolume = ConfMan.getInt("music_volume");
 
-	_rnd = new Common::RandomSource("fullpipe");
 	_console = 0;
 
 	_gameProjectVersion = 0;
@@ -203,7 +205,6 @@ FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc)
 }
 
 FullpipeEngine::~FullpipeEngine() {
-	delete _rnd;
 	delete _console;
 	delete _globalMessageQueueList;
 	delete _soundStream1;
diff --git a/engines/fullpipe/fullpipe.h b/engines/fullpipe/fullpipe.h
index d5aa730..ddcb5ad 100644
--- a/engines/fullpipe/fullpipe.h
+++ b/engines/fullpipe/fullpipe.h
@@ -115,7 +115,7 @@ public:
 	bool isDemo();
 	Common::Language getLanguage() const;
 
-	Common::RandomSource *_rnd;
+	Common::RandomSource _rnd;
 
 	Common::KeyCode _keyState;
 	uint16 _buttonState;
diff --git a/engines/fullpipe/scenes/scene02.cpp b/engines/fullpipe/scenes/scene02.cpp
index fd542d5..e2350a9 100644
--- a/engines/fullpipe/scenes/scene02.cpp
+++ b/engines/fullpipe/scenes/scene02.cpp
@@ -56,7 +56,7 @@ void scene02_initScene(Scene *sc) {
 		g_vars->scene02_boxOpen = false;
 	} else {
 		g_vars->scene02_boxOpen = true;
-		g_vars->scene02_boxDelay = 100 * g_fp->_rnd->getRandomNumber(32767) + 150;
+		g_vars->scene02_boxDelay = 100 * g_fp->_rnd.getRandomNumber(32767) + 150;
 	}
 
 	g_fp->_floaters->init(g_fp->_gameLoader->_gameVar->getSubVarByName("SC_2"));
@@ -116,13 +116,13 @@ int sceneHandler02(ExCommand *ex) {
 				if (g_fp->_floaters->_array2[0]->val5 == -50) {
 					g_fp->_floaters->stopAll();
 					g_vars->scene02_boxOpen = false;
-					g_vars->scene02_boxDelay = 100 * g_fp->_rnd->getRandomNumber(32767) + 150;
+					g_vars->scene02_boxDelay = 100 * g_fp->_rnd.getRandomNumber(32767) + 150;
 				} else {
 					g_fp->_floaters->_array2[0]->val3 = -50;
 				}
 			} else {
-				g_fp->_floaters->genFlies(g_fp->_currentScene, g_fp->_rnd->getRandomNumber(700) + 100, -50, 0, 0);
-				g_vars->scene02_boxDelay = 500 * g_fp->_rnd->getRandomNumber(32767) + 1000;
+				g_fp->_floaters->genFlies(g_fp->_currentScene, g_fp->_rnd.getRandomNumber(700) + 100, -50, 0, 0);
+				g_vars->scene02_boxDelay = 500 * g_fp->_rnd.getRandomNumber(32767) + 1000;
 			}
 		}
 
diff --git a/engines/fullpipe/scenes/scene04.cpp b/engines/fullpipe/scenes/scene04.cpp
index 228fc77..b78d66d 100644
--- a/engines/fullpipe/scenes/scene04.cpp
+++ b/engines/fullpipe/scenes/scene04.cpp
@@ -56,7 +56,7 @@ void scene04_speakerCallback(int *phase) {
 
 			if (scene04_speakerPhases[g_vars->scene04_speakerPhase + 6 * g_vars->scene04_speakerVariant] < 0) {
 				g_vars->scene04_speakerPhase = 0;
-				g_vars->scene04_speakerVariant = g_fp->_rnd->getRandomNumber(2);
+				g_vars->scene04_speakerVariant = g_fp->_rnd.getRandomNumber(2);
 			}
 		} else {
 			++g_vars->scene04_speakerPhase;
@@ -709,9 +709,9 @@ MessageQueue *sceneHandler04_kozFly6(StaticANIObject *ani) {
 
 	mkQueue.ani = ani;
 	mkQueue.staticsId2 = ST_KZW_SIT;
-	mkQueue.x1 = 397 - 4 * g_fp->_rnd->getRandomNumber(1);
+	mkQueue.x1 = 397 - 4 * g_fp->_rnd.getRandomNumber(1);
 	mkQueue.field_1C = ani->_priority;
-	mkQueue.y1 = g_vars->scene04_bottle->_oy - 4 * g_fp->_rnd->getRandomNumber(1) + 109;
+	mkQueue.y1 = g_vars->scene04_bottle->_oy - 4 * g_fp->_rnd.getRandomNumber(1) + 109;
 	mkQueue.field_10 = 1;
 	mkQueue.flags = 78;
 	mkQueue.movementId = MV_KZW_JUMPROTATE;
@@ -1253,7 +1253,7 @@ void sceneHandler04_bigBallWalkIn() {
 		 && (!ball || !(ball->_flags & 4))
 		 && g_vars->scene04_ladder->collisionDetection(g_fp->_aniMan) > 3) {
 
-		if (!g_fp->_rnd->getRandomNumber(49)) {
+		if (!g_fp->_rnd.getRandomNumber(49)) {
 			if (g_vars->scene04_bigBallFromLeft)
 				chainQueue(QU_BALL_WALKR, 0);
 			else
diff --git a/engines/fullpipe/scenes/scene05.cpp b/engines/fullpipe/scenes/scene05.cpp
index b8ecdc4..35fd24e 100644
--- a/engines/fullpipe/scenes/scene05.cpp
+++ b/engines/fullpipe/scenes/scene05.cpp
@@ -151,12 +151,12 @@ void sceneHandler05_genFlies() {
 	if (g_vars->scene05_floatersTicker <= 1000)
 		return;
 
-	if (g_fp->_rnd->getRandomNumber(1)) {
-		int numFlies = g_fp->_rnd->getRandomNumber(3) + 1;
+	if (g_fp->_rnd.getRandomNumber(1)) {
+		int numFlies = g_fp->_rnd.getRandomNumber(3) + 1;
 
 		for (int i = 0; i < numFlies; i++) {
-			int x = g_fp->_rnd->getRandomNumber(55) + 538;
-			int y = g_fp->_rnd->getRandomNumber(60) + i * 30 + 520;
+			int x = g_fp->_rnd.getRandomNumber(55) + 538;
+			int y = g_fp->_rnd.getRandomNumber(60) + i * 30 + 520;
 
 			g_fp->_floaters->genFlies(g_fp->_currentScene, x, y, 5, 1);
 			g_fp->_floaters->_array2.back()->val2 = 585;
diff --git a/engines/fullpipe/scenes/scene06.cpp b/engines/fullpipe/scenes/scene06.cpp
index 4e003c6..f434848 100644
--- a/engines/fullpipe/scenes/scene06.cpp
+++ b/engines/fullpipe/scenes/scene06.cpp
@@ -382,7 +382,7 @@ void sceneHandler06_throwBall() {
 }
 
 void sceneHandler06_eggieWalk() {
-	if (15 - g_vars->scene06_numBallsGiven >= 4 && !g_fp->_rnd->getRandomNumber(9)) {
+	if (15 - g_vars->scene06_numBallsGiven >= 4 && !g_fp->_rnd.getRandomNumber(9)) {
 		StaticANIObject *ani = g_fp->_currentScene->getStaticANIObject1ById(ANI_EGGIE, -1);
 
 		if (!ani || !(ani->_flags & 4)) {
diff --git a/engines/fullpipe/scenes/scene12.cpp b/engines/fullpipe/scenes/scene12.cpp
index f63bb9a..23bab31 100644
--- a/engines/fullpipe/scenes/scene12.cpp
+++ b/engines/fullpipe/scenes/scene12.cpp
@@ -42,15 +42,15 @@ void scene12_initScene(Scene *sc) {
 	g_vars->scene12_fly = g_fp->getObjectState(sO_Fly_12);
 
 	if (g_vars->scene12_fly)
-		g_vars->scene12_flyCountdown = g_fp->_rnd->getRandomNumber(600) + 600;
+		g_vars->scene12_flyCountdown = g_fp->_rnd.getRandomNumber(600) + 600;
 
-	g_fp->setObjectState(sO_Fly_12, g_fp->_rnd->getRandomNumber(1));
+	g_fp->setObjectState(sO_Fly_12, g_fp->_rnd.getRandomNumber(1));
 }
 
 void sceneHandler12_updateFloaters() {
 	g_fp->_floaters->genFlies(g_fp->_currentScene, 397, -50, 100, 6);
 
-	g_fp->_floaters->_array2[0]->countdown = g_fp->_rnd->getRandomNumber(6) + 4;
+	g_fp->_floaters->_array2[0]->countdown = g_fp->_rnd.getRandomNumber(6) + 4;
 	g_fp->_floaters->_array2[0]->val6 = 397;
 	g_fp->_floaters->_array2[0]->val7 = -50;
 }
diff --git a/engines/fullpipe/scenes/scene15.cpp b/engines/fullpipe/scenes/scene15.cpp
index 436a043..cb4ae39 100644
--- a/engines/fullpipe/scenes/scene15.cpp
+++ b/engines/fullpipe/scenes/scene15.cpp
@@ -128,7 +128,7 @@ int sceneHandler15(ExCommand *cmd) {
 		break;
 
 	case MSG_SC15_ASSDRYG:
-		if (g_fp->_rnd->getRandomNumber(1))
+		if (g_fp->_rnd.getRandomNumber(1))
 			g_fp->playSound(SND_15_011, 0);
 		else
 			g_fp->playSound(SND_15_006, 0);
diff --git a/engines/fullpipe/scenes/scene17.cpp b/engines/fullpipe/scenes/scene17.cpp
index 3ea35b7..a830a8f 100644
--- a/engines/fullpipe/scenes/scene17.cpp
+++ b/engines/fullpipe/scenes/scene17.cpp
@@ -62,9 +62,9 @@ void scene17_restoreState() {
 	g_vars->scene17_flyState = g_fp->getObjectState(sO_Fly_17);
 
 	if (g_vars->scene17_flyState <= 0 ) {
-		g_vars->scene17_flyCountdown = g_fp->_rnd->getRandomNumber(600) + 600;
+		g_vars->scene17_flyCountdown = g_fp->_rnd.getRandomNumber(600) + 600;
 
-		g_vars->scene17_flyState = g_fp->_rnd->getRandomNumber(4) + 1;
+		g_vars->scene17_flyState = g_fp->_rnd.getRandomNumber(4) + 1;
 	}
 
 	g_fp->setObjectState(sO_Fly_17, g_vars->scene17_flyState - 1);
@@ -157,7 +157,7 @@ void sceneHandler17_moonshineFill() {
 void sceneHandler17_updateFlies() {
 	g_fp->_floaters->genFlies(g_fp->_currentScene, 239, -50, 20, 4);
 
-	g_fp->_floaters->_array2[0]->countdown = g_fp->_rnd->getRandomNumber(5) + 6;
+	g_fp->_floaters->_array2[0]->countdown = g_fp->_rnd.getRandomNumber(5) + 6;
 	g_fp->_floaters->_array2[0]->val6 = 239;
 	g_fp->_floaters->_array2[0]->val7 = -50;
 }
diff --git a/engines/fullpipe/scenes/scene18and19.cpp b/engines/fullpipe/scenes/scene18and19.cpp
index eb338ea..7e26632 100644
--- a/engines/fullpipe/scenes/scene18and19.cpp
+++ b/engines/fullpipe/scenes/scene18and19.cpp
@@ -181,7 +181,7 @@ void scene18_setupSwingers(StaticANIObject *ani, Scene *sc) {
 		else
 			ani->startAnim(MV_KSL_SWING, 0, -1);
 
-		ani->_movement->setDynamicPhaseIndex(g_fp->_rnd->getRandomNumber(17));
+		ani->_movement->setDynamicPhaseIndex(g_fp->_rnd.getRandomNumber(17));
 
 		g_vars->scene18_swingers.push_back(swinger);
 	}
diff --git a/engines/fullpipe/scenes/scene20.cpp b/engines/fullpipe/scenes/scene20.cpp
index ab3e474..9085f02 100644
--- a/engines/fullpipe/scenes/scene20.cpp
+++ b/engines/fullpipe/scenes/scene20.cpp
@@ -84,13 +84,13 @@ void scene20_initScene(Scene *sc) {
 	g_fp->_floaters->init(g_fp->getGameLoaderGameVar()->getSubVarByName("SC_20"));
 
 	for (int i = 0; i < 3; i++) {
-		g_fp->_floaters->genFlies(sc, g_fp->_rnd->getRandomNumber(101) + 70, g_fp->_rnd->getRandomNumber(51) + 175, 100, 0);
-		g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->val13 = g_fp->_rnd->getRandomNumber(9);
+		g_fp->_floaters->genFlies(sc, g_fp->_rnd.getRandomNumber(101) + 70, g_fp->_rnd.getRandomNumber(51) + 175, 100, 0);
+		g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->val13 = g_fp->_rnd.getRandomNumber(9);
 	}
 
 	g_fp->_currentScene = oldsc;
 
-	g_vars->scene20_fliesCountdown = g_fp->_rnd->getRandomNumber(200) + 400;
+	g_vars->scene20_fliesCountdown = g_fp->_rnd.getRandomNumber(200) + 400;
 }
 
 void sceneHandler20_updateFlies() {
@@ -101,7 +101,7 @@ void sceneHandler20_updateFlies() {
 		g_fp->_floaters->_array2[sz - 1]->val2 = 250;
 		g_fp->_floaters->_array2[sz - 1]->val3 = 200;
 	} else {
-		int idx = g_fp->_rnd->getRandomNumber(sz);
+		int idx = g_fp->_rnd.getRandomNumber(sz);
 
 		g_fp->_floaters->_array2[idx]->countdown = 0;
 		g_fp->_floaters->_array2[idx]->fflags |= 4u;
@@ -112,7 +112,7 @@ void sceneHandler20_updateFlies() {
 		g_fp->_floaters->_array2[idx]->ani->_priority = 200;
 	}
 
-	g_vars->scene20_fliesCountdown = g_fp->_rnd->getRandomNumber(200) + 400;
+	g_vars->scene20_fliesCountdown = g_fp->_rnd.getRandomNumber(200) + 400;
 }
 
 int sceneHandler20(ExCommand *cmd) {
diff --git a/engines/fullpipe/scenes/scene25.cpp b/engines/fullpipe/scenes/scene25.cpp
index 8323e3d..248049f 100644
--- a/engines/fullpipe/scenes/scene25.cpp
+++ b/engines/fullpipe/scenes/scene25.cpp
@@ -229,29 +229,29 @@ void sceneHandler25_toLadder() {
 }
 
 void sceneHandler25_animateBearders() {
-	if (g_fp->_rnd->getRandomNumber(32767) < 218) {
+	if (g_fp->_rnd.getRandomNumber(32767) < 218) {
 		MessageQueue *mq;
 
 		mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC25_BEARDED), 0, 1);
 
 		mq->setParamInt(-1, g_vars->scene25_bearders[0]->_odelay);
-		mq->getExCommandByIndex(0)->_x = g_fp->_rnd->getRandomNumber(650) + 100;
+		mq->getExCommandByIndex(0)->_x = g_fp->_rnd.getRandomNumber(650) + 100;
 		mq->chain(0);
 
 		g_vars->scene25_beardersCounter = 0;
 
-		if (g_fp->_rnd->getRandomNumber(32767) < 0x1FFF) {
+		if (g_fp->_rnd.getRandomNumber(32767) < 0x1FFF) {
 			mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC25_BEARDED2), 0, 1);
 
 			mq->setParamInt(-1, g_vars->scene25_bearders[1]->_odelay);
-			mq->getExCommandByIndex(0)->_x = g_fp->_rnd->getRandomNumber(650) + 100;
+			mq->getExCommandByIndex(0)->_x = g_fp->_rnd.getRandomNumber(650) + 100;
 			mq->chain(0);
 
-			if (g_fp->_rnd->getRandomNumber(32767) < 8191) {
+			if (g_fp->_rnd.getRandomNumber(32767) < 8191) {
 				mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC25_BEARDED3), 0, 1);
 
 				mq->setParamInt(-1, g_vars->scene25_bearders[2]->_odelay);
-				mq->getExCommandByIndex(0)->_x = g_fp->_rnd->getRandomNumber(650) + 100;
+				mq->getExCommandByIndex(0)->_x = g_fp->_rnd.getRandomNumber(650) + 100;
 				mq->chain(0);
 			}
 		}
@@ -259,7 +259,7 @@ void sceneHandler25_animateBearders() {
 }
 
 void sceneHandler25_sneeze() {
-	if (g_fp->_rnd->getRandomNumber(32767) % 10) {
+	if (g_fp->_rnd.getRandomNumber(32767) % 10) {
 		if (g_fp->_aniMan->_statics->_staticsId == ST_MAN25_ONBOARD) {
 			g_fp->_aniMan->startAnim(MV_MAN25_ONBOARD, 0, -1);
 		} else if (g_fp->_aniMan->_statics->_staticsId == (ST_MAN25_ONBOARD|0x4000)) {
@@ -570,7 +570,7 @@ int sceneHandler25(ExCommand *cmd) {
 		break;
 
 	case MSG_BRD_TURN:
-		switch (g_fp->_rnd->getRandomNumber(3)) {
+		switch (g_fp->_rnd.getRandomNumber(3)) {
 		case 0:
 			g_fp->playSound(SND_25_025, 0);
 			break;
diff --git a/engines/fullpipe/scenes/scene27.cpp b/engines/fullpipe/scenes/scene27.cpp
index aaf7fab..7a9a25d 100644
--- a/engines/fullpipe/scenes/scene27.cpp
+++ b/engines/fullpipe/scenes/scene27.cpp
@@ -335,7 +335,7 @@ void sceneHandler27_knockBats(int bat1n, int bat2n) {
 	debugC(2, kDebugSceneLogic, "scene27: knockBats(%d, %d)", bat1n, bat2n);
 
 	if (bat1->power != 0.0) {
-		double rndF = (double)g_fp->_rnd->getRandomNumber(32767) * 0.03 / 32767.0 - 0.015
+		double rndF = (double)g_fp->_rnd.getRandomNumber(32767) * 0.03 / 32767.0 - 0.015
 			+ atan2(bat2->currY - bat1->currY, bat2->currX - bat1->currX);
 
 		double pow1x = cos(bat1->angle - rndF) * ((bat2->currX - bat1->currX) >= 0 ? bat1->power : -bat1->power);
@@ -349,7 +349,7 @@ void sceneHandler27_knockBats(int bat1n, int bat2n) {
 
 		debugC(3, kDebugSceneLogic, "scene27: knockBats: bat1 to: powerCos: %f powerSin: %f", bat1->powerCos, bat1->powerSin);
 
-		double rndF2 = (double)g_fp->_rnd->getRandomNumber(32767) * 0.03 / 32767.0 - 0.015
+		double rndF2 = (double)g_fp->_rnd.getRandomNumber(32767) * 0.03 / 32767.0 - 0.015
 								+ atan2(bat1->currY - bat2->currY, bat1->currX - bat2->currX);
 		double pow2x = cos(bat2->angle - rndF2) * ((bat1->currX - bat2->currX) >= 0 ? bat2->power : -bat2->power);
 		double pow2y = sin(bat2->angle - rndF2) * ((bat1->currY - bat2->currY) >= 0 ? bat2->power : -bat2->power);
diff --git a/engines/fullpipe/scenes/scene28.cpp b/engines/fullpipe/scenes/scene28.cpp
index 275c788..7cf683a 100644
--- a/engines/fullpipe/scenes/scene28.cpp
+++ b/engines/fullpipe/scenes/scene28.cpp
@@ -86,7 +86,7 @@ void sceneHandler28_makeFaces(ExCommand *cmd) {
 		for (int i = 0; i < 5; i++) {
 			int pos;
 
-			while (frames[pos = g_fp->_rnd->getRandomNumber(4)] == 0)
+			while (frames[pos = g_fp->_rnd.getRandomNumber(4)] == 0)
 				;
 
 			mq->getExCommandByIndex(i)->_messageNum = frames[pos];
@@ -173,12 +173,12 @@ void sceneHandler28_turnOn2() {
 		g_fp->_floaters->genFlies(g_fp->_currentScene, 1013, 329, 60, 4);
 
 		g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->val13 = 30;
-		g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->countdown = g_fp->_rnd->getRandomNumber(12) + 12;
+		g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->countdown = g_fp->_rnd.getRandomNumber(12) + 12;
 
 		g_fp->_floaters->genFlies(g_fp->_currentScene, 1074, 311, 60, 4);
 
 		g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->val13 = 30;
-		g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->countdown = g_fp->_rnd->getRandomNumber(12) + 12;
+		g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->countdown = g_fp->_rnd.getRandomNumber(12) + 12;
 	}
 
 	g_vars->scene28_fliesArePresent = false;
diff --git a/engines/fullpipe/scenes/scene29.cpp b/engines/fullpipe/scenes/scene29.cpp
index 862b691..62af438 100644
--- a/engines/fullpipe/scenes/scene29.cpp
+++ b/engines/fullpipe/scenes/scene29.cpp
@@ -569,7 +569,7 @@ void sceneHandler29_manRideBack() {
 
 void sceneHandler29_shoot() {
 	if (g_vars->scene29_arcadeIsOn && g_vars->scene29_manX < 1310) {
-		if (g_fp->_rnd->getRandomNumber(32767) <= 16383|| g_vars->scene29_shooter1->_movement || g_vars->scene29_shooter1->_statics->_staticsId != ST_STR1_RIGHT) {
+		if (g_fp->_rnd.getRandomNumber(32767) <= 16383|| g_vars->scene29_shooter1->_movement || g_vars->scene29_shooter1->_statics->_staticsId != ST_STR1_RIGHT) {
 			if (!g_vars->scene29_shooter2->_movement && g_vars->scene29_shooter2->_statics->_staticsId == ST_STR2_RIGHT) {
 				if (g_vars->scene29_shooter2->_flags & 4) {
 					g_vars->scene29_shooter2->startAnim(MV_STR2_SHOOT, 0, -1);
@@ -637,7 +637,7 @@ void sceneHandler29_animBearded() {
 		if (g_vars->scene29_arcadeIsOn && g_vars->scene29_bearders[i]->wbcounter > 30) {
 			int newx;
 
-			if (g_fp->_rnd->getRandomNumber(1))
+			if (g_fp->_rnd.getRandomNumber(1))
 				goto dostuff;
 
 			if (g_vars->scene29_manX <= 700) {
diff --git a/engines/fullpipe/scenes/scene34.cpp b/engines/fullpipe/scenes/scene34.cpp
index 69f3cd5..040d023 100644
--- a/engines/fullpipe/scenes/scene34.cpp
+++ b/engines/fullpipe/scenes/scene34.cpp
@@ -87,7 +87,7 @@ void scene34_initScene(Scene *sc) {
 	g_vars->scene34_dudeClimbed = false;
 	g_vars->scene34_dudeOnBoard = false;
 	g_vars->scene34_dudeOnCactus = false;
-	g_vars->scene34_fliesCountdown = g_fp->_rnd->getRandomNumber(500) + 500;
+	g_vars->scene34_fliesCountdown = g_fp->_rnd.getRandomNumber(500) + 500;
 
 	g_fp->_floaters->init(g_fp->getGameLoaderGameVar()->getSubVarByName("SC_34"));
 
@@ -164,7 +164,7 @@ void sceneHandler34_genFlies() {
 	g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->val6 = 1072;
 	g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->val7 = -50;
 
-	g_vars->scene34_fliesCountdown = g_fp->_rnd->getRandomNumber(500) + 500;
+	g_vars->scene34_fliesCountdown = g_fp->_rnd.getRandomNumber(500) + 500;
 }
 
 void sceneHandler34_fromCactus(ExCommand *cmd) {
diff --git a/engines/fullpipe/scenes/scene35.cpp b/engines/fullpipe/scenes/scene35.cpp
index e8b08b2..ed2ab46 100644
--- a/engines/fullpipe/scenes/scene35.cpp
+++ b/engines/fullpipe/scenes/scene35.cpp
@@ -123,10 +123,10 @@ void sceneHandler35_genFlies() {
 	StaticANIObject *fly = g_fp->_currentScene->getStaticANIObject1ById(ANI_FLY, -1);
 
 	int xoff = 0;
-	if ((!fly || !(fly->_flags & 4)) && !(g_fp->_rnd->getRandomNumber(32767) % 30)) {
+	if ((!fly || !(fly->_flags & 4)) && !(g_fp->_rnd.getRandomNumber(32767) % 30)) {
 		int x, y;
 
-		if (g_fp->_rnd->getRandomNumber(1)) {
+		if (g_fp->_rnd.getRandomNumber(1)) {
 			x = 600;
 			y = 0;
 		} else {
@@ -134,10 +134,10 @@ void sceneHandler35_genFlies() {
 			y = 600;
 		}
 
-		int numFlies = g_fp->_rnd->getRandomNumber(3) + 1;
+		int numFlies = g_fp->_rnd.getRandomNumber(3) + 1;
 
 		while (numFlies--) {
-			g_fp->_floaters->genFlies(g_fp->_currentScene, g_fp->_rnd->getRandomNumber(55) + 1057,  g_fp->_rnd->getRandomNumber(60) + x + xoff, 4, 1);
+			g_fp->_floaters->genFlies(g_fp->_currentScene, g_fp->_rnd.getRandomNumber(55) + 1057,  g_fp->_rnd.getRandomNumber(60) + x + xoff, 4, 1);
 
 			xoff += 40;
 
diff --git a/engines/fullpipe/scenes/scene38.cpp b/engines/fullpipe/scenes/scene38.cpp
index 2bdae1c..3bcbabe 100644
--- a/engines/fullpipe/scenes/scene38.cpp
+++ b/engines/fullpipe/scenes/scene38.cpp
@@ -101,7 +101,7 @@ void sceneHandler38_propose() {
 	if (!g_vars->scene38_tally->_movement) {
 		if (g_vars->scene38_tally->_flags & 4) {
 			if (!(g_vars->scene38_tally->_flags & 2) && g_vars->scene38_tallyCounter > 0
-				&& g_fp->_rnd->getRandomNumber(32767) < 32767) {
+				&& g_fp->_rnd.getRandomNumber(32767) < 32767) {
 				chainQueue(QU_DLD_DENY, 0);
 				g_vars->scene38_tallyCounter = 0;
 			}
@@ -112,7 +112,7 @@ void sceneHandler38_propose() {
 void sceneHandler38_point() {
 	if ((!g_vars->scene38_boss->_movement && ((g_vars->scene38_boss->_flags & 4) || !(g_vars->scene38_boss->_flags & 2)))
 		&& g_vars->scene38_bossCounter > 0
-		&& g_fp->_rnd->getRandomNumber(32767) < 32767) {
+		&& g_fp->_rnd.getRandomNumber(32767) < 32767) {
 		if (g_vars->scene38_boss->_statics->_staticsId == ST_GLV_HAMMER) {
 			chainQueue(QU_GLV_TOSMALL, 0);
 			g_vars->scene38_bossCounter = 0;
@@ -130,7 +130,7 @@ void sceneHandler38_hammerKick() {
 		if (g_vars->scene38_shorty->_flags & 4) {
 			if (!(g_vars->scene38_shorty->_flags & 2) && g_vars->scene38_shortyCounter > 1
 				&& g_vars->scene38_shorty->_statics->_staticsId == ST_MLS_LEFT2
-				&& g_fp->_rnd->getRandomNumber(32767) < 3276) {
+				&& g_fp->_rnd.getRandomNumber(32767) < 3276) {
 				chainQueue(QU_MLS_TURNR, 0);
 				g_vars->scene38_shortyCounter = 0;
 			}
@@ -150,7 +150,7 @@ void sceneHandler38_drink() {
 		if (g_vars->scene38_shorty->_flags & 4) {
 			if (!(g_vars->scene38_shorty->_flags & 2) && g_vars->scene38_shortyCounter > 0
 				&& g_vars->scene38_shorty->_statics->_staticsId == ST_MLS_LEFT2
-				&& g_fp->_rnd->getRandomNumber(32767) < 3276) {
+				&& g_fp->_rnd.getRandomNumber(32767) < 3276) {
 				chainQueue(QU_MLS_TURNR, 0);
 				g_vars->scene38_shortyCounter = 0;
 			}
@@ -189,9 +189,9 @@ void sceneHandler38_animateAlcoholics() {
 			} else {
 				int bossAnim = 0;
 
-				if (g_fp->_rnd->getRandomNumber(32767) >= 1310 || g_vars->scene38_boss->_statics->_staticsId != ST_GLV_HAMMER) {
-					if (g_fp->_rnd->getRandomNumber(32767) >= 1310) {
-						if (g_fp->_rnd->getRandomNumber(32767) < 1310) {
+				if (g_fp->_rnd.getRandomNumber(32767) >= 1310 || g_vars->scene38_boss->_statics->_staticsId != ST_GLV_HAMMER) {
+					if (g_fp->_rnd.getRandomNumber(32767) >= 1310) {
+						if (g_fp->_rnd.getRandomNumber(32767) < 1310) {
 							if (bossSt == ST_GLV_HAMMER)
 								bossAnim = QU_GLV_DRINK;
 							else if (bossSt == ST_GLV_NOHAMMER)
@@ -237,10 +237,10 @@ void sceneHandler38_animateAlcoholics() {
 	if (g_vars->scene38_tallyCounter >= 50) {
 		int tallyAnim = 0;
 
-		if (g_fp->_rnd->getRandomNumber(32767) >= 1310) {
-			if (g_fp->_rnd->getRandomNumber(32767) >= 1310) {
-				if (g_fp->_rnd->getRandomNumber(32767) >= 1310) {
-					if (g_fp->_rnd->getRandomNumber(32767) < 1310)
+		if (g_fp->_rnd.getRandomNumber(32767) >= 1310) {
+			if (g_fp->_rnd.getRandomNumber(32767) >= 1310) {
+				if (g_fp->_rnd.getRandomNumber(32767) >= 1310) {
+					if (g_fp->_rnd.getRandomNumber(32767) < 1310)
 						tallyAnim = QU_DLD_ICK;
 				} else {
 					tallyAnim = QU_DLD_GLOT;
@@ -285,9 +285,9 @@ void sceneHandler38_animateAlcoholics() {
 
 	int shortyAnim = 0;
 
-	if (g_fp->_rnd->getRandomNumber(32767) >= 1310) {
-		if (g_fp->_rnd->getRandomNumber(32767) >= 1310 || g_vars->scene38_shorty->_statics->_staticsId != ST_MLS_LEFT2) {
-			if (g_vars->scene38_boss->_statics->_staticsId != ST_GLV_SLEEP2 && g_vars->scene38_bossCounter > 30 && g_fp->_rnd->getRandomNumber(32767) < 0x3FFF && g_vars->scene38_shorty->_statics->_staticsId == ST_MLS_LEFT2)
+	if (g_fp->_rnd.getRandomNumber(32767) >= 1310) {
+		if (g_fp->_rnd.getRandomNumber(32767) >= 1310 || g_vars->scene38_shorty->_statics->_staticsId != ST_MLS_LEFT2) {
+			if (g_vars->scene38_boss->_statics->_staticsId != ST_GLV_SLEEP2 && g_vars->scene38_bossCounter > 30 && g_fp->_rnd.getRandomNumber(32767) < 0x3FFF && g_vars->scene38_shorty->_statics->_staticsId == ST_MLS_LEFT2)
 				shortyAnim = QU_MLS_HAND;
 		} else {
 			shortyAnim = QU_MLS_BLINK;


Commit: 926bcb6740e19d644757fc21ccd3dbf750342985
    https://github.com/scummvm/scummvm/commit/926bcb6740e19d644757fc21ccd3dbf750342985
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Handle quit/RTL events correctly

Fixes Trac#10316.

Changed paths:
    engines/fullpipe/fullpipe.cpp
    engines/fullpipe/fullpipe.h
    engines/fullpipe/gfx.cpp


diff --git a/engines/fullpipe/fullpipe.cpp b/engines/fullpipe/fullpipe.cpp
index 4bcdac7..f359639 100644
--- a/engines/fullpipe/fullpipe.cpp
+++ b/engines/fullpipe/fullpipe.cpp
@@ -262,6 +262,10 @@ void FullpipeEngine::restartGame() {
 	}
 }
 
+bool FullpipeEngine::shouldQuit() {
+	return !_gameContinue || Engine::shouldQuit();
+}
+
 Common::Error FullpipeEngine::loadGameState(int slot) {
 	if (_gameLoader->readSavegame(getSavegameFile(slot)))
 		return Common::kNoError;
@@ -312,15 +316,16 @@ Common::Error FullpipeEngine::run() {
 	loadAllScenes();
 #endif
 
-	_gameContinue = true;
-
 	int time1 = g_fp->_system->getMillis();
 
 	// Center mouse
 	_system->warpMouse(400, 300);
 
-	while (_gameContinue) {
+	for (;;) {
 		updateEvents();
+		if (shouldQuit()) {
+			break;
+		}
 
 		int time2 = g_fp->_system->getMillis();
 
@@ -436,8 +441,7 @@ void FullpipeEngine::updateEvents() {
 			_mouseScreenPos = event.mouse;
 			break;
 		case Common::EVENT_QUIT:
-			_gameContinue = false;
-			break;
+			return;
 		case Common::EVENT_RBUTTONDOWN:
 			if (!_inputArFlag && (_updateTicks - _lastInputTicks) >= 2) {
 				ex = new ExCommand(0, 17, 107, event.mouse.x, event.mouse.y, 0, 1, 0, 0, 0);
diff --git a/engines/fullpipe/fullpipe.h b/engines/fullpipe/fullpipe.h
index ddcb5ad..39c03fe 100644
--- a/engines/fullpipe/fullpipe.h
+++ b/engines/fullpipe/fullpipe.h
@@ -106,6 +106,7 @@ public:
 
 	void initialize();
 	void restartGame();
+	bool shouldQuit();
 
 	void setMusicAllowed(int val) { _musicAllowed = val; }
 
diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp
index d41505e..8ba2e80 100644
--- a/engines/fullpipe/gfx.cpp
+++ b/engines/fullpipe/gfx.cpp
@@ -626,7 +626,7 @@ void Picture::drawRotated(int x, int y, int angle) {
 }
 
 void Picture::displayPicture() {
-	if (!g_fp->_gameContinue)
+	if (g_fp->shouldQuit())
 		return;
 
 	getData();
@@ -644,7 +644,7 @@ void Picture::displayPicture() {
 	g_fp->_system->delayMillis(10);
 	g_fp->_system->updateScreen();
 
-	while (g_fp->_gameContinue) {
+	while (!g_fp->shouldQuit()) {
 		g_fp->updateEvents();
 		g_fp->_system->delayMillis(10);
 		g_fp->_system->updateScreen();


Commit: ac593e045e1410c541d2941f7fdc4cad7bcb3b5a
    https://github.com/scummvm/scummvm/commit/ac593e045e1410c541d2941f7fdc4cad7bcb3b5a
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix memory leaks in ModalVideoPlayer

Changed paths:
    engines/fullpipe/modal.cpp
    engines/fullpipe/modal.h


diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp
index 68f0455..1c98f5e 100644
--- a/engines/fullpipe/modal.cpp
+++ b/engines/fullpipe/modal.cpp
@@ -34,7 +34,6 @@
 
 #include "graphics/palette.h"
 #include "graphics/surface.h"
-#include "video/avi_decoder.h"
 
 #include "engines/savestate.h"
 #include "engines/advancedDetector.h"
@@ -363,30 +362,48 @@ void ModalIntroDemo::finish() {
 		g_fp->_gameLoader->updateSystems(42);
 }
 
-void ModalVideoPlayer::play(const char *filename) {
-	Video::AVIDecoder *aviDecoder = new Video::AVIDecoder();
+static bool checkSkipVideo(const Common::Event &event) {
+	switch (event.type) {
+	case Common::EVENT_KEYDOWN:
+		switch (event.kbd.keycode) {
+		case Common::KEYCODE_ESCAPE:
+		case Common::KEYCODE_RETURN:
+		case Common::KEYCODE_SPACE:
+			return true;
+		default:
+			return false;
+		}
+	case Common::EVENT_QUIT:
+	case Common::EVENT_RTL:
+		return true;
+	default:
+		return false;
+	}
+}
 
-	if (!aviDecoder->loadFile(filename))
+void ModalVideoPlayer::play(const char *filename) {
+	if (!_decoder.loadFile(filename))
 		return;
 
-	uint16 x = (g_system->getWidth() - aviDecoder->getWidth()) / 2;
-	uint16 y = (g_system->getHeight() - aviDecoder->getHeight()) / 2;
-	bool skipVideo = false;
+	uint16 x = (g_system->getWidth() - _decoder.getWidth()) / 2;
+	uint16 y = (g_system->getHeight() - _decoder.getHeight()) / 2;
 
-	aviDecoder->start();
+	_decoder.start();
 
-	while (!g_fp->shouldQuit() && !aviDecoder->endOfVideo() && !skipVideo) {
-		if (aviDecoder->needsUpdate()) {
-			const Graphics::Surface *frame = aviDecoder->decodeNextFrame();
+	while (!g_fp->shouldQuit() && !_decoder.endOfVideo()) {
+		if (_decoder.needsUpdate()) {
+			const Graphics::Surface *frame = _decoder.decodeNextFrame();
 			if (frame) {
-				Graphics::Surface *frameCopy = frame->convertTo(g_system->getScreenFormat());
-				g_fp->_system->copyRectToScreen(frameCopy->getPixels(), frameCopy->pitch,
-					x, y, frameCopy->w, frameCopy->h);
-				frameCopy->free();
-				delete frameCopy;
+				Common::ScopedPtr<Graphics::Surface, Graphics::SurfaceDeleter> tmpFrame;
+				if (frame->format != g_system->getScreenFormat()) {
+					tmpFrame.reset(frame->convertTo(g_system->getScreenFormat()));
+					frame = tmpFrame.get();
+				}
+				g_fp->_system->copyRectToScreen(frame->getPixels(), frame->pitch,
+					x, y, frame->w, frame->h);
 
-				if (aviDecoder->hasDirtyPalette())
-					g_fp->_system->getPaletteManager()->setPalette(aviDecoder->getPalette(), 0, 256);
+				if (_decoder.hasDirtyPalette())
+					g_fp->_system->getPaletteManager()->setPalette(_decoder.getPalette(), 0, 256);
 
 				g_fp->_system->updateScreen();
 			}
@@ -394,15 +411,16 @@ void ModalVideoPlayer::play(const char *filename) {
 
 		Common::Event event;
 		while (g_fp->_system->getEventManager()->pollEvent(event)) {
-			if ((event.type == Common::EVENT_KEYDOWN && (event.kbd.keycode == Common::KEYCODE_ESCAPE ||
-														 event.kbd.keycode == Common::KEYCODE_RETURN ||
-														 event.kbd.keycode == Common::KEYCODE_SPACE))
-				 || event.type == Common::EVENT_LBUTTONUP)
-				skipVideo = true;
+			if (checkSkipVideo(event)) {
+				goto finish;
+			}
 		}
 
-		g_fp->_system->delayMillis(aviDecoder->getTimeToNextFrame());
+		g_fp->_system->delayMillis(_decoder.getTimeToNextFrame());
 	}
+
+finish:
+	_decoder.close();
 }
 
 ModalMap::ModalMap() {
diff --git a/engines/fullpipe/modal.h b/engines/fullpipe/modal.h
index 6cd4581..5beba92 100644
--- a/engines/fullpipe/modal.h
+++ b/engines/fullpipe/modal.h
@@ -23,6 +23,8 @@
 #ifndef FULLPIPE_MODAL_H
 #define FULLPIPE_MODAL_H
 
+#include "video/avi_decoder.h"
+
 namespace Fullpipe {
 
 class PictureObject;
@@ -108,6 +110,9 @@ public:
 	virtual void saveload() {}
 
 	void play(const char *fname);
+
+private:
+	Video::AVIDecoder _decoder;
 };
 
 class ModalMap : public BaseModalObject {


Commit: 5ab7a12779af3ade5494fa53a265fe70103f720a
    https://github.com/scummvm/scummvm/commit/5ab7a12779af3ade5494fa53a265fe70103f720a
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix memory leaks of inventory icons and items

Changed paths:
    engines/fullpipe/inventory.cpp
    engines/fullpipe/inventory.h


diff --git a/engines/fullpipe/inventory.cpp b/engines/fullpipe/inventory.cpp
index 9d6152d..fd8f73c 100644
--- a/engines/fullpipe/inventory.cpp
+++ b/engines/fullpipe/inventory.cpp
@@ -94,18 +94,12 @@ Inventory2::~Inventory2() {
 }
 
 bool Inventory2::loadPartial(MfcArchive &file) { // Inventory2_SerializePartially
-	for (uint i = 0; i < _inventoryItems.size(); i++)
-		delete _inventoryItems[i];
-
 	_inventoryItems.clear();
 
 	int numInvs = file.readUint32LE();
 
 	for (int i = 0; i < numInvs; i++) {
-		InventoryItem *t = new InventoryItem();
-		t->itemId = file.readUint16LE();
-		t->count = file.readUint16LE();
-		_inventoryItems.push_back(t);
+		_inventoryItems.push_back(InventoryItem(file.readUint16LE(), file.readUint16LE()));
 	}
 
 	return true;
@@ -115,8 +109,8 @@ bool Inventory2::savePartial(MfcArchive &file) {
 	file.writeUint32LE(_inventoryItems.size());
 
 	for (uint i = 0; i < _inventoryItems.size(); i++) {
-		file.writeUint16LE(_inventoryItems[i]->itemId);
-		file.writeUint16LE(_inventoryItems[i]->count);
+		file.writeUint16LE(_inventoryItems[i].itemId);
+		file.writeUint16LE(_inventoryItems[i].count);
 	}
 
 	return true;
@@ -124,7 +118,7 @@ bool Inventory2::savePartial(MfcArchive &file) {
 
 void Inventory2::addItem(int itemId, int count) {
 	if (getInventoryPoolItemIndexById(itemId) >= 0)
-		_inventoryItems.push_back(new InventoryItem(itemId, count));
+		_inventoryItems.push_back(InventoryItem(itemId, count));
 }
 
 void Inventory2::addItem2(StaticANIObject *obj) {
@@ -140,14 +134,15 @@ void Inventory2::removeItem(int itemId, int count) {
 	while (count) {
 		int i;
 		for (i = _inventoryItems.size() - 1; i >= 0; i--) {
-			if (_inventoryItems[i]->itemId == itemId) {
+			InventoryItem &item = _inventoryItems[i];
+			if (item.itemId == itemId) {
 				if (_selectedId == itemId)
 					unselectItem(false);
 
-				if (_inventoryItems[i]->count > count) {
-					_inventoryItems[i]->count -= count;
+				if (item.count > count) {
+					item.count -= count;
 				} else {
-					count -= _inventoryItems[i]->count;
+					count -= item.count;
 					_inventoryItems.remove_at(i);
 				}
 
@@ -166,7 +161,7 @@ void Inventory2::removeItem2(Scene *sceneObj, int itemId, int x, int y, int prio
 	debugC(2, kDebugInventory, "removeItem2(*, %d, %d, %d, %d)", itemId, x, y, priority);
 
 	if (idx >= 0) {
-		if (_inventoryItems[idx]->count) {
+		if (_inventoryItems[idx].count) {
 			removeItem(itemId, 1);
 
 			Scene *sc = g_fp->accessScene(_sceneId);
@@ -188,8 +183,8 @@ int Inventory2::getCountItemsWithId(int itemId) {
 	int res = 0;
 
 	for (uint i = 0; i < _inventoryItems.size(); i++) {
-		if (_inventoryItems[i]->itemId == itemId)
-			res += _inventoryItems[i]->count;
+		if (_inventoryItems[i].itemId == itemId)
+			res += _inventoryItems[i].count;
 	}
 
 	return res;
@@ -197,7 +192,7 @@ int Inventory2::getCountItemsWithId(int itemId) {
 
 int Inventory2::getInventoryItemIndexById(int itemId) {
 	for (uint i = 0; i < _inventoryItems.size(); i++) {
-		if (_inventoryItems[i]->itemId == itemId)
+		if (_inventoryItems[i].itemId == itemId)
 			return i;
 	}
 
@@ -256,36 +251,35 @@ void Inventory2::rebuildItemRects() {
 	}
 
 	for (uint i = 0; i < _inventoryItems.size(); i++) {
-		int idx = getInventoryPoolItemIndexById(_inventoryItems[i]->itemId);
+		int idx = getInventoryPoolItemIndexById(_inventoryItems[i].itemId);
 
-		InventoryIcon *icn = new InventoryIcon();
+		_inventoryIcons.push_back(InventoryIcon());
+		InventoryIcon &icn = _inventoryIcons.back();
 
-		icn->inventoryItemId = _itemsPool[idx]->id;
+		icn.inventoryItemId = _itemsPool[idx]->id;
 
-		icn->pictureObjectNormal = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectNormal, 0);
-		icn->pictureObjectHover = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectHover, 0);
-		icn->pictureObjectSelected = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectSelected, 0);
+		icn.pictureObjectNormal = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectNormal, 0);
+		icn.pictureObjectHover = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectHover, 0);
+		icn.pictureObjectSelected = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectSelected, 0);
 
-		const Dims dims = icn->pictureObjectNormal->getDimensions();
+		const Dims dims = icn.pictureObjectNormal->getDimensions();
 
 		if (_itemsPool[idx]->flags & 0x10000) {
-			icn->x1 = 730;
-			icn->y1 = itemY;
-			icn->x2 = dims.x + 730;
-			icn->y2 = dims.y + itemY + 10;
+			icn.x1 = 730;
+			icn.y1 = itemY;
+			icn.x2 = dims.x + 730;
+			icn.y2 = dims.y + itemY + 10;
 		} else {
-			icn->x1 = itemX;
-			icn->y1 = itemY;
-			icn->x2 = itemX + dims.x;
-			itemX = icn->x2 + 1;
-			icn->y2 = dims.y + itemY + 10;
+			icn.x1 = itemX;
+			icn.y1 = itemY;
+			icn.x2 = itemX + dims.x;
+			itemX = icn.x2 + 1;
+			icn.y2 = dims.y + itemY + 10;
 		}
 
-		_inventoryIcons.push_back(icn);
-
-		if (itemX >= 2 * (icn->x1 - icn->x2) + 800) {
+		if (itemX >= 2 * (icn.x1 - icn.x2) + 800) {
 			itemX = 9;
-			itemY = icn->y2 + 1;
+			itemY = icn.y2 + 1;
 		}
 	}
 }
@@ -303,15 +297,15 @@ void Inventory2::draw() {
 	_picture->draw(-1, -1, 0, 0);
 
 	for (uint i = 0; i < _inventoryIcons.size(); i++) {
-		InventoryIcon *icn = _inventoryIcons[i];
+		const InventoryIcon &icn = _inventoryIcons[i];
 
-		if (icn->isSelected) {
-			icn->pictureObjectSelected->drawAt(icn->x1, icn->y1 + 10);
+		if (icn.isSelected) {
+			icn.pictureObjectSelected->drawAt(icn.x1, icn.y1 + 10);
 		} else {
-			if (icn->isMouseHover)
-				icn->pictureObjectHover->drawAt(icn->x1, icn->y1 + 10);
+			if (icn.isMouseHover)
+				icn.pictureObjectHover->drawAt(icn.x1, icn.y1 + 10);
 			else
-				icn->pictureObjectNormal->drawAt(icn->x1, icn->y1 + 10);
+				icn.pictureObjectNormal->drawAt(icn.x1, icn.y1 + 10);
 		}
 	}
 
@@ -394,22 +388,23 @@ bool Inventory2::handleLeftClick(ExCommand *cmd) {
 	bool res = false;
 
 	for (uint i = 0; i < _inventoryIcons.size(); i++) {
-		if (cmd->_x >= _inventoryIcons[i]->x1 && cmd->_x <= _inventoryIcons[i]->x2 &&
-			cmd->_y >= _inventoryIcons[i]->y1 && cmd->_y <= _inventoryIcons[i]->y2) {
+		InventoryIcon &icon = _inventoryIcons[i];
+		if (cmd->_x >= icon.x1 && cmd->_x <= icon.x2 &&
+			cmd->_y >= icon.y1 && cmd->_y <= icon.y2) {
 			if (getSelectedItemId()) {
-				if (getSelectedItemId() != _inventoryIcons[i]->inventoryItemId)
+				if (getSelectedItemId() != icon.inventoryItemId)
 					unselectItem(0);
 			}
-			if (getItemFlags(_inventoryIcons[i]->inventoryItemId) & 1) {
+			if (getItemFlags(icon.inventoryItemId) & 1) {
 				ExCommand *ex = new ExCommand(0, 17, 65, 0, 0, 0, 1, 0, 0, 0);
 				ex->_field_2C = 11;
-				ex->_field_14 = _inventoryIcons[i]->inventoryItemId;
+				ex->_field_14 = _inventoryIcons[i].inventoryItemId;
 				ex->_excFlags |= 3;
 				ex->postMessage();
 			}
-			if (!(getItemFlags(_inventoryIcons[i]->inventoryItemId) & 2)) {
-				selectItem(_inventoryIcons[i]->inventoryItemId);
-				_inventoryIcons[i]->isSelected = true;
+			if (!(getItemFlags(icon.inventoryItemId) & 2)) {
+				selectItem(icon.inventoryItemId);
+				icon.isSelected = true;
 			}
 			res = true;
 		}
@@ -446,8 +441,8 @@ bool Inventory2::unselectItem(bool flag) {
 	_selectedId = -1;
 
 	for (uint i = 0; i < _inventoryIcons.size(); i++) {
-		if (_inventoryIcons[i]->isSelected)
-			_inventoryIcons[i]->isSelected = false;
+		if (_inventoryIcons[i].isSelected)
+			_inventoryIcons[i].isSelected = false;
 	}
 
 	g_fp->getGameLoaderInputController()->setCursorItemPicture(0);
@@ -473,16 +468,16 @@ int Inventory2::getHoveredItem(Common::Point *point) {
 		return 0;
 
 	for (uint i = 0; i < _inventoryIcons.size(); i++) {
-		InventoryIcon *icn = _inventoryIcons[i];
+		InventoryIcon &icn = _inventoryIcons[i];
 		if (selId ||
-			point->x < icn->x1 ||
-			point->x > icn->x2 ||
-			point->y < _topOffset + icn->y1 ||
-			point->y > _topOffset + icn->y2) {
-			icn->isMouseHover = false;
+			point->x < icn.x1 ||
+			point->x > icn.x2 ||
+			point->y < _topOffset + icn.y1 ||
+			point->y > _topOffset + icn.y2) {
+			icn.isMouseHover = false;
 		} else {
-			icn->isMouseHover = true;
-			return icn->inventoryItemId;
+			icn.isMouseHover = true;
+			return icn.inventoryItemId;
 		}
 	}
 
@@ -493,7 +488,7 @@ void Inventory2::clear() {
 	unselectItem(0);
 
 	for (uint i = 0; i < _inventoryItems.size(); i++)
-		getInventoryPoolItemFieldCById(_inventoryItems[i]->itemId);
+		getInventoryPoolItemFieldCById(_inventoryItems[i].itemId);
 
 	_inventoryItems.clear();
 }
diff --git a/engines/fullpipe/inventory.h b/engines/fullpipe/inventory.h
index 9f9b996..2c08c8a 100644
--- a/engines/fullpipe/inventory.h
+++ b/engines/fullpipe/inventory.h
@@ -66,8 +66,6 @@ struct InventoryItem {
 	InventoryItem(int id, int cnt) : itemId(id), count(cnt) {}
 };
 
-typedef Common::Array<InventoryItem *> InventoryItems;
-
 class PictureObject;
 
 struct InventoryIcon {
@@ -83,11 +81,9 @@ struct InventoryIcon {
 	bool isMouseHover;
 };
 
-typedef Common::Array<InventoryIcon *> InventoryIcons;
-
 class Inventory2 : public Inventory {
-	InventoryItems _inventoryItems;
-	InventoryIcons _inventoryIcons;
+	Common::Array<InventoryItem> _inventoryItems;
+	Common::Array<InventoryIcon> _inventoryIcons;
 	int _selectedId;
 	int _field_48;
 	bool _isInventoryOut;


Commit: 6f8a65c739740956930c95e1d5a5c5fe0c80fbbd
    https://github.com/scummvm/scummvm/commit/6f8a65c739740956930c95e1d5a5c5fe0c80fbbd
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix memory leak & unnecessary heap allocation of Rects

Changed paths:
    engines/fullpipe/messagehandlers.cpp
    engines/fullpipe/statics.cpp
    engines/fullpipe/statics.h


diff --git a/engines/fullpipe/messagehandlers.cpp b/engines/fullpipe/messagehandlers.cpp
index f72ae98..61b3429 100644
--- a/engines/fullpipe/messagehandlers.cpp
+++ b/engines/fullpipe/messagehandlers.cpp
@@ -801,12 +801,12 @@ int MovGraph::messageHandler(ExCommand *cmd) {
 	}
 
 	if (ani->_movement) {
-		ani->_movement->_currDynamicPhase->_rect->top = 255 - top;
+		ani->_movement->_currDynamicPhase->_rect.top = 255 - top;
 		return 0;
 	}
 
 	if (ani->_statics)
-		ani->_statics->_rect->top = 255 - top;
+		ani->_statics->_rect.top = 255 - top;
 
 	return 0;
 }
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index 6b7dbbb..f487f17 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -539,14 +539,14 @@ void Movement::draw(bool flipFlag, int angle) {
 	}
 
 	if (flipFlag) {
-		bmp->flipVertical()->drawShaded(1, x, y + 30 + _currDynamicPhase->_rect->bottom, _currDynamicPhase->getPaletteData(), _currDynamicPhase->getAlpha());
+		bmp->flipVertical()->drawShaded(1, x, y + 30 + _currDynamicPhase->_rect.bottom, _currDynamicPhase->getPaletteData(), _currDynamicPhase->getAlpha());
 	} else if (angle) {
 		bmp->drawRotated(x, y, angle, _currDynamicPhase->getPaletteData(), _currDynamicPhase->getAlpha());
 	} else {
 		bmp->putDib(x, y, _currDynamicPhase->getPaletteData(), _currDynamicPhase->getAlpha());
 	}
 
-	if (_currDynamicPhase->_rect->top) {
+	if (_currDynamicPhase->_rect.top) {
 		if (!_currDynamicPhase->getConvertedBitmap()) {
 			//v12 = Picture_getPixelData(v5);
 			//v13 = Bitmap_convertTo16Bit565(v12, (unsigned int *)&_currDynamicPhase->rect);
@@ -595,8 +595,6 @@ void StaticANIObject::draw() {
 	if ((_flags & 4) == 0)
 		return;
 
-	Common::Rect rect;
-
 	debugC(6, kDebugDrawing, "StaticANIObject::draw() (%s) [%d] [%d, %d]", transCyrillic(_objectName), _id, _ox, _oy);
 
 	if (_shadowsOn && g_fp->_currentScene && g_fp->_currentScene->_shadows
@@ -615,7 +613,7 @@ void StaticANIObject::draw() {
 		}
 
 		if (dyn->getDynFlags() & 4) {
-			rect = *dyn->_rect;
+			const Common::Rect &rect = dyn->_rect;
 
 			DynamicPhase *shd = g_fp->_currentScene->_shadows->findSize(rect.width(), rect.height());
 			if (shd) {
@@ -1450,17 +1448,15 @@ Common::Point Statics::getSomeXY() const {
 }
 
 Common::Point Statics::getCenter() const {
-	Common::Rect rect;
-
-	rect = *_rect;
+	Common::Rect rect(_rect);
 
 	if (_staticsId & 0x4000) {
 		const Dims dims = getDimensions();
-		rect.moveTo(dims.x - _rect->right, _rect->top);
+		rect.moveTo(dims.x - _rect.right, _rect.top);
 	}
 
-	return Common::Point(rect.left + _rect->width() / 2,
-						 rect.top + _rect->height() / 2);
+	return Common::Point(rect.left + _rect.width() / 2,
+						 rect.top + _rect.height() / 2);
 }
 
 Movement::Movement() {
@@ -2124,22 +2120,19 @@ void Movement::gotoLastFrame() {
 }
 
 Common::Point Movement::getCenter() const {
-	Common::Rect rect;
-
-	rect = *_currDynamicPhase->_rect;
+	Common::Rect rect(_currDynamicPhase->_rect);
 
 	if (_currMovement) {
 		const Dims dims = _currMovement->getDimensionsOfPhase(_currDynamicPhaseIndex);
-		rect.moveTo(dims.x - _currDynamicPhase->_rect->right, _currDynamicPhase->_rect->top);
+		rect.moveTo(dims.x - _currDynamicPhase->_rect.right, _currDynamicPhase->_rect.top);
 	}
 
-	return Common::Point(rect.left + _currDynamicPhase->_rect->width() / 2,
-						 rect.top + _currDynamicPhase->_rect->height() / 2);
+	return Common::Point(rect.left + _currDynamicPhase->_rect.width() / 2,
+						 rect.top + _currDynamicPhase->_rect.height() / 2);
 }
 
 DynamicPhase::DynamicPhase() {
 	_someX = 0;
-	_rect = 0;
 	_field_7C = 0;
 	_field_7E = 0;
 	_dynFlags = 0;
@@ -2147,14 +2140,9 @@ DynamicPhase::DynamicPhase() {
 	_data = nullptr;
 }
 
-DynamicPhase::~DynamicPhase() {
-	delete _rect;
-}
-
 DynamicPhase::DynamicPhase(DynamicPhase *src, bool reverse) {
 	_field_7C = src->_field_7C;
 	_field_7E = 0;
-	_rect = new Common::Rect();
 
 	debugC(1, kDebugAnimation, "DynamicPhase::DynamicPhase(src, %d)", reverse);
 
@@ -2193,7 +2181,7 @@ DynamicPhase::DynamicPhase(DynamicPhase *src, bool reverse) {
 		_someY = src->_someY;
 	}
 
-	*_rect = *src->_rect;
+	_rect = src->_rect;
 
 	_width = src->_width;
 	_height = src->_height;
@@ -2219,11 +2207,10 @@ bool DynamicPhase::load(MfcArchive &file) {
 	StaticPhase::load(file);
 
 	_field_7C = file.readUint16LE();
-	_rect = new Common::Rect();
-	_rect->left = file.readSint32LE();
-	_rect->top = file.readSint32LE();
-	_rect->right = file.readSint32LE();
-	_rect->bottom = file.readSint32LE();
+	_rect.left = file.readSint32LE();
+	_rect.top = file.readSint32LE();
+	_rect.right = file.readSint32LE();
+	_rect.bottom = file.readSint32LE();
 
 	assert(g_fp->_gameProjectVersion >= 1);
 
diff --git a/engines/fullpipe/statics.h b/engines/fullpipe/statics.h
index 71137dd..24d9fd0 100644
--- a/engines/fullpipe/statics.h
+++ b/engines/fullpipe/statics.h
@@ -71,7 +71,7 @@ class DynamicPhase : public StaticPhase {
  public:
 	int _someX;
 	int _someY;
-	Common::Rect *_rect;
+	Common::Rect _rect;
 	int16 _field_7C;
 	int16 _field_7E;
 	int _dynFlags;
@@ -79,7 +79,6 @@ class DynamicPhase : public StaticPhase {
   public:
 	DynamicPhase();
 	DynamicPhase(DynamicPhase *src, bool reverse);
-	virtual ~DynamicPhase();
 
 	virtual bool load(MfcArchive &file);
 


Commit: ff96db23dfd9e2075a710786fa0b1a01c6759a02
    https://github.com/scummvm/scummvm/commit/ff96db23dfd9e2075a710786fa0b1a01c6759a02
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix leaks and unnecessary extra allocations in FullpipeEngine

Changed paths:
    engines/fullpipe/fullpipe.cpp
    engines/fullpipe/fullpipe.h
    engines/fullpipe/gameloader.cpp
    engines/fullpipe/gameloader.h
    engines/fullpipe/gfx.cpp
    engines/fullpipe/scene.cpp
    engines/fullpipe/scenes/scene04.cpp
    engines/fullpipe/scenes/sceneFinal.cpp
    engines/fullpipe/sound.cpp
    engines/fullpipe/stateloader.cpp


diff --git a/engines/fullpipe/fullpipe.cpp b/engines/fullpipe/fullpipe.cpp
index f359639..4e05f89 100644
--- a/engines/fullpipe/fullpipe.cpp
+++ b/engines/fullpipe/fullpipe.cpp
@@ -45,13 +45,18 @@
 
 namespace Fullpipe {
 
-FullpipeEngine *g_fp = 0;
-Vars *g_vars = 0;
+FullpipeEngine *g_fp = nullptr;
+Vars *g_vars = nullptr;
 
 FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc) :
 	Engine(syst),
 	_gameDescription(gameDesc),
-	_rnd("fullpipe") {
+	_console(this),
+	_rnd("fullpipe"),
+	_gameProject(nullptr),
+	_modalObject(nullptr),
+	_currSoundList1(),
+	_mapTable() {
 	DebugMan.addDebugChannel(kDebugPathfinding, "path", "Pathfinding");
 	DebugMan.addDebugChannel(kDebugDrawing, "drawing", "Drawing");
 	DebugMan.addDebugChannel(kDebugLoading, "loading", "Scene loading");
@@ -72,8 +77,6 @@ FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc)
 	_sfxVolume = ConfMan.getInt("sfx_volume") * 39 - 10000;
 	_musicVolume = ConfMan.getInt("music_volume");
 
-	_console = 0;
-
 	_gameProjectVersion = 0;
 	_pictureScale = 8;
 	_scrollSpeed = 0;
@@ -96,13 +99,10 @@ FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc)
 	_currentCheat = -1;
 	_currentCheatPos = 0;
 
-	_modalObject = 0;
-	_origFormat = 0;
-
 	_liftEnterMQ = 0;
 	_liftExitMQ = 0;
 	_lift = 0;
-	_lastLiftButton = 0;
+	_lastLiftButton = nullptr;
 	_liftX = 0;
 	_liftY = 0;
 
@@ -125,32 +125,23 @@ FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc)
 	_musicLocal = 0;
 	_trackStartDelay = 0;
 
-	_soundStream1 = new Audio::SoundHandle();
-	_soundStream2 = new Audio::SoundHandle();
-	_soundStream3 = new Audio::SoundHandle();
-	_soundStream4 = new Audio::SoundHandle();
-
 	_stream2playing = false;
 
 	_numSceneTracks = 0;
 	_sceneTrackHasSequence = false;
 	_sceneTrackIsPlaying = false;
 
-	_aniMan = 0;
-	_aniMan2 = 0;
-	_currentScene = 0;
-	_loaderScene = 0;
-	_scene2 = 0;
-	_scene3 = 0;
-	_movTable = 0;
-	_floaters = 0;
-	_aniHandler = 0;
-
-	_globalMessageQueueList = 0;
-	_messageHandlers = 0;
+	_aniMan = nullptr;
+	_aniMan2 = nullptr;
+	_currentScene = nullptr;
+	_loaderScene = nullptr;
+	_scene2 = nullptr;
+	_scene3 = nullptr;
+	_movTable = nullptr;
+	_messageHandlers = nullptr;
 
-	_updateScreenCallback = 0;
-	_updateCursorCallback = 0;
+	_updateScreenCallback = nullptr;
+	_updateCursorCallback = nullptr;
 
 	_msgX = 0;
 	_msgY = 0;
@@ -161,38 +152,27 @@ FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc)
 
 	_currSelectedInventoryItemId = 0;
 
-	_behaviorManager = 0;
-
 	_cursorId = 0;
 
 	_keyState = Common::KEYCODE_INVALID;
 	_buttonState = 0;
 
-	_gameLoader = 0;
-	_gameProject = 0;
-
 	_updateFlag = true;
 	_flgCanOpenMap = true;
 
 	_sceneWidth = 1;
 	_sceneHeight = 1;
 
-	for (int i = 0; i < 11; i++)
-		_currSoundList1[i] = 0;
-
-	for (int i = 0; i < 200; i++)
-		_mapTable[i] = 0;
-
-	_inventoryScene = 0;
-	_inventory = 0;
+	_inventoryScene = nullptr;
+	_inventory = nullptr;
 
 	_minCursorId = 0xffff;
 	_maxCursorId = 0;
 	_objectAtCursor = 0;
 	_objectIdAtCursor = 0;
 
-	_arcadeOverlay = 0;
-	_arcadeOverlayHelper = 0;
+	_arcadeOverlay = nullptr;
+	_arcadeOverlayHelper = nullptr;
 	_arcadeOverlayX = 0;
 	_arcadeOverlayY = 0;
 	_arcadeOverlayMidX = 0;
@@ -205,25 +185,9 @@ FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc)
 }
 
 FullpipeEngine::~FullpipeEngine() {
-	delete _console;
-	delete _globalMessageQueueList;
-	delete _soundStream1;
-	delete _soundStream2;
-	delete _soundStream3;
-	delete _soundStream4;
-}
-
-void FullpipeEngine::initialize() {
-	_globalMessageQueueList = new GlobalMessageQueueList;
-	_behaviorManager = new BehaviorManager;
-
-	_sceneRect.left = 0;
-	_sceneRect.top = 0;
-	_sceneRect.right = 799;
-	_sceneRect.bottom = 599;
-
-	_floaters = new Floaters;
-	_aniHandler = new AniHandler;
+	g_fp = nullptr;
+	delete g_vars;
+	g_vars = nullptr;
 }
 
 void FullpipeEngine::restartGame() {
@@ -236,13 +200,13 @@ void FullpipeEngine::restartGame() {
 
 	if (_scene2) {
 		_scene2->getAniMan();
-		_scene2 = 0;
+		_scene2 = nullptr;
 	}
 
 	if (_currentScene) {
 		_gameLoader->unloadScene(_currentScene->_sceneId);
 
-		_currentScene = 0;
+		_currentScene = nullptr;
 	}
 
 	_gameLoader->restoreDefPicAniInfos();
@@ -286,14 +250,19 @@ Common::Error FullpipeEngine::run() {
 	// Initialize backend
 	initGraphics(800, 600, &format);
 
-	_backgroundSurface = new Graphics::Surface;
-	_backgroundSurface->create(800, 600, format);
+	_backgroundSurface.create(800, 600, format);
+	_origFormat = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
 
-	_origFormat = new Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
+	_globalMessageQueueList.reset(new GlobalMessageQueueList);
+	_behaviorManager.reset(new BehaviorManager);
 
-	_console = new Console(this);
+	_sceneRect.left = 0;
+	_sceneRect.top = 0;
+	_sceneRect.right = 799;
+	_sceneRect.bottom = 599;
 
-	initialize();
+	_floaters.reset(new Floaters);
+	_aniHandler.reset(new AniHandler);
 	_globalPalette = &_defaultPalette;
 
 	_isSaveAllowed = false;
@@ -336,13 +305,9 @@ Common::Error FullpipeEngine::run() {
 		}
 
 		if (_needRestart) {
-			if (_modalObject) {
-				delete _modalObject;
-				_modalObject = 0;
-			}
-
+			delete _modalObject;
 			freeGameLoader();
-			_currentScene = 0;
+			_currentScene = nullptr;
 			_updateTicks = 0;
 			_globalPalette = &_defaultPalette;
 
@@ -357,6 +322,7 @@ Common::Error FullpipeEngine::run() {
 	freeGameLoader();
 
 	cleanup();
+	_backgroundSurface.free();
 
 	return Common::kNoError;
 }
@@ -488,7 +454,7 @@ void FullpipeEngine::freeGameLoader() {
 	setCursor(0);
 	delete _movTable;
 	_floaters->stopAll();
-	delete _gameLoader;
+	_gameLoader.reset();
 	_currentScene = 0;
 	_scene2 = 0;
 	_loaderScene = 0;
@@ -504,11 +470,6 @@ void FullpipeEngine::cleanup() {
 		delete (*_globalMessageQueueList)[i];
 
 	stopAllSoundStreams();
-
-	delete _origFormat;
-	_backgroundSurface->free();
-
-	delete _backgroundSurface;
 }
 
 void FullpipeEngine::updateScreen() {
diff --git a/engines/fullpipe/fullpipe.h b/engines/fullpipe/fullpipe.h
index 39c03fe..9426c32 100644
--- a/engines/fullpipe/fullpipe.h
+++ b/engines/fullpipe/fullpipe.h
@@ -23,12 +23,15 @@
 #ifndef FULLPIPE_FULLPIPE_H
 #define FULLPIPE_FULLPIPE_H
 
+#include "audio/mixer.h"
 #include "common/scummsys.h"
 #include "common/events.h"
 #include "common/keyboard.h"
+#include "common/ptr.h"
 #include "common/random.h"
 #include "common/savefile.h"
 #include "common/system.h"
+#include "graphics/surface.h"
 
 #include "engines/engine.h"
 
@@ -101,8 +104,8 @@ public:
 	FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc);
 	virtual ~FullpipeEngine();
 
-	Console *_console;
-	GUI::Debugger *getDebugger() { return _console; }
+	Console _console;
+	GUI::Debugger *getDebugger() { return &_console; }
 
 	void initialize();
 	void restartGame();
@@ -123,10 +126,10 @@ public:
 
 	void updateEvents();
 
-	Graphics::Surface *_backgroundSurface;
-	Graphics::PixelFormat *_origFormat;
+	Graphics::Surface _backgroundSurface;
+	Graphics::PixelFormat _origFormat;
 
-	GameLoader *_gameLoader;
+	Common::ScopedPtr<GameLoader> _gameLoader;
 	GameProject *_gameProject;
 	bool loadGam(const char *fname, int scene = 0);
 
@@ -187,7 +190,7 @@ public:
 	void updateTrackDelay();
 	void startSceneTrack();
 	void startSoundStream1(const Common::String &trackName);
-	void playOggSound(const Common::String &trackName, Audio::SoundHandle *stream);
+	void playOggSound(const Common::String &trackName, Audio::SoundHandle &stream);
 	void stopSoundStream2();
 	void stopAllSoundStreams();
 	void stopAllSoundInstances(int id);
@@ -197,7 +200,7 @@ public:
 	int _sfxVolume;
 	int _musicVolume;
 
-	GlobalMessageQueueList *_globalMessageQueueList;
+	Common::ScopedPtr<GlobalMessageQueueList> _globalMessageQueueList;
 	MessageHandler *_messageHandlers;
 
 	int _msgX;
@@ -212,12 +215,12 @@ public:
 	int _mouseVirtY;
 	Common::Point _mouseScreenPos;
 
-	BehaviorManager *_behaviorManager;
+	Common::ScopedPtr<BehaviorManager> _behaviorManager;
 
 	MovTable *_movTable;
 
-	Floaters *_floaters;
-	AniHandler *_aniHandler;
+	Common::ScopedPtr<Floaters> _floaters;
+	Common::ScopedPtr<AniHandler> _aniHandler;
 
 	Common::Array<Common::Point *> _arcadeKeys;
 
@@ -333,10 +336,10 @@ public:
 	void lift_openLift();
 
 	GameVar *_musicGameVar;
-	Audio::SoundHandle *_soundStream1;
-	Audio::SoundHandle *_soundStream2;
-	Audio::SoundHandle *_soundStream3;
-	Audio::SoundHandle *_soundStream4;
+	Audio::SoundHandle _soundStream1;
+	Audio::SoundHandle _soundStream2;
+	Audio::SoundHandle _soundStream3;
+	Audio::SoundHandle _soundStream4;
 
 	bool _stream2playing;
 
diff --git a/engines/fullpipe/gameloader.cpp b/engines/fullpipe/gameloader.cpp
index efa5f8c..32c2d0d 100644
--- a/engines/fullpipe/gameloader.cpp
+++ b/engines/fullpipe/gameloader.cpp
@@ -54,8 +54,6 @@ GameLoader::GameLoader() {
 	_interactionController = new InteractionController();
 	_inputController = new InputController();
 
-	_gameProject = 0;
-
 	addMessageHandlerByIndex(global_messageHandler2, 0, 0);
 	insertMessageHandler(global_messageHandler3, 0, 128);
 	insertMessageHandler(global_messageHandler4, 0, 1);
@@ -77,12 +75,9 @@ GameLoader::GameLoader() {
 }
 
 GameLoader::~GameLoader() {
-	delete _gameProject;
 	delete _interactionController;
 	delete _inputController;
 
-	g_fp->_gameLoader = 0;
-
 	for (uint i = 0; i < _sc2array.size(); i++) {
 		if (_sc2array[i]._defPicAniInfos)
 			free(_sc2array[i]._defPicAniInfos);
@@ -112,11 +107,11 @@ bool GameLoader::load(MfcArchive &file) {
 	_gameName = file.readPascalString();
 	debugC(1, kDebugLoading, "_gameName: %s", _gameName.c_str());
 
-	_gameProject = new GameProject();
+	_gameProject.reset(new GameProject());
 
 	_gameProject->load(file);
 
-	g_fp->_gameProject = _gameProject;
+	g_fp->_gameProject = _gameProject.get();
 
 	if (g_fp->_gameProjectVersion < 12) {
 		error("Old gameProjectVersion: %d", g_fp->_gameProjectVersion);
diff --git a/engines/fullpipe/gameloader.h b/engines/fullpipe/gameloader.h
index 6180ab0..5e4d931 100644
--- a/engines/fullpipe/gameloader.h
+++ b/engines/fullpipe/gameloader.h
@@ -121,7 +121,7 @@ class GameLoader : public CObject {
 
 	void restoreDefPicAniInfos();
 
-	GameProject *_gameProject;
+	Common::ScopedPtr<GameProject> _gameProject;
 	InteractionController *_interactionController;
 	InputController *_inputController;
 	Inventory2 _inventory;
diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp
index 8ba2e80..3abf2fc 100644
--- a/engines/fullpipe/gfx.cpp
+++ b/engines/fullpipe/gfx.cpp
@@ -635,8 +635,8 @@ void Picture::displayPicture() {
 	if (!_dataSize)
 		return;
 
-	g_fp->_backgroundSurface->fillRect(Common::Rect(0, 0, 800, 600), 0);
-	g_fp->_system->copyRectToScreen(g_fp->_backgroundSurface->getBasePtr(0, 0), g_fp->_backgroundSurface->pitch, 0, 0, 800, 600);
+	g_fp->_backgroundSurface.fillRect(Common::Rect(0, 0, 800, 600), 0);
+	g_fp->_system->copyRectToScreen(g_fp->_backgroundSurface.getBasePtr(0, 0), g_fp->_backgroundSurface.pitch, 0, 0, 800, 600);
 
 	draw(0, 0, 0, 0);
 
@@ -808,8 +808,8 @@ void Bitmap::putDib(int x, int y, const Palette &palette, byte alpha) {
 
 	int alphac = TS_ARGB(0xff, alpha, 0xff, 0xff);
 
-	_surface->blit(*g_fp->_backgroundSurface, x1, y1, _flipping, &sub, alphac);
-	g_fp->_system->copyRectToScreen(g_fp->_backgroundSurface->getBasePtr(x1, y1), g_fp->_backgroundSurface->pitch, x1, y1, sub.width(), sub.height());
+	_surface->blit(g_fp->_backgroundSurface, x1, y1, _flipping, &sub, alphac);
+	g_fp->_system->copyRectToScreen(g_fp->_backgroundSurface.getBasePtr(x1, y1), g_fp->_backgroundSurface.pitch, x1, y1, sub.width(), sub.height());
 }
 
 bool Bitmap::putDibRB(byte *pixels, const Palette &palette) {
@@ -967,7 +967,7 @@ void Bitmap::colorFill(uint32 *dest, int len, int32 color) {
 #endif
 	byte r, g, b;
 
-	g_fp->_origFormat->colorToRGB(color, r, g, b);
+	g_fp->_origFormat.colorToRGB(color, r, g, b);
 
 	uint32 c = TS_ARGB(0xff, r, g, b);
 
@@ -990,7 +990,7 @@ void Bitmap::paletteFill(uint32 *dest, byte *src, int len, const Palette &palett
 	byte r, g, b;
 
 	for (int i = 0; i < len; i++) {
-		g_fp->_origFormat->colorToRGB(READ_LE_UINT32(&palette[*src++]) & 0xffff, r, g, b);
+		g_fp->_origFormat.colorToRGB(palette[*src++] & 0xffff, r, g, b);
 
 		*dest++ = TS_ARGB(0xff, r, g, b);
 	}
@@ -1019,7 +1019,7 @@ void Bitmap::copierKeyColor(uint32 *dest, byte *src, int len, int keyColor, cons
 	if (!cb05_format) {
 		for (int i = 0; i < len; i++) {
 			if (*src != keyColor) {
-				g_fp->_origFormat->colorToRGB(READ_LE_UINT32(&palette[*src]) & 0xffff, r, g, b);
+				g_fp->_origFormat.colorToRGB(palette[*src] & 0xffff, r, g, b);
 				*dest = TS_ARGB(0xff, r, g, b);
 			}
 
@@ -1031,7 +1031,7 @@ void Bitmap::copierKeyColor(uint32 *dest, byte *src, int len, int keyColor, cons
 
 		for (int i = 0; i < len; i++) {
 			if (*src16 != 0) {
-				g_fp->_origFormat->colorToRGB(READ_LE_UINT16(src16) & 0xffff, r, g, b);
+				g_fp->_origFormat.colorToRGB(READ_LE_UINT16(src16), r, g, b);
 				*dest = TS_ARGB(0xff, r, g, b);
 			}
 
@@ -1063,7 +1063,7 @@ void Bitmap::copier(uint32 *dest, byte *src, int len, const Palette &palette, bo
 
 	if (!cb05_format) {
 		for (int i = 0; i < len; i++) {
-			g_fp->_origFormat->colorToRGB(READ_LE_UINT32(&palette[*src++]) & 0xffff, r, g, b);
+			g_fp->_origFormat.colorToRGB(palette[*src++] & 0xffff, r, g, b);
 
 			*dest++ = TS_ARGB(0xff, r, g, b);
 		}
@@ -1071,7 +1071,7 @@ void Bitmap::copier(uint32 *dest, byte *src, int len, const Palette &palette, bo
 		int16 *src16 = (int16 *)src;
 
 		for (int i = 0; i < len; i++) {
-			g_fp->_origFormat->colorToRGB(READ_LE_UINT32(src16++) & 0xffff, r, g, b);
+			g_fp->_origFormat.colorToRGB(READ_LE_UINT16(src16++), r, g, b);
 			*dest++ = TS_ARGB(0xff, r, g, b);
 		}
 	}
@@ -1203,7 +1203,7 @@ DynamicPhase *Shadows::findSize(int width, int height) {
 
 void FullpipeEngine::drawAlphaRectangle(int x1, int y1, int x2, int y2, int alpha) {
 	for (int y = y1; y < y2; y++) {
-		uint32 *ptr = (uint32 *)g_fp->_backgroundSurface->getBasePtr(x1, y);
+		uint32 *ptr = (uint32 *)g_fp->_backgroundSurface.getBasePtr(x1, y);
 
 		for (int x = x1; x < x2; x++) {
 			uint32 color = *ptr;
@@ -1222,8 +1222,8 @@ void FullpipeEngine::sceneFade(Scene *sc, bool direction) {
 		int ticks = g_fp->_system->getMillis();
 		sc->draw();
 
-		drawAlphaRectangle(0, 0, g_fp->_backgroundSurface->w, g_fp->_backgroundSurface->h, direction ? dim : 255 - dim);
-		g_fp->_system->copyRectToScreen(g_fp->_backgroundSurface->getBasePtr(0, 0), g_fp->_backgroundSurface->pitch, 0, 0, 800, 600);
+		drawAlphaRectangle(0, 0, g_fp->_backgroundSurface.w, g_fp->_backgroundSurface.h, direction ? dim : 255 - dim);
+		g_fp->_system->copyRectToScreen(g_fp->_backgroundSurface.getBasePtr(0, 0), g_fp->_backgroundSurface.pitch, 0, 0, 800, 600);
 
 		g_fp->_system->updateScreen();
 		ticks = g_fp->_system->getMillis() - ticks;
diff --git a/engines/fullpipe/scene.cpp b/engines/fullpipe/scene.cpp
index ee0e5e5..46ad205 100644
--- a/engines/fullpipe/scene.cpp
+++ b/engines/fullpipe/scene.cpp
@@ -523,7 +523,7 @@ void Scene::draw() {
 	updateScrolling();
 
 	// Clean previous stuff
-	g_fp->_backgroundSurface->fillRect(Common::Rect(0, 0, 800, 600), 0);
+	g_fp->_backgroundSurface.fillRect(Common::Rect(0, 0, 800, 600), 0);
 
 	drawContent(60000, 0, true);
 
diff --git a/engines/fullpipe/scenes/scene04.cpp b/engines/fullpipe/scenes/scene04.cpp
index b78d66d..4b5e105 100644
--- a/engines/fullpipe/scenes/scene04.cpp
+++ b/engines/fullpipe/scenes/scene04.cpp
@@ -1086,13 +1086,13 @@ void updateSound() {
 		return;
 
 	case 1:
-		if (!g_fp->_mixer->isSoundHandleActive(*g_fp->_soundStream2)) {
+		if (!g_fp->_mixer->isSoundHandleActive(g_fp->_soundStream2)) {
 			g_fp->playOggSound("sc4_loop.ogg", g_fp->_soundStream3);
 			g_vars->scene04_musicStage = 2;
 		}
 		break;
 	case 2:
-		if (!g_fp->_mixer->isSoundHandleActive(*g_fp->_soundStream3)) {
+		if (!g_fp->_mixer->isSoundHandleActive(g_fp->_soundStream3)) {
 			if (g_fp->_stream2playing) { // Looop it
 				g_fp->playOggSound("sc4_loop.ogg", g_fp->_soundStream3);
 			} else {
@@ -1102,7 +1102,7 @@ void updateSound() {
 		}
 		break;
 	case 3:
-		if (!g_fp->_mixer->isSoundHandleActive(*g_fp->_soundStream4)) {
+		if (!g_fp->_mixer->isSoundHandleActive(g_fp->_soundStream4)) {
 			g_vars->scene04_musicStage = 0;
 		}
 		break;
diff --git a/engines/fullpipe/scenes/sceneFinal.cpp b/engines/fullpipe/scenes/sceneFinal.cpp
index 30ca31b..2b4100b 100644
--- a/engines/fullpipe/scenes/sceneFinal.cpp
+++ b/engines/fullpipe/scenes/sceneFinal.cpp
@@ -124,7 +124,7 @@ void sceneHandlerFinal_fallCoin() {
 }
 
 void updateMusic() {
-	if (g_vars->sceneFinal_trackHasStarted && !g_fp->_mixer->isSoundHandleActive(*g_fp->_soundStream1)) { // loop music
+	if (g_vars->sceneFinal_trackHasStarted && !g_fp->_mixer->isSoundHandleActive(g_fp->_soundStream1)) { // loop music
 		sceneHandlerFinal_startMusic("track16.ogg");
 	}
 }
diff --git a/engines/fullpipe/sound.cpp b/engines/fullpipe/sound.cpp
index 44dbe56..b1d0a26 100644
--- a/engines/fullpipe/sound.cpp
+++ b/engines/fullpipe/sound.cpp
@@ -228,8 +228,8 @@ void Sound::stop() {
 void FullpipeEngine::setSceneMusicParameters(GameVar *gvar) {
 	stopSoundStream2();
 
-	if (_mixer->isSoundHandleActive(*_soundStream3))
-		_mixer->stopHandle(*_soundStream4);
+	if (_mixer->isSoundHandleActive(_soundStream3))
+		_mixer->stopHandle(_soundStream4);
 
 	if (_musicLocal)
 		stopAllSoundStreams();
@@ -288,7 +288,7 @@ void FullpipeEngine::updateTrackDelay() {
 
 void FullpipeEngine::startSceneTrack() {
 	if (_sceneTrackIsPlaying) {
-		if (!_mixer->isSoundHandleActive(*_soundStream1)) { // Simulate end of sound callback
+		if (!_mixer->isSoundHandleActive(_soundStream1)) { // Simulate end of sound callback
 			updateTrackDelay();
 		}
 	}
@@ -349,9 +349,9 @@ void FullpipeEngine::startSoundStream1(const Common::String &trackName) {
 	playOggSound(trackName, _soundStream1);
 }
 
-void FullpipeEngine::playOggSound(const Common::String &trackName, Audio::SoundHandle *stream) {
+void FullpipeEngine::playOggSound(const Common::String &trackName, Audio::SoundHandle &stream) {
 #ifdef USE_VORBIS
-	if (_mixer->isSoundHandleActive(*stream))
+	if (_mixer->isSoundHandleActive(stream))
 		return;
 
 	Common::File *track = new Common::File();
@@ -361,7 +361,7 @@ void FullpipeEngine::playOggSound(const Common::String &trackName, Audio::SoundH
 		return;
 	}
 	Audio::RewindableAudioStream *ogg = Audio::makeVorbisStream(track, DisposeAfterUse::YES);
-	_mixer->playStream(Audio::Mixer::kMusicSoundType, stream, ogg);
+	_mixer->playStream(Audio::Mixer::kMusicSoundType, &stream, ogg);
 #endif
 }
 
@@ -399,8 +399,8 @@ void FullpipeEngine::playSound(int id, int flag) {
 }
 
 void FullpipeEngine::playTrack(GameVar *sceneVar, const char *name, bool delayed) {
-	if (_mixer->isSoundHandleActive(*_soundStream3))
-		_mixer->stopHandle(*_soundStream4);
+	if (_mixer->isSoundHandleActive(_soundStream3))
+		_mixer->stopHandle(_soundStream4);
 
 	stopSoundStream2();
 
@@ -491,17 +491,17 @@ void global_messageHandler_handleSound(ExCommand *cmd) {
 void FullpipeEngine::stopSoundStream2() {
 	_stream2playing = false;
 
-	if (_mixer->isSoundHandleActive(*_soundStream3)) {
-		_mixer->stopHandle(*_soundStream2);
-		_mixer->stopHandle(*_soundStream3);
+	if (_mixer->isSoundHandleActive(_soundStream3)) {
+		_mixer->stopHandle(_soundStream2);
+		_mixer->stopHandle(_soundStream3);
 	}
 }
 
 void FullpipeEngine::stopAllSoundStreams() {
-	_mixer->stopHandle(*_soundStream1);
-	_mixer->stopHandle(*_soundStream2);
-	_mixer->stopHandle(*_soundStream3);
-	_mixer->stopHandle(*_soundStream4);
+	_mixer->stopHandle(_soundStream1);
+	_mixer->stopHandle(_soundStream2);
+	_mixer->stopHandle(_soundStream3);
+	_mixer->stopHandle(_soundStream4);
 
 	_stream2playing = false;
 }
diff --git a/engines/fullpipe/stateloader.cpp b/engines/fullpipe/stateloader.cpp
index d55f7db..5a2ad51 100644
--- a/engines/fullpipe/stateloader.cpp
+++ b/engines/fullpipe/stateloader.cpp
@@ -280,7 +280,7 @@ void gameLoaderSavegameCallback(MfcArchive *archive, bool mode) {
 }
 
 bool FullpipeEngine::loadGam(const char *fname, int scene) {
-	_gameLoader = new GameLoader();
+	_gameLoader.reset(new GameLoader());
 
 	if (!_gameLoader->loadFile(fname))
 		return false;


Commit: 5c89c39325f271a5ef4dcb55fbc013b3858791d5
    https://github.com/scummvm/scummvm/commit/5c89c39325f271a5ef4dcb55fbc013b3858791d5
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix memory leak of save game thumbnail

Changed paths:
    engines/fullpipe/detection.cpp
    engines/fullpipe/gameloader.h
    engines/fullpipe/stateloader.cpp
    engines/savestate.h


diff --git a/engines/fullpipe/detection.cpp b/engines/fullpipe/detection.cpp
index e22bcd3..82c7954 100644
--- a/engines/fullpipe/detection.cpp
+++ b/engines/fullpipe/detection.cpp
@@ -180,13 +180,11 @@ SaveStateList FullpipeMetaEngine::listSaves(const char *target) const {
 		int slotNum = atoi(file->c_str() + file->size() - 2);
 
 		if (slotNum >= 0 && slotNum <= getMaximumSaveSlot()) {
-			Common::InSaveFile *in = saveFileMan->openForLoading(*file);
+			Common::ScopedPtr<Common::InSaveFile> in(saveFileMan->openForLoading(*file));
 			if (in) {
 				Fullpipe::FullpipeSavegameHeader header;
-				Fullpipe::readSavegameHeader(in, header);
+				Fullpipe::readSavegameHeader(in.get(), header);
 				saveList.push_back(SaveStateDescriptor(slotNum, header.saveName));
-				delete header.thumbnail;
-				delete in;
 			}
 		}
 	}
@@ -201,13 +199,12 @@ void FullpipeMetaEngine::removeSaveState(const char *target, int slot) const {
 }
 
 SaveStateDescriptor FullpipeMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
-	Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(
-		Fullpipe::getSavegameFile(slot));
+	Common::ScopedPtr<Common::InSaveFile> f(g_system->getSavefileManager()->openForLoading(
+		Fullpipe::getSavegameFile(slot)));
 
 	if (f) {
 		Fullpipe::FullpipeSavegameHeader header;
-		Fullpipe::readSavegameHeader(f, header);
-		delete f;
+		Fullpipe::readSavegameHeader(f.get(), header);
 
 		// Create the return descriptor
 		SaveStateDescriptor desc(slot, header.saveName);
diff --git a/engines/fullpipe/gameloader.h b/engines/fullpipe/gameloader.h
index 5e4d931..39ccb77 100644
--- a/engines/fullpipe/gameloader.h
+++ b/engines/fullpipe/gameloader.h
@@ -23,6 +23,7 @@
 #ifndef FULLPIPE_GAMELOADER_H
 #define FULLPIPE_GAMELOADER_H
 
+#include "common/ptr.h"
 #include "engines/savestate.h"
 
 #include "fullpipe/objects.h"
@@ -83,7 +84,7 @@ struct FullpipeSavegameHeader {
 	uint32 date;
 	uint16 time;
 	uint32 playtime;
-	Graphics::Surface *thumbnail;
+	Common::SharedPtr<Graphics::Surface> thumbnail;
 };
 
 struct SaveHeader {
diff --git a/engines/fullpipe/stateloader.cpp b/engines/fullpipe/stateloader.cpp
index 5a2ad51..34c2252 100644
--- a/engines/fullpipe/stateloader.cpp
+++ b/engines/fullpipe/stateloader.cpp
@@ -195,8 +195,6 @@ void fillDummyHeader(Fullpipe::FullpipeSavegameHeader &header) {
 }
 
 bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header) {
-	header.thumbnail = NULL;
-
 	uint oldPos = in->pos();
 
 	in->seek(-4, SEEK_END);
@@ -239,7 +237,7 @@ bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header)
 	header.saveName = Common::String::format("%s %s", desc.getSaveDate().c_str(), desc.getSaveTime().c_str());
 
 	// Get the thumbnail
-	header.thumbnail = Graphics::loadThumbnail(*in);
+	header.thumbnail = Common::SharedPtr<Graphics::Surface>(Graphics::loadThumbnail(*in), Graphics::SurfaceDeleter());
 
 	in->seek(oldPos, SEEK_SET); // Rewind the file
 
diff --git a/engines/savestate.h b/engines/savestate.h
index 3244d61..567750c 100644
--- a/engines/savestate.h
+++ b/engines/savestate.h
@@ -121,6 +121,7 @@ public:
 	 * Hence the caller must not delete the surface.
 	 */
 	void setThumbnail(Graphics::Surface *t);
+	void setThumbnail(Common::SharedPtr<Graphics::Surface> t) { _thumbnail = t; }
 
 	/**
 	 * Sets the date the save state was created.


Commit: 8e8932f38d61789c76fd03a4a01e3cb74d3dc52d
    https://github.com/scummvm/scummvm/commit/8e8932f38d61789c76fd03a4a01e3cb74d3dc52d
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Remove unnecessary and illegal C-style casts

Changed paths:
    engines/fullpipe/anihandler.cpp
    engines/fullpipe/interaction.cpp
    engines/fullpipe/inventory.cpp
    engines/fullpipe/scenes/scene04.cpp
    engines/fullpipe/scenes/scene16.cpp
    engines/fullpipe/scenes/scene27.cpp


diff --git a/engines/fullpipe/anihandler.cpp b/engines/fullpipe/anihandler.cpp
index 3c13a70..c8feeae 100644
--- a/engines/fullpipe/anihandler.cpp
+++ b/engines/fullpipe/anihandler.cpp
@@ -163,14 +163,14 @@ void AniHandler::resetData(int objId) {
 
 	debugC(1, kDebugPathfinding, "WWW rebuild. idx: %d, size: %d", idx, obj->_staticsList.size() * obj->_staticsList.size());
 	for (uint i = 0; i < obj->_staticsList.size(); i++) {
-		_items[idx]->statics.push_back((Statics *)obj->_staticsList[i]);
+		_items[idx]->statics.push_back(obj->_staticsList[i]);
 
 		for (uint j = 0; j < obj->_staticsList.size(); j++) // Yes, square
 			_items[idx]->subItems.push_back(MGMSubItem());
 	}
 
 	for (uint i = 0; i < obj->_movements.size(); i++) {
-		_items[idx]->movements1.push_back((Movement *)obj->_movements[i]);
+		_items[idx]->movements1.push_back(obj->_movements[i]);
 		_items[idx]->movements2.push_back(0);
 	}
 
diff --git a/engines/fullpipe/interaction.cpp b/engines/fullpipe/interaction.cpp
index f13d826..4e3a3a3 100644
--- a/engines/fullpipe/interaction.cpp
+++ b/engines/fullpipe/interaction.cpp
@@ -172,7 +172,10 @@ bool InteractionController::handleInteraction(StaticANIObject *subj, GameObject
 		return false;
 
 	if (!inter->_objectId2) {
-		StaticANIObject *ani = (StaticANIObject *)obj;
+		if (obj->_objtype != kObjTypeStaticANIObject)
+			return false;
+
+		StaticANIObject *ani = static_cast<StaticANIObject *>(obj);
 
 		if (!ani->isIdle())
 			return false;
@@ -521,9 +524,14 @@ bool Interaction::isOverlapping(StaticANIObject *subj, GameObject *obj) {
 	if (abs(_xOffs + obj->_ox - subj->_ox) <= 1
 		&& abs(obj->_oy + _yOffs - subj->_oy) <= 1) {
 		if (!_staticsId2 || (subj->_statics != 0 && subj->_statics->_staticsId == _staticsId2)) {
-			StaticANIObject *ani = dynamic_cast<StaticANIObject *>(obj);
-			if (!_staticsId1 || !(_flags & 1) || (ani && ani->_statics != 0 && ani->_statics->_staticsId == _staticsId1))
+			if (!_staticsId1 || !(_flags & 1))
 				return true;
+
+			if (obj->_objtype == kObjTypeStaticANIObject) {
+				const StaticANIObject *ani = static_cast<StaticANIObject *>(obj);
+				if (ani->_statics != 0 && ani->_statics->_staticsId == _staticsId1)
+					return true;
+			}
 		}
 	}
 	return false;
diff --git a/engines/fullpipe/inventory.cpp b/engines/fullpipe/inventory.cpp
index fd8f73c..5ddf26d 100644
--- a/engines/fullpipe/inventory.cpp
+++ b/engines/fullpipe/inventory.cpp
@@ -171,7 +171,7 @@ void Inventory2::removeItem2(Scene *sceneObj, int itemId, int x, int y, int prio
 
 				sceneObj->addStaticANIObject(ani, 1);
 
-				ani->_statics = (Statics *)ani->_staticsList[0];
+				ani->_statics = ani->_staticsList[0];
 				ani->setOXY(x, y);
 				ani->_priority = priority;
 			}
diff --git a/engines/fullpipe/scenes/scene04.cpp b/engines/fullpipe/scenes/scene04.cpp
index 4b5e105..ae8e567 100644
--- a/engines/fullpipe/scenes/scene04.cpp
+++ b/engines/fullpipe/scenes/scene04.cpp
@@ -275,7 +275,7 @@ void sceneHandler04_checkBigBallClick() {
 
 	if (ball)
 		for (uint i = 0; i < ball->_movements.size(); i++)
-			((Movement *)ball->_movements[i])->_counterMax = 73;
+			ball->_movements[i]->_counterMax = 73;
 
 	g_vars->scene04_bigBallIn = true;
 }
@@ -1127,7 +1127,7 @@ void sceneHandler04_bigBallOut() {
 
 	if (ball && ball->_flags & 4)
 		for (uint i = 0; i < ball->_movements.size(); i++)
-			((Movement *)ball->_movements[i])->_counterMax = 0;
+			ball->_movements[i]->_counterMax = 0;
 
 	g_vars->scene04_bigBallIn = false;
 }
diff --git a/engines/fullpipe/scenes/scene16.cpp b/engines/fullpipe/scenes/scene16.cpp
index b7a63df..04de100 100644
--- a/engines/fullpipe/scenes/scene16.cpp
+++ b/engines/fullpipe/scenes/scene16.cpp
@@ -86,7 +86,7 @@ void scene16_initScene(Scene *sc) {
 
 		StaticANIObject *ani = new StaticANIObject(g_fp->accessScene(SC_COMMON)->getStaticANIObject1ById(ANI_BEARDED_CMN, -1));
 		ani->_movement = 0;
-		ani->_statics = (Statics *)ani->_staticsList[0];
+		ani->_statics = ani->_staticsList[0];
 		sc->addStaticANIObject(ani, 1);
 	}
 
diff --git a/engines/fullpipe/scenes/scene27.cpp b/engines/fullpipe/scenes/scene27.cpp
index 7a9a25d..171cd6d 100644
--- a/engines/fullpipe/scenes/scene27.cpp
+++ b/engines/fullpipe/scenes/scene27.cpp
@@ -235,7 +235,7 @@ void sceneHandler27_startBat(StaticANIObject *bat) {
 	newbat->currX = newbat->powerCos + (double)g_fp->_aniMan->_ox + 42.0;
 	newbat->currY = newbat->powerSin + (double)g_fp->_aniMan->_oy + 58.0;
 
-	bat->_statics = (Statics *)bat->_staticsList[0];
+	bat->_statics = bat->_staticsList[0];
 	bat->setOXY((int)newbat->currX, (int)newbat->currY);
 	bat->_flags |= 4;
 


Commit: 1337f04122cac5f0343090ac23119e4133624db0
    https://github.com/scummvm/scummvm/commit/1337f04122cac5f0343090ac23119e4133624db0
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix memory leaks of SceneTag

Changed paths:
    engines/fullpipe/objects.h
    engines/fullpipe/scene.cpp
    engines/fullpipe/stateloader.cpp


diff --git a/engines/fullpipe/objects.h b/engines/fullpipe/objects.h
index 78165c4..7501f2bd 100644
--- a/engines/fullpipe/objects.h
+++ b/engines/fullpipe/objects.h
@@ -23,6 +23,7 @@
 #ifndef FULLPIPE_OBJECTS_H
 #define FULLPIPE_OBJECTS_H
 
+#include "common/ptr.h"
 #include "fullpipe/utils.h"
 
 namespace Fullpipe {
@@ -34,12 +35,11 @@ class GameProject : public CObject {
  public:
 	int _field_4;
 	Common::String _headerFilename;
-	SceneTagList *_sceneTagList;
+	Common::ScopedPtr<SceneTagList> _sceneTagList;
 	int _field_10;
 
  public:
 	GameProject();
-	~GameProject();
 	virtual bool load(MfcArchive &file);
 };
 
diff --git a/engines/fullpipe/scene.cpp b/engines/fullpipe/scene.cpp
index 46ad205..6295e3b 100644
--- a/engines/fullpipe/scene.cpp
+++ b/engines/fullpipe/scene.cpp
@@ -61,9 +61,8 @@ bool SceneTagList::load(MfcArchive &file) {
 	int numEntries = file.readUint16LE();
 
 	for (int i = 0; i < numEntries; i++) {
-		SceneTag *t = new SceneTag();
-		t->load(file);
-		push_back(*t);
+		push_back(SceneTag());
+		back().load(file);
 	}
 
 	return true;
diff --git a/engines/fullpipe/stateloader.cpp b/engines/fullpipe/stateloader.cpp
index 34c2252..de10f2e 100644
--- a/engines/fullpipe/stateloader.cpp
+++ b/engines/fullpipe/stateloader.cpp
@@ -359,8 +359,6 @@ bool FullpipeEngine::loadGam(const char *fname, int scene) {
 GameProject::GameProject() {
 	_field_4 = 0;
 	_field_10 = 12;
-
-	_sceneTagList = 0;
 }
 
 bool GameProject::load(MfcArchive &file) {
@@ -380,7 +378,7 @@ bool GameProject::load(MfcArchive &file) {
 	debugC(1, kDebugLoading, "_scrollSpeed = %d", g_fp->_scrollSpeed);
 	debugC(1, kDebugLoading, "_headerFilename = %s", _headerFilename.c_str());
 
-	_sceneTagList = new SceneTagList();
+	_sceneTagList.reset(new SceneTagList());
 
 	_sceneTagList->load(file);
 
@@ -395,10 +393,6 @@ bool GameProject::load(MfcArchive &file) {
 	return true;
 }
 
-GameProject::~GameProject() {
-	delete _sceneTagList;
-}
-
 GameVar::GameVar() {
 	_subVars = 0;
 	_parentVarObj = 0;


Commit: c85f409a0b2fa1094ebd1a51c088d2d830383d38
    https://github.com/scummvm/scummvm/commit/c85f409a0b2fa1094ebd1a51c088d2d830383d38
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Remove memory leaks and manual memory management in Scene

Changed paths:
    engines/fullpipe/gameloader.cpp
    engines/fullpipe/scene.cpp
    engines/fullpipe/scene.h
    engines/fullpipe/scenes.cpp


diff --git a/engines/fullpipe/gameloader.cpp b/engines/fullpipe/gameloader.cpp
index 32c2d0d..4ed1890 100644
--- a/engines/fullpipe/gameloader.cpp
+++ b/engines/fullpipe/gameloader.cpp
@@ -286,7 +286,7 @@ bool preloadCallback(PreloadItem &pre, int flag) {
 
 		if (g_fp->_soundEnabled) {
 			g_fp->_currSoundListCount = 1;
-			g_fp->_currSoundList1[0] = g_fp->accessScene(SC_COMMON)->_soundList;
+			g_fp->_currSoundList1[0] = g_fp->accessScene(SC_COMMON)->_soundList.get();
 		}
 
 		g_vars->scene18_inScene18p1 = false;
diff --git a/engines/fullpipe/scene.cpp b/engines/fullpipe/scene.cpp
index 6295e3b..751f992 100644
--- a/engines/fullpipe/scene.cpp
+++ b/engines/fullpipe/scene.cpp
@@ -117,18 +117,9 @@ void SceneTag::loadScene() {
 	g_fp->_currArchive = 0;
 }
 
-Scene::Scene() {
-	_sceneId = 0;
-	_field_BC = 0;
-	_shadows = 0;
-	_soundList = 0;
-	_libHandle = 0;
-}
+Scene::Scene() : _sceneId(0), _field_BC(0) {}
 
 Scene::~Scene() {
-	delete _soundList;
-	delete _shadows;
-
 	// _faObjlist is not used
 
 	for (uint i = 0; i < _messageQueueList.size(); i++)
@@ -141,8 +132,6 @@ Scene::~Scene() {
 
 	_staticANIObjectList1.clear();
 
-	delete _libHandle;
-
 	// delete _field_BC;
 }
 
@@ -206,7 +195,7 @@ bool Scene::load(MfcArchive &file) {
 		assert(0);
 	}
 
-	_libHandle = g_fp->_currArchive;
+	_libHandle.reset(g_fp->_currArchive);
 
 	if (_picObjList.size() > 0 && !_bgname.empty()) {
 		char fname[260];
@@ -231,12 +220,14 @@ bool Scene::load(MfcArchive &file) {
 	Shadows *shd = new Shadows();
 
 	if (shd->loadFile(shdname))
-		_shadows = shd;
+		_shadows.reset(shd);
+	else
+		delete shd;
 
 	Common::String slsname = genFileName(0, _sceneId, "sls");
 
 	if (g_fp->_soundEnabled) {
-		_soundList = new SoundList();
+		_soundList.reset(new SoundList());
 
 		if (g_fp->_flgSoundList) {
 			Common::String nlname = genFileName(17, _sceneId, "nl");
diff --git a/engines/fullpipe/scene.h b/engines/fullpipe/scene.h
index 9a684ce..dd559a3 100644
--- a/engines/fullpipe/scene.h
+++ b/engines/fullpipe/scene.h
@@ -23,6 +23,7 @@
 #ifndef FULLPIPE_SCENE_H
 #define FULLPIPE_SCENE_H
 
+#include "common/ptr.h"
 #include "fullpipe/gfx.h"
 
 namespace Fullpipe {
@@ -35,12 +36,12 @@ class Scene : public Background {
 	Common::Array<StaticANIObject *> _staticANIObjectList2;
 	Common::Array<MessageQueue *> _messageQueueList;
 	// PtrList _faObjectList; // not used
-	Shadows *_shadows;
-	SoundList *_soundList;
+	Common::ScopedPtr<Shadows> _shadows;
+	Common::ScopedPtr<SoundList> _soundList;
 	int16 _sceneId;
 	Common::String _sceneName;
 	int _field_BC;
-	NGIArchive *_libHandle;
+	Common::ScopedPtr<NGIArchive> _libHandle;
 
   public:
 	Scene();
diff --git a/engines/fullpipe/scenes.cpp b/engines/fullpipe/scenes.cpp
index 896ea5a..034d2a7 100644
--- a/engines/fullpipe/scenes.cpp
+++ b/engines/fullpipe/scenes.cpp
@@ -573,15 +573,15 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
 	if (_soundEnabled) {
 		if (scene->_soundList) {
 			_currSoundListCount = 2;
-			_currSoundList1[0] = accessScene(SC_COMMON)->_soundList;
-			_currSoundList1[1] = scene->_soundList;
+			_currSoundList1[0] = accessScene(SC_COMMON)->_soundList.get();
+			_currSoundList1[1] = scene->_soundList.get();
 
 			for (int i = 0; i < scene->_soundList->getCount(); i++) {
 				scene->_soundList->getSoundByIndex(i).updateVolume();
 			}
 		} else {
 			_currSoundListCount = 1;
-			_currSoundList1[0] = accessScene(SC_COMMON)->_soundList;
+			_currSoundList1[0] = accessScene(SC_COMMON)->_soundList.get();
 		}
 	}
 


Commit: 350ddcee102b56029c42016b8c116fc839936e1c
    https://github.com/scummvm/scummvm/commit/350ddcee102b56029c42016b8c116fc839936e1c
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Take references instead of pointers for required arguments in statics, remove unnecessary Picture allocation

Changed paths:
    engines/fullpipe/gfx.cpp
    engines/fullpipe/gfx.h
    engines/fullpipe/statics.cpp
    engines/fullpipe/statics.h


diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp
index 3abf2fc..ecc9f8c 100644
--- a/engines/fullpipe/gfx.cpp
+++ b/engines/fullpipe/gfx.cpp
@@ -664,9 +664,9 @@ void Picture::setPaletteData(const Palette &pal) {
 	}
 }
 
-void Picture::copyMemoryObject2(Picture *src) {
-	if (_width == src->_width && _height == src->_height) {
-		if (src->_memoryObject2 && src->_memoryObject2->_rows && _memoryObject2) {
+void Picture::copyMemoryObject2(Picture &src) {
+	if (_width == src._width && _height == src._height) {
+		if (src._memoryObject2 && src._memoryObject2->_rows && _memoryObject2) {
 			byte *data = loadData();
 			_memoryObject2->copyData(data, _dataSize);
 			setAOIDs();
diff --git a/engines/fullpipe/gfx.h b/engines/fullpipe/gfx.h
index b92e94b..a2f7230 100644
--- a/engines/fullpipe/gfx.h
+++ b/engines/fullpipe/gfx.h
@@ -112,7 +112,7 @@ public:
 	const Palette &getPaletteData() const { return _paletteData; }
 	void setPaletteData(const Palette &pal);
 
-	void copyMemoryObject2(Picture *src);
+	void copyMemoryObject2(Picture &src);
 
 	int _x, _y;
 
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index f487f17..289dfa9 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -179,7 +179,7 @@ StaticANIObject::StaticANIObject(StaticANIObject *src) : GameObject(src) {
 	_objtype = kObjTypeStaticANIObject;
 
 	for (uint i = 0; i < src->_staticsList.size(); i++)
-		_staticsList.push_back(new Statics(src->_staticsList[i], 0));
+		_staticsList.push_back(new Statics(*src->_staticsList[i], false));
 
 	_movement = 0;
 	_statics = 0;
@@ -580,11 +580,11 @@ void StaticANIObject::freeMovementsPixelData() {
 }
 
 Statics *StaticANIObject::addReverseStatics(Statics *st) {
+	assert(st);
 	Statics *res = getStaticsById(st->_staticsId ^ 0x4000);
 
 	if (!res) {
-		res = new Statics(st, true);
-
+		res = new Statics(*st, true);
 		_staticsList.push_back(res);
 	}
 
@@ -1396,27 +1396,20 @@ Common::Point *StaticANIObject::calcStepLen(Common::Point *p) {
 
 Statics::Statics() {
 	_staticsId = 0;
-	_picture = nullptr;
 	_data = nullptr;
 }
 
-Statics::~Statics() {
-	delete _picture;
-}
-
-Statics::Statics(Statics *src, bool reverse) : DynamicPhase(src, reverse) {
-	_staticsId = src->_staticsId;
+Statics::Statics(Statics &src, bool reverse) : DynamicPhase(src, reverse) {
+	_staticsId = src._staticsId;
 
 	if (reverse) {
 		_staticsId ^= 0x4000;
-		_staticsName = sO_MirroredTo + src->_staticsName;
+		_staticsName = sO_MirroredTo + src._staticsName;
 	} else {
-		_staticsName = src->_staticsName;
+		_staticsName = src._staticsName;
 	}
 
-	_memfilename = src->_memfilename;
-
-	_picture = new Picture();
+	_memfilename = src._memfilename;
 }
 
 bool Statics::load(MfcArchive &file) {
@@ -1429,8 +1422,7 @@ bool Statics::load(MfcArchive &file) {
 	_staticsName = file.readPascalString();
 	debugC(7, kDebugLoading, "statics: <%s> id: %d (%x)", transCyrillic(_staticsName), _staticsId, _staticsId);
 
-	_picture = new Picture();
-	_picture->load(file);
+	_picture.load(file);
 
 	return true;
 }
@@ -1613,7 +1605,7 @@ Movement::Movement(Movement *src, int *oldIdxs, int newSize, StaticANIObject *an
 			src->setDynamicPhaseIndex(i);
 
 			if (i < newSize - 1)
-				_dynamicPhases.push_back(new DynamicPhase(src->_currDynamicPhase, 0));
+				_dynamicPhases.push_back(new DynamicPhase(*src->_currDynamicPhase, 0));
 
 			_framePosOffsets[i]->x = src->_framePosOffsets[i]->x;
 			_framePosOffsets[i]->y = src->_framePosOffsets[i]->y;
@@ -2140,18 +2132,18 @@ DynamicPhase::DynamicPhase() {
 	_data = nullptr;
 }
 
-DynamicPhase::DynamicPhase(DynamicPhase *src, bool reverse) {
-	_field_7C = src->_field_7C;
+DynamicPhase::DynamicPhase(DynamicPhase &src, bool reverse) {
+	_field_7C = src._field_7C;
 	_field_7E = 0;
 
 	debugC(1, kDebugAnimation, "DynamicPhase::DynamicPhase(src, %d)", reverse);
 
 	if (reverse) {
-		if (!src->_bitmap)
-			src->init();
+		if (!src._bitmap)
+			src.init();
 
-		_bitmap = BitmapPtr(src->_bitmap->reverseImage());
-		_dataSize = src->_dataSize;
+		_bitmap = BitmapPtr(src._bitmap->reverseImage());
+		_dataSize = src._dataSize;
 
 		if (g_fp->_currArchive) {
 			_mfield_14 = 0;
@@ -2160,43 +2152,43 @@ DynamicPhase::DynamicPhase(DynamicPhase *src, bool reverse) {
 
 		_mflags |= 1;
 
-		_someX = src->_someX;
-		_someY = src->_someY;
+		_someX = src._someX;
+		_someY = src._someY;
 	} else {
-		_mfield_14 = src->_mfield_14;
-		_mfield_8 = src->_mfield_8;
-		_mflags = src->_mflags;
+		_mfield_14 = src._mfield_14;
+		_mfield_8 = src._mfield_8;
+		_mflags = src._mflags;
 
-		_memfilename = src->_memfilename;
-		_dataSize = src->_dataSize;
-		_mfield_10 = src->_mfield_10;
-		_libHandle = src->_libHandle;
+		_memfilename = src._memfilename;
+		_dataSize = src._dataSize;
+		_mfield_10 = src._mfield_10;
+		_libHandle = src._libHandle;
 
-		if (src->_bitmap) {
+		if (src._bitmap) {
 			_field_54 = 1;
-			_bitmap = BitmapPtr(src->_bitmap->reverseImage(false));
+			_bitmap = BitmapPtr(src._bitmap->reverseImage(false));
 		}
 
-		_someX = src->_someX;
-		_someY = src->_someY;
+		_someX = src._someX;
+		_someY = src._someY;
 	}
 
-	_rect = src->_rect;
+	_rect = src._rect;
 
-	_width = src->_width;
-	_height = src->_height;
-	_field_7C = src->_field_7C;
+	_width = src._width;
+	_height = src._height;
+	_field_7C = src._field_7C;
 
-	if (src->getExCommand())
-		_exCommand = src->getExCommand()->createClone();
+	if (src.getExCommand())
+		_exCommand = src.getExCommand()->createClone();
 	else
 		_exCommand = 0;
 
-	_initialCountdown = src->_initialCountdown;
-	_field_6A = src->_field_6A;
-	_dynFlags = src->_dynFlags;
+	_initialCountdown = src._initialCountdown;
+	_field_6A = src._field_6A;
+	_dynFlags = src._dynFlags;
 
-	setPaletteData(src->getPaletteData());
+	setPaletteData(src.getPaletteData());
 
 	copyMemoryObject2(src);
 }
diff --git a/engines/fullpipe/statics.h b/engines/fullpipe/statics.h
index 24d9fd0..46b4a4b 100644
--- a/engines/fullpipe/statics.h
+++ b/engines/fullpipe/statics.h
@@ -78,7 +78,7 @@ class DynamicPhase : public StaticPhase {
 
   public:
 	DynamicPhase();
-	DynamicPhase(DynamicPhase *src, bool reverse);
+	DynamicPhase(DynamicPhase &src, bool reverse);
 
 	virtual bool load(MfcArchive &file);
 
@@ -89,12 +89,11 @@ class Statics : public DynamicPhase {
  public:
  	int16 _staticsId;
 	Common::String _staticsName;
-	Picture *_picture;
+	Picture _picture;
 
   public:
 	Statics();
-	Statics(Statics *src, bool reverse);
-	virtual ~Statics();
+	Statics(Statics &src, bool reverse);
 
 	virtual bool load(MfcArchive &file);
 	virtual void init();


Commit: b90f21597a1f77141dcfcd916850041258164882
    https://github.com/scummvm/scummvm/commit/b90f21597a1f77141dcfcd916850041258164882
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Use bool literals instead of ints for bool properties

Changed paths:
    engines/fullpipe/input.cpp


diff --git a/engines/fullpipe/input.cpp b/engines/fullpipe/input.cpp
index 0448c1b..499b985 100644
--- a/engines/fullpipe/input.cpp
+++ b/engines/fullpipe/input.cpp
@@ -186,8 +186,8 @@ void FullpipeEngine::defHandleKeyDown(int key) {
 			_normalSpeed = !_normalSpeed;
 			break;
 		case 3:								// OHWAIT
-			_gamePaused = 1;
-			_flgGameIsRunning = 0;
+			_gamePaused = true;
+			_flgGameIsRunning = false;
 			break;
 		case 4:								// MUSOFF
 			if (_musicAllowed & 2)


Commit: 7514c5289bb3f1a351aebf834532179925269f5c
    https://github.com/scummvm/scummvm/commit/7514c5289bb3f1a351aebf834532179925269f5c
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Remove manual memory management of streams

Changed paths:
    engines/fullpipe/statics.cpp
    engines/fullpipe/utils.cpp


diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index 289dfa9..223cc8c 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -222,17 +222,14 @@ bool StaticANIObject::load(MfcArchive &file) {
 
 		Common::String movname = genFileName(_id, movNum, "mov");
 
-		Common::SeekableReadStream *f = g_fp->_currArchive->createReadStreamForMember(movname);
+		Common::ScopedPtr<Common::SeekableReadStream> f(g_fp->_currArchive->createReadStreamForMember(movname));
 
 		Movement *mov = new Movement();
+		_movements.push_back(mov);
 
-		MfcArchive archive(f);
+		MfcArchive archive(f.get());
 
 		mov->load(archive, this);
-
-		_movements.push_back(mov);
-
-		delete f;
 	}
 
 	Common::Point pt;
diff --git a/engines/fullpipe/utils.cpp b/engines/fullpipe/utils.cpp
index 02b235a..72a3377 100644
--- a/engines/fullpipe/utils.cpp
+++ b/engines/fullpipe/utils.cpp
@@ -24,6 +24,7 @@
 
 #include "common/file.h"
 #include "common/memstream.h"
+#include "common/ptr.h"
 
 #include "fullpipe/objects.h"
 #include "fullpipe/motion.h"
@@ -166,7 +167,7 @@ void MemoryObject::loadFile(const Common::String &filename) {
 		if (g_fp->_currArchive != _libHandle && _libHandle)
 			g_fp->_currArchive = _libHandle;
 
-		Common::SeekableReadStream *s = g_fp->_currArchive->createReadStreamForMember(filename);
+		Common::ScopedPtr<Common::SeekableReadStream> s(g_fp->_currArchive->createReadStreamForMember(filename));
 
 		if (s) {
 			assert(s->size() > 0);
@@ -176,8 +177,6 @@ void MemoryObject::loadFile(const Common::String &filename) {
 			debugC(5, kDebugLoading, "Loading %s (%d bytes)", filename.c_str(), _dataSize);
 			_data = (byte *)calloc(_dataSize, 1);
 			s->read(_data, _dataSize);
-
-			delete s;
 		} else {
 			// We have no object to read. This is fine
 		}


Commit: 14a6ff0810b926d79808b3ff72d8a6ff8ee781d5
    https://github.com/scummvm/scummvm/commit/14a6ff0810b926d79808b3ff72d8a6ff8ee781d5
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix memory leaks of MovTable and remove unnecessary extra class

Changed paths:
    engines/fullpipe/fullpipe.cpp
    engines/fullpipe/fullpipe.h
    engines/fullpipe/gameloader.cpp
    engines/fullpipe/stateloader.cpp
    engines/fullpipe/statics.cpp
    engines/fullpipe/statics.h


diff --git a/engines/fullpipe/fullpipe.cpp b/engines/fullpipe/fullpipe.cpp
index 4e05f89..6f8e642 100644
--- a/engines/fullpipe/fullpipe.cpp
+++ b/engines/fullpipe/fullpipe.cpp
@@ -137,7 +137,6 @@ FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc)
 	_loaderScene = nullptr;
 	_scene2 = nullptr;
 	_scene3 = nullptr;
-	_movTable = nullptr;
 	_messageHandlers = nullptr;
 
 	_updateScreenCallback = nullptr;
@@ -452,7 +451,6 @@ void FullpipeEngine::updateEvents() {
 
 void FullpipeEngine::freeGameLoader() {
 	setCursor(0);
-	delete _movTable;
 	_floaters->stopAll();
 	_gameLoader.reset();
 	_currentScene = 0;
diff --git a/engines/fullpipe/fullpipe.h b/engines/fullpipe/fullpipe.h
index 9426c32..e6a3fde 100644
--- a/engines/fullpipe/fullpipe.h
+++ b/engines/fullpipe/fullpipe.h
@@ -77,7 +77,6 @@ class GameObject;
 class GlobalMessageQueueList;
 struct MessageHandler;
 class MessageQueue;
-struct MovTable;
 class AniHandler;
 class NGIArchive;
 class PictureObject;
@@ -86,6 +85,7 @@ class Scene;
 class SoundList;
 class StaticANIObject;
 class Vars;
+typedef Common::Array<int16> MovTable;
 typedef Common::Array<int32> Palette;
 
 int global_messageHandler1(ExCommand *cmd);
@@ -217,7 +217,7 @@ public:
 
 	Common::ScopedPtr<BehaviorManager> _behaviorManager;
 
-	MovTable *_movTable;
+	Common::ScopedPtr<MovTable> _movTable;
 
 	Common::ScopedPtr<Floaters> _floaters;
 	Common::ScopedPtr<AniHandler> _aniHandler;
diff --git a/engines/fullpipe/gameloader.cpp b/engines/fullpipe/gameloader.cpp
index 4ed1890..f2c078a 100644
--- a/engines/fullpipe/gameloader.cpp
+++ b/engines/fullpipe/gameloader.cpp
@@ -253,7 +253,7 @@ bool GameLoader::gotoScene(int sceneId, int entranceId) {
 bool preloadCallback(PreloadItem &pre, int flag) {
 	if (flag) {
 		if (flag == 50)
-			g_fp->_aniMan->preloadMovements(g_fp->_movTable);
+			g_fp->_aniMan->preloadMovements(g_fp->_movTable.get());
 
 		StaticANIObject *pbar = g_fp->_loaderScene->getStaticANIObject1ById(ANI_PBAR, -1);
 
diff --git a/engines/fullpipe/stateloader.cpp b/engines/fullpipe/stateloader.cpp
index de10f2e..0ff8c60 100644
--- a/engines/fullpipe/stateloader.cpp
+++ b/engines/fullpipe/stateloader.cpp
@@ -310,7 +310,7 @@ bool FullpipeEngine::loadGam(const char *fname, int scene) {
 	_aniMan = accessScene(SC_COMMON)->getAniMan();
 	_scene2 = 0;
 
-	_movTable = _aniMan->countMovements();
+	_movTable.reset(_aniMan->countMovements());
 
 	_aniMan->setSpeed(1);
 
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index 223cc8c..185a7e5 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -668,22 +668,19 @@ MovTable *StaticANIObject::countMovements() {
 	GameVar *preloadSubVar = g_fp->getGameLoaderGameVar()->getSubVarByName(getName())->getSubVarByName("PRELOAD");
 
 	if (!preloadSubVar || preloadSubVar->getSubVarsCount() == 0)
-		return 0;
+		return nullptr;
 
 	MovTable *movTable = new MovTable;
-
-	movTable->count = _movements.size();
-	movTable->movs = (int16 *)calloc(_movements.size(), sizeof(int16));
-
+	movTable->reserve(_movements.size());
 	for (uint i = 0; i < _movements.size(); i++) {
-		movTable->movs[i] = 2;
-
+		int16 value = 2;
 		for (GameVar *sub = preloadSubVar->_subVars; sub; sub = sub->_nextVarObj) {
 			if (scumm_stricmp(_movements[i]->getName().c_str(), sub->_varName.c_str()) == 0) {
-				movTable->movs[i] = 1;
+				value = 1;
 				break;
 			}
 		}
+		movTable->push_back(value);
 	}
 
 	return movTable;
@@ -728,9 +725,9 @@ void StaticANIObject::preloadMovements(MovTable *mt) {
 		for (uint i = 0; i < _movements.size(); i++) {
 			Movement *mov = _movements[i];
 
-			if (mt->movs[i] == 1)
+			if ((*mt)[i] == 1)
 				mov->loadPixelData();
-			else if (mt->movs[i] == 2)
+			else if ((*mt)[i] == 2)
 				mov->freePixelData();
 		}
 	}
diff --git a/engines/fullpipe/statics.h b/engines/fullpipe/statics.h
index 46b4a4b..462a76c 100644
--- a/engines/fullpipe/statics.h
+++ b/engines/fullpipe/statics.h
@@ -244,6 +244,7 @@ public:
 	void draw();
 	void draw2();
 
+	/** ownership of returned object is transferred to caller */
 	MovTable *countMovements();
 	Common::Point *calcStepLen(Common::Point *p);
 	void setSpeed(int speed);
@@ -259,14 +260,6 @@ public:
 	bool isPixelHitAtPos(int x, int y);
 };
 
-struct MovTable {
-	int count;
-	int16 *movs;
-
-	MovTable() { count = 0; movs = 0; }
-	~MovTable() { free(movs); }
-};
-
 } // End of namespace Fullpipe
 
 #endif /* FULLPIPE_STATICS_H */


Commit: 7c66ffe5c89594f2d6f072b8e6b5c1f089395a11
    https://github.com/scummvm/scummvm/commit/7c66ffe5c89594f2d6f072b8e6b5c1f089395a11
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix memory leak of MGMItem

Changed paths:
    engines/fullpipe/anihandler.cpp
    engines/fullpipe/anihandler.h


diff --git a/engines/fullpipe/anihandler.cpp b/engines/fullpipe/anihandler.cpp
index c8feeae..b7489b7 100644
--- a/engines/fullpipe/anihandler.cpp
+++ b/engines/fullpipe/anihandler.cpp
@@ -59,14 +59,14 @@ MessageQueue *AniHandler::makeQueue(StaticANIObject *ani, int staticsIndex, int
 
 	int startidx = getStaticsIndexById(idx, stid);
 	int endidx = getStaticsIndexById(idx, staticsIndex);
-	int subidx = startidx + endidx * _items[idx]->statics.size();
+	int subidx = startidx + endidx * _items[idx].statics.size();
 
-	if (!_items[idx]->subItems[subidx].movement) {
+	if (!_items[idx].subItems[subidx].movement) {
 		clearVisitsList(idx);
 		seekWay(idx, startidx, endidx, 0, 1);
 	}
 
-	if (!_items[idx]->subItems[subidx].movement)
+	if (!_items[idx].subItems[subidx].movement)
 		return 0;
 
 	MessageQueue *mq = new MessageQueue(g_fp->_globalMessageQueueList->compact());
@@ -75,23 +75,23 @@ MessageQueue *AniHandler::makeQueue(StaticANIObject *ani, int staticsIndex, int
 
 	int i = 0;
 	do {
-		subidx = startidx + endidx * _items[idx]->statics.size();
+		subidx = startidx + endidx * _items[idx].statics.size();
 
-		point = _items[idx]->subItems[subidx].movement->calcSomeXY(0, -1);
+		point = _items[idx].subItems[subidx].movement->calcSomeXY(0, -1);
 
 		if (pointArr) {
 			int sz;
 
-			if (_items[idx]->subItems[subidx].movement->_currMovement)
-				sz = _items[idx]->subItems[subidx].movement->_currMovement->_dynamicPhases.size();
+			if (_items[idx].subItems[subidx].movement->_currMovement)
+				sz = _items[idx].subItems[subidx].movement->_currMovement->_dynamicPhases.size();
 			else
-				sz = _items[idx]->subItems[subidx].movement->_dynamicPhases.size();
+				sz = _items[idx].subItems[subidx].movement->_dynamicPhases.size();
 
 			ex = new ExCommand2(20, ani->_id, &pointArr[i], sz);
 
-			ex->_messageNum = _items[idx]->subItems[subidx].movement->_id;
+			ex->_messageNum = _items[idx].subItems[subidx].movement->_id;
 		} else {
-			ex = new ExCommand(ani->_id, 1, _items[idx]->subItems[subidx].movement->_id, 0, 0, 0, 1, 0, 0, 0);
+			ex = new ExCommand(ani->_id, 1, _items[idx].subItems[subidx].movement->_id, 0, 0, 0, 1, 0, 0, 0);
 		}
 
 		ex->_param = ani->_odelay;
@@ -101,16 +101,16 @@ MessageQueue *AniHandler::makeQueue(StaticANIObject *ani, int staticsIndex, int
 		mq->addExCommandToEnd(ex);
 
 		if (resStatId)
-			*resStatId = _items[idx]->subItems[subidx].movement->_id;
+			*resStatId = _items[idx].subItems[subidx].movement->_id;
 
-		startidx = _items[idx]->subItems[subidx].staticsIndex;
+		startidx = _items[idx].subItems[subidx].staticsIndex;
 
 		uint step;
 
-		if (_items[idx]->subItems[subidx].movement->_currMovement)
-			step = _items[idx]->subItems[subidx].movement->_currMovement->_dynamicPhases.size();
+		if (_items[idx].subItems[subidx].movement->_currMovement)
+			step = _items[idx].subItems[subidx].movement->_currMovement->_dynamicPhases.size();
 		else
-			step = _items[idx]->subItems[subidx].movement->_dynamicPhases.size();
+			step = _items[idx].subItems[subidx].movement->_dynamicPhases.size();
 
 		i += step;
 	} while (startidx != endidx);
@@ -135,10 +135,8 @@ void AniHandler::attachObject(int objId) {
 	debugC(4, kDebugPathfinding, "AniHandler::addItem(%d)", objId);
 
 	if (getIndex(objId) == -1) {
-		MGMItem *item = new MGMItem();
-
-		item->objId = objId;
-		_items.push_back(item);
+		_items.push_back(MGMItem());
+		_items.back().objId = objId;
 	}
 	resetData(objId);
 }
@@ -149,12 +147,12 @@ void AniHandler::resetData(int objId) {
 	if (idx == -1)
 		return;
 
-	debugC(3, kDebugPathfinding, "AniHandler::resetData. (1) movements1 sz: %d movements2 sz: %d", _items[idx]->movements1.size(), _items[idx]->movements2.size());
+	debugC(3, kDebugPathfinding, "AniHandler::resetData. (1) movements1 sz: %d movements2 sz: %d", _items[idx].movements1.size(), _items[idx].movements2.size());
 
-	_items[idx]->subItems.clear();
-	_items[idx]->statics.clear();
-	_items[idx]->movements1.clear();
-	_items[idx]->movements2.clear();
+	_items[idx].subItems.clear();
+	_items[idx].statics.clear();
+	_items[idx].movements1.clear();
+	_items[idx].movements2.clear();
 
 	StaticANIObject *obj = g_fp->_currentScene->getStaticANIObject1ById(objId, -1);
 
@@ -163,23 +161,23 @@ void AniHandler::resetData(int objId) {
 
 	debugC(1, kDebugPathfinding, "WWW rebuild. idx: %d, size: %d", idx, obj->_staticsList.size() * obj->_staticsList.size());
 	for (uint i = 0; i < obj->_staticsList.size(); i++) {
-		_items[idx]->statics.push_back(obj->_staticsList[i]);
+		_items[idx].statics.push_back(obj->_staticsList[i]);
 
 		for (uint j = 0; j < obj->_staticsList.size(); j++) // Yes, square
-			_items[idx]->subItems.push_back(MGMSubItem());
+			_items[idx].subItems.push_back(MGMSubItem());
 	}
 
 	for (uint i = 0; i < obj->_movements.size(); i++) {
-		_items[idx]->movements1.push_back(obj->_movements[i]);
-		_items[idx]->movements2.push_back(0);
+		_items[idx].movements1.push_back(obj->_movements[i]);
+		_items[idx].movements2.push_back(0);
 	}
 
-	debugC(3, kDebugPathfinding, "AniHandler::resetData. (2) movements1 sz: %d movements2 sz: %d", _items[idx]->movements1.size(), _items[idx]->movements2.size());
+	debugC(3, kDebugPathfinding, "AniHandler::resetData. (2) movements1 sz: %d movements2 sz: %d", _items[idx].movements1.size(), _items[idx].movements2.size());
 }
 
 int AniHandler::getIndex(int objId) {
 	for (uint i = 0; i < _items.size(); i++)
-		if (_items[i]->objId == objId)
+		if (_items[i].objId == objId)
 			return i;
 
 	return -1;
@@ -235,15 +233,15 @@ MessageQueue *AniHandler::makeRunQueue(MakeQueueStruct *mkQueue) {
 	int st1idx = getStaticsIndexById(itemIdx, mov->_staticsObj2->_staticsId);
 	int subOffset = getStaticsIndexById(itemIdx, mkQueue->staticsId2);
 
-	debugC(3, kDebugPathfinding, "AniHandler::genMovement. (1) movements1 sz: %d movements2 sz: %d", _items[itemIdx]->movements1.size(), _items[itemIdx]->movements2.size());
+	debugC(3, kDebugPathfinding, "AniHandler::genMovement. (1) movements1 sz: %d movements2 sz: %d", _items[itemIdx].movements1.size(), _items[itemIdx].movements2.size());
 
 	clearVisitsList(itemIdx);
 	seekWay(itemIdx, subIdx, st2idx, 0, 1);
 	clearVisitsList(itemIdx);
 	seekWay(itemIdx, st1idx, subOffset, 0, 1);
 
-	const MGMSubItem &sub1 = _items[itemIdx]->subItems[subIdx + st2idx * _items[itemIdx]->statics.size()];
-	const MGMSubItem &sub2 = _items[itemIdx]->subItems[st1idx + subOffset * _items[itemIdx]->statics.size()];
+	const MGMSubItem &sub1 = _items[itemIdx].subItems[subIdx + st2idx * _items[itemIdx].statics.size()];
+	const MGMSubItem &sub2 = _items[itemIdx].subItems[st1idx + subOffset * _items[itemIdx].statics.size()];
 
 	if (subIdx != st2idx && !sub1.movement)
 		return 0;
@@ -344,7 +342,7 @@ MessageQueue *AniHandler::makeRunQueue(MakeQueueStruct *mkQueue) {
 	ExCommand2 *ex2;
 
 	for (int i = subIdx; i != st2idx;) {
-		const MGMSubItem &s = _items[itemIdx]->subItems[i + st2idx * _items[itemIdx]->statics.size()];
+		const MGMSubItem &s = _items[itemIdx].subItems[i + st2idx * _items[itemIdx].statics.size()];
 
 		ex2 = createCommand(s.movement, mkQueue->ani->_id, x1, y1, &x2, &y2, -1);
 		ex2->_parId = mq->_id;
@@ -371,7 +369,7 @@ MessageQueue *AniHandler::makeRunQueue(MakeQueueStruct *mkQueue) {
 	}
 
 	for (int j = st1idx; j != subOffset;) {
-		const MGMSubItem &s = _items[itemIdx]->subItems[j + subOffset * _items[itemIdx]->statics.size()];
+		const MGMSubItem &s = _items[itemIdx].subItems[j + subOffset * _items[itemIdx].statics.size()];
 
 		ex2 = createCommand(s.movement, mkQueue->ani->_id, x1, y1, &x2, &y2, -1);
 		ex2->_parId = mq->_id;
@@ -391,7 +389,7 @@ MessageQueue *AniHandler::makeRunQueue(MakeQueueStruct *mkQueue) {
 
 	mq->addExCommandToEnd(ex);
 
-	debugC(3, kDebugPathfinding, "AniHandler::genMovement. (2) movements1 sz: %d movements2 sz: %d", _items[itemIdx]->movements1.size(), _items[itemIdx]->movements2.size());
+	debugC(3, kDebugPathfinding, "AniHandler::genMovement. (2) movements1 sz: %d movements2 sz: %d", _items[itemIdx].movements1.size(), _items[itemIdx].movements2.size());
 
 	return mq;
 }
@@ -406,9 +404,9 @@ int AniHandler::getFramesCount(int idx, int subIdx, int endIdx, int flag) {
 		if (subIdx < 0)
 			break;
 
-		res += _items[idx]->subItems[subIdx + endIdx * _items[idx]->statics.size()].movement->countPhasesWithFlag(0xffffffff, flag);
+		res += _items[idx].subItems[subIdx + endIdx * _items[idx].statics.size()].movement->countPhasesWithFlag(0xffffffff, flag);
 
-		subIdx = _items[idx]->subItems[subIdx + endIdx * _items[idx]->statics.size()].staticsIndex;
+		subIdx = _items[idx].subItems[subIdx + endIdx * _items[idx].statics.size()].staticsIndex;
 	}
 
 	return res;
@@ -457,19 +455,19 @@ Common::Point AniHandler::getTransitionSize(int objectId, int staticsId1, int st
 		return Common::Point(0, 0);
 	}
 
-	int subidx = st1idx + st2idx * _items[idx]->statics.size();
+	int subidx = st1idx + st2idx * _items[idx].statics.size();
 
-	if (!_items[idx]->subItems[subidx].movement) {
+	if (!_items[idx].subItems[subidx].movement) {
 		clearVisitsList(idx);
 		seekWay(idx, st1idx, st2idx, false, true);
 
-		if (!_items[idx]->subItems[subidx].movement) {
+		if (!_items[idx].subItems[subidx].movement) {
 			clearVisitsList(idx);
 			seekWay(idx, st1idx, st2idx, true, false);
 		}
 	}
 
-	const MGMSubItem &sub = _items[idx]->subItems[subidx];
+	const MGMSubItem &sub = _items[idx].subItems[subidx];
 
 	if (!sub.movement) {
 		return Common::Point(0, 0);
@@ -479,11 +477,11 @@ Common::Point AniHandler::getTransitionSize(int objectId, int staticsId1, int st
 }
 
 int AniHandler::getStaticsIndexById(int idx, int16 id) {
-	if (!_items[idx]->statics.size())
+	if (!_items[idx].statics.size())
 		return -1;
 
-	for (uint i = 0; i < _items[idx]->statics.size(); i++) {
-		if (_items[idx]->statics[i]->_staticsId == id)
+	for (uint i = 0; i < _items[idx].statics.size(); i++) {
+		if (_items[idx].statics[i]->_staticsId == id)
 			return i;
 	}
 
@@ -491,11 +489,11 @@ int AniHandler::getStaticsIndexById(int idx, int16 id) {
 }
 
 int AniHandler::getStaticsIndex(int idx, Statics *st) {
-	if (!_items[idx]->statics.size())
+	if (!_items[idx].statics.size())
 		return -1;
 
-	for (uint i = 0; i < _items[idx]->statics.size(); i++) {
-		if (_items[idx]->statics[i] == st)
+	for (uint i = 0; i < _items[idx].statics.size(); i++) {
+		if (_items[idx].statics[i] == st)
 			return i;
 	}
 
@@ -505,69 +503,69 @@ int AniHandler::getStaticsIndex(int idx, Statics *st) {
 void AniHandler::clearVisitsList(int idx) {
 	debugC(2, kDebugPathfinding, "AniHandler::clearVisitsList(%d)", idx);
 
-	for (uint i = 0; i < _items[idx]->movements2.size(); i++)
-		_items[idx]->movements2[i] = 0;
+	for (uint i = 0; i < _items[idx].movements2.size(); i++)
+		_items[idx].movements2[i] = 0;
 
-	debugC(3, kDebugPathfinding, "AniHandler::clearVisitsList. movements1 sz: %d movements2 sz: %d", _items[idx]->movements1.size(), _items[idx]->movements2.size());
+	debugC(3, kDebugPathfinding, "AniHandler::clearVisitsList. movements1 sz: %d movements2 sz: %d", _items[idx].movements1.size(), _items[idx].movements2.size());
 }
 
 int AniHandler::seekWay(int idx, int st1idx, int st2idx, bool flip, bool flop) {
-	MGMItem *item = _items[idx];
-	int subIdx = st1idx + st2idx * item->statics.size();
+	MGMItem &item = _items[idx];
+	int subIdx = st1idx + st2idx * item.statics.size();
 
 	debugC(2, kDebugPathfinding, "AniHandler::seekWay(%d, %d, %d, %d, %d)", idx, st1idx, st2idx, flip, flop);
 
 	if (st1idx == st2idx) {
-		memset(&item->subItems[subIdx], 0, sizeof(item->subItems[subIdx]));
+		memset(&item.subItems[subIdx], 0, sizeof(item.subItems[subIdx]));
 		return 0;
 	}
 
-	if (item->subItems[subIdx].movement)
-		return item->subItems[subIdx].field_8;
+	if (item.subItems[subIdx].movement)
+		return item.subItems[subIdx].field_8;
 
 	Common::Point point;
 
-	debugC(3, kDebugPathfinding, "AniHandler::seekWay. movements1 sz: %d movements2 sz: %d", item->movements1.size(), item->movements2.size());
+	debugC(3, kDebugPathfinding, "AniHandler::seekWay. movements1 sz: %d movements2 sz: %d", item.movements1.size(), item.movements2.size());
 
-	for (uint i = 0; i < item->movements1.size(); i++) {
-		Movement *mov = item->movements1[i];
+	for (uint i = 0; i < item.movements1.size(); i++) {
+		Movement *mov = item.movements1[i];
 
-		if (mov->_staticsObj1 == item->statics[st1idx]) {
-			if (item->movements2[i] || (flop && !mov->_field_50))
+		if (mov->_staticsObj1 == item.statics[st1idx]) {
+			if (item.movements2[i] || (flop && !mov->_field_50))
 				continue;
 
-			item->movements2[i] = 1;
+			item.movements2[i] = 1;
 
 			int stidx = getStaticsIndex(idx, mov->_staticsObj2);
 			int recalc = seekWay(idx, stidx, st2idx, flip, flop);
 			int sz = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size();
-			debugC(1, kDebugPathfinding, "AniHandler::seekWay, want idx: %d, off: %d (%d + %d), sz: %d", idx, stidx + st2idx * _items[idx]->statics.size(), stidx, st2idx, item->subItems.size());
+			debugC(1, kDebugPathfinding, "AniHandler::seekWay, want idx: %d, off: %d (%d + %d), sz: %d", idx, stidx + st2idx * _items[idx].statics.size(), stidx, st2idx, item.subItems.size());
 
-			int newsz = sz + item->subItems[stidx + st2idx * _items[idx]->statics.size()].field_C;
+			int newsz = sz + item.subItems[stidx + st2idx * _items[idx].statics.size()].field_C;
 
 			if (recalc < 0)
 				continue;
 
-			if (!item->subItems[subIdx].movement || item->subItems[subIdx].field_8 > recalc + 1 ||
-				(item->subItems[subIdx].field_8 == recalc + 1 && item->subItems[subIdx].field_C > newsz)) {
-				item->subItems[subIdx].movement = mov;
-				item->subItems[subIdx].staticsIndex = stidx;
-				item->subItems[subIdx].field_8 = recalc + 1;
-				item->subItems[subIdx].field_C = newsz;
+			if (!item.subItems[subIdx].movement || item.subItems[subIdx].field_8 > recalc + 1 ||
+				(item.subItems[subIdx].field_8 == recalc + 1 && item.subItems[subIdx].field_C > newsz)) {
+				item.subItems[subIdx].movement = mov;
+				item.subItems[subIdx].staticsIndex = stidx;
+				item.subItems[subIdx].field_8 = recalc + 1;
+				item.subItems[subIdx].field_C = newsz;
 
 				point = mov->calcSomeXY(0, -1);
 
-				item->subItems[subIdx].x = item->subItems[stidx + st2idx * _items[idx]->statics.size()].x + point.x;
-				item->subItems[subIdx].y = item->subItems[stidx + st2idx * _items[idx]->statics.size()].y + point.y;
+				item.subItems[subIdx].x = item.subItems[stidx + st2idx * _items[idx].statics.size()].x + point.x;
+				item.subItems[subIdx].y = item.subItems[stidx + st2idx * _items[idx].statics.size()].y + point.y;
 			}
 		} else if (flip) {
-			if (mov->_staticsObj2 != item->statics[st1idx])
+			if (mov->_staticsObj2 != item.statics[st1idx])
 				continue;
 
-			if (item->movements2[i] || (flop && !mov->_field_50))
+			if (item.movements2[i] || (flop && !mov->_field_50))
 				continue;
 
-			item->movements2[i] = 1;
+			item.movements2[i] = 1;
 
 			int stidx = getStaticsIndex(idx, mov->_staticsObj1);
 			int recalc = seekWay(idx, stidx, st2idx, flip, flop);
@@ -575,25 +573,25 @@ int AniHandler::seekWay(int idx, int st1idx, int st2idx, bool flip, bool flop) {
 			if (recalc < 0)
 				continue;
 
-			if (!item->subItems[subIdx].movement || item->subItems[subIdx].field_8 > recalc + 1) {
-				item->subItems[subIdx].movement = mov;
-				item->subItems[subIdx].staticsIndex = stidx;
-				item->subItems[subIdx].field_8 = recalc + 1;
+			if (!item.subItems[subIdx].movement || item.subItems[subIdx].field_8 > recalc + 1) {
+				item.subItems[subIdx].movement = mov;
+				item.subItems[subIdx].staticsIndex = stidx;
+				item.subItems[subIdx].field_8 = recalc + 1;
 
 				int sz = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size();
 
-				item->subItems[subIdx].field_C = sz + item->subItems[stidx + st2idx * _items[idx]->statics.size()].field_C;
+				item.subItems[subIdx].field_C = sz + item.subItems[stidx + st2idx * _items[idx].statics.size()].field_C;
 
 				point = mov->calcSomeXY(0, -1);
 
-				item->subItems[subIdx].x = item->subItems[stidx + st2idx * _items[idx]->statics.size()].x - point.x;
-				item->subItems[subIdx].y = item->subItems[stidx + st2idx * _items[idx]->statics.size()].y - point.y;
+				item.subItems[subIdx].x = item.subItems[stidx + st2idx * _items[idx].statics.size()].x - point.x;
+				item.subItems[subIdx].y = item.subItems[stidx + st2idx * _items[idx].statics.size()].y - point.y;
 			}
 		}
 	}
 
-	if (item->subItems[subIdx].movement)
-		return item->subItems[subIdx].field_8;
+	if (item.subItems[subIdx].movement)
+		return item.subItems[subIdx].field_8;
 
 	return -1;
 }
@@ -607,8 +605,8 @@ int AniHandler::getNumMovements(int objectId, int idx1, int idx2) {
 		int from = getStaticsIndexById(idx, idx1);
 		int to = getStaticsIndexById(idx, idx2);
 
-		debugC(1, kDebugPathfinding, "WWW 6, want idx: %d, off: %d", idx, from + to * _items[idx]->statics.size());
-		const MGMSubItem &sub = _items[idx]->subItems[from + to * _items[idx]->statics.size()];
+		debugC(1, kDebugPathfinding, "WWW 6, want idx: %d, off: %d", idx, from + to * _items[idx].statics.size());
+		const MGMSubItem &sub = _items[idx].subItems[from + to * _items[idx].statics.size()];
 
 		if (sub.movement) {
 			idx = sub.field_8;
diff --git a/engines/fullpipe/anihandler.h b/engines/fullpipe/anihandler.h
index 73f96c3..5bc771a 100644
--- a/engines/fullpipe/anihandler.h
+++ b/engines/fullpipe/anihandler.h
@@ -67,8 +67,8 @@ struct MakeQueueStruct {
 };
 
 class AniHandler : public CObject {
-public:
-	Common::Array<MGMItem *> _items;
+protected:
+	Common::Array<MGMItem> _items;
 
 public:
 	void detachAllObjects();


Commit: 384d68b679de37c906c8cac250fe2bb407c1ecb3
    https://github.com/scummvm/scummvm/commit/384d68b679de37c906c8cac250fe2bb407c1ecb3
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Correctly fix Bitmap leaks

Changed paths:
    engines/fullpipe/gfx.cpp
    engines/fullpipe/gfx.h
    engines/fullpipe/statics.cpp


diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp
index ecc9f8c..da626c7 100644
--- a/engines/fullpipe/gfx.cpp
+++ b/engines/fullpipe/gfx.cpp
@@ -524,7 +524,7 @@ void Picture::init() {
 
 	MemoryObject::getData();
 
-	_bitmap = BitmapPtr(new Bitmap());
+	_bitmap.reset(new Bitmap());
 
 	getDibInfo();
 
@@ -735,7 +735,7 @@ Bitmap::Bitmap(const Bitmap &src) {
 	_type = src._type;
 	_width = src._width;
 	_height = src._height;
-	_surface = TransSurfacePtr(src._surface);
+	_surface = src._surface;
 	_flipping = src._flipping;
 }
 
@@ -773,8 +773,7 @@ bool Bitmap::isPixelHitAtPos(int x, int y) {
 }
 
 void Bitmap::decode(byte *pixels, const Palette &palette) {
-	_surface = TransSurfacePtr(new Graphics::TransparentSurface);
-
+	_surface = TransSurfacePtr(new Graphics::TransparentSurface, Graphics::SurfaceDeleter());
 	_surface->create(_width, _height, Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
 
 	if (_type == MKTAG('R', 'B', '\0', '\0'))
diff --git a/engines/fullpipe/gfx.h b/engines/fullpipe/gfx.h
index a2f7230..eb8d03f 100644
--- a/engines/fullpipe/gfx.h
+++ b/engines/fullpipe/gfx.h
@@ -81,8 +81,6 @@ private:
 	Bitmap operator=(const Bitmap &);
 };
 
-typedef Common::SharedPtr<Bitmap> BitmapPtr;
-
 class Picture : public MemoryObject {
 public:
 	Picture();
@@ -122,7 +120,7 @@ protected:
 	int _field_44;
 	int _width;
 	int _height;
-	BitmapPtr _bitmap;
+	Common::ScopedPtr<Bitmap> _bitmap;
 	int _field_54;
 	Common::ScopedPtr<MemoryObject2> _memoryObject2;
 	int _alpha;
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index 185a7e5..8c0a045 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -1425,7 +1425,7 @@ void Statics::init() {
 	Picture::init();
 
 	if (_staticsId & 0x4000) {
-		_bitmap = BitmapPtr(_bitmap->reverseImage());
+		_bitmap.reset(_bitmap->reverseImage());
 	}
 }
 
@@ -2136,7 +2136,7 @@ DynamicPhase::DynamicPhase(DynamicPhase &src, bool reverse) {
 		if (!src._bitmap)
 			src.init();
 
-		_bitmap = BitmapPtr(src._bitmap->reverseImage());
+		_bitmap.reset(src._bitmap->reverseImage());
 		_dataSize = src._dataSize;
 
 		if (g_fp->_currArchive) {
@@ -2160,7 +2160,7 @@ DynamicPhase::DynamicPhase(DynamicPhase &src, bool reverse) {
 
 		if (src._bitmap) {
 			_field_54 = 1;
-			_bitmap = BitmapPtr(src._bitmap->reverseImage(false));
+			_bitmap.reset(src._bitmap->reverseImage(false));
 		}
 
 		_someX = src._someX;


Commit: d07e9a0cf108cfc1525060e9d1b2260c26b901df
    https://github.com/scummvm/scummvm/commit/d07e9a0cf108cfc1525060e9d1b2260c26b901df
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix memory leaks and ownership problems with Behavior objects

Changed paths:
    engines/fullpipe/behavior.cpp
    engines/fullpipe/behavior.h


diff --git a/engines/fullpipe/behavior.cpp b/engines/fullpipe/behavior.cpp
index 61327c2..a1e01b2 100644
--- a/engines/fullpipe/behavior.cpp
+++ b/engines/fullpipe/behavior.cpp
@@ -39,12 +39,6 @@ BehaviorManager::~BehaviorManager() {
 }
 
 void BehaviorManager::clear() {
-	for (uint i = 0; i < _behaviors.size(); i++) {
-		for (int j = 0; j < _behaviors[i]->_animsCount; j++)
-			delete _behaviors[i]->_behaviorAnims[j];
-
-		delete _behaviors[i];
-	}
 	_behaviors.clear();
 }
 
@@ -54,8 +48,6 @@ void BehaviorManager::initBehavior(Scene *sc, GameVar *var) {
 	clear();
 	_scene = sc;
 
-	BehaviorInfo *behinfo;
-
 	GameVar *behvar = var->getSubVarByName("BEHAVIOR");
 	if (!behvar)
 		return;
@@ -65,20 +57,17 @@ void BehaviorManager::initBehavior(Scene *sc, GameVar *var) {
 	for (GameVar *subvar = behvar->_subVars; subvar; subvar = subvar->_nextVarObj) {
 		debugC(3, kDebugBehavior, "BehaviorManager::initBehavior. subVar %s", transCyrillic(subvar->_varName));
 		if (subvar->_varName == "AMBIENT") {
-			behinfo = new BehaviorInfo;
-			behinfo->initAmbientBehavior(subvar, sc);
-
-			_behaviors.push_back(behinfo);
+			_behaviors.push_back(BehaviorInfo());
+			_behaviors.back().initAmbientBehavior(subvar, sc);
 		} else {
 			StaticANIObject *ani = sc->getStaticANIObject1ByName(subvar->_varName, -1);
 			if (ani) {
 				for (uint i = 0; i < sc->_staticANIObjectList1.size(); i++) {
 					if (((StaticANIObject *)sc->_staticANIObjectList1[i])->_id == ani->_id) {
-						behinfo = new BehaviorInfo;
-						behinfo->initObjectBehavior(subvar, sc, ani);
-						behinfo->_ani = (StaticANIObject *)sc->_staticANIObjectList1[i];
-
-						_behaviors.push_back(behinfo);
+						_behaviors.push_back(BehaviorInfo());
+						BehaviorInfo &behinfo = _behaviors.back();
+						behinfo.initObjectBehavior(subvar, sc, ani);
+						behinfo._ani = sc->_staticANIObjectList1[i];
 					}
 				}
 			}
@@ -92,35 +81,37 @@ void BehaviorManager::updateBehaviors() {
 
 	debugC(6, kDebugBehavior, "BehaviorManager::updateBehaviors()");
 	for (uint i = 0; i < _behaviors.size(); i++) {
-		BehaviorInfo *beh = _behaviors[i];
+		BehaviorInfo &beh = _behaviors[i];
 
-		if (!beh->_ani) {
-			beh->_counter++;
-			if (beh->_counter >= beh->_counterMax)
-				updateBehavior(beh, beh->_behaviorAnims[0]);
+		if (!beh._ani) {
+			beh._counter++;
+			if (beh._counter >= beh._counterMax)
+				updateBehavior(beh, beh._behaviorAnims[0]);
 
 			continue;
 		}
 
-		if (beh->_ani->_movement || !(beh->_ani->_flags & 4) || (beh->_ani->_flags & 2)) {
-			beh->_staticsId = 0;
+		if (beh._ani->_movement || !(beh._ani->_flags & 4) || (beh._ani->_flags & 2)) {
+			beh._staticsId = 0;
 			continue;
 		}
 
-		if (beh->_ani->_statics->_staticsId == beh->_staticsId) {
-			beh->_counter++;
-			if (beh->_counter >= beh->_counterMax) {
-				if (beh->_subIndex >= 0 && !(beh->_flags & 1) && beh->_ani->_messageQueueId <= 0)
-					updateStaticAniBehavior(beh->_ani, beh->_counter, beh->_behaviorAnims[beh->_subIndex]);
+		if (beh._ani->_statics->_staticsId == beh._staticsId) {
+			beh._counter++;
+			if (beh._counter >= beh._counterMax) {
+				if (beh._subIndex >= 0 && !(beh._flags & 1) && beh._ani->_messageQueueId <= 0) {
+					assert(beh._ani);
+					updateStaticAniBehavior(*beh._ani, beh._counter, beh._behaviorAnims[beh._subIndex]);
+				}
 			}
 		} else {
-			beh->_staticsId = beh->_ani->_statics->_staticsId;
-			beh->_counter = 0;
-			beh->_subIndex = -1;
+			beh._staticsId = beh._ani->_statics->_staticsId;
+			beh._counter = 0;
+			beh._subIndex = -1;
 
-			for (int j = 0; j < beh->_animsCount; j++)
-				if (beh->_behaviorAnims[j]->_staticsId == beh->_staticsId) {
-					beh->_subIndex = j;
+			for (int j = 0; j < beh._animsCount; j++)
+				if (beh._behaviorAnims[j]._staticsId == beh._staticsId) {
+					beh._subIndex = j;
 					break;
 				}
 
@@ -128,51 +119,51 @@ void BehaviorManager::updateBehaviors() {
 	}
 }
 
-void BehaviorManager::updateBehavior(BehaviorInfo *behaviorInfo, BehaviorAnim *entry) {
-	debugC(7, kDebugBehavior, "BehaviorManager::updateBehavior() moves: %d", entry->_movesCount);
-	for (int i = 0; i < entry->_movesCount; i++) {
-		BehaviorMove *bhi = entry->_behaviorMoves[i];
-		if (!(bhi->_flags & 1)) {
-			if (bhi->_flags & 2) {
-				MessageQueue *mq = new MessageQueue(bhi->_messageQueue, 0, 1);
+void BehaviorManager::updateBehavior(BehaviorInfo &behaviorInfo, BehaviorAnim &entry) {
+	debugC(7, kDebugBehavior, "BehaviorManager::updateBehavior() moves: %d", entry._behaviorMoves.size());
+	for (uint i = 0; i < entry._behaviorMoves.size(); i++) {
+		BehaviorMove &bhi = entry._behaviorMoves[i];
+		if (!(bhi._flags & 1)) {
+			if (bhi._flags & 2) {
+				MessageQueue *mq = new MessageQueue(bhi._messageQueue, 0, 1);
 
 				mq->sendNextCommand();
 
-				bhi->_flags &= 0xFFFFFFFD;
-			} else if (behaviorInfo->_counter >= bhi->_delay && bhi->_percent && g_fp->_rnd.getRandomNumber(32767) <= entry->_behaviorMoves[i]->_percent) {
-				MessageQueue *mq = new MessageQueue(bhi->_messageQueue, 0, 1);
+				bhi._flags &= 0xFFFFFFFD;
+			} else if (behaviorInfo._counter >= bhi._delay && bhi._percent && g_fp->_rnd.getRandomNumber(32767) <= entry._behaviorMoves[i]._percent) {
+				MessageQueue *mq = new MessageQueue(bhi._messageQueue, 0, 1);
 
 				mq->sendNextCommand();
 
-				behaviorInfo->_counter = 0;
+				behaviorInfo._counter = 0;
 			}
 		}
 	}
 }
 
-void BehaviorManager::updateStaticAniBehavior(StaticANIObject *ani, int delay, BehaviorAnim *bhe) {
-	debugC(6, kDebugBehavior, "BehaviorManager::updateStaticAniBehavior(%s)", transCyrillic(ani->_objectName));
+void BehaviorManager::updateStaticAniBehavior(StaticANIObject &ani, int delay, const BehaviorAnim &beh) {
+	debugC(6, kDebugBehavior, "BehaviorManager::updateStaticAniBehavior(%s)", transCyrillic(ani._objectName));
 
 	MessageQueue *mq = 0;
 
-	if (bhe->_flags & 1) {
+	if (beh._flags & 1) {
 		uint rnd = g_fp->_rnd.getRandomNumber(32767);
 		uint runPercent = 0;
-		for (int i = 0; i < bhe->_movesCount; i++) {
-			if (!(bhe->_behaviorMoves[i]->_flags & 1) && bhe->_behaviorMoves[i]->_percent) {
-				if ((rnd >= runPercent && rnd <= runPercent + bhe->_behaviorMoves[i]->_percent) || i == bhe->_movesCount - 1) {
-					mq = new MessageQueue(bhe->_behaviorMoves[i]->_messageQueue, 0, 1);
+		for (uint i = 0; i < beh._behaviorMoves.size(); i++) {
+			if (!(beh._behaviorMoves[i]._flags & 1) && beh._behaviorMoves[i]._percent) {
+				if ((rnd >= runPercent && rnd <= runPercent + beh._behaviorMoves[i]._percent) || i == beh._behaviorMoves.size() - 1) {
+					mq = new MessageQueue(beh._behaviorMoves[i]._messageQueue, 0, 1);
 					break;
 				}
-				runPercent += bhe->_behaviorMoves[i]->_percent;
+				runPercent += beh._behaviorMoves[i]._percent;
 			}
 		}
 	} else {
-		for (int i = 0; i < bhe->_movesCount; i++) {
-			if (!(bhe->_behaviorMoves[i]->_flags & 1) && delay >= bhe->_behaviorMoves[i]->_delay) {
-				if (bhe->_behaviorMoves[i]->_percent) {
-					if (g_fp->_rnd.getRandomNumber(32767) <= bhe->_behaviorMoves[i]->_percent) {
-						mq = new MessageQueue(bhe->_behaviorMoves[i]->_messageQueue, 0, 1);
+		for (uint i = 0; i < beh._behaviorMoves.size(); i++) {
+			if (!(beh._behaviorMoves[i]._flags & 1) && delay >= beh._behaviorMoves[i]._delay) {
+				if (beh._behaviorMoves[i]._percent) {
+					if (g_fp->_rnd.getRandomNumber(32767) <= beh._behaviorMoves[i]._percent) {
+						mq = new MessageQueue(beh._behaviorMoves[i]._messageQueue, 0, 1);
 						break;
 					}
 				}
@@ -181,8 +172,8 @@ void BehaviorManager::updateStaticAniBehavior(StaticANIObject *ani, int delay, B
 	}
 
 	if (mq) {
-		mq->setParamInt(-1, ani->_odelay);
-		mq->chain(ani);
+		mq->setParamInt(-1, ani._odelay);
+		mq->chain(&ani);
 	}
 }
 
@@ -202,25 +193,25 @@ bool BehaviorManager::setBehaviorEnabled(StaticANIObject *obj, int aniId, int qu
 
 void BehaviorManager::setFlagByStaticAniObject(StaticANIObject *ani, int flag) {
 	for (uint i = 0; i < _behaviors.size(); i++) {
-		BehaviorInfo *beh = _behaviors[i];
+		BehaviorInfo &beh = _behaviors[i];
 
-		if (ani == beh->_ani) {
+		if (ani == beh._ani) {
 			if (flag)
-				beh->_flags &= 0xfffffffe;
+				beh._flags &= 0xfffffffe;
 			else
-				beh->_flags |= 1;
+				beh._flags |= 1;
 		}
 	}
 }
 
 BehaviorMove *BehaviorManager::getBehaviorMoveByMessageQueueDataId(StaticANIObject *ani, int id1, int id2) {
 	for (uint i = 0; i < _behaviors.size(); i++) {
-		if (_behaviors[i]->_ani == ani) {
-			for (uint j = 0; j < _behaviors[i]->_behaviorAnims.size(); j++) {
-				if (_behaviors[i]->_behaviorAnims[j]->_staticsId == id1) {
-					for (int k = 0; k < _behaviors[i]->_behaviorAnims[j]->_movesCount; k++) {
-						if (_behaviors[i]->_behaviorAnims[j]->_behaviorMoves[k]->_messageQueue->_dataId == id2)
-							return _behaviors[i]->_behaviorAnims[j]->_behaviorMoves[k];
+		if (_behaviors[i]._ani == ani) {
+			for (uint j = 0; j < _behaviors[i]._behaviorAnims.size(); j++) {
+				if (_behaviors[i]._behaviorAnims[j]._staticsId == id1) {
+					for (uint k = 0; k < _behaviors[i]._behaviorAnims[j]._behaviorMoves.size(); k++) {
+						if (_behaviors[i]._behaviorAnims[j]._behaviorMoves[k]._messageQueue->_dataId == id2)
+							return &_behaviors[i]._behaviorAnims[j]._behaviorMoves[k];
 					}
 				}
 			}
@@ -231,14 +222,13 @@ BehaviorMove *BehaviorManager::getBehaviorMoveByMessageQueueDataId(StaticANIObje
 }
 
 void BehaviorInfo::clear() {
-	_ani = NULL;
+	_ani = nullptr;
 	_staticsId = 0;
 	_counter = 0;
 	_counterMax = 0;
 	_flags = 0;
 	_subIndex = 0;
 	_animsCount = 0;
-
 	_behaviorAnims.clear();
 }
 
@@ -249,20 +239,18 @@ void BehaviorInfo::initAmbientBehavior(GameVar *var, Scene *sc) {
 	_animsCount = 1;
 	_counterMax = -1;
 
-	BehaviorAnim *bi = new BehaviorAnim();
-
-	_behaviorAnims.push_back(bi);
+	_behaviorAnims.push_back(BehaviorAnim());
+	BehaviorAnim &bi = _behaviorAnims.back();
 
-	bi->_movesCount = var->getSubVarsCount();
-
-	bi->_behaviorMoves = (BehaviorMove **)calloc(bi->_movesCount, sizeof(BehaviorMove *));
-
-	for (int i = 0; i < bi->_movesCount; i++) {
+	int movesCount = var->getSubVarsCount();
+	bi._behaviorMoves.reserve(movesCount);
+	for (int i = 0; i < movesCount; i++) {
 		int delay;
-		bi->_behaviorMoves[i] = new BehaviorMove(var->getSubVarByIndex(i), sc, &delay);
+		bi._behaviorMoves.push_back(BehaviorMove(var->getSubVarByIndex(i), sc, &delay));
+		BehaviorMove &move = bi._behaviorMoves.back();
 
-		if (bi->_behaviorMoves[i]->_delay <_counterMax)
-			_counterMax = bi->_behaviorMoves[i]->_delay;
+		if (move._delay < _counterMax)
+			_counterMax = move._delay;
 	}
 }
 
@@ -293,7 +281,7 @@ void BehaviorInfo::initObjectBehavior(GameVar *var, Scene *sc, StaticANIObject *
 	for (int i = 0; i < _animsCount; i++) {
 		int maxDelay = 0;
 
-		_behaviorAnims.push_back(new BehaviorAnim(var->getSubVarByIndex(i), sc, ani, &maxDelay));
+		_behaviorAnims.push_back(BehaviorAnim(var->getSubVarByIndex(i), sc, ani, &maxDelay));
 
 		if (maxDelay < _counterMax)
 			_counterMax = maxDelay;
@@ -302,38 +290,34 @@ void BehaviorInfo::initObjectBehavior(GameVar *var, Scene *sc, StaticANIObject *
 
 BehaviorAnim::BehaviorAnim() {
 	_staticsId = 0;
-	_movesCount = 0;
 	_flags = 0;
-	_behaviorMoves = NULL;
 }
 
 BehaviorAnim::BehaviorAnim(GameVar *var, Scene *sc, StaticANIObject *ani, int *minDelay) {
 	_staticsId = 0;
-	_movesCount = 0;
 
 	*minDelay = 0xffffffff;
 
 	int totalPercent = 0;
 	_flags = 0;
-	_behaviorMoves = 0;
 
 	Statics *st = ani->getStaticsByName(var->_varName);
 	if (st)
 		_staticsId = st->_staticsId;
 
-	_movesCount = var->getSubVarsCount();
-	if (_movesCount) {
-		_behaviorMoves = (BehaviorMove **)calloc(_movesCount, sizeof(BehaviorMove *));
-
-		for (int i = 0; i < _movesCount; i++) {
+	int movesCount = var->getSubVarsCount();
+	if (movesCount) {
+		_behaviorMoves.reserve(movesCount);
+		for (int i = 0; i < movesCount; i++) {
 			GameVar *subvar = var->getSubVarByIndex(i);
 			int delay = 0;
 
-			_behaviorMoves[i] = new BehaviorMove(subvar, sc, &delay);
+			_behaviorMoves.push_back(BehaviorMove(subvar, sc, &delay));
+			BehaviorMove &move = _behaviorMoves.back();
 			totalPercent += delay;
 
-			if (_behaviorMoves[i]->_delay < *minDelay)
-				*minDelay = _behaviorMoves[i]->_delay;
+			if (move._delay < *minDelay)
+				*minDelay = move._delay;
 		}
 
 		if (!*minDelay && totalPercent == 1000)
diff --git a/engines/fullpipe/behavior.h b/engines/fullpipe/behavior.h
index e534371..b20a42c 100644
--- a/engines/fullpipe/behavior.h
+++ b/engines/fullpipe/behavior.h
@@ -36,9 +36,8 @@ struct BehaviorMove {
 
 struct BehaviorAnim {
 	int _staticsId;
-	int _movesCount;
 	int _flags;
-	BehaviorMove **_behaviorMoves;
+	Common::Array<BehaviorMove> _behaviorMoves;
 
 	BehaviorAnim();
 	BehaviorAnim(GameVar *var, Scene *sc, StaticANIObject *ani, int *minDelay);
@@ -52,7 +51,7 @@ struct BehaviorInfo {
 	int _flags;
 	int _subIndex;
 	int _animsCount;
-	Common::Array<BehaviorAnim *> _behaviorAnims;
+	Common::Array<BehaviorAnim> _behaviorAnims;
 
 	BehaviorInfo() { clear(); }
 
@@ -62,7 +61,7 @@ struct BehaviorInfo {
 };
 
 class BehaviorManager : public CObject {
-	Common::Array<BehaviorInfo *> _behaviors;
+	Common::Array<BehaviorInfo> _behaviors;
 	Scene *_scene;
 	bool _isActive;
 
@@ -75,8 +74,8 @@ class BehaviorManager : public CObject {
 	void initBehavior(Scene *scene, GameVar *var);
 
 	void updateBehaviors();
-	void updateBehavior(BehaviorInfo *behaviorInfo, BehaviorAnim *entry);
-	void updateStaticAniBehavior(StaticANIObject *ani, int delay, BehaviorAnim *beh);
+	void updateBehavior(BehaviorInfo &behaviorInfo, BehaviorAnim &entry);
+	void updateStaticAniBehavior(StaticANIObject &ani, int delay, const BehaviorAnim &beh);
 
 	bool setBehaviorEnabled(StaticANIObject *obj, int aniId, int quId, int flag);
 


Commit: 0e28f2be4776f2b581ce47865468bad20b84e547
    https://github.com/scummvm/scummvm/commit/0e28f2be4776f2b581ce47865468bad20b84e547
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Remove unused gap data from EntranceInfo

Changed paths:
    engines/fullpipe/interaction.cpp
    engines/fullpipe/interaction.h


diff --git a/engines/fullpipe/interaction.cpp b/engines/fullpipe/interaction.cpp
index 4e3a3a3..1d04aa0 100644
--- a/engines/fullpipe/interaction.cpp
+++ b/engines/fullpipe/interaction.cpp
@@ -543,7 +543,7 @@ bool EntranceInfo::load(MfcArchive &file) {
 	_sceneId = file.readUint32LE();
 	_field_4 = file.readUint32LE();
 	_messageQueueId = file.readUint32LE();
-	file.read(_gap_C, 292); // FIXME, Ugh
+	file.skip(292); // FIXME: Ugh
 	_field_130 = file.readUint32LE();
 
 	return true;
diff --git a/engines/fullpipe/interaction.h b/engines/fullpipe/interaction.h
index 89af8d7..97fb19b 100644
--- a/engines/fullpipe/interaction.h
+++ b/engines/fullpipe/interaction.h
@@ -90,7 +90,6 @@ struct EntranceInfo {
 	int32 _sceneId;
 	int32 _field_4;
 	int32 _messageQueueId;
-	byte _gap_C[292]; // FIXME
 	int32 _field_130;
 
 	bool load(MfcArchive &file);


Commit: 073692fd5250ae6fb2224f791821c5bd225ba5f0
    https://github.com/scummvm/scummvm/commit/073692fd5250ae6fb2224f791821c5bd225ba5f0
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Reduce chance of Scene leaks, remove unused SceneTag member

Changed paths:
    engines/fullpipe/gameloader.cpp
    engines/fullpipe/scene.cpp
    engines/fullpipe/scene.h
    engines/fullpipe/scenes/scene18and19.cpp


diff --git a/engines/fullpipe/gameloader.cpp b/engines/fullpipe/gameloader.cpp
index f2c078a..70cb937 100644
--- a/engines/fullpipe/gameloader.cpp
+++ b/engines/fullpipe/gameloader.cpp
@@ -420,7 +420,7 @@ bool GameLoader::unloadScene(int sceneId) {
 	_sc2array[sceneTag]._motionController->detachAllObjects();
 
 	delete tag->_scene;
-	tag->_scene = 0;
+	tag->_scene = nullptr;
 
 	_sc2array[sceneTag]._isLoaded = 0;
 	_sc2array[sceneTag]._scene = 0;
diff --git a/engines/fullpipe/scene.cpp b/engines/fullpipe/scene.cpp
index 751f992..76384c3 100644
--- a/engines/fullpipe/scene.cpp
+++ b/engines/fullpipe/scene.cpp
@@ -68,18 +68,17 @@ bool SceneTagList::load(MfcArchive &file) {
 	return true;
 }
 
-SceneTag::SceneTag() {
-	_field_4 = 0;
-	_scene = 0;
-	_sceneId = 0;
+SceneTag::SceneTag() :
+	_scene(nullptr),
+	_sceneId(0) {}
+
+SceneTag::~SceneTag() {
+	delete _scene;
 }
 
 bool SceneTag::load(MfcArchive &file) {
 	debugC(5, kDebugLoading, "SceneTag::load()");
 
-	_field_4 = 0;
-	_scene = 0;
-
 	_sceneId = file.readUint16LE();
 
 	_tag = file.readPascalString();
@@ -89,11 +88,6 @@ bool SceneTag::load(MfcArchive &file) {
 	return true;
 }
 
-SceneTag::~SceneTag() {
-	delete _scene;
-	delete _field_4;
-}
-
 void SceneTag::loadScene() {
 	Common::String archname = genFileName(0, _sceneId, "nl");
 
@@ -101,20 +95,19 @@ void SceneTag::loadScene() {
 
 	Common::String fname = genFileName(0, _sceneId, "sc");
 
-	Common::SeekableReadStream *file = arch->createReadStreamForMember(fname);
+	Common::ScopedPtr<Common::SeekableReadStream> file(arch->createReadStreamForMember(fname));
 
+	delete _scene;
 	_scene = new Scene();
 
-	MfcArchive archive(file);
+	MfcArchive archive(file.get());
 
 	_scene->load(archive);
 
 	if (_scene->_shadows)
 		_scene->_shadows->init();
 
-	delete file;
-
-	g_fp->_currArchive = 0;
+	g_fp->_currArchive = nullptr;
 }
 
 Scene::Scene() : _sceneId(0), _field_BC(0) {}
diff --git a/engines/fullpipe/scene.h b/engines/fullpipe/scene.h
index dd559a3..cc4cf17 100644
--- a/engines/fullpipe/scene.h
+++ b/engines/fullpipe/scene.h
@@ -65,6 +65,7 @@ class Scene : public Background {
 	MessageQueue *getMessageQueueByName(const Common::String &name);
 
 	void deleteStaticANIObject(StaticANIObject *obj);
+	/** takes ownership of the passed obj */
 	void addStaticANIObject(StaticANIObject *obj, bool addList2);
 
 	void setPictureObjectsFlag4();
@@ -94,14 +95,14 @@ class Scene : public Background {
 
 class SceneTag : public CObject {
  public:
-	CObject *_field_4;
 	Common::String _tag;
+	/** owned, but cannot use ScopedPtr because this object must be copyable */
 	Scene *_scene;
 	int16 _sceneId;
 
  public:
 	SceneTag();
-	~SceneTag();
+	virtual ~SceneTag();
 
 	virtual bool load(MfcArchive &file);
 	void loadScene();
diff --git a/engines/fullpipe/scenes/scene18and19.cpp b/engines/fullpipe/scenes/scene18and19.cpp
index 7e26632..9181bc7 100644
--- a/engines/fullpipe/scenes/scene18and19.cpp
+++ b/engines/fullpipe/scenes/scene18and19.cpp
@@ -130,6 +130,7 @@ void scene19_setMovements(Scene *sc, int entranceId) {
 void scene19_preload() {
 	for (SceneTagList::iterator s = g_fp->_gameProject->_sceneTagList->begin(); s != g_fp->_gameProject->_sceneTagList->end(); ++s) {
 		if (s->_sceneId == SC_18) {
+			delete s->_scene;
 			s->_scene = g_fp->_scene3;
 
 			break;


Commit: 39ea2f66ac635613c3a817c16f80b11ac207d320
    https://github.com/scummvm/scummvm/commit/39ea2f66ac635613c3a817c16f80b11ac207d320
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix deleted queue leaks & clarify flags

Changed paths:
    engines/fullpipe/messages.cpp
    engines/fullpipe/messages.h


diff --git a/engines/fullpipe/messages.cpp b/engines/fullpipe/messages.cpp
index 111c70c..22a1fe7 100644
--- a/engines/fullpipe/messages.cpp
+++ b/engines/fullpipe/messages.cpp
@@ -362,17 +362,16 @@ bool MessageQueue::load(MfcArchive &file) {
 
 bool MessageQueue::chain(StaticANIObject *ani) {
 	if (checkGlobalExCommandList1() && checkGlobalExCommandList2()) {
-		if (!(getFlags() & 2)) {
+		if (!(getFlags() & kInGlobalQueue)) {
 			g_fp->_globalMessageQueueList->addMessageQueue(this);
-			_flags |= 2;
+			_flags |= kInGlobalQueue;
 		}
 		if (ani) {
 			ani->queueMessageQueue(this);
-			return true;
 		} else {
 			sendNextCommand();
-			return true;
 		}
+		return true;
 	}
 	return false;
 }
@@ -653,8 +652,7 @@ MessageQueue *GlobalMessageQueueList::getMessageQueueById(int id) {
 void GlobalMessageQueueList::deleteQueueById(int id) {
 	for (uint i = 0; i < size(); i++)
 		if (_storage[i]->_id == id) {
-			remove_at(i);
-
+			delete remove_at(i);
 			disableQueueById(id);
 			return;
 		}
@@ -663,7 +661,7 @@ void GlobalMessageQueueList::deleteQueueById(int id) {
 void GlobalMessageQueueList::removeQueueById(int id) {
 	for (uint i = 0; i < size(); i++)
 		if (_storage[i]->_id == id) {
-			_storage[i]->_flags &= 0xFD; // It is quite pointless
+			_storage[i]->_flags &= ~kInGlobalQueue;
 			remove_at(i);
 
 			disableQueueById(id);
@@ -708,7 +706,7 @@ int GlobalMessageQueueList::compact() {
 }
 
 void GlobalMessageQueueList::addMessageQueue(MessageQueue *msg) {
-	msg->setFlags(msg->getFlags() | 2);
+	msg->setFlags(msg->getFlags() | kInGlobalQueue);
 
 	push_back(msg);
 }
diff --git a/engines/fullpipe/messages.h b/engines/fullpipe/messages.h
index 0bdfb23..65c5e9b 100644
--- a/engines/fullpipe/messages.h
+++ b/engines/fullpipe/messages.h
@@ -31,6 +31,10 @@
 
 namespace Fullpipe {
 
+enum QueueFlags {
+	kInGlobalQueue = 2
+};
+
 class Message : public CObject {
  public:
 	int _messageKind;
@@ -146,6 +150,7 @@ class MessageQueue : public CObject {
 
 	void setParamInt(int key1, int key2);
 
+	/** `ani` will own `this` if `chain` returns true */
 	bool chain(StaticANIObject *ani);
 	void update();
 	void sendNextCommand();
@@ -168,6 +173,7 @@ class GlobalMessageQueueList : public Common::Array<MessageQueue *> {
 	void deleteQueueById(int id);
 	void removeQueueById(int id);
 	void disableQueueById(int id);
+	/** `msg` becomes owned by `this` */
 	void addMessageQueue(MessageQueue *msg);
 
 	int compact();


Commit: e2367f3ed2060b273559200b3e40f75a98bb6a6f
    https://github.com/scummvm/scummvm/commit/e2367f3ed2060b273559200b3e40f75a98bb6a6f
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Remove unnecessary and unsafe C-style casts

Changed paths:
    engines/fullpipe/behavior.cpp
    engines/fullpipe/gameloader.cpp
    engines/fullpipe/gameloader.h
    engines/fullpipe/gfx.cpp
    engines/fullpipe/input.cpp
    engines/fullpipe/interaction.cpp
    engines/fullpipe/interaction.h
    engines/fullpipe/inventory.cpp
    engines/fullpipe/lift.cpp
    engines/fullpipe/messagehandlers.cpp
    engines/fullpipe/messages.cpp
    engines/fullpipe/modal.cpp
    engines/fullpipe/motion.cpp
    engines/fullpipe/motion.h
    engines/fullpipe/scene.cpp
    engines/fullpipe/scenes/scene03.cpp
    engines/fullpipe/scenes/scene04.cpp
    engines/fullpipe/scenes/scene06.cpp
    engines/fullpipe/scenes/scene11.cpp
    engines/fullpipe/scenes/scene33.cpp
    engines/fullpipe/scenes/sceneDbg.cpp
    engines/fullpipe/stateloader.cpp
    engines/fullpipe/statics.cpp
    engines/fullpipe/utils.cpp
    engines/fullpipe/utils.h


diff --git a/engines/fullpipe/behavior.cpp b/engines/fullpipe/behavior.cpp
index a1e01b2..2c0cba8 100644
--- a/engines/fullpipe/behavior.cpp
+++ b/engines/fullpipe/behavior.cpp
@@ -63,7 +63,7 @@ void BehaviorManager::initBehavior(Scene *sc, GameVar *var) {
 			StaticANIObject *ani = sc->getStaticANIObject1ByName(subvar->_varName, -1);
 			if (ani) {
 				for (uint i = 0; i < sc->_staticANIObjectList1.size(); i++) {
-					if (((StaticANIObject *)sc->_staticANIObjectList1[i])->_id == ani->_id) {
+					if (sc->_staticANIObjectList1[i]->_id == ani->_id) {
 						_behaviors.push_back(BehaviorInfo());
 						BehaviorInfo &behinfo = _behaviors.back();
 						behinfo.initObjectBehavior(subvar, sc, ani);
diff --git a/engines/fullpipe/gameloader.cpp b/engines/fullpipe/gameloader.cpp
index 70cb937..ce98d7c 100644
--- a/engines/fullpipe/gameloader.cpp
+++ b/engines/fullpipe/gameloader.cpp
@@ -38,12 +38,32 @@ Inventory2 *getGameLoaderInventory() {
 	return &g_fp->_gameLoader->_inventory;
 }
 
-MctlCompound *getSc2MctlCompoundBySceneId(int16 sceneId) {
-	for (uint i = 0; i < g_fp->_gameLoader->_sc2array.size(); i++)
-		if (g_fp->_gameLoader->_sc2array[i]._sceneId == sceneId)
-			return (MctlCompound *)g_fp->_gameLoader->_sc2array[i]._motionController;
+static MotionController *getMotionControllerBySceneId(int16 sceneId) {
+	for (uint i = 0; i < g_fp->_gameLoader->_sc2array.size(); i++) {
+		if (g_fp->_gameLoader->_sc2array[i]._sceneId == sceneId) {
+			return g_fp->_gameLoader->_sc2array[i]._motionController;
+		}
+	}
+
+	return nullptr;
+}
 
-	return 0;
+MovGraph *getSc2MovGraphBySceneId(int16 sceneId) {
+	MotionController *mc = getMotionControllerBySceneId(sceneId);
+	if (mc) {
+		assert(mc->_objtype == kObjTypeMovGraph);
+		return static_cast<MovGraph *>(mc);
+	}
+	return nullptr;
+}
+
+MctlCompound *getSc2MctlCompoundBySceneId(int16 sceneId) {
+	MotionController *mc = getMotionControllerBySceneId(sceneId);
+	if (mc) {
+		assert(mc->_objtype == kObjTypeMctlCompound);
+		return static_cast<MctlCompound *>(mc);
+	}
+	return nullptr;
 }
 
 InteractionController *getGameLoaderInteractionController() {
@@ -136,7 +156,7 @@ bool GameLoader::load(MfcArchive &file) {
 
 		debugC(1, kDebugLoading, "sc: %s", tmp);
 
-		_sc2array[i].loadFile((const char *)tmp);
+		_sc2array[i].loadFile(tmp);
 	}
 
 	_preloadItems.load(file);
@@ -146,7 +166,7 @@ bool GameLoader::load(MfcArchive &file) {
 
 	debugC(1, kDebugLoading, "_field_FA: %d\n_field_F8: %d", _field_FA, _field_F8);
 
-	_gameVar = (GameVar *)file.readClass();
+	_gameVar = file.readClass<GameVar>();
 
 	return true;
 }
@@ -615,7 +635,7 @@ bool Sc2::load(MfcArchive &file) {
 
 	_sceneId = file.readUint16LE();
 
-	_motionController = (MotionController *)file.readClass();
+	_motionController = file.readClass<MotionController>();
 
 	_count1 = file.readUint32LE();
 	debugC(4, kDebugLoading, "count1: %d", _count1);
diff --git a/engines/fullpipe/gameloader.h b/engines/fullpipe/gameloader.h
index 39ccb77..10c0912 100644
--- a/engines/fullpipe/gameloader.h
+++ b/engines/fullpipe/gameloader.h
@@ -39,6 +39,7 @@ class MctlCompound;
 class InputController;
 class InteractionController;
 class MotionController;
+class MovGraph;
 
 class Sc2 : public CObject {
  public:
@@ -148,6 +149,7 @@ void parseSavegameHeader(Fullpipe::FullpipeSavegameHeader &header, SaveStateDesc
 Inventory2 *getGameLoaderInventory();
 InteractionController *getGameLoaderInteractionController();
 MctlCompound *getSc2MctlCompoundBySceneId(int16 sceneId);
+MovGraph *getSc2MovGraphBySceneId(int16 sceneId);
 MctlCompound *getCurrSceneSc2MotionController();
 
 } // End of namespace Fullpipe
diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp
index da626c7..b12edcb 100644
--- a/engines/fullpipe/gfx.cpp
+++ b/engines/fullpipe/gfx.cpp
@@ -300,8 +300,8 @@ void GameObject::renumPictures(Common::Array<StaticANIObject *> *lst) {
 	int *buf = (int *)calloc(lst->size() + 2, sizeof(int));
 
 	for (uint i = 0; i < lst->size(); i++) {
-		if (_id == ((GameObject *)((*lst)[i]))->_id)
-			buf[((GameObject *)((*lst)[i]))->_odelay] = 1;
+		if (_id == (*lst)[i]->_id)
+			buf[(*lst)[i]->_odelay] = 1;
 	}
 
 	if (buf[_odelay]) {
@@ -318,8 +318,8 @@ void GameObject::renumPictures(Common::Array<PictureObject *> *lst) {
 	int *buf = (int *)calloc(lst->size() + 2, sizeof(int));
 
 	for (uint i = 0; i < lst->size(); i++) {
-		if (_id == ((GameObject *)((*lst)[i]))->_id)
-			buf[((GameObject *)((*lst)[i]))->_odelay] = 1;
+		if (_id == (*lst)[i]->_id)
+			buf[(*lst)[i]->_odelay] = 1;
 	}
 
 	if (buf[_odelay]) {
@@ -348,7 +348,7 @@ bool GameObject::getPicAniInfo(PicAniInfo *info) {
 	}
 
 	if (_objtype == kObjTypeStaticANIObject) {
-		StaticANIObject *ani = (StaticANIObject *)this;
+		StaticANIObject *ani = static_cast<StaticANIObject *>(this);
 
 		info->type = (ani->_messageQueueId << 16) | 1;
 		info->objectId = ani->_id;
@@ -398,8 +398,8 @@ bool GameObject::setPicAniInfo(PicAniInfo *picAniInfo) {
 		return true;
 	}
 
-	if (picAniInfo->type & 1) {
-		StaticANIObject *ani = (StaticANIObject *)this;
+	if (picAniInfo->type & 1 && _objtype == kObjTypeStaticANIObject) {
+		StaticANIObject *ani = static_cast<StaticANIObject *>(this);
 
 		ani->_messageQueueId = (picAniInfo->type >> 16) & 0xffff;
 		ani->_odelay = picAniInfo->field_8;
diff --git a/engines/fullpipe/input.cpp b/engines/fullpipe/input.cpp
index 499b985..6bd992a 100644
--- a/engines/fullpipe/input.cpp
+++ b/engines/fullpipe/input.cpp
@@ -215,7 +215,7 @@ void FullpipeEngine::winArcade() {
 void FullpipeEngine::updateCursorCommon() {
 	GameObject *ani = _currentScene->getStaticANIObjectAtPos(_mouseVirtX, _mouseVirtY);
 
-	GameObject *pic = _currentScene->getPictureObjectAtPos(_mouseVirtX, _mouseVirtY);
+	PictureObject *pic = _currentScene->getPictureObjectAtPos(_mouseVirtX, _mouseVirtY);
 	if (!ani || (pic && pic->_priority < ani->_priority))
 		ani = pic;
 
@@ -241,7 +241,7 @@ void FullpipeEngine::updateCursorCommon() {
 			_cursorId = PIC_CSR_DEFAULT_INV;
 			return;
 		}
-		if (_objectIdAtCursor == ANI_LIFTBUTTON && lift_getButtonIdP(((StaticANIObject *)ani)->_statics->_staticsId)) {
+		if (_objectIdAtCursor == ANI_LIFTBUTTON && ani->_objtype == kObjTypeStaticANIObject && lift_getButtonIdP(static_cast<StaticANIObject *>(ani)->_statics->_staticsId)) {
 			_cursorId = PIC_CSR_LIFT;
 			return;
 		}
diff --git a/engines/fullpipe/interaction.cpp b/engines/fullpipe/interaction.cpp
index 1d04aa0..b15ae80 100644
--- a/engines/fullpipe/interaction.cpp
+++ b/engines/fullpipe/interaction.cpp
@@ -40,8 +40,8 @@ bool canInteractAny(GameObject *obj1, GameObject *obj2, int invId) {
 		sceneId = g_fp->_currentScene->_sceneId;
 
 	InteractionController *intC = getGameLoaderInteractionController();
-	for (ObList::iterator i = intC->_interactions.begin(); i != intC->_interactions.end(); ++i) {
-		Interaction *intr = (Interaction *)*i;
+	for (InteractionController::InteractionList::iterator i = intC->_interactions.begin(); i != intC->_interactions.end(); ++i) {
+		Interaction *intr = *i;
 
 		if (intr->_sceneId > 0 && intr->_sceneId != sceneId)
 			break;
@@ -69,10 +69,7 @@ bool InteractionController::load(MfcArchive &file) {
 
 int static_compSceneId = 0;
 
-bool InteractionController::compareInteractions(const void *p1, const void *p2) {
-	const Interaction *i1 = (const Interaction *)p1;
-	const Interaction *i2 = (const Interaction *)p2;
-
+bool InteractionController::compareInteractions(const Interaction *i1, const Interaction *i2) {
 	if (i2->_sceneId < i1->_sceneId) {
 		if (i1->_sceneId != static_compSceneId)
 			return false;
@@ -118,8 +115,8 @@ bool InteractionController::handleInteraction(StaticANIObject *subj, GameObject
 	MessageQueue *mq;
 	ExCommand *ex;
 
-	for (ObList::iterator i = _interactions.begin(); i != _interactions.end(); ++i) {
-		Interaction *cinter = (Interaction *)*i;
+	for (InteractionList::iterator i = _interactions.begin(); i != _interactions.end(); ++i) {
+		Interaction *cinter = *i;
 
 		if (!cinter->canInteract(subj, obj, invId))
 			continue;
@@ -134,8 +131,8 @@ bool InteractionController::handleInteraction(StaticANIObject *subj, GameObject
 
 			obj->getPicAniInfo(&aniInfo);
 
-			if (cinter->_staticsId1) {
-				StaticANIObject *ani = (StaticANIObject *)obj;
+			if (cinter->_staticsId1 && obj->_objtype == kObjTypeStaticANIObject) {
+				StaticANIObject *ani = static_cast<StaticANIObject *>(obj);
 				ani->_messageQueueId = 0;
 				ani->changeStatics2(cinter->_staticsId1);
 			}
@@ -241,7 +238,7 @@ LABEL_38:
 
 	if (inter->isOverlapping(subj, obj)) {
 		if (obj->_objtype == kObjTypeStaticANIObject) {
-			StaticANIObject *ani = (StaticANIObject *)obj;
+			StaticANIObject *ani = static_cast<StaticANIObject *>(obj);
 
 			ani->queueMessageQueue(0);
 
@@ -304,7 +301,7 @@ LABEL_38:
 		obj->getPicAniInfo(&aniInfo);
 
 		if (obj->_objtype == kObjTypeStaticANIObject && inter->_staticsId1) {
-			StaticANIObject *ani = (StaticANIObject *)obj;
+			StaticANIObject *ani = static_cast<StaticANIObject *>(obj);
 
 			ani->_messageQueueId = 0;
 			ani->changeStatics2(inter->_staticsId1);
@@ -346,7 +343,10 @@ LABEL_38:
 		if (!inter->_staticsId1 || !(inter->_flags & 1))
 			return true;
 
-		StaticANIObject *ani = (StaticANIObject *)obj;
+		if (obj->_objtype != kObjTypeStaticANIObject)
+			return false;
+
+		StaticANIObject *ani = static_cast<StaticANIObject *>(obj);
 
 		if (!ani->isIdle())
 			return false;
@@ -407,8 +407,8 @@ LABEL_38:
 }
 
 Interaction *InteractionController::getInteractionByObjectIds(int obId, int obId2, int obId3) {
-	for (ObList::iterator i = _interactions.begin(); i != _interactions.end(); ++i) {
-		Interaction *intr = (Interaction *)*i;
+	for (InteractionList::iterator i = _interactions.begin(); i != _interactions.end(); ++i) {
+		Interaction *intr = *i;
 
 		if (intr->_objectId1 == obId && intr->_objectId2 == obId2 && intr->_objectId3 == obId3)
 			return intr;
@@ -458,7 +458,7 @@ bool Interaction::load(MfcArchive &file) {
 	_flags = file.readUint32LE();
 	_actionName = file.readPascalString();
 
-	_messageQueue = (MessageQueue *)file.readClass();
+	_messageQueue = file.readClass<MessageQueue>();
 
 	return true;
 }
@@ -480,7 +480,7 @@ bool Interaction::canInteract(GameObject *obj1, GameObject *obj2, int invId) {
 		if (obj2->_objtype != kObjTypeStaticANIObject)
 			return false;
 
-		StaticANIObject *st = (StaticANIObject *)obj2;
+		StaticANIObject *st = static_cast<StaticANIObject *>(obj2);
 
 		if (!st->_statics)
 			return false;
diff --git a/engines/fullpipe/interaction.h b/engines/fullpipe/interaction.h
index 97fb19b..9ffcdcc 100644
--- a/engines/fullpipe/interaction.h
+++ b/engines/fullpipe/interaction.h
@@ -62,13 +62,16 @@ class Interaction : public CObject {
 };
 
 class InteractionController : public CObject {
- public:
-	ObList _interactions;
-	int16 _field_20;
+	friend bool canInteractAny(GameObject *obj1, GameObject *obj2, int invId);
+
+public:
+	typedef ObList<Interaction> InteractionList;
 	bool _flag24;
 
  private:
-	static bool compareInteractions(const void *p1, const void *p2);
+	InteractionList _interactions;
+	int16 _field_20;
+	static bool compareInteractions(const Interaction *i1, const Interaction *i2);
 
  public:
 	InteractionController() : _field_20(0), _flag24(true) {}
diff --git a/engines/fullpipe/inventory.cpp b/engines/fullpipe/inventory.cpp
index 5ddf26d..cb9eec7 100644
--- a/engines/fullpipe/inventory.cpp
+++ b/engines/fullpipe/inventory.cpp
@@ -238,7 +238,7 @@ void Inventory2::rebuildItemRects() {
 	int itemY = 0;
 
 	for (uint i = 0; i < _scene->_picObjList.size(); i++) {
-		PictureObject *pic = (PictureObject *)_scene->_picObjList[i];
+		PictureObject *pic = _scene->_picObjList[i];
 
 		for (uint j = 0; j < _itemsPool.size(); j++) {
 			if (_itemsPool[j]->pictureObjectNormal == pic->_id) {
diff --git a/engines/fullpipe/lift.cpp b/engines/fullpipe/lift.cpp
index 113ddf7..1bbe5a7 100644
--- a/engines/fullpipe/lift.cpp
+++ b/engines/fullpipe/lift.cpp
@@ -195,7 +195,7 @@ void FullpipeEngine::lift_init(Scene *sc, int enterSeq, int exitSeq) {
 	_lift = sc->getStaticANIObject1ById(ANI_LIFT, -1);
 
 	for (uint i = 0; i < sc->_staticANIObjectList1.size(); i++) {
-		StaticANIObject *ani = (StaticANIObject *)sc->_staticANIObjectList1[i];
+		StaticANIObject *ani = sc->_staticANIObjectList1[i];
 
 		if (ani->_id == ANI_LIFTBUTTON)
 			ani->_statics = ani->getStaticsById(lift_getButtonIdP(ani->_statics->_staticsId));
@@ -205,7 +205,7 @@ void FullpipeEngine::lift_init(Scene *sc, int enterSeq, int exitSeq) {
 	if (var) {
 		for (var = var->_subVars; var; var = var->_nextVarObj) {
 			for (uint i = 0; i < sc->_staticANIObjectList1.size(); i++) {
-				StaticANIObject *ani = (StaticANIObject *)sc->_staticANIObjectList1[i];
+				StaticANIObject *ani = sc->_staticANIObjectList1[i];
 
 				if (ani->_id == ANI_LIFTBUTTON) {
 					int id = lift_getButtonIdN(ani->_statics->_staticsId);
@@ -506,7 +506,7 @@ bool FullpipeEngine::lift_checkButton(const char *varName) {
 
 void FullpipeEngine::lift_setButtonStatics(Scene *sc, int buttonId) {
 	for (uint i = 0; i < sc->_staticANIObjectList1.size(); i++) {
-		StaticANIObject *ani = (StaticANIObject *)sc->_staticANIObjectList1[i];
+		StaticANIObject *ani = sc->_staticANIObjectList1[i];
 
 		if (ani->_id == ANI_LIFTBUTTON) {
 			int id = lift_getButtonIdN(ani->_statics->_staticsId);
diff --git a/engines/fullpipe/messagehandlers.cpp b/engines/fullpipe/messagehandlers.cpp
index 61b3429..d5f0e0d 100644
--- a/engines/fullpipe/messagehandlers.cpp
+++ b/engines/fullpipe/messagehandlers.cpp
@@ -517,7 +517,7 @@ int global_messageHandler3(ExCommand *cmd) {
 		return doSomeAnimation2(cmd->_parentId, cmd->_param);
 	case 63:
 		if (cmd->_objtype == kObjTypeObjstateCommand) {
-			ObjstateCommand *c = (ObjstateCommand *)cmd;
+			ObjstateCommand *c = static_cast<ObjstateCommand *>(cmd);
 			result = 1;
 			g_fp->setObjectState(c->_objCommandName.c_str(), c->_value);
 		}
@@ -595,12 +595,14 @@ int global_messageHandler4(ExCommand *cmd) {
 		if (flags <= 0)
 			flags = -1;
 
-		ExCommand2 *cmd2 = (ExCommand2 *)cmd;
+		if (cmd->_objtype == kObjTypeExCommand2) {
+			ExCommand2 *cmd2 = static_cast<ExCommand2 *>(cmd);
 
-		if (cmd->_excFlags & 1) {
-			ani->startAnimSteps(cmd->_messageNum, 0, cmd->_x, cmd->_y, cmd2->_points, cmd2->_pointsSize, flags);
-		} else {
-			ani->startAnimSteps(cmd->_messageNum, cmd->_parId, cmd->_x, cmd->_y, cmd2->_points, cmd2->_pointsSize, flags);
+			if (cmd->_excFlags & 1) {
+				ani->startAnimSteps(cmd->_messageNum, 0, cmd->_x, cmd->_y, cmd2->_points, cmd2->_pointsSize, flags);
+			} else {
+				ani->startAnimSteps(cmd->_messageNum, cmd->_parId, cmd->_x, cmd->_y, cmd2->_points, cmd2->_pointsSize, flags);
+			}
 		}
 		break;
 	}
@@ -769,20 +771,20 @@ int MovGraph::messageHandler(ExCommand *cmd) {
 	if (getSc2MctlCompoundBySceneId(g_fp->_currentScene->_sceneId)->_objtype != kObjTypeMovGraph || !ani)
 		return 0;
 
-	MovGraph *gr = (MovGraph *)getSc2MctlCompoundBySceneId(g_fp->_currentScene->_sceneId);
+	MovGraph *gr = getSc2MovGraphBySceneId(g_fp->_currentScene->_sceneId);
 
 	MovGraphLink *link = 0;
 	double mindistance = 1.0e10;
 	Common::Point point;
 
-	for (ObList::iterator i = gr->_links.begin(); i != gr->_links.end(); ++i) {
+	for (LinkList::iterator i = gr->_links.begin(); i != gr->_links.end(); ++i) {
 		point.x = ani->_ox;
 		point.y = ani->_oy;
 
-		double dst = gr->putToLink(&point, (MovGraphLink *)(*i), 0);
+		double dst = gr->putToLink(&point, *i, 0);
 		if (dst >= 0.0 && dst < mindistance) {
 			mindistance = dst;
-			link = (MovGraphLink *)(*i);
+			link = *i;
 		}
 	}
 
diff --git a/engines/fullpipe/messages.cpp b/engines/fullpipe/messages.cpp
index 22a1fe7..e332728 100644
--- a/engines/fullpipe/messages.cpp
+++ b/engines/fullpipe/messages.cpp
@@ -317,7 +317,7 @@ MessageQueue::MessageQueue(MessageQueue *src, int parId, int field_38) {
 
 MessageQueue::~MessageQueue() {
 	for (Common::List<ExCommand *>::iterator it = _exCommands.begin(); it != _exCommands.end(); ++it) {
-		ExCommand *ex = (ExCommand *)*it;
+		ExCommand *ex = *it;
 
 		if (ex && ex->_excFlags & 2)
 			delete ex;
@@ -347,8 +347,7 @@ bool MessageQueue::load(MfcArchive &file) {
 	_queueName = file.readPascalString();
 
 	for (int i = 0; i < count; i++) {
-		ExCommand *tmp = (ExCommand *)file.readClass();
-
+		ExCommand *tmp = file.readClass<ExCommand>();
 		_exCommands.push_back(tmp);
 	}
 
diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp
index 1c98f5e..ef35467 100644
--- a/engines/fullpipe/modal.cpp
+++ b/engines/fullpipe/modal.cpp
@@ -2340,7 +2340,7 @@ bool ModalDemo::launch() {
 		_scene = sc;
 
 		for (uint i = 1; i < sc->_picObjList.size(); i++) {
-			if (((PictureObject *)sc->_picObjList[i])->_id == 399)
+			if (sc->_picObjList[i]->_id == 399)
 				sc->_picObjList[i]->_flags |= 4;
 			else
 				sc->_picObjList[i]->_flags &= 0xFFFB;
diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp
index cfe9ecb..5a106ed 100644
--- a/engines/fullpipe/motion.cpp
+++ b/engines/fullpipe/motion.cpp
@@ -49,10 +49,10 @@ void MotionController::enableLinks(const char *linkName, bool enable) {
 		if (con->_objtype == kObjTypeMovGraph) {
 			MovGraph *gr = static_cast<MovGraph *>(con);
 
-			for (ObList::iterator l = gr->_links.begin(); l != gr->_links.end(); ++l) {
-				assert(((CObject *)*l)->_objtype == kObjTypeMovGraphLink);
+			for (MovGraph::LinkList::iterator l = gr->_links.begin(); l != gr->_links.end(); ++l) {
+				assert((*l)->_objtype == kObjTypeMovGraphLink);
 
-				MovGraphLink *lnk = (MovGraphLink *)*l;
+				MovGraphLink *lnk = static_cast<MovGraphLink *>(*l);
 
 				if (lnk->_name == linkName) {
 					if (enable)
@@ -69,18 +69,18 @@ MovGraphLink *MotionController::getLinkByName(const char *name) {
 	debugC(4, kDebugPathfinding, "MotionController::getLinkByName(%s)", name);
 
 	if (_objtype == kObjTypeMctlCompound) {
-		MctlCompound *obj = (MctlCompound *)this;
+		MctlCompound *obj = static_cast<MctlCompound *>(this);
 
 		for (uint i = 0;  i < obj->getMotionControllerCount(); i++) {
 			MotionController *con = obj->getMotionController(i);
 
 			if (con->_objtype == kObjTypeMovGraph) {
-				MovGraph *gr = (MovGraph *)con;
+				MovGraph *gr = static_cast<MovGraph *>(con);
 
-				for (ObList::iterator l = gr->_links.begin(); l != gr->_links.end(); ++l) {
-					assert(((CObject *)*l)->_objtype == kObjTypeMovGraphLink);
+				for (MovGraph::LinkList::iterator l = gr->_links.begin(); l != gr->_links.end(); ++l) {
+					assert((*l)->_objtype == kObjTypeMovGraphLink);
 
-					MovGraphLink *lnk = (MovGraphLink *)*l;
+					MovGraphLink *lnk = static_cast<MovGraphLink *>(*l);
 
 					if (lnk->_name == name)
 						return lnk;
@@ -90,12 +90,12 @@ MovGraphLink *MotionController::getLinkByName(const char *name) {
 	}
 
 	if (_objtype == kObjTypeMovGraph) {
-		MovGraph *gr = (MovGraph *)this;
+		MovGraph *gr = static_cast<MovGraph *>(this);
 
-		for (ObList::iterator l = gr->_links.begin(); l != gr->_links.end(); ++l) {
-			assert(((CObject *)*l)->_objtype == kObjTypeMovGraphLink);
+		for (MovGraph::LinkList::iterator l = gr->_links.begin(); l != gr->_links.end(); ++l) {
+			assert((*l)->_objtype == kObjTypeMovGraphLink);
 
-			MovGraphLink *lnk = (MovGraphLink *)*l;
+			MovGraphLink *lnk = static_cast<MovGraphLink *>(*l);
 
 			if (lnk->_name == name)
 				return lnk;
@@ -116,14 +116,14 @@ bool MctlCompound::load(MfcArchive &file) {
 		debugC(6, kDebugLoading, "CompoundArray[%d]", i);
 		MctlItem *obj = new MctlItem();
 
-		obj->_motionControllerObj = (MotionController *)file.readClass();
+		obj->_motionControllerObj = file.readClass<MotionController>();
 
 		int count1 = file.readUint32LE();
 
 		debugC(6, kDebugLoading, "ConnectionPoint::count: %d", count1);
 		for (int j = 0; j < count1; j++) {
 			debugC(6, kDebugLoading, "ConnectionPoint[%d]", j);
-			MctlConnectionPoint *obj1 = (MctlConnectionPoint *)file.readClass();
+			MctlConnectionPoint *obj1 = file.readClass<MctlConnectionPoint>();
 
 			obj->_connectionPoints.push_back(obj1);
 		}
@@ -132,7 +132,7 @@ bool MctlCompound::load(MfcArchive &file) {
 		obj->_field_24 = file.readUint32LE();
 
 		debugC(6, kDebugLoading, "graphReact");
-		obj->_movGraphReactObj = (MovGraphReact *)file.readClass();
+		obj->_movGraphReactObj = file.readClass<MovGraphReact>();
 
 		_motionControllers.push_back(obj);
 	}
@@ -166,7 +166,7 @@ void MctlCompound::initMctlGraph() {
 		if (_motionControllers[i]->_motionControllerObj->_objtype != kObjTypeMovGraph)
 			continue;
 
-		MovGraph *gr = (MovGraph *)_motionControllers[i]->_motionControllerObj;
+		MovGraph *gr = static_cast<MovGraph *>(_motionControllers[i]->_motionControllerObj);
 
 		MctlGraph *newgr = new MctlGraph();
 
@@ -701,10 +701,10 @@ MctlConnectionPoint *MctlCompound::findClosestConnectionPoint(int ox, int oy, in
 void MctlCompound::replaceNodeX(int from, int to) {
 	for (uint i = 0; i < _motionControllers.size(); i++) {
 		if (_motionControllers[i]->_motionControllerObj->_objtype == kObjTypeMovGraph) {
-			MovGraph *gr = (MovGraph *)_motionControllers[i]->_motionControllerObj;
+			MovGraph *gr = static_cast<MovGraph *>(_motionControllers[i]->_motionControllerObj);
 
-			for (ObList::iterator n = gr->_nodes.begin(); n != gr->_nodes.end(); ++n) {
-				MovGraphNode *node = (MovGraphNode *)*n;
+			for (MovGraph::NodeList::iterator n = gr->_nodes.begin(); n != gr->_nodes.end(); ++n) {
+				MovGraphNode *node = static_cast<MovGraphNode *>(*n);
 
 				if (node->_x == from)
 					node->_x = to;
@@ -816,10 +816,10 @@ MovGraph::MovGraph() {
 }
 
 MovGraph::~MovGraph() {
-	for (ObList::iterator i = _links.begin(); i != _links.end(); ++i)
+	for (LinkList::iterator i = _links.begin(); i != _links.end(); ++i)
 		delete *i;
 
-	for (ObList::iterator i = _nodes.begin(); i != _nodes.end(); ++i)
+	for (NodeList::iterator i = _nodes.begin(); i != _nodes.end(); ++i)
 		delete *i;
 
 	detachAllObjects();
@@ -1395,10 +1395,10 @@ double MovGraph::putToLink(Common::Point *point, MovGraphLink *link, int fuzzyMa
 void MovGraph::recalcLinkParams() {
 	debugC(4, kDebugPathfinding, "MovGraph::recalcLinkParams()");
 
-	for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) {
-		assert(((CObject *)*i)->_objtype == kObjTypeMovGraphLink);
+	for (LinkList::iterator i = _links.begin(); i != _links.end(); ++i) {
+		assert((*i)->_objtype == kObjTypeMovGraphLink);
 
-		MovGraphLink *lnk = (MovGraphLink *)*i;
+		MovGraphLink *lnk = static_cast<MovGraphLink *>(*i);
 
 		lnk->_flags &= 0x7FFFFFFF;
 
@@ -1413,8 +1413,8 @@ bool MovGraph::getNearestPoint(int unusedArg, Common::Point *p, MovArr *movarr)
 	double mindist = 1.0e20;
 	int resx = 0, resy = 0;
 
-	for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) {
-		MovGraphLink *lnk = (MovGraphLink *)*i;
+	for (LinkList::iterator i = _links.begin(); i != _links.end(); ++i) {
+		MovGraphLink *lnk = static_cast<MovGraphLink *>(*i);
 
 		if ((lnk->_flags & 0x10000000) && !(lnk->_flags & 0x20000000) ) {
 			double dx1 = lnk->_graphSrc->_x - p->x;
@@ -1483,8 +1483,8 @@ Common::Array<MovArr *> *MovGraph::getHitPoints(int x, int y, int *arrSize, int
 	Common::Array<MovArr *> *arr = new Common::Array<MovArr *>;
 	MovArr *movarr;
 
-	for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) {
-		MovGraphLink *lnk = (MovGraphLink *)*i;
+	for (LinkList::iterator i = _links.begin(); i != _links.end(); ++i) {
+		MovGraphLink *lnk = static_cast<MovGraphLink *>(*i);
 
 		if (flag1) {
 			Common::Point point(x, y);
@@ -1556,8 +1556,8 @@ void MovGraph::findAllPaths(MovGraphLink *lnk, MovGraphLink *lnk2, Common::Array
 
 		tempObList1.push_back(lnk);
 
-		for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) {
-			MovGraphLink *l = (MovGraphLink *)*i;
+		for (LinkList::iterator i = _links.begin(); i != _links.end(); ++i) {
+			MovGraphLink *l = static_cast<MovGraphLink *>(*i);
 
 			if (l->_graphSrc != lnk->_graphSrc) {
 				if (l->_graphDst != lnk->_graphSrc) {
@@ -2430,10 +2430,10 @@ MessageQueue *MctlGraph::makeQueue(StaticANIObject *obj, int xpos, int ypos, int
 }
 
 MovGraphNode *MctlGraph::getHitNode(int x, int y, int strictMatch) {
-	for (ObList::iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
-		assert(((CObject *)*i)->_objtype == kObjTypeMovGraphNode);
+	for (NodeList::iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
+		assert((*i)->_objtype == kObjTypeMovGraphNode);
 
-		MovGraphNode *node = (MovGraphNode *)*i;
+		MovGraphNode *node = *i;
 
 		if (!strictMatch) {
 			if (abs(node->_x - x) < 15 && abs(node->_y - y) < 15)
@@ -2719,10 +2719,10 @@ MovGraphLink *MctlGraph::getHitLink(int x, int y, int idx, int fuzzyMatch) {
 	Common::Point point;
 	MovGraphLink *res = 0;
 
-	for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) {
-		assert(((CObject *)*i)->_objtype == kObjTypeMovGraphLink);
+	for (LinkList::iterator i = _links.begin(); i != _links.end(); ++i) {
+		assert((*i)->_objtype == kObjTypeMovGraphLink);
 
-		MovGraphLink *lnk = (MovGraphLink *)*i;
+		MovGraphLink *lnk = static_cast<MovGraphLink *>(*i);
 
 		if (fuzzyMatch) {
 			point.x = x;
@@ -2755,10 +2755,10 @@ MovGraphLink *MctlGraph::getNearestLink(int x, int y) {
 	double mindist = 1.0e20;
 	MovGraphLink *res = 0;
 
-	for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) {
-		assert(((CObject *)*i)->_objtype == kObjTypeMovGraphLink);
+	for (LinkList::iterator i = _links.begin(); i != _links.end(); ++i) {
+		assert((*i)->_objtype == kObjTypeMovGraphLink);
 
-		MovGraphLink *lnk = (MovGraphLink *)*i;
+		MovGraphLink *lnk = static_cast<MovGraphLink *>(*i);
 
 		if (!(lnk->_flags & 0x20000000)) {
 			double n1x = lnk->_graphSrc->_x;
@@ -2802,8 +2802,8 @@ double MctlGraph::iterate(LinkInfo *linkInfoSource, LinkInfo *linkInfoDest, Comm
 		double minDistance = -1.0;
 
 		if (linkInfoSource->node) {
-			for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) {
-				MovGraphLink *lnk = (MovGraphLink *)*i;
+			for (LinkList::iterator i = _links.begin(); i != _links.end(); ++i) {
+				MovGraphLink *lnk = static_cast<MovGraphLink *>(*i);
 
 				if ((lnk->_graphSrc == linkInfoSource->node || lnk->_graphDst == linkInfoSource->node) && !(lnk->_flags & 0xA0000000)) {
 					linkInfoWorkSource.node = 0;
@@ -2872,10 +2872,10 @@ MovGraphNode *MovGraph::calcOffset(int ox, int oy) {
 	MovGraphNode *res = 0;
 	double mindist = 1.0e10;
 
-	for (ObList::iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
-		assert(((CObject *)*i)->_objtype == kObjTypeMovGraphNode);
+	for (NodeList::iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
+		assert((*i)->_objtype == kObjTypeMovGraphNode);
 
-		MovGraphNode *node = (MovGraphNode *)*i;
+		MovGraphNode *node = static_cast<MovGraphNode *>(*i);
 
 		double dist = sqrt((double)((node->_x - oy) * (node->_x - oy) + (node->_x - ox) * (node->_x - ox)));
 		if (dist < mindist) {
@@ -2917,16 +2917,16 @@ bool MovGraphLink::load(MfcArchive &file) {
 	_flags = file.readUint32LE();
 
 	debugC(8, kDebugLoading, "GraphNode1");
-	_graphSrc = (MovGraphNode *)file.readClass();
+	_graphSrc = file.readClass<MovGraphNode>();
 	debugC(8, kDebugLoading, "GraphNode2");
-	_graphDst = (MovGraphNode *)file.readClass();
+	_graphDst = file.readClass<MovGraphNode>();
 
 	_length = file.readDouble();
 	_angle = file.readDouble();
 
 	debugC(8, kDebugLoading, "length: %g, angle: %g", _length, _angle);
 
-	_movGraphReact = (MovGraphReact *)file.readClass();
+	_movGraphReact = file.readClass<MovGraphReact>();
 	_name = file.readPascalString();
 
 	return true;
diff --git a/engines/fullpipe/motion.h b/engines/fullpipe/motion.h
index c08d56f..c86c161 100644
--- a/engines/fullpipe/motion.h
+++ b/engines/fullpipe/motion.h
@@ -280,8 +280,10 @@ friend class MctlCompound;
 friend class MctlGraph;
 friend class MotionController;
 private:
-	ObList _nodes;
-	ObList _links;
+	typedef ObList<MovGraphNode> NodeList;
+	typedef ObList<MovGraphLink> LinkList;
+	NodeList _nodes;
+	LinkList _links;
 	int _field_44;
 	Common::Array<MovGraphItem> _items;
 	MovArr *(*_callback1)(StaticANIObject *ani, Common::Array<MovItem *> *items, signed int counter);
diff --git a/engines/fullpipe/scene.cpp b/engines/fullpipe/scene.cpp
index 76384c3..69ab170 100644
--- a/engines/fullpipe/scene.cpp
+++ b/engines/fullpipe/scene.cpp
@@ -251,7 +251,7 @@ void Scene::init() {
 	g_fp->_sceneRect.moveTo(0, 0);
 
 	for (uint i = 0; i < _picObjList.size(); i++)
-		((PictureObject *)_picObjList[i])->clearFlags();
+		_picObjList[i]->clearFlags();
 
 	for (uint i = 0; i < _staticANIObjectList1.size(); i++)
 		_staticANIObjectList1[i]->clearFlags();
@@ -324,7 +324,7 @@ void Scene::addStaticANIObject(StaticANIObject *obj, bool addList2) {
 
 void Scene::setPictureObjectsFlag4() {
 	for (uint i = 0; i < _picObjList.size(); i++) {
-		((PictureObject *)_picObjList[i])->_flags |= 4;
+		_picObjList[i]->_flags |= 4;
 	}
 }
 
@@ -335,8 +335,8 @@ void Scene::stopAllSounds() {
 
 PictureObject *Scene::getPictureObjectById(int objId, int flags) {
 	for (uint i = 1; i < _picObjList.size(); i++) {
-		if (((PictureObject *)_picObjList[i])->_id == objId && ((PictureObject *)_picObjList[i])->_odelay == flags)
-			return (PictureObject *)_picObjList[i];
+		if (_picObjList[i]->_id == objId && _picObjList[i]->_odelay == flags)
+			return _picObjList[i];
 	}
 
 	return 0;
@@ -344,8 +344,8 @@ PictureObject *Scene::getPictureObjectById(int objId, int flags) {
 
 PictureObject *Scene::getPictureObjectByName(const Common::String &objName, int flags) {
 	for (uint i = 0; i < _picObjList.size(); i++) {
-		if ((((PictureObject *)_picObjList[i])->_objectName == objName) && (((PictureObject *)_picObjList[i])->_odelay == flags || flags == -1))
-			return (PictureObject *)_picObjList[i];
+		if ((_picObjList[i]->_objectName == objName) && (_picObjList[i]->_odelay == flags || flags == -1))
+			return _picObjList[i];
 	}
 
 	return 0;
@@ -353,7 +353,7 @@ PictureObject *Scene::getPictureObjectByName(const Common::String &objName, int
 
 void Scene::deletePictureObject(PictureObject *obj) {
 	for (uint i = 0; i < _picObjList.size(); i++) {
-		if (((PictureObject *)_picObjList[i]) == obj) {
+		if (_picObjList[i] == obj) {
 			_picObjList.remove_at(i);
 			delete obj;
 
@@ -547,7 +547,7 @@ void Scene::updateScrolling() {
 		int offsetY = 0;
 
 		if (_x < 0) {
-			if (!g_fp->_sceneRect.left && !(((PictureObject *)_picObjList[0])->_flags & 2))
+			if (!g_fp->_sceneRect.left && !(_picObjList[0]->_flags & 2))
 				_x = 0;
 
 			if (_x <= -g_fp->_scrollSpeed) {
@@ -620,7 +620,7 @@ PictureObject *Scene::getPictureObjectAtPos(int x, int y) {
 	PictureObject *res = 0;
 
 	for (uint i = 0; i < _picObjList.size(); i++) {
-		PictureObject *p = (PictureObject *)_picObjList[i];
+		PictureObject *p = _picObjList[i];
 		if ((p->_field_8 & 0x100) && (p->_flags & 4) &&
 				p->isPixelHitAtPos(x, y) &&
 				(!res || res->_priority >= p->_priority))
@@ -635,7 +635,7 @@ int Scene::getPictureObjectIdAtPos(int x, int y) {
 	int res = 0;
 
 	for (uint i = 0; i < _picObjList.size(); i++) {
-		PictureObject *p = (PictureObject *)_picObjList[i];
+		PictureObject *p = _picObjList[i];
 		if ((p->_field_8 & 0x100) && (p->_flags & 4) &&
 				p->isPixelHitAtPos(x, y) &&
 				(!res || resp->_priority >= p->_priority)) {
@@ -673,7 +673,7 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
 #endif
 
 	if (minPri == -1 && _picObjList.size())
-		minPri = ((PictureObject *)_picObjList.back())->_priority - 1;
+		minPri = _picObjList.back()->_priority - 1;
 
 	if (maxPri == -1)
 		maxPri = 60000;
@@ -725,7 +725,7 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
 					v25++;
 
 					if (v25 >= _bigPictureArray2Count) {
-						if (!(((PictureObject *)_picObjList[0])->_flags & 0x20))
+						if (!(_picObjList[0]->_flags & 0x20))
 							break;
 						v25 = 0;
 					}
@@ -736,7 +736,7 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
 				bgNumX++;
 
 				if (bgNumX >= _bigPictureArray1Count) {
-					if (!(((PictureObject *)_picObjList[0])->_flags & 0x2))
+					if (!(_picObjList[0]->_flags & 0x2))
 						break;
 					bgNumX = 0;
 				}
@@ -748,7 +748,7 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
 
 
 	for (uint i = 1; i < _picObjList.size(); i++) {
-		PictureObject *obj = (PictureObject *)_picObjList[i];
+		PictureObject *obj = _picObjList[i];
 
 		if (obj->_priority < minPri || obj->_priority >= maxPri)
 			continue;
diff --git a/engines/fullpipe/scenes/scene03.cpp b/engines/fullpipe/scenes/scene03.cpp
index 25b48de..1882ecf 100644
--- a/engines/fullpipe/scenes/scene03.cpp
+++ b/engines/fullpipe/scenes/scene03.cpp
@@ -210,7 +210,7 @@ void sceneHandler03_takeEgg(ExCommand *ex) {
 			 && ex1) {
 
 			if (ex1->_objtype == kObjTypeObjstateCommand) {
-				ObjstateCommand *com = (ObjstateCommand *)ex1;
+				ObjstateCommand *com = static_cast<ObjstateCommand *>(ex1);
 
 				com->_value = g_fp->getObjectEnumState(sO_EggGulper, sO_WantsNothing);
 			}
diff --git a/engines/fullpipe/scenes/scene04.cpp b/engines/fullpipe/scenes/scene04.cpp
index ae8e567..c899e46 100644
--- a/engines/fullpipe/scenes/scene04.cpp
+++ b/engines/fullpipe/scenes/scene04.cpp
@@ -958,7 +958,7 @@ void sceneHandler04_walkKozyawka() {
 void sceneHandler04_bottleUpdateObjects(int off) {
 	for (Common::List<GameObject *>::iterator it = g_vars->scene04_bottleObjList.begin(); it != g_vars->scene04_bottleObjList.end(); ++it) {
 		if ((*it)->_objtype == kObjTypeStaticANIObject) {
-			StaticANIObject *st = (StaticANIObject *)*it;
+			StaticANIObject *st = static_cast<StaticANIObject *>(*it);
 
 			st->setOXY(st->_ox, off + st->_oy);
 		} else {
@@ -1138,7 +1138,7 @@ void sceneHandler04_leaveLadder(ExCommand *ex) {
 
 	if (!(g_fp->_aniMan->_flags & 0x100)) {
 		if (getSc2MctlCompoundBySceneId(g_fp->_currentScene->_sceneId)->_objtype == kObjTypeMctlCompound) {
-			MctlCompound *mc = (MctlCompound *)getSc2MctlCompoundBySceneId(g_fp->_currentScene->_sceneId);
+			MctlCompound *mc = static_cast<MctlCompound *>(getSc2MctlCompoundBySceneId(g_fp->_currentScene->_sceneId));
 
 			if (mc->_motionControllers[0]->_movGraphReactObj->pointInRegion(g_fp->_sceneRect.left + ex->_x, g_fp->_sceneRect.top + ex->_y)) {
 				if (g_vars->scene04_ladder->collisionDetection(g_fp->_aniMan)) {
diff --git a/engines/fullpipe/scenes/scene06.cpp b/engines/fullpipe/scenes/scene06.cpp
index f434848..54b3fb7 100644
--- a/engines/fullpipe/scenes/scene06.cpp
+++ b/engines/fullpipe/scenes/scene06.cpp
@@ -53,13 +53,13 @@ int scene06_updateCursor() {
 
 			return PIC_CSR_ARCADE2_D;
 		}
-		if (g_fp->_aniMan == (StaticANIObject *)g_fp->_objectAtCursor) {
+		if (g_fp->_aniMan == g_fp->_objectAtCursor) {
 			if (g_fp->_aniMan->_statics->_staticsId == ST_MAN6_BALL && g_fp->_cursorId == PIC_CSR_DEFAULT) {
 				g_fp->_cursorId = PIC_CSR_ITN;
 
 				return PIC_CSR_ITN;
 			}
-		} else if (g_fp->_objectAtCursor && (StaticANIObject *)g_fp->_objectAtCursor == g_vars->scene06_currentBall
+		} else if (g_fp->_objectAtCursor && g_fp->_objectAtCursor == g_vars->scene06_currentBall
 					&& g_fp->_cursorId == PIC_CSR_DEFAULT) {
 			g_fp->_cursorId = PIC_CSR_ITN;
 		}
diff --git a/engines/fullpipe/scenes/scene11.cpp b/engines/fullpipe/scenes/scene11.cpp
index 72af59a..6a08677 100644
--- a/engines/fullpipe/scenes/scene11.cpp
+++ b/engines/fullpipe/scenes/scene11.cpp
@@ -134,9 +134,7 @@ void scene11_initScene(Scene *sc) {
 		getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing1, 1);
 		getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing2, 1);
 		getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing3, 0);
-
-		((MctlCompound *)getCurrSceneSc2MotionController())->replaceNodeX(805, 905);
-
+		getCurrSceneSc2MotionController()->replaceNodeX(805, 905);
 		getSc2MctlCompoundBySceneId(sc->_sceneId)->replaceNodeX(303, 353);
 	} else if (swingie == g_fp->getObjectEnumState(sO_Swingie, sO_IsStandingInBoots)
 				|| swingie == g_fp->getObjectEnumState(sO_Swingie, sO_IsStandingInCorner)) {
@@ -148,8 +146,7 @@ void scene11_initScene(Scene *sc) {
 		getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing1, 0);
 		getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing2, 1);
 		getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing3, 0);
-
-		((MctlCompound *)getCurrSceneSc2MotionController())->replaceNodeX(905, 805);
+		getCurrSceneSc2MotionController()->replaceNodeX(905, 805);
 	} else {
 		g_vars->scene11_swingIsSwinging = false;
 		g_vars->scene11_swingieStands = false;
diff --git a/engines/fullpipe/scenes/scene33.cpp b/engines/fullpipe/scenes/scene33.cpp
index 717e9f6..6719673 100644
--- a/engines/fullpipe/scenes/scene33.cpp
+++ b/engines/fullpipe/scenes/scene33.cpp
@@ -211,7 +211,7 @@ void sceneHandler33_clickZones(ExCommand *cmd) {
 	double mindist = 1e10;
 
 	for (uint i = 0; i < g_fp->_currentScene->_staticANIObjectList1.size(); i++) {
-		StaticANIObject *ani = (StaticANIObject *)g_fp->_currentScene->_staticANIObjectList1[i];
+		StaticANIObject *ani = g_fp->_currentScene->_staticANIObjectList1[i];
 
 		if (ani->_id == ANI_VENT_33) {
 			int dx = ani->_ox - cmd->_sceneClickX;
diff --git a/engines/fullpipe/scenes/sceneDbg.cpp b/engines/fullpipe/scenes/sceneDbg.cpp
index 4d061e6..759480d 100644
--- a/engines/fullpipe/scenes/sceneDbg.cpp
+++ b/engines/fullpipe/scenes/sceneDbg.cpp
@@ -45,7 +45,7 @@ GameObject *sceneHandlerDbgMenu_getObjectAtXY(int x, int y) {
 		return 0;
 
 	for (uint i = 1; i < g_fp->_currentScene->_picObjList.size(); i++) {
-		PictureObject *pic = (PictureObject *)g_fp->_currentScene->_picObjList[i];
+		PictureObject *pic = g_fp->_currentScene->_picObjList[i];
 
 		if (x >= pic->_ox && y >= pic->_oy) {
 			const Dims dims = pic->getDimensions();
diff --git a/engines/fullpipe/stateloader.cpp b/engines/fullpipe/stateloader.cpp
index 0ff8c60..cc5c904 100644
--- a/engines/fullpipe/stateloader.cpp
+++ b/engines/fullpipe/stateloader.cpp
@@ -85,7 +85,7 @@ bool GameLoader::readSavegame(const char *fname) {
 	Common::MemoryReadStream *archiveStream = new Common::MemoryReadStream(data, header.encSize);
 	MfcArchive *archive = new MfcArchive(archiveStream);
 
-	GameVar *var = (GameVar *)archive->readClass();
+	GameVar *var = archive->readClass<GameVar>();
 
 	GameVar *v = _gameVar->getSubVarByName("OBJSTATES");
 
@@ -301,7 +301,7 @@ bool FullpipeEngine::loadGam(const char *fname, int scene) {
 	_inventory->rebuildItemRects();
 
 	for (uint i = 0; i < _inventory->getScene()->_picObjList.size(); i++)
-		((MemoryObject *)_inventory->getScene()->_picObjList[i]->_picture)->load();
+		_inventory->getScene()->_picObjList[i]->_picture->MemoryObject::load();
 
 	// _sceneSwitcher = sceneSwitcher; // substituted with direct call
 	_gameLoader->_preloadCallback = preloadCallback;
@@ -474,11 +474,11 @@ bool GameVar::load(MfcArchive &file) {
 	}
 
 	file.incLevel();
-	_parentVarObj = (GameVar *)file.readClass();
-	_prevVarObj = (GameVar *)file.readClass();
-	_nextVarObj = (GameVar *)file.readClass();
-	_field_14 = (GameVar *)file.readClass();
-	_subVars = (GameVar *)file.readClass();
+	_parentVarObj = file.readClass<GameVar>();
+	_prevVarObj = file.readClass<GameVar>();
+	_nextVarObj = file.readClass<GameVar>();
+	_field_14 = file.readClass<GameVar>();
+	_subVars = file.readClass<GameVar>();
 	file.decLevel();
 
 	return true;
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index 8c0a045..994feee 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -1592,8 +1592,8 @@ Movement::Movement(Movement *src, int *oldIdxs, int newSize, StaticANIObject *an
 				_framePosOffsets[i]->y = src->_framePosOffsets[oldIdxs[i]]->y;
 			}
 		}
-		_staticsObj1 = (Statics *)_dynamicPhases.front();
-		_staticsObj2 = (Statics *)_dynamicPhases.back();
+		_staticsObj1 = dynamic_cast<Statics *>(_dynamicPhases.front());
+		_staticsObj2 = dynamic_cast<Statics *>(_dynamicPhases.back());
 	} else {
 		for (int i = 0; i < newSize; i++) {
 			src->setDynamicPhaseIndex(i);
@@ -2231,7 +2231,7 @@ bool StaticPhase::load(MfcArchive &file) {
 	_field_6A = file.readUint16LE();
 
 	if (g_fp->_gameProjectVersion >= 12) {
-		_exCommand = (ExCommand *)file.readClass();
+		_exCommand = file.readClass<ExCommand>();
 
 		return true;
 	}
diff --git a/engines/fullpipe/utils.cpp b/engines/fullpipe/utils.cpp
index 72a3377..f3f07b0 100644
--- a/engines/fullpipe/utils.cpp
+++ b/engines/fullpipe/utils.cpp
@@ -45,22 +45,6 @@ bool CObject::loadFile(const Common::String &fname) {
 	return load(archive);
 }
 
-bool ObList::load(MfcArchive &file) {
-	debugC(5, kDebugLoading, "ObList::load()");
-	int count = file.readCount();
-
-	debugC(9, kDebugLoading, "ObList::count: %d:", count);
-
-	for (int i = 0; i < count; i++) {
-		debugC(9, kDebugLoading, "ObList::[%d]", i);
-		CObject *t = file.readClass();
-
-		push_back(t);
-	}
-
-	return true;
-}
-
 bool ObArray::load(MfcArchive &file) {
 	debugC(5, kDebugLoading, "ObArray::load()");
 	int count = file.readCount();
@@ -68,7 +52,7 @@ bool ObArray::load(MfcArchive &file) {
 	resize(count);
 
 	for (int i = 0; i < count; i++) {
-		CObject *t = file.readClass();
+		CObject *t = file.readClass<CObject>();
 
 		push_back(*t);
 	}
@@ -379,7 +363,7 @@ void MfcArchive::init() {
 	_objectIdMap.push_back(kNullObject);
 }
 
-CObject *MfcArchive::readClass() {
+CObject *MfcArchive::readBaseClass() {
 	bool isCopyReturned;
 	CObject *res = parseClass(&isCopyReturned);
 
diff --git a/engines/fullpipe/utils.h b/engines/fullpipe/utils.h
index 2b97ab6..8966ceb 100644
--- a/engines/fullpipe/utils.h
+++ b/engines/fullpipe/utils.h
@@ -58,7 +58,17 @@ public:
 	int readCount();
 	double readDouble();
 	CObject *parseClass(bool *isCopyReturned);
-	CObject *readClass();
+
+	template <typename T>
+	T *readClass() {
+		CObject *obj = readBaseClass();
+		if (!obj)
+			return nullptr;
+
+		T *res = dynamic_cast<T *>(obj);
+		assert(res);
+		return res;
+	}
 
 	void writeObject(CObject *obj);
 
@@ -76,6 +86,7 @@ public:
 
 private:
 	void init();
+	CObject *readBaseClass();
 };
 
 enum ObjType {
@@ -106,9 +117,24 @@ public:
 	bool loadFile(const Common::String &fname);
 };
 
-class ObList : public Common::List<CObject *>, public CObject {
+template <class T>
+class ObList : public Common::List<T *>, public CObject {
 public:
-	virtual bool load(MfcArchive &file);
+	virtual bool load(MfcArchive &file) {
+		debugC(5, kDebugLoading, "ObList::load()");
+		int count = file.readCount();
+
+		debugC(9, kDebugLoading, "ObList::count: %d:", count);
+
+		for (int i = 0; i < count; i++) {
+			debugC(9, kDebugLoading, "ObList::[%d]", i);
+			T *t = file.readClass<T>();
+
+			this->push_back(t);
+		}
+
+		return true;
+	}
 };
 
 class MemoryObject : CObject {


Commit: c2dcb27e356cb3bff4ddcecfb40733a76954550d
    https://github.com/scummvm/scummvm/commit/c2dcb27e356cb3bff4ddcecfb40733a76954550d
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix memory leaks in ModalMainMenu

Changed paths:
    engines/fullpipe/modal.cpp
    engines/fullpipe/modal.h


diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp
index ef35467..564d5ea 100644
--- a/engines/fullpipe/modal.cpp
+++ b/engines/fullpipe/modal.cpp
@@ -1234,8 +1234,6 @@ void ModalCredits::update() {
 }
 
 ModalMainMenu::ModalMainMenu() {
-	_areas.clear();
-
 	_lastArea = 0;
 	_hoverAreaId = 0;
 	_mfield_34 = 0;
@@ -1262,66 +1260,68 @@ ModalMainMenu::ModalMainMenu() {
 
 	MenuArea *area;
 
-	area = new MenuArea();
+	_areas.push_back(MenuArea());
+	area = &_areas.back();
 	area->picIdL = PIC_MNU_EXIT_L;
 	area->picObjD = 0;
 	area->picObjL = _scene->getPictureObjectById(area->picIdL, 0);
 	area->picObjL->_flags &= 0xFFFB;
-	_areas.push_back(area);
 
-	area = new MenuArea();
+	_areas.push_back(MenuArea());
+	area = &_areas.back();
 	area->picIdL = PIC_MNU_CONTINUE_L;
 	area->picObjD = 0;
 	area->picObjL = _scene->getPictureObjectById(area->picIdL, 0);
 	area->picObjL->_flags &= 0xFFFB;
-	_areas.push_back(area);
 
 	if (isSaveAllowed()) {
-		area = new MenuArea();
+		_areas.push_back(MenuArea());
+		area = &_areas.back();
 		area->picIdL = PIC_MNU_SAVE_L;
 		area->picObjD = 0;
 		area->picObjL = _scene->getPictureObjectById(area->picIdL, 0);
 		area->picObjL->_flags &= 0xFFFB;
-		_areas.push_back(area);
 	}
 
-	area = new MenuArea();
+	_areas.push_back(MenuArea());
+	area = &_areas.back();
 	area->picIdL = PIC_MNU_LOAD_L;
 	area->picObjD = 0;
 	area->picObjL = _scene->getPictureObjectById(area->picIdL, 0);
 	area->picObjL->_flags &= 0xFFFB;
-	_areas.push_back(area);
 
-	area = new MenuArea();
+	_areas.push_back(MenuArea());
+	area = &_areas.back();
 	area->picIdL = PIC_MNU_RESTART_L;
 	area->picObjD = 0;
 	area->picObjL = _scene->getPictureObjectById(area->picIdL, 0);
 	area->picObjL->_flags &= 0xFFFB;
-	_areas.push_back(area);
 
-	area = new MenuArea();
+	_areas.push_back(MenuArea());
+	area = &_areas.back();
 	area->picIdL = PIC_MNU_AUTHORS_L;
 	area->picObjD = 0;
 	area->picObjL = _scene->getPictureObjectById(area->picIdL, 0);
 	area->picObjL->_flags &= 0xFFFB;
-	_areas.push_back(area);
 
-	area = new MenuArea();
+	_areas.push_back(MenuArea());
+	area = &_areas.back();
 	area->picIdL = PIC_MNU_SLIDER_L;
 	area->picObjD = _scene->getPictureObjectById(PIC_MNU_SLIDER_D, 0);
 	area->picObjD->_flags |= 4;
 	area->picObjL = _scene->getPictureObjectById(area->picIdL, 0);
 	area->picObjL->_flags &= 0xFFFB;
-	_areas.push_back(area);
+
 	_menuSliderIdx = _areas.size() - 1;
 
-	area = new MenuArea();
+	_areas.push_back(MenuArea());
+	area = &_areas.back();
 	area->picIdL = PIC_MNU_MUSICSLIDER_L;
 	area->picObjD = _scene->getPictureObjectById(PIC_MNU_MUSICSLIDER_D, 0);
 	area->picObjD->_flags |= 4;
 	area->picObjL = _scene->getPictureObjectById(area->picIdL, 0);
 	area->picObjL->_flags &= 0xFFFB;
-	_areas.push_back(area);
+
 	_musicSliderIdx = _areas.size() - 1;
 
 	if (g_fp->_mainMenu_debugEnabled)
@@ -1348,20 +1348,20 @@ bool ModalMainMenu::handleMessage(ExCommand *message) {
 
 		if (numarea >= 0) {
 			if (numarea == _menuSliderIdx) {
-				_lastArea = _areas[_menuSliderIdx];
+				_lastArea = &_areas[_menuSliderIdx];
 				_sliderOffset = _lastArea->picObjL->_ox - point.x;
 
 				return false;
 			}
 
 			if (numarea == _musicSliderIdx) {
-				_lastArea = _areas[_musicSliderIdx];
+				_lastArea = &_areas[_musicSliderIdx];
 				_sliderOffset = _lastArea->picObjL->_ox - point.x;
 
 				return false;
 			}
 
-			_hoverAreaId = _areas[numarea]->picIdL;
+			_hoverAreaId = _areas[numarea].picIdL;
 		}
 
 		return false;
@@ -1628,23 +1628,23 @@ void ModalMainMenu::updateSliderPos() {
 
 int ModalMainMenu::checkHover(Common::Point &point) {
 	for (uint i = 0; i < _areas.size(); i++) {
-		if (_areas[i]->picObjL->isPixelHitAtPos(point.x, point.y)) {
-			_areas[i]->picObjL->_flags |= 4;
+		if (_areas[i].picObjL->isPixelHitAtPos(point.x, point.y)) {
+			_areas[i].picObjL->_flags |= 4;
 
 			return i;
 		} else {
-			_areas[i]->picObjL->_flags &= 0xFFFB;
+			_areas[i].picObjL->_flags &= 0xFFFB;
 		}
 	}
 
-	if (isOverArea(_areas[_menuSliderIdx]->picObjL, &point)) {
-		_areas[_menuSliderIdx]->picObjL->_flags |= 4;
+	if (isOverArea(_areas[_menuSliderIdx].picObjL, &point)) {
+		_areas[_menuSliderIdx].picObjL->_flags |= 4;
 
 		return _menuSliderIdx;
 	}
 
-	if (isOverArea(_areas[_musicSliderIdx]->picObjL, &point)) {
-		_areas[_musicSliderIdx]->picObjL->_flags |= 4;
+	if (isOverArea(_areas[_musicSliderIdx].picObjL, &point)) {
+		_areas[_musicSliderIdx].picObjL->_flags |= 4;
 
 		return _musicSliderIdx;
 	}
@@ -1697,25 +1697,23 @@ void ModalMainMenu::enableDebugMenu(char c) {
 }
 
 void ModalMainMenu::enableDebugMenuButton() {
-	MenuArea *area;
-
 	for (uint i = 0; i < _areas.size(); i++)
-		if (_areas[i]->picIdL == PIC_MNU_DEBUG_L)
+		if (_areas[i].picIdL == PIC_MNU_DEBUG_L)
 			return;
 
-	area = new MenuArea();
+	_areas.push_back(MenuArea());
+	MenuArea *area = &_areas.back();
 	area->picIdL = PIC_MNU_DEBUG_L;
 	area->picObjD = 0;
 	area->picObjL = _scene->getPictureObjectById(area->picIdL, 0);
 	area->picObjL->_flags &= 0xFFFB;
-	_areas.push_back(area);
 
 	g_fp->_mainMenu_debugEnabled = true;
 }
 
 void ModalMainMenu::setSliderPos() {
 	int x = 173 * (g_fp->_sfxVolume + 3000) / 3000 + 65;
-	PictureObject *obj = _areas[_menuSliderIdx]->picObjD;
+	PictureObject *obj = _areas[_menuSliderIdx].picObjD;
 
 	if (x >= 65) {
 		if (x > 238)
@@ -1725,10 +1723,10 @@ void ModalMainMenu::setSliderPos() {
 	}
 
 	obj->setOXY(x, obj->_oy);
-	_areas[_menuSliderIdx]->picObjL->setOXY(x, obj->_oy);
+	_areas[_menuSliderIdx].picObjL->setOXY(x, obj->_oy);
 
 	x = 173 * g_fp->_musicVolume / 255 + 65;
-	obj = _areas[_musicSliderIdx]->picObjD;
+	obj = _areas[_musicSliderIdx].picObjD;
 
 	if (x >= 65) {
 		if (x > 238)
@@ -1738,7 +1736,7 @@ void ModalMainMenu::setSliderPos() {
 	}
 
 	obj->setOXY(x, obj->_oy);
-	_areas[_musicSliderIdx]->picObjL->setOXY(x, obj->_oy);
+	_areas[_musicSliderIdx].picObjL->setOXY(x, obj->_oy);
 }
 
 ModalHelp::ModalHelp() {
diff --git a/engines/fullpipe/modal.h b/engines/fullpipe/modal.h
index 5beba92..800cba6 100644
--- a/engines/fullpipe/modal.h
+++ b/engines/fullpipe/modal.h
@@ -205,7 +205,7 @@ class ModalMainMenu : public BaseModalObject {
 public:
 	Scene *_scene;
 	int _hoverAreaId;
-	Common::Array<MenuArea *> _areas;
+	Common::Array<MenuArea> _areas;
 	int _menuSliderIdx;
 	int _musicSliderIdx;
 	MenuArea *_lastArea;


Commit: ca5a86e703d3fe72cc370845622097ee16f4d67e
    https://github.com/scummvm/scummvm/commit/ca5a86e703d3fe72cc370845622097ee16f4d67e
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix memory leak of global message queues

Changed paths:
    engines/fullpipe/messages.cpp


diff --git a/engines/fullpipe/messages.cpp b/engines/fullpipe/messages.cpp
index e332728..c865690 100644
--- a/engines/fullpipe/messages.cpp
+++ b/engines/fullpipe/messages.cpp
@@ -684,7 +684,7 @@ int GlobalMessageQueueList::compact() {
 	for (uint i = 0; i < size();) {
 		if (_storage[i]->_isFinished) {
 			disableQueueById(_storage[i]->_id);
-			remove_at(i);
+			delete remove_at(i);
 		} else {
 			if ((uint)_storage[i]->_id < size() + 2)
 				useList[_storage[i]->_id] = 1;


Commit: bb26bf7994420a8af3fd5e1c3a1b174448aefc5c
    https://github.com/scummvm/scummvm/commit/bb26bf7994420a8af3fd5e1c3a1b174448aefc5c
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix memory leaks and unnecessary indirect allocations in Motion and Sc2

Changed paths:
    engines/fullpipe/fullpipe.h
    engines/fullpipe/gameloader.cpp
    engines/fullpipe/gameloader.h
    engines/fullpipe/gfx.cpp
    engines/fullpipe/gfx.h
    engines/fullpipe/interaction.cpp
    engines/fullpipe/messagehandlers.cpp
    engines/fullpipe/modal.cpp
    engines/fullpipe/motion.cpp
    engines/fullpipe/motion.h
    engines/fullpipe/objects.h
    engines/fullpipe/scenes.cpp
    engines/fullpipe/scenes/scene04.cpp
    engines/fullpipe/scenes/scene09.cpp
    engines/fullpipe/scenes/scene18and19.cpp
    engines/fullpipe/scenes/scene25.cpp
    engines/fullpipe/stateloader.cpp
    engines/fullpipe/statesaver.cpp
    engines/fullpipe/statics.cpp
    engines/fullpipe/statics.h


diff --git a/engines/fullpipe/fullpipe.h b/engines/fullpipe/fullpipe.h
index e6a3fde..fefe24c 100644
--- a/engines/fullpipe/fullpipe.h
+++ b/engines/fullpipe/fullpipe.h
@@ -283,7 +283,7 @@ public:
 	int getObjectEnumState(const Common::String &name, const char *state);
 
 	void sceneAutoScrolling();
-	bool sceneSwitcher(EntranceInfo *entrance);
+	bool sceneSwitcher(const EntranceInfo &entrance);
 	Scene *accessScene(int sceneId);
 	void setSceneMusicParameters(GameVar *var);
 	int convertScene(int scene);
diff --git a/engines/fullpipe/gameloader.cpp b/engines/fullpipe/gameloader.cpp
index ce98d7c..58d3a4c 100644
--- a/engines/fullpipe/gameloader.cpp
+++ b/engines/fullpipe/gameloader.cpp
@@ -97,28 +97,7 @@ GameLoader::GameLoader() {
 GameLoader::~GameLoader() {
 	delete _interactionController;
 	delete _inputController;
-
-	for (uint i = 0; i < _sc2array.size(); i++) {
-		if (_sc2array[i]._defPicAniInfos)
-			free(_sc2array[i]._defPicAniInfos);
-
-		if (_sc2array[i]._picAniInfos)
-			free(_sc2array[i]._picAniInfos);
-
-		if (_sc2array[i]._motionController)
-			delete _sc2array[i]._motionController;
-
-		if (_sc2array[i]._data1)
-			free(_sc2array[i]._data1);
-
-		if (_sc2array[i]._entranceData)
-			free(_sc2array[i]._entranceData);
-	}
-
 	delete _gameVar;
-	_gameVar = 0;
-
-	_sc2array.clear();
 }
 
 bool GameLoader::load(MfcArchive &file) {
@@ -185,11 +164,11 @@ bool GameLoader::loadScene(int sceneId) {
 	if (st->_scene) {
 		st->_scene->init();
 
-		applyPicAniInfos(st->_scene, _sc2array[idx]._defPicAniInfos, _sc2array[idx]._defPicAniInfosCount);
-		applyPicAniInfos(st->_scene, _sc2array[idx]._picAniInfos, _sc2array[idx]._picAniInfosCount);
+		applyPicAniInfos(st->_scene, _sc2array[idx]._defPicAniInfos);
+		applyPicAniInfos(st->_scene, _sc2array[idx]._picAniInfos);
 
 		_sc2array[idx]._scene = st->_scene;
-		_sc2array[idx]._isLoaded = 1;
+		_sc2array[idx]._isLoaded = true;
 
 		return true;
 	}
@@ -208,18 +187,18 @@ bool GameLoader::gotoScene(int sceneId, int entranceId) {
 	if (!_sc2array[sc2idx]._isLoaded)
 		return false;
 
-	if (_sc2array[sc2idx]._entranceDataCount < 1) {
+	if (_sc2array[sc2idx]._entranceData.size() < 1) {
 		g_fp->_currentScene = st->_scene;
 		return true;
 	}
 
-	if (_sc2array[sc2idx]._entranceDataCount <= 0)
+	if (!_sc2array[sc2idx]._entranceData.size())
 		return false;
 
-	int entranceIdx = 0;
+	uint entranceIdx = 0;
 	if (sceneId != 726) // WORKAROUND
-		for (entranceIdx = 0; _sc2array[sc2idx]._entranceData[entranceIdx]->_field_4 != entranceId; entranceIdx++) {
-			if (entranceIdx >= _sc2array[sc2idx]._entranceDataCount)
+		for (entranceIdx = 0; _sc2array[sc2idx]._entranceData[entranceIdx]._field_4 != entranceId; entranceIdx++) {
+			if (entranceIdx >= _sc2array[sc2idx]._entranceData.size())
 				return false;
 		}
 
@@ -237,7 +216,7 @@ bool GameLoader::gotoScene(int sceneId, int entranceId) {
 
 	g_fp->_currentScene = st->_scene;
 
-	MessageQueue *mq1 = g_fp->_currentScene->getMessageQueueById(_sc2array[sc2idx]._entranceData[entranceIdx]->_messageQueueId);
+	MessageQueue *mq1 = g_fp->_currentScene->getMessageQueueById(_sc2array[sc2idx]._entranceData[entranceIdx]._messageQueueId);
 	if (mq1) {
 		MessageQueue *mq = new MessageQueue(mq1, 0, 0);
 
@@ -442,8 +421,8 @@ bool GameLoader::unloadScene(int sceneId) {
 	delete tag->_scene;
 	tag->_scene = nullptr;
 
-	_sc2array[sceneTag]._isLoaded = 0;
-	_sc2array[sceneTag]._scene = 0;
+	_sc2array[sceneTag]._isLoaded = false;
+	_sc2array[sceneTag]._scene = nullptr;
 
 	return true;
 }
@@ -467,46 +446,47 @@ int GameLoader::getSceneTagBySceneId(int sceneId, SceneTag **st) {
 	return -1;
 }
 
-void GameLoader::applyPicAniInfos(Scene *sc, PicAniInfo **picAniInfo, int picAniInfoCount) {
-	if (picAniInfoCount <= 0)
+void GameLoader::applyPicAniInfos(Scene *sc, const PicAniInfoList &picAniInfo) {
+	if (!picAniInfo.size())
 		return;
 
-	debugC(0, kDebugAnimation, "GameLoader::applyPicAniInfos(sc, ptr, %d)", picAniInfoCount);
+	debugC(0, kDebugAnimation, "GameLoader::applyPicAniInfos(sc, ptr, %d)", picAniInfo.size());
 
 	PictureObject *pict;
 	StaticANIObject *ani;
 
-	for (int i = 0; i < picAniInfoCount; i++) {
-		debugC(7, kDebugAnimation, "PicAniInfo: id: %d type: %d", picAniInfo[i]->objectId, picAniInfo[i]->type);
-		if (picAniInfo[i]->type & 2) {
-			pict = sc->getPictureObjectById(picAniInfo[i]->objectId, picAniInfo[i]->field_8);
+	for (uint i = 0; i < picAniInfo.size(); i++) {
+		const PicAniInfo &info = picAniInfo[i];
+		debugC(7, kDebugAnimation, "PicAniInfo: id: %d type: %d", info.objectId, info.type);
+		if (info.type & 2) {
+			pict = sc->getPictureObjectById(info.objectId, info.field_8);
 			if (pict) {
-				pict->setPicAniInfo(picAniInfo[i]);
+				pict->setPicAniInfo(info);
 				continue;
 			}
-			pict = sc->getPictureObjectById(picAniInfo[i]->objectId, 0);
+			pict = sc->getPictureObjectById(info.objectId, 0);
 			if (pict) {
 				PictureObject *pictNew = new PictureObject(pict);
 
 				sc->_picObjList.push_back(pictNew);
-				pictNew->setPicAniInfo(picAniInfo[i]);
+				pictNew->setPicAniInfo(info);
 				continue;
 			}
 		} else {
-			if (!(picAniInfo[i]->type & 1))
+			if (!(info.type & 1))
 				continue;
 
-			Scene *scNew = g_fp->accessScene(picAniInfo[i]->sceneId);
+			Scene *scNew = g_fp->accessScene(info.sceneId);
 			if (!scNew)
 				continue;
 
-			ani = sc->getStaticANIObject1ById(picAniInfo[i]->objectId, picAniInfo[i]->field_8);
+			ani = sc->getStaticANIObject1ById(info.objectId, info.field_8);
 			if (ani) {
 				ani->setPicAniInfo(picAniInfo[i]);
 				continue;
 			}
 
-			ani = scNew->getStaticANIObject1ById(picAniInfo[i]->objectId, 0);
+			ani = scNew->getStaticANIObject1ById(info.objectId, 0);
 			if (ani) {
 				StaticANIObject *aniNew = new StaticANIObject(ani);
 
@@ -533,42 +513,29 @@ void GameLoader::saveScenePicAniInfos(int sceneId) {
 	if (!st->_scene)
 		return;
 
-	int picAniInfosCount;
-
-	PicAniInfo **pic = savePicAniInfos(st->_scene, 0, 128, &picAniInfosCount);
-
-	if (_sc2array[idx]._picAniInfos)
-		free(_sc2array[idx]._picAniInfos);
-
-	_sc2array[idx]._picAniInfos = pic;
-	_sc2array[idx]._picAniInfosCount = picAniInfosCount;
+	_sc2array[idx]._picAniInfos = savePicAniInfos(st->_scene, 0, 128);
 }
 
-PicAniInfo **GameLoader::savePicAniInfos(Scene *sc, int flag1, int flag2, int *picAniInfoCount) {
-	PicAniInfo **res;
-
-	*picAniInfoCount = 0;
+PicAniInfoList GameLoader::savePicAniInfos(Scene *sc, int flag1, int flag2) {
 	if (!sc)
-		return NULL;
+		return PicAniInfoList();
 
 	if (!sc->_picObjList.size())
-		return NULL;
+		return PicAniInfoList();
 
 	int numInfos = sc->_staticANIObjectList1.size() + sc->_picObjList.size() - 1;
 	if (numInfos < 1)
-		return NULL;
-
-	res = (PicAniInfo **)malloc(sizeof(PicAniInfo *) * numInfos);
+		return PicAniInfoList();
 
-	int idx = 0;
+	PicAniInfoList res;
+	res.reserve(numInfos);
 
 	for (uint i = 0; i < sc->_picObjList.size(); i++) {
 		PictureObject *obj = sc->_picObjList[i];
 
 		if (obj && ((obj->_flags & flag1) == flag1) && ((obj->_field_8 & flag2) == flag2)) {
-			res[idx] = new PicAniInfo();
-			obj->getPicAniInfo(res[idx]);
-			idx++;
+			res.push_back(PicAniInfo());
+			obj->getPicAniInfo(res.back());
 		}
 	}
 
@@ -576,21 +543,13 @@ PicAniInfo **GameLoader::savePicAniInfos(Scene *sc, int flag1, int flag2, int *p
 		StaticANIObject *obj = sc->_staticANIObjectList1[i];
 
 		if (obj && ((obj->_flags & flag1) == flag1) && ((obj->_field_8 & flag2) == flag2)) {
-			res[idx] = new PicAniInfo();
-			obj->getPicAniInfo(res[idx]);
-			res[idx]->type &= 0xFFFF;
-			idx++;
+			res.push_back(PicAniInfo());
+			obj->getPicAniInfo(res.back());
+			res.back().type &= 0xFFFF;
 		}
 	}
 
-	*picAniInfoCount = idx;
-
-	debugC(4, kDebugBehavior | kDebugAnimation, "savePicAniInfos: Stored %d infos", idx);
-
-	if (!idx) {
-		free(res);
-		return NULL;
-	}
+	debugC(4, kDebugBehavior | kDebugAnimation, "savePicAniInfos: Stored %d infos", res.size());
 
 	return res;
 }
@@ -614,20 +573,15 @@ void GameLoader::updateSystems(int counterdiff) {
 	}
 }
 
-Sc2::Sc2() {
-	_sceneId = 0;
-	_field_2 = 0;
-	_scene = 0;
-	_motionController = 0;
-	_data1 = 0;
-	_count1 = 0;
-	_defPicAniInfos = 0;
-	_defPicAniInfosCount = 0;
-	_picAniInfos = 0;
-	_picAniInfosCount = 0;
-	_isLoaded = 0;
-	_entranceData = 0;
-	_entranceDataCount = 0;
+Sc2::Sc2() :
+	_sceneId(0),
+	_field_2(0),
+	_scene(nullptr),
+	_isLoaded(false),
+	_motionController(nullptr) {}
+
+Sc2::~Sc2() {
+	delete _motionController;
 }
 
 bool Sc2::load(MfcArchive &file) {
@@ -635,49 +589,35 @@ bool Sc2::load(MfcArchive &file) {
 
 	_sceneId = file.readUint16LE();
 
+	delete _motionController;
 	_motionController = file.readClass<MotionController>();
 
-	_count1 = file.readUint32LE();
-	debugC(4, kDebugLoading, "count1: %d", _count1);
-	if (_count1 > 0) {
-		_data1 = (int32 *)malloc(_count1 * sizeof(int32));
-
-		for (int i = 0; i < _count1; i++) {
-			_data1[i] = file.readUint32LE();
+	const uint count1 = file.readUint32LE();
+	debugC(4, kDebugLoading, "count1: %d", count1);
+	if (count1) {
+		_data1.reserve(count1);
+		for (uint i = 0; i < count1; i++) {
+			_data1.push_back(file.readUint32LE());
 		}
-	} else {
-		_data1 = 0;
 	}
 
-	_defPicAniInfosCount = file.readUint32LE();
-	debugC(4, kDebugLoading, "defPicAniInfos: %d", _defPicAniInfosCount);
-	if (_defPicAniInfosCount > 0) {
-		_defPicAniInfos = (PicAniInfo **)malloc(_defPicAniInfosCount * sizeof(PicAniInfo *));
-
-		for (int i = 0; i < _defPicAniInfosCount; i++) {
-			_defPicAniInfos[i] = new PicAniInfo();
-
-			_defPicAniInfos[i]->load(file);
+	const uint defPicAniInfosCount = file.readUint32LE();
+	debugC(4, kDebugLoading, "defPicAniInfos: %d", defPicAniInfosCount);
+	if (defPicAniInfosCount) {
+		_defPicAniInfos.resize(defPicAniInfosCount);
+		for (uint i = 0; i < defPicAniInfosCount; i++) {
+			_defPicAniInfos[i].load(file);
 		}
-	} else {
-		_defPicAniInfos = 0;
 	}
 
-	_picAniInfos = 0;
-	_picAniInfosCount = 0;
-
-	_entranceDataCount = file.readUint32LE();
-	debugC(4, kDebugLoading, "_entranceData: %d", _entranceDataCount);
-
-	if (_entranceDataCount > 0) {
-		_entranceData = (EntranceInfo **)malloc(_entranceDataCount * sizeof(EntranceInfo *));
+	const uint entranceDataCount = file.readUint32LE();
+	debugC(4, kDebugLoading, "_entranceData: %d", entranceDataCount);
 
-		for (int i = 0; i < _entranceDataCount; i++) {
-			_entranceData[i] = new EntranceInfo();
-			_entranceData[i]->load(file);
+	if (entranceDataCount) {
+		_entranceData.resize(entranceDataCount);
+		for (uint i = 0; i < entranceDataCount; i++) {
+			_entranceData[i].load(file);
 		}
-	} else {
-		_entranceData = 0;
 	}
 
 	if (file.size() - file.pos() > 0)
@@ -714,14 +654,8 @@ const char *getSavegameFile(int saveGameIdx) {
 
 void GameLoader::restoreDefPicAniInfos() {
 	for (uint i = 0; i < _sc2array.size(); i++) {
-		if (_sc2array[i]._picAniInfos) {
-			free(_sc2array[i]._picAniInfos);
-			_sc2array[i]._picAniInfos = 0;
-			_sc2array[i]._picAniInfosCount = 0;
-		}
-
 		if (_sc2array[i]._scene)
-			applyPicAniInfos(_sc2array[i]._scene, _sc2array[i]._defPicAniInfos, _sc2array[i]._defPicAniInfosCount);
+			applyPicAniInfos(_sc2array[i]._scene, _sc2array[i]._defPicAniInfos);
 	}
 }
 
diff --git a/engines/fullpipe/gameloader.h b/engines/fullpipe/gameloader.h
index 10c0912..1279dd8 100644
--- a/engines/fullpipe/gameloader.h
+++ b/engines/fullpipe/gameloader.h
@@ -46,19 +46,17 @@ class Sc2 : public CObject {
 	int16 _sceneId;
 	int16 _field_2;
 	Scene *_scene;
+	/** owned */
 	MotionController *_motionController;
-	int32 *_data1; // FIXME, could be a struct
-	int _count1;
-	PicAniInfo **_defPicAniInfos;
-	int _defPicAniInfosCount;
-	PicAniInfo **_picAniInfos;
-	int _picAniInfosCount;
-	int _isLoaded;
-	EntranceInfo **_entranceData;
-	int _entranceDataCount;
+	Common::Array<int32> _data1; // FIXME, could be a struct
+	PicAniInfoList _defPicAniInfos;
+	PicAniInfoList _picAniInfos;
+	bool _isLoaded;
+	Common::Array<EntranceInfo> _entranceData;
 
  public:
 	Sc2();
+	virtual ~Sc2();
 	virtual bool load(MfcArchive &file);
 };
 
@@ -112,9 +110,9 @@ class GameLoader : public CObject {
 	void updateSystems(int counterdiff);
 
 	int getSceneTagBySceneId(int sceneId, SceneTag **st);
-	void applyPicAniInfos(Scene *sc, PicAniInfo **picAniInfo, int picAniInfoCount);
+	void applyPicAniInfos(Scene *sc, const PicAniInfoList &picAniInfo);
 	void saveScenePicAniInfos(int sceneId);
-	PicAniInfo **savePicAniInfos(Scene *sc, int flag1, int flag2, int *picAniInfoCount);
+	PicAniInfoList savePicAniInfos(Scene *sc, int flag1, int flag2);
 
 	bool readSavegame(const char *fname);
 	bool writeSavegame(Scene *sc, const char *fname);
diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp
index b12edcb..b5614fd 100644
--- a/engines/fullpipe/gfx.cpp
+++ b/engines/fullpipe/gfx.cpp
@@ -189,19 +189,17 @@ void PictureObject::drawAt(int x, int y) {
 		_picture->draw(x, y, 0, 0);
 }
 
-bool PictureObject::setPicAniInfo(PicAniInfo *picAniInfo) {
-	if (!(picAniInfo->type & 2) || (picAniInfo->type & 1)) {
-		error("PictureObject::setPicAniInfo(): Wrong type: %d", picAniInfo->type);
-
-		return false;
+bool PictureObject::setPicAniInfo(const PicAniInfo &picAniInfo) {
+	if (!(picAniInfo.type & 2) || (picAniInfo.type & 1)) {
+		error("PictureObject::setPicAniInfo(): Wrong type: %d", picAniInfo.type);
 	}
 
-	if (picAniInfo->type & 2) {
-		setOXY(picAniInfo->ox, picAniInfo->oy);
-		_priority = picAniInfo->priority;
-		_odelay = picAniInfo->field_8;
-		setFlags(picAniInfo->flags);
-		_field_8 = picAniInfo->field_24;
+	if (picAniInfo.type & 2) {
+		setOXY(picAniInfo.ox, picAniInfo.oy);
+		_priority = picAniInfo.priority;
+		_odelay = picAniInfo.field_8;
+		setFlags(picAniInfo.flags);
+		_field_8 = picAniInfo.field_24;
 
 		return true;
 	}
@@ -332,17 +330,17 @@ void GameObject::renumPictures(Common::Array<PictureObject *> *lst) {
 	free(buf);
 }
 
-bool GameObject::getPicAniInfo(PicAniInfo *info) {
+bool GameObject::getPicAniInfo(PicAniInfo &info) {
 	if (_objtype == kObjTypePictureObject) {
-		info->type = 2;
-		info->objectId = _id;
-		info->sceneId = 0;
-		info->field_8 = _odelay;
-		info->flags = _flags;
-		info->field_24 = _field_8;
-		info->ox = _ox;
-		info->oy = _oy;
-		info->priority = _priority;
+		info.type = 2;
+		info.objectId = _id;
+		info.sceneId = 0;
+		info.field_8 = _odelay;
+		info.flags = _flags;
+		info.field_24 = _field_8;
+		info.ox = _ox;
+		info.oy = _oy;
+		info.priority = _priority;
 
 		return true;
 	}
@@ -350,30 +348,30 @@ bool GameObject::getPicAniInfo(PicAniInfo *info) {
 	if (_objtype == kObjTypeStaticANIObject) {
 		StaticANIObject *ani = static_cast<StaticANIObject *>(this);
 
-		info->type = (ani->_messageQueueId << 16) | 1;
-		info->objectId = ani->_id;
-		info->field_8 = ani->_odelay;
-		info->sceneId = ani->_sceneId;
-		info->flags = ani->_flags;
-		info->field_24 = ani->_field_8;
+		info.type = (ani->_messageQueueId << 16) | 1;
+		info.objectId = ani->_id;
+		info.field_8 = ani->_odelay;
+		info.sceneId = ani->_sceneId;
+		info.flags = ani->_flags;
+		info.field_24 = ani->_field_8;
 		if (ani->_movement) {
-			info->ox = ani->_movement->_ox;
-			info->oy = ani->_movement->_oy;
+			info.ox = ani->_movement->_ox;
+			info.oy = ani->_movement->_oy;
 		} else {
-			info->ox = ani->_ox;
-			info->oy = ani->_oy;
+			info.ox = ani->_ox;
+			info.oy = ani->_oy;
 		}
-		info->priority = ani->_priority;
+		info.priority = ani->_priority;
 
 		if (ani->_statics)
-			info->staticsId = ani->_statics->_staticsId;
+			info.staticsId = ani->_statics->_staticsId;
 
 		if (ani->_movement) {
-			info->movementId = ani->_movement->_id;
-			info->dynamicPhaseIndex = ani->_movement->_currDynamicPhaseIndex;
+			info.movementId = ani->_movement->_id;
+			info.dynamicPhaseIndex = ani->_movement->_currDynamicPhaseIndex;
 		}
 
-		info->someDynamicPhaseIndex = ani->_someDynamicPhaseIndex;
+		info.someDynamicPhaseIndex = ani->_someDynamicPhaseIndex;
 
 		return true;
 	}
@@ -381,49 +379,49 @@ bool GameObject::getPicAniInfo(PicAniInfo *info) {
 	return false;
 }
 
-bool GameObject::setPicAniInfo(PicAniInfo *picAniInfo) {
-	if (!(picAniInfo->type & 3)) {
-		warning("StaticANIObject::setPicAniInfo(): Wrong type: %d", picAniInfo->type);
+bool GameObject::setPicAniInfo(const PicAniInfo &picAniInfo) {
+	if (!(picAniInfo.type & 3)) {
+		warning("StaticANIObject::setPicAniInfo(): Wrong type: %d", picAniInfo.type);
 
 		return false;
 	}
 
-	if (picAniInfo->type & 2) {
-		setOXY(picAniInfo->ox, picAniInfo->oy);
-		_priority = picAniInfo->priority;
-		_odelay = picAniInfo->field_8;
-		setFlags(picAniInfo->flags);
-		_field_8 = picAniInfo->field_24;
+	if (picAniInfo.type & 2) {
+		setOXY(picAniInfo.ox, picAniInfo.oy);
+		_priority = picAniInfo.priority;
+		_odelay = picAniInfo.field_8;
+		setFlags(picAniInfo.flags);
+		_field_8 = picAniInfo.field_24;
 
 		return true;
 	}
 
-	if (picAniInfo->type & 1 && _objtype == kObjTypeStaticANIObject) {
+	if (picAniInfo.type & 1 && _objtype == kObjTypeStaticANIObject) {
 		StaticANIObject *ani = static_cast<StaticANIObject *>(this);
 
-		ani->_messageQueueId = (picAniInfo->type >> 16) & 0xffff;
-		ani->_odelay = picAniInfo->field_8;
-		ani->setFlags(picAniInfo->flags);
-		ani->_field_8 = picAniInfo->field_24;
+		ani->_messageQueueId = (picAniInfo.type >> 16) & 0xffff;
+		ani->_odelay = picAniInfo.field_8;
+		ani->setFlags(picAniInfo.flags);
+		ani->_field_8 = picAniInfo.field_24;
 
-		if (picAniInfo->staticsId) {
-			ani->_statics = ani->getStaticsById(picAniInfo->staticsId);
+		if (picAniInfo.staticsId) {
+			ani->_statics = ani->getStaticsById(picAniInfo.staticsId);
 		} else {
 			ani->_statics = 0;
 		}
 
-		if (picAniInfo->movementId) {
-			ani->_movement = ani->getMovementById(picAniInfo->movementId);
+		if (picAniInfo.movementId) {
+			ani->_movement = ani->getMovementById(picAniInfo.movementId);
 			if (ani->_movement)
-				ani->_movement->setDynamicPhaseIndex(picAniInfo->dynamicPhaseIndex);
+				ani->_movement->setDynamicPhaseIndex(picAniInfo.dynamicPhaseIndex);
 		} else {
 			ani->_movement = 0;
 		}
 
-		ani->setOXY(picAniInfo->ox, picAniInfo->oy);
-		ani->_priority = picAniInfo->priority;
+		ani->setOXY(picAniInfo.ox, picAniInfo.oy);
+		ani->_priority = picAniInfo.priority;
 
-		ani->setSomeDynamicPhaseIndex(picAniInfo->someDynamicPhaseIndex);
+		ani->setSomeDynamicPhaseIndex(picAniInfo.someDynamicPhaseIndex);
 
 		return true;
 	}
diff --git a/engines/fullpipe/gfx.h b/engines/fullpipe/gfx.h
index eb8d03f..af3ce8a 100644
--- a/engines/fullpipe/gfx.h
+++ b/engines/fullpipe/gfx.h
@@ -163,8 +163,8 @@ class GameObject : public CObject {
 	void clearFlags() { _flags = 0; }
 	Common::String getName() { return _objectName; }
 
-	bool getPicAniInfo(PicAniInfo *info);
-	bool setPicAniInfo(PicAniInfo *info);
+	bool getPicAniInfo(PicAniInfo &info);
+	bool setPicAniInfo(const PicAniInfo &info);
 };
 
 class PictureObject : public GameObject {
@@ -187,7 +187,7 @@ class PictureObject : public GameObject {
 	void draw();
 	void drawAt(int x, int y);
 
-	bool setPicAniInfo(PicAniInfo *picAniInfo);
+	bool setPicAniInfo(const PicAniInfo &picAniInfo);
 	bool isPointInside(int x, int y);
 	bool isPixelHitAtPos(int x, int y);
 	void setOXY2();
diff --git a/engines/fullpipe/interaction.cpp b/engines/fullpipe/interaction.cpp
index b15ae80..89e3174 100644
--- a/engines/fullpipe/interaction.cpp
+++ b/engines/fullpipe/interaction.cpp
@@ -129,7 +129,7 @@ bool InteractionController::handleInteraction(StaticANIObject *subj, GameObject
 
 			PicAniInfo aniInfo;
 
-			obj->getPicAniInfo(&aniInfo);
+			obj->getPicAniInfo(aniInfo);
 
 			if (cinter->_staticsId1 && obj->_objtype == kObjTypeStaticANIObject) {
 				StaticANIObject *ani = static_cast<StaticANIObject *>(obj);
@@ -139,7 +139,7 @@ bool InteractionController::handleInteraction(StaticANIObject *subj, GameObject
 			int xpos = cinter->_xOffs + obj->_ox;
 			int ypos = cinter->_yOffs + obj->_oy;
 
-			obj->setPicAniInfo(&aniInfo);
+			obj->setPicAniInfo(aniInfo);
 
 			if (abs(xpos - subj->_ox) > 1 || abs(ypos - subj->_oy) > 1) {
 				debugC(0, kDebugPathfinding, "Calling makeQueue() at [%d, %d]", xpos, ypos);
@@ -298,7 +298,7 @@ LABEL_38:
 		bool someFlag = false;
 		PicAniInfo aniInfo;
 
-		obj->getPicAniInfo(&aniInfo);
+		obj->getPicAniInfo(aniInfo);
 
 		if (obj->_objtype == kObjTypeStaticANIObject && inter->_staticsId1) {
 			StaticANIObject *ani = static_cast<StaticANIObject *>(obj);
@@ -310,7 +310,7 @@ LABEL_38:
 		int xpos = inter->_xOffs + obj->_ox;
 		int ypos = inter->_yOffs + obj->_oy;
 
-		obj->setPicAniInfo(&aniInfo);
+		obj->setPicAniInfo(aniInfo);
 
 		if (abs(xpos - subj->_ox) > 1 || abs(ypos - subj->_oy) > 1
 				|| (inter->_staticsId2 != 0 && (subj->_statics == 0 || subj->_statics->_staticsId != inter->_staticsId2))) {
diff --git a/engines/fullpipe/messagehandlers.cpp b/engines/fullpipe/messagehandlers.cpp
index d5f0e0d..55edae7 100644
--- a/engines/fullpipe/messagehandlers.cpp
+++ b/engines/fullpipe/messagehandlers.cpp
@@ -204,9 +204,9 @@ int global_messageHandler1(ExCommand *cmd) {
 			case '8':
 				{
 					int num = 32;
-					for (int i = 0; i < g_fp->_gameLoader->_sc2array[num]._picAniInfosCount; i++) {
+					for (uint i = 0; i < g_fp->_gameLoader->_sc2array[num]._picAniInfos.size(); i++) {
 						debug("pic %d, %d:", num, i);
-						g_fp->_gameLoader->_sc2array[num]._picAniInfos[i]->print();
+						g_fp->_gameLoader->_sc2array[num]._picAniInfos[i].print();
 					}
 				}
 				break;
diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp
index 564d5ea..f07fb9a 100644
--- a/engines/fullpipe/modal.cpp
+++ b/engines/fullpipe/modal.cpp
@@ -2156,10 +2156,10 @@ bool ModalSaveGame::getFileInfo(int slot, FileInfo *fileinfo) {
 
 	Fullpipe::parseSavegameHeader(header, desc);
 
-	snprintf(res, 17, "%s %s", desc.getSaveDate().c_str(), desc.getSaveTime().c_str());
+	snprintf(res, sizeof(res), "%s %s", desc.getSaveDate().c_str(), desc.getSaveTime().c_str());
 
 	for (int i = 0; i < 16; i++) {
-		switch(res[i]) {
+		switch (res[i]) {
 		case '.':
 			fileinfo->date[i] = 11;
 			break;
diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp
index 5a106ed..9963776 100644
--- a/engines/fullpipe/motion.cpp
+++ b/engines/fullpipe/motion.cpp
@@ -116,7 +116,7 @@ bool MctlCompound::load(MfcArchive &file) {
 		debugC(6, kDebugLoading, "CompoundArray[%d]", i);
 		MctlItem *obj = new MctlItem();
 
-		obj->_motionControllerObj = file.readClass<MotionController>();
+		obj->_motionControllerObj.reset(file.readClass<MotionController>());
 
 		int count1 = file.readUint32LE();
 
@@ -132,7 +132,7 @@ bool MctlCompound::load(MfcArchive &file) {
 		obj->_field_24 = file.readUint32LE();
 
 		debugC(6, kDebugLoading, "graphReact");
-		obj->_movGraphReactObj = file.readClass<MovGraphReact>();
+		obj->_movGraphReactObj.reset(file.readClass<MovGraphReact>());
 
 		_motionControllers.push_back(obj);
 	}
@@ -166,19 +166,14 @@ void MctlCompound::initMctlGraph() {
 		if (_motionControllers[i]->_motionControllerObj->_objtype != kObjTypeMovGraph)
 			continue;
 
-		MovGraph *gr = static_cast<MovGraph *>(_motionControllers[i]->_motionControllerObj);
+		MovGraph *gr = static_cast<MovGraph *>(_motionControllers[i]->_motionControllerObj.get());
 
 		MctlGraph *newgr = new MctlGraph();
 
 		newgr->_links = gr->_links;
 		newgr->_nodes = gr->_nodes;
 
-		gr->_links.clear();
-		gr->_nodes.clear();
-
-		delete gr;
-
-		_motionControllers[i]->_motionControllerObj = newgr;
+		_motionControllers[i]->_motionControllerObj.reset(newgr);
 	}
 }
 
@@ -326,11 +321,6 @@ MessageQueue *MctlCompound::makeQueue(StaticANIObject *subj, int xpos, int ypos,
 	return mq;
 }
 
-MctlItem::~MctlItem() {
-	delete _movGraphReactObj;
-	delete _motionControllerObj;
-}
-
 MctlLadder::MctlLadder() {
 	_width = 0;
 	_ladderX = 0;
@@ -490,7 +480,7 @@ MessageQueue *MctlLadder::makeQueue(StaticANIObject *ani, int xpos, int ypos, in
 	Common::Point point;
 
 	if (ani->_movement) {
-		ani->getPicAniInfo(&picinfo);
+		ani->getPicAniInfo(picinfo);
 
 		int ox = ani->_ox;
 		int oy = ani->_oy;
@@ -502,7 +492,7 @@ MessageQueue *MctlLadder::makeQueue(StaticANIObject *ani, int xpos, int ypos, in
 
 		mq = makeQueue(ani, normx, normy, fuzzyMatch, staticsId);
 
-		ani->setPicAniInfo(&picinfo);
+		ani->setPicAniInfo(picinfo);
 
 		return mq;
 	}
@@ -588,7 +578,7 @@ MessageQueue *MctlLadder::makeQueue(StaticANIObject *ani, int xpos, int ypos, in
 		nx += point.x;
 		ny += point.y;
 
-		ani->getPicAniInfo(&picinfo);
+		ani->getPicAniInfo(picinfo);
 
 		ani->_statics = ani->getStaticsById(_ladmovements[pos]->staticIds[0]);
 		ani->_movement = 0;
@@ -600,7 +590,7 @@ MessageQueue *MctlLadder::makeQueue(StaticANIObject *ani, int xpos, int ypos, in
 
 		delete newmq;
 
-		ani->setPicAniInfo(&picinfo);
+		ani->setPicAniInfo(picinfo);
 
 		return mq;
 	}
@@ -701,7 +691,7 @@ MctlConnectionPoint *MctlCompound::findClosestConnectionPoint(int ox, int oy, in
 void MctlCompound::replaceNodeX(int from, int to) {
 	for (uint i = 0; i < _motionControllers.size(); i++) {
 		if (_motionControllers[i]->_motionControllerObj->_objtype == kObjTypeMovGraph) {
-			MovGraph *gr = static_cast<MovGraph *>(_motionControllers[i]->_motionControllerObj);
+			MovGraph *gr = static_cast<MovGraph *>(_motionControllers[i]->_motionControllerObj.get());
 
 			for (MovGraph::NodeList::iterator n = gr->_nodes.begin(); n != gr->_nodes.end(); ++n) {
 				MovGraphNode *node = static_cast<MovGraphNode *>(*n);
@@ -721,12 +711,6 @@ MctlConnectionPoint::MctlConnectionPoint() {
 	_mctlflags = 0;
 	_mctlstatic = 0;
 	_mctlmirror = 0;
-	_messageQueueObj = 0;
-	_motionControllerObj = 0;
-}
-
-MctlConnectionPoint::~MctlConnectionPoint() {
-	delete _messageQueueObj;
 }
 
 MctlMQ::MctlMQ(MctlMQ *src) {
@@ -755,6 +739,10 @@ void MctlMQ::clear() {
 	flags = 0;
 }
 
+MctlItem::~MctlItem() {
+	Common::for_each(_connectionPoints.begin(), _connectionPoints.end(), Common::DefaultDeleter<MctlConnectionPoint>());
+}
+
 bool MctlCompoundArray::load(MfcArchive &file) {
 	debugC(5, kDebugLoading, "MctlCompoundArray::load()");
 
@@ -1089,7 +1077,7 @@ MessageQueue *MovGraph::makeQueue(StaticANIObject *subj, int xpos, int ypos, int
 
 	Common::Array<MovItem *> *movitem = getPaths(subj, xpos, ypos, fuzzyMatch, &ss);
 
-	subj->getPicAniInfo(&picAniInfo);
+	subj->getPicAniInfo(picAniInfo);
 
 	if (movitem) {
 		MovArr *goal = _callback1(subj, movitem, ss);
@@ -1130,7 +1118,7 @@ MessageQueue *MovGraph::makeQueue(StaticANIObject *subj, int xpos, int ypos, int
 				arridx++;
 
 				if (arridx >= _items[idx].count) {
-					subj->setPicAniInfo(&picAniInfo);
+					subj->setPicAniInfo(picAniInfo);
 					return 0;
 				}
 			}
@@ -1150,13 +1138,13 @@ MessageQueue *MovGraph::makeQueue(StaticANIObject *subj, int xpos, int ypos, int
 				ex->_field_3C = 1;
 				mq->addExCommandToEnd(ex);
 			}
-			subj->setPicAniInfo(&picAniInfo);
+			subj->setPicAniInfo(picAniInfo);
 
 			return mq;
 		}
 	}
 
-	subj->setPicAniInfo(&picAniInfo);
+	subj->setPicAniInfo(picAniInfo);
 
 	return 0;
 }
@@ -1166,7 +1154,7 @@ MessageQueue *MovGraph::sub1(StaticANIObject *ani, int x, int y, int stid, int x
 
 	PicAniInfo picinfo;
 
-	ani->getPicAniInfo(&picinfo);
+	ani->getPicAniInfo(picinfo);
 
 	ani->_statics = ani->getStaticsById(stid);
 	ani->_movement = 0;
@@ -1177,7 +1165,7 @@ MessageQueue *MovGraph::sub1(StaticANIObject *ani, int x, int y, int stid, int x
 	Common::Array<MovItem *> *movitems = getPaths(ani, x1, y1, flag1, &rescount);
 
 	if (!movitems) {
-		ani->setPicAniInfo(&picinfo);
+		ani->setPicAniInfo(picinfo);
 
 		return 0;
 	}
@@ -1204,7 +1192,7 @@ MessageQueue *MovGraph::sub1(StaticANIObject *ani, int x, int y, int stid, int x
 		}
 	}
 
-	ani->setPicAniInfo(&picinfo);
+	ani->setPicAniInfo(picinfo);
 
 	return res;
 }
@@ -2162,11 +2150,11 @@ MessageQueue *MctlGraph::startMove(StaticANIObject *ani, int xpos, int ypos, int
 		if (mq->getCount() <= 1 || mq->getExCommandByIndex(0)->_messageKind != 22) {
 			PicAniInfo picAniInfo;
 
-			ani->getPicAniInfo(&picAniInfo);
+			ani->getPicAniInfo(picAniInfo);
 			ani->updateStepPos();
 			MessageQueue *mq1 = makeQueue(ani, xpos, ypos, fuzzyMatch, staticsId);
 
-			ani->setPicAniInfo(&picAniInfo);
+			ani->setPicAniInfo(picAniInfo);
 
 			if (mq1) {
 				delete mq;
@@ -2209,7 +2197,7 @@ MessageQueue *MctlGraph::makeQueue(StaticANIObject *obj, int xpos, int ypos, int
 
 	point.x = 0;
 
-	obj->getPicAniInfo(&picAniInfo);
+	obj->getPicAniInfo(picAniInfo);
 
 	int idxsub;
 
@@ -2260,7 +2248,7 @@ MessageQueue *MctlGraph::makeQueue(StaticANIObject *obj, int xpos, int ypos, int
 		if (staticsId && obj->_statics->_staticsId != staticsId) {
 			int idxwalk = getDirByStatics(idx, staticsId);
 			if (idxwalk == -1) {
-				obj->setPicAniInfo(&picAniInfo);
+				obj->setPicAniInfo(picAniInfo);
 
 				delete mq;
 
@@ -2289,7 +2277,7 @@ MessageQueue *MctlGraph::makeQueue(StaticANIObject *obj, int xpos, int ypos, int
 			mq->addExCommandToEnd(ex);
 		}
 
-		obj->setPicAniInfo(&picAniInfo);
+		obj->setPicAniInfo(picAniInfo);
 
 		return mq;
 	}
@@ -2303,7 +2291,7 @@ MessageQueue *MctlGraph::makeQueue(StaticANIObject *obj, int xpos, int ypos, int
 			linkInfoSource.link = getNearestLink(obj->_ox, obj->_oy);
 
 			if (!linkInfoSource.link) {
-				obj->setPicAniInfo(&picAniInfo);
+				obj->setPicAniInfo(picAniInfo);
 
 				return 0;
 			}
@@ -2316,7 +2304,7 @@ MessageQueue *MctlGraph::makeQueue(StaticANIObject *obj, int xpos, int ypos, int
 		linkInfoDest.link = getHitLink(xpos, ypos, idxsub, fuzzyMatch);
 
 		if (!linkInfoDest.link) {
-			obj->setPicAniInfo(&picAniInfo);
+			obj->setPicAniInfo(picAniInfo);
 
 			return 0;
 		}
@@ -2424,7 +2412,7 @@ MessageQueue *MctlGraph::makeQueue(StaticANIObject *obj, int xpos, int ypos, int
 		mq = 0;
 	}
 
-	obj->setPicAniInfo(&picAniInfo);
+	obj->setPicAniInfo(picAniInfo);
 
 	return mq;
 }
diff --git a/engines/fullpipe/motion.h b/engines/fullpipe/motion.h
index c86c161..2a1450e 100644
--- a/engines/fullpipe/motion.h
+++ b/engines/fullpipe/motion.h
@@ -84,15 +84,15 @@ public:
 
 class MctlItem : public CObject {
 public:
-	MotionController *_motionControllerObj;
-	MovGraphReact *_movGraphReactObj;
+	Common::ScopedPtr<MotionController> _motionControllerObj;
+	Common::ScopedPtr<MovGraphReact> _movGraphReactObj;
 	Common::Array<MctlConnectionPoint *> _connectionPoints;
 	int _field_20;
 	int _field_24;
 	int _field_28;
 
 public:
-	MctlItem() : _movGraphReactObj(0), _motionControllerObj(0), _field_20(0), _field_24(0), _field_28(0) {}
+	MctlItem() : _field_20(0), _field_24(0), _field_28(0) {}
 	~MctlItem();
 };
 
@@ -120,7 +120,7 @@ public:
 	void replaceNodeX(int from, int to);
 
 	uint getMotionControllerCount() { return _motionControllers.size(); }
-	MotionController *getMotionController(int num) { return _motionControllers[num]->_motionControllerObj; }
+	MotionController *getMotionController(int num) { return _motionControllers[num]->_motionControllerObj.get(); }
 };
 
 struct MctlLadderMovementVars {
@@ -414,11 +414,10 @@ public:
 	int _mctlflags;
 	int _mctlstatic;
 	int16 _mctlmirror;
-	MessageQueue *_messageQueueObj;
+	Common::ScopedPtr<MessageQueue> _messageQueueObj;
 	int _motionControllerObj;
 
 	MctlConnectionPoint();
-	~MctlConnectionPoint();
 };
 
 } // End of namespace Fullpipe
diff --git a/engines/fullpipe/objects.h b/engines/fullpipe/objects.h
index 7501f2bd..6048580 100644
--- a/engines/fullpipe/objects.h
+++ b/engines/fullpipe/objects.h
@@ -66,6 +66,7 @@ struct PicAniInfo {
 
 	PicAniInfo() { memset(this, 0, sizeof(PicAniInfo)); }
 };
+typedef Common::Array<PicAniInfo> PicAniInfoList;
 
 union VarValue {
 	float floatValue;
diff --git a/engines/fullpipe/scenes.cpp b/engines/fullpipe/scenes.cpp
index 034d2a7..f4f9308 100644
--- a/engines/fullpipe/scenes.cpp
+++ b/engines/fullpipe/scenes.cpp
@@ -530,11 +530,11 @@ void FullpipeEngine::sceneAutoScrolling() {
 	}
 }
 
-bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
+bool FullpipeEngine::sceneSwitcher(const EntranceInfo &entrance) {
 	GameVar *sceneVar;
 	Common::Point sceneDim;
 
-	Scene *scene = accessScene(entrance->_sceneId);
+	Scene *scene = accessScene(entrance._sceneId);
 
 	if (!scene)
 		return 0;
@@ -563,7 +563,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
 	_updateFlag = true;
 	_flgCanOpenMap = true;
 
-	if (entrance->_sceneId == SC_DBGMENU) {
+	if (entrance._sceneId == SC_DBGMENU) {
 		_inventoryScene = 0;
 	} else {
 		_gameLoader->loadScene(SC_INV);
@@ -594,7 +594,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
 	_aniMan->setOXY(0, 0);
 
 	_aniMan2 = _aniMan;
-	MctlCompound *cmp = getSc2MctlCompoundBySceneId(entrance->_sceneId);
+	MctlCompound *cmp = getSc2MctlCompoundBySceneId(entrance._sceneId);
 	cmp->initMctlGraph();
 	cmp->attachObject(_aniMan);
 	cmp->activate();
@@ -612,7 +612,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
 	removeMessageHandler(2, -1);
 	_updateScreenCallback = 0;
 
-	switch (entrance->_sceneId) {
+	switch (entrance._sceneId) {
 	case SC_INTRO1:
 		sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_INTRO1");
 		scene->preloadMovements(sceneVar);
@@ -639,7 +639,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
 		scene01_fixEntrance();
 		sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_1");
 		scene->preloadMovements(sceneVar);
-		scene01_initScene(scene, entrance->_field_4);
+		scene01_initScene(scene, entrance._field_4);
 		_behaviorManager->initBehavior(scene, sceneVar);
 		scene->initObjectCursors("SC_1");
 		setSceneMusicParameters(sceneVar);
@@ -854,7 +854,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
 
 			scene18_initScene2(g_fp->_scene3);
 			scene18_preload();
-			scene19_setMovements(g_fp->_scene3, entrance->_field_4);
+			scene19_setMovements(g_fp->_scene3, entrance._field_4);
 
 			g_vars->scene18_inScene18p1 = true;
 		}
@@ -938,12 +938,12 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
 	case SC_25:
 		sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_25");
 		scene->preloadMovements(sceneVar);
-		scene25_initScene(scene, entrance->_field_4);
+		scene25_initScene(scene, entrance._field_4);
 		_behaviorManager->initBehavior(scene, sceneVar);
 		scene->initObjectCursors("SC_25");
 		setSceneMusicParameters(sceneVar);
 		addMessageHandler(sceneHandler25, 2);
-		scene25_setupWater(scene, entrance->_field_4);
+		scene25_setupWater(scene, entrance._field_4);
 		_updateCursorCallback = scene25_updateCursor;
 		break;
 
@@ -995,7 +995,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
 	case SC_30:
 		sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_30");
 		scene->preloadMovements(sceneVar);
-		scene30_initScene(scene, entrance->_field_4);
+		scene30_initScene(scene, entrance._field_4);
 		_behaviorManager->initBehavior(scene, sceneVar);
 		scene->initObjectCursors("SC_30");
 		setSceneMusicParameters(sceneVar);
@@ -1115,7 +1115,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
 		break;
 
 	default:
-		error("Unknown scene %d", entrance->_sceneId);
+		error("Unknown scene %d", entrance._sceneId);
 		break;
 	}
 
diff --git a/engines/fullpipe/scenes/scene04.cpp b/engines/fullpipe/scenes/scene04.cpp
index c899e46..0d27313 100644
--- a/engines/fullpipe/scenes/scene04.cpp
+++ b/engines/fullpipe/scenes/scene04.cpp
@@ -97,8 +97,8 @@ void scene04_initScene(Scene *sc) {
 			for (uint i = 0; i < kozsize; i++) {
 				kozmov->setDynamicPhaseIndex(i);
 
-				if (kozmov->_framePosOffsets) {
-					g_vars->scene04_jumpingKozyawki[i] = *kozmov->_framePosOffsets[kozmov->_currDynamicPhaseIndex];
+				if (kozmov->_framePosOffsets.size()) {
+					g_vars->scene04_jumpingKozyawki[i] = kozmov->_framePosOffsets[kozmov->_currDynamicPhaseIndex];
 				} else {
 					kozmov->_somePoint.x = 0;
 					kozmov->_somePoint.y = 0;
@@ -114,8 +114,8 @@ void scene04_initScene(Scene *sc) {
 			for (uint i = 0; i < kozsize; i++) {
 				kozmov->setDynamicPhaseIndex(i);
 
-				if (kozmov->_framePosOffsets) {
-					g_vars->scene04_jumpRotateKozyawki[i] = *kozmov->_framePosOffsets[kozmov->_currDynamicPhaseIndex];
+				if (kozmov->_framePosOffsets.size()) {
+					g_vars->scene04_jumpRotateKozyawki[i] = kozmov->_framePosOffsets[kozmov->_currDynamicPhaseIndex];
 				} else {
 					kozmov->_somePoint.x = 0;
 					kozmov->_somePoint.y = 0;
@@ -747,8 +747,8 @@ void sceneHandler04_kozMove(Movement *mov, int from, int to, Common::Point *poin
 		mov->setDynamicPhaseIndex(i);
 
 		Common::Point *p;
-		if (mov->_framePosOffsets) {
-			p = mov->_framePosOffsets[mov->_currDynamicPhaseIndex];
+		if (mov->_framePosOffsets.size()) {
+			p = &mov->_framePosOffsets[mov->_currDynamicPhaseIndex];
 		} else {
 			p = &mov->_somePoint;
 			p->x = 0;
diff --git a/engines/fullpipe/scenes/scene09.cpp b/engines/fullpipe/scenes/scene09.cpp
index 169d06c..eab6cf6 100644
--- a/engines/fullpipe/scenes/scene09.cpp
+++ b/engines/fullpipe/scenes/scene09.cpp
@@ -190,14 +190,14 @@ void sceneHandler09_spitterClick() {
 	if (g_vars->scene09_spitter->_flags & 4) {
 		PicAniInfo info;
 
-		g_vars->scene09_spitter->getPicAniInfo(&info);
+		g_vars->scene09_spitter->getPicAniInfo(info);
 		g_vars->scene09_spitter->_messageQueueId = 0;
 		g_vars->scene09_spitter->changeStatics2(ST_PLV_SIT);
 
 		int x = g_vars->scene09_spitter->_ox - 10;
 		int y = g_vars->scene09_spitter->_oy + 145;
 
-		g_vars->scene09_spitter->setPicAniInfo(&info);
+		g_vars->scene09_spitter->setPicAniInfo(info);
 
 		if (ABS(x - g_fp->_aniMan->_ox) > 1 || ABS(y - g_fp->_aniMan->_oy) > 1) {
 			MessageQueue *mq = getCurrSceneSc2MotionController()->startMove(g_fp->_aniMan, x, y, 1, ST_MAN_UP);
diff --git a/engines/fullpipe/scenes/scene18and19.cpp b/engines/fullpipe/scenes/scene18and19.cpp
index 9181bc7..3b6ff07 100644
--- a/engines/fullpipe/scenes/scene18and19.cpp
+++ b/engines/fullpipe/scenes/scene18and19.cpp
@@ -217,9 +217,9 @@ void scene18_initScene1(Scene *sc) {
 	g_vars->scene18_girlJumpY += newy;
 
 	for (uint i = 0; i < g_vars->scene18_swingers.size(); i++) {
-		g_vars->scene18_swingers[i]->ani->getPicAniInfo(&info);
+		g_vars->scene18_swingers[i]->ani->getPicAniInfo(info);
 		sc->addStaticANIObject(g_vars->scene18_swingers[i]->ani, 1);
-		g_vars->scene18_swingers[i]->ani->setPicAniInfo(&info);
+		g_vars->scene18_swingers[i]->ani->setPicAniInfo(info);
 
 		g_vars->scene18_swingers[i]->sx += newx;
 		g_vars->scene18_swingers[i]->sy += newy;
@@ -257,9 +257,9 @@ void scene18_initScene1(Scene *sc) {
 
 	g_fp->playSound(sndid, 1);
 
-	g_vars->scene18_boy->getPicAniInfo(&info);
+	g_vars->scene18_boy->getPicAniInfo(info);
 	sc->addStaticANIObject(g_vars->scene18_boy, 1);
-	g_vars->scene18_boy->setPicAniInfo(&info);
+	g_vars->scene18_boy->setPicAniInfo(info);
 
 	int x, y;
 
@@ -273,9 +273,9 @@ void scene18_initScene1(Scene *sc) {
 
 	g_vars->scene18_boy->setOXY(newx + x, newy + y);
 
-	g_vars->scene18_girl->getPicAniInfo(&info);
+	g_vars->scene18_girl->getPicAniInfo(info);
 	sc->addStaticANIObject(g_vars->scene18_girl, 1);
-	g_vars->scene18_girl->setPicAniInfo(&info);
+	g_vars->scene18_girl->setPicAniInfo(info);
 
 	if (g_vars->scene18_girl->_movement) {
 		x = g_vars->scene18_girl->_movement->_ox;
diff --git a/engines/fullpipe/scenes/scene25.cpp b/engines/fullpipe/scenes/scene25.cpp
index 248049f..6871f37 100644
--- a/engines/fullpipe/scenes/scene25.cpp
+++ b/engines/fullpipe/scenes/scene25.cpp
@@ -161,14 +161,14 @@ void sceneHandler25_enterMan() {
 void sceneHandler25_enterTruba() {
 	PicAniInfo info;
 
-	g_fp->_aniMan->getPicAniInfo(&info);
+	g_fp->_aniMan->getPicAniInfo(info);
 	g_fp->_aniMan->_messageQueueId = 0;
 	g_fp->_aniMan->changeStatics2(g_fp->_aniMan->_statics->_staticsId);
 
 	int x = g_fp->_aniMan->_ox;
 	int y = g_fp->_aniMan->_oy;
 
-	g_fp->_aniMan->setPicAniInfo(&info);
+	g_fp->_aniMan->setPicAniInfo(info);
 
 	int id = g_fp->_aniMan->_statics->_staticsId;
 	int qid = 0;
@@ -196,14 +196,14 @@ void sceneHandler25_saveEntrance(int value) {
 void sceneHandler25_toLadder() {
 	PicAniInfo info;
 
-	g_fp->_aniMan->getPicAniInfo(&info);
+	g_fp->_aniMan->getPicAniInfo(info);
 	g_fp->_aniMan->_messageQueueId = 0;
 	g_fp->_aniMan->changeStatics2(g_fp->_aniMan->_statics->_staticsId);
 
 	int x = g_fp->_aniMan->_ox;
 	int y = g_fp->_aniMan->_oy;
 
-	g_fp->_aniMan->setPicAniInfo(&info);
+	g_fp->_aniMan->setPicAniInfo(info);
 
 	int id = g_fp->_aniMan->_statics->_staticsId;
 	int qid = 0;
@@ -275,14 +275,14 @@ void sceneHandler25_sneeze() {
 void sceneHandler25_rowShovel() {
 	PicAniInfo info;
 
-	g_fp->_aniMan->getPicAniInfo(&info);
+	g_fp->_aniMan->getPicAniInfo(info);
 	g_fp->_aniMan->_messageQueueId = 0;
 	g_fp->_aniMan->changeStatics2(g_fp->_aniMan->_statics->_staticsId);
 
 	int x = g_fp->_aniMan->_ox;
 	int y = g_fp->_aniMan->_oy;
 
-	g_fp->_aniMan->setPicAniInfo(&info);
+	g_fp->_aniMan->setPicAniInfo(info);
 
 	int id = g_fp->_aniMan->_statics->_staticsId;
 	int qid = 0;
@@ -309,14 +309,14 @@ void sceneHandler25_rowShovel() {
 void sceneHandler25_rowHand() {
 	PicAniInfo info;
 
-	g_fp->_aniMan->getPicAniInfo(&info);
+	g_fp->_aniMan->getPicAniInfo(info);
 	g_fp->_aniMan->_messageQueueId = 0;
 	g_fp->_aniMan->changeStatics2(g_fp->_aniMan->_statics->_staticsId);
 
 	int x = g_fp->_aniMan->_ox;
 	int y = g_fp->_aniMan->_oy;
 
-	g_fp->_aniMan->setPicAniInfo(&info);
+	g_fp->_aniMan->setPicAniInfo(info);
 
 	int id = g_fp->_aniMan->_statics->_staticsId;
 	int qid = 0;
@@ -363,14 +363,14 @@ void sceneHandler25_tryWater() {
 void sceneHandler25_tryRow(int obj) {
 	PicAniInfo info;
 
-	g_fp->_aniMan->getPicAniInfo(&info);
+	g_fp->_aniMan->getPicAniInfo(info);
 	g_fp->_aniMan->_messageQueueId = 0;
 	g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT | 0x4000);
 
 	int x = g_fp->_aniMan->_ox;
 	int y = g_fp->_aniMan->_oy;
 
-	g_fp->_aniMan->setPicAniInfo(&info);
+	g_fp->_aniMan->setPicAniInfo(info);
 
 	int qid = 0;
 
diff --git a/engines/fullpipe/stateloader.cpp b/engines/fullpipe/stateloader.cpp
index cc5c904..4041eb1 100644
--- a/engines/fullpipe/stateloader.cpp
+++ b/engines/fullpipe/stateloader.cpp
@@ -109,20 +109,19 @@ bool GameLoader::readSavegame(const char *fname) {
 	debugC(3, kDebugLoading, "Reading %d infos", arrSize);
 
 	for (uint i = 0; i < arrSize; i++) {
-		_sc2array[i]._picAniInfosCount = archive->readUint32LE();
 
-		if (_sc2array[i]._picAniInfosCount)
-			debugC(3, kDebugLoading, "Count %d: %d", i, _sc2array[i]._picAniInfosCount);
+		const uint picAniInfosCount = archive->readUint32LE();
+		if (picAniInfosCount)
+			debugC(3, kDebugLoading, "Count %d: %d", i, picAniInfosCount);
 
-		free(_sc2array[i]._picAniInfos);
-		_sc2array[i]._picAniInfos = (PicAniInfo **)malloc(sizeof(PicAniInfo *) * _sc2array[i]._picAniInfosCount);
+		_sc2array[i]._picAniInfos.clear();
+		_sc2array[i]._picAniInfos.resize(picAniInfosCount);
 
-		for (int j = 0; j < _sc2array[i]._picAniInfosCount; j++) {
-			_sc2array[i]._picAniInfos[j] = new PicAniInfo();
-			_sc2array[i]._picAniInfos[j]->load(*archive);
+		for (uint j = 0; j < picAniInfosCount; j++) {
+			_sc2array[i]._picAniInfos[j].load(*archive);
 		}
 
-		_sc2array[i]._isLoaded = 0;
+		_sc2array[i]._isLoaded = false;
 	}
 
 	delete archiveStream;
diff --git a/engines/fullpipe/statesaver.cpp b/engines/fullpipe/statesaver.cpp
index 5eb08fe..d06bd9c 100644
--- a/engines/fullpipe/statesaver.cpp
+++ b/engines/fullpipe/statesaver.cpp
@@ -88,13 +88,13 @@ bool GameLoader::writeSavegame(Scene *sc, const char *fname) {
 	debugC(3, kDebugLoading, "Saving %d infos", _sc2array.size());
 
 	for (uint i = 0; i < _sc2array.size(); i++) {
-		archive->writeUint32LE(_sc2array[i]._picAniInfosCount);
+		archive->writeUint32LE(_sc2array[i]._picAniInfos.size());
 
-		if (_sc2array[i]._picAniInfosCount)
-			debugC(3, kDebugLoading, "Count %d: %d", i, _sc2array[i]._picAniInfosCount);
+		if (_sc2array[i]._picAniInfos.size())
+			debugC(3, kDebugLoading, "Count %d: %d", i, _sc2array[i]._picAniInfos.size());
 
-		for (int j = 0; j < _sc2array[i]._picAniInfosCount; j++) {
-			_sc2array[i]._picAniInfos[j]->save(*archive);
+		for (uint j = 0; j < _sc2array[i]._picAniInfos.size(); j++) {
+			_sc2array[i]._picAniInfos[j].save(*archive);
 		}
 	}
 
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index 994feee..8c2807f 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -1457,7 +1457,6 @@ Movement::Movement() {
 	_m2y = 0;
 	_field_50 = 1;
 	_field_78 = 0;
-	_framePosOffsets = 0;
 	_field_84 = 0;
 	_currDynamicPhase = 0;
 	_field_8C = 0;
@@ -1466,15 +1465,9 @@ Movement::Movement() {
 	_currMovement = 0;
 	_counter = 0;
 	_counterMax = 83;
-
-	_somePoint.x = 0;
-	_somePoint.y = 0;
 }
 
 Movement::~Movement() {
-	for (uint i = 0; i < _dynamicPhases.size(); i++)
-		delete _framePosOffsets[i];
-
 	if (!_currMovement) {
 		if (_updateFlag1) {
 			_dynamicPhases[0]->freePixelData();
@@ -1487,8 +1480,6 @@ Movement::~Movement() {
 
 		_dynamicPhases.clear();
 	}
-
-	free(_framePosOffsets);
 }
 
 Movement::Movement(Movement *src, StaticANIObject *ani) {
@@ -1503,7 +1494,6 @@ Movement::Movement(Movement *src, StaticANIObject *ani) {
 	_m2y = 0;
 
 	_field_78 = 0;
-	_framePosOffsets = 0;
 	_field_84 = 0;
 	_currDynamicPhase = 0;
 	_field_8C = 0;
@@ -1540,7 +1530,6 @@ Movement::Movement(Movement *src, int *oldIdxs, int newSize, StaticANIObject *an
 	_counterMax = 0;
 
 	_field_78 = 0;
-	_framePosOffsets = 0;
 	_field_84 = 0;
 	_currDynamicPhase = 0;
 	_field_8C = 0;
@@ -1571,25 +1560,19 @@ Movement::Movement(Movement *src, int *oldIdxs, int newSize, StaticANIObject *an
 		return;
 	}
 
-	_framePosOffsets = (Common::Point **)calloc(newSize, sizeof(Common::Point *));
-
-	for (int i = 0; i < newSize; i++)
-		_framePosOffsets[i] = new Common::Point();
+	_framePosOffsets.resize(newSize);
 
 	if (oldIdxs) {
 		for (int i = 0; i < newSize - 1; i++, oldIdxs++) {
 			if (oldIdxs[i] == -1) {
 				_dynamicPhases.push_back(src->_staticsObj1);
-
-				_framePosOffsets[i]->x = 0;
-				_framePosOffsets[i]->y = 0;
 			} else {
 				src->setDynamicPhaseIndex(oldIdxs[i]);
 
 				_dynamicPhases.push_back(src->_currDynamicPhase);
 
-				_framePosOffsets[i]->x = src->_framePosOffsets[oldIdxs[i]]->x;
-				_framePosOffsets[i]->y = src->_framePosOffsets[oldIdxs[i]]->y;
+				_framePosOffsets[i].x = src->_framePosOffsets[oldIdxs[i]].x;
+				_framePosOffsets[i].y = src->_framePosOffsets[oldIdxs[i]].y;
 			}
 		}
 		_staticsObj1 = dynamic_cast<Statics *>(_dynamicPhases.front());
@@ -1601,8 +1584,8 @@ Movement::Movement(Movement *src, int *oldIdxs, int newSize, StaticANIObject *an
 			if (i < newSize - 1)
 				_dynamicPhases.push_back(new DynamicPhase(*src->_currDynamicPhase, 0));
 
-			_framePosOffsets[i]->x = src->_framePosOffsets[i]->x;
-			_framePosOffsets[i]->y = src->_framePosOffsets[i]->y;
+			_framePosOffsets[i].x = src->_framePosOffsets[i].x;
+			_framePosOffsets[i].y = src->_framePosOffsets[i].y;
 		}
 
 		_staticsObj1 = ani->getStaticsById(src->_staticsObj1->_staticsId);
@@ -1632,10 +1615,7 @@ bool Movement::load(MfcArchive &file, StaticANIObject *ani) {
 
 	debugC(7, kDebugLoading, "dynCount: %d  _id: %d", dynCount, _id);
 	if (dynCount != 0xffff || _id == MV_MAN_TURN_LU) {
-		_framePosOffsets = (Common::Point **)calloc(dynCount + 2, sizeof(Common::Point *));
-
-		for (int i = 0; i < dynCount + 2; i++)
-			_framePosOffsets[i] = new Common::Point();
+		_framePosOffsets.resize(dynCount + 2);
 
 		for (int i = 0; i < dynCount; i++) {
 			DynamicPhase *ph = new DynamicPhase();
@@ -1643,8 +1623,8 @@ bool Movement::load(MfcArchive &file, StaticANIObject *ani) {
 
 			_dynamicPhases.push_back(ph);
 
-			_framePosOffsets[i]->x = ph->_x;
-			_framePosOffsets[i]->y = ph->_y;
+			_framePosOffsets[i].x = ph->_x;
+			_framePosOffsets[i].y = ph->_y;
 		}
 
 		int staticsid = file.readUint16LE();
@@ -1674,8 +1654,8 @@ bool Movement::load(MfcArchive &file, StaticANIObject *ani) {
 		if (_staticsObj2) {
 			_dynamicPhases.push_back(_staticsObj2);
 
-			_framePosOffsets[_dynamicPhases.size() - 1]->x = _m2x;
-			_framePosOffsets[_dynamicPhases.size() - 1]->y = _m2y;
+			_framePosOffsets[_dynamicPhases.size() - 1].x = _m2x;
+			_framePosOffsets[_dynamicPhases.size() - 1].y = _m2y;
 		}
 
 	} else {
@@ -1909,8 +1889,8 @@ void Movement::removeFirstPhase() {
 			_dynamicPhases.remove_at(0);
 
 			for (uint i = 0; i < _dynamicPhases.size(); i++) {
-				_framePosOffsets[i]->x = _framePosOffsets[i + 1]->x;
-				_framePosOffsets[i]->y = _framePosOffsets[i + 1]->y;
+				_framePosOffsets[i].x = _framePosOffsets[i + 1].x;
+				_framePosOffsets[i].y = _framePosOffsets[i + 1].y;
 			}
 		}
 		_currDynamicPhaseIndex--;
@@ -1967,9 +1947,9 @@ bool Movement::gotoNextFrame(void (*callback1)(int, Common::Point *point, int, i
 			_currDynamicPhaseIndex = 0;
 			result = false;
 		}
-		if (_currMovement->_framePosOffsets) {
+		if (_currMovement->_framePosOffsets.size()) {
 			if (callback1) {
-				point = *_currMovement->_framePosOffsets[_currDynamicPhaseIndex];
+				point = _currMovement->_framePosOffsets[_currDynamicPhaseIndex];
 				callback1(_currDynamicPhaseIndex, &point, _ox, _oy);
 
 				_ox += deltax - point.x;
@@ -1981,8 +1961,8 @@ bool Movement::gotoNextFrame(void (*callback1)(int, Common::Point *point, int, i
 					_ox += deltax;
 					deltax = _currMovement->getDimensionsOfPhase(oldDynIndex).x;
 
-					_ox += _currMovement->_framePosOffsets[oldDynIndex]->x;
-					_oy -= _currMovement->_framePosOffsets[oldDynIndex]->y;
+					_ox += _currMovement->_framePosOffsets[oldDynIndex].x;
+					_oy -= _currMovement->_framePosOffsets[oldDynIndex].y;
 					oldDynIndex--;
 
 					_ox -= _currMovement->getDimensionsOfPhase(oldDynIndex).x;
@@ -1991,8 +1971,8 @@ bool Movement::gotoNextFrame(void (*callback1)(int, Common::Point *point, int, i
 				for (int i = oldDynIndex + 1; i <= _currDynamicPhaseIndex; i++) {
 					_ox += deltax;
 					deltax = _currMovement->getDimensionsOfPhase(i).x;
-					_ox -= _currMovement->_framePosOffsets[i]->x;
-					_oy += _currMovement->_framePosOffsets[i]->y;
+					_ox -= _currMovement->_framePosOffsets[i].x;
+					_oy += _currMovement->_framePosOffsets[i].y;
 					_ox -= _currMovement->getDimensionsOfPhase(i).x;
 				}
 			}
@@ -2007,23 +1987,23 @@ bool Movement::gotoNextFrame(void (*callback1)(int, Common::Point *point, int, i
 			result = false;
 		}
 
-		if (_framePosOffsets) {
+		if (_framePosOffsets.size()) {
 			if (callback1) {
-				point.x = _framePosOffsets[_currDynamicPhaseIndex]->x;
-				point.y = _framePosOffsets[_currDynamicPhaseIndex]->y;
+				point.x = _framePosOffsets[_currDynamicPhaseIndex].x;
+				point.y = _framePosOffsets[_currDynamicPhaseIndex].y;
 
 				callback1(_currDynamicPhaseIndex, &point, _ox, _oy);
 				_ox += point.x;
 				_oy += point.y;
 			} else if (oldDynIndex >= _currDynamicPhaseIndex) {
 				for (int i = oldDynIndex; i > _currDynamicPhaseIndex; i--) {
-					_ox -= _framePosOffsets[i]->x;
-					_oy -= _framePosOffsets[i]->y;
+					_ox -= _framePosOffsets[i].x;
+					_oy -= _framePosOffsets[i].y;
 				}
 			} else {
 				for (int i = oldDynIndex + 1; i <= _currDynamicPhaseIndex; i++) {
-					_ox += _framePosOffsets[i]->x;
-					_oy += _framePosOffsets[i]->y;
+					_ox += _framePosOffsets[i].x;
+					_oy += _framePosOffsets[i].y;
 				}
 			}
 		}
@@ -2053,10 +2033,10 @@ bool Movement::gotoPrevFrame() {
 	_oy -= point.y;
 
 	if (_currMovement) {
-		if (_currMovement->_framePosOffsets) {
+		if (_currMovement->_framePosOffsets.size()) {
 			_ox += _currMovement->getDimensionsOfPhase(_currDynamicPhaseIndex).x;
-			_ox += _currMovement->_framePosOffsets[_currDynamicPhaseIndex]->x;
-			_oy -= _currMovement->_framePosOffsets[_currDynamicPhaseIndex]->y;
+			_ox += _currMovement->_framePosOffsets[_currDynamicPhaseIndex].x;
+			_oy -= _currMovement->_framePosOffsets[_currDynamicPhaseIndex].y;
 		}
 
 		_currDynamicPhaseIndex--;
@@ -2065,9 +2045,9 @@ bool Movement::gotoPrevFrame() {
 
 		_ox -= _currMovement->getDimensionsOfPhase(_currDynamicPhaseIndex).x;
 	} else {
-		if (_framePosOffsets) {
-			_ox -= _framePosOffsets[_currDynamicPhaseIndex]->x;
-			_oy -= _framePosOffsets[_currDynamicPhaseIndex]->y;
+		if (_framePosOffsets.size()) {
+			_ox -= _framePosOffsets[_currDynamicPhaseIndex].x;
+			_oy -= _framePosOffsets[_currDynamicPhaseIndex].y;
 		}
 
 		_currDynamicPhaseIndex--;
diff --git a/engines/fullpipe/statics.h b/engines/fullpipe/statics.h
index 462a76c..841c158 100644
--- a/engines/fullpipe/statics.h
+++ b/engines/fullpipe/statics.h
@@ -122,7 +122,7 @@ class Movement : public GameObject {
 	int _counter;
 	Common::Array<DynamicPhase *> _dynamicPhases;
 	int _field_78;
-	Common::Point **_framePosOffsets;
+	Common::Array<Common::Point> _framePosOffsets;
 	Movement *_currMovement;
 	int _field_84;
 	DynamicPhase *_currDynamicPhase;


Commit: d2249a1bed00bae4a7e0c78d66df0a04f927b673
    https://github.com/scummvm/scummvm/commit/d2249a1bed00bae4a7e0c78d66df0a04f927b673
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Annotate ownership rule of MfcArchive::readClass

Changed paths:
    engines/fullpipe/utils.h


diff --git a/engines/fullpipe/utils.h b/engines/fullpipe/utils.h
index 8966ceb..6ffafc5 100644
--- a/engines/fullpipe/utils.h
+++ b/engines/fullpipe/utils.h
@@ -59,6 +59,7 @@ public:
 	double readDouble();
 	CObject *parseClass(bool *isCopyReturned);
 
+	/** ownership of returned object is passed to caller */
 	template <typename T>
 	T *readClass() {
 		CObject *obj = readBaseClass();


Commit: 6a13592633a6a4cf935409edd1c5504ef7dfa75e
    https://github.com/scummvm/scummvm/commit/6a13592633a6a4cf935409edd1c5504ef7dfa75e
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Disable some unused code paths

Changed paths:
    engines/fullpipe/anihandler.cpp


diff --git a/engines/fullpipe/anihandler.cpp b/engines/fullpipe/anihandler.cpp
index b7489b7..b847986 100644
--- a/engines/fullpipe/anihandler.cpp
+++ b/engines/fullpipe/anihandler.cpp
@@ -33,17 +33,21 @@ void AniHandler::detachAllObjects() {
 	_items.clear();
 }
 
-MessageQueue *AniHandler::makeQueue(StaticANIObject *ani, int staticsIndex, int staticsId, int *resStatId, Common::Point **pointArr) {
-	debugC(4, kDebugPathfinding, "AniHandler::makeQueue(*%d, %d, %d, res, point)", ani->_id, staticsIndex, staticsId);
+MessageQueue *AniHandler::makeQueue(StaticANIObject *ani, int staticsIndex, int, int *, Common::Point **) {
+	debugC(4, kDebugPathfinding, "AniHandler::makeQueue(*%d, %d, id, res, point)", ani->_id, staticsIndex);
 
 	int idx = getIndex(ani->_id);
 
 	if (idx == -1)
 		return 0;
 
+#if 0
 	int stid = staticsId;
 
 	if (!staticsId) {
+#else
+	int stid;
+#endif
 		if (ani->_movement) {
 			stid = ani->_movement->_staticsObj2->_staticsId;
 		} else {
@@ -52,7 +56,9 @@ MessageQueue *AniHandler::makeQueue(StaticANIObject *ani, int staticsIndex, int
 
 			stid = ani->_statics->_staticsId;
 		}
+#if 0
 	}
+#endif
 
 	if (stid == staticsIndex)
 		return new MessageQueue(g_fp->_globalMessageQueueList->compact());
@@ -79,6 +85,7 @@ MessageQueue *AniHandler::makeQueue(StaticANIObject *ani, int staticsIndex, int
 
 		point = _items[idx].subItems[subidx].movement->calcSomeXY(0, -1);
 
+#if 0
 		if (pointArr) {
 			int sz;
 
@@ -91,8 +98,11 @@ MessageQueue *AniHandler::makeQueue(StaticANIObject *ani, int staticsIndex, int
 
 			ex->_messageNum = _items[idx].subItems[subidx].movement->_id;
 		} else {
+#endif
 			ex = new ExCommand(ani->_id, 1, _items[idx].subItems[subidx].movement->_id, 0, 0, 0, 1, 0, 0, 0);
+#if 0
 		}
+#endif
 
 		ex->_param = ani->_odelay;
 		ex->_field_3C = 1;
@@ -100,8 +110,10 @@ MessageQueue *AniHandler::makeQueue(StaticANIObject *ani, int staticsIndex, int
 
 		mq->addExCommandToEnd(ex);
 
+#if 0
 		if (resStatId)
 			*resStatId = _items[idx].subItems[subidx].movement->_id;
+#endif
 
 		startidx = _items[idx].subItems[subidx].staticsIndex;
 


Commit: 715d4bd76ab749b88f888ea8196ce252de6140ad
    https://github.com/scummvm/scummvm/commit/715d4bd76ab749b88f888ea8196ce252de6140ad
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix memory leaks, ownership issues with various point lists

Changed paths:
    engines/fullpipe/anihandler.cpp
    engines/fullpipe/anihandler.h
    engines/fullpipe/floaters.cpp
    engines/fullpipe/floaters.h
    engines/fullpipe/fullpipe.h
    engines/fullpipe/gfx.cpp
    engines/fullpipe/gfx.h
    engines/fullpipe/messagehandlers.cpp
    engines/fullpipe/messages.cpp
    engines/fullpipe/messages.h
    engines/fullpipe/motion.cpp
    engines/fullpipe/motion.h
    engines/fullpipe/scenes/scene02.cpp
    engines/fullpipe/scenes/scene05.cpp
    engines/fullpipe/scenes/scene12.cpp
    engines/fullpipe/scenes/scene17.cpp
    engines/fullpipe/scenes/scene20.cpp
    engines/fullpipe/scenes/scene28.cpp
    engines/fullpipe/scenes/scene34.cpp
    engines/fullpipe/scenes/scene35.cpp
    engines/fullpipe/statics.cpp
    engines/fullpipe/statics.h


diff --git a/engines/fullpipe/anihandler.cpp b/engines/fullpipe/anihandler.cpp
index b847986..e556a8e 100644
--- a/engines/fullpipe/anihandler.cpp
+++ b/engines/fullpipe/anihandler.cpp
@@ -356,7 +356,7 @@ MessageQueue *AniHandler::makeRunQueue(MakeQueueStruct *mkQueue) {
 	for (int i = subIdx; i != st2idx;) {
 		const MGMSubItem &s = _items[itemIdx].subItems[i + st2idx * _items[itemIdx].statics.size()];
 
-		ex2 = createCommand(s.movement, mkQueue->ani->_id, x1, y1, &x2, &y2, -1);
+		ex2 = createCommand(s.movement, mkQueue->ani->_id, x1, y1, x2, y2, -1);
 		ex2->_parId = mq->_id;
 		ex2->_param = mkQueue->ani->_odelay;
 
@@ -373,7 +373,7 @@ MessageQueue *AniHandler::makeRunQueue(MakeQueueStruct *mkQueue) {
 		else
 			plen = -1;
 
-		ex2 = createCommand(mov, mkQueue->ani->_id, x1, y1, &x2, &y2, plen);
+		ex2 = createCommand(mov, mkQueue->ani->_id, x1, y1, x2, y2, plen);
 		ex2->_parId = mq->_id;
 		ex2->_param = mkQueue->ani->_odelay;
 
@@ -383,7 +383,7 @@ MessageQueue *AniHandler::makeRunQueue(MakeQueueStruct *mkQueue) {
 	for (int j = st1idx; j != subOffset;) {
 		const MGMSubItem &s = _items[itemIdx].subItems[j + subOffset * _items[itemIdx].statics.size()];
 
-		ex2 = createCommand(s.movement, mkQueue->ani->_id, x1, y1, &x2, &y2, -1);
+		ex2 = createCommand(s.movement, mkQueue->ani->_id, x1, y1, x2, y2, -1);
 		ex2->_parId = mq->_id;
 		ex2->_param = mkQueue->ani->_odelay;
 
@@ -701,8 +701,8 @@ Common::Point AniHandler::getNumCycles(Movement *mov, int x, int y, int *mult, i
 	return Common::Point(p2x + p1x * newmult, p2y + p1y * newmult);
 }
 
-ExCommand2 *AniHandler::createCommand(Movement *mov, int objId, int x1, int y1, Common::Point *x2, Common::Point *y2, int len) {
-	debugC(2, kDebugPathfinding, "AniHandler::createCommand(mov, %d, %d, %d, [%d, %d], [%d, %d], %d)", objId, x1, y1, x2->x, x2->y, y2->x, y2->y, len);
+ExCommand2 *AniHandler::createCommand(Movement *mov, int objId, int x1, int y1, Common::Point &x2, Common::Point &y2, int len) {
+	debugC(2, kDebugPathfinding, "AniHandler::createCommand(mov, %d, %d, %d, [%d, %d], [%d, %d], %d)", objId, x1, y1, x2.x, x2.y, y2.x, y2.y, len);
 
 	uint cnt;
 
@@ -714,44 +714,37 @@ ExCommand2 *AniHandler::createCommand(Movement *mov, int objId, int x1, int y1,
 	if (len > 0 && cnt > (uint)len)
 		cnt = len;
 
-	Common::Point **points = (Common::Point **)malloc(sizeof(Common::Point *) * cnt);
+	PointList points(cnt);
 
 	for (uint i = 0; i < cnt; i++) {
 		int flags = mov->getDynamicPhaseByIndex(i)->getDynFlags();
 
-		points[i] = new Common::Point;
-
 		if (flags & 1) {
-			points[i]->x = x1 + x2->x;
+			points[i].x = x1 + x2.x;
 
-			y2->x -= x2->x;
+			y2.x -= x2.x;
 
-			if (!y2->x)
-				x2->x = 0;
+			if (!y2.x)
+				x2.x = 0;
 		}
 
 		if (flags & 2) {
-			points[i]->y = y1 + x2->y;
+			points[i].y = y1 + x2.y;
 
-			y2->y -= x2->y;
+			y2.y -= x2.y;
 
-			if (!y2->y)
-				x2->y = 0;
+			if (!y2.y)
+				x2.y = 0;
 		}
 	}
 
-	ExCommand2 *ex = new ExCommand2(20, objId, points, cnt);
+	ExCommand2 *ex = new ExCommand2(20, objId, points);
 	ex->_excFlags = 2;
 	ex->_messageNum = mov->_id;
 	ex->_field_14 = len;
 	ex->_field_24 = 1;
 	ex->_param = -1;
 
-	for (uint i = 0; i < cnt; i++)
-		delete points[i];
-
-	free(points);
-
 	return ex;
 }
 
diff --git a/engines/fullpipe/anihandler.h b/engines/fullpipe/anihandler.h
index 5bc771a..f73d755 100644
--- a/engines/fullpipe/anihandler.h
+++ b/engines/fullpipe/anihandler.h
@@ -84,7 +84,7 @@ public:
 	void clearVisitsList(int idx);
 	int seekWay(int idx, int st1idx, int st2idx, bool flip, bool flop);
 	Common::Point getNumCycles(Movement *mov, int x, int y, int *mult, int *len, int flag);
-	ExCommand2 *createCommand(Movement *mov, int objId, int x1, int y1, Common::Point *x2, Common::Point *y2, int len);
+	ExCommand2 *createCommand(Movement *mov, int objId, int x1, int y1, Common::Point &x2, Common::Point &y2, int len);
 	MessageQueue *makeQueue(StaticANIObject *ani, int staticsIndex, int staticsId, int *resStatId, Common::Point **pointArr);
 	int getFramesCount(int idx, int subIdx, int subOffset, int flag);
 	int getNumMovements(int objectId, int idx1, int idx2);
diff --git a/engines/fullpipe/floaters.cpp b/engines/fullpipe/floaters.cpp
index 01afa24..284e8b7 100644
--- a/engines/fullpipe/floaters.cpp
+++ b/engines/fullpipe/floaters.cpp
@@ -32,10 +32,6 @@
 
 namespace Fullpipe {
 
-Floaters::~Floaters() {
-	delete _hRgn;
-}
-
 void Floaters::init(GameVar *var) {
 	_array1.clear();
 	_array2.clear();
@@ -48,21 +44,16 @@ void Floaters::init(GameVar *var) {
 	GameVar *sub = varFliers->getSubVarByName("flyIdleRegion");
 
 	if (sub) {
-		_hRgn = new ReactPolygonal();
+		_hRgn.reset(new ReactPolygonal());
 
-		_hRgn->_pointCount = sub->getSubVarsCount();
-		_hRgn->_points = (Common::Point **)malloc(sizeof(Common::Point *) * _hRgn->_pointCount);
+		_hRgn->_points.resize(sub->getSubVarsCount());
 
 		sub = sub->_subVars;
-
-		int idx = 0;
-
+		uint idx = 0;
 		while (sub) {
-			_hRgn->_points[idx] = new Common::Point;
-			_hRgn->_points[idx]->x = sub->_subVars->_value.intValue;
-			_hRgn->_points[idx]->y = sub->_subVars->_nextVarObj->_value.intValue;
-
-			idx++;
+			_hRgn->_points[idx].x = sub->_subVars->_value.intValue;
+			_hRgn->_points[idx].y = sub->_subVars->_nextVarObj->_value.intValue;
+			++idx;
 			sub = sub->_nextVarObj;
 		}
 	}
@@ -70,24 +61,20 @@ void Floaters::init(GameVar *var) {
 	sub = varFliers->getSubVarByName("flyIdlePath");
 
 	if (sub) {
-		_array1.reserve(sub->getSubVarsCount());
+		_array1.resize(sub->getSubVarsCount());
 
 		sub = sub->_subVars;
 
-		int idx = 0;
-
+		uint idx = 0;
 		while (sub) {
-			FloaterArray1 *f = new FloaterArray1;
-
-			f->val1 = sub->_subVars->_value.intValue;
-			f->val2 = sub->_subVars->_nextVarObj->_value.intValue;
+			FloaterArray1 &f = _array1[idx];
 
-			_array1.push_back(f);
+			f.val1 = sub->_subVars->_value.intValue;
+			f.val2 = sub->_subVars->_nextVarObj->_value.intValue;
 
-			idx++;
+			++idx;
 			sub = sub->_nextVarObj;
 		}
-
 	}
 }
 
@@ -113,65 +100,64 @@ void Floaters::genFlies(Scene *sc, int x, int y, int priority, int flags) {
 
 	ani->_movement->setDynamicPhaseIndex(g_fp->_rnd.getRandomNumber(nummoves - 1));
 
-	FloaterArray2 *arr2 = new FloaterArray2;
-
-	arr2->ani = ani;
-	arr2->val11 = 15.0;
-	arr2->val3 = y;
-	arr2->val5 = y;
-	arr2->val2 = x;
-	arr2->val4 = x;
-	arr2->fflags = flags;
-
-	_array2.push_back(arr2);
+	_array2.push_back(FloaterArray2());
+	FloaterArray2 &arr2 = _array2.back();
+	arr2.ani = ani;
+	arr2.val11 = 15.0;
+	arr2.val3 = y;
+	arr2.val5 = y;
+	arr2.val2 = x;
+	arr2.val4 = x;
+	arr2.fflags = flags;
 }
 
 void Floaters::update() {
 	for (uint i = 0; i < _array2.size(); ++i) {
-		if (_array2[i]->val13 <= 0) {
-			if (_array2[i]->val4 != _array2[i]->val2 || _array2[i]->val5 != _array2[i]->val3) {
-				if (_array2[i]->val9 < 2.0)
-					_array2[i]->val9 = 2.0;
-
-				int dy = _array2[i]->val3 - _array2[i]->val5;
-				int dx = _array2[i]->val2 - _array2[i]->val4;
+		FloaterArray2 &a2 = _array2[i];
+		if (_array2[i].val13 <= 0) {
+			if (_array2[i].val4 != a2.val2 || a2.val5 != a2.val3) {
+				if (_array2[i].val9 < 2.0)
+					_array2[i].val9 = 2.0;
+
+				int dy = a2.val3 - a2.val5;
+				int dx = a2.val2 - a2.val4;
 				double dst = sqrt((double)(dy * dy + dx * dx));
 				double at = atan2((double)dy, (double)dx);
-				int newX = (int)(cos(at) * _array2[i]->val9);
-				int newY = (int)(sin(at) * _array2[i]->val9);
+				int newX = (int)(cos(at) * a2.val9);
+				int newY = (int)(sin(at) * a2.val9);
 
-				if (dst < _array2[i]->val9) {
-					newX = _array2[i]->val2 - _array2[i]->val4;
-					newY = _array2[i]->val3 - _array2[i]->val5;
+				if (dst < a2.val9) {
+					newX = a2.val2 - a2.val4;
+					newY = a2.val3 - a2.val5;
 				}
 				if (dst <= 30.0) {
 					if (dst < 30.0) {
-						_array2[i]->val9 = _array2[i]->val9 - _array2[i]->val9 * 0.5;
+						a2.val9 = a2.val9 - a2.val9 * 0.5;
 
-						if (_array2[i]->val9 < 2.0)
-							_array2[i]->val9 = 2.0;
+						if (a2.val9 < 2.0)
+							a2.val9 = 2.0;
 					}
 				} else {
-					_array2[i]->val9 = _array2[i]->val9 * 0.5 + _array2[i]->val9;
+					a2.val9 = a2.val9 * 0.5 + a2.val9;
 
-					if (_array2[i]->val9 > _array2[i]->val11)
-						_array2[i]->val9 = _array2[i]->val11;
+					if (a2.val9 > a2.val11)
+						a2.val9 = a2.val11;
 				}
 
-				_array2[i]->val4 += newX;
-				_array2[i]->val5 += newY;
-				_array2[i]->ani->setOXY(newX + _array2[i]->ani->_ox, newY + _array2[i]->ani->_oy);
+				a2.val4 += newX;
+				a2.val5 += newY;
+				a2.ani->setOXY(newX + a2.ani->_ox, newY + a2.ani->_oy);
 
-				if (_array2[i]->val4 == _array2[i]->val2 && _array2[i]->val5 == _array2[i]->val3) {
-					_array2[i]->val9 = 0.0;
+				if (a2.val4 == a2.val2 && a2.val5 == a2.val3) {
+					a2.val9 = 0.0;
 
-					_array2[i]->val13 = g_fp->_rnd.getRandomNumber(200) + 20;
+					a2.val13 = g_fp->_rnd.getRandomNumber(200) + 20;
 
-					if (_array2[i]->fflags & 1) {
-						g_fp->_currentScene->deleteStaticANIObject(_array2[i]->ani);
+					if (a2.fflags & 1) {
+						g_fp->_currentScene->deleteStaticANIObject(a2.ani);
 
-						if (_array2[i]->ani)
-							delete _array2[i]->ani;
+						if (a2.ani)
+							delete a2.ani;
 
 						_array2.remove_at(i);
 
@@ -184,66 +170,64 @@ void Floaters::update() {
 					}
 				}
 			} else {
-				if ((_array2[i]->fflags & 4) && _array2[i]->countdown < 1) {
-					_array2[i]->fflags |= 1;
-					_array2[i]->val2 = _array2[i]->val6;
-					_array2[i]->val3 = _array2[i]->val7;
+				if ((a2.fflags & 4) && a2.countdown < 1) {
+					a2.fflags |= 1;
+					a2.val2 = a2.val6;
+					a2.val3 = a2.val7;
 				} else {
-					if (_array2[i]->fflags & 2) {
+					if (a2.fflags & 2) {
 						int idx1 = g_fp->_rnd.getRandomNumber(_array1.size() - 1);
 
-						_array2[i]->val2 = _array1[idx1]->val1;
-						_array2[i]->val3 = _array1[idx1]->val2;
+						a2.val2 = _array1[idx1].val1;
+						a2.val3 = _array1[idx1].val2;
 					} else {
-						Common::Rect rect;
-
 						if (!_hRgn)
 							error("Floaters::update(): empty fliers region");
 
-						_hRgn->getBBox(&rect);
+						const Common::Rect rect = _hRgn->getBBox();
 
 						int x2 = rect.left + g_fp->_rnd.getRandomNumber(rect.right - rect.left);
 						int y2 = rect.top + g_fp->_rnd.getRandomNumber(rect.bottom - rect.top);
 
 						if (_hRgn->pointInRegion(x2, y2)) {
-							int dx = _array2[i]->val2 - x2;
-							int dy = _array2[i]->val3 - y2;
+							int dx = a2.val2 - x2;
+							int dy = a2.val3 - y2;
 							double dst = sqrt((double)(dy * dy + dx * dx));
 
-							if (dst < 300.0 || !_hRgn->pointInRegion(_array2[i]->val4, _array2[i]->val5)) {
-								_array2[i]->val2 = x2;
-								_array2[i]->val3 = y2;
+							if (dst < 300.0 || !_hRgn->pointInRegion(a2.val4, a2.val5)) {
+								a2.val2 = x2;
+								a2.val3 = y2;
 							}
 						}
 					}
 
 					g_fp->playSound(SND_CMN_061, 0);
 
-					if (_array2[i]->fflags & 4)
-						_array2[i]->countdown--;
+					if (a2.fflags & 4)
+						a2.countdown--;
 				}
 			}
 		} else {
-			_array2[i]->val13--;
+			a2.val13--;
 		}
 
-		if (!_array2[i]->ani->_movement && _array2[i]->ani->_statics->_staticsId == ST_FLY_FLY) {
-			if (!_array2[i]->val15) {
+		if (!a2.ani->_movement && a2.ani->_statics->_staticsId == ST_FLY_FLY) {
+			if (!a2.val15) {
 				g_fp->playSound(SND_CMN_060, 1);
 
-				_array2[i]->val15 = 1;
+				a2.val15 = 1;
 			}
 
-			_array2[i]->ani->startAnim(MV_FLY_FLY, 0, -1);
+			a2.ani->startAnim(MV_FLY_FLY, 0, -1);
 		}
 	}
 }
 
 void Floaters::stopAll() {
 	for (uint i = 0; i < _array2.size(); i++) {
-		g_fp->_currentScene->deleteStaticANIObject(_array2[i]->ani);
-
-		delete _array2[i]->ani;
+		FloaterArray2 &a2 = _array2[i];
+		g_fp->_currentScene->deleteStaticANIObject(a2.ani);
+		delete a2.ani;
 	}
 
 	_array2.clear();
diff --git a/engines/fullpipe/floaters.h b/engines/fullpipe/floaters.h
index bd7b7ff..161a342 100644
--- a/engines/fullpipe/floaters.h
+++ b/engines/fullpipe/floaters.h
@@ -23,6 +23,9 @@
 #ifndef FULLPIPE_FLOATERS_H
 #define FULLPIPE_FLOATERS_H
 
+#include "common/array.h"
+#include "common/ptr.h"
+
 namespace Fullpipe {
 
 class StaticANIObject;
@@ -52,18 +55,16 @@ struct FloaterArray2 {
 	int val15;
 	int fflags;
 
-	FloaterArray2() : ani(0), val2(0), val3(0), val4(0), val5(0), val6(0), val7(0), val8(0),
+	FloaterArray2() : ani(nullptr), val2(0), val3(0), val4(0), val5(0), val6(0), val7(0), val8(0),
 		val9(0.0), val11(0.0), val13(0), countdown(0), val15(0), fflags(0) {}
 };
 
 class Floaters {
 public:
-	ReactPolygonal *_hRgn;
-	Common::Array<FloaterArray1 *> _array1;
-	Common::Array<FloaterArray2 *> _array2;
+	Common::ScopedPtr<ReactPolygonal> _hRgn;
+	Common::Array<FloaterArray1> _array1;
+	Common::Array<FloaterArray2> _array2;
 
-	Floaters() { _hRgn = 0; }
-	~Floaters();
 	void init(GameVar *var);
 	void genFlies(Scene *sc, int x, int y, int priority, int flags);
 	void update();
diff --git a/engines/fullpipe/fullpipe.h b/engines/fullpipe/fullpipe.h
index fefe24c..a24f11e 100644
--- a/engines/fullpipe/fullpipe.h
+++ b/engines/fullpipe/fullpipe.h
@@ -87,6 +87,7 @@ class StaticANIObject;
 class Vars;
 typedef Common::Array<int16> MovTable;
 typedef Common::Array<int32> Palette;
+typedef Common::Array<Common::Point> PointList;
 
 int global_messageHandler1(ExCommand *cmd);
 int global_messageHandler2(ExCommand *cmd);
diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp
index b5614fd..ae2ddac 100644
--- a/engines/fullpipe/gfx.cpp
+++ b/engines/fullpipe/gfx.cpp
@@ -266,9 +266,6 @@ GameObject::GameObject(GameObject *src) {
 	_field_8 = src->_field_8;
 }
 
-GameObject::~GameObject() {
-}
-
 bool GameObject::load(MfcArchive &file) {
 	debugC(5, kDebugLoading, "GameObject::load()");
 	_odelay = 0;
diff --git a/engines/fullpipe/gfx.h b/engines/fullpipe/gfx.h
index af3ce8a..252f855 100644
--- a/engines/fullpipe/gfx.h
+++ b/engines/fullpipe/gfx.h
@@ -153,7 +153,6 @@ class GameObject : public CObject {
   public:
 	GameObject();
 	GameObject(GameObject *src);
-	~GameObject();
 
 	virtual bool load(MfcArchive &file);
 	void setOXY(int x, int y);
diff --git a/engines/fullpipe/messagehandlers.cpp b/engines/fullpipe/messagehandlers.cpp
index 55edae7..de22685 100644
--- a/engines/fullpipe/messagehandlers.cpp
+++ b/engines/fullpipe/messagehandlers.cpp
@@ -599,9 +599,9 @@ int global_messageHandler4(ExCommand *cmd) {
 			ExCommand2 *cmd2 = static_cast<ExCommand2 *>(cmd);
 
 			if (cmd->_excFlags & 1) {
-				ani->startAnimSteps(cmd->_messageNum, 0, cmd->_x, cmd->_y, cmd2->_points, cmd2->_pointsSize, flags);
+				ani->startAnimSteps(cmd->_messageNum, 0, cmd->_x, cmd->_y, cmd2->_points, flags);
 			} else {
-				ani->startAnimSteps(cmd->_messageNum, cmd->_parId, cmd->_x, cmd->_y, cmd2->_points, cmd2->_pointsSize, flags);
+				ani->startAnimSteps(cmd->_messageNum, cmd->_parId, cmd->_x, cmd->_y, cmd2->_points, flags);
 			}
 		}
 		break;
diff --git a/engines/fullpipe/messages.cpp b/engines/fullpipe/messages.cpp
index c865690..632e054 100644
--- a/engines/fullpipe/messages.cpp
+++ b/engines/fullpipe/messages.cpp
@@ -146,36 +146,12 @@ void ExCommand::firef34() {
 	}
 }
 
-ExCommand2::ExCommand2(int messageKind, int parentId, Common::Point **points, int pointsSize) : ExCommand(parentId, messageKind, 0, 0, 0, 0, 1, 0, 0, 0) {
+ExCommand2::ExCommand2(int messageKind, int parentId, const PointList &points) : ExCommand(parentId, messageKind, 0, 0, 0, 0, 1, 0, 0, 0) {
 	_objtype = kObjTypeExCommand2;
-
-	_pointsSize = pointsSize;
-	_points = (Common::Point **)malloc(sizeof(Common::Point *) * pointsSize);
-
-	for (int i = 0; i < pointsSize; i++) {
-		_points[i] = new Common::Point;
-
-		*_points[i] = *points[i];
-	}
+	_points = points;
 }
 
-ExCommand2::ExCommand2(ExCommand2 *src) : ExCommand(src) {
-	_pointsSize = src->_pointsSize;
-	_points = (Common::Point **)malloc(sizeof(Common::Point *) * _pointsSize);
-
-	for (int i = 0; i < _pointsSize; i++) {
-		_points[i] = new Common::Point;
-
-		*_points[i] = *src->_points[i];
-	}
-}
-
-ExCommand2::~ExCommand2() {
-	for (int i = 0; i < _pointsSize; i++)
-		delete _points[i];
-
-	free(_points);
-}
+ExCommand2::ExCommand2(ExCommand2 *src) : ExCommand(src), _points(src->_points) {}
 
 ExCommand2 *ExCommand2::createClone() {
 	return new ExCommand2(this);
@@ -242,9 +218,6 @@ ObjstateCommand::ObjstateCommand(ObjstateCommand *src) : ExCommand(src) {
 	_objCommandName = src->_objCommandName;
 }
 
-ObjstateCommand::~ObjstateCommand() {
-}
-
 bool ObjstateCommand::load(MfcArchive &file) {
 	debugC(5, kDebugLoading, "ObjStateCommand::load()");
 
diff --git a/engines/fullpipe/messages.h b/engines/fullpipe/messages.h
index 65c5e9b..74af61c 100644
--- a/engines/fullpipe/messages.h
+++ b/engines/fullpipe/messages.h
@@ -86,12 +86,10 @@ class ExCommand : public Message {
 
 class ExCommand2 : public ExCommand {
  public:
-	Common::Point **_points;
-	int _pointsSize;
+	PointList _points;
 
-	ExCommand2(int messageKind, int parentId, Common::Point **points, int pointsSize);
+	ExCommand2(int messageKind, int parentId, const PointList &points);
 	ExCommand2(ExCommand2 *src);
-	virtual ~ExCommand2();
 
 	virtual ExCommand2 *createClone();
 };
@@ -104,7 +102,6 @@ class ObjstateCommand : public ExCommand {
  public:
 	ObjstateCommand();
 	ObjstateCommand(ObjstateCommand *src);
-	virtual ~ObjstateCommand();
 
 	virtual bool load(MfcArchive &file);
 
diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp
index 9963776..005ed70 100644
--- a/engines/fullpipe/motion.cpp
+++ b/engines/fullpipe/motion.cpp
@@ -735,7 +735,6 @@ void MctlMQ::clear() {
 	subIndex = 0;
 	item1Index = 0;
 	items.clear();
-	itemsCount = 0;
 	flags = 0;
 }
 
@@ -1531,7 +1530,7 @@ Common::Array<MovArr *> *MovGraph::getHitPoints(int x, int y, int *arrSize, int
 	return arr;
 }
 
-void MovGraph::findAllPaths(MovGraphLink *lnk, MovGraphLink *lnk2, Common::Array<MovGraphLink *> &tempObList1, Common::Array<MovGraphLink *> &allPaths) {
+void MovGraph::findAllPaths(MovGraphLink *lnk, MovGraphLink *lnk2, MovGraphLinkList &tempObList1, MovGraphLinkList &allPaths) {
 	debugC(4, kDebugPathfinding, "MovGraph::findAllPaths(...)");
 
 	if (lnk == lnk2) {
@@ -1566,8 +1565,8 @@ void MovGraph::findAllPaths(MovGraphLink *lnk, MovGraphLink *lnk2, Common::Array
 Common::Array<MovItem *> *MovGraph::getPaths(MovArr *currPos, MovArr *destPos, int *pathCount) {
 	debugC(4, kDebugPathfinding, "MovGraph::getPaths(...)");
 
-	Common::Array<MovGraphLink *> tempObList1;
-	Common::Array<MovGraphLink *> allPaths;
+	MovGraphLinkList tempObList1;
+	MovGraphLinkList allPaths;
 
 	// Get all paths between two edges of the graph
 	findAllPaths(currPos->_link, destPos->_link, tempObList1, allPaths);
@@ -1677,7 +1676,7 @@ void MovGraph::setEnds(MovStep *step1, MovStep *step2) {
 
 int MctlGraph::getObjIndex(int objectId) {
 	for (uint i = 0; i < _items2.size(); i++)
-		if (_items2[i]->_objectId == objectId)
+		if (_items2[i]._objectId == objectId)
 			return i;
 
 	return -1;
@@ -1685,7 +1684,7 @@ int MctlGraph::getObjIndex(int objectId) {
 
 int MctlGraph::getDirByStatics(int idx, int staticsId) {
 	for (int i = 0; i < 4; i++)
-		if (_items2[idx]->_subItems[i]._staticsId1 == staticsId || _items2[idx]->_subItems[i]._staticsId2 == staticsId)
+		if (_items2[idx]._subItems[i]._staticsId1 == staticsId || _items2[idx]._subItems[i]._staticsId2 == staticsId)
 			return i;
 
 	return -1;
@@ -1693,9 +1692,9 @@ int MctlGraph::getDirByStatics(int idx, int staticsId) {
 
 int MctlGraph::getDirByMovement(int idx, int movId) {
 	for (int i = 0; i < 4; i++)
-		if (_items2[idx]->_subItems[i]._walk[0]._movementId == movId
-		 || _items2[idx]->_subItems[i]._walk[1]._movementId == movId
-		 || _items2[idx]->_subItems[i]._walk[2]._movementId == movId)
+		if (_items2[idx]._subItems[i]._walk[0]._movementId == movId
+		 || _items2[idx]._subItems[i]._walk[1]._movementId == movId
+		 || _items2[idx]._subItems[i]._walk[2]._movementId == movId)
 			return i;
 
 	return -1;
@@ -1708,7 +1707,7 @@ int MctlGraph::getDirByPoint(int index, StaticANIObject *ani) {
 
 		for (int i = 0; i < 4; i++) {
 			debugC(1, kDebugPathfinding, "WWW 5");
-			int tmp = _aniHandler.getNumMovements(ani->_id, ani->_statics->_staticsId, _items2[index]->_subItems[i]._staticsId1);
+			int tmp = _aniHandler.getNumMovements(ani->_id, ani->_statics->_staticsId, _items2[index]._subItems[i]._staticsId1);
 
 			if (tmp >= 0 && (minidx == -1 || tmp < min)) {
 				minidx = i;
@@ -1722,11 +1721,11 @@ int MctlGraph::getDirByPoint(int index, StaticANIObject *ani) {
 	return -1;
 }
 
-bool MctlGraph::fillData(StaticANIObject *obj, MctlAni *item) {
+bool MctlGraph::fillData(StaticANIObject *obj, MctlAni &item) {
 	debugC(4, kDebugPathfinding, "MovGraph::fillData(%d, ...)", obj->_id);
 
-	item->_obj = obj;
-	item->_objectId = obj->_id;
+	item._obj = obj;
+	item._objectId = obj->_id;
 
 	GameVar *var = g_fp->getGameLoaderGameVar()->getSubVarByName(obj->_objectName);
 	if (!var)
@@ -1774,15 +1773,15 @@ bool MctlGraph::fillData(StaticANIObject *obj, MctlAni *item) {
 				break;
 			}
 
-			item->_subItems[dir]._walk[act]._movementId = idx;
+			item._subItems[dir]._walk[act]._movementId = idx;
 
 			Movement *mov = obj->getMovementById(idx);
 
-			item->_subItems[dir]._walk[act]._mov = mov;
+			item._subItems[dir]._walk[act]._mov = mov;
 			if (mov) {
 				point = mov->calcSomeXY(0, -1);
-				item->_subItems[dir]._walk[act]._mx = point.x;
-				item->_subItems[dir]._walk[act]._my = point.y;
+				item._subItems[dir]._walk[act]._mx = point.x;
+				item._subItems[dir]._walk[act]._my = point.y;
 			}
 		}
 
@@ -1804,15 +1803,15 @@ bool MctlGraph::fillData(StaticANIObject *obj, MctlAni *item) {
 				break;
 			}
 
-			item->_subItems[dir]._turn[act]._movementId = idx;
+			item._subItems[dir]._turn[act]._movementId = idx;
 
 			Movement *mov = obj->getMovementById(idx);
 
-			item->_subItems[dir]._turn[act]._mov = mov;
+			item._subItems[dir]._turn[act]._mov = mov;
 			if (mov) {
 				point = mov->calcSomeXY(0, -1);
-				item->_subItems[dir]._turn[act]._mx = point.x;
-				item->_subItems[dir]._turn[act]._my = point.y;
+				item._subItems[dir]._turn[act]._mx = point.x;
+				item._subItems[dir]._turn[act]._my = point.y;
 			}
 		}
 
@@ -1834,20 +1833,20 @@ bool MctlGraph::fillData(StaticANIObject *obj, MctlAni *item) {
 				break;
 			}
 
-			item->_subItems[dir]._turnS[act]._movementId = idx;
+			item._subItems[dir]._turnS[act]._movementId = idx;
 
 			Movement *mov = obj->getMovementById(idx);
 
-			item->_subItems[dir]._turnS[act]._mov = mov;
+			item._subItems[dir]._turnS[act]._mov = mov;
 			if (mov) {
 				point = mov->calcSomeXY(0, -1);
-				item->_subItems[dir]._turnS[act]._mx = point.x;
-				item->_subItems[dir]._turnS[act]._my = point.y;
+				item._subItems[dir]._turnS[act]._mx = point.x;
+				item._subItems[dir]._turnS[act]._my = point.y;
 			}
 		}
 
-		item->_subItems[dir]._staticsId1 = item->_subItems[dir]._walk[0]._mov->_staticsObj1->_staticsId;
-		item->_subItems[dir]._staticsId2 = item->_subItems[dir]._walk[0]._mov->_staticsObj2->_staticsId;
+		item._subItems[dir]._staticsId1 = item._subItems[dir]._walk[0]._mov->_staticsObj1->_staticsId;
+		item._subItems[dir]._staticsId2 = item._subItems[dir]._walk[0]._mov->_staticsObj2->_staticsId;
 
 	}
 	return true;
@@ -1861,47 +1860,44 @@ void MctlGraph::attachObject(StaticANIObject *obj) {
 	int id = getObjIndex(obj->_id);
 
 	if (id >= 0) {
-		_items2[id]->_obj = obj;
+		_items2[id]._obj = obj;
 	} else {
-		MctlAni *item = new MctlAni;
-
-		if (fillData(obj, item)) {
-			_items2.push_back(item);
-		} else {
-			delete item;
+		// this is a little dumb due to no move semantics
+		_items2.push_back(MctlAni());
+		if (!fillData(obj, _items2.back())) {
+			_items2.pop_back();
 		}
 	}
 }
 
-void MctlGraph::generateList(MctlMQ *movinfo, Common::Array<MovGraphLink *> *linkList, LinkInfo *lnkSrc, LinkInfo *lnkDst) {
+void MctlGraph::generateList(MctlMQ &movinfo, MovGraphLinkList *linkList, LinkInfo *lnkSrc, LinkInfo *lnkDst) {
 	debugC(4, kDebugPathfinding, "MctlGraph::generateList(...)");
 
 	MctlMQSub *elem;
 	Common::Point point;
 	Common::Rect rect;
 
-	int subIndex = movinfo->subIndex;
+	int subIndex = movinfo.subIndex;
 
-	movinfo->items.clear();
+	movinfo.items.clear();
 
-	elem = new MctlMQSub;
+	movinfo.items.push_back(MctlMQSub());
+	elem = &movinfo.items.back();
 	elem->subIndex = subIndex;
-	elem->x = movinfo->pt1.x;
-	elem->y = movinfo->pt1.y;
+	elem->x = movinfo.pt1.x;
+	elem->y = movinfo.pt1.y;
 	elem->distance = -1;
 
-	movinfo->items.push_back(elem);
-
-	int prevSubIndex = movinfo->subIndex;
+	int prevSubIndex = movinfo.subIndex;
 
 	for (uint i = 0; i < linkList->size(); i++) {
 		int idx1;
 
 		if (linkList->size() <= 1) {
 			if (linkList->size() == 1)
-				idx1 = getDirBySize((*linkList)[0], movinfo->pt2.x - movinfo->pt1.x, movinfo->pt2.y - movinfo->pt1.y);
+				idx1 = getDirBySize((*linkList)[0], movinfo.pt2.x - movinfo.pt1.x, movinfo.pt2.y - movinfo.pt1.y);
 			else
-				idx1 = getDirBySize(0, movinfo->pt2.x - movinfo->pt1.x, movinfo->pt2.y - movinfo->pt1.y);
+				idx1 = getDirBySize(0, movinfo.pt2.x - movinfo.pt1.x, movinfo.pt2.y - movinfo.pt1.y);
 
 			point.y = -1;
 			rect.bottom = -1;
@@ -1916,17 +1912,16 @@ void MctlGraph::generateList(MctlMQ *movinfo, Common::Array<MovGraphLink *> *lin
 			prevSubIndex = idx1;
 			subIndex = idx1;
 
-			elem = new MctlMQSub;
+			movinfo.items.push_back(MctlMQSub());
+			elem = &movinfo.items.back();
 			elem->subIndex = subIndex;
 			elem->x = rect.left;
 			elem->y = rect.top;
 			elem->distance = -1;
-
-			movinfo->items.push_back(elem);
 		}
 
 		if (i != linkList->size() - 1) {
-			while (1) {
+			for (;;) {
 				i++;
 				if (getLinkDir(linkList, i, &rect, 0) != prevSubIndex) {
 					i--;
@@ -1940,84 +1935,77 @@ void MctlGraph::generateList(MctlMQ *movinfo, Common::Array<MovGraphLink *> *lin
 			}
 		}
 
-		if (movinfo->items.back()->subIndex != 10) {
+		if (movinfo.items.back().subIndex != 10) {
 			subIndex = prevSubIndex;
 
-			elem = new MctlMQSub;
+			movinfo.items.push_back(MctlMQSub());
+			elem = &movinfo.items.back();
 			elem->subIndex = 10;
 			elem->x = -1;
 			elem->y = -1;
 			elem->distance = -1;
 
-			movinfo->items.push_back(elem);
-
+			movinfo.items.push_back(MctlMQSub());
+			elem = &movinfo.items.back();
+			elem->subIndex = prevSubIndex;
 			if (i == linkList->size() - 1) {
-				elem = new MctlMQSub;
-				elem->subIndex = prevSubIndex;
-				elem->x = movinfo->pt2.x;
-				elem->y = movinfo->pt2.y;
-				elem->distance = movinfo->distance2;
-
-				movinfo->items.push_back(elem);
+				elem->x = movinfo.pt2.x;
+				elem->y = movinfo.pt2.y;
+				elem->distance = movinfo.distance2;
 			} else {
-				elem = new MctlMQSub;
-				elem->subIndex = prevSubIndex;
 				elem->x = rect.right;
 				elem->y = rect.bottom;
 				elem->distance = point.y;
-
-				movinfo->items.push_back(elem);
 			}
 		}
 	}
 
-	if (subIndex != movinfo->item1Index) {
-		elem = new MctlMQSub;
-		elem->subIndex = movinfo->item1Index;
-		elem->x = movinfo->pt2.x;
-		elem->y = movinfo->pt2.y;
-		elem->distance = movinfo->distance2;
-
-		movinfo->items.push_back(elem);
+	if (subIndex != movinfo.item1Index) {
+		movinfo.items.push_back(MctlMQSub());
+		elem = &movinfo.items.back();
+		elem->subIndex = movinfo.item1Index;
+		elem->x = movinfo.pt2.x;
+		elem->y = movinfo.pt2.y;
+		elem->distance = movinfo.distance2;
 	}
-
-	movinfo->itemsCount = movinfo->items.size();
 }
 
-MessageQueue *MctlGraph::makeWholeQueue(MctlMQ *mctlMQ) {
+MessageQueue *MctlGraph::makeWholeQueue(MctlMQ &mctlMQ) {
 	debugC(4, kDebugPathfinding, "MctlGraph::makeWholeQueue(...)");
 
 	MctlMQ movinfo(mctlMQ);
 
-	int curX = mctlMQ->pt1.x;
-	int curY = mctlMQ->pt1.y;
-	int curDistance = mctlMQ->distance1;
+	int curX = mctlMQ.pt1.x;
+	int curY = mctlMQ.pt1.y;
+	int curDistance = mctlMQ.distance1;
 
 	MessageQueue *mq = new MessageQueue(g_fp->_globalMessageQueueList->compact());
 
-	for (int i = 0; i < mctlMQ->itemsCount - 1; i++) {
-		if (mctlMQ->items[i + 1]->subIndex != 10) {
+	int numItems = mctlMQ.items.size();
+
+	for (int i = 0; i < numItems - 1; i++) {
+		if (mctlMQ.items[i + 1].subIndex != 10) {
 			MG2I *mg2i;
 
-			if (i >= mctlMQ->itemsCount - 2 || mctlMQ->items[i + 2]->subIndex != 10) {
+			if (i >= numItems - 2 || mctlMQ.items[i + 2].subIndex != 10) {
 				movinfo.flags = 0;
-				mg2i = &_items2[mctlMQ->index]->_subItems[mctlMQ->items[i]->subIndex]._turnS[mctlMQ->items[i + 1]->subIndex];
+				mg2i = &_items2[mctlMQ.index]._subItems[mctlMQ.items[i].subIndex]._turnS[mctlMQ.items[i + 1].subIndex];
 			} else {
 				movinfo.flags = 2;
-				mg2i = &_items2[mctlMQ->index]->_subItems[mctlMQ->items[i]->subIndex]._turn[mctlMQ->items[i + 1]->subIndex];
+				mg2i = &_items2[mctlMQ.index]._subItems[mctlMQ.items[i].subIndex]._turn[mctlMQ.items[i + 1].subIndex];
 			}
-			if (i < mctlMQ->itemsCount - 2
-				|| (mctlMQ->items[i]->x == mctlMQ->items[i + 1]->x
-					&& mctlMQ->items[i]->y == mctlMQ->items[i + 1]->y)
-				 || mctlMQ->items[i]->x == -1
-				 || mctlMQ->items[i]->y == -1
-				 || mctlMQ->items[i + 1]->x == -1
-				 || mctlMQ->items[i + 1]->y == -1) {
+			if (i < numItems - 2
+				|| (mctlMQ.items[i].x == mctlMQ.items[i + 1].x
+					&& mctlMQ.items[i].y == mctlMQ.items[i + 1].y)
+				 || mctlMQ.items[i].x == -1
+				 || mctlMQ.items[i].y == -1
+				 || mctlMQ.items[i + 1].x == -1
+				 || mctlMQ.items[i + 1].y == -1) {
 
-				ExCommand *ex = new ExCommand(_items2[mctlMQ->index]->_objectId, 1, mg2i->_movementId, 0, 0, 0, 1, 0, 0, 0);
+				ExCommand *ex = new ExCommand(_items2[mctlMQ.index]._objectId, 1, mg2i->_movementId, 0, 0, 0, 1, 0, 0, 0);
 
 				ex->_excFlags |= 2;
-				ex->_param = _items2[mctlMQ->index]->_obj->_odelay;
+				ex->_param = _items2[mctlMQ.index]._obj->_odelay;
 				ex->_field_24 = 1;
 				ex->_field_14 = -1;
 				mq->addExCommandToEnd(ex);
@@ -2029,45 +2017,43 @@ MessageQueue *MctlGraph::makeWholeQueue(MctlMQ *mctlMQ) {
 
 				memset(&mkQueue, 0, sizeof(mkQueue));
 
-				mkQueue.ani = _items2[mctlMQ->index]->_obj;
+				mkQueue.ani = _items2[mctlMQ.index]._obj;
 				mkQueue.staticsId2 = mg2i->_mov->_staticsObj2->_staticsId;
-				mkQueue.x1 = mctlMQ->items[i + 1]->x;
-				mkQueue.y1 = mctlMQ->items[i + 1]->y;
-				mkQueue.field_1C = mctlMQ->items[i + 1]->distance;
+				mkQueue.x1 = mctlMQ.items[i + 1].x;
+				mkQueue.y1 = mctlMQ.items[i + 1].y;
+				mkQueue.field_1C = mctlMQ.items[i + 1].distance;
 				mkQueue.staticsId1 = mg2i->_mov->_staticsObj1->_staticsId;
 
-				mkQueue.x2 = mctlMQ->items[i]->x;
-				mkQueue.y2 = mctlMQ->items[i]->y;
+				mkQueue.x2 = mctlMQ.items[i].x;
+				mkQueue.y2 = mctlMQ.items[i].y;
 				mkQueue.field_10 = 1;
 				mkQueue.flags = 0x7f;
 				mkQueue.movementId = mg2i->_movementId;
 
-				MessageQueue *mq2 = _aniHandler.makeRunQueue(&mkQueue);
-				mq->mergeQueue(mq2);
+				Common::ScopedPtr<MessageQueue> mq2(_aniHandler.makeRunQueue(&mkQueue));
+				mq->mergeQueue(mq2.get());
 
-				delete mq2;
-
-				curX = mctlMQ->items[i + 1]->x;
-				curY = mctlMQ->items[i + 1]->y;
+				curX = mctlMQ.items[i + 1].x;
+				curY = mctlMQ.items[i + 1].y;
 			}
 		} else {
-			movinfo.item1Index = mctlMQ->items[i]->subIndex;
+			movinfo.item1Index = mctlMQ.items[i].subIndex;
 			movinfo.subIndex = movinfo.item1Index;
 			movinfo.pt1.y = curY;
 			movinfo.pt1.x = curX;
 
 			movinfo.distance1 = curDistance;
-			movinfo.pt2.x = mctlMQ->items[i + 2]->x;
-			movinfo.pt2.y = mctlMQ->items[i + 2]->y;
-			movinfo.distance2 = mctlMQ->items[i + 2]->distance;
+			movinfo.pt2.x = mctlMQ.items[i + 2].x;
+			movinfo.pt2.y = mctlMQ.items[i + 2].y;
+			movinfo.distance2 = mctlMQ.items[i + 2].distance;
 
-			if (i < mctlMQ->itemsCount - 4
-				&& mctlMQ->items[i + 2]->subIndex != 10
-				&& mctlMQ->items[i + 3]->subIndex != 10
-				&& mctlMQ->items[i + 2]->subIndex != mctlMQ->items[i + 3]->subIndex
-				&& mctlMQ->items[i + 4]->subIndex == 10) {
+			if (i < numItems - 4
+				&& mctlMQ.items[i + 2].subIndex != 10
+				&& mctlMQ.items[i + 3].subIndex != 10
+				&& mctlMQ.items[i + 2].subIndex != mctlMQ.items[i + 3].subIndex
+				&& mctlMQ.items[i + 4].subIndex == 10) {
 
-				MG2I *m = &_items2[mctlMQ->index]->_subItems[mctlMQ->items[i + 2]->subIndex]._turn[mctlMQ->items[i + 3]->subIndex];
+				MG2I *m = &_items2[mctlMQ.index]._subItems[mctlMQ.items[i + 2].subIndex]._turn[mctlMQ.items[i + 3].subIndex];
 
 				if (movinfo.item1Index && movinfo.item1Index != 1) {
 					movinfo.pt2.y -= m->_my;
@@ -2077,18 +2063,18 @@ MessageQueue *MctlGraph::makeWholeQueue(MctlMQ *mctlMQ) {
 					movinfo.flags = (movinfo.flags & 2) | 1;
 				}
 
-			} else if (i < mctlMQ->itemsCount - 3
-				&& mctlMQ->items[i + 2]->subIndex != 10
-				&& mctlMQ->items[i + 3]->subIndex != 10
-				&& mctlMQ->items[i + 2]->subIndex != mctlMQ->items[i + 3]->subIndex) {
+			} else if (i < numItems - 3
+				&& mctlMQ.items[i + 2].subIndex != 10
+				&& mctlMQ.items[i + 3].subIndex != 10
+				&& mctlMQ.items[i + 2].subIndex != mctlMQ.items[i + 3].subIndex) {
 
-				MG2I *m = &_items2[mctlMQ->index]->_subItems[mctlMQ->items[i + 2]->subIndex]._turnS[mctlMQ->items[i + 3]->subIndex];
+				MG2I *m = &_items2[mctlMQ.index]._subItems[mctlMQ.items[i + 2].subIndex]._turnS[mctlMQ.items[i + 3].subIndex];
 				movinfo.pt2.x -= m->_mx;
 				movinfo.pt2.y -= m->_my;
-				movinfo.flags = (movinfo.flags & 2) | (mctlMQ->flags & 1);
+				movinfo.flags = (movinfo.flags & 2) | (mctlMQ.flags & 1);
 
 			} else {
-				movinfo.flags = (movinfo.flags & 2) | (mctlMQ->flags & 1);
+				movinfo.flags = (movinfo.flags & 2) | (mctlMQ.flags & 1);
 			}
 
 			i++; // intentional
@@ -2110,8 +2096,8 @@ MessageQueue *MctlGraph::makeWholeQueue(MctlMQ *mctlMQ) {
 		}
 	}
 
-	mctlMQ->pt2.x = movinfo.pt2.x;
-	mctlMQ->pt2.y = movinfo.pt2.y;
+	mctlMQ.pt2.x = movinfo.pt2.x;
+	mctlMQ.pt2.y = movinfo.pt2.y;
 
 	return mq;
 }
@@ -2124,10 +2110,6 @@ int MctlGraph::detachObject(StaticANIObject *obj) {
 
 void MctlGraph::detachAllObjects() {
 	debugC(4, kDebugPathfinding, "MctlGraph::detachAllObjects()");
-
-	for (uint i = 0; i < _items2.size(); i++)
-		delete _items2[i];
-
 	_items2.clear();
 }
 
@@ -2222,7 +2204,7 @@ MessageQueue *MctlGraph::makeQueue(StaticANIObject *obj, int xpos, int ypos, int
 
 		if (subMgm) {
 			obj->_messageQueueId = 0;
-			obj->changeStatics2(_items2[idx]->_subItems[idxsub]._staticsId1);
+			obj->changeStatics2(_items2[idx]._subItems[idxsub]._staticsId1);
 			newx = obj->_ox;
 			newy = obj->_oy;
 		} else {
@@ -2255,7 +2237,7 @@ MessageQueue *MctlGraph::makeQueue(StaticANIObject *obj, int xpos, int ypos, int
 				return 0;
 			}
 
-			ExCommand *ex = new ExCommand(picAniInfo.objectId, 1, _items2[idx]->_subItems[idxsub]._turnS[idxwalk]._movementId, 0, 0, 0, 1, 0, 0, 0);
+			ExCommand *ex = new ExCommand(picAniInfo.objectId, 1, _items2[idx]._subItems[idxsub]._turnS[idxwalk]._movementId, 0, 0, 0, 1, 0, 0, 0);
 
 			ex->_field_24 = 1;
 			ex->_param = picAniInfo.field_8;
@@ -2310,7 +2292,7 @@ MessageQueue *MctlGraph::makeQueue(StaticANIObject *obj, int xpos, int ypos, int
 		}
 	}
 
-	Common::Array<MovGraphLink *> tempLinkList;
+	MovGraphLinkList tempLinkList;
 	double minPath = iterate(&linkInfoSource, &linkInfoDest, &tempLinkList);
 
 	debugC(0, kDebugPathfinding, "MctlGraph::makeQueue(): path: %g  parts: %d", minPath, tempLinkList.size());
@@ -2372,12 +2354,12 @@ MessageQueue *MctlGraph::makeQueue(StaticANIObject *obj, int xpos, int ypos, int
 
 	mctlMQ1.flags = fuzzyMatch != 0;
 
-	if (_items2[idx]->_subItems[idxsub]._staticsId1 != obj->_statics->_staticsId)
+	if (_items2[idx]._subItems[idxsub]._staticsId1 != obj->_statics->_staticsId)
 		mctlMQ1.flags |= 2;
 
-	generateList(&mctlMQ1, &tempLinkList, &linkInfoSource, &linkInfoDest);
+	generateList(mctlMQ1, &tempLinkList, &linkInfoSource, &linkInfoDest);
 
-	MessageQueue *mq = makeWholeQueue(&mctlMQ1);
+	MessageQueue *mq = makeWholeQueue(mctlMQ1);
 
 	linkInfoDest.node = getHitNode(mctlMQ1.pt2.x, mctlMQ1.pt2.y, fuzzyMatch);
 
@@ -2399,7 +2381,7 @@ MessageQueue *MctlGraph::makeQueue(StaticANIObject *obj, int xpos, int ypos, int
 				ex->_excFlags |= 2;
 				mq->addExCommand(ex);
 
-				ex = new ExCommand(picAniInfo.objectId, 22, _items2[idx]->_subItems[idxsub]._staticsId1, 0, 0, 0, 1, 0, 0, 0);
+				ex = new ExCommand(picAniInfo.objectId, 22, _items2[idx]._subItems[idxsub]._staticsId1, 0, 0, 0, 1, 0, 0, 0);
 
 				ex->_param = picAniInfo.field_8;
 				ex->_excFlags |= 3;
@@ -2407,9 +2389,8 @@ MessageQueue *MctlGraph::makeQueue(StaticANIObject *obj, int xpos, int ypos, int
 			}
 		}
 	} else {
-		if (mq)
-			delete mq;
-		mq = 0;
+		delete mq;
+		mq = nullptr;
 	}
 
 	obj->setPicAniInfo(picAniInfo);
@@ -2449,7 +2430,7 @@ int MctlGraph::getDirBySize(MovGraphLink *lnk, int x, int y) {
 		return ((y > 0) + 2);
 }
 
-int MctlGraph::getLinkDir(Common::Array<MovGraphLink *> *linkList, int idx, Common::Rect *rect, Common::Point *point) {
+int MctlGraph::getLinkDir(MovGraphLinkList *linkList, int idx, Common::Rect *rect, Common::Point *point) {
 	debugC(4, kDebugPathfinding, "MctlGraph::getLinkDir(...)");
 
 	MovGraphNode *node1 = (*linkList)[idx]->_graphSrc;
@@ -2505,16 +2486,16 @@ MessageQueue *MctlGraph::makeLineQueue(MctlMQ *info) {
 	int my1 = 0;
 
 	if (!(info->flags & 2)) {
-		mx1 = _items2[info->index]->_subItems[info->subIndex]._walk[0]._mx;
-		my1 = _items2[info->index]->_subItems[info->subIndex]._walk[0]._my;
+		mx1 = _items2[info->index]._subItems[info->subIndex]._walk[0]._mx;
+		my1 = _items2[info->index]._subItems[info->subIndex]._walk[0]._my;
 	}
 
 	int mx2 = 0;
 	int my2 = 0;
 
 	if (!(info->flags & 4)) {
-		mx2 = _items2[info->index]->_subItems[info->subIndex]._walk[2]._mx;
-		my2 = _items2[info->index]->_subItems[info->subIndex]._walk[2]._my;
+		mx2 = _items2[info->index]._subItems[info->subIndex]._walk[2]._mx;
+		my2 = _items2[info->index]._subItems[info->subIndex]._walk[2]._my;
 	}
 
 	Common::Point point;
@@ -2524,7 +2505,7 @@ MessageQueue *MctlGraph::makeLineQueue(MctlMQ *info) {
 	int a2 = 0;
 	int mgmLen;
 
-	point = _aniHandler.getNumCycles(_items2[info->index]->_subItems[info->subIndex]._walk[1]._mov, x, y, &mgmLen, &a2, info->flags & 1);
+	point = _aniHandler.getNumCycles(_items2[info->index]._subItems[info->subIndex]._walk[1]._mov, x, y, &mgmLen, &a2, info->flags & 1);
 
 	int x1 = point.x;
 	int y1 = point.y;
@@ -2532,7 +2513,7 @@ MessageQueue *MctlGraph::makeLineQueue(MctlMQ *info) {
 	if (!(info->flags & 1)) {
 		if (info->subIndex == 1 || info->subIndex == 0) {
 			a2 = -1;
-			x1 = mgmLen * _items2[info->index]->_subItems[info->subIndex]._walk[1]._mx;
+			x1 = mgmLen * _items2[info->index]._subItems[info->subIndex]._walk[1]._mx;
 			x = x1;
 			info->pt2.x = x1 + info->pt1.x + mx1 + mx2;
 		}
@@ -2541,7 +2522,7 @@ MessageQueue *MctlGraph::makeLineQueue(MctlMQ *info) {
 	if (!(info->flags & 1)) {
 		if (info->subIndex == 2 || info->subIndex == 3) {
 			a2 = -1;
-			y1 = mgmLen * _items2[info->index]->_subItems[info->subIndex]._walk[1]._my;
+			y1 = mgmLen * _items2[info->index]._subItems[info->subIndex]._walk[1]._my;
 			y = y1;
 			info->pt2.y = y1 + info->pt1.y + my1 + my2;
 		}
@@ -2551,23 +2532,23 @@ MessageQueue *MctlGraph::makeLineQueue(MctlMQ *info) {
 	int cntY = 0;
 
 	if (!(info->flags & 2)) {
-		cntX = _items2[info->index]->_subItems[info->subIndex]._walk[0]._mov->countPhasesWithFlag(-1, 1);
-		cntY = _items2[info->index]->_subItems[info->subIndex]._walk[0]._mov->countPhasesWithFlag(-1, 2);
+		cntX = _items2[info->index]._subItems[info->subIndex]._walk[0]._mov->countPhasesWithFlag(-1, 1);
+		cntY = _items2[info->index]._subItems[info->subIndex]._walk[0]._mov->countPhasesWithFlag(-1, 2);
 	}
 
 	if (mgmLen > 1) {
-		cntX += (mgmLen - 1) * _items2[info->index]->_subItems[info->subIndex]._walk[1]._mov->countPhasesWithFlag(-1, 1);
-		cntY += (mgmLen - 1) * _items2[info->index]->_subItems[info->subIndex]._walk[1]._mov->countPhasesWithFlag(-1, 2);
+		cntX += (mgmLen - 1) * _items2[info->index]._subItems[info->subIndex]._walk[1]._mov->countPhasesWithFlag(-1, 1);
+		cntY += (mgmLen - 1) * _items2[info->index]._subItems[info->subIndex]._walk[1]._mov->countPhasesWithFlag(-1, 2);
 	}
 
 	if (mgmLen > 0) {
-		cntX += _items2[info->index]->_subItems[info->subIndex]._walk[1]._mov->countPhasesWithFlag(a2, 1);
-		cntY += _items2[info->index]->_subItems[info->subIndex]._walk[1]._mov->countPhasesWithFlag(a2, 2);
+		cntX += _items2[info->index]._subItems[info->subIndex]._walk[1]._mov->countPhasesWithFlag(a2, 1);
+		cntY += _items2[info->index]._subItems[info->subIndex]._walk[1]._mov->countPhasesWithFlag(a2, 2);
 	}
 
 	if (!(info->flags & 4)) {
-		cntX += _items2[info->index]->_subItems[info->subIndex]._walk[2]._mov->countPhasesWithFlag(-1, 1);
-		cntY += _items2[info->index]->_subItems[info->subIndex]._walk[2]._mov->countPhasesWithFlag(-1, 2);
+		cntX += _items2[info->index]._subItems[info->subIndex]._walk[2]._mov->countPhasesWithFlag(-1, 1);
+		cntY += _items2[info->index]._subItems[info->subIndex]._walk[2]._mov->countPhasesWithFlag(-1, 2);
 	}
 
 	int dx1 = x - x1;
@@ -2603,9 +2584,9 @@ MessageQueue *MctlGraph::makeLineQueue(MctlMQ *info) {
 
 	if (info->flags & 2) {
 		ex = new ExCommand(
-							_items2[info->index]->_objectId,
+							_items2[info->index]._objectId,
 							5,
-							_items2[info->index]->_subItems[info->subIndex]._walk[1]._movementId,
+							_items2[info->index]._subItems[info->subIndex]._walk[1]._movementId,
 							info->pt1.x,
 							info->pt1.y,
 							0,
@@ -2616,14 +2597,14 @@ MessageQueue *MctlGraph::makeLineQueue(MctlMQ *info) {
 
 		ex->_field_14 = info->distance1;
 
-		ex->_param = _items2[info->index]->_obj->_odelay;
+		ex->_param = _items2[info->index]._obj->_odelay;
 		ex->_field_24 = 1;
 		ex->_excFlags |= 2;
 	} else {
 		ex = new ExCommand(
-							 _items2[info->index]->_objectId,
+							 _items2[info->index]._objectId,
 							 5,
-							 _items2[info->index]->_subItems[info->subIndex]._walk[0]._movementId,
+							 _items2[info->index]._subItems[info->subIndex]._walk[0]._movementId,
 							 info->pt1.x,
 							 info->pt1.y,
 							 0,
@@ -2634,21 +2615,21 @@ MessageQueue *MctlGraph::makeLineQueue(MctlMQ *info) {
 
 		ex->_field_14 = info->distance1;
 
-		ex->_param = _items2[info->index]->_obj->_odelay;
+		ex->_param = _items2[info->index]._obj->_odelay;
 		ex->_field_24 = 1;
 		ex->_excFlags |= 2;
 		mq->addExCommandToEnd(ex);
 
 		ex = _aniHandler.createCommand(
-								  _items2[info->index]->_subItems[info->subIndex]._walk[0]._mov,
-								  _items2[info->index]->_objectId,
+								  _items2[info->index]._subItems[info->subIndex]._walk[0]._mov,
+								  _items2[info->index]._objectId,
 								  x1,
 								  y1,
-								  &x2,
-								  &y2,
+								  x2,
+								  y2,
 								  -1);
 		ex->_parId = mq->_id;
-		ex->_param = _items2[info->index]->_obj->_odelay;
+		ex->_param = _items2[info->index]._obj->_odelay;
 	}
 
 	mq->addExCommandToEnd(ex);
@@ -2662,37 +2643,37 @@ MessageQueue *MctlGraph::makeLineQueue(MctlMQ *info) {
 			par = -1;
 
 		ex = _aniHandler.createCommand(
-								  _items2[info->index]->_subItems[info->subIndex]._walk[1]._mov,
-								  _items2[info->index]->_objectId,
+								  _items2[info->index]._subItems[info->subIndex]._walk[1]._mov,
+								  _items2[info->index]._objectId,
 								  x1,
 								  y1,
-								  &x2,
-								  &y2,
+								  x2,
+								  y2,
 								  par);
 		ex->_parId = mq->_id;
-		ex->_param = _items2[info->index]->_obj->_odelay;
+		ex->_param = _items2[info->index]._obj->_odelay;
 		mq->addExCommandToEnd(ex);
 	}
 
 	if (!(info->flags & 4)) {
 		ex = _aniHandler.createCommand(
-								  _items2[info->index]->_subItems[info->subIndex]._walk[2]._mov,
-								  _items2[info->index]->_objectId,
+								  _items2[info->index]._subItems[info->subIndex]._walk[2]._mov,
+								  _items2[info->index]._objectId,
 								  x1,
 								  y1,
-								  &x2,
-								  &y2,
+								  x2,
+								  y2,
 								  -1);
 		ex->_parId = mq->_id;
-		ex->_param = _items2[info->index]->_obj->_odelay;
+		ex->_param = _items2[info->index]._obj->_odelay;
 
 		mq->addExCommandToEnd(ex);
 	}
 
-	ex = new ExCommand(_items2[info->index]->_objectId, 5, -1, info->pt2.x, info->pt2.y, 0, 1, 0, 0, 0);
+	ex = new ExCommand(_items2[info->index]._objectId, 5, -1, info->pt2.x, info->pt2.y, 0, 1, 0, 0, 0);
 	ex->_field_14 = info->distance2;
 
-	ex->_param = _items2[info->index]->_obj->_odelay;
+	ex->_param = _items2[info->index]._obj->_odelay;
 	ex->_field_24 = 0;
 	ex->_excFlags |= 2;
 
@@ -2781,7 +2762,7 @@ MovGraphLink *MctlGraph::getNearestLink(int x, int y) {
 		return 0;
 }
 
-double MctlGraph::iterate(LinkInfo *linkInfoSource, LinkInfo *linkInfoDest, Common::Array<MovGraphLink *> *listObj) {
+double MctlGraph::iterate(LinkInfo *linkInfoSource, LinkInfo *linkInfoDest, MovGraphLinkList *listObj) {
 	debugC(4, kDebugPathfinding, "MctlGraph::iterate(...)");
 
 	LinkInfo linkInfoWorkSource;
@@ -2797,7 +2778,7 @@ double MctlGraph::iterate(LinkInfo *linkInfoSource, LinkInfo *linkInfoDest, Comm
 					linkInfoWorkSource.node = 0;
 					linkInfoWorkSource.link = lnk;
 
-					Common::Array<MovGraphLink *> tmpList;
+					MovGraphLinkList tmpList;
 
 					lnk->_flags |= 0x80000000;
 
@@ -2817,7 +2798,7 @@ double MctlGraph::iterate(LinkInfo *linkInfoSource, LinkInfo *linkInfoDest, Comm
 			linkInfoWorkSource.node = linkInfoSource->link->_graphSrc;
 			linkInfoWorkSource.link = 0;
 
-			Common::Array<MovGraphLink *> tmpList;
+			MovGraphLinkList tmpList;
 
 			double newDistance = iterate(&linkInfoWorkSource, linkInfoDest, &tmpList);
 
@@ -2966,28 +2947,24 @@ bool ReactParallel::load(MfcArchive &file) {
 }
 
 void ReactParallel::createRegion() {
-	_points = (Common::Point **)malloc(sizeof(Common::Point *) * 4);
-
-	for (int i = 0; i < 4; i++)
-		_points[i] = new Common::Point;
+	_points.resize(4);
 
 	double at = atan2((double)(_y1 - _y2), (double)(_x1 - _x2)) + 1.570796; // pi/2
 	double sn = sin(at);
 	double cs = cos(at);
 
-	_points[0]->x = (int16)(_x1 - _dx * cs);
-	_points[0]->y = (int16)(_y1 - _dx * sn);
+	_points[0].x = _x1 - _dx * cs;
+	_points[0].y = _y1 - _dx * sn;
 
-	_points[1]->x = (int16)(_x2 - _dx * cs);
-	_points[1]->y = (int16)(_y2 - _dx * sn);
+	_points[1].x = _x2 - _dx * cs;
+	_points[1].y = _y2 - _dx * sn;
 
-	_points[2]->x = (int16)(_x2 + _dy * cs);
-	_points[2]->y = (int16)(_y2 + _dy * sn);
+	_points[2].x = _x2 + _dy * cs;
+	_points[2].y = _y2 + _dy * sn;
 
-	_points[3]->x = (int16)(_x1 + _dy * cs);
-	_points[3]->y = (int16)(_y1 + _dy * sn);
+	_points[3].x = _x1 + _dy * cs;
+	_points[3].y = _y1 + _dy * sn;
 
-	_pointCount = 4;
 	// GdiObject::Attach(_rgn, CreatePolygonRgn(_points, 4, 2);
 }
 
@@ -2999,13 +2976,12 @@ void ReactParallel::setCenter(int x1, int y1, int x2, int y2) {
 }
 
 ReactPolygonal::ReactPolygonal() {
+	// hack for using isValid to avoid creating another state variable for
+	// getBBox
+	_bbox.right = -1;
+
 	_centerX = 0;
 	_centerY = 0;
-	_bbox = 0;
-}
-
-ReactPolygonal::~ReactPolygonal() {
-	delete _bbox;
 }
 
 bool ReactPolygonal::load(MfcArchive &file) {
@@ -3013,18 +2989,11 @@ bool ReactPolygonal::load(MfcArchive &file) {
 
 	_centerX = file.readSint32LE();
 	_centerY = file.readSint32LE();
-	_pointCount = file.readUint32LE();
-
-	if (_pointCount > 0) {
-		_points = (Common::Point **)malloc(sizeof(Common::Point *) * _pointCount);
-
-		for (int i = 0; i < _pointCount; i++) {
-			_points[i] = new Common::Point;
-
-			_points[i]->x = file.readUint32LE();
-			_points[i]->y = file.readUint32LE();
-		}
+	_points.resize(file.readUint32LE());
 
+	for (uint i = 0; i < _points.size(); ++i) {
+		_points[i].x = file.readUint32LE();
+		_points[i].y = file.readUint32LE();
 	}
 
 	createRegion();
@@ -3033,7 +3002,7 @@ bool ReactPolygonal::load(MfcArchive &file) {
 }
 
 void ReactPolygonal::createRegion() {
-	if (_points) {
+	if (_points.size()) {
 
 		// GdiObject::Attach(_rgn, CreatePolygonRgn(_points, _pointCount, 2);
 	}
@@ -3043,52 +3012,46 @@ void ReactPolygonal::setCenter(int x1, int y1, int x2, int y2) {
 	int cX = (x2 + x1) / 2;
 	int cY = (y2 + y1) / 2;
 
-	if (_points) {
-		for (int i = 0; i < _pointCount; i++) {
-			_points[i]->x += cX - _centerX;
-			_points[i]->y += cY - _centerY;
-		}
+	for (uint i = 0; i < _points.size(); ++i) {
+		_points[i].x += cX - _centerX;
+		_points[i].y += cY - _centerY;
 	}
 
 	_centerX = cX;
 	_centerY = cY;
 }
 
-void ReactPolygonal::getBBox(Common::Rect *rect) {
-	if (!_pointCount)
-		return;
-
-	if (_bbox) {
-		*rect = *_bbox;
-		return;
-	}
+Common::Rect ReactPolygonal::getBBox() {
+	if (!_points.size())
+		return Common::Rect();
 
-	rect->left = _points[0]->x;
-	rect->top = _points[0]->y;
-	rect->right = _points[0]->x;
-	rect->bottom = _points[0]->y;
+	if (!_bbox.isValidRect()) {
+		_bbox.left = _points[0].x;
+		_bbox.top = _points[0].y;
+		_bbox.right = _points[0].x;
+		_bbox.bottom = _points[0].y;
 
-	for (int i = 1; i < _pointCount; i++) {
-		if (rect->left > _points[i]->x)
-			rect->left = _points[i]->x;
+		for (uint i = 1; i < _points.size(); ++i) {
+			if (_bbox.left > _points[i].x)
+				_bbox.left = _points[i].x;
 
-		if (rect->top > _points[i]->y)
-			rect->top = _points[i]->y;
+			if (_bbox.top > _points[i].y)
+				_bbox.top = _points[i].y;
 
-		if (rect->right < _points[i]->x)
-			rect->right = _points[i]->x;
+			if (_bbox.right < _points[i].x)
+				_bbox.right = _points[i].x;
 
-		if (rect->bottom < _points[i]->y)
-			rect->bottom = _points[i]->y;
+			if (_bbox.bottom < _points[i].y)
+				_bbox.bottom = _points[i].y;
+		}
 	}
 
-	_bbox = new Common::Rect;
-	*_bbox = *rect;
+	return _bbox;
 }
 
 
 bool MovGraphReact::pointInRegion(int x, int y) {
-	if (_pointCount < 3) {
+	if (_points.size() < 3) {
 		return false;
 	}
 
@@ -3099,12 +3062,12 @@ bool MovGraphReact::pointInRegion(int x, int y) {
 	p.x = x;
 	p.y = y;
 
-	p1.x = _points[0]->x;
-	p1.y = _points[0]->y;
+	p1.x = _points[0].x;
+	p1.y = _points[0].y;
 
-	for (int i = 1; i <= _pointCount; i++) {
-		p2.x = _points[i % _pointCount]->x;
-		p2.y = _points[i % _pointCount]->y;
+	for (uint i = 1; i <= _points.size(); i++) {
+		p2.x = _points[i % _points.size()].x;
+		p2.y = _points[i % _points.size()].y;
 
 		if (p.y > MIN(p1.y, p2.y)) {
 			if (p.y <= MAX(p1.y, p2.y)) {
diff --git a/engines/fullpipe/motion.h b/engines/fullpipe/motion.h
index 2a1450e..b47cff9 100644
--- a/engines/fullpipe/motion.h
+++ b/engines/fullpipe/motion.h
@@ -70,13 +70,9 @@ public:
 
 class MovGraphReact : public CObject {
 public:
-	int _pointCount;
-	Common::Point **_points;
+	PointList _points;
 
 public:
-	MovGraphReact() : _pointCount(0), _points(0) {}
-	~MovGraphReact() { free(_points); }
-
 	virtual void setCenter(int x1, int y1, int x2, int y2) {}
 	virtual void createRegion() {}
 	virtual bool pointInRegion(int x, int y);
@@ -200,20 +196,19 @@ public:
 };
 
 class ReactPolygonal : public MovGraphReact {
-	Common::Rect *_bbox;
+	Common::Rect _bbox;
 	int _centerX;
 	int _centerY;
 
 public:
 	ReactPolygonal();
-	~ReactPolygonal();
 
 	virtual bool load(MfcArchive &file);
 
 	virtual void setCenter(int x1, int y1, int x2, int y2);
 	virtual void createRegion();
 
-	void getBBox(Common::Rect *rect);
+	Common::Rect getBBox();
 };
 
 class MovGraphLink : public CObject {
@@ -238,6 +233,7 @@ class MovGraphLink : public CObject {
 
 	void recalcLength();
 };
+typedef Common::Array<MovGraphLink *> MovGraphLinkList;
 
 struct MovStep {
 	int sfield_0;
@@ -315,7 +311,7 @@ public:
 	MovGraphNode *calcOffset(int ox, int oy);
 	int getObjectIndex(StaticANIObject *ani);
 	Common::Array<MovArr *> *getHitPoints(int x, int y, int *arrSize, int flag1, int flag2);
-	void findAllPaths(MovGraphLink *lnk, MovGraphLink *lnk2, Common::Array<MovGraphLink *> &tempObList1, Common::Array<MovGraphLink *> &tempObList2);
+	void findAllPaths(MovGraphLink *lnk, MovGraphLink *lnk2, MovGraphLinkList &tempObList1, MovGraphLinkList &tempObList2);
 	Common::Array<MovItem *> *getPaths(MovArr *movarr1, MovArr *movarr2, int *listCount);
 	void genMovItem(MovItem *movitem, MovGraphLink *grlink, MovArr *movarr1, MovArr *movarr2);
 	bool getHitPoint(int idx, int x, int y, MovArr *arr, int a6);
@@ -361,12 +357,10 @@ struct MctlMQ {
 	int distance2;
 	int subIndex;
 	int item1Index;
-	Common::Array<MctlMQSub *> items;
-	int itemsCount;
+	Common::Array<MctlMQSub> items;
 	int flags;
 
 	MctlMQ() { clear(); }
-	MctlMQ(MctlMQ *src);
 	void clear();
 };
 
@@ -378,7 +372,7 @@ struct MctlAni { // 744
 
 class MctlGraph : public MovGraph {
 public:
-	Common::Array<MctlAni *> _items2;
+	Common::Array<MctlAni> _items2;
 
 public:
 	virtual void attachObject(StaticANIObject *obj);
@@ -393,16 +387,16 @@ public:
 	int getDirByPoint(int idx, StaticANIObject *ani);
 
 	int getDirBySize(MovGraphLink *lnk, int x, int y);
-	int getLinkDir(Common::Array<MovGraphLink *> *linkList, int idx, Common::Rect *a3, Common::Point *a4);
+	int getLinkDir(MovGraphLinkList *linkList, int idx, Common::Rect *a3, Common::Point *a4);
 
-	bool fillData(StaticANIObject *obj, MctlAni *item);
-	void generateList(MctlMQ *movinfo, Common::Array<MovGraphLink *> *linkList, LinkInfo *lnkSrc, LinkInfo *lnkDst);
-	MessageQueue *makeWholeQueue(MctlMQ *mctlMQ);
+	bool fillData(StaticANIObject *obj, MctlAni &item);
+	void generateList(MctlMQ &movinfo, MovGraphLinkList *linkList, LinkInfo *lnkSrc, LinkInfo *lnkDst);
+	MessageQueue *makeWholeQueue(MctlMQ &mctlMQ);
 
 	MovGraphNode *getHitNode(int x, int y, int strictMatch);
 	MovGraphLink *getHitLink(int x, int y, int idx, int fuzzyMatch);
 	MovGraphLink *getNearestLink(int x, int y);
-	double iterate(LinkInfo *linkInfoSource, LinkInfo *linkInfoDest, Common::Array<MovGraphLink *> *listObj);
+	double iterate(LinkInfo *linkInfoSource, LinkInfo *linkInfoDest, MovGraphLinkList *listObj);
 
 	MessageQueue *makeLineQueue(MctlMQ *movinfo);
 };
diff --git a/engines/fullpipe/scenes/scene02.cpp b/engines/fullpipe/scenes/scene02.cpp
index e2350a9..c503013 100644
--- a/engines/fullpipe/scenes/scene02.cpp
+++ b/engines/fullpipe/scenes/scene02.cpp
@@ -113,12 +113,12 @@ int sceneHandler02(ExCommand *ex) {
 			if (g_vars->scene02_boxDelay >= 1) {
 				--g_vars->scene02_boxDelay;
 			} else if (g_fp->_floaters->_array2.size() >= 1) {
-				if (g_fp->_floaters->_array2[0]->val5 == -50) {
+				if (g_fp->_floaters->_array2[0].val5 == -50) {
 					g_fp->_floaters->stopAll();
 					g_vars->scene02_boxOpen = false;
 					g_vars->scene02_boxDelay = 100 * g_fp->_rnd.getRandomNumber(32767) + 150;
 				} else {
-					g_fp->_floaters->_array2[0]->val3 = -50;
+					g_fp->_floaters->_array2[0].val3 = -50;
 				}
 			} else {
 				g_fp->_floaters->genFlies(g_fp->_currentScene, g_fp->_rnd.getRandomNumber(700) + 100, -50, 0, 0);
diff --git a/engines/fullpipe/scenes/scene05.cpp b/engines/fullpipe/scenes/scene05.cpp
index 35fd24e..e67e12a 100644
--- a/engines/fullpipe/scenes/scene05.cpp
+++ b/engines/fullpipe/scenes/scene05.cpp
@@ -159,9 +159,9 @@ void sceneHandler05_genFlies() {
 			int y = g_fp->_rnd.getRandomNumber(60) + i * 30 + 520;
 
 			g_fp->_floaters->genFlies(g_fp->_currentScene, x, y, 5, 1);
-			g_fp->_floaters->_array2.back()->val2 = 585;
-			g_fp->_floaters->_array2.back()->val3 = -70;
-			g_fp->_floaters->_array2.back()->val11 = 8.0;
+			g_fp->_floaters->_array2.back().val2 = 585;
+			g_fp->_floaters->_array2.back().val3 = -70;
+			g_fp->_floaters->_array2.back().val11 = 8.0;
 		}
 	}
 
diff --git a/engines/fullpipe/scenes/scene12.cpp b/engines/fullpipe/scenes/scene12.cpp
index 23bab31..81732bc 100644
--- a/engines/fullpipe/scenes/scene12.cpp
+++ b/engines/fullpipe/scenes/scene12.cpp
@@ -50,9 +50,9 @@ void scene12_initScene(Scene *sc) {
 void sceneHandler12_updateFloaters() {
 	g_fp->_floaters->genFlies(g_fp->_currentScene, 397, -50, 100, 6);
 
-	g_fp->_floaters->_array2[0]->countdown = g_fp->_rnd.getRandomNumber(6) + 4;
-	g_fp->_floaters->_array2[0]->val6 = 397;
-	g_fp->_floaters->_array2[0]->val7 = -50;
+	g_fp->_floaters->_array2[0].countdown = g_fp->_rnd.getRandomNumber(6) + 4;
+	g_fp->_floaters->_array2[0].val6 = 397;
+	g_fp->_floaters->_array2[0].val7 = -50;
 }
 
 int sceneHandler12(ExCommand *cmd) {
diff --git a/engines/fullpipe/scenes/scene17.cpp b/engines/fullpipe/scenes/scene17.cpp
index a830a8f..7dd75ae 100644
--- a/engines/fullpipe/scenes/scene17.cpp
+++ b/engines/fullpipe/scenes/scene17.cpp
@@ -157,9 +157,9 @@ void sceneHandler17_moonshineFill() {
 void sceneHandler17_updateFlies() {
 	g_fp->_floaters->genFlies(g_fp->_currentScene, 239, -50, 20, 4);
 
-	g_fp->_floaters->_array2[0]->countdown = g_fp->_rnd.getRandomNumber(5) + 6;
-	g_fp->_floaters->_array2[0]->val6 = 239;
-	g_fp->_floaters->_array2[0]->val7 = -50;
+	g_fp->_floaters->_array2[0].countdown = g_fp->_rnd.getRandomNumber(5) + 6;
+	g_fp->_floaters->_array2[0].val6 = 239;
+	g_fp->_floaters->_array2[0].val7 = -50;
 }
 
 
diff --git a/engines/fullpipe/scenes/scene20.cpp b/engines/fullpipe/scenes/scene20.cpp
index 9085f02..53c019b 100644
--- a/engines/fullpipe/scenes/scene20.cpp
+++ b/engines/fullpipe/scenes/scene20.cpp
@@ -85,7 +85,7 @@ void scene20_initScene(Scene *sc) {
 
 	for (int i = 0; i < 3; i++) {
 		g_fp->_floaters->genFlies(sc, g_fp->_rnd.getRandomNumber(101) + 70, g_fp->_rnd.getRandomNumber(51) + 175, 100, 0);
-		g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->val13 = g_fp->_rnd.getRandomNumber(9);
+		g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1].val13 = g_fp->_rnd.getRandomNumber(9);
 	}
 
 	g_fp->_currentScene = oldsc;
@@ -98,18 +98,18 @@ void sceneHandler20_updateFlies() {
 
 	if (sz < 3) {
 		g_fp->_floaters->genFlies(g_fp->_currentScene, 253, 650, 200, 0);
-		g_fp->_floaters->_array2[sz - 1]->val2 = 250;
-		g_fp->_floaters->_array2[sz - 1]->val3 = 200;
+		g_fp->_floaters->_array2[sz - 1].val2 = 250;
+		g_fp->_floaters->_array2[sz - 1].val3 = 200;
 	} else {
 		int idx = g_fp->_rnd.getRandomNumber(sz);
 
-		g_fp->_floaters->_array2[idx]->countdown = 0;
-		g_fp->_floaters->_array2[idx]->fflags |= 4u;
-		g_fp->_floaters->_array2[idx]->val2 = 250;
-		g_fp->_floaters->_array2[idx]->val3 = 200;
-		g_fp->_floaters->_array2[idx]->val6 = 253;
-		g_fp->_floaters->_array2[idx]->val7 = 650;
-		g_fp->_floaters->_array2[idx]->ani->_priority = 200;
+		g_fp->_floaters->_array2[idx].countdown = 0;
+		g_fp->_floaters->_array2[idx].fflags |= 4u;
+		g_fp->_floaters->_array2[idx].val2 = 250;
+		g_fp->_floaters->_array2[idx].val3 = 200;
+		g_fp->_floaters->_array2[idx].val6 = 253;
+		g_fp->_floaters->_array2[idx].val7 = 650;
+		g_fp->_floaters->_array2[idx].ani->_priority = 200;
 	}
 
 	g_vars->scene20_fliesCountdown = g_fp->_rnd.getRandomNumber(200) + 400;
diff --git a/engines/fullpipe/scenes/scene28.cpp b/engines/fullpipe/scenes/scene28.cpp
index 7cf683a..c5422bf 100644
--- a/engines/fullpipe/scenes/scene28.cpp
+++ b/engines/fullpipe/scenes/scene28.cpp
@@ -172,13 +172,13 @@ void sceneHandler28_turnOn2() {
 	if (g_vars->scene28_fliesArePresent) {
 		g_fp->_floaters->genFlies(g_fp->_currentScene, 1013, 329, 60, 4);
 
-		g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->val13 = 30;
-		g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->countdown = g_fp->_rnd.getRandomNumber(12) + 12;
+		g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1].val13 = 30;
+		g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1].countdown = g_fp->_rnd.getRandomNumber(12) + 12;
 
 		g_fp->_floaters->genFlies(g_fp->_currentScene, 1074, 311, 60, 4);
 
-		g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->val13 = 30;
-		g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->countdown = g_fp->_rnd.getRandomNumber(12) + 12;
+		g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1].val13 = 30;
+		g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1].countdown = g_fp->_rnd.getRandomNumber(12) + 12;
 	}
 
 	g_vars->scene28_fliesArePresent = false;
@@ -467,8 +467,8 @@ int sceneHandler28(ExCommand *cmd) {
 		g_fp->_floaters->update();
 
 		for (uint i = 0; i < g_fp->_floaters->_array2.size(); i++)
-			if (g_fp->_floaters->_array2[i]->val13 == 1)
-				g_fp->_floaters->_array2[i]->ani->_priority = 15;
+			if (g_fp->_floaters->_array2[i].val13 == 1)
+				g_fp->_floaters->_array2[i].ani->_priority = 15;
 
 		g_fp->_behaviorManager->updateBehaviors();
 
diff --git a/engines/fullpipe/scenes/scene34.cpp b/engines/fullpipe/scenes/scene34.cpp
index 040d023..b51715a 100644
--- a/engines/fullpipe/scenes/scene34.cpp
+++ b/engines/fullpipe/scenes/scene34.cpp
@@ -160,9 +160,9 @@ void sceneHandler34_climb() {
 void sceneHandler34_genFlies() {
 	g_fp->_floaters->genFlies(g_fp->_currentScene, 1072, -50, 100, 4);
 
-	g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->countdown = 1;
-	g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->val6 = 1072;
-	g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->val7 = -50;
+	g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1].countdown = 1;
+	g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1].val6 = 1072;
+	g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1].val7 = -50;
 
 	g_vars->scene34_fliesCountdown = g_fp->_rnd.getRandomNumber(500) + 500;
 }
diff --git a/engines/fullpipe/scenes/scene35.cpp b/engines/fullpipe/scenes/scene35.cpp
index ed2ab46..abeffbe 100644
--- a/engines/fullpipe/scenes/scene35.cpp
+++ b/engines/fullpipe/scenes/scene35.cpp
@@ -141,9 +141,9 @@ void sceneHandler35_genFlies() {
 
 			xoff += 40;
 
-			g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->val2 = 1084;
-			g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->val3 = y;
-			g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->val11 = 8.0;
+			g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1].val2 = 1084;
+			g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1].val3 = y;
+			g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1].val11 = 8.0;
 		}
 
 		g_vars->scene35_fliesCounter = 0;
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index 8c2807f..c1daea0 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -35,56 +35,37 @@
 namespace Fullpipe {
 
 StepArray::StepArray() {
-	_points = 0;
-	_maxPointIndex = 0;
 	_currPointIndex = 0;
-	_pointsCount = 0;
-	_isEos = 0;
-}
-
-StepArray::~StepArray() {
-	if (_pointsCount) {
-		for (int i = 0; i < _pointsCount; i++)
-			delete _points[i];
-
-		free(_points);
-
-		_points = 0;
-	}
+	_isEos = false;
 }
 
 void StepArray::clear() {
 	_currPointIndex = 0;
-	_maxPointIndex = 0;
-	_isEos = 0;
-
-	for (int i = 0; i < _pointsCount; i++) {
-		_points[i]->x = 0;
-		_points[i]->y = 0;
-	}
+	_isEos = false;
+	_points.clear();
 }
 
 Common::Point StepArray::getCurrPoint() const {
-	if (_isEos || _points == 0) {
+	if (_isEos || !_points.size()) {
 		return Common::Point();
 	}
 
-	return Common::Point(_points[_currPointIndex]->x,
-						 _points[_currPointIndex]->y);
+	return Common::Point(_points[_currPointIndex].x,
+						 _points[_currPointIndex].y);
 }
 
 Common::Point StepArray::getPoint(int index, int offset) const {
 	if (index == -1)
 		index = _currPointIndex;
 
-	if (index + offset > _maxPointIndex - 1)
-		offset = _maxPointIndex - index;
+	if (index + offset > getPointsCount() - 1)
+		offset = getPointsCount() - index;
 
 	Common::Point point;
 
 	while (offset >= 1) {
-		point.x += _points[index]->x;
-		point.y += _points[index]->y;
+		point.x += _points[index].x;
+		point.y += _points[index].y;
 
 		index++;
 		offset--;
@@ -94,33 +75,18 @@ Common::Point StepArray::getPoint(int index, int offset) const {
 }
 
 bool StepArray::gotoNextPoint() {
-	if (_currPointIndex < _maxPointIndex - 1) {
+	if (_currPointIndex < getPointsCount() - 1) {
 		_currPointIndex++;
 		return true;
 	} else {
-		_isEos = 1;
+		_isEos = true;
 		return false;
 	}
 }
 
-void StepArray::insertPoints(Common::Point **points, int pointsCount) {
-	if (_currPointIndex + pointsCount >= _pointsCount) {
-		_points = (Common::Point **)realloc(_points, sizeof(Common::Point *) * (_pointsCount + pointsCount));
-
-		if (!_points) {
-			error("Out of memory at StepArray::insertPoints()");
-		}
-
-		for(int i = 0; i < pointsCount; i++)
-			_points[_pointsCount + i] = new Common::Point;
-
-		_pointsCount += pointsCount;
-	}
-
-	_maxPointIndex = _currPointIndex + pointsCount;
-
-	for (int i = 0; i < pointsCount; i++)
-		*_points[_currPointIndex + i] = *points[i];
+void StepArray::insertPoints(const PointList &points) {
+	_points.resize(_currPointIndex + points.size());
+	Common::copy(points.begin(), points.end(), _points.begin() + _currPointIndex);
 }
 
 StaticANIObject::StaticANIObject() {
@@ -179,7 +145,7 @@ StaticANIObject::StaticANIObject(StaticANIObject *src) : GameObject(src) {
 	_objtype = kObjTypeStaticANIObject;
 
 	for (uint i = 0; i < src->_staticsList.size(); i++)
-		_staticsList.push_back(new Statics(*src->_staticsList[i], false));
+		_staticsList.push_back(new Statics(src->_staticsList[i], false));
 
 	_movement = 0;
 	_statics = 0;
@@ -427,7 +393,7 @@ Movement *StaticANIObject::getMovementById(int itemId) {
 	return 0;
 }
 
-int StaticANIObject::getMovementIdById(int itemId) {
+int StaticANIObject::getMovementIdById(int itemId) const {
 	for (uint i = 0; i < _movements.size(); i++) {
 		Movement *mov = _movements[i];
 
@@ -581,7 +547,7 @@ Statics *StaticANIObject::addReverseStatics(Statics *st) {
 	Statics *res = getStaticsById(st->_staticsId ^ 0x4000);
 
 	if (!res) {
-		res = new Statics(*st, true);
+		res = new Statics(st, true);
 		_staticsList.push_back(res);
 	}
 
@@ -1169,7 +1135,7 @@ void StaticANIObject::playIdle() {
 		adjustSomeXY();
 }
 
-void StaticANIObject::startAnimSteps(int movementId, int messageQueueId, int x, int y, Common::Point **points, int pointsCount, int someDynamicPhaseIndex) {
+void StaticANIObject::startAnimSteps(int movementId, int messageQueueId, int x, int y, const PointList &points, int someDynamicPhaseIndex) {
 	Movement *mov = 0;
 
 	if (!(_flags & 0x80)) {
@@ -1205,7 +1171,7 @@ void StaticANIObject::startAnimSteps(int movementId, int messageQueueId, int x,
 		_movement->gotoFirstFrame();
 
 	_stepArray.clear();
-	_stepArray.insertPoints(points, pointsCount);
+	_stepArray.insertPoints(points);
 
 	if (!(_flags & 0x40)) {
 		if (!_movement->_currDynamicPhaseIndex) {
@@ -1393,17 +1359,17 @@ Statics::Statics() {
 	_data = nullptr;
 }
 
-Statics::Statics(Statics &src, bool reverse) : DynamicPhase(src, reverse) {
-	_staticsId = src._staticsId;
+Statics::Statics(Statics *src, bool reverse) : DynamicPhase(src, reverse) {
+	_staticsId = src->_staticsId;
 
 	if (reverse) {
 		_staticsId ^= 0x4000;
-		_staticsName = sO_MirroredTo + src._staticsName;
+		_staticsName = sO_MirroredTo + src->_staticsName;
 	} else {
-		_staticsName = src._staticsName;
+		_staticsName = src->_staticsName;
 	}
 
-	_memfilename = src._memfilename;
+	_memfilename = src->_memfilename;
 }
 
 bool Statics::load(MfcArchive &file) {
@@ -1582,7 +1548,7 @@ Movement::Movement(Movement *src, int *oldIdxs, int newSize, StaticANIObject *an
 			src->setDynamicPhaseIndex(i);
 
 			if (i < newSize - 1)
-				_dynamicPhases.push_back(new DynamicPhase(*src->_currDynamicPhase, 0));
+				_dynamicPhases.push_back(new DynamicPhase(src->_currDynamicPhase, 0));
 
 			_framePosOffsets[i].x = src->_framePosOffsets[i].x;
 			_framePosOffsets[i].y = src->_framePosOffsets[i].y;
@@ -2106,18 +2072,18 @@ DynamicPhase::DynamicPhase() {
 	_data = nullptr;
 }
 
-DynamicPhase::DynamicPhase(DynamicPhase &src, bool reverse) {
-	_field_7C = src._field_7C;
+DynamicPhase::DynamicPhase(DynamicPhase *src, bool reverse) {
+	_field_7C = src->_field_7C;
 	_field_7E = 0;
 
 	debugC(1, kDebugAnimation, "DynamicPhase::DynamicPhase(src, %d)", reverse);
 
 	if (reverse) {
-		if (!src._bitmap)
-			src.init();
+		if (!src->_bitmap)
+			src->init();
 
-		_bitmap.reset(src._bitmap->reverseImage());
-		_dataSize = src._dataSize;
+		_bitmap.reset(src->_bitmap->reverseImage());
+		_dataSize = src->_dataSize;
 
 		if (g_fp->_currArchive) {
 			_mfield_14 = 0;
@@ -2126,45 +2092,45 @@ DynamicPhase::DynamicPhase(DynamicPhase &src, bool reverse) {
 
 		_mflags |= 1;
 
-		_someX = src._someX;
-		_someY = src._someY;
+		_someX = src->_someX;
+		_someY = src->_someY;
 	} else {
-		_mfield_14 = src._mfield_14;
-		_mfield_8 = src._mfield_8;
-		_mflags = src._mflags;
+		_mfield_14 = src->_mfield_14;
+		_mfield_8 = src->_mfield_8;
+		_mflags = src->_mflags;
 
-		_memfilename = src._memfilename;
-		_dataSize = src._dataSize;
-		_mfield_10 = src._mfield_10;
-		_libHandle = src._libHandle;
+		_memfilename = src->_memfilename;
+		_dataSize = src->_dataSize;
+		_mfield_10 = src->_mfield_10;
+		_libHandle = src->_libHandle;
 
-		if (src._bitmap) {
+		if (src->_bitmap) {
 			_field_54 = 1;
-			_bitmap.reset(src._bitmap->reverseImage(false));
+			_bitmap.reset(src->_bitmap->reverseImage(false));
 		}
 
-		_someX = src._someX;
-		_someY = src._someY;
+		_someX = src->_someX;
+		_someY = src->_someY;
 	}
 
-	_rect = src._rect;
+	_rect = src->_rect;
 
-	_width = src._width;
-	_height = src._height;
-	_field_7C = src._field_7C;
+	_width = src->_width;
+	_height = src->_height;
+	_field_7C = src->_field_7C;
 
-	if (src.getExCommand())
-		_exCommand = src.getExCommand()->createClone();
+	if (src->getExCommand())
+		_exCommand = src->getExCommand()->createClone();
 	else
 		_exCommand = 0;
 
-	_initialCountdown = src._initialCountdown;
-	_field_6A = src._field_6A;
-	_dynFlags = src._dynFlags;
+	_initialCountdown = src->_initialCountdown;
+	_field_6A = src->_field_6A;
+	_dynFlags = src->_dynFlags;
 
-	setPaletteData(src.getPaletteData());
+	setPaletteData(src->getPaletteData());
 
-	copyMemoryObject2(src);
+	copyMemoryObject2(*src);
 }
 
 bool DynamicPhase::load(MfcArchive &file) {
diff --git a/engines/fullpipe/statics.h b/engines/fullpipe/statics.h
index 841c158..124a293 100644
--- a/engines/fullpipe/statics.h
+++ b/engines/fullpipe/statics.h
@@ -31,23 +31,20 @@ class ExCommand;
 
 class StepArray : public CObject {
 	int _currPointIndex;
-	Common::Point **_points;
-	int _maxPointIndex;
-	int _pointsCount;
-	int _isEos;
+	PointList _points;
+	bool _isEos;
 
   public:
 	StepArray();
-	~StepArray();
 	void clear();
 
-	int getCurrPointIndex() { return _currPointIndex; }
-	int getPointsCount() { return _maxPointIndex; }
+	int getCurrPointIndex() const { return _currPointIndex; }
+	int getPointsCount() const { return _points.size(); }
 
 	Common::Point getCurrPoint() const;
 	Common::Point getPoint(int index, int offset) const;
 	bool gotoNextPoint();
-	void insertPoints(Common::Point **points, int pointsCount);
+	void insertPoints(const PointList &points);
 };
 
 class StaticPhase : public Picture {
@@ -78,7 +75,7 @@ class DynamicPhase : public StaticPhase {
 
   public:
 	DynamicPhase();
-	DynamicPhase(DynamicPhase &src, bool reverse);
+	DynamicPhase(DynamicPhase *src, bool reverse);
 
 	virtual bool load(MfcArchive &file);
 
@@ -93,7 +90,7 @@ class Statics : public DynamicPhase {
 
   public:
 	Statics();
-	Statics(Statics &src, bool reverse);
+	Statics(Statics *src, bool reverse);
 
 	virtual bool load(MfcArchive &file);
 	virtual void init();
@@ -122,7 +119,7 @@ class Movement : public GameObject {
 	int _counter;
 	Common::Array<DynamicPhase *> _dynamicPhases;
 	int _field_78;
-	Common::Array<Common::Point> _framePosOffsets;
+	PointList _framePosOffsets;
 	Movement *_currMovement;
 	int _field_84;
 	DynamicPhase *_currDynamicPhase;
@@ -204,7 +201,7 @@ public:
 	Statics *getStaticsById(int id);
 	Statics *getStaticsByName(const Common::String &name);
 	Movement *getMovementById(int id);
-	int getMovementIdById(int itemId);
+	int getMovementIdById(int itemId) const;
 	Movement *getMovementByName(const Common::String &name);
 	Common::Point getCurrDimensions() const;
 
@@ -232,7 +229,7 @@ public:
 
 	bool startAnim(int movementId, int messageQueueId, int dynPhaseIdx);
 	bool startAnimEx(int movid, int parId, int flag1, int flag2);
-	void startAnimSteps(int movementId, int messageQueueId, int x, int y, Common::Point **points, int pointsCount, int someDynamicPhaseIndex);
+	void startAnimSteps(int movementId, int messageQueueId, int x, int y, const PointList &points, int someDynamicPhaseIndex);
 
 	void hide();
 	void show1(int x, int y, int movementId, int mqId);


Commit: a475cec2aab9a56e618e7858373b40b0cbda5aed
    https://github.com/scummvm/scummvm/commit/a475cec2aab9a56e618e7858373b40b0cbda5aed
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Remove unnecessary constructors

These appear to be default member-wise copy constructors or POD
constructors that zero all members. I suspect that quite a few
pointer-taking constructors are actually supposed to be
copy-constructors but since they don't all just do default
member-wise copies I do not feel confident in changing them without
verifying that there are not separate copy constructors in the
disassembly, and I don't have the database for this game.

Changed paths:
    engines/fullpipe/input.cpp
    engines/fullpipe/input.h
    engines/fullpipe/messages.cpp
    engines/fullpipe/messages.h
    engines/fullpipe/motion.cpp


diff --git a/engines/fullpipe/input.cpp b/engines/fullpipe/input.cpp
index 6bd992a..d692f87 100644
--- a/engines/fullpipe/input.cpp
+++ b/engines/fullpipe/input.cpp
@@ -71,7 +71,7 @@ void setInputDisabled(bool state) {
 }
 
 void InputController::addCursor(CursorInfo *cursor) {
-	CursorInfo *newc = new CursorInfo(cursor);
+	CursorInfo *newc = new CursorInfo(*cursor);
 	const Dims dims = cursor->picture->getDimensions();
 
 	newc->width = dims.x;
@@ -119,28 +119,6 @@ void InputController::setCursor(int cursorId) {
 	}
 }
 
-CursorInfo::CursorInfo() {
-	pictureId = 0;
-	picture = 0;
-	hotspotX = 0;
-	hotspotY = 0;
-	itemPictureOffsX = 0;
-	itemPictureOffsY = 0;
-	width = 0;
-	height = 0;
-}
-
-CursorInfo::CursorInfo(CursorInfo *src) {
-	pictureId = src->pictureId;
-	picture = src->picture;
-	hotspotX = src->hotspotX;
-	hotspotY = src->hotspotY;
-	itemPictureOffsX = src->itemPictureOffsX;
-	itemPictureOffsY = src->itemPictureOffsY;
-	width = src->width;
-	height = src->height;
-}
-
 void FullpipeEngine::setCursor(int id) {
 	if (_inputController)
 		_inputController->setCursor(id);
diff --git a/engines/fullpipe/input.h b/engines/fullpipe/input.h
index 6a1d0f8..8efb1c4 100644
--- a/engines/fullpipe/input.h
+++ b/engines/fullpipe/input.h
@@ -39,8 +39,7 @@ struct CursorInfo {
 	int width;
 	int height;
 
-	CursorInfo();
-	CursorInfo(CursorInfo *src);
+	CursorInfo() { memset(this, 0, sizeof(*this)); }
 };
 
 typedef Common::Array<CursorInfo *> CursorsArray;
diff --git a/engines/fullpipe/messages.cpp b/engines/fullpipe/messages.cpp
index 632e054..ece904d 100644
--- a/engines/fullpipe/messages.cpp
+++ b/engines/fullpipe/messages.cpp
@@ -37,7 +37,7 @@ ExCommand::ExCommand() {
 	_parId = 0;
 }
 
-ExCommand::ExCommand(ExCommand *src) : Message(src) {
+ExCommand::ExCommand(ExCommand *src) : Message(*src) {
 	_field_3C = 1;
 	_messageNum = src->_messageNum;
 	_excFlags = src->_excFlags;
@@ -174,22 +174,6 @@ Message::Message() {
 	_field_34 = 0;
 }
 
-Message::Message(Message *src) {
-	_parentId = src->_parentId;
-	_messageKind = src->_messageKind;
-	_x = src->_x;
-	_y = src->_y;
-	_field_14 = src->_field_14;
-	_sceneClickX = src->_sceneClickX;
-	_sceneClickY = src->_sceneClickY;
-	_field_20 = src->_field_20;
-	_field_24 = src->_field_24;
-	_param = src->_param;
-	_field_2C = src->_field_2C;
-	_field_30 = src->_field_30;
-	_field_34 = src->_field_34;
-}
-
 Message::Message(int16 parentId, int messageKind, int x, int y, int a6, int a7, int sceneClickX, int sceneClickY, int a10) {
 	_messageKind = messageKind;
 	_parentId = parentId;
diff --git a/engines/fullpipe/messages.h b/engines/fullpipe/messages.h
index 74af61c..91677a1 100644
--- a/engines/fullpipe/messages.h
+++ b/engines/fullpipe/messages.h
@@ -53,8 +53,6 @@ class Message : public CObject {
 
  public:
 	Message();
-	Message(Message *src);
-	virtual ~Message() {}
 
 	Message(int16 parentId, int messageKind, int x, int y, int a6, int a7, int sceneClickX, int sceneClickY, int a10);
 };
diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp
index 005ed70..4f854b6 100644
--- a/engines/fullpipe/motion.cpp
+++ b/engines/fullpipe/motion.cpp
@@ -713,19 +713,6 @@ MctlConnectionPoint::MctlConnectionPoint() {
 	_mctlmirror = 0;
 }
 
-MctlMQ::MctlMQ(MctlMQ *src) {
-	index = src->index;
-	pt1 = src->pt1;
-	pt2 = src->pt2;
-	distance1 = src->distance1;
-	distance2 = src->distance2;
-	subIndex = src->subIndex;
-	item1Index = src->item1Index;
-	items = src->items;
-	itemsCount = src->itemsCount;
-	flags = src->flags;
-}
-
 void MctlMQ::clear() {
 	index = 0;
 	pt1.x = pt1.y = 0;


Commit: 7232f67fe91381be359d3e46ce0ea78442033adf
    https://github.com/scummvm/scummvm/commit/7232f67fe91381be359d3e46ce0ea78442033adf
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix memory leak of graph nodes and lists

Changed paths:
    engines/fullpipe/motion.cpp


diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp
index 4f854b6..7c46d17 100644
--- a/engines/fullpipe/motion.cpp
+++ b/engines/fullpipe/motion.cpp
@@ -171,7 +171,9 @@ void MctlCompound::initMctlGraph() {
 		MctlGraph *newgr = new MctlGraph();
 
 		newgr->_links = gr->_links;
+		gr->_links.clear();
 		newgr->_nodes = gr->_nodes;
+		gr->_nodes.clear();
 
 		_motionControllers[i]->_motionControllerObj.reset(newgr);
 	}


Commit: a2e2569347794ee2c54bfac3b64076b481f50fd6
    https://github.com/scummvm/scummvm/commit/a2e2569347794ee2c54bfac3b64076b481f50fd6
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Use flag enum

Changed paths:
    engines/fullpipe/messages.cpp


diff --git a/engines/fullpipe/messages.cpp b/engines/fullpipe/messages.cpp
index ece904d..22d0c55 100644
--- a/engines/fullpipe/messages.cpp
+++ b/engines/fullpipe/messages.cpp
@@ -285,7 +285,7 @@ MessageQueue::~MessageQueue() {
 	if (_field_14)
 		delete _field_14;
 
-	if (_flags & 2) {
+	if (_flags & kInGlobalQueue) {
 		g_fp->_globalMessageQueueList->removeQueueById(_id);
 	}
 


Commit: 4cc64c4139903c9a6b769855ab2a8a8125beb644
    https://github.com/scummvm/scummvm/commit/4cc64c4139903c9a6b769855ab2a8a8125beb644
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix memory leaks in PictureObject, Background

Changed paths:
    engines/fullpipe/gfx.cpp
    engines/fullpipe/gfx.h
    engines/fullpipe/init.cpp
    engines/fullpipe/inventory.cpp
    engines/fullpipe/modal.cpp
    engines/fullpipe/scene.cpp
    engines/fullpipe/scene.h


diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp
index ae2ddac..a2626e2 100644
--- a/engines/fullpipe/gfx.cpp
+++ b/engines/fullpipe/gfx.cpp
@@ -38,22 +38,11 @@ Background::Background() {
 	_x = 0;
 	_y = 0;
 	_messageQueueId = 0;
-	_bigPictureArray1Count = 0;
-	_bigPictureArray2Count = 0;
-	_bigPictureArray = 0;
 }
 
 Background::~Background() {
-	_picObjList.clear();
-
-	for (int i = 0; i < _bigPictureArray1Count; i++) {
-		for (int j = 0; j < _bigPictureArray2Count; j++)
-			delete _bigPictureArray[i][j];
-
-		free(_bigPictureArray[i]);
-	}
-
-	free(_bigPictureArray);
+	Common::for_each(_picObjList.begin(), _picObjList.end(), Common::DefaultDeleter<PictureObject>());
+	Common::for_each(_bigPictureArray.begin(), _bigPictureArray.end(), Common::DefaultDeleter<BigPicture>());
 }
 
 bool Background::load(MfcArchive &file) {
@@ -69,25 +58,16 @@ bool Background::load(MfcArchive &file) {
 		addPictureObject(pct);
 	}
 
-	assert(g_fp->_gameProjectVersion >= 4);
-
-	_bigPictureArray1Count = file.readUint32LE();
-
 	assert(g_fp->_gameProjectVersion >= 5);
 
-	_bigPictureArray2Count = file.readUint32LE();
-
-	_bigPictureArray = (BigPicture ***)calloc(_bigPictureArray1Count, sizeof(BigPicture **));
+	_bigPictureXDim = file.readUint32LE();
+	_bigPictureYDim = file.readUint32LE();
 
-	debugC(6, kDebugLoading, "bigPictureArray[%d][%d]", _bigPictureArray1Count, _bigPictureArray2Count);
+	debugC(6, kDebugLoading, "bigPictureArray[%d][%d]", _bigPictureXDim, _bigPictureYDim);
 
-	for (int i = 0; i < _bigPictureArray1Count; i++) {
-		_bigPictureArray[i] = (BigPicture **)calloc(_bigPictureArray2Count, sizeof(BigPicture *));
-		for (int j = 0; j < _bigPictureArray2Count; j++) {
-			_bigPictureArray[i][j] = new BigPicture();
-
-			_bigPictureArray[i][j]->load(file);
-		}
+	for (uint i = 0; i < _bigPictureXDim * _bigPictureYDim; ++i) {
+		_bigPictureArray.push_back(new BigPicture());
+		_bigPictureArray[i]->load(file);
 	}
 
 	return true;
@@ -114,19 +94,11 @@ void Background::addPictureObject(PictureObject *pct) {
 PictureObject::PictureObject() {
 	_ox = 0;
 	_oy = 0;
-	_picture = 0;
 	_ox2 = 0;
 	_oy2 = 0;
-	_pictureObject2List = 0;
 	_objtype = kObjTypePictureObject;
 }
 
-PictureObject::~PictureObject() {
-	delete _picture;
-	_pictureObject2List->clear();
-	delete _pictureObject2List;
-}
-
 PictureObject::PictureObject(PictureObject *src) : GameObject(src) {
 	_picture = src->_picture;
 	_ox2 = _ox;
@@ -140,21 +112,17 @@ bool PictureObject::load(MfcArchive &file, bool bigPicture) {
 	GameObject::load(file);
 
 	if (bigPicture)
-		_picture = new BigPicture();
+		_picture = Common::SharedPtr<Picture>(new BigPicture());
 	else
-		_picture = new Picture();
+		_picture = Common::SharedPtr<Picture>(new Picture());
 
 	_picture->load(file);
 
-	_pictureObject2List = new Common::Array<GameObject *>;
-
 	int count = file.readUint16LE();
 
 	if (count > 0) {
-		GameObject *o = new GameObject();
-
-		o->load(file);
-		_pictureObject2List->push_back(o);
+		_pictureObject2List.push_back(GameObject());
+		_pictureObject2List.back().load(file);
 	}
 
 	_ox2 = _ox;
diff --git a/engines/fullpipe/gfx.h b/engines/fullpipe/gfx.h
index 252f855..a7c0c76 100644
--- a/engines/fullpipe/gfx.h
+++ b/engines/fullpipe/gfx.h
@@ -167,17 +167,10 @@ class GameObject : public CObject {
 };
 
 class PictureObject : public GameObject {
-  public:
-	Picture *_picture;
-	Common::Array<GameObject *> *_pictureObject2List;
-	int _ox2;
-	int _oy2;
-
-  public:
+public:
 	PictureObject();
 
 	PictureObject(PictureObject *src);
-	virtual ~PictureObject();
 
 	virtual bool load(MfcArchive &file, bool bigPicture);
 	virtual bool load(MfcArchive &file) { assert(0); return false; } // Disable base class
@@ -190,10 +183,18 @@ class PictureObject : public GameObject {
 	bool isPointInside(int x, int y);
 	bool isPixelHitAtPos(int x, int y);
 	void setOXY2();
+
+	Common::SharedPtr<Picture> _picture;
+
+private:
+	Common::Array<GameObject> _pictureObject2List;
+	int _ox2;
+	int _oy2;
 };
 
 class Background : public CObject {
-  public:
+public:
+	/** list items are owned */
 	Common::Array<PictureObject *> _picObjList;
 
 	Common::String _bgname;
@@ -201,18 +202,19 @@ class Background : public CObject {
 	int _y;
 	int16 _messageQueueId;
 	Palette _palette;
-	int _bigPictureArray1Count;
-	int _bigPictureArray2Count;
-	BigPicture ***_bigPictureArray;
+	/** list items are owned */
+	Common::Array<BigPicture *> _bigPictureArray;
+	uint _bigPictureXDim;
+	uint _bigPictureYDim;
 
-  public:
+public:
 	Background();
 	virtual ~Background();
 
 	virtual bool load(MfcArchive &file);
 	void addPictureObject(PictureObject *pct);
 
-	BigPicture *getBigPicture(int x, int y) { return _bigPictureArray[x][y]; }
+	BigPicture *getBigPicture(int x, int y) { return _bigPictureArray[y * _bigPictureYDim + x]; }
 };
 
 struct ShadowsItem {
diff --git a/engines/fullpipe/init.cpp b/engines/fullpipe/init.cpp
index db95cd8..d49d956 100644
--- a/engines/fullpipe/init.cpp
+++ b/engines/fullpipe/init.cpp
@@ -144,7 +144,7 @@ void FullpipeEngine::setLevelStates() {
 
 void FullpipeEngine::addCursor(CursorInfo *cursorInfo, Scene *inv, int pictureId, int hotspotX, int hotspotY, int itemPictureOffsX, int itemPictureOffsY) {
 	cursorInfo->pictureId = pictureId;
-	cursorInfo->picture = inv->getPictureObjectById(pictureId, 0)->_picture;
+	cursorInfo->picture = inv->getPictureObjectById(pictureId, 0)->_picture.get();
 	cursorInfo->hotspotX = hotspotX;
 	cursorInfo->hotspotY = hotspotY;
 	cursorInfo->itemPictureOffsX = itemPictureOffsX;
diff --git a/engines/fullpipe/inventory.cpp b/engines/fullpipe/inventory.cpp
index cb9eec7..952b359 100644
--- a/engines/fullpipe/inventory.cpp
+++ b/engines/fullpipe/inventory.cpp
@@ -427,7 +427,7 @@ int Inventory2::selectItem(int itemId) {
 	if (_scene) {
 		int idx = getInventoryPoolItemIndexById(itemId);
 
-		Picture *pic = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectId1, 0)->_picture;
+		Picture *pic = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectId1, 0)->_picture.get();
 		g_fp->getGameLoaderInputController()->setCursorItemPicture(pic);
 	}
 
diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp
index f07fb9a..0f9877a 100644
--- a/engines/fullpipe/modal.cpp
+++ b/engines/fullpipe/modal.cpp
@@ -1796,9 +1796,9 @@ void ModalHelp::launch() {
 
 	if (_mainMenuScene) {
 		if (g_fp->isDemo() && g_fp->getLanguage() == Common::RU_RUS)
-			_bg = _mainMenuScene->getPictureObjectById(364, 0)->_picture;
+			_bg = _mainMenuScene->getPictureObjectById(364, 0)->_picture.get();
 		else
-			_bg = _mainMenuScene->getPictureObjectById(PIC_HLP_BGR, 0)->_picture;
+			_bg = _mainMenuScene->getPictureObjectById(PIC_HLP_BGR, 0)->_picture.get();
 		_isRunning = 1;
 	}
 }
diff --git a/engines/fullpipe/scene.cpp b/engines/fullpipe/scene.cpp
index 69ab170..d4da322 100644
--- a/engines/fullpipe/scene.cpp
+++ b/engines/fullpipe/scene.cpp
@@ -655,7 +655,7 @@ void Scene::update(int counterdiff) {
 }
 
 void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
-	if (!_picObjList.size() && !_bigPictureArray1Count)
+	if (!_picObjList.size() && !_bigPictureXDim)
 		return;
 
 	if (_palette.size()) {
@@ -682,11 +682,11 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
 
 	Dims dims;
 
-	debugC(1, kDebugDrawing, "_bigPict: %d objlist: %d", _bigPictureArray1Count, _picObjList.size());
+	debugC(1, kDebugDrawing, "_bigPict: %d objlist: %d", _bigPictureXDim, _picObjList.size());
 
-	if (drawBg && _bigPictureArray1Count && _picObjList.size()) {
+	if (drawBg && _bigPictureXDim && _picObjList.size()) {
 
-		dims = _bigPictureArray[0][0]->getDimensions();
+		dims = _bigPictureArray[0]->getDimensions();
 
 		int width = dims.x;
 		int height = dims.y;
@@ -716,26 +716,26 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
 		int bgPosX = g_fp->_sceneRect.left - bgOffsetX;
 
 		if (bgPosX < g_fp->_sceneRect.right - 1) {
-			while (1) {
-				int v25 = bgNumY;
+			for (;;) {
+				uint v25 = bgNumY;
 				for (int y = g_fp->_sceneRect.top - bgOffsetY; y < g_fp->_sceneRect.bottom - 1;) {
-					BigPicture *v27 = _bigPictureArray[bgNumX][v25];
+					BigPicture *v27 = getBigPicture(bgNumX, v25);
 					v27->draw(bgPosX, y, 0, 0);
 					y += v27->getDimensions().y;
 					v25++;
 
-					if (v25 >= _bigPictureArray2Count) {
+					if (v25 >= _bigPictureYDim) {
 						if (!(_picObjList[0]->_flags & 0x20))
 							break;
 						v25 = 0;
 					}
 				}
-				dims = _bigPictureArray[bgNumX][0]->getDimensions();
+				dims = getBigPicture(bgNumX, 0)->getDimensions();
 				int oldx = dims.x + bgPosX;
 				bgPosX += dims.x;
 				bgNumX++;
 
-				if (bgNumX >= _bigPictureArray1Count) {
+				if (bgNumX >= (int)_bigPictureXDim) {
 					if (!(_picObjList[0]->_flags & 0x2))
 						break;
 					bgNumX = 0;
diff --git a/engines/fullpipe/scene.h b/engines/fullpipe/scene.h
index cc4cf17..97e654d 100644
--- a/engines/fullpipe/scene.h
+++ b/engines/fullpipe/scene.h
@@ -32,7 +32,9 @@ class MessageQueue;
 
 class Scene : public Background {
  public:
+	/** list items are owned */
 	Common::Array<StaticANIObject *> _staticANIObjectList1;
+
 	Common::Array<StaticANIObject *> _staticANIObjectList2;
 	Common::Array<MessageQueue *> _messageQueueList;
 	// PtrList _faObjectList; // not used


Commit: a6fc77ec65561f9f0768322b618f6ceac21f1efc
    https://github.com/scummvm/scummvm/commit/a6fc77ec65561f9f0768322b618f6ceac21f1efc
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Clarify ownership of pointer arrays in StaticANIObject

Changed paths:
    engines/fullpipe/statics.cpp
    engines/fullpipe/statics.h


diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index c1daea0..a85b90b 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -112,16 +112,8 @@ StaticANIObject::StaticANIObject() {
 }
 
 StaticANIObject::~StaticANIObject() {
-	for (uint i = 0; i < _staticsList.size(); i++)
-		delete _staticsList[i];
-
-	_staticsList.clear();
-
-	for (uint i = 0; i < _movements.size(); i++)
-		delete _movements[i];
-
-	_movements.clear();
-
+	Common::for_each(_staticsList.begin(), _staticsList.end(), Common::DefaultDeleter<Statics>());
+	Common::for_each(_movements.begin(), _movements.end(), Common::DefaultDeleter<Movement>());
 	g_fp->_aniHandler->detachAllObjects();
 }
 
diff --git a/engines/fullpipe/statics.h b/engines/fullpipe/statics.h
index 124a293..ab5ba67 100644
--- a/engines/fullpipe/statics.h
+++ b/engines/fullpipe/statics.h
@@ -177,7 +177,9 @@ class StaticANIObject : public GameObject {
 	int _initialCounter;
 	void (*_callback1)(int, Common::Point *point, int, int);
 	void (*_callback2)(int *);
+	/** items in list are owned */
 	Common::Array<Movement *> _movements;
+	/** items in list are owned */
 	Common::Array<Statics *> _staticsList;
 	StepArray _stepArray;
 	int16 _field_96;


Commit: c7b1f6b26c0276f0d9dafb8c4ec4daac268d26c6
    https://github.com/scummvm/scummvm/commit/c7b1f6b26c0276f0d9dafb8c4ec4daac268d26c6
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Clarify ownership of DynamicPhase::_exCommand

Changed paths:
    engines/fullpipe/messagehandlers.cpp
    engines/fullpipe/statics.cpp
    engines/fullpipe/statics.h


diff --git a/engines/fullpipe/messagehandlers.cpp b/engines/fullpipe/messagehandlers.cpp
index de22685..bd67fd4 100644
--- a/engines/fullpipe/messagehandlers.cpp
+++ b/engines/fullpipe/messagehandlers.cpp
@@ -39,18 +39,16 @@ void global_messageHandler_KickStucco() {
 	bool flip = false;
 
 	for (int i = 0; i < end; i++) {
-		ExCommand *ex = mov->getDynamicPhaseByIndex(i)->_exCommand;
-
-		if (ex)
-			if (ex->_messageKind == 35)
-				if (ex->_messageNum == SND_CMN_015) {
-					if (flip) {
-						ex->_messageNum = SND_CMN_055;
-					} else {
-						ex->_messageNum = SND_CMN_054;
-						flip = true;
-					}
-				}
+		ExCommand *ex = mov->getDynamicPhaseByIndex(i)->getExCommand();
+
+		if (ex && ex->_messageKind == 35 && ex->_messageNum == SND_CMN_015) {
+			if (flip) {
+				ex->_messageNum = SND_CMN_055;
+			} else {
+				ex->_messageNum = SND_CMN_054;
+				flip = true;
+			}
+		}
 	}
 
 	mov = g_fp->_aniMan->getMovementById(MV_MAN_HMRKICK_COINLESS);
@@ -58,18 +56,16 @@ void global_messageHandler_KickStucco() {
 	flip = false;
 
 	for (int i = 0; i < end; i++) {
-		ExCommand *ex = mov->getDynamicPhaseByIndex(i)->_exCommand;
-
-		if (ex)
-			if (ex->_messageKind == 35)
-				if (ex->_messageNum == SND_CMN_015) {
-					if (flip) {
-						ex->_messageNum = SND_CMN_055;
-					} else {
-						ex->_messageNum = SND_CMN_054;
-						flip = true;
-					}
-				}
+		ExCommand *ex = mov->getDynamicPhaseByIndex(i)->getExCommand();
+
+		if (ex && ex->_messageKind == 35 && ex->_messageNum == SND_CMN_015) {
+			if (flip) {
+				ex->_messageNum = SND_CMN_055;
+			} else {
+				ex->_messageNum = SND_CMN_054;
+				flip = true;
+			}
+		}
 	}
 }
 
@@ -78,24 +74,24 @@ void global_messageHandler_KickMetal() {
 	int end = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size();
 
 	for (int i = 0; i < end; i++) {
-		ExCommand *ex = mov->getDynamicPhaseByIndex(i)->_exCommand;
+		ExCommand *ex = mov->getDynamicPhaseByIndex(i)->getExCommand();
 
-		if (ex)
-			if (ex->_messageKind == 35)
-				if (ex->_messageNum == SND_CMN_054 || ex->_messageNum == SND_CMN_055)
-					ex->_messageNum = SND_CMN_015;
+		if (ex && ex->_messageKind == 35) {
+			if (ex->_messageNum == SND_CMN_054 || ex->_messageNum == SND_CMN_055)
+				ex->_messageNum = SND_CMN_015;
+		}
 	}
 
 	mov = g_fp->_aniMan->getMovementById(MV_MAN_HMRKICK_COINLESS);
 	end = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size();
 
 	for (int i = 0; i < end; i++) {
-		ExCommand *ex = mov->getDynamicPhaseByIndex(i)->_exCommand;
+		ExCommand *ex = mov->getDynamicPhaseByIndex(i)->getExCommand();
 
-		if (ex)
-			if (ex->_messageKind == 35)
-				if (ex->_messageNum == SND_CMN_054 || ex->_messageNum == SND_CMN_055)
-					ex->_messageNum = SND_CMN_015;
+		if (ex && ex->_messageKind == 35) {
+			if (ex->_messageNum == SND_CMN_054 || ex->_messageNum == SND_CMN_055)
+				ex->_messageNum = SND_CMN_015;
+		}
 	}
 }
 
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index a85b90b..eb28b93 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -2112,9 +2112,9 @@ DynamicPhase::DynamicPhase(DynamicPhase *src, bool reverse) {
 	_field_7C = src->_field_7C;
 
 	if (src->getExCommand())
-		_exCommand = src->getExCommand()->createClone();
+		_exCommand.reset(src->getExCommand()->createClone());
 	else
-		_exCommand = 0;
+		_exCommand.reset();
 
 	_initialCountdown = src->_initialCountdown;
 	_field_6A = src->_field_6A;
@@ -2153,11 +2153,6 @@ StaticPhase::StaticPhase() {
 	_initialCountdown = 0;
 	_countdown = 0;
 	_field_68 = 0;
-	_exCommand = 0;
-}
-
-StaticPhase::~StaticPhase() {
-	delete _exCommand;
 }
 
 bool StaticPhase::load(MfcArchive &file) {
@@ -2168,15 +2163,9 @@ bool StaticPhase::load(MfcArchive &file) {
 	_initialCountdown = file.readUint16LE();
 	_field_6A = file.readUint16LE();
 
-	if (g_fp->_gameProjectVersion >= 12) {
-		_exCommand = file.readClass<ExCommand>();
-
-		return true;
-	}
-
-	assert (g_fp->_gameProjectVersion >= 12);
+	assert(g_fp->_gameProjectVersion >= 12);
 
-	warning("StaticPhase::load(): Code continues here");
+	_exCommand.reset(file.readClass<ExCommand>());
 
 	return true;
 }
diff --git a/engines/fullpipe/statics.h b/engines/fullpipe/statics.h
index ab5ba67..fa893d6 100644
--- a/engines/fullpipe/statics.h
+++ b/engines/fullpipe/statics.h
@@ -53,15 +53,14 @@ class StaticPhase : public Picture {
 	int16 _countdown;
 	int16 _field_68;
 	int16 _field_6A;
-	ExCommand *_exCommand;
+	Common::ScopedPtr<ExCommand> _exCommand;
 
   public:
 	StaticPhase();
-	virtual ~StaticPhase();
 
 	virtual bool load(MfcArchive &file);
 
-	ExCommand *getExCommand() { return _exCommand; }
+	ExCommand *getExCommand() { return _exCommand.get(); }
 };
 
 class DynamicPhase : public StaticPhase {


Commit: cef4d7787748fe8f0fae45d2573da4dfd4cc1c85
    https://github.com/scummvm/scummvm/commit/cef4d7787748fe8f0fae45d2573da4dfd4cc1c85
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix memory leaks of MctlItems in MctlCompound

Changed paths:
    engines/fullpipe/motion.cpp
    engines/fullpipe/motion.h


diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp
index 7c46d17..a6c55bf 100644
--- a/engines/fullpipe/motion.cpp
+++ b/engines/fullpipe/motion.cpp
@@ -105,6 +105,10 @@ MovGraphLink *MotionController::getLinkByName(const char *name) {
 	return 0;
 }
 
+MctlCompound::~MctlCompound() {
+	Common::for_each(_motionControllers.begin(), _motionControllers.end(), Common::DefaultDeleter<MctlItem>());
+}
+
 bool MctlCompound::load(MfcArchive &file) {
 	debugC(5, kDebugLoading, "MctlCompound::load()");
 
@@ -731,18 +735,6 @@ MctlItem::~MctlItem() {
 	Common::for_each(_connectionPoints.begin(), _connectionPoints.end(), Common::DefaultDeleter<MctlConnectionPoint>());
 }
 
-bool MctlCompoundArray::load(MfcArchive &file) {
-	debugC(5, kDebugLoading, "MctlCompoundArray::load()");
-
-	int count = file.readUint32LE();
-
-	debugC(0, kDebugLoading, "MctlCompoundArray::count = %d", count);
-
-	assert(0);
-
-	return true;
-}
-
 MovGraphItem::MovGraphItem() {
 	ani = 0;
 	field_4 = 0;
diff --git a/engines/fullpipe/motion.h b/engines/fullpipe/motion.h
index b47cff9..f71d58a 100644
--- a/engines/fullpipe/motion.h
+++ b/engines/fullpipe/motion.h
@@ -92,16 +92,13 @@ public:
 	~MctlItem();
 };
 
-class MctlCompoundArray : public Common::Array<MctlItem *>, public CObject {
- public:
-	virtual bool load(MfcArchive &file);
-};
-
 class MctlCompound : public MotionController {
 public:
-	MctlCompoundArray _motionControllers;
+	/** list items are owned */
+	Common::Array<MctlItem *> _motionControllers;
 
 	MctlCompound() { _objtype = kObjTypeMctlCompound; }
+	virtual ~MctlCompound();
 
 	virtual bool load(MfcArchive &file);
 


Commit: a8b635e4cdac9a42d2c81517576bb970e5f9d06f
    https://github.com/scummvm/scummvm/commit/a8b635e4cdac9a42d2c81517576bb970e5f9d06f
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix leaks of DynamicPhases

I am not entirely sure this is a correct fix for these leaks;
there is still the issue of the last member of _dynamicPhases being
invalidated and not removed sometime before the destruction of
Movement. Also, some of the items in this array are not actually
owned by Movement so deleting them will cause double-frees or
use-after-frees. It may be the case that a second list should be
maintained instead containing only the objects that are created
internally within Movement. Further testing will tell for sure.

Changed paths:
    engines/fullpipe/statics.cpp
    engines/fullpipe/statics.h


diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index eb28b93..524eeff 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -1429,14 +1429,17 @@ Movement::~Movement() {
 	if (!_currMovement) {
 		if (_updateFlag1) {
 			_dynamicPhases[0]->freePixelData();
-			_dynamicPhases.remove_at(0);
+			delete _dynamicPhases.remove_at(0);
 		}
 
 		// FIXME: At this point, the last entry in _dynamicPhases is invalid
-		for (uint i = 0; i < _dynamicPhases.size() - 1; i++)
-			_dynamicPhases[i]->freePixelData();
-
-		_dynamicPhases.clear();
+		for (uint i = 0; i < _dynamicPhases.size() - 1; i++) {
+			DynamicPhase *phase = _dynamicPhases[i];
+			if (phase != _staticsObj1 && phase != _staticsObj2)
+				delete phase;
+			else
+				_dynamicPhases[i]->freePixelData();
+		}
 	}
 }
 
@@ -1844,12 +1847,12 @@ void Movement::removeFirstPhase() {
 			gotoNextFrame(0, 0);
 
 		if (!_currMovement) {
-			_dynamicPhases.remove_at(0);
+			delete _dynamicPhases.remove_at(0);
 
 			for (uint i = 0; i < _dynamicPhases.size(); i++) {
-				_framePosOffsets[i].x = _framePosOffsets[i + 1].x;
-				_framePosOffsets[i].y = _framePosOffsets[i + 1].y;
+				_framePosOffsets[i] = _framePosOffsets[i + 1];
 			}
+			_framePosOffsets.pop_back();
 		}
 		_currDynamicPhaseIndex--;
 	}
diff --git a/engines/fullpipe/statics.h b/engines/fullpipe/statics.h
index fa893d6..a309153 100644
--- a/engines/fullpipe/statics.h
+++ b/engines/fullpipe/statics.h
@@ -116,6 +116,7 @@ class Movement : public GameObject {
 	int _field_50;
 	int _counterMax;
 	int _counter;
+	/** a confusing mix of owned and unowned items */
 	Common::Array<DynamicPhase *> _dynamicPhases;
 	int _field_78;
 	PointList _framePosOffsets;


Commit: 54f8cf55ea6e041a6985056de06235a344b0dfa4
    https://github.com/scummvm/scummvm/commit/54f8cf55ea6e041a6985056de06235a344b0dfa4
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix memory leaks of InventoryPoolItem

Changed paths:
    engines/fullpipe/inventory.cpp
    engines/fullpipe/inventory.h


diff --git a/engines/fullpipe/inventory.cpp b/engines/fullpipe/inventory.cpp
index 952b359..7cf8fe9 100644
--- a/engines/fullpipe/inventory.cpp
+++ b/engines/fullpipe/inventory.cpp
@@ -30,27 +30,23 @@
 
 namespace Fullpipe {
 
-Inventory::~Inventory() {
-	_itemsPool.clear();
-}
-
 bool Inventory::load(MfcArchive &file) {
 	debugC(5, kDebugLoading | kDebugInventory, "Inventory::load()");
 
 	_sceneId = file.readUint16LE();
 	int numInvs = file.readUint32LE();
 
+	_itemsPool.resize(numInvs);
 	for (int i = 0; i < numInvs; i++) {
-		InventoryPoolItem *t = new InventoryPoolItem();
-		t->id = file.readUint16LE();
-		t->pictureObjectNormal = file.readUint16LE();
-		t->pictureObjectId1 = file.readUint16LE();
-		t->pictureObjectHover = file.readUint16LE();
-		t->pictureObjectSelected = file.readUint16LE();
-		t->flags = file.readUint32LE();
-		t->field_C = 0;
-		t->field_A = -536;
-		_itemsPool.push_back(t);
+		InventoryPoolItem &t = _itemsPool[i];
+		t.id = file.readUint16LE();
+		t.pictureObjectNormal = file.readUint16LE();
+		t.pictureObjectId1 = file.readUint16LE();
+		t.pictureObjectHover = file.readUint16LE();
+		t.pictureObjectSelected = file.readUint16LE();
+		t.flags = file.readUint32LE();
+		t.field_C = 0;
+		t.field_A = -536;
 	}
 
 	return true;
@@ -61,7 +57,7 @@ int Inventory::getInventoryPoolItemIndexById(int itemId) {
 		return -1;
 
 	for (uint i = 0; i < _itemsPool.size(); i++) {
-		if (_itemsPool[i]->id == itemId)
+		if (_itemsPool[i].id == itemId)
 			return i;
 	}
 
@@ -74,7 +70,7 @@ bool Inventory::setItemFlags(int itemId, int flags) {
 	if (idx < 0)
 		return false;
 	else
-		_itemsPool[idx]->flags = flags;
+		_itemsPool[idx].flags = flags;
 
 	return true;
 }
@@ -200,13 +196,13 @@ int Inventory2::getInventoryItemIndexById(int itemId) {
 }
 
 int Inventory2::getInventoryPoolItemIdAtIndex(int itemId) {
-	return _itemsPool[itemId]->id;
+	return _itemsPool[itemId].id;
 }
 
 int Inventory2::getInventoryPoolItemFieldCById(int itemId) {
 	for (uint i = 0; i < _itemsPool.size(); i++) {
-		if (_itemsPool[i]->id == itemId)
-			return _itemsPool[i]->field_C;
+		if (_itemsPool[i].id == itemId)
+			return _itemsPool[i].field_C;
 	}
 
 	return 0;
@@ -218,7 +214,7 @@ int Inventory2::getItemFlags(int itemId) {
 	if (idx < 0)
 		return 0;
 
-	return _itemsPool[idx]->flags;
+	return _itemsPool[idx].flags;
 }
 
 void Inventory2::rebuildItemRects() {
@@ -241,7 +237,7 @@ void Inventory2::rebuildItemRects() {
 		PictureObject *pic = _scene->_picObjList[i];
 
 		for (uint j = 0; j < _itemsPool.size(); j++) {
-			if (_itemsPool[j]->pictureObjectNormal == pic->_id) {
+			if (_itemsPool[j].pictureObjectNormal == pic->_id) {
 				if (pic->_odelay)
 					_scene->deletePictureObject(pic);
 				else
@@ -256,15 +252,15 @@ void Inventory2::rebuildItemRects() {
 		_inventoryIcons.push_back(InventoryIcon());
 		InventoryIcon &icn = _inventoryIcons.back();
 
-		icn.inventoryItemId = _itemsPool[idx]->id;
+		icn.inventoryItemId = _itemsPool[idx].id;
 
-		icn.pictureObjectNormal = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectNormal, 0);
-		icn.pictureObjectHover = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectHover, 0);
-		icn.pictureObjectSelected = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectSelected, 0);
+		icn.pictureObjectNormal = _scene->getPictureObjectById(_itemsPool[idx].pictureObjectNormal, 0);
+		icn.pictureObjectHover = _scene->getPictureObjectById(_itemsPool[idx].pictureObjectHover, 0);
+		icn.pictureObjectSelected = _scene->getPictureObjectById(_itemsPool[idx].pictureObjectSelected, 0);
 
 		const Dims dims = icn.pictureObjectNormal->getDimensions();
 
-		if (_itemsPool[idx]->flags & 0x10000) {
+		if (_itemsPool[idx].flags & 0x10000) {
 			icn.x1 = 730;
 			icn.y1 = itemY;
 			icn.x2 = dims.x + 730;
@@ -427,7 +423,7 @@ int Inventory2::selectItem(int itemId) {
 	if (_scene) {
 		int idx = getInventoryPoolItemIndexById(itemId);
 
-		Picture *pic = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectId1, 0)->_picture.get();
+		Picture *pic = _scene->getPictureObjectById(_itemsPool[idx].pictureObjectId1, 0)->_picture.get();
 		g_fp->getGameLoaderInputController()->setCursorItemPicture(pic);
 	}
 
diff --git a/engines/fullpipe/inventory.h b/engines/fullpipe/inventory.h
index 2c08c8a..e15a170 100644
--- a/engines/fullpipe/inventory.h
+++ b/engines/fullpipe/inventory.h
@@ -40,7 +40,7 @@ struct InventoryPoolItem {
 	int flags;
 };
 
-typedef Common::Array<InventoryPoolItem *> InventoryPoolItems;
+typedef Common::Array<InventoryPoolItem> InventoryPoolItems;
 
 class Inventory : public CObject {
  protected:
@@ -49,7 +49,6 @@ class Inventory : public CObject {
 
  public:
 	Inventory() { _sceneId = 0; }
-	virtual ~Inventory();
 
 	virtual bool load(MfcArchive &file);
 


Commit: 7323bef77bd6acf180a6316950c06723075e8299
    https://github.com/scummvm/scummvm/commit/7323bef77bd6acf180a6316950c06723075e8299
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Remove manual memory management of use list

Changed paths:
    engines/fullpipe/messages.cpp


diff --git a/engines/fullpipe/messages.cpp b/engines/fullpipe/messages.cpp
index 22d0c55..db75146 100644
--- a/engines/fullpipe/messages.cpp
+++ b/engines/fullpipe/messages.cpp
@@ -633,10 +633,7 @@ void GlobalMessageQueueList::disableQueueById(int id) {
 }
 
 int GlobalMessageQueueList::compact() {
-	int *useList = new int[size() + 2];
-
-	for (uint i = 0; i < size() + 2; i++)
-		useList[i] = 0;
+	Common::Array<bool> useList(size() + 2);
 
 	for (uint i = 0; i < size();) {
 		if (_storage[i]->_isFinished) {
@@ -644,7 +641,7 @@ int GlobalMessageQueueList::compact() {
 			delete remove_at(i);
 		} else {
 			if ((uint)_storage[i]->_id < size() + 2)
-				useList[_storage[i]->_id] = 1;
+				useList[_storage[i]->_id] = true;
 			i++;
 		}
 	}
@@ -656,8 +653,6 @@ int GlobalMessageQueueList::compact() {
 			break;
 	}
 
-	delete [] useList;
-
 	return i;
 }
 


Commit: c9327f29859dcbbeca99a116d9ce2aebf366ced1
    https://github.com/scummvm/scummvm/commit/c9327f29859dcbbeca99a116d9ce2aebf366ced1
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix memory leaks of PreloadItems

Changed paths:
    engines/fullpipe/gameloader.cpp
    engines/fullpipe/gameloader.h
    engines/fullpipe/lift.cpp
    engines/fullpipe/modal.cpp


diff --git a/engines/fullpipe/gameloader.cpp b/engines/fullpipe/gameloader.cpp
index 58d3a4c..e6f5b08 100644
--- a/engines/fullpipe/gameloader.cpp
+++ b/engines/fullpipe/gameloader.cpp
@@ -347,8 +347,8 @@ bool preloadCallback(PreloadItem &pre, int flag) {
 	return true;
 }
 
-void GameLoader::addPreloadItem(PreloadItem *item) {
-	_preloadItems.push_back(new PreloadItem(*item));
+void GameLoader::addPreloadItem(const PreloadItem &item) {
+	_preloadItems.push_back(item);
 }
 
 bool GameLoader::preloadScene(int sceneId, int entranceId) {
@@ -363,7 +363,7 @@ bool GameLoader::preloadScene(int sceneId, int entranceId) {
 	int idx = -1;
 
 	for (uint i = 0; i < _preloadItems.size(); i++)
-		if (_preloadItems[i]->preloadId1 == sceneId && _preloadItems[i]->preloadId2 == entranceId) {
+		if (_preloadItems[i].preloadId1 == sceneId && _preloadItems[i].preloadId2 == entranceId) {
 			idx = i;
 			break;
 		}
@@ -375,7 +375,7 @@ bool GameLoader::preloadScene(int sceneId, int entranceId) {
 	}
 
 	if (_preloadCallback) {
-		if (!_preloadCallback(*_preloadItems[idx], 0))
+		if (!_preloadCallback(_preloadItems[idx], 0))
 			return false;
 	}
 
@@ -387,19 +387,19 @@ bool GameLoader::preloadScene(int sceneId, int entranceId) {
 	unloadScene(sceneId);
 
 	if (_preloadCallback)
-		_preloadCallback(*_preloadItems[idx], 50);
+		_preloadCallback(_preloadItems[idx], 50);
 
-	loadScene(_preloadItems[idx]->sceneId);
+	loadScene(_preloadItems[idx].sceneId);
 
-	ExCommand *ex = new ExCommand(_preloadItems[idx]->sceneId, 17, 62, 0, 0, 0, 1, 0, 0, 0);
+	ExCommand *ex = new ExCommand(_preloadItems[idx].sceneId, 17, 62, 0, 0, 0, 1, 0, 0, 0);
 	ex->_excFlags = 2;
-	ex->_param = _preloadItems[idx]->param;
+	ex->_param = _preloadItems[idx].param;
 
 	_preloadSceneId = 0;
 	_preloadEntranceId = 0;
 
 	if (_preloadCallback)
-		_preloadCallback(*_preloadItems[idx], 100);
+		_preloadCallback(_preloadItems[idx], 100);
 
 	ex->postMessage();
 
@@ -633,14 +633,13 @@ bool PreloadItems::load(MfcArchive &file) {
 
 	clear();
 
+	resize(count);
 	for (int i = 0; i < count; i++) {
-		PreloadItem *t = new PreloadItem();
-		t->preloadId1 = file.readUint32LE();
-		t->preloadId2 = file.readUint32LE();
-		t->sceneId = file.readUint32LE();
-		t->param = file.readSint32LE();
-
-		push_back(t);
+		PreloadItem &t = (*this)[i];
+		t.preloadId1 = file.readUint32LE();
+		t.preloadId2 = file.readUint32LE();
+		t.sceneId = file.readUint32LE();
+		t.param = file.readSint32LE();
 	}
 
 	return true;
diff --git a/engines/fullpipe/gameloader.h b/engines/fullpipe/gameloader.h
index 1279dd8..f76a96f 100644
--- a/engines/fullpipe/gameloader.h
+++ b/engines/fullpipe/gameloader.h
@@ -71,7 +71,7 @@ struct PreloadItem {
 
 bool preloadCallback(PreloadItem &pre, int flag);
 
-class PreloadItems : public Common::Array<PreloadItem *>, public CObject {
+class PreloadItems : public Common::Array<PreloadItem>, public CObject {
  public:
 	virtual bool load(MfcArchive &file);
 };
@@ -105,7 +105,7 @@ class GameLoader : public CObject {
 	bool preloadScene(int sceneId, int entranceId);
 	bool unloadScene(int sceneId);
 
-	void addPreloadItem(PreloadItem *item);
+	void addPreloadItem(const PreloadItem &item);
 
 	void updateSystems(int counterdiff);
 
diff --git a/engines/fullpipe/lift.cpp b/engines/fullpipe/lift.cpp
index 1bbe5a7..feee335 100644
--- a/engines/fullpipe/lift.cpp
+++ b/engines/fullpipe/lift.cpp
@@ -403,12 +403,12 @@ void FullpipeEngine::lift_goAnimation() {
 		int numItems = _gameLoader->_preloadItems.size();
 
 		for (int i = 0; i < numItems; i++) {
-			PreloadItem *pre = _gameLoader->_preloadItems[i];
+			PreloadItem &pre = _gameLoader->_preloadItems[i];
 
-			if (pre->preloadId2 == buttonId && pre->preloadId1 == _currentScene->_sceneId) {
+			if (pre.preloadId2 == buttonId && pre.preloadId1 == _currentScene->_sceneId) {
 				MessageQueue *mq = new MessageQueue(_globalMessageQueueList->compact());
 
-				ExCommand *ex = new ExCommand(ANI_MAN, 1, (pre->param != LiftDown ? MV_MAN_LIFTDOWN : MV_MAN_LIFTUP), 0, 0, 0, 1, 0, 0, 0);
+				ExCommand *ex = new ExCommand(ANI_MAN, 1, (pre.param != LiftDown ? MV_MAN_LIFTDOWN : MV_MAN_LIFTUP), 0, 0, 0, 1, 0, 0, 0);
 
 				ex->_param = -1;
 				ex->_field_24 = 1;
diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp
index 0f9877a..a513cd4 100644
--- a/engines/fullpipe/modal.cpp
+++ b/engines/fullpipe/modal.cpp
@@ -570,10 +570,10 @@ bool ModalMap::init2(int counterdiff) {
 
 int ModalMap::findMapSceneId(int picId) {
 	for (uint i = 0; i < g_fp->_gameLoader->_preloadItems.size(); i++) {
-		PreloadItem *pitem = g_fp->_gameLoader->_preloadItems[i];
+		PreloadItem &pitem = g_fp->_gameLoader->_preloadItems[i];
 
-		if (pitem->preloadId1 == SC_MAP && pitem->preloadId2 == picId) {
-			return pitem->sceneId;
+		if (pitem.preloadId1 == SC_MAP && pitem.preloadId2 == picId) {
+			return pitem.sceneId;
 		}
 	}
 
@@ -705,11 +705,11 @@ void ModalMap::clickButton(PictureObject *pic) {
 		return;
 	}
 
-	PreloadItem *pitem = 0;
+	PreloadItem *pitem = nullptr;
 
 	for (uint i = 0; i < g_fp->_gameLoader->_preloadItems.size(); i++)
-		if (g_fp->_gameLoader->_preloadItems[i]->preloadId2 == SC_MAP) {
-			pitem = g_fp->_gameLoader->_preloadItems[i];
+		if (g_fp->_gameLoader->_preloadItems[i].preloadId2 == SC_MAP) {
+			pitem = &g_fp->_gameLoader->_preloadItems[i];
 			break;
 		}
 
@@ -717,16 +717,16 @@ void ModalMap::clickButton(PictureObject *pic) {
 		PreloadItem preload;
 
 		preload.preloadId2 = SC_MAP;
-		g_fp->_gameLoader->addPreloadItem(&preload);
-		pitem = g_fp->_gameLoader->_preloadItems[g_fp->_gameLoader->_preloadItems.size() - 1];
+		g_fp->_gameLoader->addPreloadItem(preload);
+		pitem = &g_fp->_gameLoader->_preloadItems[g_fp->_gameLoader->_preloadItems.size() - 1];
 	}
 
-	PreloadItem *pitem2 = 0;
+	PreloadItem *pitem2 = nullptr;
 
 	for (uint i = 0; i < g_fp->_gameLoader->_preloadItems.size(); i++)
-		if (g_fp->_gameLoader->_preloadItems[i]->preloadId1 == SC_MAP &&
-				g_fp->_gameLoader->_preloadItems[i]->preloadId2 == pic->_id) {
-			pitem2 = g_fp->_gameLoader->_preloadItems[i];
+		if (g_fp->_gameLoader->_preloadItems[i].preloadId1 == SC_MAP &&
+				g_fp->_gameLoader->_preloadItems[i].preloadId2 == pic->_id) {
+			pitem2 = &g_fp->_gameLoader->_preloadItems[i];
 			break;
 		}
 


Commit: 51b19e97c8d54d88e54cf7c88aca19d7b0962371
    https://github.com/scummvm/scummvm/commit/51b19e97c8d54d88e54cf7c88aca19d7b0962371
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix memory leaks of Interactions

Changed paths:
    engines/fullpipe/interaction.cpp


diff --git a/engines/fullpipe/interaction.cpp b/engines/fullpipe/interaction.cpp
index 89e3174..08c8c8f 100644
--- a/engines/fullpipe/interaction.cpp
+++ b/engines/fullpipe/interaction.cpp
@@ -56,8 +56,7 @@ bool canInteractAny(GameObject *obj1, GameObject *obj2, int invId) {
 }
 
 InteractionController::~InteractionController() {
-	_interactions.clear();
-
+	Common::for_each(_interactions.begin(), _interactions.end(), Common::DefaultDeleter<Interaction>());
 	removeMessageHandler(124, -1);
 }
 


Commit: bd07925134a3c29091ddd4a6df2f7cae80828ab0
    https://github.com/scummvm/scummvm/commit/bd07925134a3c29091ddd4a6df2f7cae80828ab0
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix leaks of MessageQueues

Changed paths:
    engines/fullpipe/behavior.cpp
    engines/fullpipe/messages.cpp


diff --git a/engines/fullpipe/behavior.cpp b/engines/fullpipe/behavior.cpp
index 2c0cba8..db91643 100644
--- a/engines/fullpipe/behavior.cpp
+++ b/engines/fullpipe/behavior.cpp
@@ -173,7 +173,9 @@ void BehaviorManager::updateStaticAniBehavior(StaticANIObject &ani, int delay, c
 
 	if (mq) {
 		mq->setParamInt(-1, ani._odelay);
-		mq->chain(&ani);
+		if (!mq->chain(&ani)) {
+			g_fp->_globalMessageQueueList->deleteQueueById(mq->_id);
+		}
 	}
 }
 
diff --git a/engines/fullpipe/messages.cpp b/engines/fullpipe/messages.cpp
index db75146..63d5c4d 100644
--- a/engines/fullpipe/messages.cpp
+++ b/engines/fullpipe/messages.cpp
@@ -883,9 +883,8 @@ bool chainQueue(int queueId, int flags) {
 
 	nmq->_flags |= flags;
 
-	if (!nmq->chain(0)) {
-		delete nmq;
-
+	if (!nmq->chain(nullptr)) {
+		g_fp->_globalMessageQueueList->deleteQueueById(nmq->_id);
 		return false;
 	}
 
@@ -903,8 +902,7 @@ bool chainObjQueue(StaticANIObject *obj, int queueId, int flags) {
 	nmq->_flags |= flags;
 
 	if (!nmq->chain(obj)) {
-		delete nmq;
-
+		g_fp->_globalMessageQueueList->deleteQueueById(nmq->_id);
 		return false;
 	}
 


Commit: dcf8f588c700cb967baccdafd745ac1cffdd3554
    https://github.com/scummvm/scummvm/commit/dcf8f588c700cb967baccdafd745ac1cffdd3554
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Remove unnecessary member array clear in destructor

Changed paths:
    engines/fullpipe/messages.cpp


diff --git a/engines/fullpipe/messages.cpp b/engines/fullpipe/messages.cpp
index 63d5c4d..fd58de2 100644
--- a/engines/fullpipe/messages.cpp
+++ b/engines/fullpipe/messages.cpp
@@ -280,8 +280,6 @@ MessageQueue::~MessageQueue() {
 			delete ex;
 	}
 
-	_exCommands.clear();
-
 	if (_field_14)
 		delete _field_14;
 


Commit: 0cc3d8f05d7302651ec5c8dce47ee511db829cf9
    https://github.com/scummvm/scummvm/commit/0cc3d8f05d7302651ec5c8dce47ee511db829cf9
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix leaks of ExCommands loaded from an archive

Nearly every construction of an ExCommand in the engine sets flag
2 of _excFlags. It may even be that the remaining ones that don't
are themselves bugs. This flag is needed in order for an ExCommand
to be cleaned up when its parent MessageQueue is deleted.

Changed paths:
    engines/fullpipe/messages.cpp


diff --git a/engines/fullpipe/messages.cpp b/engines/fullpipe/messages.cpp
index fd58de2..d856d1b 100644
--- a/engines/fullpipe/messages.cpp
+++ b/engines/fullpipe/messages.cpp
@@ -303,6 +303,7 @@ bool MessageQueue::load(MfcArchive &file) {
 
 	for (int i = 0; i < count; i++) {
 		ExCommand *tmp = file.readClass<ExCommand>();
+		tmp->_excFlags |= 2;
 		_exCommands.push_back(tmp);
 	}
 


Commit: 2be96457b9132b62d220be072a1752e16946a123
    https://github.com/scummvm/scummvm/commit/2be96457b9132b62d220be072a1752e16946a123
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Make list item ownership comments more consistent

Changed paths:
    engines/fullpipe/statics.h


diff --git a/engines/fullpipe/statics.h b/engines/fullpipe/statics.h
index a309153..b0e083e 100644
--- a/engines/fullpipe/statics.h
+++ b/engines/fullpipe/statics.h
@@ -177,9 +177,9 @@ class StaticANIObject : public GameObject {
 	int _initialCounter;
 	void (*_callback1)(int, Common::Point *point, int, int);
 	void (*_callback2)(int *);
-	/** items in list are owned */
+	/** list items are owned */
 	Common::Array<Movement *> _movements;
-	/** items in list are owned */
+	/** list items are owned */
 	Common::Array<Statics *> _staticsList;
 	StepArray _stepArray;
 	int16 _field_96;


Commit: 8808817d56d37a66eb6a590715035076fcc14ade
    https://github.com/scummvm/scummvm/commit/8808817d56d37a66eb6a590715035076fcc14ade
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix memory leaks of MessageQueues when clearing GlobalMessageQueueList

Changed paths:
    engines/fullpipe/messages.cpp
    engines/fullpipe/messages.h


diff --git a/engines/fullpipe/messages.cpp b/engines/fullpipe/messages.cpp
index d856d1b..bd8dff8 100644
--- a/engines/fullpipe/messages.cpp
+++ b/engines/fullpipe/messages.cpp
@@ -263,7 +263,7 @@ MessageQueue::MessageQueue(MessageQueue *src, int parId, int field_38) {
 
 	_id = g_fp->_globalMessageQueueList->compact();
 	_dataId = src->_dataId;
-	_flags = src->_flags;
+	_flags = src->_flags & ~kInGlobalQueue;
 	_queueName = "";
 
 	g_fp->_globalMessageQueueList->addMessageQueue(this);
@@ -319,7 +319,6 @@ bool MessageQueue::chain(StaticANIObject *ani) {
 	if (checkGlobalExCommandList1() && checkGlobalExCommandList2()) {
 		if (!(getFlags() & kInGlobalQueue)) {
 			g_fp->_globalMessageQueueList->addMessageQueue(this);
-			_flags |= kInGlobalQueue;
 		}
 		if (ani) {
 			ani->queueMessageQueue(this);
@@ -656,9 +655,23 @@ int GlobalMessageQueueList::compact() {
 }
 
 void GlobalMessageQueueList::addMessageQueue(MessageQueue *msg) {
-	msg->setFlags(msg->getFlags() | kInGlobalQueue);
+	if ((msg->getFlags() & kInGlobalQueue) == 0) {
+		msg->setFlags(msg->getFlags() | kInGlobalQueue);
+		push_back(msg);
+	} else {
+		warning("Trying to add a MessageQueue already in the queue");
+	}
+}
 
-	push_back(msg);
+void GlobalMessageQueueList::clear() {
+	for (iterator it = begin(); it != end(); ++it) {
+		// The MessageQueue destructor will try to remove itself from the global
+		// queue if it thinks it is in the global queue, which will break the
+		// iteration over the list
+		(*it)->_flags &= ~kInGlobalQueue;
+		delete *it;
+	}
+	Common::Array<MessageQueue *>::clear();
 }
 
 void clearGlobalMessageQueueList() {
diff --git a/engines/fullpipe/messages.h b/engines/fullpipe/messages.h
index 91677a1..71ec962 100644
--- a/engines/fullpipe/messages.h
+++ b/engines/fullpipe/messages.h
@@ -163,13 +163,14 @@ class MessageQueue : public CObject {
 };
 
 class GlobalMessageQueueList : public Common::Array<MessageQueue *> {
-  public:
+public:
 	MessageQueue *getMessageQueueById(int id);
 	void deleteQueueById(int id);
 	void removeQueueById(int id);
 	void disableQueueById(int id);
 	/** `msg` becomes owned by `this` */
 	void addMessageQueue(MessageQueue *msg);
+	void clear();
 
 	int compact();
 };


Commit: d0efcb7ad54fab6c9192ef099c400fc217644493
    https://github.com/scummvm/scummvm/commit/d0efcb7ad54fab6c9192ef099c400fc217644493
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix use-after-free in ModalMainMenu

Pointers to objects which are invalidated when the scene gets
unloaded may continue to be accessed if a mouse hover event is
dispatched to the ModalMainMenu.

Changed paths:
    engines/fullpipe/modal.cpp


diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp
index a513cd4..e3d0ee0 100644
--- a/engines/fullpipe/modal.cpp
+++ b/engines/fullpipe/modal.cpp
@@ -1338,6 +1338,9 @@ bool ModalMainMenu::handleMessage(ExCommand *message) {
 	if (message->_messageKind != 17)
 		return false;
 
+	if (!_scene)
+		return false;
+
 	Common::Point point;
 
 	if (message->_messageNum == 29) {
@@ -1412,6 +1415,7 @@ bool ModalMainMenu::init(int counterdiff) {
 
 	case PIC_MNU_DEBUG_L:
 		g_fp->_gameLoader->unloadScene(SC_MAINMENU);
+		_scene = nullptr;
 		g_fp->_sceneRect = _screct;
 
 		if (!g_fp->_currentScene)
@@ -1427,6 +1431,7 @@ bool ModalMainMenu::init(int counterdiff) {
 	case PIC_MNU_CONTINUE_L:
 		if (!_mfield_34) {
 			g_fp->_gameLoader->unloadScene(SC_MAINMENU);
+			_scene = nullptr;
 			g_fp->_sceneRect = _screct;
 
 			if (g_fp->_currentScene) {


Commit: a5060cf3789a438a76b8e70b6e07ba7a26906895
    https://github.com/scummvm/scummvm/commit/a5060cf3789a438a76b8e70b6e07ba7a26906895
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Remove manual memory management and fix in-game save/load

Changed paths:
    engines/fullpipe/modal.cpp
    engines/fullpipe/modal.h


diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp
index e3d0ee0..6543a88 100644
--- a/engines/fullpipe/modal.cpp
+++ b/engines/fullpipe/modal.cpp
@@ -1988,14 +1988,6 @@ ModalSaveGame::ModalSaveGame() {
 
 ModalSaveGame::~ModalSaveGame() {
 	g_fp->_sceneRect = _rect;
-
-	_arrayD.clear();
-	_arrayL.clear();
-
-	for (uint i = 0; i < _files.size(); i++)
-		free(_files[i]);
-
-	_files.clear();
 }
 
 void ModalSaveGame::setScene(Scene *sc) {
@@ -2107,16 +2099,16 @@ void ModalSaveGame::setup(Scene *sc, int mode) {
 	int x = _bgr->_ox + _bgr->getDimensions().x / 2;
 	int y = _bgr->_oy + 90;
 	int w;
-	FileInfo *fileinfo;
 
+	_files.clear();
+	_files.resize(7);
 	for (int i = 0; i < 7; i++) {
-		fileinfo = new FileInfo;
-		memset(fileinfo, 0, sizeof(FileInfo));
+		FileInfo &fileinfo = _files[i];
 
-		Common::strlcpy(fileinfo->filename, getSavegameFile(i), 160);
+		Common::strlcpy(fileinfo.filename, getSavegameFile(i), sizeof(fileinfo.filename));
 
-		if (!getFileInfo(i, fileinfo)) {
-			fileinfo->empty = true;
+		if (!getFileInfo(i, &fileinfo)) {
+			fileinfo.empty = true;
 			w = _emptyD->getDimensions().x;
 		} else {
 			w = 0;
@@ -2126,14 +2118,11 @@ void ModalSaveGame::setup(Scene *sc, int mode) {
 			}
 		}
 
-		fileinfo->fx1 = x - w / 2;
-		fileinfo->fx2 = x + w / 2;
-		fileinfo->fy1 = y;
-		fileinfo->fy2 = y + _emptyD->getDimensions().y;
-
-		_files.push_back(fileinfo);
-
-		y = fileinfo->fy2 + 3;
+		fileinfo.fx1 = x - w / 2;
+		fileinfo.fx2 = x + w / 2;
+		fileinfo.fy1 = y;
+		fileinfo.fy2 = y + _emptyD->getDimensions().y;
+		y = fileinfo.fy2 + 3;
 	}
 }
 
@@ -2141,19 +2130,18 @@ char *ModalSaveGame::getSaveName() {
 	if (_queryRes < 0)
 		return 0;
 
-	return _files[_queryRes - 1]->filename;
+	return _files[_queryRes - 1].filename;
 }
 
 bool ModalSaveGame::getFileInfo(int slot, FileInfo *fileinfo) {
-	Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(
-		Fullpipe::getSavegameFile(slot));
+	Common::ScopedPtr<Common::InSaveFile> f(g_system->getSavefileManager()->openForLoading(
+		Fullpipe::getSavegameFile(slot)));
 
 	if (!f)
 		return false;
 
 	Fullpipe::FullpipeSavegameHeader header;
-	Fullpipe::readSavegameHeader(f, header);
-	delete f;
+	Fullpipe::readSavegameHeader(f.get(), header);
 
 	// Create the return descriptor
 	SaveStateDescriptor desc(slot, header.saveName);
@@ -2165,6 +2153,7 @@ bool ModalSaveGame::getFileInfo(int slot, FileInfo *fileinfo) {
 
 	for (int i = 0; i < 16; i++) {
 		switch (res[i]) {
+		case '-':
 		case '.':
 			fileinfo->date[i] = 11;
 			break;
@@ -2211,33 +2200,33 @@ void ModalSaveGame::update() {
 	g_fp->setCursor(g_fp->_cursorId);
 
 	for (uint i = 0; i < _files.size(); i++) {
-		if (g_fp->_mouseScreenPos.x < _files[i]->fx1 || g_fp->_mouseScreenPos.x > _files[i]->fx2 ||
-			g_fp->_mouseScreenPos.y < _files[i]->fy1 || g_fp->_mouseScreenPos.y > _files[i]->fy2 ) {
-			if (_files[i]->empty) {
-				_emptyD->setOXY(_files[i]->fx1, _files[i]->fy1);
+		if (g_fp->_mouseScreenPos.x < _files[i].fx1 || g_fp->_mouseScreenPos.x > _files[i].fx2 ||
+			g_fp->_mouseScreenPos.y < _files[i].fy1 || g_fp->_mouseScreenPos.y > _files[i].fy2 ) {
+			if (_files[i].empty) {
+				_emptyD->setOXY(_files[i].fx1, _files[i].fy1);
 				_emptyD->draw();
 			} else {
-				int x = _files[i]->fx1;
+				int x = _files[i].fx1;
 
 				for (int j = 0; j < 16; j++) {
-					_arrayL[_files[i]->date[j]]->setOXY(x + 1, _files[i]->fy1);
-					_arrayL[_files[i]->date[j]]->draw();
+					_arrayL[_files[i].date[j]]->setOXY(x + 1, _files[i].fy1);
+					_arrayL[_files[i].date[j]]->draw();
 
-					x += _arrayL[_files[i]->date[j]]->getDimensions().x + 2;
+					x += _arrayL[_files[i].date[j]]->getDimensions().x + 2;
 				}
 			}
 		} else {
-			if (_files[i]->empty) {
-				_emptyL->setOXY(_files[i]->fx1, _files[i]->fy1);
+			if (_files[i].empty) {
+				_emptyL->setOXY(_files[i].fx1, _files[i].fy1);
 				_emptyL->draw();
 			} else {
-				int x = _files[i]->fx1;
+				int x = _files[i].fx1;
 
 				for (int j = 0; j < 16; j++) {
-					_arrayD[_files[i]->date[j]]->setOXY(x + 1, _files[i]->fy1);
-					_arrayD[_files[i]->date[j]]->draw();
+					_arrayD[_files[i].date[j]]->setOXY(x + 1, _files[i].fy1);
+					_arrayD[_files[i].date[j]]->draw();
 
-					x += _arrayD[_files[i]->date[j]]->getDimensions().x + 2;
+					x += _arrayD[_files[i].date[j]]->getDimensions().x + 2;
 				}
 			}
 		}
@@ -2262,11 +2251,11 @@ bool ModalSaveGame::handleMessage(ExCommand *cmd) {
 
 void ModalSaveGame::processMouse(int x, int y) {
 	for (uint i = 0; i < _files.size(); i++) {
-		if (x >= _files[i]->fx1 && x <= _files[i]->fx2 && y >= _files[i]->fy1 && y <= _files[i]->fy2) {
+		if (x >= _files[i].fx1 && x <= _files[i].fx2 && y >= _files[i].fy1 && y <= _files[i].fy2) {
 			_queryRes = i + 1;
 
 			if (_mode) {
-				if (!_files[i]->empty) {
+				if (!_files[i].empty) {
 					_queryDlg = new ModalQuery;
 
 					_queryDlg->create(_menuScene, 0, PIC_MOV_BGR);
diff --git a/engines/fullpipe/modal.h b/engines/fullpipe/modal.h
index 800cba6..1bc576c 100644
--- a/engines/fullpipe/modal.h
+++ b/engines/fullpipe/modal.h
@@ -319,7 +319,7 @@ public:
 	Scene *_menuScene;
 	int _mode;
 	ModalQuery *_queryDlg;
-	Common::Array <FileInfo *> _files;
+	Common::Array <FileInfo> _files;
 	Common::Array <PictureObject *> _arrayL;
 	Common::Array <PictureObject *> _arrayD;
 	int _queryRes;


Commit: e40b4a348a8beb91fe97aa97f6e2323e78b3e10e
    https://github.com/scummvm/scummvm/commit/e40b4a348a8beb91fe97aa97f6e2323e78b3e10e
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix memory leaks of arcade keys

Fixes Trac#9657.

Changed paths:
    engines/fullpipe/fullpipe.h
    engines/fullpipe/input.cpp


diff --git a/engines/fullpipe/fullpipe.h b/engines/fullpipe/fullpipe.h
index a24f11e..cd7b120 100644
--- a/engines/fullpipe/fullpipe.h
+++ b/engines/fullpipe/fullpipe.h
@@ -223,7 +223,7 @@ public:
 	Common::ScopedPtr<Floaters> _floaters;
 	Common::ScopedPtr<AniHandler> _aniHandler;
 
-	Common::Array<Common::Point *> _arcadeKeys;
+	Common::Array<Common::Point> _arcadeKeys;
 
 	void initMap();
 	void updateMap(PreloadItem *pre);
diff --git a/engines/fullpipe/input.cpp b/engines/fullpipe/input.cpp
index d692f87..3b733b9 100644
--- a/engines/fullpipe/input.cpp
+++ b/engines/fullpipe/input.cpp
@@ -262,16 +262,12 @@ void FullpipeEngine::initArcadeKeys(const char *varname) {
 		return;
 
 	int cnt = var->getSubVarsCount();
-
+	_arcadeKeys.resize(cnt);
 	for (int i = 0; i < cnt; i++) {
-		Common::Point *point = new Common::Point;
-
+		Common::Point &point = _arcadeKeys[i];
 		GameVar *sub = var->getSubVarByIndex(i);
-
-		point->x = sub->getSubVarAsInt("X");
-		point->y = sub->getSubVarAsInt("Y");
-
-		_arcadeKeys.push_back(point);
+		point.x = sub->getSubVarAsInt("X");
+		point.y = sub->getSubVarAsInt("Y");
 	}
 }
 
@@ -283,7 +279,7 @@ void FullpipeEngine::processArcade(ExCommand *cmd) {
 
 	if (cmd->_sceneClickX <= g_fp->_aniMan2->_ox) {
 		for (idx = (int)_arcadeKeys.size() - 1; idx >= 0; idx--) {
-			if (_arcadeKeys[idx]->x < g_fp->_aniMan2->_ox)
+			if (_arcadeKeys[idx].x < g_fp->_aniMan2->_ox)
 				break;
 		}
 
@@ -291,7 +287,7 @@ void FullpipeEngine::processArcade(ExCommand *cmd) {
 			return;
 	} else {
 		for (idx = 0; idx < (int)_arcadeKeys.size(); idx++) {
-			if (_arcadeKeys[idx]->x > g_fp->_aniMan2->_ox)
+			if (_arcadeKeys[idx].x > g_fp->_aniMan2->_ox)
 				break;
 		}
 
@@ -299,8 +295,8 @@ void FullpipeEngine::processArcade(ExCommand *cmd) {
 			return;
 	}
 
-	cmd->_sceneClickX = _arcadeKeys[idx]->x;
-	cmd->_sceneClickY = _arcadeKeys[idx]->y;
+	cmd->_sceneClickX = _arcadeKeys[idx].x;
+	cmd->_sceneClickY = _arcadeKeys[idx].y;
 
 	cmd->_x = cmd->_sceneClickX - g_fp->_sceneRect.left;
 	cmd->_y = cmd->_sceneClickY - g_fp->_sceneRect.top;


Commit: 2cc79fe9c800c2f6e711d135e2039461af7e199e
    https://github.com/scummvm/scummvm/commit/2cc79fe9c800c2f6e711d135e2039461af7e199e
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-11-18T22:35:12+01:00

Commit Message:
FULLPIPE: Fix memory leaks restoring save games

Changed paths:
    engines/fullpipe/stateloader.cpp


diff --git a/engines/fullpipe/stateloader.cpp b/engines/fullpipe/stateloader.cpp
index 4041eb1..231379c 100644
--- a/engines/fullpipe/stateloader.cpp
+++ b/engines/fullpipe/stateloader.cpp
@@ -42,7 +42,7 @@ namespace Fullpipe {
 
 bool GameLoader::readSavegame(const char *fname) {
 	SaveHeader header;
-	Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(fname);
+	Common::ScopedPtr<Common::InSaveFile> saveFile(g_system->getSavefileManager()->openForLoading(fname));
 
 	if (!saveFile) {
 		warning("Cannot open save %s for loading", fname);
@@ -63,29 +63,28 @@ bool GameLoader::readSavegame(const char *fname) {
 
 	_updateCounter = header.updateCounter;
 
-	byte *data = (byte *)malloc(header.encSize);
-	saveFile->read(data, header.encSize);
+	Common::Array<byte> data(header.encSize);
+	saveFile->read(data.data(), header.encSize);
 
-	byte *map = (byte *)malloc(800);
-	saveFile->read(map, 800);
+	Common::Array<byte> map(800);
+	saveFile->read(map.data(), 800);
 
-	Common::MemoryReadStream *tempStream = new Common::MemoryReadStream(map, 800);
-	MfcArchive temp(tempStream);
+	{
+		Common::MemoryReadStream tempStream(map.data(), 800, DisposeAfterUse::NO);
+		MfcArchive temp(&tempStream);
 
-	if (_savegameCallback)
-		_savegameCallback(&temp, false);
-
-	delete tempStream;
-	delete saveFile;
+		if (_savegameCallback)
+			_savegameCallback(&temp, false);
+	}
 
 	// Deobfuscate the data
 	for (int i = 0; i < header.encSize; i++)
 		data[i] -= i & 0x7f;
 
-	Common::MemoryReadStream *archiveStream = new Common::MemoryReadStream(data, header.encSize);
-	MfcArchive *archive = new MfcArchive(archiveStream);
+	Common::MemoryReadStream archiveStream(data.data(), header.encSize, DisposeAfterUse::NO);
+	MfcArchive archive(&archiveStream);
 
-	GameVar *var = archive->readClass<GameVar>();
+	GameVar *var = archive.readClass<GameVar>();
 
 	GameVar *v = _gameVar->getSubVarByName("OBJSTATES");
 
@@ -94,23 +93,22 @@ bool GameLoader::readSavegame(const char *fname) {
 
 		if (!v) {
 			warning("No state to save");
-			delete archiveStream;
-			delete archive;
+			delete var;
 			return false;
 		}
 	}
 
 	addVar(var, v);
 
-	getGameLoaderInventory()->loadPartial(*archive);
+	getGameLoaderInventory()->loadPartial(archive);
 
-	uint32 arrSize = archive->readUint32LE();
+	uint32 arrSize = archive.readUint32LE();
 
 	debugC(3, kDebugLoading, "Reading %d infos", arrSize);
 
 	for (uint i = 0; i < arrSize; i++) {
 
-		const uint picAniInfosCount = archive->readUint32LE();
+		const uint picAniInfosCount = archive.readUint32LE();
 		if (picAniInfosCount)
 			debugC(3, kDebugLoading, "Count %d: %d", i, picAniInfosCount);
 
@@ -118,15 +116,12 @@ bool GameLoader::readSavegame(const char *fname) {
 		_sc2array[i]._picAniInfos.resize(picAniInfosCount);
 
 		for (uint j = 0; j < picAniInfosCount; j++) {
-			_sc2array[i]._picAniInfos[j].load(*archive);
+			_sc2array[i]._picAniInfos[j].load(archive);
 		}
 
 		_sc2array[i]._isLoaded = false;
 	}
 
-	delete archiveStream;
-	delete archive;
-
 	getGameLoaderInventory()->rebuildItemRects();
 
 	PreloadItem preloadItem;





More information about the Scummvm-git-logs mailing list