diff options
Diffstat (limited to 'engines/mutationofjb')
-rw-r--r-- | engines/mutationofjb/room.cpp | 10 | ||||
-rw-r--r-- | engines/mutationofjb/util.h | 56 |
2 files changed, 58 insertions, 8 deletions
diff --git a/engines/mutationofjb/room.cpp b/engines/mutationofjb/room.cpp index dd9a6dbab5..a396a64828 100644 --- a/engines/mutationofjb/room.cpp +++ b/engines/mutationofjb/room.cpp @@ -120,8 +120,14 @@ bool Room::load(uint8 roomNumber, bool roomB) { // TODO: Take the threshold value from ATN data. struct ThresholdBlitOperation { - bool operator()(const byte /*srcColor*/, const byte destColor) { - return destColor <= 0xBF; + byte operator()(const byte srcColor, const byte destColor) { + if (destColor <= 0xBF) { + // Within threshold - replace destination with source color. + return srcColor; + } + + // Outside of threshold - keep destination color. + return destColor; } }; diff --git a/engines/mutationofjb/util.h b/engines/mutationofjb/util.h index 06d1a0b2a1..51c532b814 100644 --- a/engines/mutationofjb/util.h +++ b/engines/mutationofjb/util.h @@ -38,29 +38,73 @@ namespace MutationOfJB { void reportFileMissingError(const char *fileName); Common::String toUpperCP895(const Common::String &str); +template <typename SurfaceType> +void clipBounds(Common::Rect &srcBounds, Common::Rect &destBounds, SurfaceType &destSurf) { + // Clip the bounds if source is too big to fit into destination. + if (destBounds.right > destSurf.w) { + srcBounds.right -= destBounds.right - destSurf.w; + destBounds.right = destSurf.w; + } + + if (destBounds.bottom > destSurf.h) { + srcBounds.bottom -= destBounds.bottom - destSurf.h; + destBounds.bottom = destSurf.h; + } + + if (destBounds.top < 0) { + srcBounds.top += -destBounds.top; + destBounds.top = 0; + } + + if (destBounds.left < 0) { + srcBounds.left += -destBounds.left; + destBounds.left = 0; + } +} + template <typename BlitOp> -void blit_if(const Graphics::Surface &src, const Common::Rect &srcRect, Graphics::ManagedSurface &dest, const Common::Point &destPos, BlitOp blitOp) { - const Common::Rect srcBounds = srcRect; - const Common::Rect destBounds(destPos.x, destPos.y, destPos.x + srcRect.width(), destPos.y + srcRect.height()); +void blit_if(const Graphics::Surface &src, const Common::Rect &srcRect, Graphics::Surface &dest, const Common::Point &destPos, BlitOp blitOp) { + Common::Rect srcBounds = srcRect; + Common::Rect destBounds(destPos.x, destPos.y, destPos.x + srcRect.width(), destPos.y + srcRect.height()); assert(srcRect.isValidRect()); assert(dest.format == src.format); + clipBounds(srcBounds, destBounds, dest); + for (int y = 0; y < srcBounds.height(); ++y) { const byte *srcP = reinterpret_cast<const byte *>(src.getBasePtr(srcBounds.left, srcBounds.top + y)); const byte *srcEndP = srcP + srcBounds.width(); byte *destP = reinterpret_cast<byte *>(dest.getBasePtr(destBounds.left, destBounds.top + y)); while (srcP != srcEndP) { - if (blitOp(*srcP, *destP)) { - *destP = *srcP; + const byte newColor = blitOp(*srcP, *destP); + if (*destP != newColor) { + *destP = newColor; } ++srcP; ++destP; } } +} - dest.getSubArea(destBounds); // This is a hack to invalidate the destination rectangle. +template <typename BlitOp> +void blit_if(const Graphics::Surface &src, const Common::Rect &srcRect, Graphics::ManagedSurface &dest, const Common::Point &destPos, BlitOp blitOp) { + Common::Rect srcBounds = srcRect; + Common::Rect destBounds(destPos.x, destPos.y, destPos.x + srcRect.width(), destPos.y + srcRect.height()); + + assert(srcRect.isValidRect()); + assert(dest.format == src.format); + + clipBounds(srcBounds, destBounds, dest); + + Graphics::Surface destSurf = dest.getSubArea(destBounds); // This will invalidate the rectangle. + blit_if(src, srcRect, destSurf, Common::Point(0, 0), blitOp); +} + +template <typename BlitOp> +void blit_if(const Graphics::Surface &src, Graphics::Surface &dest, const Common::Point &destPos, BlitOp blitOp) { + blit_if(src, Common::Rect(0, 0, src.w, src.h), dest, destPos, blitOp); } template <typename BlitOp> |