aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2015-06-27 19:23:42 -0400
committerPaul Gilbert2015-06-27 19:23:42 -0400
commit7594507277ba7506b8c7142b8a1463a97036c14d (patch)
tree678a9f0e4df20423559ba5ccb38e019a38b0468d
parent7ecf553e24ce6d8267e66bb903388ff55805e418 (diff)
downloadscummvm-rg350-7594507277ba7506b8c7142b8a1463a97036c14d.tar.gz
scummvm-rg350-7594507277ba7506b8c7142b8a1463a97036c14d.tar.bz2
scummvm-rg350-7594507277ba7506b8c7142b8a1463a97036c14d.zip
SHERLOCK: RT: Properly implement StreamingImageFile class
-rw-r--r--engines/sherlock/image_file.cpp95
-rw-r--r--engines/sherlock/image_file.h58
-rw-r--r--engines/sherlock/objects.cpp36
-rw-r--r--engines/sherlock/objects.h38
-rw-r--r--engines/sherlock/scalpel/scalpel_scene.cpp2
-rw-r--r--engines/sherlock/scene.cpp34
-rw-r--r--engines/sherlock/scene.h2
-rw-r--r--engines/sherlock/tattoo/tattoo_scene.cpp39
-rw-r--r--engines/sherlock/tattoo/tattoo_scene.h2
-rw-r--r--engines/sherlock/tattoo/tattoo_user_interface.cpp2
10 files changed, 174 insertions, 134 deletions
diff --git a/engines/sherlock/image_file.cpp b/engines/sherlock/image_file.cpp
index 78284e416d..4d713b155a 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 f24e831440..3ac0cf4b5f 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 79822623d2..97d63c5da6 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 f29c7890ab..7e94dd2bdd 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 bbe6674837..fa820d95fd 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 e6a2762055..c3917fb003 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 d4c88350cc..5037b9d2cf 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 1c6f9263e9..3a0888ca57 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 106903f076..81d76374f3 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 ff98706844..51dd4d1f7c 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