[Scummvm-cvs-logs] scummvm master -> 6928ddba1574dcbe87c06f3774968ae8f3fc02ea

sev- sev at scummvm.org
Tue Jun 14 19:28:37 CEST 2016


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:
6928ddba15 SCUMM HE: Initial Moonbase distortion code


Commit: 6928ddba1574dcbe87c06f3774968ae8f3fc02ea
    https://github.com/scummvm/scummvm/commit/6928ddba1574dcbe87c06f3774968ae8f3fc02ea
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2016-06-14T19:28:29+02:00

Commit Message:
SCUMM HE: Initial Moonbase distortion code

Changed paths:
  A engines/scumm/he/moonbase/distortion.cpp
    engines/scumm/he/moonbase/moonbase.h
    engines/scumm/module.mk



diff --git a/engines/scumm/he/moonbase/distortion.cpp b/engines/scumm/he/moonbase/distortion.cpp
new file mode 100644
index 0000000..121a194
--- /dev/null
+++ b/engines/scumm/he/moonbase/distortion.cpp
@@ -0,0 +1,236 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "scumm/he/intern_he.h"
+#include "engines/scumm/he/moonbase/moonbase.h"
+
+namespace Scumm {
+
+enum {
+	kHalfRange = (0x1f / 2),
+	kBptHeaderSize = 8,
+
+	kReflectionClipped = 0,
+	kNotClipped = 1,
+	kSpecializedNotClipped = 2
+};
+
+void blitCore(
+	Graphics::Surface *dstBitmap,
+	const int x, const int y,
+	const Graphics::Surface *distortionBitmap,
+	const Common::Rect *optionalclipRectPtr,
+	int transferOp,
+	const Graphics::Surface *srcBitmap,
+	int offset_x, int offset_y,
+	Common::Rect *srcClipRect
+) {
+	Common::Rect clipRect(dstBitmap->w, dstBitmap->h);
+
+	if (optionalclipRectPtr)
+		if (!clipRect.intersects(*optionalclipRectPtr))
+			return;
+
+	clipRect.clip(*optionalclipRectPtr);
+
+	Common::Rect distortionRect(distortionBitmap->w, distortionBitmap->h);
+	Common::Rect dstRect(x, y, x + distortionRect.width(), y + distortionRect.height());
+
+	if (!dstRect.intersects(clipRect))
+		return;
+
+	dstRect.clip(clipRect);
+
+	distortionRect.moveTo(dstRect.left - x, dstRect.top - y);
+
+	byte *distortionPtr = (byte *)distortionBitmap->getBasePtr(distortionRect.left, distortionRect.top);
+	byte *dstPtr = (byte *)dstBitmap->getBasePtr(dstRect.left, dstRect.top);
+	int cw = dstRect.width();
+	int ch = dstRect.height();
+	int idx = dstRect.left;
+	int dy = dstRect.top;
+
+	int baseX, baseY;
+	byte *srcData = (byte *)srcBitmap->getBasePtr(0, 0);
+	int srcPitch = srcBitmap->pitch;
+
+	switch (transferOp) {
+	case kReflectionClipped:
+	case kNotClipped:
+		baseX = offset_x - kHalfRange;
+		baseY = offset_y - kHalfRange;
+		break;
+
+	case kSpecializedNotClipped:
+	default:
+		baseX = 0;
+		baseY = 0;
+	}
+
+	while (--ch >= 0) {
+		uint16 *d = (uint16 *)dstPtr;
+		uint16 *is = (uint16 *)distortionPtr;
+		int dx = idx;
+
+		for (int i = cw; --i >= 0;) {
+			uint16 p = READ_LE_UINT16(is);
+			int sx = baseX + dx + (p >> 5) & 0x1f; // G color
+			int sy = baseY + dy + p & 0x1f;        // B color;
+
+			if (transferOp == kReflectionClipped) {
+				if (sx < srcClipRect->left)
+					sx -= (srcClipRect->left - sx);
+
+				if (sx > srcClipRect->right)
+					sx -= (sx - srcClipRect->right);
+
+				sx = MAX<int>(srcClipRect->left, MIN<int>(sx, srcClipRect->right));
+
+				if (sy < srcClipRect->top)
+					sy -= (srcClipRect->top - sy);
+
+				if (sy > srcClipRect->bottom)
+					sy -= (sy - srcClipRect->bottom);
+
+				sy = MAX<int>(srcClipRect->top, MIN<int>(sy, srcClipRect->bottom));
+			}
+
+			*d = *((uint16 *)(srcData + sy * srcPitch + sx * 2));
+
+			++d;
+			++is;
+			++dx;
+		}
+
+		dstPtr += dstBitmap->pitch;
+		distortionPtr += distortionBitmap->pitch;
+
+		++dy;
+	}
+}
+
+void distortionBlit(
+	Graphics::Surface *dstBitmap,
+	Graphics::Surface *srcBitmap,
+	Graphics::Surface *distortionBitmap,
+	const int dst_x, const int dst_y,
+	const int src_x, const int src_y,
+	const int l_reach, const int r_reach, const int t_reach, const int b_reach,
+	const Common::Rect &srcClipRect, const Common::Rect &dstClipRect
+) {
+	Common::Rect srcReach((src_x - l_reach), (src_y - t_reach), (src_x + r_reach), (src_y + b_reach));
+	Common::Rect srcLimits(srcBitmap->w, srcBitmap->h);
+
+	if (!srcLimits.intersects(srcClipRect))
+		return;
+
+	srcLimits.clip(srcClipRect);
+
+	if (!srcReach.intersects(srcLimits))
+		return;
+
+	srcReach.clip(srcLimits);
+
+	if (srcLimits.contains(srcReach)) {
+		if (srcBitmap->pitch == 1280) {
+			blitCore(dstBitmap, dst_x, dst_y, distortionBitmap, &dstClipRect, kSpecializedNotClipped, srcBitmap, (dst_x - src_x), (dst_y - src_y), 0);
+		} else {
+			blitCore(dstBitmap, dst_x, dst_y, distortionBitmap, &dstClipRect, kNotClipped, srcBitmap, (dst_x - src_x), (dst_y - src_y), 0);
+		}
+	} else {
+		blitCore(dstBitmap, dst_x, dst_y, distortionBitmap, &dstClipRect, kReflectionClipped, srcBitmap, (dst_x - src_x), (dst_y - src_y), &srcLimits);
+	}
+}
+
+void Moonbase::blitDistortion(byte *bufferData, const int bufferWidth, const int bufferHeight, const int bufferPitch,
+		const Common::Rect *optionalClippingRect, byte *dataStream, const int x, const int y, byte *altSourceBuffer) {
+	byte *sourcePixels = (altSourceBuffer) ? altSourceBuffer : bufferData;
+	Common::Rect dstLimitsRect(bufferWidth, bufferHeight);
+	Common::Rect clippedDstRect = dstLimitsRect;
+
+	if (optionalClippingRect) {
+		if (!dstLimitsRect.intersects(*optionalClippingRect))
+			return;
+		dstLimitsRect.clip(*optionalClippingRect);
+	} else {
+		clippedDstRect = dstLimitsRect;
+	}
+
+	int w = READ_LE_UINT16(dataStream + kBptHeaderSize + 0);
+	int h = READ_LE_UINT16(dataStream + kBptHeaderSize + 2);
+	Common::Rect srcLimitsRect(w, h);
+	Common::Rect clippedSrcRect = srcLimitsRect;
+	Common::Rect dstOperation(x, y, x + clippedSrcRect.width(), y + clippedSrcRect.height());
+
+	if (!clippedDstRect.intersects(dstOperation))
+		return;
+
+	clippedDstRect.clip(dstOperation);
+
+	int subBlockCount = READ_LE_UINT16(dataStream + kBptHeaderSize + 4);
+	byte *subBlockStream = dataStream + kBptHeaderSize + READ_LE_UINT16(dataStream) + 2;
+	int cx1 = clippedDstRect.left;
+	int cy1 = clippedDstRect.top;
+	int cx2 = clippedDstRect.right - 1;
+	int cy2 = clippedDstRect.bottom - 1;
+
+	for (int i = 0; i < subBlockCount; i++) {
+		byte *blockData = subBlockStream;
+		uint32 blockSize = READ_LE_UINT32(blockData); blockData += 4;
+		subBlockStream += blockSize;
+		int xOffset = READ_LE_UINT16(blockData); blockData += 2;
+		int yOffset = READ_LE_UINT16(blockData); blockData += 2;
+		int width = READ_LE_UINT16(blockData); blockData += 2;
+		int height = READ_LE_UINT16(blockData); blockData += 2;
+		int l_Reach = READ_LE_UINT16(blockData); blockData += 2;
+		int r_Reach = READ_LE_UINT16(blockData); blockData += 2;
+		int t_Reach = READ_LE_UINT16(blockData); blockData += 2;
+		int b_Reach = READ_LE_UINT16(blockData); blockData += 2;
+		int distortionPitch = ((width * 2 + 7) / 8); // 2 for 555
+
+		if (width == 0 && height == 0)
+			continue;
+
+		Graphics::Surface mappedDstBitmap;
+		mappedDstBitmap.init(bufferWidth, bufferHeight, bufferPitch, bufferData, Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0));
+
+		Graphics::Surface mappedSrcBitmap;
+		mappedSrcBitmap.init(bufferWidth, bufferHeight, bufferPitch, sourcePixels, Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0));
+
+		Graphics::Surface mappedDistortionBitmap;
+		mappedDistortionBitmap.init(width, height, distortionPitch, blockData, Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0));
+
+		Common::Rect srcClipRect(cx1, cy1, cx2, cy2);
+		Common::Rect dstClipRect(cx1, cy1, cx2, cy2);
+
+		distortionBlit(
+			&mappedDstBitmap,
+			&mappedSrcBitmap,
+			&mappedDistortionBitmap,
+			(x + xOffset), (y + yOffset),
+			(x + xOffset), (y + yOffset),
+			l_Reach, r_Reach, t_Reach, b_Reach,
+			srcClipRect, dstClipRect);
+	}
+}
+
+}
diff --git a/engines/scumm/he/moonbase/moonbase.h b/engines/scumm/he/moonbase/moonbase.h
index 1d87eed..71c03cb 100644
--- a/engines/scumm/he/moonbase/moonbase.h
+++ b/engines/scumm/he/moonbase/moonbase.h
@@ -42,6 +42,8 @@ public:
 
 	void blitT14WizImage(uint8 *dst, int dstw, int dsth, int dstPitch, const Common::Rect *clipBox,
 			 uint8 *wizd, int srcx, int srcy, int rawROP, int paramROP);
+	void blitDistortion(byte *bufferData, const int bufferWidth, const int bufferHeight, const int bufferPitch,
+			const Common::Rect *optionalClippingRect, byte *dataStream, const int x, const int y, byte *altSourceBuffer);
 
 	// FOW Stuff
 	bool isFOW(int resNum, int state, uint32 conditionBits) {
diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk
index 04611ba..85ff1aa 100644
--- a/engines/scumm/module.mk
+++ b/engines/scumm/module.mk
@@ -147,6 +147,7 @@ MODULE_OBJS += \
 	he/moonbase/ai_tree.o \
 	he/moonbase/ai_types.o \
 	he/moonbase/ai_weapon.o \
+	he/moonbase/distortion.o \
 	he/moonbase/moonbase.o \
 	he/moonbase/moonbase_fow.o
 endif






More information about the Scummvm-git-logs mailing list