[Scummvm-git-logs] scummvm master -> c7c5f28bdb2f393c1290bcac803cf9fc86ac8ed8

csnover csnover at users.noreply.github.com
Sat Oct 7 05:57:32 CEST 2017


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

Summary:
5e2e6e9e8a COMMON: Switch to compile-time checking of invalid SortedArray calls
79dd02373c COMMON: Prevent implicit conversion of smart pointers to non-bools
f037d4df16 COMMON: Allow construction of Arrays of non-copyable members
5cffa3891f SCI32: Clean up GfxPalette32
0ac5d84062 SCI32: Clean up ScreenItem
ff3503abde SCI32: Clean up GfxTransitions32
9d05bf7920 SCI32: Clean up GfxCursor32
c413030be3 SCI32: Clean up Video32
f51b158f8c SCI32: Clean up GfxFrameout
93c8044f69 SCI32: Clean up Audio32
42180527c4 SCI32: Fix music volume not being restored after speech in Torin
a2c8674252 SCI32: Clean up GfxText32
1b42146955 SCI32: Clean up GfxRemap32
31e1d0932c SCI32: Clean up Plane
4521e9774a SCI32: Clean up GfxPaint32
d5e09a9f68 SCI32: Rewrap comments to 80 columns in lists32.h
ac0a83a424 SCI32: Clean up GfxControls32
b6c3f0f547 SCI32: Clean up CelObj
ce13b1699a SCI32: Clean up Robot decoder
8c9276e75a SCI32: Clean up script patch comments
15f6e6b97e SCI32: Remove resolved TODO in helpers.h
d53e778739 SCI32: Rewrap comments to 80 columns in SOL decoder
c7c5f28bdb SCI32: Clean up scriptWidth/scriptHeight/screenWidth/screenHeight


Commit: 5e2e6e9e8a06a3a54e74b889d167a094d74f5d5a
    https://github.com/scummvm/scummvm/commit/5e2e6e9e8a06a3a54e74b889d167a094d74f5d5a
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:10:49-05:00

Commit Message:
COMMON: Switch to compile-time checking of invalid SortedArray calls

Runtime error detection is error-prone and unnecessary.

Changed paths:
    common/array.h


diff --git a/common/array.h b/common/array.h
index bb7e03c..1645db0 100644
--- a/common/array.h
+++ b/common/array.h
@@ -418,31 +418,19 @@ public:
 			Array<T>::insert(where, element);
 	}
 
-	T &operator[](size_type idx) {
-		error("Operation []= not allowed with SortedArray");
-	}
+private:
+	T &operator[](size_type idx);
 
-	void insert_at(size_type idx, const T &element) {
-		error("Operation insert_at(idx, element) not allowed with SortedArray");
-	}
+	void insert_at(size_type idx, const T &element);
 
-	void insert_at(size_type idx, const Array<T> &array) {
-		error("Operation insert_at(idx, array) not allowed with SortedArray");
-	}
+	void insert_at(size_type idx, const Array<T> &array);
 
-	void insert(iterator pos, const T &element) {
-		error("Operation insert(pos, elemnet) not allowed with SortedArray");
-	}
+	void insert(iterator pos, const T &element);
 
-	void push_back(const T &element) {
-		error("Operation push_back(element) not allowed with SortedArray");
-	}
+	void push_back(const T &element);
 
-	void push_back(const Array<T> &array) {
-		error("Operation push_back(array) not allowed with SortedArray");
-	}
+	void push_back(const Array<T> &array);
 
-private:
 	// Based on code Copyright (C) 2008-2009 Ksplice, Inc.
 	// Author: Tim Abbott <tabbott at ksplice.com>
 	// Licensed under GPLv2+
@@ -465,7 +453,6 @@ private:
 		return &this->_storage[start_];
 	}
 
-private:
 	int (*_comparator)(const void *, const void *);
 };
 


Commit: 79dd02373cb431adfceeb4be50366b7c084490d9
    https://github.com/scummvm/scummvm/commit/79dd02373cb431adfceeb4be50366b7c084490d9
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:10:49-05:00

Commit Message:
COMMON: Prevent implicit conversion of smart pointers to non-bools

Changed paths:
    common/ptr.h


diff --git a/common/ptr.h b/common/ptr.h
index ebdd77c..510fec1 100644
--- a/common/ptr.h
+++ b/common/ptr.h
@@ -25,6 +25,7 @@
 
 #include "common/scummsys.h"
 #include "common/noncopyable.h"
+#include "common/safe-bool.h"
 #include "common/types.h"
 
 namespace Common {
@@ -103,7 +104,7 @@ private:
  * a plain pointer is only possible via SharedPtr::get.
  */
 template<class T>
-class SharedPtr {
+class SharedPtr : public SafeBool<SharedPtr<T> > {
 #if !defined(__GNUC__) || GCC_ATLEAST(3, 0)
 	template<class T2> friend class SharedPtr;
 #endif
@@ -167,7 +168,7 @@ public:
 	 * Implicit conversion operator to bool for convenience, to make
 	 * checks like "if (sharedPtr) ..." possible.
 	 */
-	operator bool() const { return _pointer != 0; }
+	bool operator_bool() const { return _pointer != nullptr; }
 
 	/**
 	 * Checks if the SharedPtr object is the only object refering
@@ -223,7 +224,7 @@ private:
 };
 
 template<typename T>
-class ScopedPtr : NonCopyable {
+class ScopedPtr : private NonCopyable, public SafeBool<ScopedPtr<T> > {
 public:
 	typedef T ValueType;
 	typedef T *PointerType;
@@ -238,7 +239,7 @@ public:
 	 * Implicit conversion operator to bool for convenience, to make
 	 * checks like "if (scopedPtr) ..." possible.
 	 */
-	operator bool() const { return _pointer != 0; }
+	bool operator_bool() const { return _pointer != nullptr; }
 
 	~ScopedPtr() {
 		delete _pointer;
@@ -277,7 +278,7 @@ private:
 
 
 template<typename T>
-class DisposablePtr : NonCopyable {
+class DisposablePtr : private NonCopyable, public SafeBool<DisposablePtr<T> > {
 public:
 	typedef T  ValueType;
 	typedef T *PointerType;
@@ -296,7 +297,7 @@ public:
 	 * Implicit conversion operator to bool for convenience, to make
 	 * checks like "if (scopedPtr) ..." possible.
 	 */
-	operator bool() const { return _pointer; }
+	bool operator_bool() const { return _pointer != nullptr; }
 
 	/**
 	 * Returns the plain pointer value.


Commit: f037d4df1680aecefac2ffb240547385a74971d0
    https://github.com/scummvm/scummvm/commit/f037d4df1680aecefac2ffb240547385a74971d0
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:10:50-05:00

Commit Message:
COMMON: Allow construction of Arrays of non-copyable members

Although the previous count-constructor would never make a copy of
a member at runtime, Array<T>::reserve *may* copy-construct, so
the compiler would forbid creation of arrays of NonCopyable objects
even when the array was created only once and then never resized
(and thus never actually tried to perform a copy-construction).

Changed paths:
    common/array.h
    test/common/array.h


diff --git a/common/array.h b/common/array.h
index 1645db0..d4dac35 100644
--- a/common/array.h
+++ b/common/array.h
@@ -63,9 +63,10 @@ public:
 	 * Constructs an array with `count` default-inserted instances of T. No
 	 * copies are made.
 	 */
-	explicit Array(size_type count) : _size(0) {
+	explicit Array(size_type count) : _size(count) {
 		allocCapacity(count);
-		resize(count);
+		for (size_type i = 0; i < count; ++i)
+			new ((void *)&_storage[i]) T();
 	}
 
 	/**
diff --git a/test/common/array.h b/test/common/array.h
index 45be993..e0a6438 100644
--- a/test/common/array.h
+++ b/test/common/array.h
@@ -1,6 +1,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "common/array.h"
+#include "common/noncopyable.h"
 #include "common/str.h"
 
 class ArrayTestSuite : public CxxTest::TestSuite
@@ -315,6 +316,10 @@ class ArrayTestSuite : public CxxTest::TestSuite
 		TS_ASSERT_EQUALS(array.size(), 10U);
 		TS_ASSERT_EQUALS(array[0], 0);
 		TS_ASSERT_EQUALS(array[9], 0);
+
+		// This will fail at compile time if it is not possible to construct an
+		// array without copy-construction
+		Common::Array<Common::NonCopyable> nonCopyable(1);
 	}
 
 	void test_array_constructor_count_copy_value() {


Commit: 5cffa3891f48d64154f00571c8127ef2c601d6d5
    https://github.com/scummvm/scummvm/commit/5cffa3891f48d64154f00571c8127ef2c601d6d5
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:10:50-05:00

Commit Message:
SCI32: Clean up GfxPalette32

* Replace raw pointers with smart pointers
* Use references instead of const pointers where appropriate
* Tweak initialisation
* Tweak palette copies to the stack

Changed paths:
    engines/sci/engine/savegame.cpp
    engines/sci/graphics/palette32.cpp
    engines/sci/graphics/palette32.h


diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index b0fa31a..06a26ec 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -866,25 +866,25 @@ void GfxPalette::saveLoadWithSerializer(Common::Serializer &s) {
 }
 
 #ifdef ENABLE_SCI32
-static void saveLoadPalette32(Common::Serializer &s, Palette *const palette) {
-	s.syncAsUint32LE(palette->timestamp);
-	for (int i = 0; i < ARRAYSIZE(palette->colors); ++i) {
-		s.syncAsByte(palette->colors[i].used);
-		s.syncAsByte(palette->colors[i].r);
-		s.syncAsByte(palette->colors[i].g);
-		s.syncAsByte(palette->colors[i].b);
+static void saveLoadPalette32(Common::Serializer &s, Palette &palette) {
+	s.syncAsUint32LE(palette.timestamp);
+	for (int i = 0; i < ARRAYSIZE(palette.colors); ++i) {
+		s.syncAsByte(palette.colors[i].used);
+		s.syncAsByte(palette.colors[i].r);
+		s.syncAsByte(palette.colors[i].g);
+		s.syncAsByte(palette.colors[i].b);
 	}
 }
 
-static void saveLoadOptionalPalette32(Common::Serializer &s, Palette **const palette) {
+static void saveLoadOptionalPalette32(Common::Serializer &s, Common::ScopedPtr<Palette> &palette) {
 	bool hasPalette = false;
 	if (s.isSaving()) {
-		hasPalette = (*palette != nullptr);
+		hasPalette = palette;
 	}
 	s.syncAsByte(hasPalette);
 	if (hasPalette) {
 		if (s.isLoading()) {
-			*palette = new Palette;
+			palette.reset(new Palette);
 		}
 		saveLoadPalette32(s, *palette);
 	}
@@ -899,14 +899,11 @@ void GfxPalette32::saveLoadWithSerializer(Common::Serializer &s) {
 		++_version;
 
 		for (int i = 0; i < kNumCyclers; ++i) {
-			delete _cyclers[i];
-			_cyclers[i] = nullptr;
+			_cyclers[i].reset();
 		}
 
-		delete _varyTargetPalette;
-		_varyTargetPalette = nullptr;
-		delete _varyStartPalette;
-		_varyStartPalette = nullptr;
+		_varyTargetPalette.reset();
+		_varyStartPalette.reset();
 	}
 
 	s.syncAsSint16LE(_varyDirection);
@@ -928,14 +925,14 @@ void GfxPalette32::saveLoadWithSerializer(Common::Serializer &s) {
 
 	if (g_sci->_features->hasLatePaletteCode() && s.getVersion() >= 41) {
 		s.syncAsSint16LE(_gammaLevel);
-		saveLoadPalette32(s, &_sourcePalette);
+		saveLoadPalette32(s, _sourcePalette);
 		++_version;
 		_needsUpdate = true;
 		_gammaChanged = true;
 	}
 
-	saveLoadOptionalPalette32(s, &_varyTargetPalette);
-	saveLoadOptionalPalette32(s, &_varyStartPalette);
+	saveLoadOptionalPalette32(s, _varyTargetPalette);
+	saveLoadOptionalPalette32(s, _varyStartPalette);
 
 	// _nextPalette is not saved by SSCI
 
@@ -944,14 +941,15 @@ void GfxPalette32::saveLoadWithSerializer(Common::Serializer &s) {
 
 		bool hasCycler = false;
 		if (s.isSaving()) {
-			cycler = _cyclers[i];
+			cycler = _cyclers[i].get();
 			hasCycler = (cycler != nullptr);
 		}
 		s.syncAsByte(hasCycler);
 
 		if (hasCycler) {
 			if (s.isLoading()) {
-				_cyclers[i] = cycler = new PalCycler;
+				cycler = new PalCycler;
+				_cyclers[i].reset(cycler);
 			}
 
 			s.syncAsByte(cycler->fromColor);
diff --git a/engines/sci/graphics/palette32.cpp b/engines/sci/graphics/palette32.cpp
index d8a2ead..7a3b396 100644
--- a/engines/sci/graphics/palette32.cpp
+++ b/engines/sci/graphics/palette32.cpp
@@ -39,11 +39,10 @@ namespace Sci {
 
 HunkPalette::HunkPalette(const SciSpan<const byte> &rawPalette) :
 	_version(0),
-	// NOTE: The header size in palettes is garbage. In at least KQ7 2.00b and
-	// Phant1, the 999.pal sets this value to 0. In most other palettes it is
-	// set to 14, but the *actual* size of the header structure used in SSCI is
-	// 13, which is reflected by `kHunkPaletteHeaderSize`.
-	// _headerSize(rawPalette[0]),
+	// The header size in palettes is garbage. In at least KQ7 2.00b and Phant1,
+	// the 999.pal sets this value to 0. In most other palettes it is set to 14,
+	// but the *actual* size of the header structure used in SSCI is 13, which
+	// is reflected by `kHunkPaletteHeaderSize`.
 	_numPalettes(rawPalette.getUint8At(kNumPaletteEntriesOffset)),
 	_data() {
 	assert(_numPalettes == 0 || _numPalettes == 1);
@@ -371,18 +370,17 @@ static const uint8 gammaTables[GfxPalette32::numGammaTables][256] = {
 	_varyLastTick(0),
 	_varyTime(0),
 	_varyDirection(0),
+	_varyPercent(0),
 	_varyTargetPercent(0),
 	_varyNumTimesPaused(0),
 
 	// Palette cycling
-	_cyclers(),
 	_cycleMap(),
 
 	// Gamma correction
 	_gammaLevel(-1),
 	_gammaChanged(false) {
 
-	_varyPercent = _varyTargetPercent;
 	for (int i = 0, len = ARRAYSIZE(_fadeTable); i < len; ++i) {
 		_fadeTable[i] = 100;
 	}
@@ -390,11 +388,6 @@ static const uint8 gammaTables[GfxPalette32::numGammaTables][256] = {
 	loadPalette(999);
 }
 
-GfxPalette32::~GfxPalette32() {
-	varyOff();
-	cycleAllOff();
-}
-
 bool GfxPalette32::loadPalette(const GuiResourceId resourceId) {
 	Resource *palResource = _resMan->findResource(ResourceId(kResourceTypePalette, resourceId), false);
 
@@ -604,16 +597,16 @@ void GfxPalette32::setVary(const Palette &target, const int16 percent, const int
 }
 
 void GfxPalette32::setVaryPercent(const int16 percent, const int32 ticks) {
-	if (_varyTargetPalette != nullptr) {
+	if (_varyTargetPalette) {
 		setVaryTime(percent, ticks);
 	}
 
-	// NOTE: SSCI had two additional parameters for this function to change the
+	// SSCI had two additional parameters for this function to change the
 	// `_varyFromColor`, but they were always hardcoded to be ignored
 }
 
 void GfxPalette32::setVaryTime(const int32 time) {
-	if (_varyTargetPalette != nullptr) {
+	if (_varyTargetPalette) {
 		setVaryTime(_varyTargetPercent, time);
 	}
 }
@@ -645,16 +638,8 @@ void GfxPalette32::varyOff() {
 	_varyFromColor = 0;
 	_varyToColor = 255;
 	_varyDirection = 0;
-
-	if (_varyTargetPalette != nullptr) {
-		delete _varyTargetPalette;
-		_varyTargetPalette = nullptr;
-	}
-
-	if (_varyStartPalette != nullptr) {
-		delete _varyStartPalette;
-		_varyStartPalette = nullptr;
-	}
+	_varyTargetPalette.reset();
+	_varyStartPalette.reset();
 }
 
 void GfxPalette32::varyPause() {
@@ -667,7 +652,7 @@ void GfxPalette32::varyOn() {
 		--_varyNumTimesPaused;
 	}
 
-	if (_varyTargetPalette != nullptr && _varyNumTimesPaused == 0) {
+	if (_varyTargetPalette && _varyNumTimesPaused == 0) {
 		if (_varyPercent != _varyTargetPercent && _varyTime != 0) {
 			_varyDirection = (_varyTargetPercent - _varyPercent > 0) ? 1 : -1;
 		} else {
@@ -677,28 +662,26 @@ void GfxPalette32::varyOn() {
 }
 
 void GfxPalette32::setTarget(const Palette &palette) {
-	delete _varyTargetPalette;
-	_varyTargetPalette = new Palette(palette);
+	_varyTargetPalette.reset(new Palette(palette));
 }
 
 void GfxPalette32::setStart(const Palette &palette) {
-	delete _varyStartPalette;
-	_varyStartPalette = new Palette(palette);
+	_varyStartPalette.reset(new Palette(palette));
 }
 
 void GfxPalette32::mergeStart(const Palette &palette) {
-	if (_varyStartPalette != nullptr) {
+	if (_varyStartPalette) {
 		mergePalette(*_varyStartPalette, palette);
 	} else {
-		_varyStartPalette = new Palette(palette);
+		_varyStartPalette.reset(new Palette(palette));
 	}
 }
 
 void GfxPalette32::mergeTarget(const Palette &palette) {
-	if (_varyTargetPalette != nullptr) {
+	if (_varyTargetPalette) {
 		mergePalette(*_varyTargetPalette, palette);
 	} else {
-		_varyTargetPalette = new Palette(palette);
+		_varyTargetPalette.reset(new Palette(palette));
 	}
 }
 
@@ -714,9 +697,9 @@ void GfxPalette32::applyVary() {
 		_varyPercent += _varyDirection;
 	}
 
-	if (_varyPercent == 0 || _varyTargetPalette == nullptr) {
+	if (_varyPercent == 0 || !_varyTargetPalette) {
 		for (int i = 0; i < ARRAYSIZE(_nextPalette.colors); ++i) {
-			if (_varyStartPalette != nullptr && i >= _varyFromColor && i <= _varyToColor) {
+			if (_varyStartPalette && i >= _varyFromColor && i <= _varyToColor) {
 				_nextPalette.colors[i] = _varyStartPalette->colors[i];
 			} else {
 				_nextPalette.colors[i] = _sourcePalette.colors[i];
@@ -728,7 +711,7 @@ void GfxPalette32::applyVary() {
 				Color targetColor = _varyTargetPalette->colors[i];
 				Color sourceColor;
 
-				if (_varyStartPalette != nullptr) {
+				if (_varyStartPalette) {
 					sourceColor = _varyStartPalette->colors[i];
 				} else {
 					sourceColor = _sourcePalette.colors[i];
@@ -816,27 +799,28 @@ void GfxPalette32::setCycle(const uint8 fromColor, const uint8 toColor, const in
 		clearCycleMap(fromColor, cycler->numColorsToCycle);
 	} else {
 		for (int i = 0; i < kNumCyclers; ++i) {
-			if (_cyclers[i] == nullptr) {
-				_cyclers[i] = cycler = new PalCycler;
+			if (!_cyclers[i]) {
+				cycler = new PalCycler;
+				_cyclers[i].reset(cycler);
 				break;
 			}
 		}
 	}
 
-	// If there are no free cycler slots, SCI engine overrides the first oldest
-	// cycler that it finds, where "oldest" is determined by the difference
-	// between the tick and now
+	// If there are no free cycler slots, SSCI overrides the first oldest cycler
+	// that it finds, where "oldest" is determined by the difference between the
+	// tick and now
 	if (cycler == nullptr) {
 		const uint32 now = g_sci->getTickCount();
 		uint32 minUpdateDelta = 0xFFFFFFFF;
 
 		for (int i = 0; i < kNumCyclers; ++i) {
-			PalCycler *const candidate = _cyclers[i];
+			PalCyclerOwner &candidate = _cyclers[i];
 
 			const uint32 updateDelta = now - candidate->lastUpdateTick;
 			if (updateDelta < minUpdateDelta) {
 				minUpdateDelta = updateDelta;
-				cycler = candidate;
+				cycler = candidate.get();
 			}
 		}
 
@@ -882,19 +866,18 @@ void GfxPalette32::cyclePause(const uint8 fromColor) {
 
 void GfxPalette32::cycleAllOn() {
 	for (int i = 0; i < kNumCyclers; ++i) {
-		PalCycler *const cycler = _cyclers[i];
-		if (cycler != nullptr && cycler->numTimesPaused > 0) {
+		PalCyclerOwner &cycler = _cyclers[i];
+		if (cycler && cycler->numTimesPaused > 0) {
 			--cycler->numTimesPaused;
 		}
 	}
 }
 
 void GfxPalette32::cycleAllPause() {
-	// NOTE: The original engine did not check for null pointers in the
-	// palette cyclers pointer array.
+	// SSCI did not check for null pointers in the palette cyclers pointer array
 	for (int i = 0; i < kNumCyclers; ++i) {
-		PalCycler *const cycler = _cyclers[i];
-		if (cycler != nullptr) {
+		PalCyclerOwner &cycler = _cyclers[i];
+		if (cycler) {
 			// This seems odd, because currentCycle is 0..numColorsPerCycle,
 			// but fromColor is 0..255. When applyAllCycles runs, the values
 			// end up back in range
@@ -905,8 +888,8 @@ void GfxPalette32::cycleAllPause() {
 	applyAllCycles();
 
 	for (int i = 0; i < kNumCyclers; ++i) {
-		PalCycler *const cycler = _cyclers[i];
-		if (cycler != nullptr) {
+		PalCyclerOwner &cycler = _cyclers[i];
+		if (cycler) {
 			++cycler->numTimesPaused;
 		}
 	}
@@ -914,11 +897,10 @@ void GfxPalette32::cycleAllPause() {
 
 void GfxPalette32::cycleOff(const uint8 fromColor) {
 	for (int i = 0; i < kNumCyclers; ++i) {
-		PalCycler *const cycler = _cyclers[i];
-		if (cycler != nullptr && cycler->fromColor == fromColor) {
+		PalCyclerOwner &cycler = _cyclers[i];
+		if (cycler && cycler->fromColor == fromColor) {
 			clearCycleMap(fromColor, cycler->numColorsToCycle);
-			delete cycler;
-			_cyclers[i] = nullptr;
+			_cyclers[i].reset();
 			break;
 		}
 	}
@@ -926,11 +908,10 @@ void GfxPalette32::cycleOff(const uint8 fromColor) {
 
 void GfxPalette32::cycleAllOff() {
 	for (int i = 0; i < kNumCyclers; ++i) {
-		PalCycler *const cycler = _cyclers[i];
-		if (cycler != nullptr) {
+		PalCyclerOwner &cycler = _cyclers[i];
+		if (cycler) {
 			clearCycleMap(cycler->fromColor, cycler->numColorsToCycle);
-			delete cycler;
-			_cyclers[i] = nullptr;
+			_cyclers[i].reset();
 		}
 	}
 }
@@ -969,9 +950,9 @@ void GfxPalette32::setCycleMap(const uint16 fromColor, const uint16 numColorsToS
 
 PalCycler *GfxPalette32::getCycler(const uint16 fromColor) {
 	for (int cyclerIndex = 0; cyclerIndex < kNumCyclers; ++cyclerIndex) {
-		PalCycler *cycler = _cyclers[cyclerIndex];
-		if (cycler != nullptr && cycler->fromColor == fromColor) {
-			return cycler;
+		PalCyclerOwner &cycler = _cyclers[cyclerIndex];
+		if (cycler && cycler->fromColor == fromColor) {
+			return cycler.get();
 		}
 	}
 
@@ -980,12 +961,12 @@ PalCycler *GfxPalette32::getCycler(const uint16 fromColor) {
 
 void GfxPalette32::applyAllCycles() {
 	Color paletteCopy[256];
-	memcpy(paletteCopy, _nextPalette.colors, sizeof(Color) * 256);
+	memcpy(paletteCopy, _nextPalette.colors, sizeof(paletteCopy));
 
 	for (int i = 0; i < kNumCyclers; ++i) {
-		PalCycler *const cycler = _cyclers[i];
-		if (cycler != nullptr) {
-			cycler->currentCycle = (((int) cycler->currentCycle) + 1) % cycler->numColorsToCycle;
+		PalCyclerOwner &cycler = _cyclers[i];
+		if (cycler) {
+			cycler->currentCycle = (cycler->currentCycle + 1) % cycler->numColorsToCycle;
 			for (int j = 0; j < cycler->numColorsToCycle; j++) {
 				_nextPalette.colors[cycler->fromColor + j] = paletteCopy[cycler->fromColor + (cycler->currentCycle + j) % cycler->numColorsToCycle];
 			}
@@ -995,12 +976,12 @@ void GfxPalette32::applyAllCycles() {
 
 void GfxPalette32::applyCycles() {
 	Color paletteCopy[256];
-	memcpy(paletteCopy, _nextPalette.colors, sizeof(Color) * 256);
+	memcpy(paletteCopy, _nextPalette.colors, sizeof(paletteCopy));
 
 	const uint32 now = g_sci->getTickCount();
 	for (int i = 0; i < kNumCyclers; ++i) {
-		PalCycler *const cycler = _cyclers[i];
-		if (cycler == nullptr) {
+		PalCyclerOwner &cycler = _cyclers[i];
+		if (!cycler) {
 			continue;
 		}
 
diff --git a/engines/sci/graphics/palette32.h b/engines/sci/graphics/palette32.h
index b8ba85e..2d00b86 100644
--- a/engines/sci/graphics/palette32.h
+++ b/engines/sci/graphics/palette32.h
@@ -23,6 +23,8 @@
 #ifndef SCI_GRAPHICS_PALETTE32_H
 #define SCI_GRAPHICS_PALETTE32_H
 
+#include "common/ptr.h"
+
 namespace Sci {
 
 #pragma mark HunkPalette
@@ -233,7 +235,6 @@ struct PalCycler {
 class GfxPalette32 {
 public:
 	GfxPalette32(ResourceManager *resMan);
-	~GfxPalette32();
 
 	void saveLoadWithSerializer(Common::Serializer &s);
 
@@ -440,13 +441,13 @@ private:
 	 * operation. If this palette is not specified, `_sourcePalette` is used
 	 * instead.
 	 */
-	Palette *_varyStartPalette;
+	Common::ScopedPtr<Palette> _varyStartPalette;
 
 	/**
 	 * An optional palette used to provide target colors for a palette vary
 	 * operation.
 	 */
-	Palette *_varyTargetPalette;
+	Common::ScopedPtr<Palette> _varyTargetPalette;
 
 	/**
 	 * The minimum palette index that has been varied from the source palette.
@@ -553,7 +554,8 @@ private:
 		kNumCyclers = 10
 	};
 
-	PalCycler *_cyclers[kNumCyclers];
+	typedef Common::ScopedPtr<PalCycler> PalCyclerOwner;
+	PalCyclerOwner _cyclers[kNumCyclers];
 
 	/**
 	 * Updates the `currentCycle` of the given `cycler` by `speed` entries.
@@ -564,8 +566,8 @@ private:
 	 * The cycle map is used to detect overlapping cyclers, and to avoid
 	 * remapping to palette entries that are being cycled.
 	 *
-	 * According to SCI engine code, when two cyclers overlap, a fatal error has
-	 * occurred and the engine will display an error and then exit.
+	 * According to SSCI, when two cyclers overlap, a fatal error has occurred
+	 * and the engine will display an error and then exit.
 	 *
 	 * The color remapping system avoids attempts to remap to palette entries
 	 * that are cycling because they won't be the expected color once the cycler


Commit: 0ac5d84062e430dff0f102788015dbb609fcdaa0
    https://github.com/scummvm/scummvm/commit/0ac5d84062e430dff0f102788015dbb609fcdaa0
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:10:50-05:00

Commit Message:
SCI32: Clean up ScreenItem

* Rewrap comments to 80 columns
* Clarify comments where possible
* Use smart pointers where appropriate

Changed paths:
    engines/sci/engine/object.h
    engines/sci/graphics/plane32.cpp
    engines/sci/graphics/screen_item32.cpp
    engines/sci/graphics/screen_item32.h


diff --git a/engines/sci/engine/object.h b/engines/sci/engine/object.h
index ffc4ac2..9ab6ca3 100644
--- a/engines/sci/engine/object.h
+++ b/engines/sci/engine/object.h
@@ -169,7 +169,6 @@ public:
 		}
 	}
 
-	// NOTE: In real engine, -info- is treated as byte size
 	void clearInfoSelectorFlag(infoSelectorFlags flag) {
 		if (getSciVersion() == SCI_VERSION_3) {
 			_infoSelectorSci3 &= ~flag;
diff --git a/engines/sci/graphics/plane32.cpp b/engines/sci/graphics/plane32.cpp
index d9e0d2d..08708f2 100644
--- a/engines/sci/graphics/plane32.cpp
+++ b/engines/sci/graphics/plane32.cpp
@@ -201,10 +201,9 @@ void Plane::addPicInternal(const GuiResourceId pictureId, const Common::Point *p
 		} else {
 			screenItem->_position = celObj->_relativePosition;
 		}
-		_screenItemList.add(screenItem);
+		screenItem->_celObj.reset(celObj);
 
-		delete screenItem->_celObj;
-		screenItem->_celObj = celObj;
+		_screenItemList.add(screenItem);
 	}
 	_type = (g_sci->_features->hasTransparentPicturePlanes() && transparent) ? kPlaneTypeTransparentPicture : kPlaneTypePicture;
 }
diff --git a/engines/sci/graphics/screen_item32.cpp b/engines/sci/graphics/screen_item32.cpp
index 14e7173..4e1ed83 100644
--- a/engines/sci/graphics/screen_item32.cpp
+++ b/engines/sci/graphics/screen_item32.cpp
@@ -39,7 +39,6 @@ uint32 ScreenItem::_nextCreationId = 0;
 
 ScreenItem::ScreenItem(const reg_t object) :
 _creationId(_nextCreationId++),
-_celObj(nullptr),
 _object(object),
 _pictureId(-1),
 _created(g_sci->_gfxFrameout->getScreenCount()),
@@ -59,7 +58,6 @@ _plane(plane),
 _useInsetRect(false),
 _z(0),
 _celInfo(celInfo),
-_celObj(nullptr),
 _fixedPriority(false),
 _position(0, 0),
 _object(make_reg(0, _nextObjectId++)),
@@ -76,7 +74,6 @@ _plane(plane),
 _useInsetRect(false),
 _z(0),
 _celInfo(celInfo),
-_celObj(nullptr),
 _fixedPriority(false),
 _position(rect.left, rect.top),
 _object(make_reg(0, _nextObjectId++)),
@@ -98,7 +95,6 @@ _scale(scaleInfo),
 _useInsetRect(false),
 _z(0),
 _celInfo(celInfo),
-_celObj(nullptr),
 _fixedPriority(false),
 _position(position),
 _object(make_reg(0, _nextObjectId++)),
@@ -115,7 +111,6 @@ _plane(other._plane),
 _scale(other._scale),
 _useInsetRect(other._useInsetRect),
 _celInfo(other._celInfo),
-_celObj(nullptr),
 _object(other._object),
 _mirrorX(other._mirrorX),
 _scaledPosition(other._scaledPosition),
@@ -127,18 +122,18 @@ _drawBlackLines(other._drawBlackLines) {
 }
 
 void ScreenItem::operator=(const ScreenItem &other) {
-	// NOTE: The original engine did not check for differences in `_celInfo`
-	// to clear `_celObj` here; instead, it unconditionally set `_celInfo`,
-	// didn't clear `_celObj`, and did hacky stuff in `kIsOnMe` to avoid
-	// testing a mismatched `_celObj`. See `GfxFrameout::kernelIsOnMe` for
-	// more detail. kCelTypeMem types are unconditionally invalidated because
-	// the properties of a CelObjMem can "change" when a game deletes a bitmap
-	// and then creates a new one that reuses the old bitmap's offset in
-	// BitmapTable (as happens in the LSL7 About screen when hovering names).
+	// SSCI did not check for differences in `_celInfo` to clear `_celObj` here;
+	// instead, it unconditionally set `_celInfo`, didn't clear `_celObj`, and
+	// did hacky stuff in `kIsOnMe` to avoid testing a mismatched `_celObj`. See
+	// `GfxFrameout::kernelIsOnMe` for more detail.
+	//
+	// kCelTypeMem types are unconditionally invalidated because the properties
+	// of a CelObjMem can "change" when a game deletes a bitmap and then creates
+	// a new one that reuses the old bitmap's offset in BitmapTable (as happens
+	// in the LSL7 About screen when hovering names).
 	if (_celInfo.type == kCelTypeMem || _celInfo != other._celInfo) {
 		_celInfo = other._celInfo;
-		delete _celObj;
-		_celObj = nullptr;
+		_celObj.reset();
 	}
 
 	_creationId = other._creationId;
@@ -153,10 +148,6 @@ void ScreenItem::operator=(const ScreenItem &other) {
 	_drawBlackLines = other._drawBlackLines;
 }
 
-ScreenItem::~ScreenItem() {
-	delete _celObj;
-}
-
 void ScreenItem::init() {
 	_nextObjectId = 20000;
 	_nextCreationId = 0;
@@ -176,17 +167,12 @@ void ScreenItem::setFromObject(SegManager *segMan, const reg_t object, const boo
 		_celInfo.celNo = readSelectorValue(segMan, object, SELECTOR(cel));
 
 		if (_celInfo.resourceId <= kPlanePic) {
-			// TODO: Enhance GfxView or ResourceManager to allow
-			// metadata for resources to be retrieved once, from a
-			// single location
 			Resource *view = g_sci->getResMan()->findResource(ResourceId(kResourceTypeView, _celInfo.resourceId), false);
 			if (!view) {
 				error("Failed to load %s", _celInfo.toString().c_str());
 			}
 
-			// NOTE: +2 because the header size field itself is excluded from
-			// the header size in the data
-			const uint16 headerSize = view->getUint16SEAt(0) + 2;
+			const uint16 headerSize = view->getUint16SEAt(0) + /* header size field */ sizeof(uint16);
 			const uint8 loopCount = view->getUint8At(2);
 			const uint8 loopSize = view->getUint8At(12);
 
@@ -225,8 +211,7 @@ void ScreenItem::setFromObject(SegManager *segMan, const reg_t object, const boo
 	}
 
 	if (updateCel || updateBitmap) {
-		delete _celObj;
-		_celObj = nullptr;
+		_celObj.reset();
 	}
 
 	if (readSelectorValue(segMan, object, SELECTOR(fixPriority))) {
@@ -305,8 +290,8 @@ void ScreenItem::calcRects(const Plane &plane) {
 		}
 
 		// Cel may use a coordinate system that is not the same size as the
-		// script coordinate system (usually this means high-resolution
-		// pictures with low-resolution scripts)
+		// script coordinate system (usually this means high-resolution pictures
+		// with low-resolution scripts)
 		if (celObj._xResolution != kLowResX || celObj._yResolution != kLowResY) {
 			// high resolution coordinates
 
@@ -386,7 +371,7 @@ void ScreenItem::calcRects(const Plane &plane) {
 
 				mulinc(temp, celToScreenX, Ratio());
 
-				CelObjPic *celObjPic = dynamic_cast<CelObjPic *>(_celObj);
+				CelObjPic *celObjPic = dynamic_cast<CelObjPic *>(_celObj.get());
 				if (celObjPic == nullptr) {
 					error("Expected a CelObjPic");
 				}
@@ -415,9 +400,8 @@ void ScreenItem::calcRects(const Plane &plane) {
 
 			if (!scaleX.isOne() || !scaleY.isOne()) {
 				mulinc(_screenItemRect, scaleX, scaleY);
-				// TODO: This was in the original code, baked into the
-				// multiplication though it is not immediately clear
-				// why this is the only one that reduces the BR corner
+				// TODO: This was in SSCI, baked into the multiplication. It is
+				// not clear why this is the only one that reduces the BR corner
 				_screenItemRect.right -= 1;
 				_screenItemRect.bottom -= 1;
 			}
@@ -434,7 +418,7 @@ void ScreenItem::calcRects(const Plane &plane) {
 					temp.right -= 1;
 				}
 
-				CelObjPic *celObjPic = dynamic_cast<CelObjPic *>(_celObj);
+				CelObjPic *celObjPic = dynamic_cast<CelObjPic *>(_celObj.get());
 				if (celObjPic == nullptr) {
 					error("Expected a CelObjPic");
 				}
@@ -487,19 +471,19 @@ void ScreenItem::calcRects(const Plane &plane) {
 }
 
 CelObj &ScreenItem::getCelObj() const {
-	if (_celObj == nullptr) {
+	if (!_celObj) {
 		switch (_celInfo.type) {
 			case kCelTypeView:
-				_celObj = new CelObjView(_celInfo.resourceId, _celInfo.loopNo, _celInfo.celNo);
+				_celObj.reset(new CelObjView(_celInfo.resourceId, _celInfo.loopNo, _celInfo.celNo));
 			break;
 			case kCelTypePic:
 				error("Internal error, pic screen item with no cel.");
 			break;
 			case kCelTypeMem:
-				_celObj = new CelObjMem(_celInfo.bitmap);
+				_celObj.reset(new CelObjMem(_celInfo.bitmap));
 			break;
 			case kCelTypeColor:
-				_celObj = new CelObjColor(_celInfo.color, _insetRect.width(), _insetRect.height());
+				_celObj.reset(new CelObjColor(_celInfo.color, _insetRect.width(), _insetRect.height()));
 			break;
 		}
 	}
@@ -534,7 +518,7 @@ void ScreenItem::printDebugInfo(Console *con) const {
 
 	con->debugPrintf("    %s\n", _celInfo.toString().c_str());
 
-	if (_celObj != nullptr) {
+	if (_celObj) {
 		con->debugPrintf("    width %d, height %d, x-resolution %d, y-resolution %d\n",
 			_celObj->_width,
 			_celObj->_height,
@@ -583,8 +567,7 @@ void ScreenItem::update() {
 	}
 	_deleted = 0;
 
-	delete _celObj;
-	_celObj = nullptr;
+	_celObj.reset();
 }
 
 Common::Rect ScreenItem::getNowSeenRect(const Plane &plane) const {
@@ -647,15 +630,13 @@ Common::Rect ScreenItem::getNowSeenRect(const Plane &plane) const {
 
 		if (!scaleX.isOne() || !scaleY.isOne()) {
 			// Different games use a different cel scaling mode, but the
-			// difference isn't consistent across SCI versions; instead,
-			// it seems to be related to an update that happened during
-			// SCI2.1mid where games started using hi-resolution game
-			// scripts
+			// difference isn't consistent across SCI versions; instead, it
+			// seems to be related to an update that happened during SCI2.1mid
+			// where games started using high-resolution game scripts
 			if (scriptWidth == kLowResX) {
 				mulinc(nsRect, scaleX, scaleY);
-				// TODO: This was in the original code, baked into the
-				// multiplication though it is not immediately clear
-				// why this is the only one that reduces the BR corner
+				// TODO: This was in SSCI, baked into the multiplication. It is
+				// not clear why this is the only one that reduces the BR corner
 				nsRect.right -= 1;
 				nsRect.bottom -= 1;
 			} else {
@@ -693,9 +674,8 @@ Common::Rect ScreenItem::getNowSeenRect(const Plane &plane) const {
 
 		if (!scaleX.isOne() || !scaleY.isOne()) {
 			mulinc(nsRect, scaleX, scaleY);
-			// TODO: This was in the original code, baked into the
-			// multiplication though it is not immediately clear
-			// why this is the only one that reduces the BR corner
+			// TODO: This was in SSCI, baked into the multiplication. It is not
+			// clear why this is the only one that reduces the BR corner
 			nsRect.right -= 1;
 			nsRect.bottom -= 1;
 		}
diff --git a/engines/sci/graphics/screen_item32.h b/engines/sci/graphics/screen_item32.h
index cdde2d3..5acf759 100644
--- a/engines/sci/graphics/screen_item32.h
+++ b/engines/sci/graphics/screen_item32.h
@@ -49,22 +49,20 @@ class SegManager;
 #pragma mark ScreenItem
 
 /**
- * A ScreenItem is the engine-side representation of a
- * game script View.
+ * A ScreenItem is the engine-side representation of a game script View.
  */
 class ScreenItem {
 private:
 	/**
-	 * A serial used for screen items that are generated
-	 * inside the graphics engine, rather than the
-	 * interpreter.
+	 * A serial used for screen items that are generated inside the graphics
+	 * engine, rather than the interpreter.
 	 */
 	static uint16 _nextObjectId;
 
 	/**
-	 * A serial used to identify the creation order of
-	 * screen items, to ensure a stable sort order for
-	 * screen items with identical priorities and z-indexes.
+	 * A serial used to identify the creation order of screen items, to ensure a
+	 * stable sort order for screen items with identical priorities and
+	 * z-indexes.
 	 */
 	static uint32 _nextCreationId;
 
@@ -75,160 +73,145 @@ public:
 	reg_t _plane;
 
 	/**
-	 * Scaling data used to calculate the final screen
-	 * dimensions of the screen item as well as the scaling
-	 * ratios used when drawing the item to screen.
+	 * Scaling data used to calculate the final screen dimensions of the screen
+	 * item as well as the scaling ratios used when drawing the item to screen.
 	 */
 	ScaleInfo _scale;
 
 private:
 	/**
-	 * The position & dimensions of the screen item in
-	 * screen coordinates. This rect includes the offset
-	 * of the parent plane, but is not clipped to the
-	 * screen, so may include coordinates that are
-	 * offscreen.
+	 * The position & dimensions of the screen item in screen coordinates. This
+	 * rect includes the offset of the parent plane, but is not clipped to the
+	 * screen, so may include coordinates that are offscreen.
 	 */
 	Common::Rect _screenItemRect;
 
 	/**
-	 * If true, the `_insetRect` rectangle will be used
-	 * when calculating the dimensions of the screen item
-	 * instead of the cel's intrinsic width and height.
+	 * If true, the `_insetRect` rectangle will be used when calculating the
+	 * dimensions of the screen item instead of the cel's intrinsic width and
+	 * height.
 	 *
-	 * In other words, using an inset rect means that
-	 * the cel is cropped to the dimensions given in
-	 * `_insetRect`.
+	 * In other words, using an inset rect means that the cel is cropped to the
+	 * dimensions given in `_insetRect`.
 	 */
 	bool _useInsetRect;
 
 	/**
-	 * The cropping rectangle used when `_useInsetRect`
-	 * is true.
+	 * The cropping rectangle used when `_useInsetRect` is true.
 	 *
-	 * `_insetRect` is also used to describe the fill
-	 * rectangle of a screen item with a CelObjColor
-	 * cel.
+	 * `_insetRect` is also used to describe the fill rectangle of a screen item
+	 * with a CelObjColor cel.
 	 */
 	Common::Rect _insetRect;
 
 	/**
-	 * The z-index of the screen item in pseudo-3D space.
-	 * Higher values are drawn on top of lower values.
+	 * The z-index of the screen item in pseudo-3D space. Higher values are
+	 * drawn on top of lower values.
 	 */
 	int _z;
 
 	/**
-	 * Sets the common properties of a screen item that must
-	 * be set both during creation and update of a screen
-	 * item.
+	 * Sets the common properties of a screen item that must be set both during
+	 * creation and update of a screen item.
 	 */
 	void setFromObject(SegManager *segMan, const reg_t object, const bool updateCel, const bool updateBitmap);
 
 public:
 	/**
-	 * The creation order number, which ensures a stable
-	 * sort when screen items with identical priorities and
-	 * z-indexes are added to the screen item list.
+	 * The creation order number, which ensures a stable sort when screen items
+	 * with identical priorities and z-indexes are added to the screen item
+	 * list.
 	 */
 	uint32 _creationId;
 
 	/**
-	 * A descriptor for the cel object represented by the
-	 * screen item.
+	 * A descriptor for the cel object represented by the screen item.
 	 */
 	CelInfo32 _celInfo;
 
 	/**
-	 * The cel object used to actually render the screen
-	 * item. This member is populated by calling
-	 * `getCelObj`.
+	 * The cel object used to actually render the screen item. This member is
+	 * populated by calling `getCelObj`.
 	 */
-	mutable CelObj *_celObj;
+	mutable Common::ScopedPtr<CelObj> _celObj;
 
 	/**
-	 * If set, the priority for this screen item is fixed
-	 * in place. Otherwise, the priority of the screen item
-	 * is calculated from its y-position + z-index.
+	 * If set, the priority for this screen item is fixed in place. Otherwise,
+	 * the priority of the screen item is calculated from its y-position +
+	 * z-index.
 	 */
 	bool _fixedPriority;
 
 	/**
-	 * The rendering priority of the screen item, relative
-	 * only to the other screen items within the same plane.
-	 * Higher priorities are drawn above lower priorities.
+	 * The rendering priority of the screen item, relative only to the other
+	 * screen items within the same plane. Higher priorities are drawn above
+	 * lower priorities.
 	 */
 	int16 _priority;
 
 	/**
-	 * The top-left corner of the screen item, in game
-	 * script coordinates, relative to the parent plane.
+	 * The top-left corner of the screen item, in game script coordinates,
+	 * relative to the parent plane.
 	 */
 	Common::Point _position;
 
 	/**
-	 * The associated View script object that was
-	 * used to create the ScreenItem, or a numeric
-	 * value in the case of a ScreenItem that was
-	 * generated outside of the VM.
+	 * The associated View script object that was used to create the ScreenItem,
+	 * or a numeric value in the case of a ScreenItem that was generated by the
+	 * kernel.
 	 */
 	reg_t _object;
 
 	/**
-	 * For screen items representing picture resources,
-	 * the resource ID of the picture.
+	 * For screen items representing picture resources, the resource ID of the
+	 * picture.
 	 */
 	GuiResourceId _pictureId;
 
 	/**
 	 * Flags indicating the state of the screen item.
-	 * - `created` is set when the screen item is first
-	 *   created, either from a VM object or from within the
-	 *   engine itself
-	 * - `updated` is set when `created` is not already set
-	 *   and the screen item is updated from a VM object
-	 * - `deleted` is set by the parent plane, if the parent
-	 *   plane is a pic type and its picture resource ID has
-	 *   changed
+	 * - `created` is set when the screen item is first created, either from a
+	 *   VM object or from within the kernel
+	 * - `updated` is set when `created` is not already set and the screen item
+	 *   is updated from a VM object
+	 * - `deleted` is set by the parent plane, if the parent plane is a pic type
+	 *   and its picture resource ID has changed
 	 */
 	int _created, _updated, _deleted;
 
 	/**
-	 * For screen items that represent picture cels, this
-	 * value is set to match the `_mirrorX` property of the
-	 * parent plane and indicates that the cel should be
-	 * drawn horizontally mirrored. For final drawing, it is
-	 * XORed with the `_mirrorX` property of the cel object.
-	 * The cel object's `_mirrorX` property comes from the
-	 * resource data itself.
+	 * For screen items that represent picture cels, this value is set to match
+	 * the `_mirrorX` property of the parent plane and indicates that the cel
+	 * should be
+	 * drawn horizontally mirrored. For final drawing, it is XORed with the
+	 * `_mirrorX` property of the cel object. The cel object's `_mirrorX`
+	 * property comes from the resource data.
 	 */
 	bool _mirrorX;
 
 	/**
-	 * The scaling ratios to use when drawing this screen
-	 * item. These values are calculated according to the
-	 * scale info whenever the screen item is updated.
+	 * The scaling ratios to use when drawing this screen item. These values are
+	 * calculated according to the scale info whenever the screen item is
+	 * updated.
 	 */
 	Ratio _ratioX, _ratioY;
 
 	/**
-	 * The top-left corner of the screen item, in screen
-	 * coordinates.
+	 * The top-left corner of the screen item, in screen coordinates.
 	 */
 	Common::Point _scaledPosition;
 
 	/**
-	 * The position & dimensions of the screen item in
-	 * screen coordinates. This rect includes the offset of
-	 * the parent plane and is clipped to the screen.
+	 * The position & dimensions of the screen item in screen coordinates. This
+	 * rect includes the offset of the parent plane and is clipped to the
+	 * screen.
 	 */
 	Common::Rect _screenRect;
 
 	/**
-	 * Whether or not the screen item should be drawn
-	 * with black lines drawn every second line. This is
-	 * used when pixel doubling videos to improve apparent
-	 * sharpness at the cost of your eyesight.
+	 * Whether or not the screen item should be drawn with black lines drawn
+	 * every second line. This is used when pixel doubling videos to improve
+	 * apparent sharpness at the cost of your eyesight.
 	 */
 	bool _drawBlackLines;
 
@@ -242,7 +225,6 @@ public:
 	ScreenItem(const reg_t plane, const CelInfo32 &celInfo, const Common::Rect &rect);
 	ScreenItem(const reg_t plane, const CelInfo32 &celInfo, const Common::Point &position, const ScaleInfo &scaleInfo);
 	ScreenItem(const ScreenItem &other);
-	~ScreenItem();
 	void operator=(const ScreenItem &);
 
 	inline bool operator<(const ScreenItem &other) const {
@@ -337,39 +319,36 @@ public:
 	}
 
 	/**
-	 * Calculates the dimensions and scaling parameters for
-	 * the screen item, using the given plane as the parent
-	 * plane for screen rect positioning.
+	 * Calculates the dimensions and scaling parameters for the screen item,
+	 * using the given plane as the parent plane for screen rect positioning.
 	 *
-	 * @note This method was called Update in SCI engine.
+	 * @note This method was called Update in SSCI.
 	 */
 	void calcRects(const Plane &plane);
 
 	/**
-	 * Retrieves the corresponding cel object for this
-	 * screen item. If a cel object does not already exist,
-	 * one will be created and assigned.
+	 * Retrieves the corresponding cel object for this screen item. If a cel
+	 * object does not already exist, one will be created and assigned.
 	 */
 	CelObj &getCelObj() const;
 
 	void printDebugInfo(Console *con) const;
 
 	/**
-	 * Updates the properties of the screen item from a
-	 * VM object.
+	 * Updates the properties of the screen item from a VM object.
 	 */
 	void update(const reg_t object);
 
 	/**
-	 * Updates the properties of the screen item for one not belonging
-	 * to a VM object. Originally GraphicsMgr::UpdateScreenItem.
+	 * Updates the properties of the screen item for one not belonging to a VM
+	 * object. Originally GraphicsMgr::UpdateScreenItem.
 	 */
 	void update();
 
 	/**
-	 * Gets the "now seen" rect for the screen item, which
-	 * represents the current size and position of the
-	 * screen item on the screen in script coordinates.
+	 * Gets the "now seen" rect for the screen item, which represents the
+	 * current size and position of the screen item on the screen in script
+	 * coordinates.
 	 */
 	Common::Rect getNowSeenRect(const Plane &plane) const;
 };


Commit: ff3503abdee09fcd35d86297dfb79879d0ecc8b8
    https://github.com/scummvm/scummvm/commit/ff3503abdee09fcd35d86297dfb79879d0ecc8b8
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:10:50-05:00

Commit Message:
SCI32: Clean up GfxTransitions32

* Use containers where appropriate
* Re-wrap doxygen comments to 80 columns
* Clarify comments for parts of the engine that are understood now
  but were not understood at the time of the initial
  implementation

Changed paths:
    engines/sci/engine/kgraphics32.cpp
    engines/sci/graphics/transitions32.cpp
    engines/sci/graphics/transitions32.h


diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp
index b7fae2e..d093c55 100644
--- a/engines/sci/engine/kgraphics32.cpp
+++ b/engines/sci/engine/kgraphics32.cpp
@@ -368,10 +368,10 @@ reg_t kSetShowStyle(EngineState *s, int argc, reg_t *argv) {
 	const uint16 type = argv[0].toUint16();
 	reg_t planeObj = argv[1];
 	int16 seconds = argv[2].toSint16();
-	// NOTE: This value seems to indicate whether the transition is an
-	// “exit” transition (0) or an “enter” transition (-1) for fade
-	// transitions. For other types of transitions, it indicates a palette
-	// index value to use when filling the screen.
+	// This value indicates whether the transition is an "exit" transition (0)
+	// or an "enter" transition (-1) for fade transitions. For other types of
+	// transitions, it indicates a palette index value to use when filling the
+	// screen.
 	int16 back = argv[3].toSint16();
 	int16 priority = argv[4].toSint16();
 	int16 animate = argv[5].toSint16();
@@ -404,9 +404,8 @@ reg_t kSetShowStyle(EngineState *s, int argc, reg_t *argv) {
 		error("Illegal show style %d for plane %04x:%04x", type, PRINT_REG(planeObj));
 	}
 
-	// NOTE: The order of planeObj and showStyle are reversed
-	// because this is how SCI3 called the corresponding method
-	// on the KernelMgr
+	// The order of planeObj and showStyle are reversed because this is how
+	// SSCI3 called the corresponding method on the KernelMgr
 	g_sci->_gfxTransitions32->kernelSetShowStyle(argc, planeObj, (ShowStyleType)type, seconds, back, priority, animate, refFrame, pFadeArray, divisions, blackScreen);
 
 	return s->r_acc;
@@ -881,8 +880,8 @@ reg_t kSetScroll(EngineState *s, int argc, reg_t *argv) {
 	const int16 deltaY = argv[2].toSint16();
 	const GuiResourceId pictureId = argv[3].toUint16();
 	const bool animate = argv[4].toUint16();
-	// NOTE: speed was accepted as an argument, but then never actually used
-	// const int16 speed = argc > 5 ? (bool)argv[5].toSint16() : -1;
+	// argv[5] was some speed argument, but it was not actually used by SSCI, so
+	// we ignore it here
 	const bool mirrorX = argc > 6 ? (bool)argv[6].toUint16() : false;
 
 	g_sci->_gfxTransitions32->kernelSetScroll(plane, deltaX, deltaY, pictureId, animate, mirrorX);
diff --git a/engines/sci/graphics/transitions32.cpp b/engines/sci/graphics/transitions32.cpp
index df9c2da..8be9e63 100644
--- a/engines/sci/graphics/transitions32.cpp
+++ b/engines/sci/graphics/transitions32.cpp
@@ -126,7 +126,7 @@ void GfxTransitions32::processShowStyles() {
 			g_sci->_gfxFrameout->frameOut(true);
 			throttle();
 		}
-	} while(continueProcessing && doFrameOut);
+	} while (continueProcessing && doFrameOut);
 }
 
 void GfxTransitions32::processEffects(PlaneShowStyle &showStyle) {
@@ -249,14 +249,13 @@ void GfxTransitions32::kernelSetShowStyle(const uint16 argc, const reg_t planeOb
 
 	if (createNewEntry) {
 		entry = new PlaneShowStyle;
-		// NOTE: SCI2.1 engine tests if allocation returned a null pointer
-		// but then only avoids setting currentStep if this is so. Since
-		// this is a nonsensical approach, we do not do that here
+		// SSCI2.1 tests if allocation returned a null pointer but then only
+		// avoids setting currentStep if this is so. Since this nonsensical, we
+		// do not do that here
 		entry->currentStep = 0;
 		entry->processed = false;
 		entry->divisions = hasDivisions ? divisions : _defaultDivisions[type];
 		entry->plane = planeObj;
-		entry->fadeColorRangesCount = 0;
 
 		if (getSciVersion() < SCI_VERSION_2_1_MIDDLE) {
 			// for pixel dissolve
@@ -267,32 +266,26 @@ void GfxTransitions32::kernelSetShowStyle(const uint16 argc, const reg_t planeOb
 			entry->screenItems.clear();
 			entry->width = plane->_gameRect.width();
 			entry->height = plane->_gameRect.height();
-		} else {
-			entry->fadeColorRanges = nullptr;
-			if (hasFadeArray) {
-				// NOTE: SCI2.1mid engine does no check to verify that an array is
-				// successfully retrieved, and SegMan will cause a fatal error
-				// if we try to use a memory segment that is not an array
-				SciArray &table = *_segMan->lookupArray(pFadeArray);
-
-				uint32 rangeCount = table.size();
-				entry->fadeColorRangesCount = rangeCount;
-
-				// NOTE: SCI engine code always allocates memory even if the range
-				// table has no entries, but this does not really make sense, so
-				// we avoid the allocation call in this case
-				if (rangeCount > 0) {
-					entry->fadeColorRanges = new uint16[rangeCount];
-					for (size_t i = 0; i < rangeCount; ++i) {
-						entry->fadeColorRanges[i] = table.getAsInt16(i);
-					}
+		} else if (hasFadeArray) {
+			// SSCI2.1mid does no check to verify that an array is successfully
+			// retrieved
+			SciArray &table = *_segMan->lookupArray(pFadeArray);
+
+			const uint32 rangeCount = table.size();
+
+			// SSCI always allocates memory even if the range table has no
+			// entries, but this does not really make sense, so we avoid the
+			// allocation call in this case
+			if (rangeCount > 0) {
+				entry->fadeColorRanges.reserve(rangeCount);
+				for (uint32 i = 0; i < rangeCount; ++i) {
+					entry->fadeColorRanges.push_back(table.getAsInt16(i));
 				}
 			}
 		}
 	}
 
-	// NOTE: The original engine had no nullptr check and would just crash
-	// if it got to here
+	// SSCI had no nullptr check and would just crash if it got to here
 	if (entry == nullptr) {
 		error("Cannot edit non-existing ShowStyle entry");
 	}
@@ -397,10 +390,9 @@ ShowStyleList::iterator GfxTransitions32::deleteShowStyle(const ShowStyleList::i
 		break;
 	case kShowStyleFadeIn:
 	case kShowStyleFadeOut:
-		if (getSciVersion() > SCI_VERSION_2_1_EARLY && showStyle->fadeColorRangesCount > 0) {
-			delete[] showStyle->fadeColorRanges;
-		}
-		break;
+		// SSCI manually allocated the color ranges for fades and deleted that
+		// memory here, but we use a container so there is no extra cleanup
+		// needed
 	case kShowStyleNone:
 	case kShowStyleMorph:
 	case kShowStyleHShutterIn:
@@ -944,8 +936,8 @@ bool GfxTransitions32::processFade(const int8 direction, PlaneShowStyle &showSty
 		percent *= 100;
 		percent /= showStyle.divisions - 1;
 
-		if (showStyle.fadeColorRangesCount > 0) {
-			for (int i = 0, len = showStyle.fadeColorRangesCount; i < len; i += 2) {
+		if (showStyle.fadeColorRanges.size()) {
+			for (uint i = 0, len = showStyle.fadeColorRanges.size(); i < len; i += 2) {
 				g_sci->_gfxPalette32->setFade(percent, showStyle.fadeColorRanges[i], showStyle.fadeColorRanges[i + 1]);
 			}
 		} else {
diff --git a/engines/sci/graphics/transitions32.h b/engines/sci/graphics/transitions32.h
index c4c5228..4dbacf4 100644
--- a/engines/sci/graphics/transitions32.h
+++ b/engines/sci/graphics/transitions32.h
@@ -28,7 +28,7 @@
 #include "sci/engine/vm_types.h"
 
 namespace Sci {
-enum ShowStyleType /* : uint8 */ {
+enum ShowStyleType {
 	kShowStyleNone = 0,
 	kShowStyleHShutterOut = 1,
 	kShowStyleHShutterIn = 2,
@@ -48,14 +48,12 @@ enum ShowStyleType /* : uint8 */ {
 };
 
 /**
- * Show styles represent transitions applied to draw planes.
- * One show style per plane can be active at a time.
+ * A show style represents a transition applied to a Plane. One show style per
+ * plane can be active at a time.
  */
 struct PlaneShowStyle {
 	/**
-	 * The ID of the plane this show style belongs to.
-	 * In SCI2.1mid (at least SQ6), per-plane transitions
-	 * were removed and a single plane ID is used.
+	 * The ID of the plane this transition applies to.
 	 */
 	reg_t plane;
 
@@ -65,9 +63,8 @@ struct PlaneShowStyle {
 	ShowStyleType type;
 
 	/**
-	 * When true, the show style is an entry transition
-	 * to a new room. When false, it is an exit
-	 * transition away from an old room.
+	 * When true, the show style is an entry transition to a new room. When
+	 * false, it is an exit transition away from an old room.
 	 */
 	bool fadeUp;
 
@@ -77,38 +74,35 @@ struct PlaneShowStyle {
 	int16 divisions;
 
 	/**
-	 * The color used by transitions that draw CelObjColor
-	 * screen items. -1 for transitions that do not draw
-	 * screen items.
+	 * The color used by transitions that draw CelObjColor screen items. -1 for
+	 * transitions that do not draw screen items.
 	 */
 	int16 color;
 
-	// TODO: Probably uint32
-	// TODO: This field probably should be used in order to
-	// provide time-accurate processing of show styles. In the
-	// actual SCI engine (at least 2–2.1mid) it appears that
-	// style transitions are drawn “as fast as possible”, one
-	// step per loop, even though this delay field exists
+	/**
+	 * The amount of time, in ticks, between each cycle of the animation.
+	 */
 	int delay;
 
-	// TODO: Probably bool, but never seems to be true?
+	/**
+	 * If true, GfxTransitions32 will yield back to the main game loop after
+	 * calculating the next frame. Otherwise, GfxTransitions32 takes exclusive
+	 * control over the game loop until the transition has completed.
+	 */
 	bool animate;
 
 	/**
-	 * The wall time at which the next step of the animation
-	 * should execute.
+	 * The time at which the next step of the animation should execute.
 	 */
 	uint32 nextTick;
 
 	/**
-	 * During playback of the show style, the current step
-	 * (out of divisions).
+	 * During playback of the show style, the current step (out of `divisions`).
 	 */
 	int currentStep;
 
 	/**
-	 * Whether or not this style has finished running and
-	 * is ready for disposal.
+	 * Whether or not this style has finished running and is ready for disposal.
 	 */
 	bool processed;
 
@@ -117,32 +111,30 @@ struct PlaneShowStyle {
 	//
 
 	/**
-	 * A list of screen items, each representing one
-	 * block of a wipe transition.
+	 * A list of screen items, each representing one block of a wipe transition.
+	 * These screen items are owned by GfxFrameout.
 	 */
 	Common::Array<ScreenItem *> screenItems;
 
 	/**
-	 * For wipe transitions, the number of edges with a
-	 * moving wipe (1, 2, or 4).
+	 * For wipe transitions, the number of edges with a moving wipe (1, 2, or
+	 * 4).
 	 */
 	uint8 numEdges;
 
 	/**
-	 * The dimensions of the plane, in game script
-	 * coordinates.
+	 * The dimensions of the plane, in game script coordinates.
 	 */
 	int16 width, height;
 
 	/**
-	 * For pixel dissolve transitions, the screen item
-	 * used to render the transition.
+	 * For pixel dissolve transitions, the screen item used to render the
+	 * transition. This screen item is owned by GfxFrameout.
 	 */
 	ScreenItem *bitmapScreenItem;
 
 	/**
-	 * For pixel dissolve transitions, the bitmap used
-	 * to render the transition.
+	 * For pixel dissolve transitions, the bitmap used to render the transition.
 	 */
 	reg_t bitmap;
 
@@ -152,15 +144,13 @@ struct PlaneShowStyle {
 	uint32 dissolveMask;
 
 	/**
-	 * The first pixel that was dissolved in a pixel
-	 * dissolve transition.
+	 * The first pixel that was dissolved in a pixel dissolve transition.
 	 */
 	uint32 firstPixel;
 
 	/**
-	 * The last pixel that was dissolved. Once all
-	 * pixels have been dissolved, `pixel` will once
-	 * again equal `firstPixel`.
+	 * The last pixel that was dissolved. Once all pixels have been dissolved,
+	 * `pixel` will once again equal `firstPixel`.
 	 */
 	uint32 pixel;
 
@@ -169,21 +159,15 @@ struct PlaneShowStyle {
 	//
 
 	/**
-	 * The number of entries in the fadeColorRanges array.
-	 */
-	uint8 fadeColorRangesCount;
-
-	/**
-	 * A pointer to an dynamically sized array of palette
-	 * indexes, in the order [ fromColor, toColor, ... ].
+	 * An array of palette indexes, in the order [ fromColor, toColor, ... ].
 	 * Only colors within this range are transitioned.
 	 */
-	uint16 *fadeColorRanges;
+	Common::Array<uint16> fadeColorRanges;
 };
 
 /**
- * PlaneScroll describes a transition between two different
- * pictures within a single plane.
+ * PlaneScroll describes a transition between two different pictures within a
+ * single plane.
  */
 struct PlaneScroll {
 	/**
@@ -197,28 +181,26 @@ struct PlaneScroll {
 	int16 x, y;
 
 	/**
-	 * The distance that should be scrolled. Only one of
-	 * `deltaX` or `deltaY` may be set.
+	 * The distance that should be scrolled. Only one of `deltaX` or `deltaY`
+	 * may be set.
 	 */
 	int16 deltaX, deltaY;
 
 	/**
-	 * The pic that should be created and scrolled into
-	 * view inside the plane.
+	 * The pic that should be created and scrolled into view inside the plane.
 	 */
 	GuiResourceId newPictureId;
 
 	/**
-	 * The picture that should be scrolled out of view
-	 * and deleted from the plane.
+	 * The picture that should be scrolled out of view and deleted from the
+	 * plane.
 	 */
 	GuiResourceId oldPictureId;
 
 	/**
-	 * If true, the scroll animation is interleaved
-	 * with other updates to the graphics. If false,
-	 * the scroll will be exclusively animated until
-	 * it is finished.
+	 * If true, GfxTransitions32 will yield back to the main game loop after
+	 * calculating the next frame. Otherwise, GfxTransitions32 takes exclusive
+	 * control over the game loop until the transition has completed.
 	 */
 	bool animate;
 
@@ -235,6 +217,7 @@ class GfxTransitions32 {
 public:
 	GfxTransitions32(SegManager *_segMan);
 	~GfxTransitions32();
+
 private:
 	SegManager *_segMan;
 
@@ -264,209 +247,185 @@ public:
 	inline bool hasShowStyles() const { return !_showStyles.empty(); }
 
 	/**
-	 * Processes all active show styles in a loop
-	 * until they are finished.
+	 * Processes all active show styles in a loop until they are finished.
 	 */
 	void processShowStyles();
 
 	/**
-	 * Processes show styles that are applied
-	 * through `GfxFrameout::palMorphFrameOut`.
+	 * Processes show styles that are applied through
+	 * `GfxFrameout::palMorphFrameOut`.
 	 */
 	void processEffects(PlaneShowStyle &showStyle);
 
-	// NOTE: This signature is taken from SCI3 Phantasmagoria 2
-	// and is valid for all implementations of SCI32
 	void kernelSetShowStyle(const uint16 argc, const reg_t planeObj, const ShowStyleType type, const int16 seconds, const int16 direction, const int16 priority, const int16 animate, const int16 frameOutNow, reg_t pFadeArray, int16 divisions, const int16 blackScreen);
 
 	/**
-	 * Sets the range that will be used by
-	 * `GfxFrameout::palMorphFrameOut` to alter
-	 * palette entries.
+	 * Sets the range that will be used by `GfxFrameout::palMorphFrameOut` to
+	 * alter palette entries.
 	 */
 	void kernelSetPalStyleRange(const uint8 fromColor, const uint8 toColor);
 
 	/**
-	 * A map of palette entries that can be morphed
-	 * by the Morph show style.
+	 * A map of palette entries that can be morphed by the Morph show style.
 	 */
 	int8 _styleRanges[256];
 
 private:
 	/**
-	 * Default sequence values for pixel dissolve
-	 * transition bit masks.
+	 * Default sequence values for pixel dissolve transition bit masks.
 	 */
 	int *_dissolveSequenceSeeds;
 
 	/**
-	 * Default values for `PlaneShowStyle::divisions`
-	 * for the current SCI version.
+	 * Default values for `PlaneShowStyle::divisions` for the current SCI
+	 * version.
 	 */
 	int16 *_defaultDivisions;
 
 	/**
-	 * The list of PlaneShowStyles that are
-	 * currently active.
+	 * The list of PlaneShowStyles that are currently active.
 	 */
 	ShowStyleList _showStyles;
 
 	/**
-	 * Finds a show style that applies to the given
-	 * plane.
+	 * Finds a show style that applies to the given plane.
 	 */
 	PlaneShowStyle *findShowStyleForPlane(const reg_t planeObj);
 
 	/**
-	 * Finds the iterator for a show style that
-	 * applies to the given plane.
+	 * Finds the iterator for a show style that applies to the given plane.
 	 */
 	ShowStyleList::iterator findIteratorForPlane(const reg_t planeObj);
 
 	/**
-	 * Deletes the given PlaneShowStyle and returns
-	 * the next PlaneShowStyle from the list of
-	 * styles.
+	 * Deletes the given PlaneShowStyle and returns the next PlaneShowStyle from
+	 * the list of styles.
 	 */
 	ShowStyleList::iterator deleteShowStyle(const ShowStyleList::iterator &showStyle);
 
 	/**
-	 * Initializes the given PlaneShowStyle for a
-	 * horizontal wipe effect for SCI2 to 2.1early.
+	 * Initializes the given PlaneShowStyle for a horizontal wipe effect for
+	 * SCI2 to 2.1early.
 	 */
 	void configure21EarlyHorizontalWipe(PlaneShowStyle &showStyle, const int16 priority);
 
 	/**
-	 * Initializes the given PlaneShowStyle for a
-	 * horizontal shutter effect for SCI2 to 2.1early.
+	 * Initializes the given PlaneShowStyle for a horizontal shutter effect for
+	 * SCI2 to 2.1early.
 	 */
 	void configure21EarlyHorizontalShutter(PlaneShowStyle &showStyle, const int16 priority);
 
 	/**
-	 * Initializes the given PlaneShowStyle for an
-	 * iris effect for SCI2 to 2.1early.
+	 * Initializes the given PlaneShowStyle for an iris effect for SCI2 to
+	 * 2.1early.
 	 */
 	void configure21EarlyIris(PlaneShowStyle &showStyle, const int16 priority);
 
 	/**
-	 * Initializes the given PlaneShowStyle for a
-	 * pixel dissolve effect for SCI2 to 2.1early.
+	 * Initializes the given PlaneShowStyle for a pixel dissolve effect for SCI2
+	 * to 2.1early.
 	 */
 	void configure21EarlyDissolve(PlaneShowStyle &showStyle, const int16 priority, const Common::Rect &gameRect);
 
 	/**
-	 * Processes one tick of the given
-	 * PlaneShowStyle.
+	 * Processes one tick of the given PlaneShowStyle.
 	 */
 	bool processShowStyle(PlaneShowStyle &showStyle, uint32 now);
 
 	/**
-	 * Performs an instant transition between two
-	 * rooms.
+	 * Performs an instant transition between two rooms.
 	 */
 	bool processNone(PlaneShowStyle &showStyle);
 
 	/**
-	 * Performs a transition that renders into a room
-	 * with a horizontal shutter effect.
+	 * Performs a transition that renders into a room with a horizontal shutter
+	 * effect.
 	 */
 	bool processHShutterOut(PlaneShowStyle &showStyle);
 
 	/**
-	 * Performs a transition that renders to black
-	 * with a horizontal shutter effect.
+	 * Performs a transition that renders to black with a horizontal shutter
+	 * effect.
 	 */
 	void processHShutterIn(const PlaneShowStyle &showStyle);
 
 	/**
-	 * Performs a transition that renders into a room
-	 * with a vertical shutter effect.
+	 * Performs a transition that renders into a room with a vertical shutter
+	 * effect.
 	 */
 	void processVShutterOut(PlaneShowStyle &showStyle);
 
 	/**
-	 * Performs a transition that renders to black
-	 * with a vertical shutter effect.
+	 * Performs a transition that renders to black with a vertical shutter
+	 * effect.
 	 */
 	void processVShutterIn(PlaneShowStyle &showStyle);
 
 	/**
-	 * Performs a transition that renders into a room
-	 * with a wipe to the left.
+	 * Performs a transition that renders into a room with a wipe to the left.
 	 */
 	void processWipeLeft(PlaneShowStyle &showStyle);
 
 	/**
-	 * Performs a transition that renders to black
-	 * with a wipe to the right.
+	 * Performs a transition that renders to black with a wipe to the right.
 	 */
 	void processWipeRight(PlaneShowStyle &showStyle);
 
 	/**
-	 * Performs a transition that renders into a room
-	 * with a wipe upwards.
+	 * Performs a transition that renders into a room with a wipe upwards.
 	 */
 	void processWipeUp(PlaneShowStyle &showStyle);
 
 	/**
-	 * Performs a transition that renders to black
-	 * with a wipe downwards.
+	 * Performs a transition that renders to black with a wipe downwards.
 	 */
 	void processWipeDown(PlaneShowStyle &showStyle);
 
 	/**
-	 * Performs a transition that renders into a room
-	 * with an iris effect.
+	 * Performs a transition that renders into a room with an iris effect.
 	 */
 	bool processIrisOut(PlaneShowStyle &showStyle);
 
 	/**
-	 * Performs a transition that renders to black
-	 * with an iris effect.
+	 * Performs a transition that renders to black with an iris effect.
 	 */
 	bool processIrisIn(PlaneShowStyle &showStyle);
 
 	/**
-	 * Performs a transition that renders between
-	 * rooms using a block dissolve effect.
+	 * Performs a transition that renders between rooms using a block dissolve
+	 * effect.
 	 */
 	void processDissolveNoMorph(PlaneShowStyle &showStyle);
 
 	/**
-	 * Performs a transition that renders between
-	 * rooms with a pixel dissolve effect.
+	 * Performs a transition that renders between rooms with a pixel dissolve
+	 * effect.
 	 */
 	bool processPixelDissolve(PlaneShowStyle &showStyle);
 
 	/**
-	 * SCI2 to 2.1early implementation of pixel
-	 * dissolve.
+	 * SCI2 to 2.1early implementation of pixel dissolve.
 	 */
 	bool processPixelDissolve21Early(PlaneShowStyle &showStyle);
 
 	/**
-	 * SCI2.1mid and later implementation of
-	 * pixel dissolve.
+	 * SCI2.1mid and later implementation of pixel dissolve.
 	 */
 	bool processPixelDissolve21Mid(const PlaneShowStyle &showStyle);
 
 	/**
-	 * Performs a transition that fades to black
-	 * between rooms.
+	 * Performs a transition that fades to black between rooms.
 	 */
 	bool processFade(const int8 direction, PlaneShowStyle &showStyle);
 
 	/**
-	 * Morph transition calls back into the
-	 * transition system's `processEffects`
-	 * method, which then applies transitions
-	 * other than None, Fade, or Morph.
+	 * Morph transition calls back into the transition system's `processEffects`
+	 * method, which then applies transitions other than None, Fade, or Morph.
 	 */
 	bool processMorph(PlaneShowStyle &showStyle);
 
 	/**
-	 * Performs a generic transition for any of
-	 * the wipe/shutter/iris effects.
+	 * Performs a generic transition for any of the wipe/shutter/iris effects.
 	 */
 	bool processWipe(const int8 direction, PlaneShowStyle &showStyle);
 
@@ -476,8 +435,7 @@ public:
 	inline bool hasScrolls() const { return !_scrolls.empty(); }
 
 	/**
-	 * Processes all active plane scrolls
-	 * in a loop until they are finished.
+	 * Processes all active plane scrolls in a loop until they are finished.
 	 */
 	void processScrolls();
 
@@ -490,8 +448,7 @@ private:
 	ScrollList _scrolls;
 
 	/**
-	 * Performs a scroll of the content of
-	 * a plane.
+	 * Performs a scroll of the content of a plane.
 	 */
 	bool processScroll(PlaneScroll &scroll);
 };


Commit: 9d05bf79208fac113b81531996cead6521efa6fe
    https://github.com/scummvm/scummvm/commit/9d05bf79208fac113b81531996cead6521efa6fe
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:10:51-05:00

Commit Message:
SCI32: Clean up GfxCursor32

* Rewrap doxygen comments to 80 columns
* Renamings for clarity
* Deduplicate copy/paint code

Changed paths:
    engines/sci/graphics/cursor32.cpp
    engines/sci/graphics/cursor32.h


diff --git a/engines/sci/graphics/cursor32.cpp b/engines/sci/graphics/cursor32.cpp
index 74fbafa..ae8c014 100644
--- a/engines/sci/graphics/cursor32.cpp
+++ b/engines/sci/graphics/cursor32.cpp
@@ -34,22 +34,22 @@ namespace Sci {
 GfxCursor32::GfxCursor32() :
 	_hideCount(0),
 	_position(0, 0),
-	_writeToVMAP(false) {
+	_needsPaint(false) {
 }
 
-void GfxCursor32::init(const Buffer &vmap) {
-	_vmap = vmap;
-	_vmapRegion.rect = Common::Rect(_vmap.screenWidth, _vmap.screenHeight);
-	_vmapRegion.data = (byte *)_vmap.getPixels();
-	_restrictedArea = _vmapRegion.rect;
+void GfxCursor32::init(const Buffer &outputBuffer) {
+	_screen = outputBuffer;
+	_screenRegion.rect = Common::Rect(_screen.screenWidth, _screen.screenHeight);
+	_screenRegion.data = static_cast<byte *>(_screen.getPixels());
+	_restrictedArea = _screenRegion.rect;
 }
 
 GfxCursor32::~GfxCursor32() {
 	free(_cursor.data);
 	free(_cursorBack.data);
-	free(_drawBuff1.data);
-	free(_drawBuff2.data);
-	free(_savedVmapRegion.data);
+	free(_scratch1.data);
+	free(_scratch2.data);
+	free(_savedScreenRegion.data);
 }
 
 void GfxCursor32::hide() {
@@ -58,25 +58,26 @@ void GfxCursor32::hide() {
 	}
 
 	if (!_cursorBack.rect.isEmpty()) {
-		drawToHardware(_cursorBack);
+		drawToScreen(_cursorBack);
 	}
 }
 
 void GfxCursor32::revealCursor() {
 	_cursorBack.rect = _cursor.rect;
-	_cursorBack.rect.clip(_vmapRegion.rect);
+	_cursorBack.rect.clip(_screenRegion.rect);
 	if (_cursorBack.rect.isEmpty()) {
 		return;
 	}
 
-	readVideo(_cursorBack);
-	_drawBuff1.rect = _cursor.rect;
-	copy(_drawBuff1, _cursorBack);
-	paint(_drawBuff1, _cursor);
-	drawToHardware(_drawBuff1);
+	copyFromScreen(_cursorBack);
+	_scratch1.rect = _cursor.rect;
+	copy<false>(_scratch1, _cursorBack);
+	copy<true>(_scratch1, _cursor);
+	drawToScreen(_scratch1);
 }
 
-void GfxCursor32::paint(DrawRegion &target, const DrawRegion &source) {
+template <bool SKIP>
+void GfxCursor32::copy(DrawRegion &target, const DrawRegion &source) {
 	if (source.rect.isEmpty()) {
 		return;
 	}
@@ -96,25 +97,33 @@ void GfxCursor32::paint(DrawRegion &target, const DrawRegion &source) {
 	const byte *sourcePixel = source.data + (sourceYOffset * source.rect.width()) + sourceXOffset;
 	const uint8 skipColor = source.skipColor;
 
-	const int16 sourceStride = source.rect.width() - drawRectWidth;
-	const int16 targetStride = target.rect.width() - drawRectWidth;
+	int16 sourceStride = source.rect.width();
+	int16 targetStride = target.rect.width();
+	if (SKIP) {
+		sourceStride -= drawRectWidth;
+		targetStride -= drawRectWidth;
+	}
 
 	for (int16 y = 0; y < drawRectHeight; ++y) {
-		for (int16 x = 0; x < drawRectWidth; ++x) {
-			if (*sourcePixel != skipColor) {
-				*targetPixel = *sourcePixel;
+		if (SKIP) {
+			for (int16 x = 0; x < drawRectWidth; ++x) {
+				if (*sourcePixel != skipColor) {
+					*targetPixel = *sourcePixel;
+				}
+				++targetPixel;
+				++sourcePixel;
 			}
-			++targetPixel;
-			++sourcePixel;
+		} else {
+			memcpy(targetPixel, sourcePixel, drawRectWidth);
 		}
-		sourcePixel += sourceStride;
 		targetPixel += targetStride;
+		sourcePixel += sourceStride;
 	}
 }
 
-void GfxCursor32::drawToHardware(const DrawRegion &source) {
+void GfxCursor32::drawToScreen(const DrawRegion &source) {
 	Common::Rect drawRect(source.rect);
-	drawRect.clip(_vmapRegion.rect);
+	drawRect.clip(_screenRegion.rect);
 	const int16 sourceXOffset = drawRect.left - source.rect.left;
 	const int16 sourceYOffset = drawRect.top - source.rect.top;
 	byte *sourcePixel = source.data + (sourceYOffset * source.rect.width()) + sourceXOffset;
@@ -174,7 +183,7 @@ void GfxCursor32::setRestrictedArea(const Common::Rect &rect) {
 }
 
 void GfxCursor32::clearRestrictedArea() {
-	_restrictedArea = _vmapRegion.rect;
+	_restrictedArea = _screenRegion.rect;
 }
 
 void GfxCursor32::setView(const GuiResourceId viewId, const int16 loopNo, const int16 celNo) {
@@ -279,58 +288,29 @@ void GfxCursor32::setView(const GuiResourceId viewId, const int16 loopNo, const
 		_cursor.rect = Common::Rect(_width, _height);
 		*_cursor.data = _cursor.skipColor;
 		_cursorBack.rect = _cursor.rect;
-		_cursorBack.rect.clip(_vmapRegion.rect);
+		_cursorBack.rect.clip(_screenRegion.rect);
 		if (!_cursorBack.rect.isEmpty()) {
-			readVideo(_cursorBack);
+			copyFromScreen(_cursorBack);
 		}
 	}
 
 	_cursorBack.data = (byte *)realloc(_cursorBack.data, _width * _height);
 	memset(_cursorBack.data, 0, _width * _height);
-	_drawBuff1.data = (byte *)realloc(_drawBuff1.data, _width * _height);
-	_drawBuff2.data = (byte *)realloc(_drawBuff2.data, _width * _height * 4);
-	_savedVmapRegion.data = (byte *)realloc(_savedVmapRegion.data, _width * _height);
+	_scratch1.data = (byte *)realloc(_scratch1.data, _width * _height);
+	_scratch2.data = (byte *)realloc(_scratch2.data, _width * _height * 4);
+	_savedScreenRegion.data = (byte *)realloc(_savedScreenRegion.data, _width * _height);
 
 	unhide();
 }
 
-void GfxCursor32::readVideo(DrawRegion &target) {
-	// NOTE: In SSCI, mouse events were received via hardware interrupt, so
-	// there was a separate branch here that would read from VRAM instead of
-	// from the game's back buffer when a mouse event was received while the
-	// back buffer was being updated. In ScummVM, mouse events are polled, which
-	// means it is not possible to receive a mouse event during a back buffer
-	// update, so the code responsible for handling that is removed.
-	copy(target, _vmapRegion);
-}
-
-void GfxCursor32::copy(DrawRegion &target, const DrawRegion &source) {
-	if (source.rect.isEmpty()) {
-		return;
-	}
-
-	Common::Rect drawRect(source.rect);
-	drawRect.clip(target.rect);
-	if (drawRect.isEmpty()) {
-		return;
-	}
-
-	const int16 sourceXOffset = drawRect.left - source.rect.left;
-	const int16 sourceYOffset = drawRect.top - source.rect.top;
-	const int16 drawWidth = drawRect.width();
-	const int16 drawHeight = drawRect.height();
-
-	byte *targetPixel = target.data + ((drawRect.top - target.rect.top) * target.rect.width()) + (drawRect.left - target.rect.left);
-	const byte *sourcePixel = source.data + (sourceYOffset * source.rect.width()) + sourceXOffset;
-
-	const int16 sourceStride = source.rect.width();
-	const int16 targetStride = target.rect.width();
-
-	for (int y = 0; y < drawHeight; ++y) {
-		memcpy(targetPixel, sourcePixel, drawWidth);
-		targetPixel += targetStride;
-		sourcePixel += sourceStride;
-	}
+void GfxCursor32::copyFromScreen(DrawRegion &target) {
+	// In SSCI, mouse events were received via hardware interrupt, so there was
+	// a separate branch here that would read from VRAM instead of from the
+	// game's back buffer when a mouse event was received while the back buffer
+	// was being updated. In ScummVM, mouse events are polled, which means it is
+	// not possible to receive a mouse event during a back buffer update, so the
+	// code responsible for handling that is removed.
+	copy<false>(target, _screenRegion);
 }
 
 void GfxCursor32::setPosition(const Common::Point &position) {
@@ -349,32 +329,32 @@ void GfxCursor32::setPosition(const Common::Point &position) {
 }
 
 void GfxCursor32::gonnaPaint(Common::Rect paintRect) {
-	if (!_hideCount && !_writeToVMAP && !_cursorBack.rect.isEmpty()) {
+	if (!_hideCount && !_needsPaint && !_cursorBack.rect.isEmpty()) {
 		paintRect.left &= ~3;
 		paintRect.right |= 3;
 		if (_cursorBack.rect.intersects(paintRect)) {
-			_writeToVMAP = true;
+			_needsPaint = true;
 		}
 	}
 }
 
 void GfxCursor32::paintStarting() {
-	if (_writeToVMAP) {
-		_savedVmapRegion.rect = _cursor.rect;
-		copy(_savedVmapRegion, _vmapRegion);
-		paint(_vmapRegion, _cursor);
+	if (_needsPaint) {
+		_savedScreenRegion.rect = _cursor.rect;
+		copy<false>(_savedScreenRegion, _screenRegion);
+		copy<true>(_screenRegion, _cursor);
 	}
 }
 
 void GfxCursor32::donePainting() {
-	if (_writeToVMAP) {
-		copy(_vmapRegion, _savedVmapRegion);
-		_savedVmapRegion.rect = Common::Rect();
-		_writeToVMAP = false;
+	if (_needsPaint) {
+		copy<false>(_screenRegion, _savedScreenRegion);
+		_savedScreenRegion.rect = Common::Rect();
+		_needsPaint = false;
 	}
 
 	if (!_hideCount && !_cursorBack.rect.isEmpty()) {
-		copy(_cursorBack, _vmapRegion);
+		copy<false>(_cursorBack, _screenRegion);
 	}
 }
 
@@ -423,45 +403,45 @@ void GfxCursor32::move() {
 	}
 
 	// Cursor moved offscreen
-	if (!_cursor.rect.intersects(_vmapRegion.rect)) {
-		drawToHardware(_cursorBack);
+	if (!_cursor.rect.intersects(_screenRegion.rect)) {
+		drawToScreen(_cursorBack);
 		return;
 	}
 
 	if (!_cursor.rect.intersects(_cursorBack.rect)) {
 		// Cursor moved to a completely different part of the screen
-		_drawBuff1.rect = _cursor.rect;
-		_drawBuff1.rect.clip(_vmapRegion.rect);
-		readVideo(_drawBuff1);
+		_scratch1.rect = _cursor.rect;
+		_scratch1.rect.clip(_screenRegion.rect);
+		copyFromScreen(_scratch1);
 
-		_drawBuff2.rect = _drawBuff1.rect;
-		copy(_drawBuff2, _drawBuff1);
+		_scratch2.rect = _scratch1.rect;
+		copy<false>(_scratch2, _scratch1);
 
-		paint(_drawBuff1, _cursor);
-		drawToHardware(_drawBuff1);
+		copy<true>(_scratch1, _cursor);
+		drawToScreen(_scratch1);
 
-		drawToHardware(_cursorBack);
+		drawToScreen(_cursorBack);
 
 		_cursorBack.rect = _cursor.rect;
-		_cursorBack.rect.clip(_vmapRegion.rect);
-		copy(_cursorBack, _drawBuff2);
+		_cursorBack.rect.clip(_screenRegion.rect);
+		copy<false>(_cursorBack, _scratch2);
 	} else {
 		// Cursor moved, but still overlaps the previous cursor location
 		Common::Rect mergedRect(_cursorBack.rect);
 		mergedRect.extend(_cursor.rect);
-		mergedRect.clip(_vmapRegion.rect);
+		mergedRect.clip(_screenRegion.rect);
 
-		_drawBuff2.rect = mergedRect;
-		readVideo(_drawBuff2);
+		_scratch2.rect = mergedRect;
+		copyFromScreen(_scratch2);
 
-		copy(_drawBuff2, _cursorBack);
+		copy<false>(_scratch2, _cursorBack);
 
 		_cursorBack.rect = _cursor.rect;
-		_cursorBack.rect.clip(_vmapRegion.rect);
-		copy(_cursorBack, _drawBuff2);
+		_cursorBack.rect.clip(_screenRegion.rect);
+		copy<false>(_cursorBack, _scratch2);
 
-		paint(_drawBuff2, _cursor);
-		drawToHardware(_drawBuff2);
+		copy<true>(_scratch2, _cursor);
+		drawToScreen(_scratch2);
 	}
 }
 
diff --git a/engines/sci/graphics/cursor32.h b/engines/sci/graphics/cursor32.h
index 562a2c5..fb07c49 100644
--- a/engines/sci/graphics/cursor32.h
+++ b/engines/sci/graphics/cursor32.h
@@ -23,6 +23,7 @@
 #ifndef SCI_GRAPHICS_CURSOR32_H
 #define SCI_GRAPHICS_CURSOR32_H
 
+#include "common/array.h"           // for Array
 #include "common/rect.h"            // for Point, Rect
 #include "common/scummsys.h"        // for int16, byte, uint8
 #include "common/serializer.h"      // for Serializable, Serializer (ptr only)
@@ -37,11 +38,10 @@ public:
 	~GfxCursor32();
 
 	/**
-	 * Initialises the cursor system with the given
-	 * buffer to use as the output buffer for
-	 * rendering the cursor.
+	 * Initialises the cursor system with the given buffer to use as the output
+	 * buffer for rendering the cursor.
 	 */
-	void init(const Buffer &vmap);
+	void init(const Buffer &outputBuffer);
 
 	/**
 	 * Called when the hardware mouse moves.
@@ -49,41 +49,35 @@ public:
 	bool deviceMoved(Common::Point &position);
 
 	/**
-	 * Called by GfxFrameout once for each show
-	 * rectangle that is going to be drawn to
-	 * hardware.
+	 * Called by GfxFrameout once for each show rectangle that is going to be
+	 * drawn to hardware.
 	 */
 	void gonnaPaint(Common::Rect paintRect);
 
 	/**
-	 * Called by GfxFrameout when the rendering to
-	 * hardware begins.
+	 * Called by GfxFrameout when the rendering to hardware begins.
 	 */
 	void paintStarting();
 
 	/**
-	 * Called by GfxFrameout when the output buffer
-	 * has finished rendering to hardware.
+	 * Called by GfxFrameout when the output buffer has finished rendering to
+	 * hardware.
 	 */
 	void donePainting();
 
 	/**
-	 * Hides the cursor. Each call to `hide` will
-	 * increment a hide counter, which must be
-	 * returned to 0 before the cursor will be
-	 * shown again.
+	 * Hides the cursor. Each call to `hide` will increment a hide counter,
+	 * which must be returned to 0 before the cursor will be shown again.
 	 */
 	void hide();
 
 	/**
-	 * Shows the cursor, if the hide counter is
-	 * returned to 0.
+	 * Shows the cursor, if the hide counter is returned to 0.
 	 */
 	void unhide();
 
 	/**
-	 * Shows the cursor regardless of the state of
-	 * the hide counter.
+	 * Shows the cursor regardless of the state of the hide counter.
 	 */
 	void show();
 
@@ -93,14 +87,12 @@ public:
 	void setView(const GuiResourceId viewId, const int16 loopNo, const int16 celNo);
 
 	/**
-	 * Explicitly sets the position of the cursor,
-	 * in game script coordinates.
+	 * Explicitly sets the position of the cursor, in game script coordinates.
 	 */
 	void setPosition(const Common::Point &position);
 
 	/**
-	 * Sets the region that the mouse is allowed
-	 * to move within.
+	 * Sets the region that the mouse is allowed to move within.
 	 */
 	void setRestrictedArea(const Common::Rect &rect);
 
@@ -109,10 +101,6 @@ public:
 	 */
 	void clearRestrictedArea();
 
-#ifdef ENABLE_SCI32_MAC
-	void setMacCursorRemapList(int cursorCount, reg_t *cursors);
-#endif
-
 	virtual void saveLoadWithSerializer(Common::Serializer &ser);
 
 private:
@@ -121,42 +109,41 @@ private:
 		byte *data;
 		uint8 skipColor;
 
-		DrawRegion() : rect(), data(nullptr) {}
+		DrawRegion() : data(nullptr) {}
 	};
 
 	/**
-	 * Information about the current cursor.
-	 * Used to restore cursor when loading a
-	 * savegame.
+	 * Information about the current cursor. Used to restore cursor when loading
+	 * a savegame.
 	 */
 	CelInfo32 _cursorInfo;
 
 	/**
-	 * Content behind the cursor? TODO
+	 * The content of the frame buffer which was behind the cursor prior to its
+	 * being drawn.
 	 */
 	DrawRegion _cursorBack;
 
 	/**
 	 * Scratch buffer.
 	 */
-	DrawRegion _drawBuff1;
+	DrawRegion _scratch1;
 
 	/**
 	 * Scratch buffer 2.
 	 */
-	DrawRegion _drawBuff2;
+	DrawRegion _scratch2;
 
 	/**
-	 * A draw region representing the current
-	 * output buffer.
+	 * A draw region representing the entire output buffer.
 	 */
-	DrawRegion _vmapRegion;
+	DrawRegion _screenRegion;
 
 	/**
-	 * The content behind the cursor in the
+	 * The region behind the cursor immediately before it is painted to the
 	 * output buffer.
 	 */
-	DrawRegion _savedVmapRegion;
+	DrawRegion _savedScreenRegion;
 
 	/**
 	 * The cursor bitmap.
@@ -164,93 +151,82 @@ private:
 	DrawRegion _cursor;
 
 	/**
-	 * The width and height of the cursor,
-	 * in screen coordinates.
+	 * The width and height of the cursor, in screen coordinates.
 	 */
 	int16 _width, _height;
 
 	/**
-	 * The output buffer where the cursor is
-	 * rendered.
+	 * The output buffer where the cursor is rendered.
 	 */
-	Buffer _vmap;
+	Buffer _screen;
 
 	/**
-	 * The number of times the cursor has been
-	 * hidden.
+	 * The number of times the cursor has been hidden.
 	 */
 	int _hideCount;
 
 	/**
-	 * The rendered position of the cursor, in
-	 * screen coordinates.
+	 * The rendered position of the cursor, in screen coordinates.
 	 */
 	Common::Point _position;
 
 	/**
-	 * The position of the cursor hot spot, relative
-	 * to the cursor origin, in screen pixels.
+	 * The position of the cursor hot spot, relative to the cursor origin, in
+	 * screen pixels.
 	 */
 	Common::Point _hotSpot;
 
 	/**
-	 * The area within which the cursor is allowed
-	 * to move, in screen pixels.
+	 * The area within which the cursor is allowed to move, in screen pixels.
 	 */
 	Common::Rect _restrictedArea;
 
 	/**
-	 * Indicates whether or not the cursor needs to
-	 * be repainted on the output buffer due to a
-	 * change of graphics in the area underneath the
-	 * cursor.
-	 */
-	bool _writeToVMAP;
-
-	// Mac versions of games use a remap list to remap their cursors
-	Common::Array<uint16> _macCursorRemap;
-
-	/**
-	 * Reads data from the output buffer or hardware
-	 * to the given draw region.
+	 * Indicates whether or not the cursor needs to be repainted on the output
+	 * buffer due to a change of graphics in the area underneath the cursor.
 	 */
-	void readVideo(DrawRegion &target);
+	bool _needsPaint;
 
 	/**
-	 * Reads data from the output buffer to the
-	 * given draw region.
+	 * Reads data from the output buffer to the given draw region.
 	 */
-	void readVideoFromVmap(DrawRegion &target);
+	void copyFromScreen(DrawRegion &target);
 
 	/**
-	 * Copies pixel data from the given source to
-	 * the given target.
+	 * Copies pixel data from the given source to the given target. If SKIP is
+	 * true, pixels that match the `skipColor` property of the source will be
+	 * skipped.
+	 *
+	 * @note In SSCI, the function that did not handle skip color was called
+	 * `copy` and the one that did was called `paint`.
 	 */
+	template <bool SKIP>
 	void copy(DrawRegion &target, const DrawRegion &source);
 
 	/**
-	 * Draws from the given source onto the given
-	 * target, skipping pixels in the source that
-	 * match the `skipColor` property.
-	 */
-	void paint(DrawRegion &target, const DrawRegion &source);
-
-	/**
-	 * Draws the cursor to the position it was
-	 * drawn to prior to moving offscreen or being
-	 * hidden by a call to `hide`.
+	 * Draws the cursor to the position it was drawn to prior to moving
+	 * offscreen or being hidden by a call to `hide`.
 	 */
 	void revealCursor();
 
 	/**
 	 * Draws the given source to the output buffer.
 	 */
-	void drawToHardware(const DrawRegion &source);
+	void drawToScreen(const DrawRegion &source);
 
 	/**
 	 * Renders the cursor at its new location.
 	 */
 	void move();
+
+#ifdef ENABLE_SCI32_MAC
+public:
+	void setMacCursorRemapList(int cursorCount, reg_t *cursors);
+
+private:
+	// Mac versions of games use a remap list to remap their cursors
+	Common::Array<uint16> _macCursorRemap;
+#endif
 };
 
 } // End of namespace Sci


Commit: c413030be3a03e363c7c5728dbeb1fe65f90688e
    https://github.com/scummvm/scummvm/commit/c413030be3a03e363c7c5728dbeb1fe65f90688e
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:10:51-05:00

Commit Message:
SCI32: Clean up Video32

* Rewrap comments to 80 columns
* Clarify comments where appropriate

Changed paths:
    engines/sci/graphics/video32.cpp
    engines/sci/graphics/video32.h


diff --git a/engines/sci/graphics/video32.cpp b/engines/sci/graphics/video32.cpp
index e837cec..c128ba1 100644
--- a/engines/sci/graphics/video32.cpp
+++ b/engines/sci/graphics/video32.cpp
@@ -63,8 +63,8 @@ bool VideoPlayer::open(const Common::String &fileName) {
 	}
 
 #ifndef USE_RGB_COLOR
-	// KQ7 2.00b videos are compressed in 24bpp Cinepak, so cannot play on
-	// a system with no RGB support
+	// KQ7 2.00b videos are compressed in 24bpp Cinepak, so cannot play on a
+	// system with no RGB support
 	if (_decoder->getPixelFormat().bytesPerPixel != 1) {
 		void showScummVMDialog(const Common::String &message);
 		showScummVMDialog(Common::String::format(_("Cannot play back %dbpp video on a system with maximum color depth of 8bpp"), _decoder->getPixelFormat().bpp()));
@@ -117,8 +117,8 @@ bool VideoPlayer::endHQVideo() {
 }
 
 VideoPlayer::EventFlags VideoPlayer::playUntilEvent(const EventFlags flags, const uint32 maxSleepMs) {
-	// Flushing all the keyboard and mouse events out of the event manager
-	// keeps events queued from before the start of playback from accidentally
+	// Flushing all the keyboard and mouse events out of the event manager keeps
+	// events queued from before the start of playback from accidentally
 	// activating a video stop flag
 	_eventMan->flushEvents();
 
@@ -201,11 +201,10 @@ void VideoPlayer::submitPalette(const uint8 palette[256 * 3]) const {
 	g_system->getPaletteManager()->setPalette(palette, 0, 256);
 
 	// KQ7 1.x has videos encoded using Microsoft Video 1 where palette 0 is
-	// white and 255 is black, which is basically the opposite of DOS/Win
-	// SCI palettes. So, when drawing to an 8bpp hwscreen, whenever a new
-	// palette is seen, the screen must be re-filled with the new black
-	// entry to ensure areas outside the video are always black and not some
-	// other color
+	// white and 255 is black, which is basically the opposite of DOS/Win SCI
+	// palettes. So, when drawing to an 8bpp hwscreen, whenever a new palette is
+	// seen, the screen must be re-filled with the new black entry to ensure
+	// areas outside the video are always black and not some other color
 	for (int color = 0; color < 256; ++color) {
 		if (palette[0] == 0 && palette[1] == 0 && palette[2] == 0) {
 			g_system->fillScreen(color);
@@ -231,7 +230,8 @@ void VideoPlayer::renderFrame(const Graphics::Surface &nextFrame) const {
 	if (_decoder->getWidth() != _drawRect.width() || _decoder->getHeight() != _drawRect.height()) {
 		Graphics::Surface *const unscaledFrame(convertedFrame);
 		// TODO: The only reason TransparentSurface is used here because it is
-		// where common scaler code is right now.
+		// where common scaler code is right now, which should just be part of
+		// Graphics::Surface (or some free functions).
 		const Graphics::TransparentSurface tsUnscaledFrame(*unscaledFrame);
 #ifdef USE_RGB_COLOR
 		if (_hqVideoMode) {
@@ -315,9 +315,9 @@ void SEQPlayer::play(const Common::String &fileName, const int16 numTicks, const
 	const int16 scaledWidth = (_decoder->getWidth() * Ratio(screenWidth, scriptWidth)).toInt();
 	const int16 scaledHeight = (_decoder->getHeight() * Ratio(screenHeight, scriptHeight)).toInt();
 
-	// Normally we would use the coordinates passed into the play function
-	// to position the video, but since we are scaling the video (which SSCI
-	// did not do), the coordinates are not correct. Since videos are always
+	// Normally we would use the coordinates passed into the play function to
+	// position the video, but since we are scaling the video (which SSCI did
+	// not do), the coordinates are not correct. Since videos are always
 	// intended to play in the center of the screen, we just recalculate the
 	// origin here.
 	_drawRect.left = (screenWidth - scaledWidth) / 2;
@@ -449,9 +449,9 @@ AVIPlayer::IOStatus AVIPlayer::play(const int16 from, const int16 to, const int1
 }
 
 AVIPlayer::EventFlags AVIPlayer::playUntilEvent(const EventFlags flags, const uint32 maxSleepMs) {
-	// NOTE: In SSCI, whether or not a video could be skipped was controlled by
-	// game scripts; here, we always allow skipping video with the mouse or
-	// escape key, to improve the user experience
+	// In SSCI, whether or not a video could be skipped was controlled by game
+	// scripts; here, we always allow skipping video with the mouse or escape
+	// key, to improve the user experience
 	return VideoPlayer::playUntilEvent(flags | kEventFlagMouseDown | kEventFlagEscapeKey, maxSleepMs);
 }
 
@@ -681,8 +681,8 @@ VMDPlayer::EventFlags VMDPlayer::kernelPlayUntilEvent(const EventFlags flags, co
 
 VMDPlayer::EventFlags VMDPlayer::playUntilEvent(const EventFlags flags, const uint32) {
 	if (flags & kEventFlagReverse) {
-		// NOTE: This flag may not work properly since SSCI does not care
-		// if a video has audio, but the VMD decoder does.
+		// This flag may not work properly since SSCI does not care if a video
+		// has audio, but the VMD decoder does.
 		warning("VMD reverse playback flag was set. Please report this event to the bug tracker");
 		const bool success = _decoder->setReverse(true);
 		assert(success);
@@ -838,10 +838,10 @@ void VMDPlayer::submitPalette(const uint8 rawPalette[256 * 3]) const {
 	if (_isComposited) {
 		SciBitmap *bitmap = _segMan->lookupBitmap(_bitmapId);
 		bitmap->setPalette(palette);
-		// NOTE: SSCI calls updateScreenItem and frameOut here, but this should
-		// not be necessary in ScummVM since the new palette gets submitted
-		// before the next frame is rendered, and the frame rendering call will
-		// perform the same operations.
+		// SSCI calls updateScreenItem and frameOut here, but this is not
+		// necessary in ScummVM since the new palette gets submitted before the
+		// next frame is rendered, and the frame rendering call will perform the
+		// same operations.
 	} else {
 		g_sci->_gfxPalette32->submit(palette);
 		g_sci->_gfxPalette32->updateForFrame();
@@ -931,7 +931,7 @@ void VMDPlayer::initComposited() {
 		_screenItem->_drawBlackLines = true;
 	}
 
-	// NOTE: There was code for positioning the screen item using insetRect
+	// In SSCI, there was code for positioning the screen item using insetRect
 	// here, but none of the game scripts seem to use this functionality.
 
 	g_sci->_gfxFrameout->addScreenItem(*_screenItem);
@@ -1016,9 +1016,8 @@ void VMDPlayer::setPlane(const int16 priority, const reg_t planeId) {
 
 void VMDPlayer::restrictPalette(const uint8 startColor, const int16 endColor) {
 	_startColor = startColor;
-	// At least GK2 sends 256 as the end color, which is wrong,
-	// but works in the original engine as the storage size is 4 bytes
-	// and used values are clamped to 0-255
+	// At least GK2 sends 256 as the end color, which is wrong, but works in
+	// SSCI as the storage size is 4 bytes and used values are clamped to 0-255
 	_endColor = MIN<int16>(255, endColor);
 }
 
diff --git a/engines/sci/graphics/video32.h b/engines/sci/graphics/video32.h
index 7b2cffa..ce5e4ba 100644
--- a/engines/sci/graphics/video32.h
+++ b/engines/sci/graphics/video32.h
@@ -331,7 +331,7 @@ public:
 	 */
 	VMDStatus getStatus() const;
 
-	// NOTE: Was WaitForEvent in SSCI
+	// Was WaitForEvent in SSCI
 	EventFlags kernelPlayUntilEvent(const EventFlags flags, const int16 lastFrameNo, const int16 yieldInterval);
 
 private:
@@ -347,7 +347,8 @@ private:
 
 	/**
 	 * The Resource object for VMDs that are read out of a resource bundle
-	 * instead of being streamed from the filesystem.
+	 * instead of being streamed from the filesystem. The resource is owned by
+	 * ResourceManager.
 	 */
 	Resource *_bundledVmd;
 
@@ -399,12 +400,13 @@ protected:
 
 private:
 	/**
-	 * The plane where the VMD will be drawn.
+	 * The plane where the VMD will be drawn. The plane is owned by GfxFrameout.
 	 */
 	Plane *_plane;
 
 	/**
-	 * The screen item representing the VMD surface.
+	 * The screen item representing the VMD surface. The screen item is owned by
+	 * GfxFrameout.
 	 */
 	ScreenItem *_screenItem;
 
@@ -538,7 +540,7 @@ private:
 
 	/**
 	 * An optional plane that will be used to black out areas of the screen
-	 * outside of the VMD surface.
+	 * outside of the VMD surface. The plane is owned by GfxFrameout.
 	 */
 	Plane *_blackoutPlane;
 
@@ -675,6 +677,7 @@ protected:
 private:
 	/**
 	 * An empty plane drawn behind the video when the doFrameOut flag is true.
+	 * The plane is owned by GfxFrameout.
 	 */
 	Plane *_plane;
 


Commit: f51b158f8cc7cb40eb56904e475aae89ac5e55a4
    https://github.com/scummvm/scummvm/commit/f51b158f8cc7cb40eb56904e475aae89ac5e55a4
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:10:51-05:00

Commit Message:
SCI32: Clean up GfxFrameout

* Rewrap doxygen comments to 80 columns
* Swap public/private sections so public APIs come first
* Clarify comments where easily possible

Changed paths:
    engines/sci/engine/kgraphics32.cpp
    engines/sci/graphics/frameout.cpp
    engines/sci/graphics/frameout.h


diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp
index d093c55..1734221 100644
--- a/engines/sci/engine/kgraphics32.cpp
+++ b/engines/sci/engine/kgraphics32.cpp
@@ -102,9 +102,9 @@ reg_t kBaseSetter32(EngineState *s, int argc, reg_t *argv) {
 reg_t kSetNowSeen32(EngineState *s, int argc, reg_t *argv) {
 	const bool found = g_sci->_gfxFrameout->kernelSetNowSeen(argv[0]);
 
-	// NOTE: MGDX is assumed to use the older kSetNowSeen since it was
-	// released before SQ6, but this has not been verified since it cannot be
-	// disassembled at the moment (Phar Lap Windows-only release)
+	// MGDX is assumed to use the older kSetNowSeen since it was released before
+	// SQ6, but this has not been verified since it cannot be disassembled at
+	// the moment (Phar Lap Windows-only release)
 	// (See also getNowSeenRect)
 	if (getSciVersion() <= SCI_VERSION_2_1_EARLY ||
 		g_sci->getGameId() == GID_SQ6 ||
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp
index f2ae0df..a8746ee 100644
--- a/engines/sci/graphics/frameout.cpp
+++ b/engines/sci/graphics/frameout.cpp
@@ -119,9 +119,9 @@ void GfxFrameout::run() {
 	ScreenItem::init();
 	GfxText32::init();
 
-	// NOTE: This happens in SCI::InitPlane in the actual engine,
-	// and is a background fill plane to ensure hidden planes
-	// (planes with a priority of -1) are never drawn
+	// This plane is created in SCI::InitPlane in SSCI, and is a background fill
+	// plane to ensure "hidden" planes (planes with negative priority) are never
+	// drawn
 	Plane *initPlane = new Plane(Common::Rect(_currentBuffer.scriptWidth, _currentBuffer.scriptHeight));
 	initPlane->_priority = 0;
 	_planes.add(initPlane);
@@ -296,8 +296,8 @@ void GfxFrameout::kernelDeletePlane(const reg_t object) {
 	}
 
 	if (plane->_created) {
-		// NOTE: The original engine calls some `AbortPlane` function that
-		// just ends up doing this anyway so we skip the extra indirection
+		// SSCI calls some `AbortPlane` function that just ends up doing this
+		// anyway, so we skip the extra indirection
 		_planes.erase(plane);
 	} else {
 		plane->_created = 0;
@@ -331,8 +331,8 @@ void GfxFrameout::kernelMovePlaneItems(const reg_t object, const int16 deltaX, c
 	for (ScreenItemList::iterator it = plane->_screenItemList.begin(); it != plane->_screenItemList.end(); ++it) {
 		ScreenItem &screenItem = **it;
 
-		// If object is a number, the screen item from the
-		// engine, not a script, and should be ignored
+		// If object is a number, the screen item from the engine, not a script,
+		// and should be ignored
 		if (screenItem._object.isNumber()) {
 			continue;
 		}
@@ -365,14 +365,14 @@ void GfxFrameout::addPlane(Plane *plane) {
 }
 
 void GfxFrameout::updatePlane(Plane &plane) {
-	// NOTE: This assertion comes from SCI engine code.
+	// This assertion comes from SSCI
 	assert(_planes.findByObject(plane._object) == &plane);
 
 	Plane *visiblePlane = _visiblePlanes.findByObject(plane._object);
 	plane.sync(visiblePlane, _screenRect);
-	// NOTE: updateScreenRect was originally called a second time here,
-	// but it is already called at the end of the Plane::Update call
-	// in the original engine anyway.
+	// updateScreenRect was called a second time here in SSCI, but it is already
+	// called at the end of the sync call (also in SSCI) so there is no reason
+	// to do it again
 
 	_planes.sort();
 }
@@ -401,8 +401,8 @@ void GfxFrameout::frameOut(const bool shouldShowBits, const Common::Rect &eraseR
 		robotPlayer.doRobot();
 	}
 
-	// NOTE: The original engine allocated these as static arrays of 100
-	// pointers to ScreenItemList / RectList
+	// SSCI allocated these as static arrays of 100 pointers to
+	// ScreenItemList / RectList
 	ScreenItemListList screenItemLists;
 	EraseListList eraseLists;
 
@@ -459,8 +459,8 @@ void GfxFrameout::palMorphFrameOut(const int8 *styleRanges, PlaneShowStyle *show
 	_showList.add(rect);
 	showBits();
 
-	// NOTE: The original engine allocated these as static arrays of 100
-	// pointers to ScreenItemList / RectList
+	// SSCI allocated these as static arrays of 100 pointers to
+	// ScreenItemList / RectList
 	ScreenItemListList screenItemLists;
 	EraseListList eraseLists;
 
@@ -651,8 +651,7 @@ int splitRectsForRender(Common::Rect &middleRect, const Common::Rect &showRect,
 	return splitCount;
 }
 
-// NOTE: The third rectangle parameter is only ever given a non-empty rect
-// by VMD code, via `frameOut`
+// The third rectangle parameter is only ever passed by VMD code
 void GfxFrameout::calcLists(ScreenItemListList &drawLists, EraseListList &eraseLists, const Common::Rect &eraseRect) {
 	RectList eraseList;
 	Common::Rect outRects[4];
@@ -670,8 +669,8 @@ void GfxFrameout::calcLists(ScreenItemListList &drawLists, EraseListList &eraseL
 		const Plane *outerPlane = _planes[outerPlaneIndex];
 		const Plane *visiblePlane = _visiblePlanes.findByObject(outerPlane->_object);
 
-		// NOTE: SSCI only ever checks for kPlaneTypeTransparent here, even
-		// though kPlaneTypeTransparentPicture is also a transparent plane
+		// SSCI only ever checks for kPlaneTypeTransparent here, even though
+		// kPlaneTypeTransparentPicture is also a transparent plane
 		if (outerPlane->_type == kPlaneTypeTransparent) {
 			foundTransparentPlane = true;
 		}
@@ -741,7 +740,6 @@ void GfxFrameout::calcLists(ScreenItemListList &drawLists, EraseListList &eraseL
 		}
 	}
 
-	// clean up deleted planes
 	if (deletedPlaneCount) {
 		for (int planeIndex = planeCount - 1; planeIndex >= 0; --planeIndex) {
 			Plane *plane = _planes[planeIndex];
@@ -866,7 +864,7 @@ void GfxFrameout::calcLists(ScreenItemListList &drawLists, EraseListList &eraseL
 		}
 	}
 
-	// NOTE: SSCI only looks for kPlaneTypeTransparent, not
+	// SSCI really only looks for kPlaneTypeTransparent, not
 	// kPlaneTypeTransparentPicture
 	if (foundTransparentPlane) {
 		for (PlaneList::size_type planeIndex = 0; planeIndex < planeCount; ++planeIndex) {
@@ -913,8 +911,6 @@ void GfxFrameout::drawScreenItemList(const DrawList &screenItemList) {
 		const DrawItem &drawItem = *screenItemList[i];
 		mergeToShowList(drawItem.rect, _showList, _overdrawThreshold);
 		const ScreenItem &screenItem = *drawItem.screenItem;
-		// TODO: Remove
-//		debug("Drawing item %04x:%04x to %d %d %d %d", PRINT_REG(screenItem._object), PRINT_RECT(drawItem.rect));
 		CelObj &celObj = *screenItem._celObj;
 		celObj.draw(_currentBuffer, screenItem, drawItem.rect, screenItem._mirrorX ^ celObj._mirrorX);
 	}
@@ -986,9 +982,8 @@ void GfxFrameout::showBits() {
 
 	for (RectList::const_iterator rect = _showList.begin(); rect != _showList.end(); ++rect) {
 		Common::Rect rounded(**rect);
-		// NOTE: SCI engine used BR-inclusive rects so used slightly
-		// different masking here to ensure that the width of rects
-		// was always even.
+		// SSCI uses BR-inclusive rects so has slightly different masking here
+		// to ensure that the width of rects is always even
 		rounded.left &= ~1;
 		rounded.right = (rounded.right + 1) & ~1;
 		_cursor->gonnaPaint(rounded);
@@ -998,9 +993,8 @@ void GfxFrameout::showBits() {
 
 	for (RectList::const_iterator rect = _showList.begin(); rect != _showList.end(); ++rect) {
 		Common::Rect rounded(**rect);
-		// NOTE: SCI engine used BR-inclusive rects so used slightly
-		// different masking here to ensure that the width of rects
-		// was always even.
+		// SSCI uses BR-inclusive rects so has slightly different masking here
+		// to ensure that the width of rects is always even
 		rounded.left &= ~1;
 		rounded.right = (rounded.right + 1) & ~1;
 
@@ -1094,9 +1088,9 @@ void GfxFrameout::alterVmap(const Palette &palette1, const Palette &palette2, co
 		int8 styleRangeValue = styleRanges[currentValue];
 		if (styleRangeValue == -1 && styleRangeValue == style) {
 			currentValue = pixels[pixelIndex] = clut[currentValue];
-			// NOTE: In original engine this assignment happens outside of the
-			// condition, but if the branch is not followed the value is just
-			// going to be the same as it was before
+			// In SSCI this assignment happens outside of the condition, but if
+			// the branch is not followed the value is just going to be the same
+			// as it was before, so we do it here instead
 			styleRangeValue = styleRanges[currentValue];
 		}
 
@@ -1110,7 +1104,7 @@ void GfxFrameout::alterVmap(const Palette &palette1, const Palette &palette2, co
 }
 
 void GfxFrameout::updateScreen(const int delta) {
-	// using OSystem::getMillis instead of Sci::getTickCount because these
+	// Using OSystem::getMillis instead of Sci::getTickCount here because these
 	// values need to be monotonically increasing for the duration of the
 	// GfxFrameout object or else the screen will stop updating
 	const uint32 now = g_system->getMillis() * 60 / 1000;
@@ -1199,13 +1193,12 @@ reg_t GfxFrameout::kernelIsOnMe(const reg_t object, const Common::Point &positio
 		return make_reg(0, 0);
 	}
 
-	// NOTE: The original engine passed a copy of the ScreenItem into isOnMe
-	// as a hack around the fact that the screen items in `_visiblePlanes`
-	// did not have their `_celObj` pointers cleared when their CelInfo was
-	// updated by `Plane::decrementScreenItemArrayCounts`. We handle this
-	// this more intelligently by clearing `_celObj` in the copy assignment
-	// operator, which is only ever called by `decrementScreenItemArrayCounts`
-	// anyway.
+	// SSCI passed a copy of the ScreenItem into isOnMe as a hack around the
+	// fact that the screen items in `_visiblePlanes` did not have their
+	// `_celObj` pointers cleared when their CelInfo was updated by
+	// `Plane::decrementScreenItemArrayCounts`. We handle this this more
+	// intelligently by clearing `_celObj` in the copy assignment operator,
+	// which is only ever called by `decrementScreenItemArrayCounts` anyway.
 	return make_reg(0, isOnMe(*screenItem, *plane, position, checkPixel));
 }
 
@@ -1271,9 +1264,9 @@ bool GfxFrameout::getNowSeenRect(const reg_t screenItemObject, Common::Rect &res
 
 	const ScreenItem *screenItem = plane->_screenItemList.findByObject(screenItemObject);
 	if (screenItem == nullptr) {
-		// NOTE: MGDX is assumed to use the older getNowSeenRect since it was
-		// released before SQ6, but this has not been verified since it cannot
-		// be disassembled at the moment (Phar Lap Windows-only release)
+		// MGDX is assumed to use the older getNowSeenRect since it was released
+		// before SQ6, but this has not been verified since it cannot be
+		// disassembled at the moment (Phar Lap Windows-only release)
 		// (See also kSetNowSeen32)
 		if (getSciVersion() <= SCI_VERSION_2_1_EARLY ||
 			g_sci->getGameId() == GID_SQ6 ||
diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h
index a7b529f..78bf2e0 100644
--- a/engines/sci/graphics/frameout.h
+++ b/engines/sci/graphics/frameout.h
@@ -37,21 +37,11 @@ class GfxTransitions32;
 struct PlaneShowStyle;
 
 /**
- * Frameout class, kFrameout and relevant functions for SCI32 games.
- * Roughly equivalent to GraphicsMgr in the actual SCI engine.
+ * Frameout class, kFrameOut and relevant functions for SCI32 games.
+ * Roughly equivalent to GraphicsMgr in SSCI.
  */
 class GfxFrameout {
 	friend class GfxTransitions32;
-private:
-	GfxCursor32 *_cursor;
-	GfxPalette32 *_palette;
-	SegManager *_segMan;
-
-	/**
-	 * Determines whether the current game should be rendered in
-	 * high resolution.
-	 */
-	bool gameIsHiRes() const;
 
 public:
 	GfxFrameout(SegManager *segMan, GfxPalette32 *palette, GfxTransitions32 *transitions, GfxCursor32 *cursor);
@@ -62,12 +52,20 @@ public:
 	void clear();
 	void run();
 
-#pragma mark -
-#pragma mark Screen items
 private:
-	void remapMarkRedraw();
-	bool getNowSeenRect(const reg_t screenItemObject, Common::Rect &result) const;
+	GfxCursor32 *_cursor;
+	GfxPalette32 *_palette;
+	GfxTransitions32 *_transitions;
+	SegManager *_segMan;
+
+	/**
+	 * Determines whether the current game should be rendered in high
+	 * resolution.
+	 */
+	bool gameIsHiRes() const;
 
+#pragma mark -
+#pragma mark Screen items
 public:
 	/**
 	 * Adds a screen item.
@@ -100,39 +98,27 @@ public:
 	bool kernelSetNowSeen(const reg_t screenItemObject) const;
 	int16 kernelObjectIntersect(const reg_t object1, const reg_t object2) const;
 
-#pragma mark -
-#pragma mark Planes
 private:
-	/**
-	 * The list of planes (i.e. layers) that have been added
-	 * to the screen.
-	 *
-	 * @note This field is on `GraphicsMgr.screen` in SCI
-	 * engine.
-	 */
-	PlaneList _planes;
-
-	/**
-	 * Updates an existing plane with properties from the
-	 * given VM object.
-	 */
-	void updatePlane(Plane &plane);
+	void remapMarkRedraw();
+	bool getNowSeenRect(const reg_t screenItemObject, Common::Rect &result) const;
 
+#pragma mark -
+#pragma mark Planes
 public:
 	/**
 	 * Creates and adds a new plane to the plane list. Ownership of the passed
 	 * object is transferred to GfxFrameout.
 	 *
-	 * @note This method is on Screen in SCI engine, but it
-	 * is only ever called on `GraphicsMgr.screen`.
+	 * @note This method is on Screen in SSCI, but it is only ever called on
+	 * `GraphicsMgr.screen`.
 	 */
 	void addPlane(Plane *plane);
 
 	/**
 	 * Deletes a plane within the current plane list.
 	 *
-	 * @note This method is on Screen in SCI engine, but it
-	 * is only ever called on `GraphicsMgr.screen`.
+	 * @note This method is on Screen in SSCI, but it is only ever called on
+	 * `GraphicsMgr.screen`.
 	 */
 	void deletePlane(Plane &plane);
 
@@ -148,6 +134,20 @@ public:
 	void kernelMovePlaneItems(const reg_t object, const int16 deltaX, const int16 deltaY, const bool scrollPics);
 	int16 kernelGetHighPlanePri();
 
+private:
+	/**
+	 * The list of planes (i.e. layers) that will be rendered to the screen on
+	 * the next call to `frameOut`.
+	 *
+	 * @note This field is on `GraphicsMgr.screen` in SSCI.
+	 */
+	PlaneList _planes;
+
+	/**
+	 * Updates an existing plane with properties from the given VM object.
+	 */
+	void updatePlane(Plane &plane);
+
 #pragma mark -
 #pragma mark Pics
 public:
@@ -155,121 +155,193 @@ public:
 
 #pragma mark -
 #pragma mark Rendering
+public:
+	/**
+	 * Updates the hardware screen, no more than once per tick.
+	 *
+	 * @param delta An additional number of ticks that should elapse
+	 * since the last time the screen was updated before it gets updated now.
+	 * This is used for updating the screen within run_vm, where we normally
+	 * expect that a call to kFrameOut will occur later during the current
+	 * frame, but if it does not, then update the screen on the second frame
+	 * anyway since the game is doing something bad.
+	 */
+	void updateScreen(const int delta = 0);
+
+	/**
+	 * Resets the pixel format of the hardware surface to the given format.
+	 */
+	void setPixelFormat(const Graphics::PixelFormat &format) const {
+		initGraphics(_currentBuffer.screenWidth, _currentBuffer.screenHeight, _isHiRes, &format);
+	}
+
+	/**
+	 * Whether or not to throttle kFrameOut calls.
+	 */
+	bool _throttleKernelFrameOut;
+
+	/**
+	 * Whether `palMorphFrameOut` should be used instead of `frameOut` for
+	 * rendering. Used by `kMorphOn` to explicitly enable `palMorphFrameOut` for
+	 * one frame.
+	 */
+	bool _palMorphIsOn;
+
+	inline const Buffer &getCurrentBuffer() const {
+		return _currentBuffer;
+	}
+
+	void kernelFrameOut(const bool showBits);
+
+	/**
+	 * Throttles the engine as necessary to maintain 60fps output.
+	 */
+	void throttle();
+
+	/**
+	 * Updates the internal screen buffer for the next frame. If
+	 * `shouldShowBits` is true, also sends the buffer to hardware. If
+	 * `eraseRect` is non-empty, it is added to the erase list for this frame.
+	 */
+	void frameOut(const bool shouldShowBits, const Common::Rect &eraseRect = Common::Rect());
+
+	/**
+	 * TODO: Documentation
+	 */
+	void palMorphFrameOut(const int8 *styleRanges, PlaneShowStyle *showStyle);
+
+	/**
+	 * Draws the given rect from the internal screen buffer to hardware without
+	 * processing any other graphics updates except for cursor changes.
+	 */
+	void directFrameOut(const Common::Rect &showRect);
+
+#ifdef USE_RGB_COLOR
+	/**
+	 * Sends the entire internal screen buffer and palette to hardware.
+	 */
+	void resetHardware();
+#endif
+
+	/**
+	 * Modifies the raw pixel data for the next frame with new palette indexes
+	 * based on matched style ranges.
+	 */
+	void alterVmap(const Palette &palette1, const Palette &palette2, const int8 style, const int8 *const styleRanges);
+
+	// This function is used within ScreenItem subsystem and assigned to various
+	// booleanish fields that seem to represent the state of the screen item
+	// (created, updated, deleted). In GK1/DOS, Phant1/m68k, SQ6/DOS, SQ6/Win,
+	// and Phant2/Win, this function simply returns 1. If you know of any
+	// game/environment where this function returns some value other than 1, or
+	// if you used to work at Sierra and can explain why this is a thing (and if
+	// anyone needs to care about it), please open a ticket!!
+	inline int getScreenCount() const {
+		return 1;
+	};
+
+	/**
+	 * Shakes the screen.
+	 */
+	void shakeScreen(const int16 numShakes, const ShakeDirection direction);
+
 private:
 	/**
 	 * The last time the hardware screen was updated.
 	 */
 	uint32 _lastScreenUpdateTick;
 
-	GfxTransitions32 *_transitions;
-
 	/**
-	 * State tracker to provide more accurate 60fps
-	 * video throttling.
+	 * State tracker to provide more accurate 60fps video throttling.
 	 */
 	uint8 _throttleState;
 
 	/**
-	 * The internal display pixel buffer. During frameOut,
-	 * this buffer is drawn into according to the draw and
-	 * erase rects calculated by `calcLists`, then drawn out
-	 * to the hardware surface according to the `_showList`
-	 * rects (which are also calculated by `calcLists`).
+	 * The internal display pixel buffer. During `frameOut`, this buffer is
+	 * drawn into according to the draw and erase rects calculated by
+	 * `calcLists`, then drawn out to the hardware surface according to the
+	 * `_showList` rects (which are also calculated by `calcLists`).
 	 */
 	Buffer _currentBuffer;
 
 	/**
-	 * When true, a change to the remap zone in the palette
-	 * has occurred and screen items with remap data need to
-	 * be redrawn.
+	 * When true, a change to the remap zone in the palette has occurred and
+	 * screen items with remap data need to be redrawn.
 	 */
 	bool _remapOccurred;
 
 	/**
-	 * TODO: Document
-	 * TODO: Depending upon if the engine ever modifies this
-	 * rect, it may be stupid to store it separately instead
-	 * of just getting width/height from GfxScreen.
+	 * The dimensions of the output buffer, in display coordinates.
 	 *
-	 * @note This field is on `GraphicsMgr.screen` in SCI
-	 * engine.
+	 * @note This field is on `GraphicsMgr.screen` in SSCI.
 	 */
 	Common::Rect _screenRect;
 
 	/**
-	 * A list of rectangles, in display coordinates, that
-	 * represent portions of the internal screen buffer that
-	 * should be drawn to the hardware display surface.
+	 * A list of rectangles, in screen coordinates, that represent portions of
+	 * the internal screen buffer that are dirty and should be drawn to the
+	 * hardware display surface.
 	 *
-	 * @note This field is on `GraphicsMgr.screen` in SCI
-	 * engine.
+	 * @note This field is on `GraphicsMgr.screen` in SSCI.
 	 */
 	RectList _showList;
 
 	/**
-	 * The amount of extra overdraw that is acceptable when
-	 * merging two show list rectangles together into a
-	 * single larger rectangle.
+	 * The amount of extra overdraw that is acceptable when merging two show
+	 * list rectangles together into a single larger rectangle.
 	 *
-	 * @note This field is on `GraphicsMgr.screen` in SCI
-	 * engine.
+	 * @note This field is on `GraphicsMgr.screen` in SSCI.
 	 */
 	int _overdrawThreshold;
 
 	/**
-	 * A list of planes that are currently drawn to the
-	 * hardware display surface. Used to calculate
-	 * differences in plane properties between the last
-	 * frame and current frame.
+	 * The list of planes that are currently drawn to the hardware display
+	 * surface. Used to calculate differences in plane properties between the
+	 * last frame and current frame.
 	 *
-	 * @note This field is on `GraphicsMgr.visibleScreen` in
-	 * SCI engine.
+	 * @note This field is on `GraphicsMgr.visibleScreen` in SSCI.
 	 */
 	PlaneList _visiblePlanes;
 
 	/**
-	 * Calculates the location and dimensions of dirty rects
-	 * over the entire screen for rendering the next frame.
-	 * The draw and erase lists in `drawLists` and
-	 * `eraseLists` each represent one plane on the screen.
-	 * The optional `eraseRect` argument allows a specific
-	 * area of the screen to be erased.
+	 * Calculates the location and dimensions of dirty rects over the entire
+	 * screen for rendering the next frame. The draw and erase lists in
+	 * `drawLists` and `eraseLists` each represent one plane on the screen.
+	 * The optional `eraseRect` argument allows a specific area of the screen to
+	 * be explicitly erased.
 	 */
 	void calcLists(ScreenItemListList &drawLists, EraseListList &eraseLists, const Common::Rect &eraseRect = Common::Rect());
 
 	/**
-	 * Erases the areas in the given erase list from the
-	 * visible screen buffer by filling them with the color
-	 * from the corresponding plane. This is an optimisation
-	 * for colored-type planes only; other plane types have
-	 * to be redrawn from pixel data.
+	 * Erases the areas in the given erase list from the visible screen buffer
+	 * by filling them with the color from the corresponding plane. This is an
+	 * optimisation for colored-type planes only; other plane types have to be
+	 * redrawn from pixel data.
 	 */
 	void drawEraseList(const RectList &eraseList, const Plane &plane);
 
 	/**
-	 * Draws all screen items from the given draw list to
-	 * the visible screen buffer.
+	 * Draws all screen items from the given draw list to the visible screen
+	 * buffer.
 	 */
 	void drawScreenItemList(const DrawList &screenItemList);
 
 	/**
-	 * Adds a new rectangle to the list of regions to write
-	 * out to the hardware. The provided rect may be merged
-	 * into an existing rectangle to reduce the number of
-	 * blit operations.
+	 * Adds a new rectangle to the list of regions to write out to the hardware.
+	 * The provided rect may be merged into an existing rectangle to reduce the
+	 * number of blit operations.
 	 */
 	void mergeToShowList(const Common::Rect &drawRect, RectList &showList, const int overdrawThreshold);
 
 	/**
-	 * Sends all dirty rects from the internal frame buffer to the backend,
-	 * then updates the hardware screen.
+	 * Sends all dirty rects from the internal frame buffer to the backend, then
+	 * updates the hardware screen.
 	 */
 	void showBits();
 
 	/**
-	 * Validates whether the given palette index in the
-	 * style range should copy a color from the next
-	 * palette to the source palette during a palette
+	 * Validates whether the given palette index in the style range should copy
+	 * a color from the next palette to the source palette during a palette
 	 * morph operation.
 	 */
 	inline bool validZeroStyle(const uint8 style, const int i) const {
@@ -290,101 +362,11 @@ private:
 		}
 	}
 
-public:
-	/**
-	 * Updates the hardware screen, no more than once per tick.
-	 *
-	 * @param delta An additional number of ticks that should elapse
-	 * since the last time the screen was updated before it gets updated now.
-	 * This is used for updating the screen within run_vm, where we normally
-	 * expect that a call to kFrameOut will occur later during the current
-	 * frame, but if it does not, then update the screen on the second frame
-	 * anyway since the game is doing something bad.
-	 */
-	void updateScreen(const int delta = 0);
-
-	/**
-	 * Resets the pixel format of the hardware surface to the given format.
-	 */
-	void setPixelFormat(const Graphics::PixelFormat &format) const {
-		initGraphics(_currentBuffer.screenWidth, _currentBuffer.screenHeight, _isHiRes, &format);
-	}
-
-	/**
-	 * Whether or not to throttle kFrameOut calls.
-	 */
-	bool _throttleKernelFrameOut;
-
-	/**
-	 * Whether palMorphFrameOut should be used instead of
-	 * frameOut for rendering. Used by kMorphOn to
-	 * explicitly enable palMorphFrameOut for one frame.
-	 */
-	bool _palMorphIsOn;
-
-	inline const Buffer &getCurrentBuffer() const {
-		return _currentBuffer;
-	}
-
-	void kernelFrameOut(const bool showBits);
-
-	/**
-	 * Throttles the engine as necessary to maintain
-	 * 60fps output.
-	 */
-	void throttle();
-
-	/**
-	 * Updates the internal screen buffer for the next
-	 * frame. If `shouldShowBits` is true, also sends the
-	 * buffer to hardware. If `eraseRect` is non-empty,
-	 * it is added to the erase list for this frame.
-	 */
-	void frameOut(const bool shouldShowBits, const Common::Rect &eraseRect = Common::Rect());
-
-	/**
-	 * TODO: Documentation
-	 */
-	void palMorphFrameOut(const int8 *styleRanges, PlaneShowStyle *showStyle);
-
-	/**
-	 * Draws the given rect from the internal screen buffer to hardware without
-	 * processing any other graphics updates except for cursor changes.
-	 */
-	void directFrameOut(const Common::Rect &showRect);
-
-#ifdef USE_RGB_COLOR
-	/**
-	 * Sends the entire internal screen buffer and palette to hardware.
-	 */
-	void resetHardware();
-#endif
-
-	/**
-	 * Modifies the raw pixel data for the next frame with
-	 * new palette indexes based on matched style ranges.
-	 */
-	void alterVmap(const Palette &palette1, const Palette &palette2, const int8 style, const int8 *const styleRanges);
-
-	// NOTE: This function is used within ScreenItem subsystem and assigned
-	// to various booleanish fields that seem to represent the state of the
-	// screen item (created, updated, deleted). In GK1/DOS, Phant1/m68k,
-	// SQ6/DOS, SQ6/Win, and Phant2/Win, this function simply returns 1. If
-	// you know of any game/environment where this function returns some
-	// value other than 1, or if you used to work at Sierra and can explain
-	// why this is a thing (and if anyone needs to care about it), please
-	// open a ticket!!
-	inline int getScreenCount() const {
-		return 1;
-	};
-
-	/**
-	 * Shakes the screen.
-	 */
-	void shakeScreen(const int16 numShakes, const ShakeDirection direction);
-
 #pragma mark -
 #pragma mark Mouse cursor
+public:
+	reg_t kernelIsOnMe(const reg_t object, const Common::Point &position, const bool checkPixel) const;
+
 private:
 	void updateMousePositionForRendering() const {
 		// In SSCI, mouse events were received via hardware interrupt, so the
@@ -398,14 +380,11 @@ private:
 	}
 
 	/**
-	 * Determines whether or not the point given by
-	 * `position` is inside of the given screen item.
+	 * Determines whether or not the point given by `position` is inside of the
+	 * given screen item.
 	 */
 	bool isOnMe(const ScreenItem &screenItem, const Plane &plane, const Common::Point &position, const bool checkPixel) const;
 
-public:
-	reg_t kernelIsOnMe(const reg_t object, const Common::Point &position, const bool checkPixel) const;
-
 #pragma mark -
 #pragma mark Debugging
 public:


Commit: 93c8044f690306e23b5b3eb621207fbf57682c40
    https://github.com/scummvm/scummvm/commit/93c8044f690306e23b5b3eb621207fbf57682c40
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:10:52-05:00

Commit Message:
SCI32: Clean up Audio32

* Rewrap comments to 80 columns
* Remove resolved TODOs
* Use containers and smart pointers where appropriate

Changed paths:
    engines/sci/engine/ksound.cpp
    engines/sci/sound/audio32.cpp
    engines/sci/sound/audio32.h
    engines/sci/sound/soundcmd.cpp


diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp
index bbfadf1..4d171bd 100644
--- a/engines/sci/engine/ksound.cpp
+++ b/engines/sci/engine/ksound.cpp
@@ -384,10 +384,6 @@ reg_t kDoAudioPosition(EngineState *s, int argc, reg_t *argv) {
 }
 
 reg_t kDoAudioRate(EngineState *s, int argc, reg_t *argv) {
-	// NOTE: In the original engine this would set the hardware
-	// DSP sampling rate; ScummVM mixer does not need this, so
-	// we only store the value to satisfy engine compatibility.
-
 	if (argc > 0) {
 		const uint16 sampleRate = argv[0].toUint16();
 		if (sampleRate != 0) {
@@ -407,10 +403,6 @@ reg_t kDoAudioGetCapability(EngineState *s, int argc, reg_t *argv) {
 }
 
 reg_t kDoAudioBitDepth(EngineState *s, int argc, reg_t *argv) {
-	// NOTE: In the original engine this would set the hardware
-	// DSP bit depth; ScummVM mixer does not need this, so
-	// we only store the value to satisfy engine compatibility.
-
 	if (argc > 0) {
 		const uint16 bitDepth = argv[0].toUint16();
 		if (bitDepth != 0) {
@@ -426,10 +418,6 @@ reg_t kDoAudioMixing(EngineState *s, int argc, reg_t *argv) {
 }
 
 reg_t kDoAudioChannels(EngineState *s, int argc, reg_t *argv) {
-	// NOTE: In the original engine this would set the hardware
-	// DSP stereo output; ScummVM mixer does not need this, so
-	// we only store the value to satisfy engine compatibility.
-
 	if (argc > 0) {
 		const int16 numChannels = argv[0].toSint16();
 		if (numChannels != 0) {
@@ -441,11 +429,6 @@ reg_t kDoAudioChannels(EngineState *s, int argc, reg_t *argv) {
 }
 
 reg_t kDoAudioPreload(EngineState *s, int argc, reg_t *argv) {
-	// NOTE: In the original engine this would cause audio
-	// data for new channels to be preloaded to memory when
-	// the channel was initialized; we do not need this, so
-	// we only store the value to satisfy engine compatibility.
-
 	if (argc > 0) {
 		g_sci->_audio32->setPreload(argv[0].toUint16());
 	}
@@ -477,11 +460,8 @@ reg_t kDoAudioPanOff(EngineState *s, int argc, reg_t *argv) {
 }
 
 reg_t kSetLanguage(EngineState *s, int argc, reg_t *argv) {
-	// This is used by script 90 of MUMG Deluxe from the main menu to toggle
-	// the audio language between English and Spanish.
-	// Basically, it instructs the interpreter to switch the audio resources
-	// (resource.aud and associated map files) and load them from the "Spanish"
-	// subdirectory instead.
+	// Used by script 90 of MUMG Deluxe from the main menu to toggle between
+	// English and Spanish.
 	const Common::String audioDirectory = s->_segMan->getString(argv[0]);
 	g_sci->getResMan()->changeAudioDirectory(audioDirectory);
 	return s->r_acc;
diff --git a/engines/sci/sound/audio32.cpp b/engines/sci/sound/audio32.cpp
index 59ebc86..f9a0140 100644
--- a/engines/sci/sound/audio32.cpp
+++ b/engines/sci/sound/audio32.cpp
@@ -153,6 +153,7 @@ Audio32::Audio32(ResourceManager *resMan) :
 	_handle(),
 	_mutex(),
 
+	_channels(getSciVersion() < SCI_VERSION_2_1_EARLY ? 10 : getSciVersion() < SCI_VERSION_3 ? 5 : 8),
 	_numActiveChannels(0),
 	_inAudioThread(false),
 
@@ -170,22 +171,10 @@ Audio32::Audio32(ResourceManager *resMan) :
 	_startedAtTick(0),
 
 	_attenuatedMixing(true),
+	_useModifiedAttenuation(g_sci->_features->usesModifiedAudioAttenuation()),
 
 	_monitoredChannelIndex(-1),
-	_monitoredBuffer(nullptr),
-	_monitoredBufferSize(0),
 	_numMonitoredSamples(0) {
-
-	if (getSciVersion() < SCI_VERSION_2_1_EARLY) {
-		_channels.resize(10);
-	} else if (getSciVersion() < SCI_VERSION_3) {
-		_channels.resize(5);
-	} else {
-		_channels.resize(8);
-	}
-
-	_useModifiedAttenuation = g_sci->_features->usesModifiedAudioAttenuation();
-
 	// In games where scripts premultiply master audio volumes into the volumes
 	// of the individual audio channels sent to the mixer, Audio32 needs to use
 	// the kPlainSoundType so that the master SFX volume is not applied twice.
@@ -202,15 +191,14 @@ Audio32::Audio32(ResourceManager *resMan) :
 Audio32::~Audio32() {
 	stop(kAllChannels);
 	_mixer->stopHandle(_handle);
-	free(_monitoredBuffer);
 }
 
 #pragma mark -
 #pragma mark AudioStream implementation
 
-int Audio32::writeAudioInternal(Audio::AudioStream *const sourceStream, Audio::RateConverter *const converter, Audio::st_sample_t *targetBuffer, const int numSamples, const Audio::st_volume_t leftVolume, const Audio::st_volume_t rightVolume) {
+int Audio32::writeAudioInternal(Audio::AudioStream &sourceStream, Audio::RateConverter &converter, Audio::st_sample_t *targetBuffer, const int numSamples, const Audio::st_volume_t leftVolume, const Audio::st_volume_t rightVolume) {
 	const int samplePairsToRead = numSamples >> 1;
-	const int samplePairsWritten = converter->flow(*sourceStream, targetBuffer, samplePairsToRead, leftVolume, rightVolume);
+	const int samplePairsWritten = converter.flow(sourceStream, targetBuffer, samplePairsToRead, leftVolume, rightVolume);
 	return samplePairsWritten << 1;
 }
 
@@ -243,34 +231,28 @@ bool Audio32::channelShouldMix(const AudioChannel &channel) const {
 	return true;
 }
 
-// In earlier versions of SCI32 engine, audio mixing is
-// split into three different functions.
+// In earlier versions of SCI32 engine, audio mixing is split into three
+// different functions.
 //
-// The first function is called from the main game thread in
-// AsyncEventCheck; later versions of SSCI also call it when
-// getting the playback position. This function is
-// responsible for cleaning up finished channels and
-// filling active channel buffers with decompressed audio
-// matching the hardware output audio format so they can
-// just be copied into the main DAC buffer directly later.
+// The first function is called from the main game thread in AsyncEventCheck;
+// later versions of SSCI also call it when getting the playback position. This
+// function is responsible for cleaning up finished channels and filling active
+// channel buffers with decompressed audio matching the hardware output audio
+// format so they can just be copied into the main DAC buffer directly later.
 //
-// The second function is called by the audio hardware when
-// the DAC buffer needs to be filled, and by `play` when
-// there is only one active sample (so it can just blow away
-// whatever was already in the DAC buffer). It merges all
-// active channels into the DAC buffer and then updates the
-// offset into the DAC buffer.
+// The second function is called by the audio hardware when the DAC buffer needs
+// to be filled, and by `play` when there is only one active sample (so it can
+// just blow away whatever was already in the DAC buffer). It merges all active
+// channels into the DAC buffer and then updates the offset into the DAC buffer.
 //
-// Finally, a third function is called by the second
-// function, and it actually puts data into the DAC buffer,
-// performing volume, distortion, and balance adjustments.
+// Finally, a third function is called by the second function, and it actually
+// puts data into the DAC buffer, performing volume, distortion, and balance
+// adjustments.
 //
-// Since we only have one callback from the audio thread,
-// and should be able to do all audio processing in
-// real time, and we have streams, and we do not need to
-// completely fill the audio buffer, the functionality of
-// all these original functions is combined here and
-// simplified.
+// Since we only have one callback from the audio thread, and should be able to
+// do all audio processing in real time, and we have streams, and we do not need
+// to completely fill the audio buffer, the functionality of all these original
+// functions is combined here and simplified.
 int Audio32::readBuffer(Audio::st_sample_t *const buffer, const int numSamples) {
 	Common::StackLock lock(_mutex);
 
@@ -278,20 +260,17 @@ int Audio32::readBuffer(Audio::st_sample_t *const buffer, const int numSamples)
 		return 0;
 	}
 
-	// ResourceManager is not thread-safe so we need to
-	// avoid calling into it from the audio thread, but at
-	// the same time we need to be able to clear out any
-	// finished channels on a regular basis
+	// ResourceManager is not thread-safe so we need to avoid calling into it
+	// from the audio thread, but at the same time we need to be able to clear
+	// out any finished channels on a regular basis
 	_inAudioThread = true;
 	freeUnusedChannels();
 
 	const bool playOnlyMonitoredChannel = getSciVersion() != SCI_VERSION_3 && _monitoredChannelIndex != -1;
 
-	// The caller of `readBuffer` is a rate converter,
-	// which reuses (without clearing) an intermediate
-	// buffer, so we need to zero the intermediate buffer
-	// to prevent mixing into audio data from the last
-	// callback.
+	// The caller of `readBuffer` is a rate converter, which reuses (without
+	// clearing) an intermediate buffer, so we need to zero the intermediate
+	// buffer to prevent mixing into audio data from the last callback.
 	memset(buffer, 0, numSamples * sizeof(Audio::st_sample_t));
 
 	// This emulates the attenuated mixing mode of SSCI engine, which reduces
@@ -340,8 +319,8 @@ int Audio32::readBuffer(Audio::st_sample_t *const buffer, const int numSamples)
 			continue;
 		}
 
-		// Channel finished fading and had the
-		// stopChannelOnFade flag set, so no longer exists
+		// Channel finished fading and had the stopChannelOnFade flag set, so no
+		// longer exists
 		if (channel.fadeStartTick && processFade(channelIndex)) {
 			--channelIndex;
 			continue;
@@ -352,10 +331,10 @@ int Audio32::readBuffer(Audio::st_sample_t *const buffer, const int numSamples)
 		if (channel.pan == -1 || !isStereo()) {
 			int volume = channel.volume;
 			if (getSciVersion() == SCI_VERSION_2) {
-				// NOTE: In SSCI, audio is decompressed into a temporary
-				// buffer, then the samples in that buffer are looped over,
-				// shifting each sample right 3, 2, or 1 bits to reduce the
-				// volume.
+				// In SSCI, audio is decompressed into a temporary buffer, then
+				// the samples in that buffer are looped over, shifting each
+				// sample right 3, 2, or 1 bits to reduce the volume within the
+				// ranges given here
 				if (volume > 0 && volume <= 42) {
 					volume = 15;
 				} else if (volume > 42 && volume <= 84) {
@@ -367,20 +346,18 @@ int Audio32::readBuffer(Audio::st_sample_t *const buffer, const int numSamples)
 				// In SCI3, granularity of the non-maximum volumes is 1/32
 				volume &= ~4;
 
-				// NOTE: In the SSCI DOS interpreter, non-maximum volumes are
-				// divided by 8 which puts them in a range of [0, 16). That
-				// reduced volume range gets passed into a volume function which
-				// expects values [0, 32). So, effectively, all non-maximum
-				// volumes are half-volume in DOS in SCI3. In Windows, volumes
-				// [120, 124) are the same as 127 due to a programming bug.
-				// We do not emulate either of these incorrect behaviors.
+				// In the SSCI DOS interpreter, non-maximum volumes are divided
+				// by 8 which puts them in a range of [0, 16). That reduced
+				// volume range gets passed into a volume function which expects
+				// values [0, 32). So, effectively, all non-maximum volumes are
+				// half-volume in DOS in SCI3 due to a programming bug. In
+				// Windows, volumes [120, 124) are the same as 127 due to
+				// another programming bug. We do not emulate either of these
+				// incorrect behaviors.
 			}
 
 			leftVolume = rightVolume = volume * Audio::Mixer::kMaxChannelVolume / kMaxVolume;
 		} else {
-			// TODO: This should match the SCI3 algorithm,
-			// which seems to halve the volume of each
-			// channel when centered; is this intended?
 			leftVolume = channel.volume * (100 - channel.pan) / 100 * Audio::Mixer::kMaxChannelVolume / kMaxVolume;
 			rightVolume = channel.volume * channel.pan / 100 * Audio::Mixer::kMaxChannelVolume / kMaxVolume;
 		}
@@ -397,19 +374,15 @@ int Audio32::readBuffer(Audio::st_sample_t *const buffer, const int numSamples)
 		}
 
 		if (channelIndex == _monitoredChannelIndex) {
-			const size_t bufferSize = numSamples * sizeof(Audio::st_sample_t);
-			if (_monitoredBufferSize < bufferSize) {
-				_monitoredBuffer = (Audio::st_sample_t *)realloc(_monitoredBuffer, bufferSize);
-				_monitoredBufferSize = bufferSize;
+			if (numSamples > (int)_monitoredBuffer.size()) {
+				_monitoredBuffer.resize(numSamples);
 			}
+			memset(_monitoredBuffer.data(), 0, _monitoredBuffer.size() * sizeof(Audio::st_sample_t));
+			_numMonitoredSamples = writeAudioInternal(*channel.stream, *channel.converter, _monitoredBuffer.data(), numSamples, leftVolume, rightVolume);
 
-			memset(_monitoredBuffer, 0, _monitoredBufferSize);
-
-			_numMonitoredSamples = writeAudioInternal(channel.stream, channel.converter, _monitoredBuffer, numSamples, leftVolume, rightVolume);
-
-			Audio::st_sample_t *sourceBuffer = _monitoredBuffer;
+			Audio::st_sample_t *sourceBuffer = _monitoredBuffer.data();
 			Audio::st_sample_t *targetBuffer = buffer;
-			const Audio::st_sample_t *const end = _monitoredBuffer + _numMonitoredSamples;
+			const Audio::st_sample_t *const end = _monitoredBuffer.data() + _numMonitoredSamples;
 			while (sourceBuffer != end) {
 				Audio::clampedAdd(*targetBuffer++, *sourceBuffer++);
 			}
@@ -428,7 +401,7 @@ int Audio32::readBuffer(Audio::st_sample_t *const buffer, const int numSamples)
 				leftVolume = rightVolume = 0;
 			}
 
-			const int channelSamplesWritten = writeAudioInternal(channel.stream, channel.converter, buffer, numSamples, leftVolume, rightVolume);
+			const int channelSamplesWritten = writeAudioInternal(*channel.stream, *channel.converter, buffer, numSamples, leftVolume, rightVolume);
 			if (channelSamplesWritten > maxSamplesWritten) {
 				maxSamplesWritten = channelSamplesWritten;
 			}
@@ -458,10 +431,9 @@ uint8 Audio32::getNumUnlockedChannels() const {
 }
 
 int16 Audio32::findChannelByArgs(int argc, const reg_t *argv, const int startIndex, const reg_t soundNode) const {
-	// NOTE: argc/argv are already reduced by one in our engine because
-	// this call is always made from a subop, so no reduction for the
-	// subop is made in this function. SSCI takes extra steps to skip
-	// the subop argument.
+	// SSCI takes extra steps to skip the subop argument here, but argc/argv are
+	// already reduced by one in our engine by the kernel since these calls are
+	// always subops so we do not need to do anything extra
 
 	argc -= startIndex;
 	if (argc <= 0) {
@@ -501,10 +473,10 @@ int16 Audio32::findChannelById(const ResourceId resourceId, const reg_t soundNod
 
 	if (resourceId.getType() == kResourceTypeAudio) {
 		for (int16 i = 0; i < _numActiveChannels; ++i) {
-			const AudioChannel channel = _channels[i];
+			const AudioChannel &candidate = _channels[i];
 			if (
-				channel.id == resourceId &&
-				(soundNode.isNull() || soundNode == channel.soundNode)
+				candidate.id == resourceId &&
+				(soundNode.isNull() || soundNode == candidate.soundNode)
 			) {
 				return i;
 			}
@@ -553,7 +525,7 @@ void Audio32::freeUnusedChannels() {
 }
 
 void Audio32::freeChannel(const int16 channelIndex) {
-	// The original engine did this:
+	// SSCI did this:
 	// 1. Unlock memory-cached resource, if one existed
 	// 2. Close patched audio file descriptor, if one existed
 	// 3. Free decompression memory buffer, if one existed
@@ -563,14 +535,13 @@ void Audio32::freeChannel(const int16 channelIndex) {
 
 	// Robots have no corresponding resource to free
 	if (channel.robot) {
-		delete channel.stream;
-		channel.stream = nullptr;
+		channel.stream.reset();
 		channel.robot = false;
 	} else {
-		// We cannot unlock resources from the audio thread
-		// because ResourceManager is not thread-safe; instead,
-		// we just record that the resource needs unlocking and
-		// unlock it whenever we are on the main thread again
+		// We cannot unlock resources from the audio thread because
+		// ResourceManager is not thread-safe; instead, we just record that the
+		// resource needs unlocking and unlock it whenever we are on the main
+		// thread again
 		if (_inAudioThread) {
 			_resourcesToUnlock.push_back(channel.resource);
 		} else {
@@ -578,12 +549,10 @@ void Audio32::freeChannel(const int16 channelIndex) {
 		}
 
 		channel.resource = nullptr;
-		delete channel.stream;
-		channel.stream = nullptr;
+		channel.stream.reset();
 	}
 
-	delete channel.converter;
-	channel.converter = nullptr;
+	channel.converter.reset();
 
 	if (_monitoredChannelIndex == channelIndex) {
 		_monitoredChannelIndex = -1;
@@ -677,13 +646,12 @@ bool Audio32::playRobotAudio(const RobotAudioStream::RobotAudioPacket &packet) {
 		channel.pausedAtTick = 0;
 		channel.soundNode = NULL_REG;
 		channel.volume = kMaxVolume;
-		// TODO: SCI3 introduces stereo audio
 		channel.pan = -1;
-		channel.converter = Audio::makeRateConverter(RobotAudioStream::kRobotSampleRate, getRate(), false);
+		channel.converter.reset(Audio::makeRateConverter(RobotAudioStream::kRobotSampleRate, getRate(), false));
 		// The RobotAudioStream buffer size is
 		// ((bytesPerSample * channels * sampleRate * 2000ms) / 1000ms) & ~3
 		// where bytesPerSample = 2, channels = 1, and sampleRate = 22050
-		channel.stream = new RobotAudioStream(88200);
+		channel.stream.reset(new RobotAudioStream(88200));
 		_robotAudioPaused = false;
 
 		if (_numActiveChannels == 1) {
@@ -691,7 +659,7 @@ bool Audio32::playRobotAudio(const RobotAudioStream::RobotAudioPacket &packet) {
 		}
 	}
 
-	return static_cast<RobotAudioStream *>(channel.stream)->addPacket(packet);
+	return static_cast<RobotAudioStream *>(channel.stream.get())->addPacket(packet);
 }
 
 bool Audio32::queryRobotAudio(RobotAudioStream::StreamState &status) const {
@@ -703,7 +671,7 @@ bool Audio32::queryRobotAudio(RobotAudioStream::StreamState &status) const {
 		return false;
 	}
 
-	status = static_cast<RobotAudioStream *>(getChannel(channelIndex).stream)->getStatus();
+	status = static_cast<RobotAudioStream *>(getChannel(channelIndex).stream.get())->getStatus();
 	return true;
 }
 
@@ -715,7 +683,7 @@ bool Audio32::finishRobotAudio() {
 		return false;
 	}
 
-	static_cast<RobotAudioStream *>(getChannel(channelIndex).stream)->finish();
+	static_cast<RobotAudioStream *>(getChannel(channelIndex).stream.get())->finish();
 	return true;
 }
 
@@ -741,7 +709,7 @@ uint16 Audio32::play(int16 channelIndex, const ResourceId resourceId, const bool
 
 	if (channelIndex != kNoExistingChannel) {
 		AudioChannel &channel = getChannel(channelIndex);
-		MutableLoopAudioStream *stream = dynamic_cast<MutableLoopAudioStream *>(channel.stream);
+		MutableLoopAudioStream *stream = dynamic_cast<MutableLoopAudioStream *>(channel.stream.get());
 		if (stream == nullptr) {
 			error("[Audio32::play]: Unable to cast stream for resource %s", resourceId.toString().c_str());
 		}
@@ -760,43 +728,42 @@ uint16 Audio32::play(int16 channelIndex, const ResourceId resourceId, const bool
 		return 0;
 	}
 
-	// NOTE: SCI engine itself normally searches in this order:
+	// SSCI normally searches in this order:
 	//
 	// For Audio36:
 	//
-	// 1. First, request a FD using Audio36 name and use it as the
-	//    source FD for reading the audio resource data.
-	// 2a. If the returned FD is -1, or equals the audio map, or
-	//     equals the audio bundle, try to get the offset of the
-	//     data from the audio map, using the Audio36 name.
+	// 1. First, request a FD using Audio36 name and use it as the source FD for
+	//    reading the audio resource data.
+	// 2a. If the returned FD is -1, or equals the audio map, or equals the
+	//     audio bundle, try to get the offset of the data from the audio map,
+	//     using the Audio36 name.
 	//
-	//     If the returned offset is -1, this is not a valid resource;
-	//     return 0. Otherwise, set the read offset for the FD to the
-	//     returned offset.
-	// 2b. Otherwise, use the FD as-is (it is a patch file), with zero
-	//     offset, and record it separately so it can be closed later.
+	//     If the returned offset is -1, this is not a valid resource; return 0.
+	//     Otherwise, set the read offset for the FD to the returned offset.
+	// 2b. Otherwise, use the FD as-is (it is a patch file), with zero offset,
+	//     and record it separately so it can be closed later.
 	//
 	// For plain audio:
 	//
-	// 1. First, request an Audio resource from the resource cache. If
-	//    one does not exist, make the same request for a Wave resource.
-	// 2a. If an audio resource was discovered, record its memory ID
-	//     and clear the streaming FD
-	// 2b. Otherwise, request an Audio FD. If one does not exist, make
-	//     the same request for a Wave FD. If neither exist, this is not
-	//     a valid resource; return 0. Otherwise, use the returned FD as
-	//     the streaming ID and set the memory ID to null.
+	// 1. First, request an Audio resource from the resource cache. If one does
+	//    not exist, make the same request for a Wave resource.
+	// 2a. If an audio resource was discovered, record its memory ID and clear
+	//     the streaming FD
+	// 2b. Otherwise, request an Audio FD. If one does not exist, make the same
+	//     request for a Wave FD. If neither exist, this is not a valid
+	//     resource; return 0. Otherwise, use the returned FD as the streaming
+	//     ID and set the memory ID to null.
 	//
 	// Once these steps are complete, the audio engine either has a file
-	// descriptor + offset that it can use to read streamed audio, or it
-	// has a memory ID that it can use to read cached audio.
+	// descriptor + offset that it can use to read streamed audio, or it has a
+	// memory ID that it can use to read cached audio.
 	//
-	// Here in ScummVM we just ask the resource manager to give us the
-	// resource and we get a seekable stream.
+	// Here in ScummVM we just ask the resource manager to give us the resource
+	// and we get a seekable stream.
 
-	// TODO: This should be fixed to use streaming, which means
-	// fixing the resource manager to allow streaming, which means
-	// probably rewriting a bunch of the resource manager.
+	// TODO: This should be fixed to use streaming, which means fixing the
+	// resource manager to allow streaming, which means probably rewriting a
+	// bunch of the resource manager.
 	Resource *resource = _resMan->findResource(resourceId, true);
 	if (resource == nullptr) {
 		warning("[Audio32::play]: %s could not be found", resourceId.toString().c_str());
@@ -812,7 +779,6 @@ uint16 Audio32::play(int16 channelIndex, const ResourceId resourceId, const bool
 	channel.fadeStartTick = 0;
 	channel.soundNode = soundNode;
 	channel.volume = volume < 0 || volume > kMaxVolume ? (int)kMaxVolume : volume;
-	// TODO: SCI3 introduces stereo audio
 	channel.pan = -1;
 
 	if (monitor) {
@@ -842,18 +808,17 @@ uint16 Audio32::play(int16 channelIndex, const ResourceId resourceId, const bool
 		audioStream = Audio::makeRawStream(dataStream, _globalSampleRate, flags, DisposeAfterUse::YES);
 	}
 
-	channel.stream = new MutableLoopAudioStream(audioStream, loop);
-	channel.converter = Audio::makeRateConverter(channel.stream->getRate(), getRate(), channel.stream->isStereo(), false);
+	channel.stream.reset(new MutableLoopAudioStream(audioStream, loop));
+	channel.converter.reset(Audio::makeRateConverter(channel.stream->getRate(), getRate(), channel.stream->isStereo(), false));
 
-	// NOTE: SCI engine sets up a decompression buffer here for the audio
-	// stream, plus writes information about the sample to the channel to
-	// convert to the correct hardware output format, and allocates the
-	// monitoring buffer to match the bitrate/samplerate/channels of the
-	// original stream. We do not need to do any of these things since we
-	// use audio streams, and allocate and fill the monitoring buffer
-	// when reading audio data from the stream.
+	// SSCI sets up a decompression buffer here for the audio stream, plus
+	// writes information about the sample to the channel to convert to the
+	// correct hardware output format, and allocates the monitoring buffer to
+	// match the bitrate/samplerate/channels of the original stream. We do not
+	// need to do any of these things since we use audio streams, and allocate
+	// and fill the monitoring buffer when reading audio data from the stream.
 
-	MutableLoopAudioStream *stream = dynamic_cast<MutableLoopAudioStream *>(channel.stream);
+	MutableLoopAudioStream *stream = dynamic_cast<MutableLoopAudioStream *>(channel.stream.get());
 	if (stream == nullptr) {
 		error("[Audio32::play]: Unable to cast stream for resource %s", resourceId.toString().c_str());
 	}
@@ -958,8 +923,8 @@ bool Audio32::pause(const int16 channelIndex) {
 			}
 		}
 
-		// NOTE: The actual engine returns false here regardless of whether
-		// or not channels were paused
+		// SSCI returns false here regardless of whether or not channels were
+		// paused, so we emulate this behaviour
 	} else {
 		AudioChannel &channel = getChannel(channelIndex);
 
@@ -996,9 +961,10 @@ int16 Audio32::stop(const int16 channelIndex) {
 		}
 	}
 
-	// NOTE: SSCI stops the DSP interrupt and frees the
-	// global decompression buffer here if there are no
-	// more active channels
+	// SSCI stops the DSP interrupt and frees the global decompression buffer
+	// here if there are no more active channels, which we do not need to do
+	// since the system manages audio callbacks and we have no static
+	// decompression buffer
 
 	return oldNumChannels;
 }
@@ -1015,13 +981,14 @@ int16 Audio32::getPosition(const int16 channelIndex) const {
 		return -1;
 	}
 
-	// NOTE: SSCI treats this as an unsigned short except for
-	// when the value is 65535, then it treats it as signed
+	// SSCI treats this as an unsigned short except for when the value is 65535,
+	// then it treats it as signed
 	int position = -1;
 	const uint32 now = g_sci->getTickCount();
 
-	// NOTE: The original engine also queried the audio driver to see whether
-	// it thought that there was audio playback occurring via driver opcode 9
+	// SSCI also queried the audio driver to see whether it thought that there
+	// was audio playback occurring via driver opcode 9, but we have no analogue
+	// to query
 	if (channelIndex == kAllChannels) {
 		if (_pausedAtTick) {
 			position = _pausedAtTick - _startedAtTick;
@@ -1052,7 +1019,7 @@ void Audio32::setLoop(const int16 channelIndex, const bool loop) {
 
 	AudioChannel &channel = getChannel(channelIndex);
 
-	MutableLoopAudioStream *stream = dynamic_cast<MutableLoopAudioStream *>(channel.stream);
+	MutableLoopAudioStream *stream = dynamic_cast<MutableLoopAudioStream *>(channel.stream.get());
 	assert(stream);
 	stream->loop() = loop;
 }
@@ -1161,8 +1128,8 @@ bool Audio32::hasSignal() const {
 		return false;
 	}
 
-	const Audio::st_sample_t *buffer = _monitoredBuffer;
-	const Audio::st_sample_t *const end = _monitoredBuffer + _numMonitoredSamples;
+	const Audio::st_sample_t *buffer = _monitoredBuffer.data();
+	const Audio::st_sample_t *const end = _monitoredBuffer.data() + _numMonitoredSamples;
 
 	while (buffer != end) {
 		const Audio::st_sample_t sample = *buffer++;
@@ -1193,9 +1160,9 @@ reg_t Audio32::kernelPlay(const bool autoPlay, const int argc, const reg_t *cons
 		if (argc < 6 || argv[5].toSint16() == 1) {
 			loop = false;
 		} else {
-			// NOTE: Uses -1 for infinite loop. Presumably the
-			// engine was supposed to allow counter loops at one
-			// point, but ended up only using loop as a boolean.
+			// SSCI uses -1 for infinite loop. Presumably the engine was
+			// supposed to allow counter loops at one point, but ended up only
+			// using loop as a boolean.
 			loop = (bool)argv[5].toSint16();
 		}
 
@@ -1311,8 +1278,10 @@ reg_t Audio32::kernelFade(const int argc, const reg_t *const argv) {
 
 	Common::StackLock lock(_mutex);
 
-	// NOTE: In SSCI, this call to find the channel is hacked up; argc is
-	// set to 2 before the call, and then restored after the call.
+	// In SSCI, this call to find the channel is hacked up; argc is set to 2
+	// before the call, and then restored after the call. We just implemented
+	// findChannelByArgs in a manner that allows us to pass this information
+	// without messing with argc/argv instead
 	const int16 channelIndex = findChannelByArgs(2, argv, 0, argc > 5 ? argv[5] : NULL_REG);
 	const int16 volume = argv[1].toSint16();
 	const int16 speed = argv[2].toSint16();
@@ -1359,7 +1328,7 @@ void Audio32::printAudioList(Console *con) const {
 	Common::StackLock lock(_mutex);
 	for (int i = 0; i < _numActiveChannels; ++i) {
 		const AudioChannel &channel = _channels[i];
-		const MutableLoopAudioStream *stream = dynamic_cast<MutableLoopAudioStream *>(channel.stream);
+		const MutableLoopAudioStream *stream = dynamic_cast<MutableLoopAudioStream *>(channel.stream.get());
 		con->debugPrintf("  %d[%04x:%04x]: %s, started at %d, pos %d/%d, vol %d, pan %d%s%s\n",
 						 i,
 						 PRINT_REG(channel.soundNode),
diff --git a/engines/sci/sound/audio32.h b/engines/sci/sound/audio32.h
index 71f5883..a0167f3 100644
--- a/engines/sci/sound/audio32.h
+++ b/engines/sci/sound/audio32.h
@@ -50,22 +50,23 @@ struct AudioChannel {
 	ResourceId id;
 
 	/**
-	 * The resource loaded into this channel.
+	 * The resource loaded into this channel. The resource is owned by
+	 * ResourceManager.
 	 */
 	Resource *resource;
 
 	/**
-	 * The audio stream loaded into this channel. Can cast
-	 * to `SeekableAudioStream` for normal channels and
-	 * `RobotAudioStream` for robot channels.
+	 * The audio stream loaded into this channel. Can cast to
+	 * `SeekableAudioStream` for normal channels and `RobotAudioStream` for
+	 * robot channels.
 	 */
-	Audio::AudioStream *stream;
+	Common::ScopedPtr<Audio::AudioStream> stream;
 
 	/**
-	 * The converter used to transform and merge the input
-	 * stream into the mixer's output buffer.
+	 * The converter used to transform and merge the input stream into the
+	 * mixer's output buffer.
 	 */
-	Audio::RateConverter *converter;
+	Common::ScopedPtr<Audio::RateConverter> converter;
 
 	/**
 	 * Duration of the channel, in ticks.
@@ -83,8 +84,8 @@ struct AudioChannel {
 	uint32 pausedAtTick;
 
 	/**
-	 * The time, in ticks, that the channel fade began.
-	 * If 0, the channel is not being faded.
+	 * The time, in ticks, that the channel fade began. If 0, the channel is not
+	 * being faded.
 	 */
 	uint32 fadeStartTick;
 
@@ -104,20 +105,19 @@ struct AudioChannel {
 	int fadeTargetVolume;
 
 	/**
-	 * Whether or not the channel should be stopped and
-	 * freed when the fade is complete.
+	 * Whether or not the channel should be stopped and freed when the fade is
+	 * complete.
 	 */
 	bool stopChannelOnFade;
 
 	/**
-	 * Whether or not this channel contains a Robot
-	 * audio block.
+	 * Whether or not this channel contains a Robot audio block.
 	 */
 	bool robot;
 
 	/**
-	 * For digital sound effects, the related VM
-	 * Sound::nodePtr object for the sound.
+	 * For digital sound effects, the related VM Sound::nodePtr object for the
+	 * sound.
 	 */
 	reg_t soundNode;
 
@@ -127,17 +127,37 @@ struct AudioChannel {
 	int volume;
 
 	/**
-	 * The amount to pan to the right, from 0 to 100.
-	 * 50 is centered, -1 is not panned.
+	 * The amount to pan to the right, from 0 to 100. 50 is centered, -1 is not
+	 * panned.
 	 */
 	int pan;
+
+	AudioChannel &operator=(AudioChannel &other) {
+		id = other.id;
+		resource = other.resource;
+		stream.reset(other.stream.release());
+		converter.reset(other.converter.release());
+		duration = other.duration;
+		startedAtTick = other.startedAtTick;
+		pausedAtTick = other.pausedAtTick;
+		fadeStartTick = other.fadeStartTick;
+		fadeStartVolume = other.fadeStartVolume;
+		fadeDuration = other.fadeDuration;
+		fadeTargetVolume = other.fadeTargetVolume;
+		stopChannelOnFade = other.stopChannelOnFade;
+		robot = other.robot;
+		soundNode = other.soundNode;
+		volume = other.volume;
+		pan = other.pan;
+		return *this;
+	}
 };
 
 #pragma mark -
 
 /**
- * Special audio channel indexes used to select a channel
- * for digital audio playback.
+ * Special audio channel indexes used to select a channel for digital audio
+ * playback.
  */
 enum AudioChannelIndex {
 	kRobotChannel = -3,
@@ -146,10 +166,9 @@ enum AudioChannelIndex {
 };
 
 /**
- * Audio32 acts as a permanent audio stream into the system
- * mixer and provides digital audio services for the SCI32
- * engine, since the system mixer does not support all the
- * features of SCI.
+ * Audio32 acts as a permanent audio stream into the system mixer and provides
+ * digital audio services for the SCI32 engine, since the system mixer does not
+ * support all the features of SCI.
  */
 class Audio32 : public Audio::AudioStream, public Common::Serializable {
 public:
@@ -196,10 +215,10 @@ private:
 	bool channelShouldMix(const AudioChannel &channel) const;
 
 	/**
-	 * Mixes audio from the given source stream into the
-	 * target buffer using the given rate converter.
+	 * Mixes audio from the given source stream into the target buffer using the
+	 * given rate converter.
 	 */
-	int writeAudioInternal(Audio::AudioStream *const sourceStream, Audio::RateConverter *const converter, Audio::st_sample_t *targetBuffer, const int numSamples, const Audio::st_volume_t leftVolume, const Audio::st_volume_t rightVolume);
+	int writeAudioInternal(Audio::AudioStream &sourceStream, Audio::RateConverter &converter, Audio::st_sample_t *targetBuffer, const int numSamples, const Audio::st_volume_t leftVolume, const Audio::st_volume_t rightVolume);
 
 #pragma mark -
 #pragma mark Channel management
@@ -226,17 +245,15 @@ public:
 	uint8 getNumUnlockedChannels() const;
 
 	/**
-	 * Finds a channel that is already configured for the
-	 * given audio sample.
+	 * Finds a channel that is already configured for the given audio sample.
 	 *
-	 * @param startIndex The location of the audio resource
-	 * information in the arguments list.
+	 * @param startIndex The location of the audio resource information in the
+	 * arguments list.
 	 */
 	int16 findChannelByArgs(int argc, const reg_t *argv, const int startIndex, const reg_t soundNode) const;
 
 	/**
-	 * Finds a channel that is already configured for the
-	 * given audio sample.
+	 * Finds a channel that is already configured for the given audio sample.
 	 */
 	int16 findChannelById(const ResourceId resourceId, const reg_t soundNode = NULL_REG) const;
 
@@ -255,26 +272,24 @@ private:
 	Common::Array<AudioChannel> _channels;
 
 	/**
-	 * The number of active audio channels in the mixer.
-	 * Being active is not the same as playing; active
-	 * channels may be paused.
+	 * The number of active audio channels in the mixer. Being active is not the
+	 * same as playing; active channels may be paused.
 	 */
 	uint8 _numActiveChannels;
 
 	/**
 	 * Whether or not we are in the audio thread.
 	 *
-	 * This flag is used instead of passing a parameter to
-	 * `freeUnusedChannels` because a parameter would
-	 * require forwarding through the public method `stop`,
-	 * and there is not currently any reason for this
-	 * implementation detail to be exposed.
+	 * This flag is used instead of passing a parameter to `freeUnusedChannels`
+	 * because a parameter would require forwarding through the public method
+	 * `stop`, and there is not currently any reason for this implementation
+	 * detail to be exposed.
 	 */
 	bool _inAudioThread;
 
 	/**
-	 * The list of resources from freed channels that need
-	 * to be unlocked from the main thread.
+	 * The list of resources from freed channels that need to be unlocked from
+	 * the main thread.
 	 */
 	UnlockList _resourcesToUnlock;
 
@@ -302,8 +317,7 @@ private:
 	}
 
 	/**
-	 * Frees all non-looping channels that have reached the
-	 * end of their stream.
+	 * Frees all non-looping channels that have reached the end of their stream.
 	 */
 	void freeUnusedChannels();
 
@@ -313,8 +327,7 @@ private:
 	void freeChannel(const int16 channelIndex);
 
 	/**
-	 * Unlocks all resources that were freed by the audio
-	 * thread.
+	 * Unlocks all resources that were freed by the audio thread.
 	 */
 	void unlockResources();
 
@@ -322,58 +335,58 @@ private:
 #pragma mark Script compatibility
 public:
 	/**
-	 * Gets the (fake) sample rate of the hardware DAC.
-	 * For script compatibility only.
+	 * Gets the (fake) sample rate of the hardware DAC. For script compatibility
+	 * only.
 	 */
 	inline uint16 getSampleRate() const {
 		return _globalSampleRate;
 	}
 
 	/**
-	 * Sets the (fake) sample rate of the hardware DAC.
-	 * For script compatibility only.
+	 * Sets the (fake) sample rate of the hardware DAC. For script compatibility
+	 * only.
 	 */
 	void setSampleRate(uint16 rate);
 
 	/**
-	 * Gets the (fake) bit depth of the hardware DAC.
-	 * For script compatibility only.
+	 * Gets the (fake) bit depth of the hardware DAC. For script compatibility
+	 * only.
 	 */
 	inline uint8 getBitDepth() const {
 		return _globalBitDepth;
 	}
 
 	/**
-	 * Sets the (fake) sample rate of the hardware DAC.
-	 * For script compatibility only.
+	 * Sets the (fake) sample rate of the hardware DAC. For script compatibility
+	 * only.
 	 */
 	void setBitDepth(uint8 depth);
 
 	/**
-	 * Gets the (fake) number of output (speaker) channels
-	 * of the hardware DAC. For script compatibility only.
+	 * Gets the (fake) number of output (speaker) channels of the hardware DAC.
+	 * For script compatibility only.
 	 */
 	inline uint8 getNumOutputChannels() const {
 		return _globalNumOutputChannels;
 	}
 
 	/**
-	 * Sets the (fake) number of output (speaker) channels
-	 * of the hardware DAC. For script compatibility only.
+	 * Sets the (fake) number of output (speaker) channels of the hardware DAC.
+	 * For script compatibility only.
 	 */
 	void setNumOutputChannels(int16 numChannels);
 
 	/**
-	 * Gets the (fake) number of preloaded channels.
-	 * For script compatibility only.
+	 * Gets the (fake) number of preloaded channels. For script compatibility
+	 * only.
 	 */
 	inline uint8 getPreload() const {
 		return _preload;
 	}
 
 	/**
-	 * Sets the (fake) number of preloaded channels.
-	 * For script compatibility only.
+	 * Sets the (fake) number of preloaded channels. For script compatibility
+	 * only.
 	 */
 	inline void setPreload(uint8 preload) {
 		_preload = preload;
@@ -381,49 +394,43 @@ public:
 
 private:
 	/**
-	 * The hardware DAC sample rate. Stored only for script
-	 * compatibility.
+	 * The hardware DAC sample rate. Stored only for script compatibility.
 	 */
 	uint16 _globalSampleRate;
 
 	/**
-	 * The maximum allowed sample rate of the system mixer.
-	 * Stored only for script compatibility.
+	 * The maximum allowed sample rate of the system mixer. Stored only for
+	 * script compatibility.
 	 */
 	uint16 _maxAllowedSampleRate;
 
 	/**
-	 * The hardware DAC bit depth. Stored only for script
-	 * compatibility.
+	 * The hardware DAC bit depth. Stored only for script compatibility.
 	 */
 	uint8 _globalBitDepth;
 
 	/**
-	 * The maximum allowed bit depth of the system mixer.
-	 * Stored only for script compatibility.
+	 * The maximum allowed bit depth of the system mixer. Stored only for script
+	 * compatibility.
 	 */
 	uint8 _maxAllowedBitDepth;
 
 	/**
-	 * The hardware DAC output (speaker) channel
-	 * configuration. Stored only for script compatibility.
+	 * The hardware DAC output (speaker) channel configuration. Stored only for
+	 * script compatibility.
 	 */
 	uint8 _globalNumOutputChannels;
 
 	/**
-	 * The maximum allowed number of output (speaker)
-	 * channels of the system mixer. Stored only for script
-	 * compatibility.
+	 * The maximum allowed number of output (speaker) channels of the system
+	 * mixer. Stored only for script compatibility.
 	 */
 	uint8 _maxAllowedOutputChannels;
 
 	/**
-	 * The number of audio channels that should have their
-	 * data preloaded into memory instead of streaming from
-	 * disk.
-	 * 1 = all channels, 2 = 2nd active channel and above,
-	 * etc.
-	 * Stored only for script compatibility.
+	 * The number of audio channels that should have their data preloaded into
+	 * memory instead of streaming from disk. 1 = all channels, 2 = 2nd active
+	 * channel and above, etc. Stored only for script compatibility.
 	 */
 	uint8 _preload;
 
@@ -442,8 +449,7 @@ private:
 	int16 findRobotChannel() const;
 
 	/**
-	 * When true, channels marked as robot audio will not be
-	 * played.
+	 * When true, channels marked as robot audio will not be played.
 	 */
 	bool _robotAudioPaused;
 
@@ -456,8 +462,8 @@ public:
 	uint16 play(int16 channelIndex, const ResourceId resourceId, const bool autoPlay, const bool loop, const int16 volume, const reg_t soundNode, const bool monitor);
 
 	/**
-	 * Resumes playback of a paused audio channel, or of
-	 * the entire audio player.
+	 * Resumes playback of a paused audio channel, or of the entire audio
+	 * player.
 	 */
 	bool resume(const int16 channelIndex);
 	bool resume(const ResourceId resourceId, const reg_t soundNode = NULL_REG) {
@@ -475,8 +481,7 @@ public:
 	}
 
 	/**
-	 * Stops and unloads an audio channel, or the entire
-	 * audio player.
+	 * Stops and unloads an audio channel, or the entire audio player.
 	 */
 	int16 stop(const int16 channelIndex);
 	int16 stop(const ResourceId resourceId, const reg_t soundNode = NULL_REG) {
@@ -490,8 +495,7 @@ public:
 	uint16 restart(const ResourceId resourceId, const bool autoPlay, const bool loop, const int16 volume, const reg_t soundNode, const bool monitor);
 
 	/**
-	 * Returns the playback position for the given channel
-	 * number, in ticks.
+	 * Returns the playback position for the given channel number, in ticks.
 	 */
 	int16 getPosition(const int16 channelIndex) const;
 	int16 getPosition(const ResourceId resourceId, const reg_t soundNode = NULL_REG) {
@@ -531,8 +535,8 @@ private:
 #pragma mark Effects
 public:
 	/**
-	 * Gets the volume for a given channel. Passing
-	 * `kAllChannels` will get the global volume.
+	 * Gets the volume for a given channel. Passing `kAllChannels` will get the
+	 * global volume.
 	 */
 	int16 getVolume(const int16 channelIndex) const;
 	int16 getVolume(const ResourceId resourceId, const reg_t soundNode) const {
@@ -541,8 +545,8 @@ public:
 	}
 
 	/**
-	 * Sets the volume of an audio channel. Passing
-	 * `kAllChannels` will set the global volume.
+	 * Sets the volume of an audio channel. Passing `kAllChannels` will set the
+	 * global volume.
 	 */
 	void setVolume(const int16 channelIndex, int16 volume);
 	void setVolume(const ResourceId resourceId, const reg_t soundNode, const int16 volume) {
@@ -583,24 +587,21 @@ public:
 
 private:
 	/**
-	 * If true, audio will be mixed by reducing the target
-	 * buffer by half every time a new channel is mixed in.
-	 * The final channel is not attenuated.
+	 * If true, audio will be mixed by reducing the target buffer by half every
+	 * time a new channel is mixed in. The final channel is not attenuated.
 	 */
 	bool _attenuatedMixing;
 
 	/**
-	 * When true, a modified attenuation algorithm is used
-	 * (`A/4 + B`) instead of standard linear attenuation
-	 * (`A/2 + B/2`).
+	 * When true, a modified attenuation algorithm is used (`A/4 + B`) instead
+	 * of standard linear attenuation (`A/2 + B/2`).
 	 */
 	bool _useModifiedAttenuation;
 
 	/**
 	 * Processes an audio fade for the given channel.
 	 *
-	 * @returns true if the fade was completed and the
-	 * channel was stopped.
+	 * @returns true if the fade was completed and the channel was stopped.
 	 */
 	bool processFade(const int16 channelIndex);
 
@@ -608,35 +609,27 @@ private:
 #pragma mark Signal monitoring
 public:
 	/**
-	 * Returns whether the currently monitored audio channel
-	 * contains any signal within the next audio frame.
+	 * Returns whether the currently monitored audio channel contains any signal
+	 * within the next audio frame.
 	 */
 	bool hasSignal() const;
 
 private:
 	/**
-	 * The index of the channel being monitored for signal,
-	 * or -1 if no channel is monitored. When a channel is
-	 * monitored, it also causes the engine to play only the
-	 * monitored channel.
+	 * The index of the channel being monitored for signal, or -1 if no channel
+	 * is monitored. When a channel is monitored, it also causes the engine to
+	 * play only the monitored channel.
 	 */
 	int16 _monitoredChannelIndex;
 
 	/**
-	 * The data buffer holding decompressed audio data for
-	 * the channel that will be monitored for an audio
-	 * signal.
-	 */
-	Audio::st_sample_t *_monitoredBuffer;
-
-	/**
-	 * The size of the buffer, in bytes.
+	 * The data buffer holding decompressed audio data for the channel that will
+	 * be monitored for an audio signal.
 	 */
-	size_t _monitoredBufferSize;
+	Common::Array<Audio::st_sample_t> _monitoredBuffer;
 
 	/**
-	 * The number of valid audio samples in the signal
-	 * monitoring buffer.
+	 * The number of valid audio samples in the signal monitoring buffer.
 	 */
 	int _numMonitoredSamples;
 
diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp
index 0bb295d..5a1c2c0 100644
--- a/engines/sci/sound/soundcmd.cpp
+++ b/engines/sci/sound/soundcmd.cpp
@@ -350,11 +350,9 @@ reg_t SoundCommandParser::kDoSoundPause(EngineState *s, int argc, reg_t *argv) {
 		}
 
 #ifdef ENABLE_SCI32
-		// NOTE: The original engine also expected a global
-		// "kernel call" flag to be true in order to perform
-		// this action, but the architecture of the ScummVM
-		// implementation is so different that it doesn't
-		// matter here
+		// SSCI also expected a global "kernel call" flag to be true in order to
+		// perform this action, but the architecture of the ScummVM
+		// implementation is so different that it doesn't matter here
 		if (_soundVersion >= SCI_VERSION_2_1_EARLY && musicSlot->isSample) {
 			if (shouldPause) {
 				g_sci->_audio32->pause(ResourceId(kResourceTypeAudio, musicSlot->resourceId), musicSlot->soundObj);


Commit: 42180527c4d9df920ab1b77c78e9c5e36b93b74d
    https://github.com/scummvm/scummvm/commit/42180527c4d9df920ab1b77c78e9c5e36b93b74d
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:11:02-05:00

Commit Message:
SCI32: Fix music volume not being restored after speech in Torin

This was a regression introduced by
d556dcc57bf50a03d81ab7a1ef59a9e5758465bf.

Changed paths:
    engines/sci/sound/music.cpp
    engines/sci/sound/soundcmd.cpp


diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index 5530952..b2bd72e 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -626,13 +626,7 @@ void SciMusic::soundStop(MusicEntry *pSnd) {
 
 void SciMusic::soundSetVolume(MusicEntry *pSnd, byte volume) {
 	assert(volume <= MUSIC_VOLUME_MAX);
-	if (pSnd->isSample) {
-#ifdef ENABLE_SCI32
-		if (_soundVersion >= SCI_VERSION_2_1_EARLY) {
-			g_sci->_audio32->setVolume(ResourceId(kResourceTypeAudio, pSnd->resourceId), pSnd->soundObj, volume);
-		}
-#endif
-	} else if (pSnd->pMidiParser) {
+	if (!pSnd->isSample && pSnd->pMidiParser) {
 		Common::StackLock lock(_mutex);
 		pSnd->pMidiParser->mainThreadBegin();
 		pSnd->pMidiParser->setVolume(volume);
diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp
index 5a1c2c0..54fdcf5 100644
--- a/engines/sci/sound/soundcmd.cpp
+++ b/engines/sci/sound/soundcmd.cpp
@@ -739,8 +739,8 @@ reg_t SoundCommandParser::kDoSoundSetVolume(EngineState *s, int argc, reg_t *arg
 #ifdef ENABLE_SCI32
 	// SSCI unconditionally sets volume if it is digital audio
 	if (_soundVersion >= SCI_VERSION_2_1_EARLY && musicSlot->isSample) {
-		_music->soundSetVolume(musicSlot, value);
-	} else
+		g_sci->_audio32->setVolume(ResourceId(kResourceTypeAudio, musicSlot->resourceId), musicSlot->soundObj, value);
+	}
 #endif
 	if (musicSlot->volume != value) {
 		musicSlot->volume = value;


Commit: a2c8674252743c451600f53c77df3c7fac6e7786
    https://github.com/scummvm/scummvm/commit/a2c8674252743c451600f53c77df3c7fac6e7786
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:11:02-05:00

Commit Message:
SCI32: Clean up GfxText32

* Rewrap comments to 80 columns
* Clarify comments where possible

Changed paths:
    engines/sci/graphics/text32.cpp
    engines/sci/graphics/text32.h


diff --git a/engines/sci/graphics/text32.cpp b/engines/sci/graphics/text32.cpp
index 7399fe0..1fcf292 100644
--- a/engines/sci/graphics/text32.cpp
+++ b/engines/sci/graphics/text32.cpp
@@ -44,7 +44,7 @@ int16 GfxText32::_yResolution = 0;
 GfxText32::GfxText32(SegManager *segMan, GfxCache *fonts) :
 	_segMan(segMan),
 	_cache(fonts),
-	// Not a typo, the original engine did not initialise height, only width
+	// SSCI did not initialise height, so we intentionally do not do so also
 	_width(0),
 	_text(""),
 	_bitmap(NULL_REG) {
@@ -84,8 +84,8 @@ reg_t GfxText32::createFontBitmap(int16 width, int16 height, const Common::Rect
 		mulinc(_textRect, scaleX, scaleY);
 	}
 
-	// _textRect represents where text is drawn inside the
-	// bitmap; clipRect is the entire bitmap
+	// `_textRect` represents where text is drawn inside the bitmap; `clipRect`
+	// is the entire bitmap
 	Common::Rect bitmapRect(_width, _height);
 
 	if (_textRect.intersects(bitmapRect)) {
@@ -134,9 +134,9 @@ reg_t GfxText32::createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &
 
 	SciBitmap &bitmap = *_segMan->allocateBitmap(&_bitmap, _width, _height, _skipColor, 0, 0, _xResolution, _yResolution, 0, false, gc);
 
-	// NOTE: The engine filled the bitmap pixels with 11 here, which is silly
-	// because then it just erased the bitmap using the skip color. So we don't
-	// fill the bitmap redundantly here.
+	// SSCI filled the bitmap pixels with 11 here, which is silly because then
+	// it just erased the bitmap using the skip color. So we don't fill the
+	// bitmap redundantly here.
 
 	_backColor = _skipColor;
 	erase(bitmapRect, false);
@@ -164,9 +164,10 @@ reg_t GfxText32::createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &
 }
 
 void GfxText32::setFont(const GuiResourceId fontId) {
-	// NOTE: In SCI engine this calls FontMgr::BuildFontTable and then a font
-	// table is built on the FontMgr directly; instead, because we already have
-	// font resources, this code just grabs a font out of GfxCache.
+	// In SSCI, this calls FontMgr::BuildFontTable, and then a font table is
+	// built on the FontMgr directly; instead, because we already have GfxFont
+	// resources from SCI16 and those resources did not change in SCI32, this
+	// code just grabs those out of GfxCache
 	if (fontId != _fontId) {
 		_fontId = fontId;
 		_font = _cache->getFont(_fontId);
@@ -179,7 +180,7 @@ void GfxText32::drawFrame(const Common::Rect &rect, const int16 size, const uint
 	SciBitmap &bitmap = *_segMan->lookupBitmap(_bitmap);
 	byte *pixels = bitmap.getPixels() + rect.top * _width + rect.left;
 
-	// NOTE: Not fully disassembled, but this should be right
+	// Not fully disassembled, but appears to be correct in all cases
 	int16 rectWidth = targetRect.width();
 	int16 heightRemaining = targetRect.height();
 	int16 sidesHeight = heightRemaining - size * 2;
@@ -275,10 +276,9 @@ void GfxText32::drawTextBox(const Common::String &text) {
 void GfxText32::drawText(const uint index, uint length) {
 	assert(index + length <= _text.size());
 
-	// NOTE: This draw loop implementation is somewhat different than the
-	// implementation in the actual engine, but should be accurate. Primarily
-	// the changes revolve around eliminating some extra temporaries and
-	// fixing the logic to match.
+	// This draw loop implementation is somewhat different than the
+	// implementation in SSCI, but is accurate. Primarily the changes revolve
+	// around eliminating some extra temporaries and fixing the logic to match.
 	const char *text = _text.c_str() + index;
 	while (length-- > 0) {
 		char currentChar = *text++;
@@ -341,10 +341,10 @@ void GfxText32::invertRect(const reg_t bitmapId, int16 bitmapStride, const Commo
 
 	SciBitmap &bitmap = *_segMan->lookupBitmap(bitmapId);
 
-	// NOTE: SCI code is super weird here; it seems to be trying to look at the
-	// entire size of the bitmap including the header, instead of just the pixel
-	// data size. We just look at the pixel size. This function generally is an
-	// odd duck since the stride dimension for a bitmap is built in to the bitmap
+	// SSCI is super weird here; it seems to be trying to look at the entire
+	// size of the bitmap including the header, instead of just the pixel data
+	// size. We just look at the pixel size. This function generally is an odd
+	// duck since the stride dimension for a bitmap is built in to the bitmap
 	// header, so perhaps it was once an unheadered bitmap format and this
 	// function was never updated to match? Or maybe they exploit the
 	// configurable stride length somewhere else to do stair stepping inverts...
@@ -355,7 +355,7 @@ void GfxText32::invertRect(const reg_t bitmapId, int16 bitmapStride, const Commo
 		error("InvertRect too big: %u >= %u", invertSize, bitmapSize);
 	}
 
-	// NOTE: Actual engine just added the bitmap header size hardcoded here
+	// SSCI just added a hardcoded bitmap header size here
 	byte *pixel = bitmap.getPixels() + bitmapStride * targetRect.top + targetRect.left;
 
 	int16 stride = bitmapStride - targetRect.width();
@@ -392,16 +392,17 @@ uint GfxText32::getLongest(uint *charIndex, const int16 width) {
 
 	char currentChar;
 	while ((currentChar = *text++) != '\0') {
-		// NOTE: In the original engine, the font, color, and alignment were
-		// reset here to their initial values
+		// In SSCI, the font, color, and alignment were reset here to their
+		// initial values; this does not seem to be necessary and really
+		// complicates the font system, so we do not do it
 
 		// The text to render contains a line break; stop at the line break
 		if (currentChar == '\r' || currentChar == '\n') {
-			// Skip the rest of the line break if it is a Windows-style
-			// \r\n or non-standard \n\r
-			// NOTE: In the original engine, the `text` pointer had not been
-			// advanced yet so the indexes used to access characters were
-			// one higher
+			// Skip the rest of the line break if it is a Windows-style \r\n (or
+			// non-standard \n\r)
+
+			// In SSCI, the `text` pointer had not been advanced yet here, so
+			// the indexes used to access characters were one higher there
 			if (
 				(currentChar == '\r' && text[0] == '\n') ||
 				(currentChar == '\n' && text[0] == '\r' && text[1] != '\n')
@@ -418,16 +419,20 @@ uint GfxText32::getLongest(uint *charIndex, const int16 width) {
 			}
 
 			// Skip the line break and return all text seen up to now
-			// NOTE: In original engine, the font, color, and alignment were
-			// reset, then getTextWidth was called to use its side-effects to
-			// set font, color, and alignment according to the text from
-			// `initialCharIndex` to `testLength`
+			// In SSCI, the font, color, and alignment were reset, then
+			// getTextWidth was called to use its side-effects to set font,
+			// color, and alignment according to the text from
+			// `initialCharIndex` to `testLength`. This is complicated and
+			// apparently not necessary for correct operation, so we do not do
+			// it
+
 			++*charIndex;
 			return testLength;
 		} else if (currentChar == ' ') {
-			// The last word in the line made it too wide to fit in the text area;
-			// return up to the previous word, then collapse the whitespace
-			// between that word and its next sibling word into the line break
+			// The last word in the line made it too wide to fit in the text
+			// area; return up to the previous word, then collapse the
+			// whitespace between that word and its next sibling word into the
+			// line break
 			if (getTextWidth(initialCharIndex, testLength) > width) {
 				*charIndex = lastWordBreakIndex;
 				const char *nextChar = _text.c_str() + lastWordBreakIndex;
@@ -435,14 +440,17 @@ uint GfxText32::getLongest(uint *charIndex, const int16 width) {
 					++*charIndex;
 				}
 
-				// NOTE: In original engine, the font, color, and alignment were
-				// set here to the values that were seen at the last space character
+				// In SSCI, the font, color, and alignment were set here to the
+				// values that were seen at the last space character, but this
+				// is complicated and unnecessary so we do not do it
+
 				return length;
 			}
 
-			// NOTE: In the original engine, the values of _fontId, _foreColor,
-			// and _alignment were stored for use in the return path mentioned
-			// just above here
+			// In SSCI, the values of `_fontId`, `_foreColor`, and `_alignment`
+			// were stored for use in the return path mentioned just above here,
+			// but we do not need to do this because we do not cause
+			// side-effects when calculating text dimensions
 
 			// We found a word break that was within the text area, memorise it
 			// and continue processing. +1 on the character index because it has
@@ -456,8 +464,9 @@ uint GfxText32::getLongest(uint *charIndex, const int16 width) {
 		++*charIndex;
 		++testLength;
 
-		// NOTE: In the original engine, the font, color, and alignment were
-		// reset here to their initial values
+		// In SSCI, the font, color, and alignment were reset here to their
+		// initial values, but we do not need to do this because we do not cause
+		// side-effects when calculating text dimensions
 
 		// The text to render contained no word breaks yet but is already too
 		// wide for the text area; just split the word in half at the point
@@ -471,10 +480,11 @@ uint GfxText32::getLongest(uint *charIndex, const int16 width) {
 	// The complete text to render was a single word, or was narrower than
 	// the text area, so return the entire line
 	if (length == 0 || getTextWidth(initialCharIndex, testLength) <= width) {
-		// NOTE: In original engine, the font, color, and alignment were
-		// reset, then getTextWidth was called to use its side-effects to
-		// set font, color, and alignment according to the text from
-		// `initialCharIndex` to `testLength`
+		// In SSCI, the font, color, and alignment were reset, then getTextWidth
+		// was called to use its side-effects to set font, color, and alignment
+		// according to the text from `initialCharIndex` to `testLength`. This
+		// is not necessary because we do not cause side-effects when
+		// calculating text dimensions
 		return testLength;
 	}
 
@@ -495,14 +505,13 @@ int16 GfxText32::getTextWidth(const uint index, uint length) const {
 	while (length > 0 && currentChar != '\0') {
 		// Control codes are in the format `|<code><value>|`
 		if (currentChar == '|') {
-			// NOTE: Original engine code changed the global state of the
-			// FontMgr here upon encountering any color, alignment, or
-			// font control code.
-			// To avoid requiring all callers to manually restore these
-			// values on every call, we ignore control codes other than
-			// font change (since alignment and color do not change the
-			// width of characters), and simply update the font pointer
-			// on stack instead of the member property font.
+			// SSCI changed the global state of the FontMgr here upon
+			// encountering any color, alignment, or font control code. To avoid
+			// requiring all callers to manually restore these values on every
+			// call, we ignore control codes other than font change (since
+			// alignment and color do not change the width of characters), and
+			// simply update the font pointer on stack instead of the member
+			// property font to avoid these unnecessary side-effects.
 			currentChar = *text++;
 			--length;
 
@@ -548,12 +557,12 @@ int16 GfxText32::getTextWidth(const Common::String &text, const uint index, cons
 }
 
 Common::Rect GfxText32::getTextSize(const Common::String &text, int16 maxWidth, bool doScaling) {
-	// NOTE: Like most of the text rendering code, this function was pretty
-	// weird in the original engine. The initial result rectangle was actually
-	// a 1x1 rectangle (0, 0, 0, 0), which was then "fixed" after the main
-	// text size loop finished running by subtracting 1 from the right and
-	// bottom edges. Like other functions in SCI32, this has been converted
-	// to use exclusive rects with inclusive rounding.
+	// Like most of the text rendering code, this function was pretty weird in
+	// SSCI. The initial result rectangle was actually a 1x1 rectangle
+	// (0, 0, 0, 0), which was then "fixed" after the main text size loop
+	// finished running by subtracting 1 from the right and bottom edges. Like
+	// other functions in SCI32, this has been converted to use exclusive rects
+	// with inclusive rounding.
 
 	Common::Rect result;
 
@@ -598,17 +607,18 @@ Common::Rect GfxText32::getTextSize(const Common::String &text, int16 maxWidth,
 		if (getSciVersion() < SCI_VERSION_2_1_MIDDLE) {
 			result.bottom = 0;
 		} else {
-			// NOTE: In the original engine code, the bottom was not decremented
-			// by 1, which means that the rect was actually a pixel taller than
-			// the height of the font. This was not the case in the other branch,
-			// which decremented the bottom by 1 at the end of the loop.
+			// In SSCI, the bottom was not decremented by 1, which means that
+			// the rect was actually a pixel taller than the height of the font.
+			// This was not the case in the other branch, which decremented the
+			// bottom by 1 at the end of the loop. For accuracy, we do what SSCI
+			// did, even though this means the result is a pixel off
 			result.bottom = _font->getHeight() + 1;
 		}
 	}
 
 	if (doScaling) {
-		// NOTE: The original engine code also scaled top/left but these are
-		// always zero so there is no reason to do that.
+		// SSCI also scaled top/left but these are always zero so there is no
+		// reason to do that
 		result.right = ((result.right - 1) * scriptWidth + _xResolution - 1) / _xResolution + 1;
 		result.bottom = ((result.bottom - 1) * scriptHeight + _yResolution - 1) / _yResolution + 1;
 	}
@@ -700,7 +710,10 @@ void GfxText32::scrollLine(const Common::String &lineText, int numLines, uint8 c
 
 	_foreColor = color;
 	_alignment = align;
-	//int fc = _foreColor;
+
+	// As with other font functions, SSCI saved _foreColor here so it could be
+	// restored after the getTextWidth call, but this call is side-effect-free
+	// in our implementation so this is not necessary
 
 	setFont(fontId);
 
@@ -713,8 +726,8 @@ void GfxText32::scrollLine(const Common::String &lineText, int numLines, uint8 c
 		_drawPosition.x += _textRect.width() - textWidth;
 	}
 
-	//_foreColor = fc;
-	//setFont(fontId);
+	// _foreColor and font were restored here in SSCI due to side-effects of
+	// getTextWidth which do not exist in our implementation
 
 	drawText(0, lineText.size());
 }
diff --git a/engines/sci/graphics/text32.h b/engines/sci/graphics/text32.h
index c8fafb2..945cc81 100644
--- a/engines/sci/graphics/text32.h
+++ b/engines/sci/graphics/text32.h
@@ -45,11 +45,11 @@ enum ScrollDirection {
 class GfxFont;
 
 /**
- * This class handles text calculation and rendering for
- * SCI32 games. The text calculation system in SCI32 is
- * nearly the same as SCI16, which means this class behaves
- * similarly. Notably, GfxText32 maintains drawing
- * parameters across multiple calls.
+ * This class handles text calculation and rendering for SCI32 games. The text
+ * calculation system in SCI32 is nearly the same as SCI16, which means this
+ * class behaves similarly. Notably, GfxText32 maintains drawing parameters
+ * across multiple calls, instead of requiring all text parameters to be
+ * provided on every draw call.
  */
 class GfxText32 {
 private:
@@ -57,10 +57,10 @@ private:
 	GfxCache *_cache;
 
 	/**
-	 * The width and height of the currently active text
-	 * bitmap, in text-system coordinates.
+	 * The width and height of the currently active text bitmap, in text-system
+	 * coordinates.
 	 *
-	 * @note These are unsigned in the actual engine.
+	 * @note These are unsigned in SSCI.
 	 */
 	int16 _width, _height;
 
@@ -75,20 +75,19 @@ private:
 	uint8 _backColor;
 
 	/**
-	 * The transparent color of the text box. Used when
-	 * compositing the bitmap onto the screen.
+	 * The transparent color of the text box. Used when compositing the bitmap
+	 * onto the screen.
 	 */
 	uint8 _skipColor;
 
 	/**
-	 * The rect where the text is drawn within the bitmap.
-	 * This rect is clipped to the dimensions of the bitmap.
+	 * The rect where the text is drawn within the bitmap. This rect is clipped
+	 * to the dimensions of the bitmap.
 	 */
 	Common::Rect _textRect;
 
 	/**
-	 * The text being drawn to the currently active text
-	 * bitmap.
+	 * The text being drawn to the currently active text bitmap.
 	 */
 	Common::String _text;
 
@@ -103,7 +102,8 @@ private:
 	int16 _borderColor;
 
 	/**
-	 * TODO: Document
+	 * If true, text will be drawn using a dither that draws only every other
+	 * pixel of the text.
 	 */
 	bool _dimmed;
 
@@ -123,19 +123,17 @@ private:
 	void drawText(const uint index, uint length);
 
 	/**
-	 * Gets the length of the longest run of text available
-	 * within the currently loaded text, starting from the
-	 * given `charIndex` and running for up to `maxWidth`
-	 * pixels. Returns the number of characters that can be
-	 * written, and mutates the value pointed to by
-	 * `charIndex` to point to the index of the next
-	 * character to render.
+	 * Gets the length of the longest run of text available within the currently
+	 * loaded text, starting from the given `charIndex` and running for up to
+	 * `maxWidth` pixels. Returns the number of characters that can be written,
+	 * and mutates the value pointed to by `charIndex` to point to the index of
+	 * the next character to render.
 	 */
 	uint getLongest(uint *charIndex, const int16 maxWidth);
 
 	/**
-	 * Gets the pixel width of a substring of the currently
-	 * loaded text, without scaling.
+	 * Gets the pixel width of a substring of the currently loaded text, without
+	 * scaling.
 	 */
 	int16 getTextWidth(const uint index, uint length) const;
 
@@ -163,29 +161,27 @@ public:
 	reg_t _bitmap;
 
 	/**
-	 * The size of the x-dimension of the coordinate system
-	 * used by the text renderer. Static since it was global in SSCI.
+	 * The size of the x-dimension of the coordinate system used by the text
+	 * renderer. Static since it was global in SSCI.
 	 */
 	static int16 _xResolution;
 
 	/**
-	 * The size of the y-dimension of the coordinate system
-	 * used by the text renderer. Static since it was global in SSCI.
+	 * The size of the y-dimension of the coordinate system used by the text
+	 * renderer. Static since it was global in SSCI.
 	 */
 	static int16 _yResolution;
 
 	/**
-	 * The currently active font resource used to write text
-	 * into the bitmap.
+	 * The currently active font resource used to write text into the bitmap.
 	 *
-	 * @note SCI engine builds the font table directly
-	 * inside of FontMgr; we use GfxFont instead.
+	 * @note SSCI builds the font table directly inside of FontMgr; we use
+	 * GfxFont instead.
 	 */
 	GfxFont *_font;
 
 	/**
-	 * Creates a plain font bitmap with a flat color
-	 * background.
+	 * Creates a plain font bitmap with a flat color background.
 	 */
 	reg_t createFontBitmap(int16 width, int16 height, const Common::Rect &rect, const Common::String &text, const uint8 foreColor, const uint8 backColor, const uint8 skipColor, const GuiResourceId fontId, TextAlign alignment, const int16 borderColor, bool dimmed, const bool doScaling, const bool gc);
 
@@ -212,26 +208,22 @@ public:
 	/**
 	 * Draws the given text to the bitmap.
 	 *
-	 * @note The original engine holds a reference to a
-	 * shared string which lets the text be updated from
-	 * outside of the font manager. Instead, we give this
-	 * extra signature to send the text to draw.
-	 *
-	 * TODO: Use shared string instead?
+	 * @note SSCI holds a reference to a shared string which lets the text be
+	 * updated from outside of the font manager. Instead, we use this extra
+	 * signature to send the text to draw.
 	 */
 	void drawTextBox(const Common::String &text);
 
 	/**
-	 * Erases the given rect by filling with the background
-	 * color.
+	 * Erases the given rect by filling with the background color.
 	 */
 	void erase(const Common::Rect &rect, const bool doScaling);
 
 	void invertRect(const reg_t bitmap, const int16 bitmapStride, const Common::Rect &rect, const uint8 foreColor, const uint8 backColor, const bool doScaling);
 
 	/**
-	 * Sets the font to be used for rendering and
-	 * calculation of text dimensions.
+	 * Sets the font to be used for rendering and calculation of text
+	 * dimensions.
 	 */
 	void setFont(const GuiResourceId fontId);
 
@@ -251,8 +243,8 @@ public:
 	Common::Rect getTextSize(const Common::String &text, const int16 maxWidth, bool doScaling);
 
 	/**
-	 * Gets the pixel width of a substring of the currently
-	 * loaded text, with scaling.
+	 * Gets the pixel width of a substring of the currently loaded text, with
+	 * scaling.
 	 */
 	int16 getTextWidth(const Common::String &text, const uint index, const uint length);
 
@@ -262,23 +254,21 @@ public:
 	int16 getStringWidth(const Common::String &text);
 
 	/**
-	 * Gets the number of characters of `text`, starting
-	 * from `index`, that can be safely rendered into
-	 * `textRect`.
+	 * Gets the number of characters of `text`, starting from `index`, that can
+	 * be safely rendered into `textRect`.
 	 */
 	int16 getTextCount(const Common::String &text, const uint index, const Common::Rect &textRect, const bool doScaling);
 
 	/**
-	 * Gets the number of characters of `text`, starting
-	 * from `index`, that can be safely rendered into
-	 * `textRect` using the given font.
+	 * Gets the number of characters of `text`, starting from `index`, that can
+	 * be safely rendered into `textRect` using the given font.
 	 */
 	int16 getTextCount(const Common::String &text, const uint index, const GuiResourceId fontId, const Common::Rect &textRect, const bool doScaling);
 
 	/**
 	 * Scroll up/down one line. `numLines` is the number of the lines in the
-	 * textarea, and `textLine` contains the text to draw as the newly
-	 * visible line. Originally FontMgr::DrawOneLine and FontMgr::UpOneLine.
+	 * textarea, and `textLine` contains the text to draw as the newly visible
+	 * line. Originally FontMgr::DrawOneLine and FontMgr::UpOneLine.
 	 */
 	void scrollLine(const Common::String &textLine, int numLines, uint8 color, TextAlign align, GuiResourceId fontId, ScrollDirection dir);
 };


Commit: 1b4214695566ccadbe27806f646bed3c4c944809
    https://github.com/scummvm/scummvm/commit/1b4214695566ccadbe27806f646bed3c4c944809
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:11:03-05:00

Commit Message:
SCI32: Clean up GfxRemap32

* Rewrap comments to 80 columns
* Clarify comments where possible

Changed paths:
    engines/sci/engine/kgraphics32.cpp
    engines/sci/graphics/remap32.cpp
    engines/sci/graphics/remap32.h


diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp
index 1734221..02b2cea 100644
--- a/engines/sci/engine/kgraphics32.cpp
+++ b/engines/sci/engine/kgraphics32.cpp
@@ -1057,9 +1057,9 @@ reg_t kRemapColorsByRange(EngineState *s, int argc, reg_t *argv) {
 	const int16 from = argv[1].toSint16();
 	const int16 to = argv[2].toSint16();
 	const int16 base = argv[3].toSint16();
-	// NOTE: There is an optional last parameter after `base`
-	// which was only used by the priority map debugger, which
-	// does not exist in release versions of SSCI
+	// There is an optional last parameter after `base` which was only used by
+	// the priority map debugger which does not exist in release versions of
+	// SSCI
 	g_sci->_gfxRemap32->remapByRange(color, from, to, base);
 	return s->r_acc;
 }
@@ -1067,9 +1067,9 @@ reg_t kRemapColorsByRange(EngineState *s, int argc, reg_t *argv) {
 reg_t kRemapColorsByPercent(EngineState *s, int argc, reg_t *argv) {
 	const uint8 color = argv[0].toUint16();
 	const int16 percent = argv[1].toSint16();
-	// NOTE: There is an optional last parameter after `percent`
-	// which was only used by the priority map debugger, which
-	// does not exist in release versions of SSCI
+	// There is an optional last parameter after `percent` which was only used
+	// by the priority map debugger, which does not exist in release versions of
+	// SSCI
 	g_sci->_gfxRemap32->remapByPercent(color, percent);
 	return s->r_acc;
 }
@@ -1077,9 +1077,9 @@ reg_t kRemapColorsByPercent(EngineState *s, int argc, reg_t *argv) {
 reg_t kRemapColorsToGray(EngineState *s, int argc, reg_t *argv) {
 	const uint8 color = argv[0].toUint16();
 	const int16 gray = argv[1].toSint16();
-	// NOTE: There is an optional last parameter after `gray`
-	// which was only used by the priority map debugger, which
-	// does not exist in release versions of SSCI
+	// There is an optional last parameter after `gray` which was only used by
+	// the priority map debugger, which does not exist in release versions of
+	// SSCI
 	g_sci->_gfxRemap32->remapToGray(color, gray);
 	return s->r_acc;
 }
@@ -1088,9 +1088,9 @@ reg_t kRemapColorsToPercentGray(EngineState *s, int argc, reg_t *argv) {
 	const uint8 color = argv[0].toUint16();
 	const int16 gray = argv[1].toSint16();
 	const int16 percent = argv[2].toSint16();
-	// NOTE: There is an optional last parameter after `percent`
-	// which was only used by the priority map debugger, which
-	// does not exist in release versions of SSCI
+	// There is an optional last parameter after `percent` which was only used
+	// by the priority map debugger, which does not exist in release versions of
+	// SSCI
 	g_sci->_gfxRemap32->remapToPercentGray(color, gray, percent);
 	return s->r_acc;
 }
diff --git a/engines/sci/graphics/remap32.cpp b/engines/sci/graphics/remap32.cpp
index 9b5ffcd..6fe0a53 100644
--- a/engines/sci/graphics/remap32.cpp
+++ b/engines/sci/graphics/remap32.cpp
@@ -100,9 +100,9 @@ bool SingleRemap::updateBrightness() {
 		}
 
 		if (_percent != _lastPercent || _originalColorsChanged[i]) {
-			// NOTE: SSCI checked if percent was over 100 and only
-			// then clipped values, but we always unconditionally
-			// ensure the result is in the correct range
+			// SSCI checked if percent was over 100 and only then clipped
+			// values, but we always unconditionally ensure the result is in the
+			// correct range for simplicity's sake
 			color.r = MIN(255, (uint16)color.r * _percent / 100);
 			color.g = MIN(255, (uint16)color.g * _percent / 100);
 			color.b = MIN(255, (uint16)color.b * _percent / 100);
@@ -188,8 +188,7 @@ bool SingleRemap::apply() {
 	const GfxRemap32 *const gfxRemap32 = g_sci->_gfxRemap32;
 	const uint8 remapStartColor = gfxRemap32->getStartColor();
 
-	// Blocked colors are not allowed to be used as target
-	// colors for the remap
+	// Blocked colors are not allowed to be used as target colors for the remap
 	bool blockedColors[236];
 	Common::fill(blockedColors, blockedColors + remapStartColor, false);
 
@@ -207,9 +206,8 @@ bool SingleRemap::apply() {
 		}
 	}
 
-	// NOTE: SSCI did a loop over colors here to create a
-	// new array of updated, unblocked colors, but then
-	// never used it
+	// SSCI did a loop over colors here to create a new array of updated,
+	// unblocked colors, but then never used it
 
 	bool updated = false;
 	for (uint i = 1; i < remapStartColor; ++i) {
@@ -280,8 +278,8 @@ int16 SingleRemap::matchColor(const Color &color, const int minimumDistance, int
 		bestIndex = i;
 	}
 
-	// This value is only valid if the last index to
-	// perform a distance calculation was the best index
+	// This value is only valid if the last index to perform a distance
+	// calculation was the best index
 	outDistance = distance;
 	return bestIndex;
 }
@@ -295,10 +293,9 @@ GfxRemap32::GfxRemap32() :
 	_blockedRangeCount(0),
 	_remapStartColor(236),
 	_numActiveRemaps(0) {
-	// The `_remapStartColor` seems to always be 236 in SSCI,
-	// but if it is ever changed then the various C-style
-	// member arrays hard-coded to 236 need to be changed to
-	// match the highest possible value of `_remapStartColor`
+	// The `_remapStartColor` seems to always be 236 in SSCI, but if it is ever
+	// changed then the various C-style member arrays hard-coded to 236 need to
+	// be changed to match the highest possible value of `_remapStartColor`
 	assert(_remapStartColor == 236);
 
 	if (g_sci->_features->hasMidPaletteCode()) {
@@ -316,9 +313,8 @@ void GfxRemap32::remapOff(const uint8 color) {
 		return;
 	}
 
-	// NOTE: SSCI simply ignored invalid input values, but
-	// we at least give a warning so games can be investigated
-	// for script bugs
+	// SSCI simply ignored invalid input values, but we at least give a warning
+	// so games can be investigated for script bugs
 	if (color < _remapStartColor || color > _remapEndColor) {
 		warning("GfxRemap32::remapOff: %d out of remap range", color);
 		return;
@@ -341,9 +337,8 @@ void GfxRemap32::remapAllOff() {
 }
 
 void GfxRemap32::remapByRange(const uint8 color, const int16 from, const int16 to, const int16 delta) {
-	// NOTE: SSCI simply ignored invalid input values, but
-	// we at least give a warning so games can be investigated
-	// for script bugs
+	// SSCI simply ignored invalid input values, but we at least give a warning
+	// so games can be investigated for script bugs
 	if (color < _remapStartColor || color > _remapEndColor) {
 		warning("GfxRemap32::remapByRange: %d out of remap range", color);
 		return;
@@ -375,9 +370,8 @@ void GfxRemap32::remapByRange(const uint8 color, const int16 from, const int16 t
 }
 
 void GfxRemap32::remapByPercent(const uint8 color, const int16 percent) {
-	// NOTE: SSCI simply ignored invalid input values, but
-	// we at least give a warning so games can be investigated
-	// for script bugs
+	// SSCI simply ignored invalid input values, but we at least give a warning
+	// so games can be investigated for script bugs
 	if (color < _remapStartColor || color > _remapEndColor) {
 		warning("GfxRemap32::remapByPercent: %d out of remap range", color);
 		return;
@@ -397,9 +391,8 @@ void GfxRemap32::remapByPercent(const uint8 color, const int16 percent) {
 }
 
 void GfxRemap32::remapToGray(const uint8 color, const int8 gray) {
-	// NOTE: SSCI simply ignored invalid input values, but
-	// we at least give a warning so games can be investigated
-	// for script bugs
+	// SSCI simply ignored invalid input values, but we at least give a warning
+	// so games can be investigated for script bugs
 	if (color < _remapStartColor || color > _remapEndColor) {
 		warning("GfxRemap32::remapToGray: %d out of remap range", color);
 		return;
@@ -423,9 +416,8 @@ void GfxRemap32::remapToGray(const uint8 color, const int8 gray) {
 }
 
 void GfxRemap32::remapToPercentGray(const uint8 color, const int16 gray, const int16 percent) {
-	// NOTE: SSCI simply ignored invalid input values, but
-	// we at least give a warning so games can be investigated
-	// for script bugs
+	// SSCI simply ignored invalid input values, but we at least give a warning
+	// so games can be investigated for script bugs
 	if (color < _remapStartColor || color > _remapEndColor) {
 		warning("GfxRemap32::remapToPercentGray: %d out of remap range", color);
 		return;
diff --git a/engines/sci/graphics/remap32.h b/engines/sci/graphics/remap32.h
index 407e879..9fc7ef6 100644
--- a/engines/sci/graphics/remap32.h
+++ b/engines/sci/graphics/remap32.h
@@ -55,8 +55,7 @@ public:
 	RemapType _type;
 
 	/**
-	 * The first color that should be shifted by a range
-	 * remap.
+	 * The first color that should be shifted by a range remap.
 	 */
 	uint8 _from;
 
@@ -66,158 +65,140 @@ public:
 	uint8 _to;
 
 	/**
-	 * The direction and amount that the colors should be
-	 * shifted in a range remap.
+	 * The direction and amount that the colors should be shifted in a range
+	 * remap.
 	 */
 	int16 _delta;
 
 	/**
-	 * The difference in brightness that should be
-	 * applied by a brightness (percent) remap.
+	 * The difference in brightness that should be applied by a brightness
+	 * (percent) remap.
 	 *
-	 * This value may be be greater than 100, in
-	 * which case the color will be oversaturated.
+	 * This value may be be greater than 100, in which case the color will be
+	 * oversaturated.
 	 */
 	int16 _percent;
 
 	/**
-	 * The amount of desaturation that should be
-	 * applied by a saturation (gray) remap, where
-	 * 0 is full saturation and 100 is full
-	 * desaturation.
+	 * The amount of desaturation that should be applied by a saturation (gray)
+	 * remap, where 0 is full saturation and 100 is full desaturation.
 	 */
 	uint8 _gray;
 
 	/**
-	 * The final array used by CelObj renderers to composite
-	 * remapped pixels to the screen buffer.
+	 * The final array used by CelObj renderers to composite remapped pixels to
+	 * the screen buffer.
 	 *
 	 * Here is how it works:
 	 *
-	 * The source bitmap being rendered will have pixels
-	 * within the remap range (236-245 or 236-254), and the
-	 * target buffer will have colors in the non-remapped
-	 * range (0-235).
+	 * The source bitmap being rendered will have pixels within the remap range
+	 * (236-245 or 236-254), and the target buffer will have colors in the
+	 * non-remapped range (0-235).
 	 *
-	 * To arrive at the correct color, first the source
-	 * pixel is used to look up the correct SingleRemap for
-	 * that pixel. Then, the final composited color is
-	 * looked up in this array using the target's pixel
-	 * color. In other words,
+	 * To arrive at the correct color, first the source pixel is used to look up
+	 * the correct SingleRemap for that pixel. Then, the final composited color
+	 * is looked up in this array using the target's pixel color. In other
+	 * words,
 	 * `target = _remaps[remapEndColor - source].remapColors[target]`.
 	 */
 	uint8 _remapColors[236];
 
 	/**
-	 * Resets this SingleRemap's color information to
-	 * default values.
+	 * Resets this SingleRemap's color information to default values.
 	 */
 	void reset();
 
 	/**
-	 * Recalculates and reapplies remap colors to the
-	 * `_remapColors` array.
+	 * Recalculates and reapplies remap colors to the `_remapColors` array.
 	 */
 	bool update();
 
 private:
 	/**
-	 * The previous brightness value. Used to
-	 * determine whether or not targetColors needs
-	 * to be updated.
+	 * The previous brightness value. Used to determine whether or not
+	 * `_idealColors` needs to be updated.
 	 */
 	int16 _lastPercent;
 
 	/**
-	 * The previous saturation value. Used to
-	 * determine whether or not targetColors needs
-	 * to be updated.
+	 * The previous saturation value. Used to determine whether or not
+	 * `_idealColors` needs to be updated.
 	 */
 	uint8 _lastGray;
 
 	/**
-	 * The colors from the current GfxPalette32 palette
-	 * before this SingleRemap is applied.
+	 * The colors from the current GfxPalette32 palette before this SingleRemap
+	 * is applied.
 	 */
 	Color _originalColors[236];
 
 	/**
-	 * Map of colors that changed in `_originalColors`
-	 * when this SingleRemap was updated. This map is
-	 * transient and gets reset to `false` after the
+	 * Map of colors that changed in `_originalColors` when this SingleRemap was
+	 * updated. This map is transient and gets reset to `false` after the
 	 * SingleRemap finishes updating.
 	 */
 	bool _originalColorsChanged[236];
 
 	/**
-	 * The ideal target RGB color values for each generated
-	 * remap color.
+	 * The ideal target RGB color values for each generated remap color.
 	 */
 	Color _idealColors[236];
 
 	/**
-	 * Map of colors that changed in `_idealColors` when
-	 * this SingleRemap was updated. This map is transient
-	 * and gets reset to `false` after the SingleRemap
-	 * finishes applying.
+	 * Map of colors that changed in `_idealColors` when this SingleRemap was
+	 * updated. This map is transient and gets reset to `false` after the
+	 * SingleRemap finishes applying.
 	 */
 	bool _idealColorsChanged[236];
 
 	/**
-	 * When applying a SingleRemap, finding an appropriate
-	 * color in the palette is the responsibility of a
-	 * distance function. Once a match is found, the
-	 * distance of that match is stored here so that the
-	 * next time the SingleRemap is applied, it can check
-	 * the distance from the previous application and avoid
-	 * triggering an expensive redraw of the entire screen
+	 * When applying a SingleRemap, finding an appropriate color in the palette
+	 * is the responsibility of a distance function. Once a match is found, the
+	 * distance of that match is stored here so that the next time the
+	 * SingleRemap is applied, it can check the distance from the previous
+	 * application and avoid triggering an expensive redraw of the entire screen
 	 * if the new palette value only changed slightly.
 	 */
 	int _matchDistances[236];
 
 	/**
-	 * Computes the final target values for a range remap
-	 * and applies them directly to the `_remaps` map.
+	 * Computes the final target values for a range remap and applies them
+	 * directly to the `_remaps` map.
 	 *
 	 * @note Was ByRange in SSCI.
 	 */
 	bool updateRange();
 
 	/**
-	 * Computes the intermediate target values for a
-	 * brightness remap and applies them indirectly via
-	 * the `apply` method.
+	 * Computes the intermediate target values for a brightness remap and
+	 * applies them indirectly via the `apply` method.
 	 *
 	 * @note Was ByPercent in SSCI.
 	 */
 	bool updateBrightness();
 
 	/**
-	 * Computes the intermediate target values for a
-	 * saturation remap and applies them indirectly via
-	 * the `apply` method.
+	 * Computes the intermediate target values for a saturation remap and
+	 * applies them indirectly via the `apply` method.
 	 *
 	 * @note Was ToGray in SSCI.
 	 */
 	bool updateSaturation();
 
 	/**
-	 * Computes the intermediate target values for a
-	 * saturation + brightness bitmap and applies them
-	 * indirectly via the `apply` method.
+	 * Computes the intermediate target values for a saturation + brightness
+	 * bitmap and applies them indirectly via the `apply` method.
 	 *
 	 * @note Was ToPercentGray in SSCI.
 	 */
 	bool updateSaturationAndBrightness();
 
 	/**
-	 * Computes and applies the final values to the
-	 * `_remaps` map.
+	 * Computes and applies the final values to the `_remaps` map.
 	 *
-	 * @note In SSCI, a boolean array of changed values
-	 * was passed into this method, but this was done by
-	 * creating arrays on the stack in the caller. Instead
-	 * of doing this, we simply add another member property
+	 * @note In SSCI, a boolean array of changed values was passed into this
+	 * method, but this was done by creating arrays on the stack in the caller.
+	 * Instead of doing this, we simply add another member property
 	 * `_idealColorsChanged` and use that instead.
 	 */
 	bool apply();
@@ -225,19 +206,18 @@ private:
 	/**
 	 * Calculates the square distance of two colors.
 	 *
-	 * @note In SSCI this method is Rgb24::Dist, but it is
-	 * only used by SingleRemap.
+	 * @note In SSCI this method is Rgb24::Dist, but it is only used by
+	 * SingleRemap.
 	 */
 	int colorDistance(const Color &a, const Color &b) const;
 
 	/**
-	 * Finds the closest index in the next palette matching
-	 * the given RGB color. Returns -1 if no match can be
-	 * found that is closer than `minimumDistance`.
+	 * Finds the closest index in the next palette matching the given RGB color.
+	 * Returns -1 if no match can be found that is closer than
+	 * `minimumDistance`.
 	 *
-	 * @note In SSCI, this method is SOLPalette::Match, but
-	 * this particular signature is only used by
-	 * SingleRemap.
+	 * @note In SSCI, this method is SOLPalette::Match, but this particular
+	 * signature is only used by SingleRemap.
 	 */
 	int16 matchColor(const Color &color, const int minimumDistance, int &outDistance, const bool *const blockedIndexes) const;
 };
@@ -246,8 +226,7 @@ private:
 #pragma mark GfxRemap32
 
 /**
- * This class provides color remapping support for SCI32
- * games.
+ * This class provides color remapping support for SCI32 games.
  */
 class GfxRemap32 : public Common::Serializable {
 public:
@@ -262,8 +241,8 @@ public:
 	inline int16 getBlockedRangeCount() const { return _blockedRangeCount; }
 
 	/**
-	 * Turns off remapping of the given color. If `color` is
-	 * 0, all remaps are turned off.
+	 * Turns off remapping of the given color. If `color` is 0, all remaps are
+	 * turned off.
 	 */
 	void remapOff(const uint8 color);
 
@@ -273,55 +252,48 @@ public:
 	void remapAllOff();
 
 	/**
-	 * Configures a SingleRemap for the remap color `color`.
-	 * The SingleRemap will shift palette colors between
-	 * `from` and `to` (inclusive) by `delta` palette
-	 * entries when the remap is applied.
+	 * Configures a SingleRemap for the remap color `color`. The SingleRemap
+	 * will shift palette colors between `from` and `to` (inclusive) by `delta`
+	 * palette entries when the remap is applied.
 	 */
 	void remapByRange(const uint8 color, const int16 from, const int16 to, const int16 delta);
 
 	/**
-	 * Configures a SingleRemap for the remap color `color`
-	 * to modify the brightness of remapped colors by
-	 * `percent`.
+	 * Configures a SingleRemap for the remap color `color` to modify the
+	 * brightness of remapped colors by `percent`.
 	 */
 	void remapByPercent(const uint8 color, const int16 percent);
 
 	/**
-	 * Configures a SingleRemap for the remap color `color`
-	 * to modify the saturation of remapped colors by
-	 * `gray`.
+	 * Configures a SingleRemap for the remap color `color` to modify the
+	 * saturation of remapped colors by `gray`.
 	 */
 	void remapToGray(const uint8 color, const int8 gray);
 
 	/**
-	 * Configures a SingleRemap for the remap color `color`
-	 * to modify the brightness of remapped colors by
-	 * `percent`, and saturation of remapped colors by
-	 * `gray`.
+	 * Configures a SingleRemap for the remap color `color` to modify the
+	 * brightness of remapped colors by `percent`, and saturation of remapped
+	 * colors by `gray`.
 	 */
 	void remapToPercentGray(const uint8 color, const int16 gray, const int16 percent);
 
 	/**
-	 * Prevents GfxRemap32 from using the given range of
-	 * palette entries as potential remap targets.
+	 * Prevents GfxRemap32 from using the given range of palette entries as
+	 * potential remap targets.
 	 *
 	 * @NOTE Was DontMapToRange in SSCI.
 	 */
 	void blockRange(const uint8 from, const int16 count);
 
 	/**
-	 * Determines whether or not the given color has an
-	 * active remapper. If it does not, it is treated as a
-	 * skip color and the pixel is not drawn.
+	 * Determines whether or not the given color has an active remapper. If it
+	 * does not, it is treated as a skip color and the pixel is not drawn.
 	 *
-	 * @note SSCI uses a boolean array to decide whether a
-	 * a pixel is remapped, but it is possible to get the
-	 * same information from `_remaps`, as this function
-	 * does.
-	 * Presumably, the separate array was created for
-	 * performance reasons, since this is called a lot in
-	 * the most critical section of the renderer.
+	 * @note SSCI uses a boolean array to decide whether a pixel is remapped,
+	 * but it is possible to get the same information from `_remaps`, as this
+	 * function does. Presumably, the separate array was created for performance
+	 * reasons, since this is called a lot in the most critical section of the
+	 * renderer.
 	 */
 	inline bool remapEnabled(uint8 color) const {
 		const uint8 index = _remapEndColor - color;
@@ -335,10 +307,9 @@ public:
 	}
 
 	/**
-	 * Calculates the correct color for a target by looking
-	 * up the target color in the SingleRemap that controls
-	 * the given sourceColor. If there is no remap for the
-	 * given color, it will be treated as a skip color.
+	 * Calculates the correct color for a target by looking up the target color
+	 * in the SingleRemap that controls the given sourceColor. If there is no
+	 * remap for the given color, it will be treated as a skip color.
 	 */
 	inline uint8 remapColor(const uint8 sourceColor, const uint8 targetColor) const {
 		const uint8 index = _remapEndColor - sourceColor;
@@ -358,12 +329,11 @@ public:
 	}
 
 	/**
-	 * Updates all active remaps in response to a palette
-	 * change or a remap settings change.
+	 * Updates all active remaps in response to a palette change or a remap
+	 * settings change.
 	 *
-	 * `paletteChanged` is true if the next palette in
-	 * GfxPalette32 has been previously modified by other
-	 * palette operations.
+	 * `paletteChanged` is true if the next palette in GfxPalette32 has been
+	 * previously modified by other palette operations.
 	 */
 	bool remapAllTables(const bool paletteUpdated);
 
@@ -371,14 +341,12 @@ private:
 	typedef Common::Array<SingleRemap> SingleRemapsList;
 
 	/**
-	 * The first index of the remap area in the system
-	 * palette.
+	 * The first index of the remap area in the system palette.
 	 */
 	const uint8 _remapStartColor;
 
 	/**
-	 * The last index of the remap area in the system
-	 * palette.
+	 * The last index of the remap area in the system palette.
 	 */
 	uint8 _remapEndColor;
 
@@ -393,20 +361,19 @@ private:
 	SingleRemapsList _remaps;
 
 	/**
-	 * If true, indicates that one or more SingleRemaps were
-	 * reconfigured and all remaps need to be recalculated.
+	 * If true, indicates that one or more SingleRemaps were reconfigured and
+	 * all remaps need to be recalculated.
 	 */
 	bool _needsUpdate;
 
 	/**
-	 * The first color that is blocked from being used as a
-	 * remap target color.
+	 * The first color that is blocked from being used as a remap target color.
 	 */
 	uint8 _blockedRangeStart;
 
 	/**
-	 * The size of the range of blocked colors. If zero,
-	 * all colors are potential targets for remapping.
+	 * The size of the range of blocked colors. If zero, all colors are
+	 * potential targets for remapping.
 	 */
 	int16 _blockedRangeCount;
 };


Commit: 31e1d0932cf4cdba7fdb1d1eec6e349fcc3c0ac0
    https://github.com/scummvm/scummvm/commit/31e1d0932cf4cdba7fdb1d1eec6e349fcc3c0ac0
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:11:03-05:00

Commit Message:
SCI32: Clean up Plane

* Rewrap comments to 80 columns
* Clarify comments where possible

Changed paths:
    engines/sci/engine/features.h
    engines/sci/graphics/plane32.cpp
    engines/sci/graphics/plane32.h


diff --git a/engines/sci/engine/features.h b/engines/sci/engine/features.h
index 92cc45a..7a1c6f5 100644
--- a/engines/sci/engine/features.h
+++ b/engines/sci/engine/features.h
@@ -128,7 +128,7 @@ public:
 	inline bool hasTransparentPicturePlanes() const {
 		const SciGameId &gid = g_sci->getGameId();
 
-		// NOTE: MGDX is assumed to not have transparent picture planes since it
+		// MGDX is assumed to not have transparent picture planes since it
 		// was released before SQ6, but this has not been verified since it
 		// cannot be disassembled at the moment (Phar Lap Windows-only release)
 		return getSciVersion() >= SCI_VERSION_2_1_MIDDLE &&
diff --git a/engines/sci/graphics/plane32.cpp b/engines/sci/graphics/plane32.cpp
index 08708f2..77ca620 100644
--- a/engines/sci/graphics/plane32.cpp
+++ b/engines/sci/graphics/plane32.cpp
@@ -320,9 +320,9 @@ void Plane::calcLists(Plane &visiblePlane, const PlaneList &planeList, DrawList
 
 	for (ScreenItemList::size_type i = 0; i < screenItemCount; ++i) {
 		// Items can be added to ScreenItemList and we don't want to process
-		// those new items, but the list also can grow smaller, so we need
-		// to check that we are still within the upper bound of the list and
-		// quit if we aren't any more
+		// those new items, but the list also can grow smaller, so we need to
+		// check that we are still within the upper bound of the list and quit
+		// if we aren't any more
 		if (i >= _screenItemList.size()) {
 			break;
 		}
@@ -332,18 +332,17 @@ void Plane::calcLists(Plane &visiblePlane, const PlaneList &planeList, DrawList
 			continue;
 		}
 
-		// NOTE: The original engine used an array without bounds checking
-		// so could just get the visible screen item directly; we need to
-		// verify that the index is actually within the valid range for
-		// the visible plane before accessing the item to avoid a range
-		// error.
+		// SSCI used an array without bounds checking so could just get the
+		// visible screen item directly; we need to verify that the index is
+		// actually within the valid range for the visible plane before
+		// accessing the item to avoid a range error.
 		const ScreenItem *visibleItem = nullptr;
 		if (i < visiblePlaneItemCount) {
 			visibleItem = visiblePlane._screenItemList[i];
 		}
 
-		// Keep erase rects for this screen item from drawing outside
-		// of its owner plane
+		// Keep erase rects for this screen item from drawing outside of its
+		// owner plane
 		Common::Rect visibleItemScreenRect;
 		if (visibleItem != nullptr) {
 			visibleItemScreenRect = visibleItem->_screenRect;
@@ -427,8 +426,8 @@ void Plane::calcLists(Plane &visiblePlane, const PlaneList &planeList, DrawList
 	breakEraseListByPlanes(eraseList, planeList);
 	breakDrawListByPlanes(drawList, planeList);
 
-	// We store the current size of the drawlist, as we want to loop
-	// over the currently inserted entries later.
+	// The current size of the draw list is stored here, as we need to loop over
+	// only the already-inserted entries later.
 	DrawList::size_type drawListSizePrimary = drawList.size();
 	const RectList::size_type eraseListCount = eraseList.size();
 
@@ -823,8 +822,8 @@ void Plane::sync(const Plane *other, const Common::Rect &screenRect) {
 
 	convertGameRectToPlaneRect();
 	_screenRect = _planeRect;
-	// NOTE: screenRect originally was retrieved through globals
-	// instead of being passed into the function
+	// screenRect was retrieved through globals in SSCI instead of being passed
+	// into the function. We don't do that just to avoid the extra indirection
 	clipScreenRect(screenRect);
 }
 
diff --git a/engines/sci/graphics/plane32.h b/engines/sci/graphics/plane32.h
index a34df1c..406c3f8 100644
--- a/engines/sci/graphics/plane32.h
+++ b/engines/sci/graphics/plane32.h
@@ -40,8 +40,7 @@ enum PlaneType {
 };
 
 enum PlanePictureCodes {
-	// NOTE: Any value at or below 65531 means the plane
-	// is a kPlaneTypePicture.
+	// Any value at or below 65531 means the plane is a kPlaneTypePicture
 	kPlanePic                   = 65531,
 	kPlanePicTransparentPicture = 65532,
 	kPlanePicOpaque             = 65533,
@@ -104,61 +103,52 @@ class PlaneList;
 class Plane {
 private:
 	/**
-	 * A serial used for planes that are generated inside
-	 * the graphics engine, rather than the interpreter.
+	 * A serial used for planes that are generated inside the graphics engine,
+	 * rather than the interpreter.
 	 */
 	static uint16 _nextObjectId;
 
 	/**
-	 * A serial used to identify the creation order of
-	 * planes, to ensure a stable sort order for planes
-	 * with identical priorities.
+	 * A serial used to identify the creation order of planes, to ensure a
+	 * stable sort order for planes with identical priorities.
 	 */
 	static uint32 _nextCreationId;
 
 	/**
-	 * The creation order number, which ensures a stable
-	 * sort when planes with identical priorities are added
-	 * to the plane list.
+	 * The creation order number, which ensures a stable sort when planes with
+	 * identical priorities are added to the plane list.
 	 */
 	uint32 _creationId;
 
 	/**
-	 * For planes that are used to render picture data, the
-	 * resource ID of the picture to be displayed. This
-	 * value may also be one of the special
-	 * PlanePictureCodes, in which case the plane becomes a
-	 * non-picture plane.
+	 * For planes that are used to render picture data, the resource ID of the
+	 * picture to be displayed. This value may also be one of the special
+	 * PlanePictureCodes, in which case the plane becomes a non-picture plane.
 	 */
 	GuiResourceId _pictureId;
 
 	/**
-	 * Whether or not the contents of picture planes should
-	 * be drawn horizontally mirrored. Only applies to
-	 * planes of type kPlaneTypePicture.
+	 * Whether or not the contents of picture planes should be drawn
+	 * horizontally mirrored. Only applies to planes of type kPlaneTypePicture.
 	 */
 	bool _mirrored;
 
 	/**
-	 * Whether the picture ID for this plane has changed.
-	 * This flag is set when the plane is created or updated
-	 * from a VM object, and is cleared when the plane is
-	 * synchronised to another plane (which calls
-	 * changePic).
+	 * Whether the picture ID for this plane has changed. This flag is set when
+	 * the plane is created or updated from a VM object, and is cleared when the
+	 * plane is synchronised to another plane (which calls changePic).
 	 */
 	bool _pictureChanged;
 
 	/**
-	 * Converts the dimensions of the game rect used by
-	 * scripts to the dimensions of the plane rect used to
-	 * render content to the screen. Coordinates with
-	 * remainders are rounded up to the next whole pixel.
+	 * Converts the dimensions of the game rect used by scripts to the
+	 * dimensions of the plane rect used to render content to the screen.
+	 * Coordinates with remainders are rounded up to the next whole pixel.
 	 */
 	void convertGameRectToPlaneRect();
 
 	/**
-	 * Sets the type of the plane according to its assigned
-	 * picture resource ID.
+	 * Sets the type of the plane according to its assigned picture resource ID.
 	 */
 	void setType();
 
@@ -169,80 +159,73 @@ public:
 	PlaneType _type;
 
 	/**
-	 * The color to use when erasing the plane. Only
-	 * applies to planes of type kPlaneTypeColored.
+	 * The color to use when erasing the plane. Only applies to planes of type
+	 * kPlaneTypeColored.
 	 */
 	byte _back;
 
 	/**
-	 * Whether the priority of this plane has changed.
-	 * This flag is set when the plane is updated from
-	 * another plane and cleared when draw list calculation
-	 * occurs.
+	 * Whether the priority of this plane has changed. This flag is set when the
+	 * plane is updated from another plane and cleared when draw list
+	 * calculation occurs.
 	 */
 	int _priorityChanged;
 
 	/**
-	 * A handle to the VM object corresponding to this
-	 * plane. Some planes are generated purely within the
-	 * graphics engine and have a numeric object value.
+	 * A handle to the VM object corresponding to this plane. Some planes are
+	 * generated purely within the graphics engine and have a numeric object
+	 * value.
 	 */
 	reg_t _object;
 
 	/**
-	 * The rendering priority of the plane. Higher
-	 * priorities are drawn above lower priorities.
+	 * The rendering priority of the plane. Higher priorities are drawn above
+	 * lower priorities.
 	 */
 	int16 _priority;
 
 	/**
-	 * Whether or not all screen items in this plane should
-	 * be redrawn on the next frameout, instead of just
-	 * the screen items marked as updated. This is set when
-	 * visual changes to the plane itself are made that
-	 * affect the rendering of the entire plane, and cleared
-	 * once those changes are rendered by `redrawAll`.
+	 * Whether or not all screen items in this plane should be redrawn on the
+	 * next frameout, instead of just the screen items marked as updated. This
+	 * is set when visual changes to the plane itself are made that affect the
+	 * rendering of the entire plane, and cleared once those changes are
+	 * rendered by `redrawAll`.
 	 */
 	int _redrawAllCount;
 
 	/**
 	 * Flags indicating the state of the plane.
-	 * - `created` is set when the plane is first created,
-	 *   either from a VM object or from within the engine
-	 *   itself
-	 * - `updated` is set when the plane is updated from
-	 *   another plane and the two planes' `planeRect`s do
-	 *   not match
-	 * - `deleted` is set when the plane is deleted by a
-	 *   kernel call
-	 * - `moved` is set when the plane has been moved or
-	 *   resized
+	 * - `created` is set when the plane is first created, either from a VM
+	 *   object or from within the engine itself
+	 * - `updated` is set when the plane is updated from another plane and the
+	 *   two planes' `planeRect`s do not match
+	 * - `deleted` is set when the plane is deleted by a kernel call
+	 * - `moved` is set when the plane has been moved or resized
 	 */
 	int _created, _updated, _deleted, _moved;
 
 	/**
-	 * The vanishing point for the plane. Used when
-	 * automatically calculating the correct scaling of the
-	 * plane's screen items according to their position.
+	 * The vanishing point for the plane. Used when automatically calculating
+	 * the correct scaling of the plane's screen items according to their
+	 * position.
 	 */
 	Common::Point _vanishingPoint;
 
 	/**
-	 * The position & dimensions of the plane in screen
-	 * coordinates. This rect is not clipped to the screen,
-	 * so may include coordinates that are offscreen.
+	 * The position & dimensions of the plane in screen coordinates. This rect
+	 * is not clipped to the screen, so may include coordinates that are
+	 * offscreen.
 	 */
 	Common::Rect _planeRect;
 
 	/**
-	 * The position & dimensions of the plane in game script
-	 * coordinates.
+	 * The position & dimensions of the plane in game script coordinates.
 	 */
 	Common::Rect _gameRect;
 
 	/**
-	 * The position & dimensions of the plane in screen
-	 * coordinates. This rect is clipped to the screen.
+	 * The position & dimensions of the plane in screen coordinates. This rect
+	 * is clipped to the screen.
 	 */
 	Common::Rect _screenRect;
 
@@ -257,10 +240,10 @@ public:
 	 */
 	static void init();
 
-	// NOTE: This constructor signature originally did not accept a
-	// picture ID, but some calls to construct planes with this signature
-	// immediately set the picture ID and then called setType again, so
-	// it made more sense to just make the picture ID a parameter instead.
+	// In SSCI this constructor signature did not accept a picture ID, but some
+	// calls to construct planes with this signature immediately set the picture
+	// ID and then called setType again, so it made more sense to just make the
+	// picture ID a parameter instead.
 	Plane(const Common::Rect &gameRect, PlanePictureCodes pictureId = kPlanePicColored);
 
 	Plane(const reg_t object);
@@ -284,14 +267,13 @@ public:
 	}
 
 	/**
-	 * Clips the screen rect of this plane to fit within the
-	 * given screen rect.
+	 * Clips the screen rect of this plane to fit within the given screen rect.
 	 */
 	inline void clipScreenRect(const Common::Rect &screenRect) {
-		// LSL6 hires creates planes with invalid rects; SSCI does not
-		// care about this, but `Common::Rect::clip` does, so we need to
-		// check whether or not the rect is actually valid before clipping
-		// and only clip valid rects
+		// LSL6 hires creates planes with invalid rects; SSCI does not care
+		// about this, but `Common::Rect::clip` does, so we need to check
+		// whether or not the rect is actually valid before clipping and only
+		// clip valid rects
 		if (_screenRect.isValidRect() && _screenRect.intersects(screenRect)) {
 			_screenRect.clip(screenRect);
 		} else {
@@ -305,30 +287,25 @@ public:
 	void printDebugInfo(Console *con) const;
 
 	/**
-	 * Compares the properties of the current plane against
-	 * the properties of the `other` plane (which is the
-	 * corresponding plane from the visible plane list) to
-	 * discover which properties have been changed on this
-	 * plane by a call to `update(reg_t)`.
+	 * Compares the properties of the current plane against the properties of
+	 * the `other` plane (which is the corresponding plane from the visible
+	 * plane list) to discover which properties have been changed on this plane
+	 * by a call to `update(reg_t)`.
 	 *
-	 * @note This method was originally called UpdatePlane
-	 * in SCI engine.
+	 * @note This method was called UpdatePlane in SSCI.
 	 */
 	void sync(const Plane *other, const Common::Rect &screenRect);
 
 	/**
-	 * Updates the plane to match the state of the plane
-	 * object from the virtual machine.
+	 * Updates the plane to match the state of the plane object from the VM.
 	 *
-	 * @note This method was originally called UpdatePlane
-	 * in SCI engine.
+	 * @note This method was called UpdatePlane in SSCI.
 	 */
 	void update(const reg_t object);
 
 	/**
-	 * Modifies the position of all non-pic screen items
-	 * by the given delta. If `scrollPics` is true, pic
-	 * items are also repositioned.
+	 * Modifies the position of all non-pic screen items by the given delta. If
+	 * `scrollPics` is true, pic items are also repositioned.
 	 */
 	void scrollScreenItems(const int16 deltaX, const int16 deltaY, const bool scrollPics);
 
@@ -336,47 +313,43 @@ public:
 #pragma mark Plane - Pic
 private:
 	/**
-	 * Adds all cels from the specified picture resource to
-	 * the plane as screen items. If a position is provided,
-	 * the screen items will be given that position;
-	 * otherwise, the default relative positions for each
-	 * cel will be taken from the picture resource data.
+	 * Adds all cels from the specified picture resource to the plane as screen
+	 * items. If a position is provided, the screen items will be given that
+	 * position; otherwise, the default relative positions for each cel will be
+	 * taken from the picture resource data.
 	 */
 	inline void addPicInternal(const GuiResourceId pictureId, const Common::Point *position, const bool mirrorX);
 
 	/**
-	 * Marks all screen items to be deleted that are within
-	 * this plane and match the given picture ID.
+	 * Marks all screen items to be deleted that are within this plane and match
+	 * the given picture ID.
 	 */
 	void deletePic(const GuiResourceId pictureId);
 
 	/**
-	 * Marks all screen items to be deleted that are within
-	 * this plane and are picture cels.
+	 * Marks all screen items to be deleted that are within this plane and are
+	 * picture cels.
 	 */
 	void deleteAllPics();
 
 public:
 	/**
-	 * Marks all existing screen items matching the current
-	 * picture to be deleted, then adds all cels from the
-	 * new picture resource to the plane at the given
-	 * position.
+	 * Marks all existing screen items matching the current picture to be
+	 * deleted, then adds all cels from the new picture resource to the plane at
+	 * the given position.
 	 */
 	GuiResourceId addPic(const GuiResourceId pictureId, const Common::Point &position, const bool mirrorX, const bool deleteDuplicate = true);
 
 	/**
-	 * If the plane is a picture plane, re-adds all cels
-	 * from its picture resource to the plane. Otherwise,
-	 * just clears the _pictureChanged flag.
+	 * If the plane is a picture plane, re-adds all cels from its picture
+	 * resource to the plane. Otherwise, just clears the _pictureChanged flag.
 	 */
 	void changePic();
 
 	/**
-	 * Marks all screen items to be deleted that are within
-	 * this plane and match the given picture ID, then sets
-	 * the picture ID of the plane to the new picture ID
-	 * without adding any screen items.
+	 * Marks all screen items to be deleted that are within this plane and match
+	 * the given picture ID, then sets the picture ID of the plane to the new
+	 * picture ID without adding any screen items.
 	 */
 	void deletePic(const GuiResourceId oldPictureId, const GuiResourceId newPictureId);
 
@@ -384,120 +357,111 @@ public:
 #pragma mark Plane - Rendering
 private:
 	/**
-	 * Splits all rects in the given draw list at the edges
-	 * of all higher-priority, non-transparent, intersecting
-	 * planes.
+	 * Splits all rects in the given draw list at the edges of all
+	 * higher-priority, non-transparent, intersecting planes.
 	 */
 	void breakDrawListByPlanes(DrawList &drawList, const PlaneList &planeList) const;
 
 	/**
-	 * Splits all rects in the given erase list at the
-	 * edges of higher-priority, non-transparent,
-	 * intersecting planes.
+	 * Splits all rects in the given erase list at the edges of higher-priority,
+	 * non-transparent, intersecting planes.
 	 */
 	void breakEraseListByPlanes(RectList &eraseList, const PlaneList &planeList) const;
 
 	/**
-	 * Adds the screen item at `index` into `drawList`,
-	 * ensuring it is only drawn within the bounds of
-	 * `rect`. If an existing draw list entry exists
-	 * for this screen item, it will be modified.
-	 * Otherwise, a new entry will be added.
+	 * Adds the screen item at `index` into `drawList`, ensuring it is only
+	 * drawn within the bounds of `rect`. If an existing draw list entry exists
+	 * for this screen item, it will be modified. Otherwise, a new entry will be
+	 * added.
 	 */
 	void mergeToDrawList(const DrawList::size_type index, const Common::Rect &rect, DrawList &drawList) const;
 
 	/**
-	 * Merges `rect` with an existing rect in `eraseList`,
-	 * if possible. Otherwise, adds the rect as a new entry
-	 * to `eraseList`.
+	 * Merges `rect` with an existing rect in `eraseList`, if possible.
+	 * Otherwise, adds the rect as a new entry to `eraseList`.
 	 */
 	void mergeToRectList(const Common::Rect &rect, RectList &eraseList) const;
 
 public:
 	/**
-	 * Calculates the location and dimensions of dirty rects
-	 * of the screen items in this plane and adds them to
-	 * the given draw and erase lists, and synchronises this
-	 * plane's list of screen items to the given visible
+	 * Calculates the location and dimensions of dirty rects of the screen items
+	 * in this plane and adds them to the given draw and erase lists, and
+	 * synchronises this plane's list of screen items to the given visible
 	 * plane.
 	 */
 	void calcLists(Plane &visiblePlane, const PlaneList &planeList, DrawList &drawList, RectList &eraseList);
 
 	/**
-	 * Synchronises changes to screen items from the current
-	 * plane to the visible plane and deletes screen items
-	 * from the current plane that have been marked as
-	 * deleted. If `forceUpdate` is true, all screen items
-	 * on the visible plane will be updated, even if they
-	 * are not marked as having changed.
+	 * Synchronises changes to screen items from the current plane to the
+	 * visible plane and deletes screen items from the current plane that have
+	 * been marked as deleted. If `forceUpdate` is true, all screen items on the
+	 * visible plane will be updated, even if they are not marked as having
+	 * changed.
 	 */
 	void decrementScreenItemArrayCounts(Plane *visiblePlane, const bool forceUpdate);
 
 	/**
-	 * This method is called from the highest priority plane
-	 * to the lowest priority plane.
+	 * This method is called from the highest priority plane to the lowest
+	 * priority plane.
 	 *
-	 * Adds screen items from this plane to the draw list
-	 * that must be redrawn because they intersect entries
-	 * in the `higherEraseList`.
+	 * Adds screen items from this plane to the draw list that must be redrawn
+	 * because they intersect entries in the `higherEraseList`.
 	 *
-	 * If this plane is opaque, all intersecting erase rects
-	 * in `lowerEraseList` are removed, as they would be
-	 * completely overwritten by the contents of this plane.
+	 * If this plane is opaque, all intersecting erase rects in `lowerEraseList`
+	 * are removed, as they would be completely overwritten by the contents of
+	 * this plane.
 	 *
-	 * If this plane is transparent, erase rects from the
-	 * `lowerEraseList` are added to the erase list for this
-	 * plane, so that lower planes.
+	 * If this plane is transparent, erase rects from the `lowerEraseList` are
+	 * added to the erase list for this plane, so that lower planes.
 	 *
 	 * @param drawList The draw list for this plane.
 	 * @param eraseList The erase list for this plane.
-	 * @param higherEraseList The erase list for a plane
-	 * above this plane.
+	 * @param higherEraseList The erase list for a plane above this plane.
 	 */
 	void filterDownEraseRects(DrawList &drawList, RectList &eraseList, RectList &higherEraseList) const;
 
 	/**
-	 * This method is called from the lowest priority plane
-	 * to the highest priority plane.
+	 * This method is called from the lowest priority plane to the highest
+	 * priority plane.
 	 *
-	 * Adds screen items from this plane to the draw list
-	 * that must be drawn because the lower plane is being
-	 * redrawn and potentially transparent screen items
-	 * from this plane would draw over the lower priority
-	 * plane's screen items.
+	 * Adds screen items from this plane to the draw list that must be drawn
+	 * because the lower plane is being redrawn and potentially transparent
+	 * screen items from this plane would draw over the lower priority plane's
+	 * screen items.
 	 *
 	 * This method applies only to transparent planes.
 	 *
 	 * @param drawList The draw list for this plane.
-	 * @param eraseList The erase list for a plane below
-	 * this plane.
+	 * @param eraseList The erase list for a plane below this plane.
 	 */
 	void filterUpEraseRects(DrawList &drawList, const RectList &lowerEraseList) const;
 
 	/**
-	 * This method is called from the lowest priority plane
-	 * to the highest priority plane.
+	 * This method is called from the lowest priority plane to the highest
+	 * priority plane.
 	 *
-	 * Adds screen items from this plane to the draw list
-	 * that must be drawn because the lower plane is being
-	 * redrawn and potentially transparent screen items
-	 * from this plane would draw over the lower priority
-	 * plane's screen items.
+	 * Adds screen items from this plane to the draw list that must be drawn
+	 * because the lower plane is being redrawn and potentially transparent
+	 * screen items from this plane would draw over the lower priority plane's
+	 * screen items.
 	 *
 	 * This method applies only to transparent planes.
 	 *
 	 * @param drawList The draw list for this plane.
-	 * @param lowerDrawList The draw list for a plane below
-	 * this plane.
+	 * @param lowerDrawList The draw list for a plane below this plane.
 	 */
 	void filterUpDrawRects(DrawList &drawList, const DrawList &lowerDrawList) const;
 
 	/**
-	 * Updates all of the plane's non-deleted screen items
-	 * and adds them to the given draw and erase lists.
+	 * Updates all of the plane's non-deleted screen items and adds them to the
+	 * given draw and erase lists.
 	 */
 	void redrawAll(Plane *visiblePlane, const PlaneList &planeList, DrawList &drawList, RectList &eraseList);
 
+	/**
+	 * Marks all non-deleted remapped screen items within the plane as needing
+	 * to be updated during the next frameout.
+	 */
 	void remapMarkRedraw();
 };
 
@@ -514,10 +478,9 @@ private:
 	using PlaneListBase::push_back;
 
 public:
-	// A method for finding the index of a plane inside a
-	// PlaneList is used because entries in the main plane
-	// list and visible plane list of GfxFrameout are
-	// synchronised by index
+	// A method for finding the index of a plane inside a PlaneList is used
+	// because entries in the main plane list and visible plane list of
+	// GfxFrameout are synchronised by index
 	int findIndexByObject(const reg_t object) const;
 	Plane *findByObject(const reg_t object) const;
 
@@ -527,8 +490,8 @@ public:
 	int16 getTopPlanePriority() const;
 
 	/**
-	 * Gets the priority of the top plane in the plane list
-	 * created by a game script.
+	 * Gets the priority of the top plane in the plane list created by a game
+	 * script.
 	 */
 	int16 getTopSciPlanePriority() const;
 


Commit: 4521e9774af526b945f550c7607cf1b82d649154
    https://github.com/scummvm/scummvm/commit/4521e9774af526b945f550c7607cf1b82d649154
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:11:03-05:00

Commit Message:
SCI32: Clean up GfxPaint32

* Rewrap comments to 80 columns

Changed paths:
    engines/sci/graphics/paint32.cpp


diff --git a/engines/sci/graphics/paint32.cpp b/engines/sci/graphics/paint32.cpp
index 8a63365..f4d9c9f 100644
--- a/engines/sci/graphics/paint32.cpp
+++ b/engines/sci/graphics/paint32.cpp
@@ -42,9 +42,9 @@ reg_t GfxPaint32::kernelAddLine(const reg_t planeObject, const Common::Point &st
 	CelInfo32 celInfo;
 	celInfo.type = kCelTypeMem;
 	celInfo.bitmap = bitmapId;
-	// SSCI stores the line color on `celInfo`, even though
-	// this is not a `kCelTypeColor`, as a hack so that
-	// `kUpdateLine` can get the originally used color
+	// SSCI stores the line color on `celInfo`, even though this is not a
+	// `kCelTypeColor`, as a hack so that `kUpdateLine` can get the originally
+	// used color
 	celInfo.color = color;
 
 	ScreenItem *screenItem = new ScreenItem(planeObject, celInfo, gameRect);
@@ -93,7 +93,8 @@ void GfxPaint32::plotter(int x, int y, int color, void *data) {
 	const uint32 index = bitmapWidth * y + x;
 
 	// Only draw the points in the bitmap, and ignore the rest. SSCI scripts
-	// can draw lines ending outside the visible area (e.g. negative coordinates)
+	// can draw lines ending outside the visible area (e.g. negative
+	// coordinates)
 	if (x >= 0 && x < bitmapWidth && y >= 0 && y < bitmapHeight) {
 		if (properties.solid) {
 			pixels[index] = (uint8)color;


Commit: d5e09a9f68a8032b1e5887e50df96e16fda827be
    https://github.com/scummvm/scummvm/commit/d5e09a9f68a8032b1e5887e50df96e16fda827be
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:56:13-05:00

Commit Message:
SCI32: Rewrap comments to 80 columns in lists32.h

Changed paths:
    engines/sci/graphics/lists32.h


diff --git a/engines/sci/graphics/lists32.h b/engines/sci/graphics/lists32.h
index ff0bc6c..82e9e58 100644
--- a/engines/sci/graphics/lists32.h
+++ b/engines/sci/graphics/lists32.h
@@ -28,13 +28,11 @@
 namespace Sci {
 
 /**
- * StablePointerArray holds pointers in a fixed-size array
- * that maintains position of erased items until `pack` is
- * called. It is used by DrawList, RectList, and
- * ScreenItemList. StablePointerArray takes ownership of
- * all pointers that are passed to it and deletes them when
- * calling `erase` or when destroying the
- * StablePointerArray.
+ * StablePointerArray holds pointers in a fixed-size array that maintains
+ * position of erased items until `pack` is called. It is used by DrawList,
+ * RectList, and ScreenItemList. StablePointerArray takes ownership of all
+ * pointers that are passed to it and deletes them when calling `erase` or when
+ * destroying the StablePointerArray.
  */
 template<class T, uint N>
 class StablePointerArray {


Commit: ac0a83a4249089ecfaf47ea4e9e2505057c2d844
    https://github.com/scummvm/scummvm/commit/ac0a83a4249089ecfaf47ea4e9e2505057c2d844
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:56:24-05:00

Commit Message:
SCI32: Clean up GfxControls32

* Rewrap comments to 80 columns
* Clarify comments where possible
* Fix whitespace errors

Changed paths:
    engines/sci/graphics/controls32.cpp
    engines/sci/graphics/controls32.h


diff --git a/engines/sci/graphics/controls32.cpp b/engines/sci/graphics/controls32.cpp
index 52a9dfa..82b99e6 100644
--- a/engines/sci/graphics/controls32.cpp
+++ b/engines/sci/graphics/controls32.cpp
@@ -43,8 +43,8 @@ GfxControls32::GfxControls32(SegManager *segMan, GfxCache *cache, GfxText32 *tex
 	_gfxText32(text),
 	_overwriteMode(false),
 	_nextCursorFlashTick(0),
-	// SSCI used a memory handle for a ScrollWindow object
-	// as ID. We use a simple numeric handle instead.
+	// SSCI used a memory handle for a ScrollWindow object as ID. We use a
+	// simple numeric handle instead.
 	_nextScrollWindowId(10000) {}
 
 GfxControls32::~GfxControls32() {
@@ -137,27 +137,27 @@ reg_t GfxControls32::kernelEditText(const reg_t controlObject) {
 	ScreenItem *screenItem = new ScreenItem(plane->_object, celInfo, Common::Point(), ScaleInfo());
 	plane->_screenItemList.add(screenItem);
 
-	// frameOut must be called after the screen item is
-	// created, and before it is updated at the end of the
-	// event loop, otherwise it has both created and updated
-	// flags set which crashes the engine (it runs updates
-	// before creations)
+	// frameOut must be called after the screen item is created, and before it
+	// is updated at the end of the event loop, otherwise it has both created
+	// and updated flags set which crashes the engine (updates are handled
+	// before creations, but the screen item is not in the correct state for an
+	// update)
 	g_sci->_gfxFrameout->frameOut(true);
 
 	EventManager *eventManager = g_sci->getEventManager();
 	bool clearTextOnInput = true;
 	bool textChanged = false;
 	for (;;) {
-		// We peek here because the last event needs to be allowed to
-		// dispatch a second time to the normal event handling system.
-		// In the actual engine, the event is always consumed and then
-		// the last event just gets posted back to the event manager for
-		// reprocessing, but instead, we only remove the event from the
-		// queue *after* we have determined it is not a defocusing event
+		// We peek here because the last event needs to be allowed to dispatch a
+		// second time to the normal event handling system. In SSCI, the event
+		// is always consumed and then the last event just gets posted back to
+		// the event manager for reprocessing, but instead, we only remove the
+		// event from the queue *after* we have determined it is not a
+		// defocusing event
 		const SciEvent event = eventManager->getSciEvent(kSciEventAny | kSciEventPeek);
 
 		bool focused = true;
-		// Original engine did not have a QUIT event but we have to handle it
+		// SSCI did not have a QUIT event, but we do, so we have to handle it
 		if (event.type == kSciEventQuit) {
 			focused = false;
 		} else if (event.type == kSciEventMousePress && !editorPlaneRect.contains(event.mousePosSci)) {
@@ -179,18 +179,16 @@ reg_t GfxControls32::kernelEditText(const reg_t controlObject) {
 			break;
 		}
 
-		// Consume the event now that we know it is not one of the
-		// defocusing events above
+		// Consume the event now that we know it is not one of the defocusing
+		// events above
 		if (event.type != kSciEventNone)
 			eventManager->getSciEvent(kSciEventAny);
 
-		// NOTE: In the original engine, the font and bitmap were
-		// reset here on each iteration through the loop, but it
-		// doesn't seem like this should be necessary since
-		// control is not yielded back to the VM until input is
-		// received, which means there is nothing that could modify
-		// the GfxText32's state with a different font in the
-		// meantime
+		// In SSCI, the font and bitmap were reset here on each iteration
+		// through the loop, but this is not necessary since control is not
+		// yielded back to the VM until input is received, which means there is
+		// nothing that could modify the GfxText32's state with a different font
+		// in the meantime
 
 		bool shouldDeleteChar = false;
 		bool shouldRedrawText = false;
@@ -223,8 +221,8 @@ reg_t GfxControls32::kernelEditText(const reg_t controlObject) {
 
 			case kSciKeyInsert:
 				clearTextOnInput = false;
-				// Redrawing also changes the cursor rect to
-				// reflect the new insertion mode
+				// Redrawing also changes the cursor rect to reflect the new
+				// insertion mode
 				shouldRedrawText = true;
 				_overwriteMode = !_overwriteMode;
 				break;
@@ -324,10 +322,9 @@ void GfxControls32::drawCursor(TextEditor &editor) {
 
 		const int16 scaledFontHeight = _gfxText32->scaleUpHeight(_gfxText32->_font->getHeight());
 
-		// NOTE: The original code branched on borderColor here but
-		// the two branches appeared to be identical, differing only
-		// because the compiler decided to be differently clever
-		// when optimising multiplication in each branch
+		// SSCI branched on borderColor here but the two branches appeared to be
+		// identical, differing only because the compiler decided to be
+		// differently clever when optimising multiplication in each branch
 		if (_overwriteMode) {
 			editor.cursorRect.top = editor.textRect.top;
 			editor.cursorRect.setHeight(scaledFontHeight);
@@ -465,9 +462,8 @@ reg_t ScrollWindow::add(const Common::String &text, const GuiResourceId fontId,
 	if (_entries.size() == _maxNumEntries) {
 		ScrollWindowEntry removedEntry = _entries.remove_at(0);
 		_text.erase(0, removedEntry.text.size());
-		// `_firstVisibleChar` will be reset shortly if
-		// `scrollTo` is true, so there is no reason to
-		// update it
+		// `_firstVisibleChar` will be reset shortly if `scrollTo` is true, so
+		// there is no reason to update it
 		if (!scrollTo) {
 			_firstVisibleChar -= removedEntry.text.size();
 		}
@@ -476,17 +472,17 @@ reg_t ScrollWindow::add(const Common::String &text, const GuiResourceId fontId,
 	_entries.push_back(ScrollWindowEntry());
 	ScrollWindowEntry &entry = _entries.back();
 
-	// NOTE: In SSCI the line ID was a memory handle for the
-	// string of this line. We use a numeric ID instead.
+	// In SSCI, the line ID was a memory handle for the string of this line. We
+	// use a numeric ID instead.
 	entry.id = make_reg(0, _nextEntryId++);
 
 	if (_nextEntryId > _maxNumEntries) {
 		_nextEntryId = 1;
 	}
 
-	// NOTE: In SSCI this was updated after _text was
-	// updated, which meant there was an extra unnecessary
-	// subtraction operation (subtracting `entry.text` size)
+	// In SSCI, this was updated after _text was updated, which meant there was
+	// an extra unnecessary subtraction operation (subtracting `entry.text`
+	// size)
 	if (scrollTo) {
 		_firstVisibleChar = _text.size();
 	}
@@ -517,9 +513,8 @@ void ScrollWindow::fillEntry(ScrollWindowEntry &entry, const Common::String &tex
 	// with properties -1 can inherit properties from the previously rendered
 	// line instead of the defaults.
 
-	// NOTE: SSCI added "|s<lineIndex>|" here, but |s| is
-	// not a valid control code, so it just always ended up
-	// getting skipped
+	// SSCI added "|s<lineIndex>|" here, but |s| is not a valid control code, so
+	// it just always ended up getting skipped by the text rendering code
 	if (entry.fontId != -1) {
 		formattedText += Common::String::format("|f%d|", entry.fontId);
 	}
@@ -705,9 +700,8 @@ void ScrollWindow::pageDown() {
 
 void ScrollWindow::computeLineIndices() {
 	_gfxText32.setFont(_fontId);
-	// NOTE: Unlike SSCI, foreColor and alignment are not
-	// set since these properties do not affect the width of
-	// lines
+	// Unlike SSCI, foreColor and alignment are not set since these properties
+	// do not affect the width of lines
 
 	if (_gfxText32._font->getHeight() != _pointSize) {
 		error("Illegal font size font = %d pointSize = %d, should be %d.", _fontId, _gfxText32._font->getHeight(), _pointSize);
@@ -717,8 +711,8 @@ void ScrollWindow::computeLineIndices() {
 
 	_startsOfLines.clear();
 
-	// NOTE: The original engine had a 1000-line limit; we
-	// do not enforce any limit
+	// SSCI had a 1000-line limit; we do not enforce any limit since we use
+	// dynamic containers
 	for (uint charIndex = 0; charIndex < _text.size(); ) {
 		_startsOfLines.push_back(charIndex);
 		charIndex += _gfxText32.getTextCount(_text, charIndex, lineRect, false);
diff --git a/engines/sci/graphics/controls32.h b/engines/sci/graphics/controls32.h
index 680c70d..de292da 100644
--- a/engines/sci/graphics/controls32.h
+++ b/engines/sci/graphics/controls32.h
@@ -32,8 +32,8 @@ class GfxScreen;
 class GfxText32;
 
 enum MessageBoxStyle {
-	kMessageBoxOK               = 0x0,
-	kMessageBoxYesNo            = 0x4
+	kMessageBoxOK    = 0x0,
+	kMessageBoxYesNo = 0x4
 };
 
 struct TextEditor {
@@ -89,14 +89,12 @@ struct TextEditor {
 	uint16 cursorCharPosition;
 
 	/**
-	 * Whether or not the cursor is currently drawn to the
-	 * screen.
+	 * Whether or not the cursor is currently drawn to the screen.
 	 */
 	bool cursorIsDrawn;
 
 	/**
-	 * The rectangle for drawing the input cursor, in bitmap
-	 * pixels.
+	 * The rectangle for drawing the input cursor, in bitmap pixels.
 	 */
 	Common::Rect cursorRect;
 
@@ -111,30 +109,26 @@ struct TextEditor {
  */
 struct ScrollWindowEntry {
 	/**
-	 * ID of the line. In SSCI this was actually a memory
-	 * handle for the string of this line. We use a simple
-	 * numeric ID instead.
+	 * ID of the line. In SSCI this was actually a memory handle for the string
+	 * of this line. We use a simple numeric ID instead.
 	 */
 	reg_t id;
 
 	/**
-	 * The alignment to use when rendering this line of
-	 * text. If -1, the default alignment from the
-	 * corresponding ScrollWindow will be used.
+	 * The alignment to use when rendering this line of text. If -1, the default
+	 * alignment from the corresponding ScrollWindow will be used.
 	 */
 	TextAlign alignment;
 
 	/**
-	 * The color to use to render this line of text. If -1,
-	 * the default foreground color from the corresponding
-	 * ScrollWindow will be used.
+	 * The color to use to render this line of text. If -1, the default
+	 * foreground color from the corresponding ScrollWindow will be used.
 	 */
 	int16 foreColor;
 
 	/**
-	 * The font to use to render this line of text. If -1,
-	 * the default font from the corresponding ScrollWindow
-	 * will be used.
+	 * The font to use to render this line of text. If -1, the default font from
+	 * the corresponding ScrollWindow will be used.
 	 */
 	GuiResourceId fontId;
 
@@ -155,16 +149,15 @@ public:
 	~ScrollWindow();
 
 	/**
-	 * Adds a new text entry to the window. If `fontId`,
-	 * `foreColor`, or `alignment` are `-1`, the
-	 * ScrollWindow's default values will be used.
+	 * Adds a new text entry to the window. If `fontId`, `foreColor`, or
+	 * `alignment` are `-1`, the ScrollWindow's default values will be used.
 	 */
 	reg_t add(const Common::String &text, const GuiResourceId fontId, const int16 foreColor, const TextAlign alignment, const bool scrollTo);
 
 	/**
-	 * Modifies an existing text entry with the given ID. If
-	 * `fontId`, `foreColor`, or `alignment` are `-1`, the
-	 * ScrollWindow's default values will be used.
+	 * Modifies an existing text entry with the given ID. If `fontId`,
+	 * `foreColor`, or `alignment` are `-1`, the ScrollWindow's default values
+	 * will be used.
 	 */
 	reg_t modify(const reg_t id, const Common::String &text, const GuiResourceId fontId, const int16 foreColor, const TextAlign alignment, const bool scrollTo);
 
@@ -179,9 +172,8 @@ public:
 	void hide();
 
 	/**
-	 * Gets the number of lines that the content of a
-	 * ScrollWindow is scrolled upward, as a ratio of the
-	 * total number of lines of content.
+	 * Gets the number of lines that the content of a ScrollWindow is scrolled
+	 * upward, as a ratio of the total number of lines of content.
 	 */
 	Ratio where() const;
 
@@ -221,8 +213,8 @@ public:
 	void pageDown();
 
 	/**
-	 * Gets a reference to the in-memory bitmap that
-	 * is used to render the text in the ScrollWindow.
+	 * Gets a reference to the in-memory bitmap that is used to render the text
+	 * in the ScrollWindow.
 	 */
 	const reg_t getBitmap() const { return _bitmap; }
 
@@ -232,31 +224,26 @@ private:
 	typedef Common::Array<ScrollWindowEntry> EntriesList;
 
 	/**
-	 * A convenience function that fills a
-	 * ScrollWindowEntry's properties.
+	 * A convenience function that fills a ScrollWindowEntry's properties.
 	 */
 	void fillEntry(ScrollWindowEntry &entry, const Common::String &text, const GuiResourceId fontId, const int16 foreColor, const TextAlign alignment);
 
 	/**
-	 * Rescans the entire text of the ScrollWindow when an
-	 * entry is added or modified, calculating the character
-	 * offsets of all line endings, the total number of
-	 * lines of text, the height of the viewport (in lines
-	 * of text), the last character visible in the viewport
-	 * (assuming the viewport is scrolled to the top), and
-	 * the line index of the bottommost visible line
-	 * (assuming the viewport is scrolled to the top).
+	 * Rescans the entire text of the ScrollWindow when an entry is added or
+	 * modified, calculating the character offsets of all line endings, the
+	 * total number of lines of text, the height of the viewport (in lines of
+	 * text), the last character visible in the viewport (assuming the viewport
+	 * is scrolled to the top), and the line index of the bottommost visible
+	 * line (assuming the viewport is scrolled to the top).
 	 */
 	void computeLineIndices();
 
 	/**
-	 * Calculates which text is visible within the
-	 * ScrollWindow's viewport and renders the text to the
-	 * internal bitmap.
+	 * Calculates which text is visible within the ScrollWindow's viewport and
+	 * renders the text to the internal bitmap.
 	 *
-	 * If `doFrameOut` is true, the screen will be refreshed
-	 * immediately instead of waiting for the next call to
-	 * `kFrameOut`.
+	 * If `doFrameOut` is true, the screen will be refreshed immediately instead
+	 * of waiting for the next call to `kFrameOut`.
 	 */
 	void update(const bool doFrameOut);
 
@@ -266,21 +253,18 @@ private:
 	GfxText32 _gfxText32;
 
 	/**
-	 * The individual text entries added to the
-	 * ScrollWindow.
+	 * The individual text entries added to the ScrollWindow.
 	 */
 	EntriesList _entries;
 
 	/**
-	 * The maximum number of entries allowed. Once this
-	 * limit is reached, the oldest entry will be removed
-	 * when a new entry is added.
+	 * The maximum number of entries allowed. Once this limit is reached, the
+	 * oldest entry will be removed when a new entry is added.
 	 */
 	uint _maxNumEntries;
 
 	/**
-	 * A mapping from a line index to the line's character
-	 * offset in `_text`.
+	 * A mapping from a line index to the line's character offset in `_text`.
 	 */
 	Common::Array<int> _startsOfLines;
 
@@ -300,39 +284,36 @@ private:
 	int _firstVisibleChar;
 
 	/**
-	 * The index of the line that is at the top of the
-	 * viewport.
+	 * The index of the line that is at the top of the viewport.
 	 */
 	int _topVisibleLine;
 
 	/**
-	 * The index of the last visible character in `_text`,
-	 * or -1 if there is no text.
+	 * The index of the last visible character in `_text`, or -1 if there is no
+	 * text.
 	 */
 	int _lastVisibleChar;
 
 	/**
-	 * The index of the line that is at the bottom of the
-	 * viewport, or -1 if there is no text.
+	 * The index of the line that is at the bottom of the viewport, or -1 if
+	 * there is no text.
 	 */
 	int _bottomVisibleLine;
 
 	/**
-	 * The total number of lines in the backbuffer. This
-	 * number may be higher than the total number of entries
-	 * if an entry contains newlines.
+	 * The total number of lines in the backbuffer. This number may be higher
+	 * than the total number of entries if an entry contains newlines.
 	 */
 	int _numLines;
 
 	/**
-	 * The number of lines that are currently visible in the
-	 * text area of the window.
+	 * The number of lines that are currently visible in the text area of the
+	 * window.
 	 */
 	int _numVisibleLines;
 
 	/**
-	 * The plane in which the ScrollWindow should be
-	 * rendered.
+	 * The plane in which the ScrollWindow should be rendered.
 	 */
 	reg_t _plane;
 
@@ -347,20 +328,18 @@ private:
 	uint8 _backColor;
 
 	/**
-	 * The default border color of the text bitmap. If -1,
-	 * the viewport will have no border.
+	 * The default border color of the text bitmap. If -1, the viewport will
+	 * have no border.
 	 */
 	int16 _borderColor;
 
 	/**
-	 * The default font used for rendering text into the
-	 * ScrollWindow.
+	 * The default font used for rendering text into the ScrollWindow.
 	 */
 	GuiResourceId _fontId;
 
 	/**
-	 * The default text alignment used for rendering text
-	 * into the ScrollWindow.
+	 * The default text alignment used for rendering text into the ScrollWindow.
 	 */
 	TextAlign _alignment;
 
@@ -370,22 +349,20 @@ private:
 	bool _visible;
 
 	/**
-	 * The dimensions of the text box inside the font
-	 * bitmap, in text-system coordinates.
+	 * The dimensions of the text box inside the font bitmap, in text-system
+	 * coordinates.
 	 */
 	Common::Rect _textRect;
 
 	/**
-	 * The top-left corner of the ScrollWindow's screen
-	 * item, in game script coordinates, relative to the
-	 * parent plane.
+	 * The top-left corner of the ScrollWindow's screen item, in game script
+	 * coordinates, relative to the parent plane.
 	 */
 	Common::Point _position;
 
 	/**
-	 * The height of the default font in screen pixels. All
-	 * fonts rendered into the ScrollWindow must have this
-	 * same height.
+	 * The height of the default font in screen pixels. All fonts rendered into
+	 * the ScrollWindow must have this same height.
 	 */
 	uint8 _pointSize;
 
@@ -395,8 +372,8 @@ private:
 	reg_t _bitmap;
 
 	/**
-	 * A monotonically increasing ID used to identify
-	 * text entries added to the ScrollWindow.
+	 * A monotonically increasing ID used to identify text entries added to the
+	 * ScrollWindow.
 	 */
 	uint16 _nextEntryId;
 
@@ -407,7 +384,8 @@ private:
 };
 
 /**
- * Controls class, handles drawing of controls in SCI32 (SCI2, SCI2.1, SCI3) games
+ * Controls class, handles drawing of UI controls in SCI32 games that use kernel
+ * controls instead of custom script controls.
  */
 class GfxControls32 {
 public:
@@ -426,14 +404,13 @@ public:
 
 private:
 	/**
-	 * If true, typing will overwrite text that already
-	 * exists at the text cursor's current position.
+	 * If true, typing will overwrite text that already exists at the text
+	 * cursor's current position.
 	 */
 	bool _overwriteMode;
 
 	/**
-	 * The tick at which the text cursor should be toggled
-	 * by `flashCursor`.
+	 * The tick at which the text cursor should be toggled by `flashCursor`.
 	 */
 	uint32 _nextCursorFlashTick;
 
@@ -448,8 +425,8 @@ private:
 	void eraseCursor(TextEditor &editor);
 
 	/**
-	 * Toggles the text cursor for the given editor to be
-	 * either drawn or erased.
+	 * Toggles the text cursor for the given editor to be either drawn or
+	 * erased.
 	 */
 	void flashCursor(TextEditor &editor);
 
@@ -457,9 +434,8 @@ private:
 #pragma mark Scrollable window control
 public:
 	/**
-	 * Creates a new scrollable window and returns the ID
-	 * for the new window, which is used by game scripts to
-	 * interact with scrollable windows.
+	 * Creates a new scrollable window and returns the ID for the new window,
+	 * which is used by game scripts to interact with scrollable windows.
 	 */
 	reg_t makeScrollWindow(const Common::Rect &gameRect, const Common::Point &position, const reg_t plane, const uint8 defaultForeColor, const uint8 defaultBackColor, const GuiResourceId defaultFontId, const TextAlign defaultAlignment, const int16 defaultBorderColor, const uint16 maxNumEntries);
 
@@ -477,8 +453,7 @@ private:
 	typedef Common::HashMap<uint16, ScrollWindow *> ScrollWindowMap;
 
 	/**
-	 * Monotonically increasing ID used to identify
-	 * ScrollWindow instances.
+	 * Monotonically increasing ID used to identify ScrollWindow instances.
 	 */
 	uint16 _nextScrollWindowId;
 
@@ -497,8 +472,7 @@ public:
 
 private:
 	/**
-	 * Convenience function for creating and showing a
-	 * message box.
+	 * Convenience function for creating and showing a message box.
 	 */
 	int16 showMessageBox(const Common::String &message, const char *const okLabel, const char *const altLabel, const int16 okValue, const int16 altValue);
 };


Commit: b6c3f0f547f478271a8ecee68654f18ab8de75ce
    https://github.com/scummvm/scummvm/commit/b6c3f0f547f478271a8ecee68654f18ab8de75ce
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:56:24-05:00

Commit Message:
SCI32: Clean up CelObj

* Rewrap comments to 80 columns
* Clarify comments where possible
* Use smart pointers where appropriate
* Change view/pic flags detection to always use word-size
  (byte-size check for flag 0x80 was a compiler optimisation)

Changed paths:
    engines/sci/engine/segment.h
    engines/sci/graphics/celobj32.cpp
    engines/sci/graphics/celobj32.h


diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h
index d6e2dd3..2a4fd91 100644
--- a/engines/sci/engine/segment.h
+++ b/engines/sci/engine/segment.h
@@ -1102,12 +1102,11 @@ public:
 
 	BITMAP_PROPERTY(32, DataOffset, 24);
 
-	// NOTE: This property is used as a "magic number" for
-	// validating that a block of memory is a valid bitmap,
-	// and so is always set to the size of the header.
+	// This property is used as a "magic number" for validating that a block of
+	// memory is a valid bitmap, and so is always set to the size of the header.
 	BITMAP_PROPERTY(32, UncompressedDataOffset, 28);
 
-	// NOTE: This property always seems to be zero
+	// This property always seems to be zero in SSCI
 	BITMAP_PROPERTY(32, ControlOffset, 32);
 
 	inline uint16 getXResolution() const {
diff --git a/engines/sci/graphics/celobj32.cpp b/engines/sci/graphics/celobj32.cpp
index a49690a..c2ae29b 100644
--- a/engines/sci/graphics/celobj32.cpp
+++ b/engines/sci/graphics/celobj32.cpp
@@ -35,7 +35,7 @@
 namespace Sci {
 #pragma mark CelScaler
 
-CelScaler *CelObj::_scaler = nullptr;
+Common::ScopedPtr<CelScaler> CelObj::_scaler;
 
 void CelScaler::activateScaleTables(const Ratio &scaleX, const Ratio &scaleY) {
 	for (int i = 0; i < ARRAYSIZE(_scaleTables); ++i) {
@@ -74,9 +74,9 @@ void CelScaler::buildLookupTable(int *table, const Ratio &ratio, const int size)
 	}
 }
 
-const CelScalerTable *CelScaler::getScalerTable(const Ratio &scaleX, const Ratio &scaleY) {
+const CelScalerTable &CelScaler::getScalerTable(const Ratio &scaleX, const Ratio &scaleY) {
 	activateScaleTables(scaleX, scaleY);
-	return &_scaleTables[_activeIndex];
+	return _scaleTables[_activeIndex];
 }
 
 #pragma mark -
@@ -87,21 +87,13 @@ void CelObj::init() {
 	CelObj::deinit();
 	_drawBlackLines = false;
 	_nextCacheId = 1;
-	_scaler = new CelScaler();
-	_cache = new CelCache;
-	_cache->resize(100);
+	_scaler.reset(new CelScaler());
+	_cache.reset(new CelCache(100));
 }
 
 void CelObj::deinit() {
-	delete _scaler;
-	_scaler = nullptr;
-	if (_cache != nullptr) {
-		for (CelCache::iterator it = _cache->begin(); it != _cache->end(); ++it) {
-			delete it->celObj;
-		}
-	}
-	delete _cache;
-	_cache = nullptr;
+	_scaler.reset();
+	_cache.reset();
 }
 
 #pragma mark -
@@ -172,10 +164,9 @@ struct SCALER_Scale {
 	_minX(targetRect.left),
 	_maxX(targetRect.right - 1),
 #endif
-	// The maximum width of the scaled object may not be as
-	// wide as the source data it requires if downscaling,
-	// so just always make the reader decompress an entire
-	// line of source data when scaling
+	// The maximum width of the scaled object may not be as wide as the source
+	// data it requires if downscaling, so just always make the reader
+	// decompress an entire line of source data when scaling
 	_reader(celObj, celObj._width) {
 #ifndef NDEBUG
 		assert(_minX <= _maxX);
@@ -203,39 +194,39 @@ struct SCALER_Scale {
 		// games which use global scaling are the ones that use low-resolution
 		// script coordinates too.
 
-		const CelScalerTable *table = CelObj::_scaler->getScalerTable(scaleX, scaleY);
+		const CelScalerTable &table = CelObj::_scaler->getScalerTable(scaleX, scaleY);
 
-		if (g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth == kLowResX) {
+		if (g_sci->_gfxFrameout->getScriptWidth() == kLowResX) {
 			const int16 unscaledX = (scaledPosition.x / scaleX).toInt();
 			if (FLIP) {
 				const int lastIndex = celObj._width - 1;
 				for (int16 x = targetRect.left; x < targetRect.right; ++x) {
-					_valuesX[x] = lastIndex - (table->valuesX[x] - unscaledX);
+					_valuesX[x] = lastIndex - (table.valuesX[x] - unscaledX);
 				}
 			} else {
 				for (int16 x = targetRect.left; x < targetRect.right; ++x) {
-					_valuesX[x] = table->valuesX[x] - unscaledX;
+					_valuesX[x] = table.valuesX[x] - unscaledX;
 				}
 			}
 
 			const int16 unscaledY = (scaledPosition.y / scaleY).toInt();
 			for (int16 y = targetRect.top; y < targetRect.bottom; ++y) {
-				_valuesY[y] = table->valuesY[y] - unscaledY;
+				_valuesY[y] = table.valuesY[y] - unscaledY;
 			}
 		} else {
 			if (FLIP) {
 				const int lastIndex = celObj._width - 1;
 				for (int16 x = targetRect.left; x < targetRect.right; ++x) {
-					_valuesX[x] = lastIndex - table->valuesX[x - scaledPosition.x];
+					_valuesX[x] = lastIndex - table.valuesX[x - scaledPosition.x];
 				}
 			} else {
 				for (int16 x = targetRect.left; x < targetRect.right; ++x) {
-					_valuesX[x] = table->valuesX[x - scaledPosition.x];
+					_valuesX[x] = table.valuesX[x - scaledPosition.x];
 				}
 			}
 
 			for (int16 y = targetRect.top; y < targetRect.bottom; ++y) {
-				_valuesY[y] = table->valuesY[y - scaledPosition.y];
+				_valuesY[y] = table.valuesY[y - scaledPosition.y];
 			}
 		}
 	}
@@ -412,8 +403,8 @@ struct MAPPER_NoMDNoSkip {
 struct MAPPER_Map {
 	inline void draw(byte *target, const byte pixel, const uint8 skipColor) const {
 		if (pixel != skipColor) {
-			// NOTE: For some reason, SSCI never checks if the source
-			// pixel is *above* the range of remaps.
+			// For some reason, SSCI never checks if the source pixel is *above*
+			// the range of remaps, so we do not either.
 			if (pixel < g_sci->_gfxRemap32->getStartColor()) {
 				*target = pixel;
 			} else if (g_sci->_gfxRemap32->remapEnabled(pixel)) {
@@ -429,8 +420,8 @@ struct MAPPER_Map {
  */
 struct MAPPER_NoMap {
 	inline void draw(byte *target, const byte pixel, const uint8 skipColor) const {
-		// NOTE: For some reason, SSCI never checks if the source
-		// pixel is *above* the range of remaps.
+		// For some reason, SSCI never checks if the source pixel is *above* the
+		// range of remaps, so we do not either.
 		if (pixel != skipColor && pixel < g_sci->_gfxRemap32->getStartColor()) {
 			*target = pixel;
 		}
@@ -444,9 +435,9 @@ void CelObj::draw(Buffer &target, const ScreenItem &screenItem, const Common::Re
 	_drawBlackLines = screenItem._drawBlackLines;
 
 	if (_remap) {
-		// NOTE: In the original code this check was `g_Remap_numActiveRemaps && _remap`,
-		// but since we are already in a `_remap` branch, there is no reason to check it
-		// again
+		// In SSCI, this check was `g_Remap_numActiveRemaps && _remap`, but
+		// since we are already in a `_remap` branch, there is no reason to
+		// check that again
 		if (g_sci->_gfxRemap32->getRemapCount()) {
 			if (scaleX.isOne() && scaleY.isOne()) {
 				if (_compressionType == kCelCompressionNone) {
@@ -612,7 +603,7 @@ void CelObj::submitPalette() const {
 #pragma mark CelObj - Caching
 
 int CelObj::_nextCacheId = 1;
-CelCache *CelObj::_cache = nullptr;
+Common::ScopedPtr<CelCache> CelObj::_cache;
 
 int CelObj::searchCache(const CelInfo32 &celInfo, int *const nextInsertIndex) const {
 	*nextInsertIndex = -1;
@@ -648,12 +639,7 @@ void CelObj::putCopyInCache(const int cacheIndex) const {
 	}
 
 	CelCacheEntry &entry = (*_cache)[cacheIndex];
-
-	if (entry.celObj != nullptr) {
-		delete entry.celObj;
-	}
-
-	entry.celObj = duplicate();
+	entry.celObj.reset(duplicate());
 	entry.id = ++_nextCacheId;
 }
 
@@ -807,8 +793,8 @@ void CelObj::drawUncompHzFlipNoMDNoSkip(Buffer &target, const Common::Rect &targ
 }
 
 void CelObj::scaleDrawNoMD(Buffer &target, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition) const {
-	// In SSCI the checks are > because their rects are BR-inclusive;
-	// our checks are >= because our rects are BR-exclusive
+	// In SSCI the checks are > because their rects are BR-inclusive; our checks
+	// are >= because our rects are BR-exclusive
 	if (g_sci->_features->hasEmptyScaleDrawHack() &&
 		(targetRect.left >= targetRect.right ||
 		 targetRect.top >= targetRect.bottom)) {
@@ -822,8 +808,8 @@ void CelObj::scaleDrawNoMD(Buffer &target, const Ratio &scaleX, const Ratio &sca
 }
 
 void CelObj::scaleDrawUncompNoMD(Buffer &target, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition) const {
-	// In SSCI the checks are > because their rects are BR-inclusive;
-	// our checks are >= because our rects are BR-exclusive
+	// In SSCI the checks are > because their rects are BR-inclusive; our checks
+	// are >= because our rects are BR-exclusive
 	if (g_sci->_features->hasEmptyScaleDrawHack() &&
 		(targetRect.left >= targetRect.right ||
 		 targetRect.top >= targetRect.bottom)) {
@@ -861,11 +847,11 @@ int16 CelObjView::getNumCels(const GuiResourceId viewId, int16 loopNo) {
 
 	const uint16 loopCount = data[2];
 
-	// Every version of SCI32 has a logic error in this function that causes
-	// random memory to be read if a script requests the cel count for one
-	// past the maximum loop index. For example, GK1 room 808 does this, and
-	// gets stuck in an infinite loop because the game script expects this
-	// method to return a non-zero value.
+	// Every version of SSCI has a logic error in this function that causes
+	// random memory to be read if a script requests the cel count for one past
+	// the maximum loop index. For example, GK1 room 808 does this, and gets
+	// stuck in an infinite loop because the game script expects this method to
+	// return a non-zero value.
 	// This bug is triggered in basically every SCI32 game and appears to be
 	// universally fixable simply by always using the next lowest loop instead.
 	if (loopNo == loopCount) {
@@ -904,7 +890,7 @@ CelObjView::CelObjView(const GuiResourceId viewId, const int16 loopNo, const int
 	const int cacheIndex = searchCache(_info, &cacheInsertIndex);
 	if (cacheIndex != -1) {
 		CelCacheEntry &entry = (*_cache)[cacheIndex];
-		const CelObjView *const cachedCelObj = dynamic_cast<CelObjView *>(entry.celObj);
+		const CelObjView *const cachedCelObj = dynamic_cast<CelObjView *>(entry.celObj.get());
 		if (cachedCelObj == nullptr) {
 			error("Expected a CelObjView in cache slot %d", cacheIndex);
 		}
@@ -915,7 +901,7 @@ CelObjView::CelObjView(const GuiResourceId viewId, const int16 loopNo, const int
 
 	const Resource *const resource = g_sci->getResMan()->findResource(ResourceId(kResourceTypeView, viewId), false);
 
-	// NOTE: SCI2.1/SQ6 just silently returns here.
+	// SSCI just silently returns here
 	if (!resource) {
 		error("View resource %d not found", viewId);
 	}
@@ -944,8 +930,6 @@ CelObjView::CelObjView(const GuiResourceId viewId, const int16 loopNo, const int
 		_info.loopNo = loopCount - 1;
 	}
 
-	// NOTE: This is the actual check, in the actual location,
-	// from SCI engine.
 	if (loopNo < 0) {
 		error("Loop is less than 0");
 	}
@@ -1011,10 +995,8 @@ CelObjView::CelObjView(const GuiResourceId viewId, const int16 loopNo, const int
 		error("Compression type not supported - V: %d  L: %d  C: %d", _info.resourceId, _info.loopNo, _info.celNo);
 	}
 
-	if (celHeader[10] & 128) {
-		// NOTE: This is correct according to SCI2.1/SQ6/DOS;
-		// the engine re-reads the byte value as a word value
-		const uint16 flags = celHeader.getUint16SEAt(10);
+	const uint16 flags = celHeader.getUint16SEAt(10);
+	if (flags & 0x80) {
 		_transparent = flags & 1 ? true : false;
 		_remap = flags & 2 ? true : false;
 	} else if (_compressionType == kCelCompressionNone) {
@@ -1096,7 +1078,7 @@ Common::Point CelObjView::getLinkPosition(const int16 linkId) const {
 				Common::Point point;
 				point.x = linkTable.getInt16SEAt(0);
 				if (_mirrorX) {
-					// NOTE: SSCI had an off-by-one error here (missing -1)
+					// SSCI had an off-by-one error here (missing -1)
 					point.x = _width - point.x - 1;
 				}
 				point.y = linkTable.getInt16SEAt(2);
@@ -1127,7 +1109,7 @@ CelObjPic::CelObjPic(const GuiResourceId picId, const int16 celNo) {
 	const int cacheIndex = searchCache(_info, &cacheInsertIndex);
 	if (cacheIndex != -1) {
 		CelCacheEntry &entry = (*_cache)[cacheIndex];
-		const CelObjPic *const cachedCelObj = dynamic_cast<CelObjPic *>(entry.celObj);
+		const CelObjPic *const cachedCelObj = dynamic_cast<CelObjPic *>(entry.celObj.get());
 		if (cachedCelObj == nullptr) {
 			error("Expected a CelObjPic in cache slot %d", cacheIndex);
 		}
@@ -1138,7 +1120,7 @@ CelObjPic::CelObjPic(const GuiResourceId picId, const int16 celNo) {
 
 	const Resource *const resource = g_sci->getResMan()->findResource(ResourceId(kResourceTypePic, picId), false);
 
-	// NOTE: SCI2.1/SQ6 just silently returns here.
+	// SSCI just silently returns here
 	if (!resource) {
 		error("Pic resource %d not found", picId);
 	}
@@ -1183,10 +1165,9 @@ CelObjPic::CelObjPic(const GuiResourceId picId, const int16 celNo) {
 		_yResolution = 400;
 	}
 
-	if (celHeader.getUint8At(10) & 128) {
-		// NOTE: This is correct according to SCI2.1/SQ6/DOS;
-		// the engine re-reads the byte value as a word value
-		const uint16 flags = celHeader.getUint16SEAt(10);
+
+	const uint16 flags = celHeader.getUint16SEAt(10);
+	if (flags & 0x80) {
 		_transparent = flags & 1 ? true : false;
 		_remap = flags & 2 ? true : false;
 	} else {
@@ -1251,7 +1232,8 @@ CelObjMem::CelObjMem(const reg_t bitmapObject) {
 
 	SciBitmap *bitmap = g_sci->getEngineState()->_segMan->lookupBitmap(bitmapObject);
 
-	// NOTE: SSCI did no error checking here at all.
+	// SSCI did no error checking here at all so would just end up reading
+	// garbage or crashing if this ever happened
 	if (!bitmap) {
 		error("Bitmap %04x:%04x not found", PRINT_REG(bitmapObject));
 	}
@@ -1293,8 +1275,8 @@ CelObjColor::CelObjColor(const uint8 color, const int16 width, const int16 heigh
 }
 
 void CelObjColor::draw(Buffer &target, const ScreenItem &screenItem, const Common::Rect &targetRect, const bool mirrorX) {
-	// TODO: The original engine sets this flag but why? One cannot
-	// draw a solid color mirrored.
+	// One cannot draw a solid color mirrored, but SSCI sets it anyway, so we do
+	// too
 	_drawMirrored = mirrorX;
 	draw(target, targetRect);
 }
diff --git a/engines/sci/graphics/celobj32.h b/engines/sci/graphics/celobj32.h
index 6e50f72..02b2859 100644
--- a/engines/sci/graphics/celobj32.h
+++ b/engines/sci/graphics/celobj32.h
@@ -33,14 +33,14 @@ namespace Sci {
 typedef Common::Rational Ratio;
 
 // SCI32 has four different coordinate systems:
-// 1. low resolution, 2. game/script resolution,
-// 3. text/bitmap resolution, 4. screen resolution
+// 1. low resolution, 2. game/script resolution, 3. text/bitmap resolution,
+// 4. screen resolution
 //
-// In CelObj, these values are used when there is
-// no baked in resolution of cels.
+// In CelObj, these values are used when there is no baked in resolution of
+// cels.
 //
-// In ScreenItem, it is used when deciding which
-// path to take to calculate dimensions.
+// In ScreenItem, it is used when deciding which path to take to calculate
+// dimensions.
 enum {
 	kLowResX = 320,
 	kLowResY = 200
@@ -60,8 +60,7 @@ enum CelCompressionType {
 };
 
 /**
- * A CelInfo32 object describes the basic properties of a
- * cel object.
+ * A CelInfo32 object describes the basic properties of a cel object.
  */
 struct CelInfo32 {
 	/**
@@ -70,26 +69,24 @@ struct CelInfo32 {
 	CelType type;
 
 	/**
-	 * For cel objects that draw from resources, the ID of
-	 * the resource to load.
+	 * For cel objects that draw from resources, the ID of the resource to load.
 	 */
 	GuiResourceId resourceId;
 
 	/**
-	 * For CelObjView, the loop number to draw from the
-	 * view resource.
+	 * For CelObjView, the loop number to draw from the view resource.
 	 */
 	int16 loopNo;
 
 	/**
-	 * For CelObjView and CelObjPic, the cel number to draw
-	 * from the view or pic resource.
+	 * For CelObjView and CelObjPic, the cel number to draw from the view or pic
+	 * resource.
 	 */
 	int16 celNo;
 
 	/**
-	 * For CelObjMem, a segment register pointing to a heap
-	 * resource containing headered bitmap data.
+	 * For CelObjMem, a segment register pointing to a heap resource containing
+	 * headered bitmap data.
 	 */
 	reg_t bitmap;
 
@@ -98,18 +95,16 @@ struct CelInfo32 {
 	 */
 	uint8 color;
 
-	// NOTE: In at least SCI2.1/SQ6, color is left
-	// uninitialised.
 	CelInfo32() :
+		// In SSCI, color is left uninitialised
 		type(kCelTypeMem),
 		resourceId(0),
 		loopNo(0),
 		celNo(0),
 		bitmap(NULL_REG) {}
 
-	// NOTE: This is the equivalence criteria used by
-	// CelObj::searchCache in at least SCI2.1/SQ6. Notably,
-	// it does not check the color field.
+	// This is the equivalence criteria used by CelObj::searchCache in at least
+	// SSCI SQ6. Notably, it does not check the color field.
 	inline bool operator==(const CelInfo32 &other) {
 		return (
 			type == other.type &&
@@ -143,13 +138,12 @@ struct CelInfo32 {
 class CelObj;
 struct CelCacheEntry {
 	/**
-	 * A monotonically increasing cache ID used to identify
-	 * the least recently used item in the cache for
-	 * replacement.
+	 * A monotonically increasing cache ID used to identify the least recently
+	 * used item in the cache for replacement.
 	 */
 	int id;
-	CelObj *celObj;
-	CelCacheEntry() : id(0), celObj(nullptr) {}
+	Common::ScopedPtr<CelObj> celObj;
+	CelCacheEntry() : id(0) {}
 };
 
 typedef Common::Array<CelCacheEntry> CelCache;
@@ -166,9 +160,9 @@ enum {
 
 struct CelScalerTable {
 	/**
-	 * A lookup table of indexes that should be used to find
-	 * the correct column to read from the source bitmap
-	 * when drawing a scaled version of the source bitmap.
+	 * A lookup table of indexes that should be used to find the correct column
+	 * to read from the source bitmap when drawing a scaled version of the
+	 * source bitmap.
 	 */
 	int valuesX[kCelScalerTableSize];
 
@@ -178,9 +172,9 @@ struct CelScalerTable {
 	Ratio scaleX;
 
 	/**
-	 * A lookup table of indexes that should be used to find
-	 * the correct row to read from a source bitmap when
-	 * drawing a scaled version of the source bitmap.
+	 * A lookup table of indexes that should be used to find the correct row to
+	 * read from a source bitmap when drawing a scaled version of the source
+	 * bitmap.
 	 */
 	int valuesY[kCelScalerTableSize];
 
@@ -202,25 +196,23 @@ class CelScaler {
 	int _activeIndex;
 
 	/**
-	 * Activates a scale table for the given X and Y ratios.
-	 * If there is no table that matches the given ratios,
-	 * the least most recently used table will be replaced
-	 * and activated.
+	 * Activates a scale table for the given X and Y ratios. If there is no
+	 * table that matches the given ratios, the least most recently used table
+	 * will be replaced and activated.
 	 */
 	void activateScaleTables(const Ratio &scaleX, const Ratio &scaleY);
 
 	/**
-	 * Builds a pixel lookup table in `table` for the given
-	 * ratio. The table will be filled up to the specified
-	 * size, which should be large enough to draw across the
-	 * entire target buffer.
+	 * Builds a pixel lookup table in `table` for the given ratio. The table
+	 * will be filled up to the specified size, which should be large enough to
+	 * draw across the entire target buffer.
 	 */
 	void buildLookupTable(int *table, const Ratio &ratio, const int size);
 
 public:
 	CelScaler() :
-	_scaleTables(),
-	_activeIndex(0) {
+		_scaleTables(),
+		_activeIndex(0) {
 		CelScalerTable &table = _scaleTables[0];
 		table.scaleX = Ratio();
 		table.scaleY = Ratio();
@@ -236,7 +228,7 @@ public:
 	/**
 	 * Retrieves scaler tables for the given X and Y ratios.
 	 */
-	const CelScalerTable *getScalerTable(const Ratio &scaleX, const Ratio &scaleY);
+	const CelScalerTable &getScalerTable(const Ratio &scaleX, const Ratio &scaleY);
 };
 
 #pragma mark -
@@ -244,53 +236,47 @@ public:
 
 class ScreenItem;
 /**
- * A cel object is the lowest-level rendering primitive in
- * the SCI engine and draws itself directly to a target
- * pixel buffer.
+ * A cel object is the lowest-level rendering primitive in the SCI engine and
+ * draws itself directly to a target pixel buffer.
  */
 class CelObj {
 protected:
 	/**
-	 * When true, every second line of the cel will be
-	 * rendered as a black line.
+	 * When true, every second line of the cel will be rendered as a black line.
 	 *
 	 * @see ScreenItem::_drawBlackLines
-	 * @note Using a static member because otherwise this
-	 * would otherwise need to be copied down through
-	 * several calls. (SSCI did similar, using a global
-	 * variable.)
+	 * @note Using a static member because otherwise this would otherwise need
+	 * to be copied down through several calls. (SSCI did similar, using a
+	 * global variable.)
 	 */
 	static bool _drawBlackLines;
 
 	/**
-	 * When true, this cel will be horizontally mirrored
-	 * when it is drawn. This is an internal flag that is
-	 * set by draw methods based on the combination of the
-	 * cel's `_mirrorX` property and the owner screen item's
-	 * `_mirrorX` property.
+	 * When true, this cel will be horizontally mirrored when it is drawn. This
+	 * is an internal flag that is set by draw methods based on the combination
+	 * of the cel's `_mirrorX` property and the owner screen item's `_mirrorX`
+	 * property.
 	 */
 	bool _drawMirrored;
 
 public:
-	static CelScaler *_scaler;
+	static Common::ScopedPtr<CelScaler> _scaler;
 
 	/**
-	 * The basic identifying information for this cel. This
-	 * information effectively acts as a composite key for
-	 * a cel object, and any cel object can be recreated
-	 * from this data alone.
+	 * The basic identifying information for this cel. This information
+	 * effectively acts as a composite key for a cel object, and any cel object
+	 * can be recreated from this data alone.
 	 */
 	CelInfo32 _info;
 
 	/**
-	 * The offset to the cel header for this cel within the
-	 * raw resource data.
+	 * The offset to the cel header for this cel within the raw resource data.
 	 */
 	uint32 _celHeaderOffset;
 
 	/**
-	 * The offset to the embedded palette for this cel
-	 * within the raw resource data.
+	 * The offset to the embedded palette for this cel within the raw resource
+	 * data.
 	 */
 	uint32 _hunkPaletteOffset;
 
@@ -300,36 +286,32 @@ public:
 	uint16 _width, _height;
 
 	/**
-	 * TODO: Documentation
+	 * The origin of the cel, relative to the top-left corner, in cel
+	 * coordinates.
 	 */
 	Common::Point _origin;
 
 	/**
-	 * The dimensions of the original coordinate system for
-	 * the cel. Used to scale cels from their native size
-	 * to the correct size on screen.
+	 * The dimensions of the original coordinate system for the cel. Used to
+	 * scale cels from their native size to the correct size on screen.
 	 *
-	 * @note This is set to scriptWidth/Height for
-	 * CelObjColor. For other cel objects, the value comes
-	 * from the raw resource data. For text bitmaps, this is
-	 * the width/height of the coordinate system used to
-	 * generate the text, which also defaults to
-	 * scriptWidth/Height but seems to typically be changed
-	 * to more closely match the native screen resolution.
+	 * @note This is set to scriptWidth/Height for CelObjColor. For other cel
+	 * objects, the value comes from the raw resource data. For text bitmaps,
+	 * this is the width/height of the coordinate system used to generate the
+	 * text, which also defaults to scriptWidth/Height but seems to typically be
+	 * changed to more closely match the native screen resolution.
 	 */
 	uint16 _xResolution, _yResolution;
 
 	/**
-	 * The skip (transparent) color for the cel. When
-	 * compositing, any pixels matching this color will not
-	 * be copied to the buffer.
+	 * The skip (transparent) color for the cel. When compositing, any pixels
+	 * matching this color will not be copied to the buffer.
 	 */
 	uint8 _skipColor;
 
 	/**
-	 * Whether or not this cel has any transparent regions.
-	 * This is used for optimised drawing of non-transparent
-	 * cels.
+	 * Whether or not this cel has any transparent regions. This is used for
+	 * optimised drawing of non-transparent cels.
 	 */
 	bool _transparent;
 
@@ -339,15 +321,14 @@ public:
 	CelCompressionType _compressionType;
 
 	/**
-	 * Whether or not this cel should be palette-remapped?
+	 * Whether or not this cel contains remap pixels.
 	 */
 	bool _remap;
 
 	/**
-	 * If true, the cel contains pre-mirrored picture data.
-	 * This value comes directly from the resource data and
-	 * is XORed with the `_mirrorX` property of the owner
-	 * screen item when rendering.
+	 * If true, the cel contains pre-mirrored picture data. This value comes
+	 * directly from the resource data and is XORed with the `_mirrorX` property
+	 * of the owner screen item when rendering.
 	 */
 	bool _mirrorX;
 
@@ -364,71 +345,63 @@ public:
 	virtual ~CelObj() {};
 
 	/**
-	 * Draws the cel to the target buffer using the priority
-	 * and positioning information from the given screen
-	 * item. The mirroring of the cel will be unchanged from
-	 * any previous call to draw.
+	 * Draws the cel to the target buffer using the priority and positioning
+	 * information from the given screen item. The mirroring of the cel will be
+	 * unchanged from any previous call to draw.
 	 */
 	void draw(Buffer &target, const ScreenItem &screenItem, const Common::Rect &targetRect) const;
 
 	/**
-	 * Draws the cel to the target buffer using the priority
-	 * and positioning information from the given screen
-	 * item and the given mirror flag.
+	 * Draws the cel to the target buffer using the priority and positioning
+	 * information from the given screen item and the given mirror flag.
 	 *
-	 * @note In SCI engine, this function was a virtual
-	 * function, but CelObjView, CelObjPic, and CelObjMem
-	 * all used the same function and the compiler
-	 * deduplicated the copies; we deduplicate the source by
-	 * putting the implementation on CelObj instead of
-	 * copying it to 3/4 of the subclasses.
+	 * @note In SSCI, this function was a virtual function, but CelObjView,
+	 * CelObjPic, and CelObjMem all used the same function and the compiler
+	 * deduplicated the copies; we deduplicate the source by putting the
+	 * implementation on CelObj instead of copying it to 3/4 of the subclasses.
 	 */
 	virtual void draw(Buffer &target, const ScreenItem &screenItem, const Common::Rect &targetRect, const bool mirrorX);
 
 	/**
-	 * Draws the cel to the target buffer using the
-	 * positioning and mirroring information from the
-	 * provided arguments.
+	 * Draws the cel to the target buffer using the positioning and mirroring
+	 * information from the provided arguments.
 	 *
-	 * @note In SCI engine, this function was a virtual
-	 * function, but CelObjView, CelObjPic, and CelObjMem
-	 * all used the same function and the compiler
-	 * deduplicated the copies; we deduplicate the source by
-	 * putting the implementation on CelObj instead of
-	 * copying it to 3/4 of the subclasses.
+	 * @note In SSCI, this function was a virtual function, but CelObjView,
+	 * CelObjPic, and CelObjMem all used the same function and the compiler
+	 * deduplicated the copies; we deduplicate the source by putting the
+	 * implementation on CelObj instead of copying it to 3/4 of the subclasses.
 	 */
 	virtual void draw(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition, const bool mirrorX);
 
 	/**
-	 * Draws the cel to the target buffer using the given
-	 * position and scaling parameters. The mirroring of the
-	 * cel will be unchanged from any previous call to draw.
+	 * Draws the cel to the target buffer using the given position and scaling
+	 * parameters. The mirroring of the cel will be unchanged from any previous
+	 * call to draw.
 	 */
 	void drawTo(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition, const Ratio &scaleX, const Ratio &scaleY) const;
 
 	/**
-	 * Creates a copy of this cel on the free store and
-	 * returns a pointer to the new object. The new cel will
-	 * point to a shared copy of bitmap/resource data.
+	 * Creates a copy of this cel on the free store and returns a pointer to the
+	 * new object. The new cel will point to a shared copy of bitmap/resource
+	 * data.
 	 */
 	virtual CelObj *duplicate() const = 0;
 
 	/**
-	 * Retrieves a pointer to the raw resource data for this
-	 * cel. This method cannot be used with a CelObjColor.
+	 * Retrieves a pointer to the raw resource data for this cel. This method
+	 * cannot be used with a CelObjColor.
 	 */
 	virtual const SciSpan<const byte> getResPointer() const = 0;
 
 	/**
-	 * Reads the pixel at the given coordinates. This method
-	 * is valid only for CelObjView and CelObjPic.
+	 * Reads the pixel at the given coordinates. This method is valid only for
+	 * CelObjView and CelObjPic.
 	 */
 	virtual uint8 readPixel(const uint16 x, const uint16 y, const bool mirrorX) const;
 
 	/**
-	 * Submits the palette from this cel to the palette
-	 * manager for integration into the master screen
-	 * palette.
+	 * Submits the palette from this cel to the palette manager for integration
+	 * into the master screen palette.
 	 */
 	void submitPalette() const;
 
@@ -454,7 +427,8 @@ private:
 	void drawUncompHzFlipMap(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const;
 	void scaleDrawMap(Buffer &target, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition) const;
 	void scaleDrawUncompMap(Buffer &target, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition) const;
-	// NOTE: The original includes versions of the above functions with priority parameters, which were not actually used in SCI32
+	// SSCI includes versions of the above functions with priority parameters
+	// which are not actually used in SCI32
 
 	void drawHzFlipNoMD(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const;
 	void drawNoFlipNoMD(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const;
@@ -464,37 +438,34 @@ private:
 	void drawUncompHzFlipNoMDNoSkip(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const;
 	void scaleDrawNoMD(Buffer &target, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition) const;
 	void scaleDrawUncompNoMD(Buffer &target, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition) const;
-	// NOTE: The original includes versions of the above functions with priority parameters, which were not actually used in SCI32
+	// SSCI includes versions of the above functions with priority parameters
+	// which are not actually used in SCI32
 
 #pragma mark -
 #pragma mark CelObj - Caching
 protected:
 	/**
-	 * A monotonically increasing cache ID used to identify
-	 * the least recently used item in the cache for
-	 * replacement.
+	 * A monotonically increasing cache ID used to identify the least recently
+	 * used item in the cache for replacement.
 	 */
 	static int _nextCacheId;
 
 	/**
-	 * A cache of cel objects used to avoid reinitialisation
-	 * overhead for cels with the same CelInfo32.
+	 * A cache of cel objects used to avoid reinitialisation overhead for cels
+	 * with the same CelInfo32.
 	 */
-	// NOTE: At least SQ6 uses a fixed cache size of 100.
-	static CelCache *_cache;
+	static Common::ScopedPtr<CelCache> _cache;
 
 	/**
-	 * Searches the cel cache for a CelObj matching the
-	 * provided CelInfo32. If not found, -1 is returned.
-	 * nextInsertIndex will receive the index of the oldest
-	 * item in the cache, which can be used to replace
-	 * the oldest item with a newer item.
+	 * Searches the cel cache for a CelObj matching the provided CelInfo32. If
+	 * not found, -1 is returned. `nextInsertIndex` will receive the index of
+	 * the oldest item in the cache, which can be used to replace the oldest
+	 * item with a newer item.
 	 */
 	int searchCache(const CelInfo32 &celInfo, int *nextInsertIndex) const;
 
 	/**
-	 * Puts a copy of this CelObj into the cache at the
-	 * given cache index.
+	 * Puts a copy of this CelObj into the cache at the given cache index.
 	 */
 	void putCopyInCache(int index) const;
 };
@@ -503,22 +474,20 @@ protected:
 #pragma mark CelObjView
 
 /**
- * A CelObjView is the drawing primitive for a View type
- * resource. Each CelObjView corresponds to a single cel
- * within a single loop of a view.
+ * A CelObjView is the drawing primitive for a View type resource. Each
+ * CelObjView corresponds to a single cel within a single loop of a view.
  */
 class CelObjView : public CelObj {
 private:
 	/**
-	 * Analyses resources without baked-in remap flags
-	 * to determine whether or not they should be remapped.
+	 * Analyses resources without baked-in remap flags to determine whether or
+	 * not they should be remapped.
 	 */
 	bool analyzeUncompressedForRemap() const;
 
 	/**
-	 * Analyses compressed resources without baked-in remap
-	 * flags to determine whether or not they should be
-	 * remapped.
+	 * Analyses compressed resources without baked-in remap flags to determine
+	 * whether or not they should be remapped.
 	 */
 	bool analyzeForRemap() const;
 
@@ -532,9 +501,8 @@ public:
 	static int16 getNumCels(const GuiResourceId viewId, const int16 loopNo);
 
 	/**
-	 * Draws the cel to the target buffer using the
-	 * positioning, mirroring, and scaling information from
-	 * the provided arguments.
+	 * Draws the cel to the target buffer using the positioning, mirroring, and
+	 * scaling information from the provided arguments.
 	 */
 	void draw(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition, bool mirrorX, const Ratio &scaleX, const Ratio &scaleY);
 
@@ -548,16 +516,14 @@ public:
 #pragma mark CelObjPic
 
 /**
- * A CelObjPic is the drawing primitive for a Picture type
- * resource. Each CelObjPic corresponds to a single cel
- * within a picture.
+ * A CelObjPic is the drawing primitive for a Picture type resource. Each
+ * CelObjPic corresponds to a single cel within a picture.
  */
 class CelObjPic : public CelObj {
 private:
 	/**
-	 * Analyses uncompressed resources without baked-in skip
-	 * flags to determine whether or not they can use fast
-	 * blitting.
+	 * Analyses uncompressed resources without baked-in skip flags to determine
+	 * whether or not they can use fast blitting.
 	 */
 	bool analyzeUncompressedForSkip() const;
 
@@ -568,14 +534,13 @@ public:
 	uint8 _celCount;
 
 	/**
-	 * The position of this cel relative to the top-left
-	 * corner of the picture.
+	 * The position of this cel relative to the top-left corner of the picture.
 	 */
 	Common::Point _relativePosition;
 
 	/**
-	 * The z-buffer priority for this cel. Higher prorities
-	 * are drawn on top of lower priorities.
+	 * The z-buffer priority for this cel. Higher prorities are drawn on top of
+	 * lower priorities.
 	 */
 	int16 _priority;
 
@@ -593,10 +558,9 @@ public:
 #pragma mark CelObjMem
 
 /**
- * A CelObjMem is the drawing primitive for arbitrary
- * bitmaps generated in memory. Generated bitmaps in SCI32
- * include text & vector drawings and per-pixel screen
- * transitions like dissolves.
+ * A CelObjMem is the drawing primitive for arbitrary bitmaps generated in
+ * memory. Generated bitmaps in SCI32 include text & vector drawings and
+ * per-pixel screen transitions like dissolves.
  */
 class CelObjMem : public CelObj {
 public:


Commit: ce13b1699aa95743573b07064ee27457d0b52968
    https://github.com/scummvm/scummvm/commit/ce13b1699aa95743573b07064ee27457d0b52968
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:56:25-05:00

Commit Message:
SCI32: Clean up Robot decoder

* Rewrap comments to 80 columns
* Clarify comments where possible
* Remove resolved TODOs

Changed paths:
    engines/sci/video/robot_decoder.cpp
    engines/sci/video/robot_decoder.h


diff --git a/engines/sci/video/robot_decoder.cpp b/engines/sci/video/robot_decoder.cpp
index 79079ed..49ca226 100644
--- a/engines/sci/video/robot_decoder.cpp
+++ b/engines/sci/video/robot_decoder.cpp
@@ -112,8 +112,8 @@ bool RobotAudioStream::addPacket(const RobotAudioPacket &packet) {
 	// 4 (odd).
 	const int8 bufferIndex = packet.position % 4 ? 1 : 0;
 
-	// Packet 0 is the first primer, packet 2 is the second primer,
-	// packet 4+ are regular audio data
+	// Packet 0 is the first primer, packet 2 is the second primer, packet 4+
+	// are regular audio data
 	if (packet.position <= 2 && _firstPacketPosition == -1) {
 		_readHead = 0;
 		_readHeadAbs = 0;
@@ -445,8 +445,8 @@ void RobotDecoder::initVideo(const int16 x, const int16 y, const int16 scale, co
 	_maxFrameRate = _frameRate + kMaxFrameRateDrift;
 
 	if (_xResolution == 0 || _yResolution == 0) {
-		// TODO: Default values were taken from RESOURCE.CFG hires property
-		// if it exists, so need to check games' configuration files for those
+		// In SSCI, default values were taken from RESOURCE.CFG hires property
+		// if it exists, but no games seem to take advantage of this
 		_xResolution = g_sci->_gfxFrameout->getCurrentBuffer().screenWidth;
 		_yResolution = g_sci->_gfxFrameout->getCurrentBuffer().screenHeight;
 	}
@@ -1386,12 +1386,8 @@ void RobotDecoder::doVersion5(const bool shouldSubmitAudio) {
 	for (RobotScreenItemList::size_type i = 0; i < screenItemCount; ++i) {
 		Common::Point position(_screenItemX[i], _screenItemY[i]);
 
-// TODO: Version 6 robot?
-//		int scaleXRemainder;
 		if (_scaleInfo.signal == kScaleSignalManual) {
 			position.x = (position.x * _scaleInfo.x) / 128;
-// TODO: Version 6 robot?
-//			scaleXRemainder = (position.x * _scaleInfo.x) % 128;
 			position.y = (position.y * _scaleInfo.y) / 128;
 		}
 
@@ -1400,8 +1396,6 @@ void RobotDecoder::doVersion5(const bool shouldSubmitAudio) {
 			celInfo.bitmap = _celHandles[i].bitmapId;
 			ScreenItem *screenItem = new ScreenItem(_planeId, celInfo, position, _scaleInfo);
 			_screenItemList[i] = screenItem;
-			// TODO: Version 6 robot?
-			// screenItem->_field_30 = scaleXRemainder;
 
 			if (_priority == -1) {
 				screenItem->_fixedPriority = false;
@@ -1414,8 +1408,6 @@ void RobotDecoder::doVersion5(const bool shouldSubmitAudio) {
 			ScreenItem *screenItem = _screenItemList[i];
 			screenItem->_celInfo.bitmap = _celHandles[i].bitmapId;
 			screenItem->_position = position;
-			// TODO: Version 6 robot?
-			// screenItem->_field_30 = scaleXRemainder;
 
 			if (_priority == -1) {
 				screenItem->_fixedPriority = false;
@@ -1570,7 +1562,7 @@ void RobotDecoder::preallocateCelMemory(const byte *rawVideoData, const int16 nu
 	for (int i = 0; i < numFixedCels; ++i) {
 		CelHandleInfo &celHandle = _celHandles[i];
 
-		// NOTE: There was a check to see if the cel handle was not allocated
+		// In SSCI, there was a check to see if the cel handle was not allocated
 		// here, for some reason, which would mean that nothing was ever
 		// allocated from fixed cels, because the _celHandles array just got
 		// deleted and recreated...
diff --git a/engines/sci/video/robot_decoder.h b/engines/sci/video/robot_decoder.h
index aa1d9da..314628e 100644
--- a/engines/sci/video/robot_decoder.h
+++ b/engines/sci/video/robot_decoder.h
@@ -52,7 +52,10 @@ class SegManager;
 // Unlike traditional AV formats, Robot videos almost always require playback
 // within the game engine because certain information (like the resolution of
 // the Robot coordinates and the background for the video) is dependent on data
-// that does not exist within the Robot file itself.
+// that does not exist within the Robot file itself. In version 6, robots could
+// also participate in palette remapping by drawing remap pixels, and the
+// information for processing these pixels is also not stored within the Robot
+// file.
 //
 // The Robot container consists of a file header, an optional primer audio
 // section, an optional colour palette, a frame seek index, a set of cuepoints,
@@ -66,9 +69,9 @@ class SegManager;
 // contiguous data blocks, each of which can be independently compressed with
 // LZS or left uncompressed. An entire cel can also be line decimated, where
 // lines are deleted from the source bitmap at compression time and are
-// reconstructed by decompression using line doubling. Each cel also includes
-// coordinates where it should be placed within the video frame, relative to the
-// top-left corner of the frame.
+// reconstructed by decompression using line interpolation. Each cel also
+// includes coordinates where it should be placed within the video frame,
+// relative to the top-left corner of the frame.
 //
 // Audio coding is fixed-length, and all audio blocks except for the primer
 // audio are the same size. Audio is encoded with Sierra SOL DPCM16 compression,
@@ -254,8 +257,8 @@ class SegManager;
 #pragma mark RobotAudioStream
 
 /**
- * A Robot audio stream is a simple loop buffer
- * that accepts audio blocks from the Robot engine.
+ * A Robot audio stream is a simple loop buffer that accepts audio blocks from
+ * the Robot engine.
  */
 class RobotAudioStream : public Audio::AudioStream {
 public:
@@ -266,40 +269,34 @@ public:
 		kRobotSampleRate = 22050,
 
 		/**
-		 * Multiplier for the size of a packet that
-		 * is being expanded by writing to every other
-		 * byte of the target buffer.
+		 * Multiplier for the size of a packet that is being expanded by writing
+		 * to every other byte of the target buffer.
 		 */
 		kEOSExpansion    = 2
 	};
 
 	/**
-	 * Playback state information. Used for framerate
-	 * calculation.
+	 * Playback state information. Used for framerate calculation.
 	 */
 	struct StreamState {
 		/**
-		 * The current position of the read head of
-		 * the audio stream.
+		 * The current position of the read head of the audio stream.
 		 */
 		int bytesPlaying;
 
 		/**
-		 * The sample rate of the audio stream.
-		 * Always 22050.
+		 * The sample rate of the audio stream. Always 22050.
 		 */
 		uint16 rate;
 
 		/**
-		 * The bit depth of the audio stream.
-		 * Always 16.
+		 * The bit depth of the audio stream. Always 16.
 		 */
 		uint8 bits;
 	};
 
 	/**
-	 * A single packet of compressed audio from a
-	 * Robot data stream.
+	 * A single packet of compressed audio from a Robot data stream.
 	 */
 	struct RobotAudioPacket {
 		/**
@@ -314,8 +311,7 @@ public:
 		int dataSize;
 
 		/**
-		 * The uncompressed, file-relative position
-		 * of this audio packet.
+		 * The uncompressed, file-relative position of this audio packet.
 		 */
 		int position;
 
@@ -328,20 +324,19 @@ public:
 
 	/**
 	 * Adds a new audio packet to the stream.
-	 * @returns `true` if the audio packet was fully
-	 * consumed, otherwise `false`.
+	 * @returns `true` if the audio packet was fully consumed, otherwise
+	 * `false`.
 	 */
 	bool addPacket(const RobotAudioPacket &packet);
 
 	/**
-	 * Prevents any additional audio packets from
-	 * being added to the audio stream.
+	 * Prevents any additional audio packets from being added to the audio
+	 * stream.
 	 */
 	void finish();
 
 	/**
-	 * Returns the current status of the audio
-	 * stream.
+	 * Returns the current status of the audio stream.
 	 */
 	StreamState getStatus() const;
 
@@ -349,8 +344,7 @@ private:
 	Common::Mutex _mutex;
 
 	/**
-	 * Loop buffer for playback. Contains decompressed
-	 * 16-bit PCM samples.
+	 * Loop buffer for playback. Contains decompressed 16-bit PCM samples.
 	 */
 	byte *_loopBuffer;
 
@@ -360,66 +354,57 @@ private:
 	int32 _loopBufferSize;
 
 	/**
-	 * The position of the read head within the loop
-	 * buffer, in bytes.
+	 * The position of the read head within the loop buffer, in bytes.
 	 */
 	int32 _readHead;
 
 	/**
-	 * The lowest file position that can be buffered,
-	 * in uncompressed bytes.
+	 * The lowest file position that can be buffered, in uncompressed bytes.
 	 */
 	int32 _readHeadAbs;
 
 	/**
-	 * The highest file position that can be buffered,
-	 * in uncompressed bytes.
+	 * The highest file position that can be buffered, in uncompressed bytes.
 	 */
 	int32 _maxWriteAbs;
 
 	/**
-	 * The highest file position, in uncompressed bytes,
-	 * that has been written to the stream.
-	 * Different from `_maxWriteAbs`, which is the highest
-	 * uncompressed position which *can* be written right
-	 * now.
+	 * The highest file position, in uncompressed bytes, that has been written
+	 * to the stream. This is different from `_maxWriteAbs`, which is the
+	 * highest uncompressed position which *can* be written right now.
 	 */
 	int32 _writeHeadAbs;
 
 	/**
-	 * The highest file position, in uncompressed bytes,
-	 * that has been written to the even & odd sides of
-	 * the stream.
+	 * The highest file position, in uncompressed bytes, that has been written
+	 * to the even & odd sides of the stream.
 	 *
-	 * Index 0 corresponds to the 'even' side; index
-	 * 1 correspond to the 'odd' side.
+	 * Index 0 corresponds to the 'even' side; index 1 corresponds to the 'odd'
+	 * side.
 	 */
 	int32 _jointMin[2];
 
 	/**
-	 * When `true`, the stream is waiting for all primer
-	 * blocks to be received before allowing playback to
-	 * begin.
+	 * When `true`, the stream is waiting for all primer blocks to be received
+	 * before allowing playback to begin.
 	 */
 	bool _waiting;
 
 	/**
-	 * When `true`, the stream will accept no more audio
-	 * blocks.
+	 * When `true`, the stream will accept no more audio blocks.
 	 */
 	bool _finished;
 
 	/**
-	 * The uncompressed position of the first packet of
-	 * robot data. Used to decide whether all primer
-	 * blocks have been received and the stream should
+	 * The uncompressed position of the first packet of robot data. Used to
+	 * decide whether all primer blocks have been received and the stream should
 	 * be started.
 	 */
 	int32 _firstPacketPosition;
 
 	/**
-	 * Decompression buffer, used to temporarily store
-	 * an uncompressed block of audio data.
+	 * Decompression buffer, used to temporarily store an uncompressed block of
+	 * audio data.
 	 */
 	byte *_decompressionBuffer;
 
@@ -429,23 +414,20 @@ private:
 	int32 _decompressionBufferSize;
 
 	/**
-	 * The position of the packet currently in the
-	 * decompression buffer. Used to avoid
-	 * re-decompressing audio data that has already
-	 * been decompressed during a partial packet read.
+	 * The position of the packet currently in the decompression buffer. Used to
+	 * avoid re-decompressing audio data that has already been decompressed
+	 * during a partial packet read.
 	 */
 	int32 _decompressionBufferPosition;
 
 	/**
-	 * Calculates the absolute ranges for new fills
-	 * into the loop buffer.
+	 * Calculates the absolute ranges for new fills into the loop buffer.
 	 */
 	void fillRobotBuffer(const RobotAudioPacket &packet, const int8 bufferIndex);
 
 	/**
-	 * Interpolates `numSamples` samples from the read
-	 * head, if no true samples were written for one
-	 * (or both) of the joint channels.
+	 * Interpolates `numSamples` samples from the read head, if no true samples
+	 * were written for one (or both) of the joint channels.
 	 */
 	void interpolateMissingSamples(const int32 numSamples);
 
@@ -501,9 +483,8 @@ public:
 	};
 
 	enum {
-		// Special high value used to represent
-		// parameters that should be left unchanged
-		// when calling `showFrame`
+		// Special high value used to represent parameters that should be left
+		// unchanged when calling `showFrame`
 		kUnspecified = 50000
 	};
 
@@ -530,8 +511,8 @@ private:
 		kCueListSize           = 256,
 
 		/**
-		 * Maximum number of 'fixed' cels that never
-		 * change for the duration of a robot.
+		 * Maximum number of 'fixed' cels that never change for the duration of
+		 * a robot.
 		 */
 		kFixedCelListSize      = 4,
 
@@ -541,27 +522,22 @@ private:
 		kRawPaletteSize        = 1200,
 
 		/**
-		 * The size of a frame of Robot data. This
-		 * value was used to align the first block of
-		 * data after the main Robot header to the next
-		 * CD sector.
+		 * The size of a frame of Robot data. This value was used to align the
+		 * first block of data after the main Robot header to the next CD
+		 * sector.
 		 */
 		kRobotFrameSize        = 2048,
 
 		/**
-		 * The size of a block of zero-compressed
-		 * audio. Used to fill audio when the size of
-		 * an audio packet does not match the expected
-		 * packet size.
+		 * The size of a block of zero-compressed audio. Used to fill audio when
+		 * the size of an audio packet does not match the expected packet size.
 		 */
 		kRobotZeroCompressSize = 2048,
 
 		/**
-		 * The size of the audio block header, in bytes.
-		 * The audio block header consists of the
-		 * compressed size of the audio in the record,
-		 * plus the position of the audio in the
-		 * compressed data stream.
+		 * The size of the audio block header, in bytes. The audio block header
+		 * consists of the compressed size of the audio in the record, plus the
+		 * position of the audio in the compressed data stream.
 		 */
 		kAudioBlockHeaderSize  = 8,
 
@@ -571,23 +547,20 @@ private:
 		kCelHeaderSize         = 22,
 
 		/**
-		 * The maximum amount that the frame rate is
-		 * allowed to drift from the nominal frame rate
-		 * in order to correct for AV drift or slow
-		 * playback.
+		 * The maximum amount that the frame rate is allowed to drift from the
+		 * nominal frame rate in order to correct for AV drift or slow playback.
 		 */
 		kMaxFrameRateDrift     = 1
 	};
 
 	/**
-	 * The version number for the currently loaded
-	 * robot.
+	 * The version number for the currently loaded robot.
 	 *
 	 * There are several known versions of robot:
 	 *
 	 * v2: before Nov 1994; no known examples
 	 * v3: before Nov 1994; no known examples
-	 * v4: Jan 1995; PQ:SWAT demo
+	 * v4: Jan 1995; KQ7 1.65, PQ:SWAT demo
 	 * v5: Mar 1995; SCI2.1 and SCI3 games
 	 * v6: SCI3 games
 	 */
@@ -625,8 +598,8 @@ private:
 #pragma mark Playback
 public:
 	/**
-	 * Opens a robot file for playback.
-	 * Newly opened robots are paused by default.
+	 * Opens a robot file for playback. Newly opened robots are paused by
+	 * default.
 	 */
 	void open(const GuiResourceId robotId, const reg_t plane, const int16 priority, const int16 x, const int16 y, const int16 scale);
 
@@ -636,8 +609,8 @@ public:
 	void close();
 
 	/**
-	 * Pauses the robot. Once paused, the audio for a robot
-	 * is disabled until the end of playback.
+	 * Pauses the robot. Once paused, the audio for a robot is disabled until
+	 * the end of playback.
 	 */
 	void pause();
 
@@ -654,8 +627,7 @@ public:
 	void showFrame(const uint16 frameNo, const uint16 newX, const uint16 newY, const uint16 newPriority);
 
 	/**
-	 * Retrieves the value associated with the
-	 * current cue point.
+	 * Retrieves the value associated with the current cue point.
 	 */
 	int16 getCue() const;
 
@@ -688,27 +660,23 @@ private:
 	PositionList _recordPositions;
 
 	/**
-	 * The offset of the Robot file within a
-	 * resource bundle.
+	 * The offset of the Robot file within a resource bundle.
 	 */
 	int32 _fileOffset;
 
 	/**
-	 * A list of cue times that is updated to
-	 * prevent earlier cue values from being
-	 * given to the game more than once.
+	 * A list of cue times that is updated to prevent earlier cue values from
+	 * being given to the game more than once.
 	 */
 	mutable int32 _cueTimes[kCueListSize];
 
 	/**
-	 * The original list of cue times from the
-	 * raw Robot data.
+	 * The original list of cue times from the raw Robot data.
 	 */
 	int32 _masterCueTimes[kCueListSize];
 
 	/**
-	 * The list of values to provide to a game
-	 * when a cue value is requested.
+	 * The list of values to provide to a game when a cue value is requested.
 	 */
 	int32 _cueValues[kCueListSize];
 
@@ -723,23 +691,20 @@ private:
 	int16 _normalFrameRate;
 
 	/**
-	 * The minimal playback frame rate. Used to
-	 * correct for AV sync drift when the video
-	 * is more than one frame ahead of the audio.
+	 * The minimal playback frame rate. Used to correct for AV sync drift when
+	 * the video is more than one frame ahead of the audio.
 	 */
 	int16 _minFrameRate;
 
 	/**
-	 * The maximum playback frame rate. Used to
-	 * correct for AV sync drift when the video
-	 * is more than one frame behind the audio.
+	 * The maximum playback frame rate. Used to correct for AV sync drift when
+	 * the video is more than one frame behind the audio.
 	 */
 	int16 _maxFrameRate;
 
 	/**
-	 * The maximum number of record blocks that
-	 * can be skipped without causing audio to
-	 * drop out.
+	 * The maximum number of record blocks that can be skipped without causing
+	 * audio to drop out.
 	 */
 	int16 _maxSkippablePackets;
 
@@ -754,32 +719,28 @@ private:
 	int _previousFrameNo;
 
 	/**
-	 * The time, in ticks, when the robot was
-	 * last started or resumed.
+	 * The time, in ticks, when the robot was last started or resumed.
 	 */
 	int32 _startTime;
 
 	/**
-	 * The first frame displayed when the
-	 * robot was resumed.
+	 * The first frame displayed when the robot was resumed.
 	 */
 	int32 _startFrameNo;
 
 	/**
-	 * The last frame displayed when the robot
-	 * was resumed.
+	 * The last frame displayed when the robot was resumed.
 	 */
 	int32 _startingFrameNo;
 
 	/**
-	 * Seeks the raw data stream to the record for
-	 * the given frame number.
+	 * Seeks the raw data stream to the record for the given frame number.
 	 */
 	bool seekToFrame(const int frameNo);
 
 	/**
-	 * Sets the start time and frame of the robot
-	 * when the robot is started or resumed.
+	 * Sets the start time and frame of the robot when the robot is started or
+	 * resumed.
 	 */
 	void setRobotTime(const int frameNo);
 
@@ -787,11 +748,10 @@ private:
 #pragma mark Timing
 private:
 	/**
-	 * This class tracks the amount of time it takes for
-	 * a frame of robot animation to be rendered. This
-	 * information is used by the player to speculatively
-	 * skip rendering of future frames to keep the
-	 * animation in sync with the robot audio.
+	 * This class tracks the amount of time it takes for a frame of robot
+	 * animation to be rendered. This information is used by the player to
+	 * speculatively skip rendering of future frames to keep the animation in
+	 * sync with the robot audio.
 	 */
 	class DelayTime {
 	public:
@@ -808,14 +768,13 @@ private:
 		void endTiming();
 
 		/**
-		 * Returns whether or not timing is currently in
-		 * progress.
+		 * Returns whether or not timing is currently in progress.
 		 */
 		bool timingInProgress() const;
 
 		/**
-		 * Returns the median time, in ticks, of the
-		 * currently stored timing samples.
+		 * Returns the median time, in ticks, of the currently stored timing
+		 * samples.
 		 */
 		int predictedTicks() const;
 
@@ -823,24 +782,23 @@ private:
 		RobotDecoder *_decoder;
 
 		/**
-		 * The start time, in ticks, of the current timing
-		 * loop. If no loop is in progress, the value is 0.
+		 * The start time, in ticks, of the current timing loop. If no loop is
+		 * in progress, the value is 0.
 		 *
-		 * @note This is slightly different than SSCI where
-		 * the not-timing value was -1.
+		 * @note This is slightly different than SSCI where the not-timing value
+		 * was -1.
 		 */
 		uint32 _startTime;
 
 		/**
-		 * A sorted list containing the timing data for
-		 * the last `kDelayListSize` frames, in ticks.
+		 * A sorted list containing the timing data for the last
+		 * `kDelayListSize` frames, in ticks.
 		 */
 		int _delays[kDelayListSize];
 
 		/**
-		 * A list of monotonically increasing identifiers
-		 * used to identify and replace the oldest sample
-		 * in the `_delays` array when finishing the
+		 * A list of monotonically increasing identifiers used to identify and
+		 * replace the oldest sample in the `_delays` array when finishing the
 		 * next timing operation.
 		 */
 		uint _timestamps[kDelayListSize];
@@ -862,17 +820,14 @@ private:
 	};
 
 	/**
-	 * Calculates the next frame number that needs
-	 * to be rendered, using the timing data
-	 * collected by DelayTime.
+	 * Calculates the next frame number that needs to be rendered, using the
+	 * timing data collected by DelayTime.
 	 */
 	uint16 calculateNextFrameNo(const uint32 extraTicks = 0) const;
 
 	/**
-	 * Calculates and returns the number of frames
-	 * that should be rendered in `ticks` time,
-	 * according to the current target frame rate
-	 * of the robot.
+	 * Calculates and returns the number of frames that should be rendered in
+	 * `ticks` time, according to the current target frame rate of the robot.
 	 */
 	uint32 ticksToFrames(const uint32 ticks) const;
 
@@ -891,15 +846,13 @@ private:
 private:
 	enum {
 		/**
-		 * The number of ticks that should elapse
-		 * between each AV sync check.
+		 * The number of ticks that should elapse between each AV sync check.
 		 */
 		kAudioSyncCheckInterval = 5 * 60 /* 5 seconds */
 	};
 
 	/**
-	 * The status of the audio track of a Robot
-	 * animation.
+	 * The status of the audio track of a Robot animation.
 	 */
 	enum RobotAudioStatus {
 		kRobotAudioReady    = 1,
@@ -913,8 +866,7 @@ private:
 #pragma mark Audio - AudioList
 private:
 	/**
-	 * This class manages packetized audio playback
-	 * for robots.
+	 * This class manages packetized audio playback for robots.
 	 */
 	class AudioList {
 	public:
@@ -926,8 +878,8 @@ private:
 		void startAudioNow();
 
 		/**
-		 * Stops playback of robot audio, allowing
-		 * any queued audio to finish playing back.
+		 * Stops playback of robot audio, allowing any queued audio to finish
+		 * playing back.
 		 */
 		void stopAudio();
 
@@ -937,40 +889,36 @@ private:
 		void stopAudioNow();
 
 		/**
-		 * Submits as many blocks of audio as possible
-		 * to the audio engine.
+		 * Submits as many blocks of audio as possible to the audio engine.
 		 */
 		void submitDriverMax();
 
 		/**
 		 * Adds a new AudioBlock to the queue.
 		 *
-		 * @param position The absolute position of the
-		 * audio for the block, in compressed bytes.
+		 * @param position The absolute position of the audio for the block, in
+		 *                 compressed bytes.
 		 * @param size The size of the buffer.
-		 * @param buffer A pointer to compressed audio
-		 * data that will be copied into the new
-		 * AudioBlock.
+		 * @param buffer A pointer to compressed audio data that will be copied
+		 *               into the new AudioBlock.
 		 */
 		void addBlock(const int position, const int size, const byte *buffer);
 
 		/**
-		 * Immediately stops any active playback and
-		 * purges all audio data in the audio list.
+		 * Immediately stops any active playback and purges all audio data in
+		 * the audio list.
 		 */
 		void reset();
 
 		/**
-		 * Pauses the robot audio channel in
-		 * preparation for the first block of audio
-		 * data to be read.
+		 * Pauses the robot audio channel in preparation for the first block of
+		 * audio data to be read.
 		 */
 		void prepareForPrimer();
 
 		/**
-		 * Sets the audio offset which is used to
-		 * offset the position of audio packets
-		 * sent to the audio stream.
+		 * Sets the audio offset which is used to offset the position of audio
+		 * packets sent to the audio stream.
 		 */
 		void setAudioOffset(const int offset);
 
@@ -979,8 +927,7 @@ private:
 
 	private:
 		/**
-		 * AudioBlock represents a block of audio
-		 * from the Robot's audio track.
+		 * AudioBlock represents a block of audio from the Robot's audio track.
 		 */
 		class AudioBlock {
 		public:
@@ -988,44 +935,37 @@ private:
 			~AudioBlock();
 
 			/**
-			 * Submits the block of audio to the
-			 * audio manager.
-			 * @returns true if the block was fully
-			 * read, or false if the block was not
-			 * read or only partially read.
+			 * Submits the block of audio to the audio manager.
+			 * @returns true if the block was fully read, or false if the block
+			 * was not read or only partially read.
 			 */
 			bool submit(const int startOffset);
 
 		private:
 			/**
-			 * The absolute position, in compressed
-			 * bytes, of this audio block's audio
-			 * data in the audio stream.
+			 * The absolute position, in compressed bytes, of this audio block's
+			 * audio data in the audio stream.
 			 */
 			int _position;
 
 			/**
-			 * The compressed size, in bytes, of
-			 * this audio block's audio data.
+			 * The compressed size, in bytes, of this audio block's audio data.
 			 */
 			int _size;
 
 			/**
-			 * A buffer containing raw
-			 * SOL-compressed audio data.
+			 * A buffer containing raw SOL-compressed audio data.
 			 */
 			byte *_data;
 		};
 
 		/**
-		 * The list of compressed audio blocks
-		 * submitted for playback.
+		 * The list of compressed audio blocks submitted for playback.
 		 */
 		AudioBlock *_blocks[kAudioListSize];
 
 		/**
-		 * The number of blocks in `_blocks` that are
-		 * ready to be submitted.
+		 * The number of blocks in `_blocks` that are ready to be submitted.
 		 */
 		uint8 _blocksSize;
 
@@ -1040,8 +980,7 @@ private:
 		uint8 _newestBlockIndex;
 
 		/**
-		 * The offset used when sending packets to the
-		 * audio stream.
+		 * The offset used when sending packets to the audio stream.
 		 */
 		int _startOffset;
 
@@ -1068,46 +1007,42 @@ private:
 	AudioList _audioList;
 
 	/**
-	 * The size, in bytes, of a block of audio data,
-	 * excluding the audio block header.
+	 * The size, in bytes, of a block of audio data, excluding the audio block
+	 * header.
 	 */
 	uint16 _audioBlockSize;
 
 	/**
-	 * The expected size of a block of audio data,
-	 * in bytes, excluding the audio block header.
+	 * The expected size of a block of audio data, in bytes, excluding the audio
+	 * block header.
 	 */
 	int16 _expectedAudioBlockSize;
 
 	/**
-	 * The number of compressed audio bytes that are
-	 * needed per frame to fill the audio buffer
-	 * without causing audio to drop out.
+	 * The number of compressed audio bytes that are needed per frame to fill
+	 * the audio buffer without causing audio to drop out.
 	 */
 	int16 _audioRecordInterval;
 
 	/**
-	 * If true, primer audio buffers should be filled
-	 * with silence instead of trying to read buffers
-	 * from the Robot data.
+	 * If true, primer audio buffers should be filled with silence instead of
+	 * trying to read buffers from the Robot data.
 	 */
 	uint16 _primerZeroCompressFlag;
 
 	/**
-	 * The size, in bytes, of the primer audio in the
-	 * Robot, including any extra alignment padding.
+	 * The size, in bytes, of the primer audio in the Robot, including any extra
+	 * alignment padding.
 	 */
 	uint16 _primerReservedSize;
 
 	/**
-	 * The combined size, in bytes, of the even and odd
-	 * primer channels.
+	 * The combined size, in bytes, of the even and odd primer channels.
 	 */
 	int32 _totalPrimerSize;
 
 	/**
-	 * The absolute offset of the primer audio data in
-	 * the robot data stream.
+	 * The absolute offset of the primer audio data in the robot data stream.
 	 */
 	int32 _primerPosition;
 
@@ -1122,54 +1057,47 @@ private:
 	int32 _oddPrimerSize;
 
 	/**
-	 * The absolute position in the audio stream of
-	 * the first audio packet.
+	 * The absolute position in the audio stream of the first audio packet.
 	 */
 	int32 _firstAudioRecordPosition;
 
 	/**
-	 * A temporary buffer used to hold one frame of
-	 * raw (DPCM-compressed) audio when reading audio
-	 * records from the robot stream.
+	 * A temporary buffer used to hold one frame of raw (DPCM-compressed) audio
+	 * when reading audio records from the robot stream.
 	 */
 	byte *_audioBuffer;
 
 	/**
-	 * The next tick count when AV sync should be
-	 * checked and framerate adjustments made, if
-	 * necessary.
+	 * The next tick count when AV sync should be checked and framerate
+	 * adjustments made, if necessary.
 	 */
 	uint32 _checkAudioSyncTime;
 
 	/**
-	 * Primes the audio buffer with the first frame
-	 * of audio data.
+	 * Primes the audio buffer with the first frame of audio data.
 	 *
 	 * @note `primeAudio` was `InitAudio` in SSCI
 	 */
 	bool primeAudio(const uint32 startTick);
 
 	/**
-	 * Reads primer data from the robot data stream
-	 * and puts it into the given buffers.
+	 * Reads primer data from the robot data stream and puts it into the given
+	 * buffers.
 	 */
 	bool readPrimerData(byte *outEvenBuffer, byte *outOddBuffer);
 
 	/**
-	 * Reads audio data for the given frame number
-	 * into the given buffer.
+	 * Reads audio data for the given frame number into the given buffer.
 	 *
-	 * @param outAudioPosition The position of the
-	 * audio, in compressed bytes, in the data stream.
-	 * @param outAudioSize The size of the audio data,
-	 * in compressed bytes.
+	 * @param outAudioPosition The position of the audio, in compressed bytes,
+	 *                         in the data stream.
+	 * @param outAudioSize The size of the audio data, in compressed bytes.
 	 */
 	bool readAudioDataFromRecord(const int frameNo, byte *outBuffer, int &outAudioPosition, int &outAudioSize);
 
 	/**
-	 * Submits part of the audio packet of the given
-	 * frame to the audio list, starting `startPosition`
-	 * bytes into the audio.
+	 * Submits part of the audio packet of the given frame to the audio list,
+	 * starting `startPosition` bytes into the audio.
 	 */
 	bool readPartialAudioRecordAndSubmit(const int startFrame, const int startPosition);
 
@@ -1198,35 +1126,33 @@ public:
 	}
 
 	/**
-	 * Puts the current dimensions of the robot, in game script
-	 * coordinates, into the given rect, and returns the total
-	 * number of frames in the robot animation.
+	 * Puts the current dimensions of the robot, in game script coordinates,
+	 * into the given rect, and returns the total number of frames in the robot
+	 * animation.
 	 */
 	uint16 getFrameSize(Common::Rect &outRect) const;
 
 	/**
-	 * Pumps the robot player for the next frame of video.
-	 * This is the main rendering function.
+	 * Pumps the robot player for the next frame of video. This is the main
+	 * rendering function.
 	 */
 	void doRobot();
 
 	/**
-	 * Submits any outstanding audio blocks that should
-	 * be added to the queue before the robot frame
-	 * becomes visible.
+	 * Submits any outstanding audio blocks that should be added to the queue
+	 * before the robot frame becomes visible.
 	 */
 	void frameAlmostVisible();
 
 	/**
-	 * Evaluates frame drift and makes modifications to
-	 * the player in order to ensure that future frames
-	 * will arrive on time.
+	 * Evaluates frame drift and makes modifications to the player in order to
+	 * ensure that future frames will arrive on time.
 	 */
 	void frameNowVisible();
 
 	/**
-	 * Scales a vertically compressed cel to its original
-	 * uncompressed dimensions.
+	 * Scales a vertically compressed cel to its original uncompressed
+	 * dimensions.
 	 */
 	void expandCel(byte *target, const byte* source, const int16 celWidth, const int16 celHeight) const;
 
@@ -1258,21 +1184,18 @@ private:
 		};
 
 		/**
-		 * A reg_t pointer to an in-memory
-		 * bitmap containing the cel.
+		 * A reg_t pointer to an in-memory bitmap containing the cel.
 		 */
 		reg_t bitmapId;
 
 		/**
-		 * The lifetime of the cel, either just
-		 * for this frame or for the entire
+		 * The lifetime of the cel, either just for this frame or for the entire
 		 * duration of the robot playback.
 		 */
 		CelHandleLifetime status;
 
 		/**
-		 * The size, in pixels, of the decompressed
-		 * cel.
+		 * The size, in pixels, of the decompressed cel.
 		 */
 		int area;
 
@@ -1298,16 +1221,14 @@ private:
 	void createCels5(const byte *rawVideoData, const int16 numCels, const bool usePalette);
 
 	/**
-	 * Creates a single screen item for a cel in a
-	 * version 5/6 robot.
+	 * Creates a single screen item for a cel in a version 5/6 robot.
 	 *
 	 * Returns the size, in bytes, of the raw cel data.
 	 */
 	uint32 createCel5(const byte *rawVideoData, const int16 screenItemIndex, const bool usePalette);
 
 	/**
-	 * Preallocates memory for the next `numCels` cels
-	 * in the robot data stream.
+	 * Preallocates memory for the next `numCels` cels in the robot data stream.
 	 */
 	void preallocateCelMemory(const byte *rawVideoData, const int16 numCels);
 
@@ -1322,8 +1243,7 @@ private:
 	reg_t _planeId;
 
 	/**
-	 * The origin of the robot animation, in screen
-	 * coordinates.
+	 * The origin of the robot animation, in screen coordinates.
 	 */
 	Common::Point _position;
 
@@ -1338,80 +1258,72 @@ private:
 	int16 _xResolution, _yResolution;
 
 	/**
-	 * Whether or not the coordinates read from robot
-	 * data are high resolution.
+	 * Whether or not the coordinates read from robot data are high resolution.
 	 */
 	bool _isHiRes;
 
 	/**
-	 * The maximum number of cels that will be rendered
-	 * on any given frame in this robot. Used for
-	 * preallocation of cel memory.
+	 * The maximum number of cels that will be rendered on any given frame in
+	 * this robot. Used for preallocation of cel memory.
 	 */
 	int16 _maxCelsPerFrame;
 
 	/**
-	 * The maximum areas, in pixels, for each of
-	 * the fixed cels in the robot. Used for
-	 * preallocation of cel memory.
+	 * The maximum areas, in pixels, for each of the fixed cels in the robot.
+	 * Used for preallocation of cel memory.
 	 */
 	MaxCelAreaList _maxCelArea;
 
 	/**
-	 * The hunk palette to use when rendering the
-	 * current frame, if the `usePalette` flag was set
-	 * in the robot header.
+	 * The hunk palette to use when rendering the current frame, if the
+	 * `usePalette` flag was set in the robot header.
 	 */
 	uint8 *_rawPalette;
 
 	/**
-	 * A list of the raw video data sizes, in bytes,
-	 * for each frame of the robot.
+	 * A list of the raw video data sizes, in bytes, for each frame of the
+	 * robot.
 	 */
 	VideoSizeList _videoSizes;
 
 	/**
-	 * A list of cels that will be present for the
-	 * entire duration of the robot animation.
+	 * A list of cels that will be present for the entire duration of the robot
+	 * animation.
 	 */
 	FixedCelsList _fixedCels;
 
 	/**
-	 * A list of handles for each cel in the current
-	 * frame.
+	 * A list of handles for each cel in the current frame.
 	 */
 	CelHandleList _celHandles;
 
 	/**
-	 * Scratch memory used to temporarily store
-	 * decompressed cel data for vertically squashed
-	 * cels.
+	 * Scratch memory used to temporarily store decompressed cel data for
+	 * vertically squashed cels.
 	 */
 	ScratchMemory _celDecompressionBuffer;
 
 	/**
-	 * The size, in bytes, of the squashed cel
-	 * decompression buffer.
+	 * The size, in bytes, of the squashed cel decompression buffer.
 	 */
 	int _celDecompressionArea;
 
 	/**
-	 * If true, the robot just started playing and
-	 * is awaiting output for the first frame.
+	 * If true, the robot just started playing and is awaiting output for the
+	 * first frame.
 	 */
 	bool _syncFrame;
 
 	/**
-	 * Scratch memory used to store the compressed robot
-	 * video data for the current frame.
+	 * Scratch memory used to store the compressed robot video data for the
+	 * current frame.
 	 */
 	ScratchMemory _doVersion5Scratch;
 
 	/**
-	 * When set to a non-negative value, forces the next
-	 * call to doRobot to render the given frame number
-	 * instead of whatever frame would have normally been
-	 * rendered.
+	 * When set to a non-negative value, forces the next call to doRobot to
+	 * render the given frame number instead of whatever frame would have
+	 * normally been rendered.
 	 */
 	mutable int _cueForceShowFrame;
 
@@ -1426,14 +1338,14 @@ private:
 	RobotScreenItemList _screenItemList;
 
 	/**
-	 * The positions of the various screen items in this
-	 * robot, in screen coordinates.
+	 * The positions of the various screen items in this robot, in screen
+	 * coordinates.
 	 */
 	Common::Array<int16> _screenItemX, _screenItemY;
 
 	/**
-	 * The raw position values from the cel header for
-	 * each screen item currently on-screen.
+	 * The raw position values from the cel header for each screen item
+	 * currently on-screen.
 	 */
 	Common::Array<int16> _originalScreenItemX, _originalScreenItemY;
 
@@ -1449,11 +1361,10 @@ private:
 	int16 _priority;
 
 	/**
-	 * The amount of visual vertical compression applied
-	 * to the current cel. A value of 100 means no
-	 * compression; a value above 100 indicates how much
-	 * the cel needs to be scaled along the y-axis to
-	 * return to its original dimensions.
+	 * The amount of visual vertical compression applied to the current cel. A
+	 * value of 100 means no compression; a value above 100 indicates how much
+	 * the cel needs to be scaled along the y-axis to return to its original
+	 * dimensions.
 	 */
 	uint8 _verticalScaleFactor;
 };


Commit: 8c9276e75a9097f6eb2856767f9e6a40eab3c5aa
    https://github.com/scummvm/scummvm/commit/8c9276e75a9097f6eb2856767f9e6a40eab3c5aa
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:56:25-05:00

Commit Message:
SCI32: Clean up script patch comments

Changed paths:
    engines/sci/engine/script_patches.cpp


diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 162d97e..3e37d13 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -2289,10 +2289,10 @@ static const uint16 lighthouseFlagResetPatch[] = {
 };
 
 // When doing a system check on the portal computer in the lighthouse, the game
-// counts up to 1024MB, one megabyte at a time. In the original engine, this
-// count speed would be video speed dependent, but with our frame rate
-// throttler, it takes 17 seconds. So, replace this slowness with a much faster
-// POST that is more accurate to the original game.
+// counts up to 1024MB, one megabyte at a time. In SSCI, this count speed would
+// be video speed dependent, but with our frame rate throttler, it takes 17
+// seconds. So, replace this slowness with a much faster POST that is more
+// accurate to the original game.
 // Applies to at least: US English 1.0c
 static const uint16 lighthouseMemoryCountSignature[] = {
 	SIG_MAGICDWORD,
@@ -6411,13 +6411,12 @@ static const uint16 ramaBenchmarkPatch[] = {
 };
 
 // RAMA uses a custom save game format that game scripts read and write
-// manually. The save game format serialises object references, which in the
-// original engine could be done just by writing int16s (since object references
-// were just 16-bit indexes), but in ScummVM we have to write the full 32-bit
-// reg_t. We hijack kFileIOReadWord/kFileIOWriteWord to do this for us, but we
-// need the game to agree to use those kFileIO calls instead of doing raw reads
-// and creating its own numbers, as it tries to do here in
-// `SaveManager::readWord`.
+// manually. The save game format serialises object references, which SSCI could
+// be done just by writing int16s (since object references were just 16-bit
+// indexes), but in ScummVM we have to write the full 32-bit reg_t. We hijack
+// kFileIOReadWord/kFileIOWriteWord to do this for us, but we need the game to
+// agree to use those kFileIO calls instead of doing raw reads and creating its
+// own numbers, as it tries to do here in `SaveManager::readWord`.
 static const uint16 ramaSerializeRegTSignature1[] = {
 	SIG_MAGICDWORD,
 	0x38, SIG_SELECTOR16(newWith), // pushi $10b (newWith)


Commit: 15f6e6b97edf9bb2c3729078d374c5dfef836c22
    https://github.com/scummvm/scummvm/commit/15f6e6b97edf9bb2c3729078d374c5dfef836c22
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:56:25-05:00

Commit Message:
SCI32: Remove resolved TODO in helpers.h

Changed paths:
    engines/sci/graphics/helpers.h


diff --git a/engines/sci/graphics/helpers.h b/engines/sci/graphics/helpers.h
index 38da280..9d266fc 100644
--- a/engines/sci/graphics/helpers.h
+++ b/engines/sci/graphics/helpers.h
@@ -240,11 +240,6 @@ struct Buffer : public Graphics::Surface {
 	Buffer(const uint16 width, const uint16 height, uint8 *const pix) :
 		screenWidth(width),
 		screenHeight(height),
-		// TODO: These values are not correct for all games. Script
-		// dimensions were hard-coded per game in the original
-		// interpreter. Search all games for their internal script
-		// dimensions and set appropriately. (This code does not
-		// appear to exist at all in SCI3, which uses 640x480.)
 		scriptWidth(320),
 		scriptHeight(200) {
 		init(width, height, width, pix, Graphics::PixelFormat::createFormatCLUT8());


Commit: d53e7787391683830f57c77cc8acd87c50444d40
    https://github.com/scummvm/scummvm/commit/d53e7787391683830f57c77cc8acd87c50444d40
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:56:26-05:00

Commit Message:
SCI32: Rewrap comments to 80 columns in SOL decoder

Changed paths:
    engines/sci/sound/decoders/sol.cpp
    engines/sci/sound/decoders/sol.h


diff --git a/engines/sci/sound/decoders/sol.cpp b/engines/sci/sound/decoders/sol.cpp
index 50d353c..a6eb8a4 100644
--- a/engines/sci/sound/decoders/sol.cpp
+++ b/engines/sci/sound/decoders/sol.cpp
@@ -157,11 +157,10 @@ SOLStream<STEREO, S16BIT, OLDDPCM8>::SOLStream(Common::SeekableReadStream *strea
 template <bool STEREO, bool S16BIT, bool OLDDPCM8>
 bool SOLStream<STEREO, S16BIT, OLDDPCM8>::seek(const Audio::Timestamp &where) {
 	if (where != 0) {
-		// In order to seek in compressed SOL files, all
-		// previous bytes must be known since it uses
-		// differential compression. Therefore, only seeking
-		// to the beginning is supported now (SSCI does not
-		// offer seeking anyway)
+		// In order to seek in compressed SOL files, all previous bytes must be
+		// known since it uses differential compression. Therefore, only seeking
+		// to the beginning is supported now (SSCI does not offer seeking
+		// anyway)
 		return false;
 	}
 
diff --git a/engines/sci/sound/decoders/sol.h b/engines/sci/sound/decoders/sol.h
index 1141132..2b84b8b 100644
--- a/engines/sci/sound/decoders/sol.h
+++ b/engines/sci/sound/decoders/sol.h
@@ -47,8 +47,7 @@ private:
 	uint16 _sampleRate;
 
 	/**
-	 * The raw (possibly-compressed) size of audio data in
-	 * the stream.
+	 * The raw (possibly-compressed) size of audio data in the stream.
 	 */
 	int32 _rawDataSize;
 


Commit: c7c5f28bdb2f393c1290bcac803cf9fc86ac8ed8
    https://github.com/scummvm/scummvm/commit/c7c5f28bdb2f393c1290bcac803cf9fc86ac8ed8
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-06T22:56:26-05:00

Commit Message:
SCI32: Clean up scriptWidth/scriptHeight/screenWidth/screenHeight

This removes the unnecessary Buffer subclass and stops most places
where the output buffer was being interrogated about dimensions
instead of GfxFrameout.

Changed paths:
    engines/sci/engine/kgraphics32.cpp
    engines/sci/engine/kvideo.cpp
    engines/sci/engine/savegame.cpp
    engines/sci/engine/segment.h
    engines/sci/event.cpp
    engines/sci/graphics/celobj32.cpp
    engines/sci/graphics/controls32.cpp
    engines/sci/graphics/cursor32.cpp
    engines/sci/graphics/frameout.cpp
    engines/sci/graphics/frameout.h
    engines/sci/graphics/helpers.h
    engines/sci/graphics/paint32.cpp
    engines/sci/graphics/plane32.cpp
    engines/sci/graphics/screen_item32.cpp
    engines/sci/graphics/text32.cpp
    engines/sci/graphics/text32.h
    engines/sci/graphics/transitions32.cpp
    engines/sci/graphics/video32.cpp
    engines/sci/video/robot_decoder.cpp


diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp
index 02b2cea..f9c1ede 100644
--- a/engines/sci/engine/kgraphics32.cpp
+++ b/engines/sci/engine/kgraphics32.cpp
@@ -77,7 +77,7 @@ reg_t kBaseSetter32(EngineState *s, int argc, reg_t *argv) {
 
 	Ratio scaleX;
 	if (getSciVersion() < SCI_VERSION_2_1_LATE) {
-		const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
+		const int16 scriptWidth = g_sci->_gfxFrameout->getScriptWidth();
 		scaleX = Ratio(scriptWidth, celObj._xResolution);
 	}
 
@@ -160,11 +160,12 @@ reg_t kShakeScreen32(EngineState *s, int argc, reg_t *argv) {
 }
 
 reg_t kIsHiRes(EngineState *s, int argc, reg_t *argv) {
-	const Buffer &buffer = g_sci->_gfxFrameout->getCurrentBuffer();
-	if (buffer.screenWidth < 640 || buffer.screenHeight < 400)
-		return make_reg(0, 0);
+	const GfxFrameout *gfxFrameout = g_sci->_gfxFrameout;
+	if (gfxFrameout->getScreenWidth() < 640 || gfxFrameout->getScreenHeight() < 400) {
+		return NULL_REG;
+	}
 
-	return make_reg(0, 1);
+	return TRUE_REG;
 }
 
 reg_t kAddScreenItem(EngineState *s, int argc, reg_t *argv) {
@@ -412,25 +413,25 @@ reg_t kSetShowStyle(EngineState *s, int argc, reg_t *argv) {
 }
 
 reg_t kCelHigh32(EngineState *s, int argc, reg_t *argv) {
-	GuiResourceId resourceId = argv[0].toUint16();
-	int16 loopNo = argv[1].toSint16();
-	int16 celNo = argv[2].toSint16();
-	CelObjView celObj(resourceId, loopNo, celNo);
+	const GuiResourceId resourceId = argv[0].toUint16();
+	const int16 loopNo = argv[1].toSint16();
+	const int16 celNo = argv[2].toSint16();
+	const CelObjView celObj(resourceId, loopNo, celNo);
 	int16 height = celObj._height;
 	if (getSciVersion() < SCI_VERSION_2_1_LATE) {
-		height = mulru(height, Ratio(g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight, celObj._yResolution));
+		height = mulru(height, Ratio(g_sci->_gfxFrameout->getScriptHeight(), celObj._yResolution));
 	}
 	return make_reg(0, height);
 }
 
 reg_t kCelWide32(EngineState *s, int argc, reg_t *argv) {
-	GuiResourceId resourceId = argv[0].toUint16();
-	int16 loopNo = argv[1].toSint16();
-	int16 celNo = argv[2].toSint16();
-	CelObjView celObj(resourceId, loopNo, celNo);
+	const GuiResourceId resourceId = argv[0].toUint16();
+	const int16 loopNo = argv[1].toSint16();
+	const int16 celNo = argv[2].toSint16();
+	const CelObjView celObj(resourceId, loopNo, celNo);
 	int16 width = celObj._width;
 	if (getSciVersion() < SCI_VERSION_2_1_LATE) {
-		width = mulru(width, Ratio(g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth, celObj._xResolution));
+		width = mulru(width, Ratio(g_sci->_gfxFrameout->getScriptWidth(), celObj._xResolution));
 	}
 	return make_reg(0, width);
 }
diff --git a/engines/sci/engine/kvideo.cpp b/engines/sci/engine/kvideo.cpp
index 98b2ba2..1bd886c 100644
--- a/engines/sci/engine/kvideo.cpp
+++ b/engines/sci/engine/kvideo.cpp
@@ -460,8 +460,8 @@ reg_t kPlayVMDShowCursor(EngineState *s, int argc, reg_t *argv) {
 }
 
 reg_t kPlayVMDSetBlackoutArea(EngineState *s, int argc, reg_t *argv) {
-	const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
-	const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
+	const int16 scriptWidth = g_sci->_gfxFrameout->getScriptWidth();
+	const int16 scriptHeight = g_sci->_gfxFrameout->getScriptHeight();
 
 	Common::Rect blackoutArea;
 	blackoutArea.left = MAX<int16>(0, argv[0].toSint16());
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 06a26ec..a7ebe0b 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -801,7 +801,7 @@ void SciBitmap::saveLoadWithSerializer(Common::Serializer &s) {
 	s.syncBytes(_data, _dataSize);
 
 	if (s.isLoading()) {
-		_buffer = Buffer(getWidth(), getHeight(), getPixels());
+		_buffer.init(getWidth(), getHeight(), getWidth(), getPixels(), Graphics::PixelFormat::createFormatCLUT8());
 	}
 }
 #endif
diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h
index 2a4fd91..14744e3 100644
--- a/engines/sci/engine/segment.h
+++ b/engines/sci/engine/segment.h
@@ -977,7 +977,7 @@ public:
 		_data = (byte *)malloc(other._dataSize);
 		memcpy(_data, other._data, other._dataSize);
 		if (_dataSize) {
-			_buffer = Buffer(getWidth(), getHeight(), getPixels());
+			_buffer.init(getWidth(), getHeight(), getWidth(), getPixels(), Graphics::PixelFormat::createFormatCLUT8());
 		}
 		_gc = other._gc;
 	}
@@ -998,7 +998,7 @@ public:
 		_data = (byte *)malloc(other._dataSize);
 		memcpy(_data, other._data, _dataSize);
 		if (_dataSize) {
-			_buffer = Buffer(getWidth(), getHeight(), getPixels());
+			_buffer.init(getWidth(), getHeight(), getWidth(), getPixels(), Graphics::PixelFormat::createFormatCLUT8());
 		}
 		_gc = other._gc;
 
@@ -1032,7 +1032,7 @@ public:
 		setXResolution(xResolution);
 		setYResolution(yResolution);
 
-		_buffer = Buffer(getWidth(), getHeight(), getPixels());
+		_buffer.init(getWidth(), getHeight(), getWidth(), getPixels(), Graphics::PixelFormat::createFormatCLUT8());
 	}
 
 	inline int getRawSize() const {
diff --git a/engines/sci/event.cpp b/engines/sci/event.cpp
index e69095a..aef84e2 100644
--- a/engines/sci/event.cpp
+++ b/engines/sci/event.cpp
@@ -164,7 +164,7 @@ SciEvent EventManager::getScummVMEvent() {
 
 #if ENABLE_SCI32
 	if (getSciVersion() >= SCI_VERSION_2) {
-		const Buffer &screen = g_sci->_gfxFrameout->getCurrentBuffer();
+		const GfxFrameout *gfxFrameout = g_sci->_gfxFrameout;
 
 		// This will clamp `mousePos` according to the restricted zone,
 		// so any cursor or screen item associated with the mouse position
@@ -172,7 +172,7 @@ SciEvent EventManager::getScummVMEvent() {
 		g_sci->_gfxCursor32->deviceMoved(mousePos);
 
 		Common::Point mousePosSci = mousePos;
-		mulru(mousePosSci, Ratio(screen.scriptWidth, screen.screenWidth), Ratio(screen.scriptHeight, screen.screenHeight));
+		mulru(mousePosSci, Ratio(gfxFrameout->getScriptWidth(), gfxFrameout->getScreenWidth()), Ratio(gfxFrameout->getScriptHeight(), gfxFrameout->getScreenHeight()));
 		noEvent.mousePosSci = input.mousePosSci = mousePosSci;
 
 		if (_hotRectanglesActive) {
diff --git a/engines/sci/graphics/celobj32.cpp b/engines/sci/graphics/celobj32.cpp
index c2ae29b..fb7abe8 100644
--- a/engines/sci/graphics/celobj32.cpp
+++ b/engines/sci/graphics/celobj32.cpp
@@ -658,9 +658,9 @@ struct RENDERER {
 	_skipColor(skipColor) {}
 
 	inline void draw(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const {
-		byte *targetPixel = (byte *)target.getPixels() + target.screenWidth * targetRect.top + targetRect.left;
+		byte *targetPixel = (byte *)target.getPixels() + target.w * targetRect.top + targetRect.left;
 
-		const int16 skipStride = target.screenWidth - targetRect.width();
+		const int16 skipStride = target.w - targetRect.width();
 		const int16 targetWidth = targetRect.width();
 		const int16 targetHeight = targetRect.height();
 		for (int16 y = 0; y < targetHeight; ++y) {
@@ -1265,8 +1265,8 @@ CelObjColor::CelObjColor(const uint8 color, const int16 width, const int16 heigh
 	_info.color = color;
 	_origin.x = 0;
 	_origin.y = 0;
-	_xResolution = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
-	_yResolution = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
+	_xResolution = g_sci->_gfxFrameout->getScriptWidth();
+	_yResolution = g_sci->_gfxFrameout->getScriptHeight();
 	_hunkPaletteOffset = 0;
 	_mirrorX = false;
 	_remap = false;
diff --git a/engines/sci/graphics/controls32.cpp b/engines/sci/graphics/controls32.cpp
index 82b99e6..fa4396c 100644
--- a/engines/sci/graphics/controls32.cpp
+++ b/engines/sci/graphics/controls32.cpp
@@ -391,8 +391,8 @@ ScrollWindow::ScrollWindow(SegManager *segMan, const Common::Rect &gameRect, con
 	_gfxText32.setFont(_fontId);
 	_pointSize = _gfxText32._font->getHeight();
 
-	const uint16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
-	const uint16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
+	const uint16 scriptWidth = g_sci->_gfxFrameout->getScriptWidth();
+	const uint16 scriptHeight = g_sci->_gfxFrameout->getScriptHeight();
 
 	Common::Rect bitmapRect(gameRect);
 	mulinc(bitmapRect, Ratio(_gfxText32._xResolution, scriptWidth), Ratio(_gfxText32._yResolution, scriptHeight));
diff --git a/engines/sci/graphics/cursor32.cpp b/engines/sci/graphics/cursor32.cpp
index ae8c014..f401d1b 100644
--- a/engines/sci/graphics/cursor32.cpp
+++ b/engines/sci/graphics/cursor32.cpp
@@ -39,7 +39,7 @@ GfxCursor32::GfxCursor32() :
 
 void GfxCursor32::init(const Buffer &outputBuffer) {
 	_screen = outputBuffer;
-	_screenRegion.rect = Common::Rect(_screen.screenWidth, _screen.screenHeight);
+	_screenRegion.rect = Common::Rect(_screen.w, _screen.h);
 	_screenRegion.data = static_cast<byte *>(_screen.getPixels());
 	_restrictedArea = _screenRegion.rect;
 }
@@ -151,10 +151,10 @@ void GfxCursor32::show() {
 void GfxCursor32::setRestrictedArea(const Common::Rect &rect) {
 	_restrictedArea = rect;
 
-	const int16 screenWidth = g_sci->_gfxFrameout->getCurrentBuffer().screenWidth;
-	const int16 screenHeight = g_sci->_gfxFrameout->getCurrentBuffer().screenHeight;
-	const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
-	const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
+	const int16 screenWidth = g_sci->_gfxFrameout->getScreenWidth();
+	const int16 screenHeight = g_sci->_gfxFrameout->getScreenHeight();
+	const int16 scriptWidth = g_sci->_gfxFrameout->getScriptWidth();
+	const int16 scriptHeight = g_sci->_gfxFrameout->getScriptHeight();
 
 	mulru(_restrictedArea, Ratio(screenWidth, scriptWidth), Ratio(screenHeight, scriptHeight), 0);
 
@@ -259,7 +259,7 @@ void GfxCursor32::setView(const GuiResourceId viewId, const int16 loopNo, const
 		//      threshold size because inventory items usually have a
 		//      high-resolution cursor representation.
 		bool pixelDouble = false;
-		if (g_sci->_gfxFrameout->_isHiRes &&
+		if (g_sci->_gfxFrameout->isHiRes() &&
 			(g_sci->getGameId() == GID_GK1 ||
 			(g_sci->getGameId() == GID_PQ4 && _width <= 22 && _height <= 22))) {
 
@@ -275,7 +275,8 @@ void GfxCursor32::setView(const GuiResourceId viewId, const int16 loopNo, const
 		memset(_cursor.data, 255, _width * _height);
 		_cursor.skipColor = 255;
 
-		Buffer target(_width, _height, _cursor.data);
+		Buffer target;
+		target.init(_width, _height, _width, _cursor.data, Graphics::PixelFormat::createFormatCLUT8());
 		if (pixelDouble) {
 			view.draw(target, _cursor.rect, Common::Point(0, 0), false, 2, 2);
 		} else {
@@ -314,10 +315,10 @@ void GfxCursor32::copyFromScreen(DrawRegion &target) {
 }
 
 void GfxCursor32::setPosition(const Common::Point &position) {
-	const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
-	const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
-	const int16 screenWidth = g_sci->_gfxFrameout->getCurrentBuffer().screenWidth;
-	const int16 screenHeight = g_sci->_gfxFrameout->getCurrentBuffer().screenHeight;
+	const int16 scriptWidth = g_sci->_gfxFrameout->getScriptWidth();
+	const int16 scriptHeight = g_sci->_gfxFrameout->getScriptHeight();
+	const int16 screenWidth = g_sci->_gfxFrameout->getScreenWidth();
+	const int16 screenHeight = g_sci->_gfxFrameout->getScreenHeight();
 
 	Common::Point newPosition;
 	newPosition.x = (position.x * Ratio(screenWidth, scriptWidth)).toInt();
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp
index a8746ee..7fc92a8 100644
--- a/engines/sci/graphics/frameout.cpp
+++ b/engines/sci/graphics/frameout.cpp
@@ -61,7 +61,7 @@
 namespace Sci {
 
 GfxFrameout::GfxFrameout(SegManager *segMan, GfxPalette32 *palette, GfxTransitions32 *transitions, GfxCursor32 *cursor) :
-	_isHiRes(gameIsHiRes()),
+	_isHiRes(detectHiRes()),
 	_palette(palette),
 	_cursor(cursor),
 	_segMan(segMan),
@@ -74,15 +74,13 @@ GfxFrameout::GfxFrameout(SegManager *segMan, GfxPalette32 *palette, GfxTransitio
 	_lastScreenUpdateTick(0) {
 
 	if (g_sci->getGameId() == GID_PHANTASMAGORIA) {
-		_currentBuffer = Buffer(630, 450, nullptr);
+		_currentBuffer.create(630, 450, Graphics::PixelFormat::createFormatCLUT8());
 	} else if (_isHiRes) {
-		_currentBuffer = Buffer(640, 480, nullptr);
+		_currentBuffer.create(640, 480, Graphics::PixelFormat::createFormatCLUT8());
 	} else {
-		_currentBuffer = Buffer(320, 200, nullptr);
+		_currentBuffer.create(320, 200, Graphics::PixelFormat::createFormatCLUT8());
 	}
-	_currentBuffer.setPixels(calloc(1, _currentBuffer.screenWidth * _currentBuffer.screenHeight));
-	_screenRect = Common::Rect(_currentBuffer.screenWidth, _currentBuffer.screenHeight);
-	initGraphics(_currentBuffer.screenWidth, _currentBuffer.screenHeight, _isHiRes);
+	initGraphics(_currentBuffer.w, _currentBuffer.h, _isHiRes);
 
 	switch (g_sci->getGameId()) {
 	case GID_HOYLE5:
@@ -91,18 +89,20 @@ GfxFrameout::GfxFrameout(SegManager *segMan, GfxPalette32 *palette, GfxTransitio
 	case GID_PHANTASMAGORIA2:
 	case GID_TORIN:
 	case GID_RAMA:
-		_currentBuffer.scriptWidth = 640;
-		_currentBuffer.scriptHeight = 480;
+		_scriptWidth = 640;
+		_scriptHeight = 480;
 		break;
 	case GID_GK2:
 	case GID_PQSWAT:
 		if (!g_sci->isDemo()) {
-			_currentBuffer.scriptWidth = 640;
-			_currentBuffer.scriptHeight = 480;
+			_scriptWidth = 640;
+			_scriptHeight = 480;
+			break;
 		}
-		break;
+		// fall through
 	default:
-		// default script width for other games is 320x200
+		_scriptWidth = 320;
+		_scriptHeight = 200;
 		break;
 	}
 }
@@ -110,7 +110,7 @@ GfxFrameout::GfxFrameout(SegManager *segMan, GfxPalette32 *palette, GfxTransitio
 GfxFrameout::~GfxFrameout() {
 	clear();
 	CelObj::deinit();
-	free(_currentBuffer.getPixels());
+	_currentBuffer.free();
 }
 
 void GfxFrameout::run() {
@@ -122,7 +122,7 @@ void GfxFrameout::run() {
 	// This plane is created in SCI::InitPlane in SSCI, and is a background fill
 	// plane to ensure "hidden" planes (planes with negative priority) are never
 	// drawn
-	Plane *initPlane = new Plane(Common::Rect(_currentBuffer.scriptWidth, _currentBuffer.scriptHeight));
+	Plane *initPlane = new Plane(Common::Rect(_scriptWidth, _scriptHeight));
 	initPlane->_priority = 0;
 	_planes.add(initPlane);
 }
@@ -133,7 +133,7 @@ void GfxFrameout::clear() {
 	_showList.clear();
 }
 
-bool GfxFrameout::gameIsHiRes() const {
+bool GfxFrameout::detectHiRes() const {
 	// QFG4 is always low resolution
 	if (g_sci->getGameId() == GID_QFG4) {
 		return false;
@@ -360,7 +360,7 @@ void GfxFrameout::addPlane(Plane *plane) {
 		error("Plane %04x:%04x already exists", PRINT_REG(plane->_object));
 	}
 
-	plane->clipScreenRect(_screenRect);
+	plane->clipScreenRect(Common::Rect(_currentBuffer.w, _currentBuffer.h));
 	_planes.add(plane);
 }
 
@@ -369,7 +369,7 @@ void GfxFrameout::updatePlane(Plane &plane) {
 	assert(_planes.findByObject(plane._object) == &plane);
 
 	Plane *visiblePlane = _visiblePlanes.findByObject(plane._object);
-	plane.sync(visiblePlane, _screenRect);
+	plane.sync(visiblePlane, Common::Rect(_currentBuffer.w, _currentBuffer.h));
 	// updateScreenRect was called a second time here in SSCI, but it is already
 	// called at the end of the sync call (also in SSCI) so there is no reason
 	// to do it again
@@ -455,7 +455,7 @@ void GfxFrameout::palMorphFrameOut(const int8 *styleRanges, PlaneShowStyle *show
 
 	int16 prevRoom = g_sci->getEngineState()->variables[VAR_GLOBAL][kGlobalVarPreviousRoomNo].toSint16();
 
-	Common::Rect rect(_currentBuffer.screenWidth, _currentBuffer.screenHeight);
+	Common::Rect rect(_currentBuffer.w, _currentBuffer.h);
 	_showList.add(rect);
 	showBits();
 
@@ -557,24 +557,39 @@ void GfxFrameout::directFrameOut(const Common::Rect &showRect) {
 }
 
 #ifdef USE_RGB_COLOR
+void GfxFrameout::redrawGameScreen(const Common::Rect &skipRect) const {
+	Common::ScopedPtr<Graphics::Surface> game(_currentBuffer.convertTo(g_system->getScreenFormat(), _palette->getHardwarePalette()));
+	assert(game);
+
+	Common::Rect rects[4];
+	int splitCount = splitRects(Common::Rect(game->w, game->h), skipRect, rects);
+	if (splitCount != -1) {
+		while (splitCount--) {
+			const Common::Rect &drawRect = rects[splitCount];
+			g_system->copyRectToScreen(game->getBasePtr(drawRect.left, drawRect.top), game->pitch, drawRect.left, drawRect.top, drawRect.width(), drawRect.height());
+		}
+	}
+
+	game->free();
+}
+
 void GfxFrameout::resetHardware() {
 	updateMousePositionForRendering();
-	_showList.add(Common::Rect(getCurrentBuffer().screenWidth, getCurrentBuffer().screenHeight));
+	_showList.add(Common::Rect(_currentBuffer.w, _currentBuffer.h));
 	g_system->getPaletteManager()->setPalette(_palette->getHardwarePalette(), 0, 256);
 	showBits();
 }
 #endif
 
 /**
- * Determines the parts of `middleRect` that aren't overlapped
- * by `showRect`, optimised for contiguous memory writes.
- * Returns -1 if `middleRect` and `showRect` have no intersection.
- * Returns number of returned parts (in `outRects`) otherwise.
- * (In particular, this returns 0 if `middleRect` is contained
- * in `other`.)
+ * Determines the parts of `middleRect` that aren't overlapped by `showRect`,
+ * optimised for contiguous memory writes.
+ *
+ * `middleRect` is modified directly to extend into the upper and lower rects.
  *
- * `middleRect` is modified directly to extend into the upper
- * and lower rects.
+ * @returns -1 if `middleRect` and `showRect` have no intersection, or the
+ * number of returned parts (in `outRects`) otherwise. (In particular, this
+ * returns 0 if `middleRect` is contained in `showRect`.)
  */
 int splitRectsForRender(Common::Rect &middleRect, const Common::Rect &showRect, Common::Rect(&outRects)[2]) {
 	if (!middleRect.intersects(showRect)) {
@@ -998,7 +1013,7 @@ void GfxFrameout::showBits() {
 		rounded.left &= ~1;
 		rounded.right = (rounded.right + 1) & ~1;
 
-		byte *sourceBuffer = (byte *)_currentBuffer.getPixels() + rounded.top * _currentBuffer.screenWidth + rounded.left;
+		byte *sourceBuffer = (byte *)_currentBuffer.getPixels() + rounded.top * _currentBuffer.w + rounded.left;
 
 		// Sometimes screen items (especially from SCI2.1early transitions, like
 		// in the asteroids minigame in PQ4) generate zero-dimension show
@@ -1023,7 +1038,7 @@ void GfxFrameout::showBits() {
 #else
 		{
 #endif
-			g_system->copyRectToScreen(sourceBuffer, _currentBuffer.screenWidth, rounded.left, rounded.top, rounded.width(), rounded.height());
+			g_system->copyRectToScreen(sourceBuffer, _currentBuffer.w, rounded.left, rounded.top, rounded.width(), rounded.height());
 		}
 	}
 
@@ -1083,7 +1098,7 @@ void GfxFrameout::alterVmap(const Palette &palette1, const Palette &palette2, co
 
 	byte *pixels = (byte *)_currentBuffer.getPixels();
 
-	for (int pixelIndex = 0, numPixels = _currentBuffer.screenWidth * _currentBuffer.screenHeight; pixelIndex < numPixels; ++pixelIndex) {
+	for (int pixelIndex = 0, numPixels = _currentBuffer.w * _currentBuffer.h; pixelIndex < numPixels; ++pixelIndex) {
 		byte currentValue = pixels[pixelIndex];
 		int8 styleRangeValue = styleRanges[currentValue];
 		if (styleRangeValue == -1 && styleRangeValue == style) {
@@ -1205,7 +1220,7 @@ reg_t GfxFrameout::kernelIsOnMe(const reg_t object, const Common::Point &positio
 bool GfxFrameout::isOnMe(const ScreenItem &screenItem, const Plane &plane, const Common::Point &position, const bool checkPixel) const {
 
 	Common::Point scaledPosition(position);
-	mulru(scaledPosition, Ratio(_currentBuffer.screenWidth, _currentBuffer.scriptWidth), Ratio(_currentBuffer.screenHeight, _currentBuffer.scriptHeight));
+	mulru(scaledPosition, Ratio(_currentBuffer.w, _scriptWidth), Ratio(_currentBuffer.h, _scriptHeight));
 	scaledPosition.x += plane._planeRect.left;
 	scaledPosition.y += plane._planeRect.top;
 
@@ -1222,7 +1237,7 @@ bool GfxFrameout::isOnMe(const ScreenItem &screenItem, const Plane &plane, const
 		scaledPosition.y -= screenItem._scaledPosition.y;
 
 		if (getSciVersion() < SCI_VERSION_2_1_LATE) {
-			mulru(scaledPosition, Ratio(celObj._xResolution, _currentBuffer.screenWidth), Ratio(celObj._yResolution, _currentBuffer.screenHeight));
+			mulru(scaledPosition, Ratio(celObj._xResolution, _currentBuffer.w), Ratio(celObj._yResolution, _currentBuffer.h));
 		}
 
 		if (screenItem._scale.signal != kScaleSignalNone && screenItem._scale.x && screenItem._scale.y) {
diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h
index 78bf2e0..55ba631 100644
--- a/engines/sci/graphics/frameout.h
+++ b/engines/sci/graphics/frameout.h
@@ -47,11 +47,35 @@ public:
 	GfxFrameout(SegManager *segMan, GfxPalette32 *palette, GfxTransitions32 *transitions, GfxCursor32 *cursor);
 	~GfxFrameout();
 
-	bool _isHiRes;
-
 	void clear();
 	void run();
 
+	/**
+	 * Returns true if the game should render at a resolution greater than
+	 * 320x240.
+	 */
+	inline bool isHiRes() const { return _isHiRes; }
+
+	/**
+	 * Gets the x-resolution used by game scripts.
+	 */
+	inline int16 getScriptWidth() const { return _scriptWidth; }
+
+	/**
+	 * Gets the y-resolution used by game scripts.
+	 */
+	inline int16 getScriptHeight() const { return _scriptHeight; }
+
+	/**
+	 * Gets the x-resolution of the output buffer.
+	 */
+	inline int16 getScreenWidth() const { return _currentBuffer.w; }
+
+	/**
+	 * Gets the y-resolution of the output buffer.
+	 */
+	inline int16 getScreenHeight() const { return _currentBuffer.h; }
+
 private:
 	GfxCursor32 *_cursor;
 	GfxPalette32 *_palette;
@@ -59,10 +83,21 @@ private:
 	SegManager *_segMan;
 
 	/**
+	 * Whether or not the game should render at a resolution above 320x240.
+	 */
+	bool _isHiRes;
+
+	/**
+	 * The resolution used by game scripts.
+	 * @see celobj32.h comments on kLowResX/kLowResY.
+	 */
+	int16 _scriptWidth, _scriptHeight;
+
+	/**
 	 * Determines whether the current game should be rendered in high
 	 * resolution.
 	 */
-	bool gameIsHiRes() const;
+	bool detectHiRes() const;
 
 #pragma mark -
 #pragma mark Screen items
@@ -172,7 +207,7 @@ public:
 	 * Resets the pixel format of the hardware surface to the given format.
 	 */
 	void setPixelFormat(const Graphics::PixelFormat &format) const {
-		initGraphics(_currentBuffer.screenWidth, _currentBuffer.screenHeight, _isHiRes, &format);
+		initGraphics(_currentBuffer.w, _currentBuffer.h, _isHiRes, &format);
 	}
 
 	/**
@@ -216,6 +251,14 @@ public:
 	 */
 	void directFrameOut(const Common::Rect &showRect);
 
+	/**
+	 * Redraws the game screen from the internal frame buffer to the system.
+	 * Used after pixel format changes.
+	 *
+	 * @param skipRect An area of the screen that does not need to be redrawn.
+	 */
+	void redrawGameScreen(const Common::Rect &skipRect) const;
+
 #ifdef USE_RGB_COLOR
 	/**
 	 * Sends the entire internal screen buffer and palette to hardware.
@@ -271,13 +314,6 @@ private:
 	bool _remapOccurred;
 
 	/**
-	 * The dimensions of the output buffer, in display coordinates.
-	 *
-	 * @note This field is on `GraphicsMgr.screen` in SSCI.
-	 */
-	Common::Rect _screenRect;
-
-	/**
 	 * A list of rectangles, in screen coordinates, that represent portions of
 	 * the internal screen buffer that are dirty and should be drawn to the
 	 * hardware display surface.
diff --git a/engines/sci/graphics/helpers.h b/engines/sci/graphics/helpers.h
index 9d266fc..5842bf0 100644
--- a/engines/sci/graphics/helpers.h
+++ b/engines/sci/graphics/helpers.h
@@ -225,42 +225,7 @@ inline int splitRects(Common::Rect r, const Common::Rect &other, Common::Rect(&o
 	return splitCount;
 }
 
-struct Buffer : public Graphics::Surface {
-	uint16 screenWidth;
-	uint16 screenHeight;
-	uint16 scriptWidth;
-	uint16 scriptHeight;
-
-	Buffer() :
-		screenWidth(0),
-		screenHeight(0),
-		scriptWidth(320),
-		scriptHeight(200) {}
-
-	Buffer(const uint16 width, const uint16 height, uint8 *const pix) :
-		screenWidth(width),
-		screenHeight(height),
-		scriptWidth(320),
-		scriptHeight(200) {
-		init(width, height, width, pix, Graphics::PixelFormat::createFormatCLUT8());
-	}
-
-	void clear(const uint8 value) {
-		memset(pixels, value, w * h);
-	}
-
-	inline uint8 *getAddress(const uint16 x, const uint16 y) {
-		return (uint8 *)getBasePtr(x, y);
-	}
-
-	inline uint8 *getAddressSimRes(const uint16 x, const uint16 y) {
-		return (uint8*)pixels + (y * w * screenHeight / scriptHeight) + (x * screenWidth / scriptWidth);
-	}
-
-	bool isNull() {
-		return pixels == nullptr;
-	}
-};
+typedef Graphics::Surface Buffer;
 #endif
 
 struct Color {
diff --git a/engines/sci/graphics/paint32.cpp b/engines/sci/graphics/paint32.cpp
index f4d9c9f..f80f115 100644
--- a/engines/sci/graphics/paint32.cpp
+++ b/engines/sci/graphics/paint32.cpp
@@ -126,8 +126,8 @@ reg_t GfxPaint32::makeLineBitmap(const Common::Point &startPoint, const Common::
 	thickness = (MAX<uint8>(1, thickness) - 1) | 1;
 	const uint8 halfThickness = thickness >> 1;
 
-	const uint16 scriptWidth  = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
-	const uint16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
+	const uint16 scriptWidth  = g_sci->_gfxFrameout->getScriptWidth();
+	const uint16 scriptHeight = g_sci->_gfxFrameout->getScriptHeight();
 
 	outRect.left   = MIN<int16>(startPoint.x, endPoint.x);
 	outRect.top    = MIN<int16>(startPoint.y, endPoint.y);
diff --git a/engines/sci/graphics/plane32.cpp b/engines/sci/graphics/plane32.cpp
index 77ca620..46a8aed 100644
--- a/engines/sci/graphics/plane32.cpp
+++ b/engines/sci/graphics/plane32.cpp
@@ -137,10 +137,10 @@ void Plane::init() {
 }
 
 void Plane::convertGameRectToPlaneRect() {
-	const int16 screenWidth = g_sci->_gfxFrameout->getCurrentBuffer().screenWidth;
-	const int16 screenHeight = g_sci->_gfxFrameout->getCurrentBuffer().screenHeight;
-	const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
-	const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
+	const int16 screenWidth = g_sci->_gfxFrameout->getScreenWidth();
+	const int16 screenHeight = g_sci->_gfxFrameout->getScreenHeight();
+	const int16 scriptWidth = g_sci->_gfxFrameout->getScriptWidth();
+	const int16 scriptHeight = g_sci->_gfxFrameout->getScriptHeight();
 
 	const Ratio ratioX = Ratio(screenWidth, scriptWidth);
 	const Ratio ratioY = Ratio(screenHeight, scriptHeight);
diff --git a/engines/sci/graphics/screen_item32.cpp b/engines/sci/graphics/screen_item32.cpp
index 4e1ed83..0addd77 100644
--- a/engines/sci/graphics/screen_item32.cpp
+++ b/engines/sci/graphics/screen_item32.cpp
@@ -251,10 +251,10 @@ void ScreenItem::setFromObject(SegManager *segMan, const reg_t object, const boo
 }
 
 void ScreenItem::calcRects(const Plane &plane) {
-	const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
-	const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
-	const int16 screenWidth = g_sci->_gfxFrameout->getCurrentBuffer().screenWidth;
-	const int16 screenHeight = g_sci->_gfxFrameout->getCurrentBuffer().screenHeight;
+	const int16 scriptWidth = g_sci->_gfxFrameout->getScriptWidth();
+	const int16 scriptHeight = g_sci->_gfxFrameout->getScriptHeight();
+	const int16 screenWidth = g_sci->_gfxFrameout->getScreenWidth();
+	const int16 screenHeight = g_sci->_gfxFrameout->getScreenHeight();
 
 	const CelObj &celObj = getCelObj();
 
@@ -587,8 +587,8 @@ Common::Rect ScreenItem::getNowSeenRect(const Plane &plane) const {
 		nsRect = celObjRect;
 	}
 
-	const uint16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
-	const uint16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
+	const uint16 scriptWidth = g_sci->_gfxFrameout->getScriptWidth();
+	const uint16 scriptHeight = g_sci->_gfxFrameout->getScriptHeight();
 
 	Ratio scaleX, scaleY;
 	if (_scale.signal == kScaleSignalManual) {
diff --git a/engines/sci/graphics/text32.cpp b/engines/sci/graphics/text32.cpp
index 1fcf292..6ebbcc0 100644
--- a/engines/sci/graphics/text32.cpp
+++ b/engines/sci/graphics/text32.cpp
@@ -53,8 +53,8 @@ GfxText32::GfxText32(SegManager *segMan, GfxCache *fonts) :
 	}
 
 void GfxText32::init() {
-	_xResolution = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
-	_yResolution = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
+	_xResolution = g_sci->_gfxFrameout->getScriptWidth();
+	_yResolution = g_sci->_gfxFrameout->getScriptHeight();
 }
 
 reg_t GfxText32::createFontBitmap(int16 width, int16 height, const Common::Rect &rect, const Common::String &text, const uint8 foreColor, const uint8 backColor, const uint8 skipColor, const GuiResourceId fontId, const TextAlign alignment, const int16 borderColor, const bool dimmed, const bool doScaling, const bool gc) {
@@ -73,8 +73,8 @@ reg_t GfxText32::createFontBitmap(int16 width, int16 height, const Common::Rect
 	setFont(fontId);
 
 	if (doScaling) {
-		int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
-		int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
+		int16 scriptWidth = g_sci->_gfxFrameout->getScriptWidth();
+		int16 scriptHeight = g_sci->_gfxFrameout->getScriptHeight();
 
 		Ratio scaleX(_xResolution, scriptWidth);
 		Ratio scaleY(_yResolution, scriptHeight);
@@ -115,8 +115,8 @@ reg_t GfxText32::createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &
 
 	setFont(fontId);
 
-	int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
-	int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
+	int16 scriptWidth = g_sci->_gfxFrameout->getScriptWidth();
+	int16 scriptHeight = g_sci->_gfxFrameout->getScriptHeight();
 
 	mulinc(_textRect, Ratio(_xResolution, scriptWidth), Ratio(_yResolution, scriptHeight));
 
@@ -218,7 +218,7 @@ void GfxText32::drawChar(const char charIndex) {
 }
 
 int16 GfxText32::getScaledFontHeight() const {
-	const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
+	const int16 scriptHeight = g_sci->_gfxFrameout->getScriptHeight();
 	return (_font->getHeight() * scriptHeight + _yResolution - 1) / _yResolution;
 }
 
@@ -335,7 +335,7 @@ void GfxText32::drawText(const uint index, uint length) {
 void GfxText32::invertRect(const reg_t bitmapId, int16 bitmapStride, const Common::Rect &rect, const uint8 foreColor, const uint8 backColor, const bool doScaling) {
 	Common::Rect targetRect = rect;
 	if (doScaling) {
-		bitmapStride = bitmapStride * _xResolution / g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
+		bitmapStride = bitmapStride * _xResolution / g_sci->_gfxFrameout->getScriptWidth();
 		targetRect = scaleRect(rect);
 	}
 
@@ -566,8 +566,8 @@ Common::Rect GfxText32::getTextSize(const Common::String &text, int16 maxWidth,
 
 	Common::Rect result;
 
-	int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
-	int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
+	int16 scriptWidth = g_sci->_gfxFrameout->getScriptWidth();
+	int16 scriptHeight = g_sci->_gfxFrameout->getScriptHeight();
 
 	maxWidth = maxWidth * _xResolution / scriptWidth;
 
@@ -638,8 +638,8 @@ int16 GfxText32::getStringWidth(const Common::String &text) {
 }
 
 int16 GfxText32::getTextCount(const Common::String &text, const uint index, const Common::Rect &textRect, const bool doScaling) {
-	const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
-	const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
+	const int16 scriptWidth = g_sci->_gfxFrameout->getScriptWidth();
+	const int16 scriptHeight = g_sci->_gfxFrameout->getScriptHeight();
 
 	Common::Rect scaledRect(textRect);
 	if (doScaling) {
diff --git a/engines/sci/graphics/text32.h b/engines/sci/graphics/text32.h
index 945cc81..f9de3ad 100644
--- a/engines/sci/graphics/text32.h
+++ b/engines/sci/graphics/text32.h
@@ -139,10 +139,10 @@ private:
 
 	inline Common::Rect scaleRect(const Common::Rect &rect) {
 		Common::Rect scaledRect(rect);
-		int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
-		int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
-		Ratio scaleX(_xResolution, scriptWidth);
-		Ratio scaleY(_yResolution, scriptHeight);
+		const int16 scriptWidth = g_sci->_gfxFrameout->getScriptWidth();
+		const int16 scriptHeight = g_sci->_gfxFrameout->getScriptHeight();
+		const Ratio scaleX(_xResolution, scriptWidth);
+		const Ratio scaleY(_yResolution, scriptHeight);
 		mulinc(scaledRect, scaleX, scaleY);
 		return scaledRect;
 	}
@@ -191,12 +191,12 @@ public:
 	reg_t createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &rect, const Common::String &text, const int16 foreColor, const int16 backColor, const GuiResourceId fontId, const int16 skipColor, const int16 borderColor, const bool dimmed, const bool gc);
 
 	inline int scaleUpWidth(int value) const {
-		const int scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
+		const int scriptWidth = g_sci->_gfxFrameout->getScriptWidth();
 		return (value * scriptWidth + _xResolution - 1) / _xResolution;
 	}
 
 	inline int scaleUpHeight(int value) const {
-		const int scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
+		const int scriptHeight = g_sci->_gfxFrameout->getScriptHeight();
 		return (value * scriptHeight + _yResolution - 1) / _yResolution;
 	}
 
diff --git a/engines/sci/graphics/transitions32.cpp b/engines/sci/graphics/transitions32.cpp
index 8be9e63..43479a2 100644
--- a/engines/sci/graphics/transitions32.cpp
+++ b/engines/sci/graphics/transitions32.cpp
@@ -544,7 +544,8 @@ void GfxTransitions32::configure21EarlyDissolve(PlaneShowStyle &showStyle, const
 	showStyle.bitmap = bitmapId;
 
 	const Buffer &source = g_sci->_gfxFrameout->getCurrentBuffer();
-	Buffer target(showStyle.width, showStyle.height, bitmap.getPixels());
+	Buffer target;
+	target.init(showStyle.width, showStyle.height, showStyle.width, bitmap.getPixels(), Graphics::PixelFormat::createFormatCLUT8());
 
 	target.fillRect(Common::Rect(bitmap.getWidth(), bitmap.getHeight()), kDefaultSkipColor);
 	target.copyRectToSurface(source, 0, 0, gameRect);
@@ -754,7 +755,8 @@ bool GfxTransitions32::processPixelDissolve21Early(PlaneShowStyle &showStyle) {
 	bool unchanged = true;
 
 	SciBitmap &bitmap = *_segMan->lookupBitmap(showStyle.bitmap);
-	Buffer buffer(showStyle.width, showStyle.height, bitmap.getPixels());
+	Buffer buffer;
+	buffer.init(showStyle.width, showStyle.height, showStyle.width, bitmap.getPixels(), Graphics::PixelFormat::createFormatCLUT8());
 
 	uint32 numPixels = showStyle.width * showStyle.height;
 	uint32 numPixelsPerDivision = (numPixels + showStyle.divisions) / showStyle.divisions;
diff --git a/engines/sci/graphics/video32.cpp b/engines/sci/graphics/video32.cpp
index c128ba1..8d68c8e 100644
--- a/engines/sci/graphics/video32.cpp
+++ b/engines/sci/graphics/video32.cpp
@@ -307,10 +307,10 @@ void SEQPlayer::play(const Common::String &fileName, const int16 numTicks, const
 		return;
 	}
 
-	const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
-	const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
-	const int16 screenWidth = g_sci->_gfxFrameout->getCurrentBuffer().screenWidth;
-	const int16 screenHeight = g_sci->_gfxFrameout->getCurrentBuffer().screenHeight;
+	const int16 scriptWidth = g_sci->_gfxFrameout->getScriptWidth();
+	const int16 scriptHeight = g_sci->_gfxFrameout->getScriptHeight();
+	const int16 screenWidth = g_sci->_gfxFrameout->getScreenWidth();
+	const int16 screenHeight = g_sci->_gfxFrameout->getScreenHeight();
 
 	const int16 scaledWidth = (_decoder->getWidth() * Ratio(screenWidth, scriptWidth)).toInt();
 	const int16 scaledHeight = (_decoder->getHeight() * Ratio(screenHeight, scriptHeight)).toInt();
@@ -392,8 +392,8 @@ AVIPlayer::IOStatus AVIPlayer::init(const bool doublePixels) {
 		height *= 2;
 	}
 
-	const int16 screenWidth = g_sci->_gfxFrameout->getCurrentBuffer().screenWidth;
-	const int16 screenHeight = g_sci->_gfxFrameout->getCurrentBuffer().screenHeight;
+	const int16 screenWidth = g_sci->_gfxFrameout->getScreenWidth();
+	const int16 screenHeight = g_sci->_gfxFrameout->getScreenHeight();
 
 	// When scaling videos, they must not grow larger than the hardware screen
 	// or else the engine will crash. This is particularly important for the GK1
@@ -783,20 +783,7 @@ void VMDPlayer::redrawGameScreen() const {
 		return;
 	}
 
-	Graphics::Surface *game = g_sci->_gfxFrameout->getCurrentBuffer().convertTo(g_system->getScreenFormat(), g_sci->_gfxPalette32->getHardwarePalette());
-	assert(game);
-
-	Common::Rect rects[4];
-	int splitCount = splitRects(Common::Rect(game->w, game->h), _drawRect, rects);
-	if (splitCount != -1) {
-		while (splitCount--) {
-			const Common::Rect &drawRect = rects[splitCount];
-			g_system->copyRectToScreen(game->getBasePtr(drawRect.left, drawRect.top), game->pitch, drawRect.left, drawRect.top, drawRect.width(), drawRect.height());
-		}
-	}
-
-	game->free();
-	delete game;
+	g_sci->_gfxFrameout->redrawGameScreen(_drawRect);
 }
 #endif
 
@@ -900,8 +887,8 @@ void VMDPlayer::initComposited() {
 	}
 
 	const uint32 hunkPaletteSize = HunkPalette::calculateHunkPaletteSize(256, false);
-	const int16 screenWidth = g_sci->_gfxFrameout->getCurrentBuffer().screenWidth;
-	const int16 screenHeight = g_sci->_gfxFrameout->getCurrentBuffer().screenHeight;
+	const int16 screenWidth = g_sci->_gfxFrameout->getScreenWidth();
+	const int16 screenHeight = g_sci->_gfxFrameout->getScreenHeight();
 
 	SciBitmap &vmdBitmap = *_segMan->allocateBitmap(&_bitmapId, _drawRect.width(), _drawRect.height(), 255, 0, 0, screenWidth, screenHeight, hunkPaletteSize, false, false);
 	vmdBitmap.getBuffer().fillRect(Common::Rect(_drawRect.width(), _drawRect.height()), 0);
diff --git a/engines/sci/video/robot_decoder.cpp b/engines/sci/video/robot_decoder.cpp
index 49ca226..4711a97 100644
--- a/engines/sci/video/robot_decoder.cpp
+++ b/engines/sci/video/robot_decoder.cpp
@@ -447,8 +447,8 @@ void RobotDecoder::initVideo(const int16 x, const int16 y, const int16 scale, co
 	if (_xResolution == 0 || _yResolution == 0) {
 		// In SSCI, default values were taken from RESOURCE.CFG hires property
 		// if it exists, but no games seem to take advantage of this
-		_xResolution = g_sci->_gfxFrameout->getCurrentBuffer().screenWidth;
-		_yResolution = g_sci->_gfxFrameout->getCurrentBuffer().screenHeight;
+		_xResolution = g_sci->_gfxFrameout->getScreenWidth();
+		_yResolution = g_sci->_gfxFrameout->getScreenHeight();
 	}
 
 	if (hasPalette) {
@@ -677,10 +677,10 @@ void RobotDecoder::showFrame(const uint16 frameNo, const uint16 newX, const uint
 			if (_isHiRes) {
 				SciBitmap &bitmap = *_segMan->lookupBitmap(_celHandles[i].bitmapId);
 
-				const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
-				const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
-				const int16 screenWidth = g_sci->_gfxFrameout->getCurrentBuffer().screenWidth;
-				const int16 screenHeight = g_sci->_gfxFrameout->getCurrentBuffer().screenHeight;
+				const int16 scriptWidth = g_sci->_gfxFrameout->getScriptWidth();
+				const int16 scriptHeight = g_sci->_gfxFrameout->getScriptHeight();
+				const int16 screenWidth = g_sci->_gfxFrameout->getScreenWidth();
+				const int16 screenHeight = g_sci->_gfxFrameout->getScreenHeight();
 
 				if (scriptWidth == kLowResX && scriptHeight == kLowResY) {
 					const Ratio lowResToScreenX(screenWidth, kLowResX);
@@ -1453,10 +1453,10 @@ uint32 RobotDecoder::createCel5(const byte *rawVideoData, const int16 screenItem
 
 	rawVideoData += kCelHeaderSize;
 
-	const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
-	const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
-	const int16 screenWidth = g_sci->_gfxFrameout->getCurrentBuffer().screenWidth;
-	const int16 screenHeight = g_sci->_gfxFrameout->getCurrentBuffer().screenHeight;
+	const int16 scriptWidth = g_sci->_gfxFrameout->getScriptWidth();
+	const int16 scriptHeight = g_sci->_gfxFrameout->getScriptHeight();
+	const int16 screenWidth = g_sci->_gfxFrameout->getScreenWidth();
+	const int16 screenHeight = g_sci->_gfxFrameout->getScreenHeight();
 
 	Common::Point origin;
 	if (scriptWidth == kLowResX && scriptHeight == kLowResY) {





More information about the Scummvm-git-logs mailing list