Permalink
Browse files

MUTATIONOFJB: Extend blit_if to support both ManagedSurface and Surface.

  • Loading branch information...
LubomirR authored and sev- committed Aug 1, 2018
1 parent 32df911 commit 4fbbaf944a392d67047dac64835f37cfcf518ecf
Showing with 58 additions and 8 deletions.
  1. +8 −2 engines/mutationofjb/room.cpp
  2. +50 −6 engines/mutationofjb/util.h
@@ -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;
}
};

@@ -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>

0 comments on commit 4fbbaf9

Please sign in to comment.