From cb874522e4fac3108070d5054977696a58ddb510 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 16 Mar 2015 23:38:58 -0400 Subject: SHERLOCK: Implement screen clipping for sprite drawing --- engines/sherlock/animation.cpp | 22 ++++++++++++---------- engines/sherlock/graphics.cpp | 38 ++++++++++++++++++++++++++++++++++++++ engines/sherlock/graphics.h | 6 ++++++ 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index e4ec06b741..581971820d 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -101,7 +101,7 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f events.delay(minDelay); if (fade != 0 && fade != 255) screen.fadeToBlack(); - fade = 0; //***DEBUG**** + if (setPalette) { if (fade != 255) screen.setPalette(sprite._palette); @@ -112,19 +112,26 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f Common::Point pt; bool skipped = false; while (!_vm->shouldQuit()) { + // Get the next sprite to display spriteFrame = stream->readSint16LE(); - if (spriteFrame != -1) { + + if (spriteFrame == -2) { + // End of animation reached + break; + } else if (spriteFrame != -1) { + // Read position from either animation stream or the sprite frame itself if (spriteFrame < 0) { - spriteFrame = ABS(spriteFrame); + spriteFrame += 32769; pt.x = stream->readUint16LE(); pt.y = stream->readUint16LE(); } else { pt = sprite[spriteFrame]._position; } - screen.copyFrom(sprite[spriteFrame]._frame); - events.pollEventsAndWait(); + // Draw the sprite + screen.copyFrom(sprite[spriteFrame]._frame, pt); } else { + // No sprite to show for this animation frame if (fade == 255) { // Gradual fade in if (screen.equalizePalette(sprite._palette) == 0) @@ -144,11 +151,6 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f } events.delay(speed); - - if (stream->readSint16LE() == -2) - // End of animation - break; - stream->seek(-2, SEEK_CUR); } if (events.isKeyPressed()) { diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index f4fe6b6b46..fbfd3b7b45 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -35,6 +35,44 @@ Surface::~Surface() { free(); } +/** + * Draws a surface into another + */ +void Surface::copyFrom(const Graphics::Surface &src) { + copyFrom(src, Common::Point()); +} + +/** + * Draws a surface at a given position within this surface + */ +void Surface::copyFrom(const Graphics::Surface &src, const Common::Point &pt) { + Common::Rect drawRect(0, 0, src.w, src.h); + Common::Point destPt = pt; + + if (destPt.x < 0) { + drawRect.left += -destPt.x; + destPt.x = 0; + } + if (destPt.y < 0) { + drawRect.top += -destPt.y; + destPt.y = 0; + } + int right = destPt.x + src.w; + if (right > this->w) { + drawRect.right -= (right - this->w); + } + int bottom = destPt.y + src.h; + if (bottom > this->h) { + drawRect.bottom -= (bottom - this->h); + } + + if (drawRect.isValidRect()) { + addDirtyRect(Common::Rect(destPt.x, destPt.y, destPt.x + drawRect.width(), + destPt.y + drawRect.height())); + copyRectToSurface(src, destPt.x, destPt.y, drawRect); + } +} + void Surface::fillRect(int x1, int y1, int x2, int y2, byte color) { Graphics::Surface::fillRect(Common::Rect(x1, y1, x2, y2), color); } diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index c6611db1ce..79cffa839a 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -36,9 +36,15 @@ namespace Sherlock { class SherlockEngine; class Surface : public Graphics::Surface { +protected: + virtual void addDirtyRect(const Common::Rect &r) {} public: Surface(uint16 width, uint16 height); ~Surface(); + + void copyFrom(const Graphics::Surface &src); + void copyFrom(const Graphics::Surface &src, const Common::Point &pt); + void fillRect(int x1, int y1, int x2, int y2, byte color); void drawSprite(int x, int y, SpriteFrame *spriteFrame, bool flipped = false, bool altFlag = false); }; -- cgit v1.2.3