[Scummvm-git-logs] scummvm master -> 40501547f42b6202a15582d974d88776d759aacb

stevenhoefel stevenhoefel at hotmail.com
Fri Apr 10 12:38:28 UTC 2020


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:
40501547f4 DIRECTOR: Extend Reverse Sprite drawing for shapes and controls.


Commit: 40501547f42b6202a15582d974d88776d759aacb
    https://github.com/scummvm/scummvm/commit/40501547f42b6202a15582d974d88776d759aacb
Author: stevenhoefel (stevenhoefel at hotmail.com)
Date: 2020-04-10T22:38:12+10:00

Commit Message:
DIRECTOR: Extend Reverse Sprite drawing for shapes and controls.
Translate 32-bit images into palette-based sprites.

Changed paths:
    engines/director/frame.cpp
    engines/director/frame.h
    engines/director/images.cpp
    engines/director/images.h
    engines/director/score.cpp


diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index 02397797c5..145e24805d 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -650,7 +650,7 @@ void Frame::renderSprites(Graphics::ManagedSurface &surface, bool renderTrail) {
 			int width = _vm->getVersion() > 4 ? bc->_initialRect.width() : _sprites[i]->_width;
 			Common::Rect drawRect(x, y, x + width, y + height);
 			addDrawRect(i, drawRect);
-			inkBasedBlit(surface, *(bc->_surface), ink, drawRect);
+			inkBasedBlit(surface, *(bc->_surface), ink, drawRect, i);
 		}
 	}
 }
@@ -671,9 +671,7 @@ void Frame::renderShape(Graphics::ManagedSurface &surface, uint16 spriteId) {
 	byte backColor = sp->_backColor;
 	int lineSize = sp->_thickness & 0x3;
 
-	// D3 Shared Cast Members don't have these values specified, they're provided when you add
-	// them to the score in each movie.
-	if (_vm->getVersion() > 3 && spriteType == kCastMemberSprite) {
+	if (_vm->getVersion() >= 3 && spriteType == kCastMemberSprite) {
 		if (!sp->_cast) {
 			warning("Frame::renderShape(): kCastMemberSprite has no cast defined");
 			return;
@@ -698,10 +696,12 @@ void Frame::renderShape(Graphics::ManagedSurface &surface, uint16 spriteId) {
 				default:
 					break;
 				}
-				foreColor = sc->_fgCol;
-				backColor = sc->_bgCol;
-				lineSize = sc->_lineThickness;
-				ink = sc->_ink;
+				if (_vm->getVersion() > 3) {
+					foreColor = sc->_fgCol;
+					backColor = sc->_bgCol;
+					lineSize = sc->_lineThickness;
+					ink = sc->_ink;
+				}
 				// shapes should be rendered with transparency by default
 				if (ink == kInkTypeCopy) {
 					ink = kInkTypeTransparent;
@@ -778,7 +778,7 @@ void Frame::renderShape(Graphics::ManagedSurface &surface, uint16 spriteId) {
 	}
 
 	addDrawRect(spriteId, shapeRect);
-	inkBasedBlit(surface, tmpSurface, ink, shapeRect);
+	inkBasedBlit(surface, tmpSurface, ink, shapeRect, spriteId);
 
 }
 
@@ -1025,10 +1025,10 @@ void Frame::renderText(Graphics::ManagedSurface &surface, uint16 spriteId, Commo
 	if (spriteId == _vm->getCurrentScore()->_currentMouseDownSpriteId)
 		ink = kInkTypeReverse;
 
-	inkBasedBlit(surface, textWithFeatures, ink, Common::Rect(x, y, x + width, y + height));
+	inkBasedBlit(surface, textWithFeatures, ink, Common::Rect(x, y, x + width, y + height), spriteId);
 }
 
-void Frame::inkBasedBlit(Graphics::ManagedSurface &targetSurface, const Graphics::Surface &spriteSurface, InkType ink, Common::Rect drawRect) {
+void Frame::inkBasedBlit(Graphics::ManagedSurface &targetSurface, const Graphics::Surface &spriteSurface, InkType ink, Common::Rect drawRect, uint spriteId) {
 	// drawRect could be bigger than the spriteSurface. Clip it
 	Common::Rect t(spriteSurface.w, spriteSurface.h);
 	t.moveTo(drawRect.left, drawRect.top);
@@ -1052,7 +1052,7 @@ void Frame::inkBasedBlit(Graphics::ManagedSurface &targetSurface, const Graphics
 		drawGhostSprite(targetSurface, spriteSurface, drawRect);
 		break;
 	case kInkTypeReverse:
-		drawReverseSprite(targetSurface, spriteSurface, drawRect);
+		drawReverseSprite(targetSurface, spriteSurface, drawRect, spriteId);
 		break;
 	default:
 		warning("Frame::inkBasedBlit(): Unhandled ink type %d", ink);
@@ -1103,7 +1103,7 @@ void Frame::drawGhostSprite(Graphics::ManagedSurface &target, const Graphics::Su
 	}
 }
 
-void Frame::drawReverseSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect) {
+void Frame::drawReverseSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect, uint16 spriteId) {
 	Common::Rect srcRect(sprite.w, sprite.h);
 
 	if (!target.clip(srcRect, drawRect))
@@ -1113,14 +1113,37 @@ void Frame::drawReverseSprite(Graphics::ManagedSurface &target, const Graphics::
 	for (int ii = 0; ii < srcRect.height(); ii++) {
 		const byte *src = (const byte *)sprite.getBasePtr(srcRect.left, srcRect.top + ii);
 		byte *dst = (byte *)target.getBasePtr(drawRect.left, drawRect.top + ii);
+		byte srcColor = *src;
 
 		for (int j = 0; j < srcRect.width(); j++) {
-			if ((getSpriteIDFromPos(Common::Point(drawRect.left + j, drawRect.top + ii)) != 0)) {
-				if (*src != skipColor) {
-					*dst ^= _vm->transformColor(*src);
+			if (_sprites[spriteId]->_cast->_type == kCastShape)
+				srcColor = 0x0;
+			else
+				srcColor = *src;
+			uint16 targetSprite = getSpriteIDFromPos(Common::Point(drawRect.left + j, drawRect.top + ii));
+			if ((targetSprite != 0)) {
+				// TODO: This entire reverse colour attempt needs a lot more testing on
+				// a lot more colour depths.
+				if (srcColor != skipColor) {
+					if (_sprites[targetSprite]->_cast->_type != kCastBitmap) {
+						if (*dst == 0 || *dst == 255) {
+							*dst = _vm->transformColor(*dst);
+						} else if (srcColor == 255 || srcColor == 0) {
+							*dst = _vm->transformColor(*dst - 40);
+						} else {
+							*dst = _vm->transformColor(*src - 40);
+						}
+					} else {
+						if (*dst == 0 && _vm->getVersion() == 3 &&
+							((BitmapCast*)_sprites[spriteId]->_cast)->_bitsPerPixel > 1) {
+							*dst = _vm->transformColor(*src - 40);
+						} else {
+							*dst ^= _vm->transformColor(srcColor);
+						}
+					}
 				}
-			} else if (*src != skipColor) {
-				*dst = *src;
+			} else if (srcColor != skipColor) {
+				*dst = _vm->transformColor(srcColor);
 			}
 			src++;
 			dst++;
diff --git a/engines/director/frame.h b/engines/director/frame.h
index fb9cdd253d..1205daef5d 100644
--- a/engines/director/frame.h
+++ b/engines/director/frame.h
@@ -94,8 +94,8 @@ private:
 	void drawBackgndTransSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect);
 	void drawMatteSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect);
 	void drawGhostSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect);
-	void drawReverseSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect);
-	void inkBasedBlit(Graphics::ManagedSurface &targetSurface, const Graphics::Surface &spriteSurface, InkType ink, Common::Rect drawRect);
+	void drawReverseSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect, uint16 spriteId);
+	void inkBasedBlit(Graphics::ManagedSurface &targetSurface, const Graphics::Surface &spriteSurface, InkType ink, Common::Rect drawRect, uint spriteId);
 	void addDrawRect(uint16 entityId, Common::Rect &rect);
 
 public:
diff --git a/engines/director/images.cpp b/engines/director/images.cpp
index 7e65d3aa2c..129f393790 100644
--- a/engines/director/images.cpp
+++ b/engines/director/images.cpp
@@ -103,7 +103,7 @@ bool DIBDecoder::loadStream(Common::SeekableReadStream &stream) {
 * BITD
 ****************************/
 
-BITDDecoder::BITDDecoder(int w, int h, uint16 bitsPerPixel, uint16 pitch) {
+BITDDecoder::BITDDecoder(int w, int h, uint16 bitsPerPixel, uint16 pitch, const byte *palette) {
 	_surface = new Graphics::Surface();
 
 	if (pitch < w) {
@@ -133,12 +133,10 @@ BITDDecoder::BITDDecoder(int w, int h, uint16 bitsPerPixel, uint16 pitch) {
 	_surface->create(pitch, h, pf);
 	_surface->w = w;
 
-	_palette = new byte[256 * 3];
+	_palette = palette;
 
-	_palette[0] = _palette[1] = _palette[2] = 0;
-	_palette[255 * 3 + 0] = _palette[255 * 3 + 1] = _palette[255 * 3 + 2] = 0xff;
-
-	_paletteColorCount = 2;
+	// TODO: Bring this in from the main surface?
+	_paletteColorCount = 255;
 
 	_bitsPerPixel = bitsPerPixel;
 }
@@ -152,8 +150,6 @@ void BITDDecoder::destroy() {
 	delete _surface;
 	_surface = 0;
 
-	delete[] _palette;
-	_palette = 0;
 	_paletteColorCount = 0;
 }
 
@@ -161,6 +157,42 @@ void BITDDecoder::loadPalette(Common::SeekableReadStream &stream) {
 	// no op
 }
 
+void BITDDecoder::convertPixelIntoSurface(void* surfacePointer, uint fromBpp, uint toBpp, int red, int green, int blue) {
+	// Initial implementation of 32-bit images to palettised sprites.
+	switch (fromBpp) {
+	case 4:
+		switch (toBpp) {
+		case 1:
+			if (red == 255 && blue == 255 && green == 255) {
+				*((byte*)surfacePointer) = 255;
+			} else if (red == 0 && blue == 0 && green == 0) {
+				*((byte*)surfacePointer) = 0;
+			} else {
+				for (byte p = 0; p < _paletteColorCount; p++)
+				{
+					if (_palette[p * 3 + 0] == red &&
+						_palette[p * 3 + 1] == green &&
+						_palette[p * 3 + 2] == blue)
+					{
+						*((byte*)surfacePointer) = p;
+					}
+				}
+			}
+			break;
+
+		default:
+			warning("BITDDecoder::convertPixelIntoSurface(): conversion from %d to %d not implemented",
+				fromBpp, toBpp);
+		}
+		break;
+
+	default:
+		warning("BITDDecoder::convertPixelIntoSurface(): could not convert from %d to %d",
+			fromBpp, toBpp);
+		break;
+	}
+}
+
 bool BITDDecoder::loadStream(Common::SeekableReadStream &stream) {
 	int x = 0, y = 0;
 
@@ -180,26 +212,30 @@ bool BITDDecoder::loadStream(Common::SeekableReadStream &stream) {
 	}
 
 	Common::Array<int> pixels;
-
 	while (!stream.eos()) {
-		int data = stream.readByte();
-		int len = data + 1;
-		if ((data & 0x80) != 0) {
-			len = ((data ^ 0xFF) & 0xff) + 2;
-			data = stream.readByte();
-			for (int p = 0; p < len; p++) {
-				pixels.push_back(data);
-				//*((byte *)_surface->getBasePtr(x, y)) = data;
-			}
-			//data = stream.readByte();
+		// TODO: D3 32-bit bitmap casts seem to just be ARGB pixels in a row and not RLE.
+		// Determine how to distinguish these different types. Maybe stage version.
+		if (_bitsPerPixel == 32) {
+			int data = stream.readByte();
+			pixels.push_back(data);
 		} else {
-			for (int p = 0; p < len; p++) {
+			int data = stream.readByte();
+			int len = data + 1;
+			if ((data & 0x80) != 0) {
+				len = ((data ^ 0xFF) & 0xff) + 2;
 				data = stream.readByte();
-				pixels.push_back(data);
+				for (int p = 0; p < len; p++) {
+					pixels.push_back(data);
+				}
+			} else {
+				for (int p = 0; p < len; p++) {
+					data = stream.readByte();
+					pixels.push_back(data);
+				}
 			}
+			if (_bitsPerPixel == 32 && pixels.size() % (_surface->w * 3) == 0)
+				stream.readUint16BE();
 		}
-		if (_bitsPerPixel == 32 && pixels.size() % (_surface->w * 3) == 0)
-			stream.readUint16BE();
 	}
 
 	if (pixels.size() < (uint32)_surface->w * _surface->h) {
@@ -220,12 +256,11 @@ bool BITDDecoder::loadStream(Common::SeekableReadStream &stream) {
 		for (y = 0; y < _surface->h; y++) {
 			for (x = 0; x < _surface->w;) {
 				switch (_bitsPerPixel) {
-				case 1: {
+				case 1:
 					for (int c = 0; c < 8 && x < _surface->w; c++, x++) {
 						*((byte *)_surface->getBasePtr(x, y)) = (pixels[(((y * _surface->pitch) + x) / 8)] & (1 << (7 - c))) ? 0 : 0xff;
 					}
 					break;
-				}
 
 				case 8:
 					// this calculation is wrong.. need a demo with colours.
@@ -243,10 +278,12 @@ bool BITDDecoder::loadStream(Common::SeekableReadStream &stream) {
 					break;
 
 				case 32:
-					*((uint32*)_surface->getBasePtr(x, y)) = _surface->format.RGBToColor(
-						pixels[((y * _surface->w) * 3) + x],
-						pixels[(((y * _surface->w) * 3) + (_surface->w)) + x],
-						pixels[(((y * _surface->w) * 3) + (2 * _surface->w)) + x]);
+					convertPixelIntoSurface(_surface->getBasePtr(x, y),
+						(_bitsPerPixel / 8),
+						_surface->format.bytesPerPixel,
+						pixels[(((y * (_surface->w * 4))) + ((x * 4) + 1))],
+						pixels[(((y * (_surface->w * 4))) + ((x * 4) + 2))],
+						pixels[(((y * (_surface->w * 4))) + ((x * 4) + 3))]);
 					x++;
 					break;
 
diff --git a/engines/director/images.h b/engines/director/images.h
index c87796f6a0..8a6c5e7f7a 100644
--- a/engines/director/images.h
+++ b/engines/director/images.h
@@ -61,7 +61,7 @@ private:
 
 class BITDDecoder : public Image::ImageDecoder {
 public:
-	BITDDecoder(int w, int h, uint16 bitsPerPixel, uint16 pitch);
+	BITDDecoder(int w, int h, uint16 bitsPerPixel, uint16 pitch, const byte *palette);
 	~BITDDecoder() override;
 
 	// ImageDecoder API
@@ -71,10 +71,11 @@ public:
 	const byte *getPalette() const override { return _palette; }
 	void loadPalette(Common::SeekableReadStream &stream);
 	uint16 getPaletteColorCount() const override { return _paletteColorCount; }
+	void convertPixelIntoSurface(void* surfacePointer, uint fromBpp, uint toBpp, int red, int green, int blue);
 
 private:
 	Graphics::Surface *_surface;
-	byte *_palette;
+	const byte *_palette;
 	uint8 _paletteColorCount;
 	uint16 _bitsPerPixel;
 };
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index a0df293bb5..09ff870567 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -376,7 +376,7 @@ void Score::loadSpriteImages(bool isSharedCast) {
 
 			if (w > 0 && h > 0) {
 				if (_vm->getVersion() < 6) {
-					img = new BITDDecoder(w, h, bitmapCast->_bitsPerPixel, bitmapCast->_pitch);
+					img = new BITDDecoder(w, h, bitmapCast->_bitsPerPixel, bitmapCast->_pitch, _vm->getPalette());
 				} else {
 					img = new Image::BitmapDecoder();
 				}




More information about the Scummvm-git-logs mailing list