[Scummvm-cvs-logs] scummvm master -> 7594507277ba7506b8c7142b8a1463a97036c14d

dreammaster dreammaster at scummvm.org
Sun Jun 28 01:24:42 CEST 2015


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

Summary:
7594507277 SHERLOCK: RT: Properly implement StreamingImageFile class


Commit: 7594507277ba7506b8c7142b8a1463a97036c14d
    https://github.com/scummvm/scummvm/commit/7594507277ba7506b8c7142b8a1463a97036c14d
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2015-06-27T19:23:42-04:00

Commit Message:
SHERLOCK: RT: Properly implement StreamingImageFile class

Changed paths:
    engines/sherlock/image_file.cpp
    engines/sherlock/image_file.h
    engines/sherlock/objects.cpp
    engines/sherlock/objects.h
    engines/sherlock/scalpel/scalpel_scene.cpp
    engines/sherlock/scene.cpp
    engines/sherlock/scene.h
    engines/sherlock/tattoo/tattoo_scene.cpp
    engines/sherlock/tattoo/tattoo_scene.h
    engines/sherlock/tattoo/tattoo_user_interface.cpp



diff --git a/engines/sherlock/image_file.cpp b/engines/sherlock/image_file.cpp
index 78284e4..4d713b1 100644
--- a/engines/sherlock/image_file.cpp
+++ b/engines/sherlock/image_file.cpp
@@ -93,9 +93,10 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette, bool
 		}
 
 		// Load data for frame and decompress it
-		byte *data = new byte[frame._size];
+		byte *data = new byte[frame._size + 4];
 		stream.read(data, frame._size);
-		decompressFrame(frame, data);
+		Common::fill(data + frame._size, data + frame._size + 4, 0);
+		frame.decompressFrame(data, _vm->getGameID() == GType_RoseTattoo);
 		delete[] data;
 
 		push_back(frame);
@@ -134,21 +135,21 @@ void ImageFile::loadPalette(Common::SeekableReadStream &stream) {
 	}
 }
 
-void ImageFile::decompressFrame(ImageFrame &frame, const byte *src) {
-	frame._frame.create(frame._width, frame._height, Graphics::PixelFormat::createFormatCLUT8());
-	byte *dest = (byte *)frame._frame.getPixels();
-	Common::fill(dest, dest + frame._width * frame._height, 0xff);
+void ImageFrame::decompressFrame(const byte *src, bool isRoseTattoo) {
+	_frame.create(_width, _height, Graphics::PixelFormat::createFormatCLUT8());
+	byte *dest = (byte *)_frame.getPixels();
+	Common::fill(dest, dest + _width * _height, 0xff);
 
-	if (frame._paletteBase) {
+	if (_paletteBase) {
 		// Nibble-packed
-		for (uint idx = 0; idx < frame._size; ++idx, ++src) {
+		for (uint idx = 0; idx < _size; ++idx, ++src) {
 			*dest++ = *src & 0xF;
 			*dest++ = (*src >> 4);
 		}
-	} else if (frame._rleEncoded && _vm->getGameID() == GType_RoseTattoo) {
+	} else if (_rleEncoded && isRoseTattoo) {
 		// Rose Tattoo run length encoding doesn't use the RLE marker byte
-		for (int yp = 0; yp < frame._height; ++yp) {
-			int xSize = frame._width;
+		for (int yp = 0; yp < _height; ++yp) {
+			int xSize = _width;
 			while (xSize > 0) {
 				// Skip a given number of pixels
 				byte skip = *src++;
@@ -165,11 +166,11 @@ void ImageFile::decompressFrame(ImageFrame &frame, const byte *src) {
 			}
 			assert(xSize == 0);
 		}
-	} else if (frame._rleEncoded) {
+	} else if (_rleEncoded) {
 		// RLE encoded
-		int frameSize = frame._width * frame._height;
+		int frameSize = _width * _height;
 		while (frameSize > 0) {
-			if (*src == frame._rleMarker) {
+			if (*src == _rleMarker) {
 				byte rleColor = src[1];
 				byte rleCount = src[2];
 				src += 3;
@@ -184,7 +185,7 @@ void ImageFile::decompressFrame(ImageFrame &frame, const byte *src) {
 		assert(frameSize == 0);
 	} else {
 		// Uncompressed frame
-		Common::copy(src, src + frame._width * frame._height, dest);
+		Common::copy(src, src + _width * _height, dest);
 	}
 }
 
@@ -1007,4 +1008,68 @@ void ImageFile3DO::loadFont(Common::SeekableReadStream &stream) {
 	delete[] widthTablePtr;
 }
 
+/*----------------------------------------------------------------*/
+
+StreamingImageFile::StreamingImageFile() {
+	_frameNumber = 0;
+	_stream = nullptr;
+	_flags = 0;
+	_scaleVal = 0;
+	_zPlacement = 0;
+}
+
+StreamingImageFile::~StreamingImageFile() {
+	close();
+}
+
+void StreamingImageFile::load(Common::SeekableReadStream *stream, bool compressed) {
+	_stream = stream;
+	_compressed = compressed;
+	_frameNumber = -1;
+}
+
+void StreamingImageFile::close() {
+	delete _stream;
+	_stream = nullptr;
+	_frameNumber = -1;
+}
+
+void StreamingImageFile::getNextFrame() {
+	// Don't proceed if we're already at the end of the stream
+	if (_stream->pos() >= _stream->size())
+		return;
+
+	// Increment frame number
+	++_frameNumber;
+
+	// If necessary, decompress the next frame
+	Common::SeekableReadStream *frameStream = _stream;
+	if (_compressed) {
+		uint32 inSize = _stream->readUint32LE();
+		Resources::decompressLZ(*_stream, _buffer, STREAMING_BUFFER_SIZE, inSize);
+		frameStream = new Common::MemoryReadStream(_buffer, 11, DisposeAfterUse::NO);
+	}
+
+	// Load the data for the frame
+	_imageFrame._width = frameStream->readUint16LE() + 1;
+	_imageFrame._height = frameStream->readUint16LE() + 1;
+	_imageFrame._paletteBase = frameStream->readByte();
+	_imageFrame._rleEncoded = frameStream->readByte() == 1;
+	_imageFrame._offset.x = frameStream->readByte();
+	_imageFrame._offset.y = frameStream->readByte();
+	_imageFrame._size = frameStream->readUint16LE() - 11;
+	_imageFrame._rleMarker = frameStream->readByte();
+
+	// Decode the frame
+	if (_compressed) {
+		delete frameStream;
+		_imageFrame.decompressFrame(_buffer + 11, true);
+	} else {
+		byte *data = new byte[_imageFrame._size];
+		_stream->read(data, _imageFrame._size);
+		_imageFrame.decompressFrame(_buffer + 11, true);
+		delete[] data;
+	}
+}
+
 } // End of namespace Sherlock
diff --git a/engines/sherlock/image_file.h b/engines/sherlock/image_file.h
index f24e831..3ac0cf4 100644
--- a/engines/sherlock/image_file.h
+++ b/engines/sherlock/image_file.h
@@ -46,6 +46,11 @@ struct ImageFrame {
 	Graphics::Surface _frame;
 
 	/**
+	 * Decompress a single frame for the sprite
+	 */
+	void decompressFrame(const byte *src, bool isRoseTattoo);
+
+	/**
 	 * Return the frame width adjusted by a specified scale amount
 	 */
 	int sDrawXSize(int scaleVal) const;
@@ -79,11 +84,6 @@ private:
 	 * Gets the palette at the start of the sprite file
 	 */
 	void loadPalette(Common::SeekableReadStream &stream);
-
-	/**
-	 * Decompress a single frame for the sprite
-	 */
-	void decompressFrame(ImageFrame  &frame, const byte *src);
 public:
 	byte _palette[256 * 3];
 public:
@@ -154,6 +154,54 @@ public:
 	static void setVm(SherlockEngine *vm);
 };
 
+#define STREAMING_BUFFER_SIZE 65536
+
+class StreamingImageFile {
+private:
+	int _frameNumber;
+	Common::SeekableReadStream *_stream;
+	bool _compressed;
+	byte _buffer[STREAMING_BUFFER_SIZE];
+public:
+	ImageFrame _imageFrame;
+
+	Common::Point _position;		// Animation position
+	Common::Rect _oldBounds;		// Bounds of previous frame
+	Common::Rect _removeBounds;		// Remove area for just drawn frame
+
+	int _flags;						// Flags
+	int _scaleVal;					// Specifies the scale amount
+	int _zPlacement;				// Used by doBgAnim for determining Z order
+public:
+	StreamingImageFile();
+	~StreamingImageFile();
+
+	/**
+	 * Initialize reading of the specified stream
+	 */
+	void load(Common::SeekableReadStream *stream, bool compressed);
+
+	/**
+	 * Close the streamining image file
+	 */
+	void close();
+
+	/**
+	 * Get the next frame of the file
+	 */
+	void getNextFrame();
+
+	/**
+	 * Returns whether there are any remaining frames or not
+	 */
+	bool active() const { return _stream != nullptr && _stream->pos() < _stream->size(); }
+
+	/**
+	 * Return the current frame number
+	 */
+	int frameNumber() const { return _frameNumber; }
+};
+
 } // End of namespace Sherlock
 
 #endif
diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp
index 7982262..97d63c5 100644
--- a/engines/sherlock/objects.cpp
+++ b/engines/sherlock/objects.cpp
@@ -1498,42 +1498,6 @@ void CAnim::load3DO(Common::SeekableReadStream &s, uint32 dataOffset) {
 
 /*----------------------------------------------------------------*/
 
-CAnimStream::CAnimStream() {
-	_images = nullptr;
-	_imageFrame = nullptr;
-	_frameNumber = 0;
-	_flags = 0;
-	_scaleVal = 0;
-	_zPlacement = 0;
-}
-
-CAnimStream::~CAnimStream() {
-	delete _images;
-}
-
-void CAnimStream::load(Common::SeekableReadStream *stream) {
-	delete _images;
-	_images = new ImageFile(*stream, false);
-	_imageFrame = &(*_images)[0];
-	_frameNumber = 0;
-}
-
-void CAnimStream::close() {
-	delete _images;
-	_images = nullptr;
-	_imageFrame = nullptr;
-	_frameNumber = 0;
-}
-
-void CAnimStream::getNextFrame() {
-	if (++_frameNumber < (int)_images->size())
-		_imageFrame = &(*_images)[_frameNumber];
-	else
-		_imageFrame = nullptr;
-}
-
-/*----------------------------------------------------------------*/
-
 SceneImage::SceneImage() {
 	_images = nullptr;
 	_maxFrames = 0;
diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h
index f29c789..7e94dd2 100644
--- a/engines/sherlock/objects.h
+++ b/engines/sherlock/objects.h
@@ -458,44 +458,6 @@ struct CAnim {
 	void load3DO(Common::SeekableReadStream &s, uint32 dataOffset);
 };
 
-class CAnimStream {
-	ImageFile *_images;					
-	int _frameNumber;
-public:
-	ImageFrame *_imageFrame;
-
-	Common::Point _position;		// Animation position
-	Common::Rect _oldBounds;		// Bounds of previous frame
-	Common::Rect _removeBounds;		// Remove area for just drawn frame
-
-	int _flags;						// Flags
-	int _scaleVal;					// Specifies the scale amount
-	int _zPlacement;				// Used by doBgAnim for determining Z order
-public:
-	CAnimStream();
-	~CAnimStream();
-
-	/**
-	 * Load the animation's images
-	 */
-	void load(Common::SeekableReadStream *stream);
-
-	/**
-	 * Close any currently active animation
-	 */
-	void close();
-
-	/**
-	 * Get the next frame of the animation
-	 */
-	void getNextFrame();
-
-	/**
-	 * Returns whether the animation is active
-	 */
-	bool active() const { return _imageFrame != nullptr; }
-};
-
 struct SceneImage {
 	ImageFile *_images;				// Object images
 	int _maxFrames;					// How many frames in object
diff --git a/engines/sherlock/scalpel/scalpel_scene.cpp b/engines/sherlock/scalpel/scalpel_scene.cpp
index bbe6674..fa820d9 100644
--- a/engines/sherlock/scalpel/scalpel_scene.cpp
+++ b/engines/sherlock/scalpel/scalpel_scene.cpp
@@ -574,7 +574,7 @@ int ScalpelScene::startCAnim(int cAnimNum, int playRate) {
 			//rrmStream->seek(rrmStream->readUint32LE());
 
 			// Load the canimation into the cache
-			Common::SeekableReadStream *imgStream = !_lzwMode ? roomStream->readStream(cAnim._dataSize) :
+			Common::SeekableReadStream *imgStream = !_compressed ? roomStream->readStream(cAnim._dataSize) :
 				Resources::decompressLZ(*roomStream, cAnim._dataSize);
 			res.addToCache(fname, *imgStream);
 
diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp
index e6a2762..c3917fb 100644
--- a/engines/sherlock/scene.cpp
+++ b/engines/sherlock/scene.cpp
@@ -224,7 +224,7 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) {
 	_loadingSavedGame = false;
 	_walkedInScene = false;
 	_version = 0;
-	_lzwMode = false;
+	_compressed = false;
 	_invGraphicItems = 0;
 	_cAnimFramePause = 0;
 	_restoreFlag = false;
@@ -350,9 +350,9 @@ bool Scene::loadScene(const Common::String &filename) {
 			rrmStream->seek(39);
 			if (IS_SERRATED_SCALPEL) {
 				_version = rrmStream->readByte();
-				_lzwMode = _version == 10;
+				_compressed = _version == 10;
 			} else {
-				_lzwMode = rrmStream->readByte() > 0;
+				_compressed = rrmStream->readByte() > 0;
 			}
 
 			// Go to header and read it in
@@ -370,7 +370,7 @@ bool Scene::loadScene(const Common::String &filename) {
 				paletteLoaded();
 
 				// Read in background
-				if (_lzwMode) {
+				if (_compressed) {
 					res.decompress(*rrmStream, (byte *)screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCREEN_HEIGHT);
 				} else {
 					rrmStream->read(screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCREEN_HEIGHT);
@@ -387,29 +387,29 @@ bool Scene::loadScene(const Common::String &filename) {
 			// Read information
 			if (IS_ROSE_TATTOO) {
 				// Load shapes
-				Common::SeekableReadStream *infoStream = !_lzwMode ? rrmStream : res.decompress(*rrmStream, bgHeader._numStructs * 625);
+				Common::SeekableReadStream *infoStream = !_compressed ? rrmStream : res.decompress(*rrmStream, bgHeader._numStructs * 625);
 
 				_bgShapes.resize(bgHeader._numStructs);
 				for (int idx = 0; idx < bgHeader._numStructs; ++idx)
 					_bgShapes[idx].load(*infoStream, _vm->getGameID() == GType_RoseTattoo);
 
-				if (_lzwMode)
+				if (_compressed)
 					delete infoStream;
 
 				// Load description text
 				_descText.resize(bgHeader._descSize);
-				if (_lzwMode)
+				if (_compressed)
 					res.decompress(*rrmStream, (byte *)&_descText[0], bgHeader._descSize);
 				else
 					rrmStream->read(&_descText[0], bgHeader._descSize);
 
 				// Load sequences
 				_sequenceBuffer.resize(bgHeader._seqSize);
-				if (_lzwMode)
+				if (_compressed)
 					res.decompress(*rrmStream, &_sequenceBuffer[0], bgHeader._seqSize);
 				else
 					rrmStream->read(&_sequenceBuffer[0], bgHeader._seqSize);
-			} else if (!_lzwMode) {
+			} else if (!_compressed) {
 				// Serrated Scalpel uncompressed info
 				_bgShapes.resize(bgHeader._numStructs);
 				for (int idx = 0; idx < bgHeader._numStructs; ++idx)
@@ -465,7 +465,7 @@ bool Scene::loadScene(const Common::String &filename) {
 				_images[idx + 1]._maxFrames = bgInfo[idx]._maxFrames;
 
 				// Read in the image data
-				Common::SeekableReadStream *imageStream = _lzwMode ?
+				Common::SeekableReadStream *imageStream = _compressed ?
 					res.decompress(*rrmStream, bgInfo[idx]._filesize) :
 					rrmStream->readStream(bgInfo[idx]._filesize);
 
@@ -495,7 +495,7 @@ bool Scene::loadScene(const Common::String &filename) {
 			_cAnim.clear();
 			if (bgHeader._numcAnimations) {
 				int animSize = IS_SERRATED_SCALPEL ? 65 : 47;
-				Common::SeekableReadStream *cAnimStream = _lzwMode ?
+				Common::SeekableReadStream *cAnimStream = _compressed ?
 					res.decompress(*rrmStream, animSize * bgHeader._numcAnimations) :
 					rrmStream->readStream(animSize * bgHeader._numcAnimations);
 
@@ -533,7 +533,7 @@ bool Scene::loadScene(const Common::String &filename) {
 
 			// Read in the room bounding areas
 			int size = rrmStream->readUint16LE();
-			Common::SeekableReadStream *boundsStream = !_lzwMode ? rrmStream :
+			Common::SeekableReadStream *boundsStream = !_compressed ? rrmStream :
 				res.decompress(*rrmStream, size);
 
 			_zones.resize(size / 10);
@@ -545,7 +545,7 @@ bool Scene::loadScene(const Common::String &filename) {
 				boundsStream->skip(2);	// Skip unused scene number field
 			}
 
-			if (_lzwMode)
+			if (_compressed)
 				delete boundsStream;
 
 			// Ensure we've reached the path version byte
@@ -564,7 +564,7 @@ bool Scene::loadScene(const Common::String &filename) {
 
 			// Read in the walk data
 			size = rrmStream->readUint16LE();
-			Common::SeekableReadStream *walkStream = !_lzwMode ? rrmStream :
+			Common::SeekableReadStream *walkStream = !_compressed ? rrmStream :
 				res.decompress(*rrmStream, size);
 
 			int startPos = walkStream->pos();
@@ -574,7 +574,7 @@ bool Scene::loadScene(const Common::String &filename) {
 				_walkPoints[_walkPoints.size() - 1].load(*walkStream, IS_ROSE_TATTOO);
 			}
 
-			if (_lzwMode)
+			if (_compressed)
 				delete walkStream;
 
 			// Translate the file offsets of the walk directory to indexes in the loaded walk data
@@ -639,12 +639,12 @@ bool Scene::loadScene(const Common::String &filename) {
 				Common::copy(screen._cMap, screen._cMap + PALETTE_SIZE, screen._sMap);
 
 				// Read in the background
-				Common::SeekableReadStream *bgStream = !_lzwMode ? rrmStream :
+				Common::SeekableReadStream *bgStream = !_compressed ? rrmStream :
 					res.decompress(*rrmStream, SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT);
 
 				bgStream->read(screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT);
 
-				if (_lzwMode)
+				if (_compressed)
 					delete bgStream;
 			}
 
diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h
index d4c8835..5037b9d 100644
--- a/engines/sherlock/scene.h
+++ b/engines/sherlock/scene.h
@@ -216,7 +216,7 @@ public:
 	bool **_sceneStats;
 	bool _walkedInScene;
 	int _version;
-	bool _lzwMode;
+	bool _compressed;
 	int _invGraphicItems;
 	Common::String _comments;
 	Common::Array<char> _descText;
diff --git a/engines/sherlock/tattoo/tattoo_scene.cpp b/engines/sherlock/tattoo/tattoo_scene.cpp
index 1c6f926..3a0888c 100644
--- a/engines/sherlock/tattoo/tattoo_scene.cpp
+++ b/engines/sherlock/tattoo/tattoo_scene.cpp
@@ -130,8 +130,8 @@ void TattooScene::drawAllShapes() {
 	}
 
 	// Draw the animation if it is behind the person
-	if (_activeCAnim._imageFrame != nullptr && _activeCAnim._zPlacement == BEHIND)
-		screen._backBuffer1.transBlitFrom(*_activeCAnim._imageFrame, _activeCAnim._position,
+	if (_activeCAnim.active() && _activeCAnim._zPlacement == BEHIND)
+		screen._backBuffer1.transBlitFrom(_activeCAnim._imageFrame, _activeCAnim._position,
 			(_activeCAnim._flags & 4) >> 1, 0, _activeCAnim._scaleVal);
 
 	screen.resetDisplayBounds();
@@ -151,13 +151,13 @@ void TattooScene::drawAllShapes() {
 	}
 
 	// Queue drawing the animation if it is NORMAL and can fall in front of, or behind the people
-	if (_activeCAnim._imageFrame != nullptr && (_activeCAnim._zPlacement == NORMAL_BEHIND || _activeCAnim._zPlacement == NORMAL_FORWARD)) {
+	if (_activeCAnim.active() && (_activeCAnim._zPlacement == NORMAL_BEHIND || _activeCAnim._zPlacement == NORMAL_FORWARD)) {
 		if (_activeCAnim._scaleVal == SCALE_THRESHOLD)
-			shapeList.push_back(ShapeEntry(_activeCAnim._position.y + _activeCAnim._imageFrame->_offset.y +
-				_activeCAnim._imageFrame->_height));
+			shapeList.push_back(ShapeEntry(_activeCAnim._position.y + _activeCAnim._imageFrame._offset.y +
+				_activeCAnim._imageFrame._height));
 		else
-			shapeList.push_back(ShapeEntry(_activeCAnim._position.y + _activeCAnim._imageFrame->sDrawYOffset(_activeCAnim._scaleVal) +
-				_activeCAnim._imageFrame->sDrawYSize(_activeCAnim._scaleVal)));
+			shapeList.push_back(ShapeEntry(_activeCAnim._position.y + _activeCAnim._imageFrame.sDrawYOffset(_activeCAnim._scaleVal) +
+				_activeCAnim._imageFrame.sDrawYSize(_activeCAnim._scaleVal)));
 	}
 
 	// Queue all active characters for drawing
@@ -182,7 +182,7 @@ void TattooScene::drawAllShapes() {
 					se._shape->_flags & OBJ_FLIPPED, 0, se._shape->_scaleVal);
 		} else if (se._isAnimation) {
 			// It's an active animation
-			screen._backBuffer1.transBlitFrom(*_activeCAnim._imageFrame, _activeCAnim._position,
+			screen._backBuffer1.transBlitFrom(_activeCAnim._imageFrame, _activeCAnim._position,
 				(_activeCAnim._flags & 4) >> 1, 0, _activeCAnim._scaleVal);
 		} else {
 			// Drawing person
@@ -244,8 +244,8 @@ void TattooScene::drawAllShapes() {
 	}
 
 	// Draw the canimation if it is set as FORWARD
-	if (_activeCAnim._imageFrame != nullptr && _activeCAnim._zPlacement == FORWARD)
-		screen._backBuffer1.transBlitFrom(*_activeCAnim._imageFrame, _activeCAnim._position, (_activeCAnim._flags & 4) >> 1, 0, _activeCAnim._scaleVal);
+	if (_activeCAnim.active() && _activeCAnim._zPlacement == FORWARD)
+		screen._backBuffer1.transBlitFrom(_activeCAnim._imageFrame, _activeCAnim._position, (_activeCAnim._flags & 4) >> 1, 0, _activeCAnim._scaleVal);
 
 	// Draw all NO_SHAPE shapes which have their flag bits clear
 	for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
@@ -268,13 +268,13 @@ void TattooScene::checkBgShapes() {
 	Scene::checkBgShapes();
 
 	// Check for any active playing animation
-	if (_activeCAnim._imageFrame && _activeCAnim._zPlacement != REMOVE) {
+	if (_activeCAnim.active() && _activeCAnim._zPlacement != REMOVE) {
 		switch (_activeCAnim._flags & 3) {
 		case 0:
 			_activeCAnim._zPlacement = BEHIND;
 			break;
 		case 1:
-			_activeCAnim._zPlacement = ((_activeCAnim._position.y + _activeCAnim._imageFrame->_frame.h - 1)) ?
+			_activeCAnim._zPlacement = ((_activeCAnim._position.y + _activeCAnim._imageFrame._frame.h - 1)) ?
 				NORMAL_FORWARD : NORMAL_BEHIND;
 			break;
 		case 2:
@@ -381,10 +381,6 @@ void TattooScene::doBgAnimUpdateBgObjectsAndAnim() {
 			people[idx].adjustSprite();
 	}
 
-	if (_activeCAnim._imageFrame != nullptr && _activeCAnim._zPlacement != REMOVE) {
-		_activeCAnim.getNextFrame();
-	}
-
 	// Flag the bg shapes which need to be redrawn
 	checkBgShapes();
 	drawAllShapes();
@@ -531,9 +527,9 @@ void TattooScene::doBgAnimDrawSprites() {
 		}
 	}
 
-	if (_activeCAnim._imageFrame != nullptr || _activeCAnim._zPlacement == REMOVE) {
+	if (_activeCAnim.active() || _activeCAnim._zPlacement == REMOVE) {
 		if (_activeCAnim._zPlacement != REMOVE) {
-			screen.flushImage(_activeCAnim._imageFrame, _activeCAnim._position, _activeCAnim._oldBounds, _activeCAnim._scaleVal);
+			screen.flushImage(&_activeCAnim._imageFrame, _activeCAnim._position, _activeCAnim._oldBounds, _activeCAnim._scaleVal);
 		} else {
 			screen.slamArea(_activeCAnim._removeBounds.left - ui._currentScroll.x, _activeCAnim._removeBounds.top, 
 				_activeCAnim._removeBounds.width(), _activeCAnim._removeBounds.height());
@@ -651,11 +647,16 @@ int TattooScene::startCAnim(int cAnimNum, int playRate) {
 	_activeCAnim._scaleVal = cAnim._scaleVal;
 	_activeCAnim._zPlacement = 0;
 
-	_activeCAnim.load(animStream);
+	_activeCAnim.load(animStream, _compressed);
 
 	while (_activeCAnim.active() && !_vm->shouldQuit()) {
+		// Get the next frame
+		_activeCAnim.getNextFrame();
+
+		// Draw the frame
 		doBgAnim();
 
+		// Check for Escape key being pressed to abort animation
 		events.pollEvents();
 		if (events.kbHit()) {
 			Common::KeyState keyState = events.getKey();
diff --git a/engines/sherlock/tattoo/tattoo_scene.h b/engines/sherlock/tattoo/tattoo_scene.h
index 106903f..81d7637 100644
--- a/engines/sherlock/tattoo/tattoo_scene.h
+++ b/engines/sherlock/tattoo/tattoo_scene.h
@@ -97,7 +97,7 @@ protected:
 	 */
 	virtual void synchronize(Serializer &s);
 public:
-	CAnimStream _activeCAnim;
+	StreamingImageFile _activeCAnim;
 	Common::Array<SceneTripEntry> _sceneTripCounters;
 	bool _labTableScene;
 public:
diff --git a/engines/sherlock/tattoo/tattoo_user_interface.cpp b/engines/sherlock/tattoo/tattoo_user_interface.cpp
index ff98706..51dd4d1 100644
--- a/engines/sherlock/tattoo/tattoo_user_interface.cpp
+++ b/engines/sherlock/tattoo/tattoo_user_interface.cpp
@@ -323,7 +323,7 @@ void TattooUserInterface::doBgAnimRestoreUI() {
 	_tooltipWidget.erase();
 
 	// If a canimation is active, restore the graphics underneath it
-	if (scene._activeCAnim._imageFrame != nullptr)
+	if (scene._activeCAnim.active())
 		screen.restoreBackground(scene._activeCAnim._oldBounds);
 
 	// If a canimation just ended, remove it's graphics from the backbuffer






More information about the Scummvm-git-logs mailing list