[Scummvm-git-logs] scummvm master -> 9a4aeffc25d96c56d7abf61c9d491e14fcb91c40

npjg nathanael.gentrydb8 at gmail.com
Thu Jul 9 19:54:38 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:
9a4aeffc25 DIRECTOR: Refactoring for implementing stretch of sprite


Commit: 9a4aeffc25d96c56d7abf61c9d491e14fcb91c40
    https://github.com/scummvm/scummvm/commit/9a4aeffc25d96c56d7abf61c9d491e14fcb91c40
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-07-09T15:53:59-04:00

Commit Message:
DIRECTOR: Refactoring for implementing stretch of sprite

Changed paths:
    engines/director/channel.cpp
    engines/director/director.h
    engines/director/graphics.cpp
    engines/director/stage.cpp
    engines/director/stage.h


diff --git a/engines/director/channel.cpp b/engines/director/channel.cpp
index 8a61a9b525..9bfbb4b586 100644
--- a/engines/director/channel.cpp
+++ b/engines/director/channel.cpp
@@ -44,17 +44,17 @@ Channel::Channel(Sprite *sp) {
 }
 
 DirectorPlotData Channel::getPlotData() {
-	DirectorPlotData pd(g_director->_wm, _sprite->_ink, getBackColor(), getForeColor(), g_director->getPaletteColorCount());
-
-	void *src = getSurface();
-	if (src) {
-		pd.isShape = false;
-		pd.src = src;
+	DirectorPlotData pd(g_director->_wm, _sprite->_spriteType, _sprite->_ink, getBackColor(), getForeColor());
+	pd.colorWhite = pd._wm->_colorWhite;
+	pd.colorBlack = pd._wm->_colorBlack;
+
+	pd.srf = getSurface();
+	if (!pd.srf) {
+		// Shapes come colourized from macDrawPixel
+		pd.ms = getShape();
+		pd.applyColor = false;
 	} else {
-		pd.src = getShape();
-
-		if (pd.src)
-			pd.isShape = true;
+		pd.setApplyColor();
 	}
 
 	return pd;
diff --git a/engines/director/director.h b/engines/director/director.h
index f3c1c278d6..11e561208f 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -114,31 +114,31 @@ struct MacShape {
 struct DirectorPlotData {
 	Graphics::MacWindowManager *_wm;
 	Graphics::ManagedSurface *dst;
+
 	Common::Rect destRect;
 	Common::Point srcPoint;
 
-	bool isShape;
-	void *src;
+	Graphics::ManagedSurface *srf;
+	MacShape *ms;
 
-	bool applyColor;
-	bool manualInk;
+	SpriteType sprite;
 	InkType ink;
-	int numColors;
-	uint backColor;
-	uint foreColor;
+	int colorWhite;
+	int colorBlack;
 
-	bool setNeedsColor(); // graphics.cpp
+	int backColor;
+	int foreColor;
+	bool applyColor;
 
-	DirectorPlotData(Graphics::MacWindowManager *w, InkType i, uint b, uint f, uint n) : _wm(w), ink(i), backColor(b), foreColor(f), numColors(n) {
-		isShape = false;
-		manualInk = false;
+	void setApplyColor(); // graphics.cpp
 
-		applyColor = setNeedsColor();
+	DirectorPlotData(Graphics::MacWindowManager *w, SpriteType s,InkType i, uint b, uint f) : _wm(w), sprite(s), ink(i), backColor(b), foreColor(f) {
+		srf = nullptr;
+		ms = nullptr;
 	}
 
 	~DirectorPlotData() {
-		if (isShape)
-			delete (MacShape *)src;
+		delete ms;
 	}
 };
 
diff --git a/engines/director/graphics.cpp b/engines/director/graphics.cpp
index 9fd3a51475..8291ef94b8 100644
--- a/engines/director/graphics.cpp
+++ b/engines/director/graphics.cpp
@@ -793,60 +793,25 @@ void DirectorEngine::setCursor(int type) {
 	}
 }
 
-void inkDrawPixel(int x, int y, int color, void *data) {
+void inkDrawPixel(int x, int y, int src, void *data) {
 	DirectorPlotData *p = (DirectorPlotData *)data;
 
 	if (!p->destRect.contains(x, y))
 		return;
 
 	byte *dst;
-	byte src;
-
 	byte tmpDst;
 
 	dst = (byte *)p->dst->getBasePtr(x, y);
 
-	if (p->isShape) {
+	if (p->ms) {
 		// Get the pixel that macDrawPixel will give us, but store it to apply the
 		// ink later.
 		tmpDst = *dst;
-		Graphics::macDrawPixel(x, y, color, ((MacShape *)p->src)->pd);
+		Graphics::macDrawPixel(x, y, src, p->ms->pd);
 		src = *dst;
 
 		*dst = tmpDst;
-	} else if (!p->src) {
-			error("Director::inkDrawPixel(): No source surface");
-			return;
-	} else {
-		src = *((const byte *)((Graphics::ManagedSurface *)p->src)->getBasePtr(p->srcPoint.x, p->srcPoint.y));
-
-		if (p->manualInk) {
-			switch(p->ink) {
-			case kInkTypeMask:
-				src = (src == p->backColor ? 0xff : p->foreColor);
-				break;
-			case kInkTypeReverse:
-				src = (src == p->foreColor ? 0 : p->numColors - 1);
-				break;
-			case kInkTypeNotReverse:
-				src = (src == p->backColor ? p->numColors - 1 : 0);
-				break;
-			case kInkTypeGhost:
-				src = (src == p->foreColor ? p->backColor : p->numColors - 1);
-				break;
-			case kInkTypeNotGhost:
-				src = (src == p->backColor ? p->numColors - 1 : p->backColor);
-				break;
-			case kInkTypeNotCopy:
-				src = (src == p->foreColor ? p->backColor : p->foreColor);
-				break;
-			case kInkTypeNotTrans:
-				src = (src == p->foreColor ? p->backColor : p->numColors - 1);
-				break;
-			default:
-				break;
-			}
-		}
 	}
 
  	switch (p->ink) {
@@ -918,7 +883,7 @@ void inkDrawPixel(int x, int y, int color, void *data) {
 		break;
 		// Arithmetic ink types
 	default: {
-		if (src != p->numColors - 1) {
+		if (src != p->colorWhite) {
 			byte rSrc, gSrc, bSrc;
 			byte rDst, gDst, bDst;
 
@@ -930,10 +895,10 @@ void inkDrawPixel(int x, int y, int color, void *data) {
 					*dst = p->_wm->findBestColor((rSrc + rDst) / 2, (gSrc + gDst) / 2, (bSrc + bDst) / 2);
 				break;
 			case kInkTypeAddPin:
-					*dst = p->_wm->findBestColor(MIN((rSrc + rDst), p->numColors - 1), MIN((gSrc + gDst), p->numColors - 1), MIN((bSrc + bDst), p->numColors - 1));
+					*dst = p->_wm->findBestColor(MIN((rSrc + rDst), p->colorWhite), MIN((gSrc + gDst), p->colorWhite), MIN((bSrc + bDst), p->colorWhite));
 				break;
 			case kInkTypeAdd:
-					*dst = p->_wm->findBestColor(abs(rSrc + rDst) % p->numColors, abs(gSrc + gDst) % p->numColors, abs(bSrc + bDst) % p->numColors);
+					*dst = p->_wm->findBestColor(abs(rSrc + rDst) % p->colorWhite + 1, abs(gSrc + gDst) % p->colorWhite + 1, abs(bSrc + bDst) % p->colorWhite + 1);
 				break;
 			case kInkTypeSubPin:
 					*dst = p->_wm->findBestColor(MAX(rSrc - rDst, 0), MAX(gSrc - gDst, 0), MAX(bSrc - bDst, 0));
@@ -942,7 +907,7 @@ void inkDrawPixel(int x, int y, int color, void *data) {
 					*dst = p->_wm->findBestColor(MAX(rSrc, rDst), MAX(gSrc, gDst), MAX(bSrc, bDst));
 				break;
 			case kInkTypeSub:
-					*dst = p->_wm->findBestColor(abs(rSrc - rDst) % p->numColors, abs(gSrc - gDst) % p->numColors, abs(bSrc - bDst) % p->numColors);
+					*dst = p->_wm->findBestColor(abs(rSrc - rDst) % p->colorWhite + 1, abs(gSrc - gDst) % p->colorWhite + 1, abs(bSrc - bDst) % p->colorWhite + 1);
 				break;
 			case kInkTypeDark:
 					*dst = p->_wm->findBestColor(MIN(rSrc, rDst), MIN(gSrc, gDst), MIN(bSrc, bDst));
@@ -955,16 +920,11 @@ void inkDrawPixel(int x, int y, int color, void *data) {
 	}
 }
 
-bool DirectorPlotData::setNeedsColor() {
-	if (isShape)
-		return false;
-
-	// TODO: Is colour white always last entry in palette?
-	uint colorBlack = 0;
-	uint colorWhite = g_director->getPaletteColorCount() - 1;
+void DirectorPlotData::setApplyColor() {
+	applyColor = false;
 
 	if (foreColor == colorBlack && backColor == colorWhite)
-		return false;
+		applyColor = false;
 
 	switch (ink) {
 	case kInkTypeReverse:
@@ -976,23 +936,21 @@ bool DirectorPlotData::setNeedsColor() {
 	case kInkTypeSub:
 	case kInkTypeDark:
 	case kInkTypeBackgndTrans:
-		return false;
+		applyColor = false;
 	default:
 		break;
 	}
 
 	if (foreColor != colorBlack) {
 		if (ink != kInkTypeGhost && ink != kInkTypeNotGhost)
-			return true;
+			applyColor = true;
 	}
 
 	if (backColor != colorWhite) {
 		if (ink != kInkTypeTransparent &&
 				ink != kInkTypeNotTrans)
-			return true;
+			applyColor = true;
 	}
-
-	return false;
 }
 
 
diff --git a/engines/director/stage.cpp b/engines/director/stage.cpp
index 7636519e5d..e058309cd1 100644
--- a/engines/director/stage.cpp
+++ b/engines/director/stage.cpp
@@ -157,17 +157,9 @@ void Stage::inkBlitFrom(Channel *channel, Common::Rect destRect, Graphics::Manag
 	pd.destRect = destRect;
 	pd.dst = blitTo;
 
-	if (pd.isShape) {
+	if (pd.ms) {
 		inkBlitShape(&pd, srcRect);
-	} else if (pd.src) {
-		if (channel->_sprite->_spriteType == kTextSprite) {
-			// Copy colourization is already applied to text by default
-			if (pd.ink != kInkTypeCopy)
-				pd.manualInk = true;
-			else
-				pd.applyColor = false;
-		}
-
+	} else if (pd.srf) {
 		inkBlitSurface(&pd, srcRect, channel->getMask());
 	} else {
 		warning("Stage::inkBlitFrom: No source surface");
@@ -175,19 +167,18 @@ void Stage::inkBlitFrom(Channel *channel, Common::Rect destRect, Graphics::Manag
 }
 
 void Stage::inkBlitShape(DirectorPlotData *pd, Common::Rect &srcRect) {
-	MacShape *ms = ((MacShape *)pd->src);
-
-	if (!ms)
+	if (!pd->ms)
 		return;
 
+	// Preprocess shape colours
 	switch (pd->ink) {
 	case kInkTypeNotTrans:
 	case kInkTypeNotReverse:
 	case kInkTypeNotGhost:
 		return;
 	case kInkTypeReverse:
-		ms->foreColor = 0;
-		ms->backColor = 0;
+		pd->ms->foreColor = 0;
+		pd->ms->backColor = 0;
 		break;
 	default:
 		break;
@@ -195,60 +186,104 @@ void Stage::inkBlitShape(DirectorPlotData *pd, Common::Rect &srcRect) {
 
 	Common::Rect fillRect((int)srcRect.width(), (int)srcRect.height());
 	fillRect.moveTo(srcRect.left, srcRect.top);
-	Graphics::MacPlotData plotFill(pd->dst, nullptr, &g_director->getPatterns(), ms->pattern, srcRect.left, srcRect.top, 1, ms->backColor);
+	Graphics::MacPlotData plotFill(pd->dst, nullptr, &g_director->getPatterns(), pd->ms->pattern, srcRect.left, srcRect.top, 1, pd->ms->backColor);
 
-	Common::Rect strokeRect(MAX((int)srcRect.width() - ms->lineSize, 0), MAX((int)srcRect.height() - ms->lineSize, 0));
+	Common::Rect strokeRect(MAX((int)srcRect.width() - pd->ms->lineSize, 0), MAX((int)srcRect.height() - pd->ms->lineSize, 0));
 	strokeRect.moveTo(srcRect.left, srcRect.top);
-	Graphics::MacPlotData plotStroke(pd->dst, nullptr, &g_director->getPatterns(), 1, strokeRect.left, strokeRect.top, ms->lineSize, ms->backColor);
+	Graphics::MacPlotData plotStroke(pd->dst, nullptr, &g_director->getPatterns(), 1, strokeRect.left, strokeRect.top, pd->ms->lineSize, pd->ms->backColor);
 
-	switch (ms->spriteType) {
+	switch (pd->ms->spriteType) {
 	case kRectangleSprite:
-		ms->pd = &plotFill;
-		Graphics::drawFilledRect(fillRect, ms->foreColor, inkDrawPixel, pd);
+		pd->ms->pd = &plotFill;
+		Graphics::drawFilledRect(fillRect, pd->ms->foreColor, inkDrawPixel, pd);
 		// fall through
 	case kOutlinedRectangleSprite:
-		ms->pd = &plotStroke;
-		Graphics::drawRect(strokeRect, ms->foreColor, inkDrawPixel, pd);
+		pd->ms->pd = &plotStroke;
+		Graphics::drawRect(strokeRect, pd->ms->foreColor, inkDrawPixel, pd);
 		break;
 	case kRoundedRectangleSprite:
-		ms->pd = &plotFill;
-		Graphics::drawRoundRect(fillRect, 12, ms->foreColor, true, inkDrawPixel, pd);
+		pd->ms->pd = &plotFill;
+		Graphics::drawRoundRect(fillRect, 12, pd->ms->foreColor, true, inkDrawPixel, pd);
 		// fall through
 	case kOutlinedRoundedRectangleSprite:
-		ms->pd = &plotStroke;
-		Graphics::drawRoundRect(strokeRect, 12, ms->foreColor, false, inkDrawPixel, pd);
+		pd->ms->pd = &plotStroke;
+		Graphics::drawRoundRect(strokeRect, 12, pd->ms->foreColor, false, inkDrawPixel, pd);
 		break;
 	case kOvalSprite:
-		ms->pd = &plotFill;
-		Graphics::drawEllipse(fillRect.left, fillRect.top, fillRect.right, fillRect.bottom, ms->foreColor, true, inkDrawPixel, pd);
+		pd->ms->pd = &plotFill;
+		Graphics::drawEllipse(fillRect.left, fillRect.top, fillRect.right, fillRect.bottom, pd->ms->foreColor, true, inkDrawPixel, pd);
 		// fall through
 	case kOutlinedOvalSprite:
-		ms->pd = &plotStroke;
-		Graphics::drawEllipse(strokeRect.left, strokeRect.top, strokeRect.right, strokeRect.bottom, ms->foreColor, false, inkDrawPixel, pd);
+		pd->ms->pd = &plotStroke;
+		Graphics::drawEllipse(strokeRect.left, strokeRect.top, strokeRect.right, strokeRect.bottom, pd->ms->foreColor, false, inkDrawPixel, pd);
 		break;
 	case kLineTopBottomSprite:
-		ms->pd = &plotStroke;
-		Graphics::drawLine(strokeRect.left, strokeRect.top, strokeRect.right, strokeRect.bottom, ms->foreColor, inkDrawPixel, pd);
+		pd->ms->pd = &plotStroke;
+		Graphics::drawLine(strokeRect.left, strokeRect.top, strokeRect.right, strokeRect.bottom, pd->ms->foreColor, inkDrawPixel, pd);
 		break;
 	case kLineBottomTopSprite:
-		ms->pd = &plotStroke;
-		Graphics::drawLine(strokeRect.left, strokeRect.top, strokeRect.right, strokeRect.bottom, ms->foreColor, inkDrawPixel, pd);
+		pd->ms->pd = &plotStroke;
+		Graphics::drawLine(strokeRect.left, strokeRect.top, strokeRect.right, strokeRect.bottom, pd->ms->foreColor, inkDrawPixel, pd);
 		break;
 	default:
-		warning("Stage::inkBlitFrom: Expected shape type but got type %d", ms->spriteType);
+		warning("Stage::inkBlitFrom: Expected shape type but got type %d", pd->ms->spriteType);
 	}
 }
 
 void Stage::inkBlitSurface(DirectorPlotData *pd, Common::Rect &srcRect, const Graphics::Surface *mask) {
+	if (!pd->srf)
+		return;
+
+	// TODO: Determine why colourization causes problems in Warlock
+	if (pd->sprite == kTextSprite)
+		pd->applyColor = false;
+
 	pd->srcPoint.y = MAX(abs(srcRect.top - pd->destRect.top), 0);
 	for (int i = 0; i < pd->destRect.height(); i++, pd->srcPoint.y++) {
 		pd->srcPoint.x = MAX(abs(srcRect.left - pd->destRect.left), 0);
 		const byte *msk = mask ? (const byte *)mask->getBasePtr(pd->srcPoint.x, pd->srcPoint.y) : nullptr;
 
 		for (int j = 0; j < pd->destRect.width(); j++, pd->srcPoint.x++)
-			if (!mask || (msk && (pd->ink == kInkTypeMask ? *msk++ : !(*msk++))))
-				inkDrawPixel(pd->destRect.left + j, pd->destRect.top + i, 0, pd);
+			if (!mask || (msk && (pd->ink == kInkTypeMask ? *msk++ : !(*msk++)))) {
+				inkDrawPixel(pd->destRect.left + j, pd->destRect.top + i,
+										 preprocessColor(pd, *((byte *)pd->srf->getBasePtr(pd->srcPoint.x, pd->srcPoint.y))), pd);
+			}
+	}
+}
+
+int Stage::preprocessColor(DirectorPlotData *p, int src) {
+	// HACK: Right now this method is just used for adjusting the colourization on text
+	// sprites, as it would be costly to colourize the chunks on the fly each
+	// time a section needs drawing. It's ugly but mostly works.
+	if (p->sprite == kTextSprite) {
+		switch(p->ink) {
+		case kInkTypeMask:
+			src = (src == p->backColor ? 0xff : p->foreColor);
+			break;
+		case kInkTypeReverse:
+			src = (src == p->foreColor ? 0 : p->colorWhite);
+			break;
+		case kInkTypeNotReverse:
+			src = (src == p->backColor ? p->colorWhite : 0);
+			break;
+		case kInkTypeGhost:
+			src = (src == p->foreColor ? p->backColor : p->colorWhite);
+			break;
+		case kInkTypeNotGhost:
+			src = (src == p->backColor ? p->colorWhite : p->backColor);
+			break;
+		case kInkTypeNotCopy:
+			src = (src == p->foreColor ? p->backColor : p->foreColor);
+			break;
+		case kInkTypeNotTrans:
+			src = (src == p->foreColor ? p->backColor : p->colorWhite);
+			break;
+		default:
+			break;
+		}
 	}
+
+	return src;
 }
 
 Common::Point Stage::getMousePos() {
diff --git a/engines/director/stage.h b/engines/director/stage.h
index 77fe716959..c2aa8d5361 100644
--- a/engines/director/stage.h
+++ b/engines/director/stage.h
@@ -163,6 +163,8 @@ private:
 	Common::StringArray _movieQueue;
 
 private:
+	int preprocessColor(DirectorPlotData *p, int src);
+
 	void inkBlitFrom(Channel *channel, Common::Rect destRect, Graphics::ManagedSurface *blitTo = nullptr);
 	void inkBlitShape(DirectorPlotData *pd, Common::Rect &srcRect);
 	void inkBlitSurface(DirectorPlotData *pd, Common::Rect &srcRect, const Graphics::Surface *mask);




More information about the Scummvm-git-logs mailing list