[Scummvm-git-logs] scummvm master -> 5bc8d36cb2fb9245ec89da33e727ae1049ba2442

dreammaster dreammaster at scummvm.org
Tue Feb 23 03:24:33 UTC 2021


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:
5bc8d36cb2 AGS: Draw method specific for AGS


Commit: 5bc8d36cb2fb9245ec89da33e727ae1049ba2442
    https://github.com/scummvm/scummvm/commit/5bc8d36cb2fb9245ec89da33e727ae1049ba2442
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-02-22T19:19:34-08:00

Commit Message:
AGS: Draw method specific for AGS

Changed paths:
    engines/ags/lib/allegro/gfx.cpp
    engines/ags/lib/allegro/surface.cpp
    engines/ags/lib/allegro/surface.h


diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp
index 58a20993b1..80b91cbe0f 100644
--- a/engines/ags/lib/allegro/gfx.cpp
+++ b/engines/ags/lib/allegro/gfx.cpp
@@ -36,9 +36,6 @@ int color_conversion;
 #define TRANSPARENT_COLOR(BITMAP) ((BITMAP).format.bytesPerPixel == 1 ? 0 : \
 	(BITMAP).format.RGBToColor(255, 0, 255))
 
-// Arbitrary RGBA tuplet that should never be encountered
-#define NO_TRANSPARENT_COLOR 0x88888888
-
 /*-------------------------------------------------------------------*/
 
 void set_color_conversion(int mode) {
@@ -104,224 +101,80 @@ int bitmap_mask_color(BITMAP *bmp) {
 	return TRANSPARENT_COLOR(*bmp);
 }
 
-void add_palette_if_needed(Graphics::ManagedSurface &surf) {
-	if (surf.format.bytesPerPixel == 1) {
-		byte pal[PALETTE_SIZE];
-		palette_to_rgb8(_current_palette, pal);
-
-		// Set transparent color for index 0
-		pal[0] = 0xff;
-		pal[1] = 0;
-		pal[2] = 0xff;
-
-		surf.setPalette(pal, 0, PALETTE_COUNT);
-	}
-}
-
-void stripAlpha(Graphics::ManagedSurface &src, Graphics::ManagedSurface &dest) {
-	dest.format = src.format;
-	dest.format.aLoss = 8;
-	dest.format.aShift = 0;
-	dest.w = src.w;
-	dest.h = src.h;
-	dest.pitch = src.pitch;
-	dest.setPixels(src.getPixels());
-
-	if (src.hasTransparentColor()) {
-		byte r, g, b;
-		src.format.colorToRGB(src.getTransparentColor(), r, g, b);
-		dest.setTransparentColor(dest.format.RGBToColor(r, g, b));
-	}
-}
-
 void blit(const BITMAP *src, BITMAP *dest, int src_x, int src_y, int dst_x, int dst_y, int width, int height) {
-	Graphics::ManagedSurface &srcS = **src;
-	Graphics::ManagedSurface &destS = **dest;
-
-	add_palette_if_needed(srcS);
-
-	if (srcS.format.aBits() == 0) {
-		destS.rawBlitFrom(srcS, Common::Rect(src_x, src_y, src_x + width, src_y + height),
-			Common::Point(dst_x, dst_y), srcS.getPalette());
-	} else {
-		Graphics::ManagedSurface temp;
-		stripAlpha(srcS, temp);
-
-		destS.rawBlitFrom(temp, Common::Rect(src_x, src_y, src_x + width, src_y + height),
-			Common::Point(dst_x, dst_y), nullptr);
-	}
+	dest->draw(src, Common::Rect(src_x, src_y, src_x + width, src_y + height),
+		Common::Rect(dst_x, dst_y, dst_x + width, dst_y + height),
+		false, false, false, -1);
 }
 
-void stretch_blit(const BITMAP *src, BITMAP *dest, int source_x, int source_y, int source_width, int source_height,
+void stretch_blit(const BITMAP *src, BITMAP *dest,
+		int source_x, int source_y, int source_width, int source_height,
 		int dest_x, int dest_y, int dest_width, int dest_height) {
-	Graphics::ManagedSurface &srcS = **src;
-	Graphics::ManagedSurface &destS = **dest;
-
-	add_palette_if_needed(srcS);
-
-	destS.transBlitFrom(srcS, Common::Rect(source_x, source_y, source_x + source_width, source_y + source_height),
-		Common::Rect(dest_x, dest_y, dest_x + dest_width, dest_y + dest_height));
+	dest->draw(src,
+		Common::Rect(source_x, source_y, source_x + source_width, source_y + source_height),
+		Common::Rect(dest_x, dest_y, dest_x + dest_width, dest_y + dest_height),
+		false, false, false, -1);
 }
 
 void masked_blit(const BITMAP *src, BITMAP *dest, int src_x, int src_y, int dst_x, int dst_y, int width, int height) {
-	Graphics::ManagedSurface &srcS = **src;
-	Graphics::ManagedSurface &destS = **dest;
-
-	add_palette_if_needed(srcS);
+	assert(src->format == dest->format);
 
-	destS.blitFrom(srcS, Common::Rect(src_x, src_y, src_x + width, src_y + height), Common::Point(dst_x, dst_y));
+	dest->draw(src, Common::Rect(src_x, src_y, src_x + width, src_y + height),
+		Common::Rect(dst_x, dst_y, dst_x + width, dst_y + height),
+		false, false, true, -1);
 }
 
-void masked_stretch_blit(const BITMAP *src, BITMAP *dest, int source_x, int source_y, int source_width, int source_height,
-	int dest_x, int dest_y, int dest_width, int dest_height) {
-	Graphics::ManagedSurface &srcS = **src;
-	Graphics::ManagedSurface &destS = **dest;
-
-	add_palette_if_needed(srcS);
-
-	destS.transBlitFrom(srcS, Common::Rect(source_x, source_y, source_x + source_width, source_y + source_height),
-		Common::Rect(dest_x, dest_y, dest_x + dest_width, dest_y + dest_height));
+void masked_stretch_blit(const BITMAP *src, BITMAP *dest,
+		int source_x, int source_y, int source_width, int source_height,
+		int dest_x, int dest_y, int dest_width, int dest_height) {
+	dest->draw(src,
+		Common::Rect(source_x, source_y, source_x + source_width, source_y + source_height),
+		Common::Rect(dest_x, dest_y, dest_x + dest_width, dest_y + dest_height),
+		false, false, true, -1);
 }
 
 void draw_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y) {
-	Graphics::ManagedSurface &bmpS = **bmp;
-	Graphics::ManagedSurface &spriteS = **sprite;
-
-	add_palette_if_needed(spriteS);
-
-	if (spriteS.format.aBits() == 0) {
-		bmpS.transBlitFrom(spriteS, Common::Point(x, y), TRANSPARENT_COLOR(spriteS));
-	} else {
-		// Create a temporary ManagedSurface with a pointer to the sprite's pixels,
-		// and a pixel format that matches the sprite, but has no alpha.
-		// This will prevent it being applied from the sprite in transBlitFrom
-		assert(spriteS.format.bytesPerPixel == 4);
-		Graphics::ManagedSurface temp;
-		stripAlpha(spriteS, temp);
-
-		bmpS.transBlitFrom(temp, Common::Point(x, y), TRANSPARENT_COLOR(spriteS));
-	}
+	bmp->draw(sprite, Common::Rect(0, 0, sprite->w, sprite->h),
+		Common::Rect(x, y, x + sprite->w, y + sprite->h),
+		false, false, true, -1);
 }
 
 void stretch_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int w, int h) {
-	Graphics::ManagedSurface &bmpS = **bmp;
-	Graphics::ManagedSurface &spriteS = **sprite;
-
-	add_palette_if_needed(spriteS);
-
-	if (spriteS.format.aBits() == 0) {
-		bmpS.transBlitFrom(spriteS, Common::Rect(0, 0, sprite->w, sprite->h),
-			Common::Rect(x, y, x + w, y + h));
-	} else {
-		// Create a temporary ManagedSurface with a pointer to the sprite's pixels,
-		// and a pixel format that matches the sprite, but has no alpha.
-		// This will prevent it being applied from the sprite in transBlitFrom
-		assert(spriteS.format.bytesPerPixel == 4);
-		Graphics::ManagedSurface temp;
-		stripAlpha(spriteS, temp);
-
-		bmpS.transBlitFrom(temp, Common::Rect(0, 0, sprite->w, sprite->h),
-			Common::Rect(x, y, x + w, y + h));
-	}
+	bmp->draw(sprite, Common::Rect(0, 0, sprite->w, sprite->h),
+		Common::Rect(x, y, x + w, y + h),
+		false, false, true, -1);
 }
 
 void draw_trans_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y) {
 	assert(sprite->format.bytesPerPixel == 4);
 
-	if (trans_blend_alpha == -1) {
-		bmp->getSurface().transBlitFrom(sprite->getSurface(), Common::Point(x, y),
-			TRANSPARENT_COLOR(*sprite));
-
-	} else {
-		// Create a temporary ManagedSurface with a pointer to the sprite's pixels,
-		// and a pixel format that matches the sprite, but has no alpha.
-		// This will prevent it being applied from the sprite in transBlitFrom
-		Graphics::ManagedSurface &src = **sprite;
-		assert(src.format.bytesPerPixel == 4);
-
-		Graphics::ManagedSurface temp;
-		stripAlpha(src, temp);
-
-		bmp->getSurface().transBlitFrom(temp, Common::Rect(0, 0, temp.w, temp.h),
-			Common::Rect(x, y, x + temp.w, y + temp.h), TRANSPARENT_COLOR(*sprite),
-			false, 0, trans_blend_alpha);
-	}
+	bmp->draw(sprite, Common::Rect(0, 0, sprite->w, sprite->h),
+		Common::Rect(x, y, x + sprite->w, y + sprite->h),
+		false, false, true, trans_blend_alpha);
 }
 
 void draw_lit_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int color) {
-	assert(sprite->format.bytesPerPixel == 4 && bmp->format.bytesPerPixel == 4);
-	assert(color >= 0 && color <= 255);
-
-	byte rSrc, gSrc, bSrc, aSrc;
-	byte rDest, gDest, bDest;
-	double alpha = (double)color / 255.0;
-
-	for (int yCtr = 0, yp = y; yCtr < sprite->h && yp < bmp->h; ++yCtr, ++yp) {
-		if (yp < 0)
-			continue;
-
-		const uint32 *srcP = (const uint32 *)sprite->getBasePtr(0, yCtr);
-		uint32 *destP = (uint32 *)bmp->getBasePtr(x, yp);
-
-		for (int xCtr = 0, xp = x; xCtr < sprite->w && xp < bmp->w; ++xCtr, ++xp, ++destP, ++srcP) {
-			if (x < 0 || x >= bmp->w)
-				continue;
-
-			// Get the source pixels
-			sprite->format.colorToARGB(*srcP, aSrc, rSrc, gSrc, bSrc);
-
-			if (rSrc == 255 && gSrc == 0 && bSrc == 255)
-				// Skip transparent pixels
-				continue;
-
-			// Blend the two
-			rDest = static_cast<byte>((rSrc * alpha) + (trans_blend_red * (1.0 - alpha)));
-			gDest = static_cast<byte>((gSrc * alpha) + (trans_blend_green * (1.0 - alpha)));
-			bDest = static_cast<byte>((bSrc * alpha) + (trans_blend_blue * (1.0 - alpha)));
-
-			*destP = bmp->format.RGBToColor(rDest, gDest, bDest);
-		}
-	}
+	bmp->draw(sprite, Common::Rect(0, 0, sprite->w, sprite->h),
+		Common::Rect(x, y, x + sprite->w, y + sprite->h),
+		false, false, true, color);
 }
 
 void draw_sprite_h_flip(BITMAP *bmp, const BITMAP *sprite, int x, int y) {
-	Graphics::ManagedSurface &bmpS = **bmp;
-	Graphics::ManagedSurface &spriteS = **sprite;
-
-	add_palette_if_needed(spriteS);
-	bmpS.transBlitFrom(spriteS, Common::Point(x, y), (uint)-1, true);
-}
-
-static void verticallyFlip(Graphics::ManagedSurface &dest, const Graphics::ManagedSurface &src) {
-	dest.create(src.w, src.h, src.format);
-
-	for (int y = 0; y < src.h; ++y) {
-		const byte *srcP = (const byte *)src.getBasePtr(0, src.h - y - 1);
-		byte *destP = (byte *)dest.getBasePtr(0, y);
-		Common::copy(srcP, srcP + src.pitch, destP);
-	}
+	bmp->draw(sprite, Common::Rect(0, 0, sprite->w, sprite->h),
+		Common::Rect(x, y, x + sprite->w, y + sprite->h),
+		true, false, true, -1);
 }
 
 void draw_sprite_v_flip(BITMAP *bmp, const BITMAP *sprite, int x, int y) {
-	Graphics::ManagedSurface &bmpS = **bmp;
-	Graphics::ManagedSurface &spriteS = **sprite;
-	Graphics::ManagedSurface temp;
-
-	verticallyFlip(temp, spriteS);
-	add_palette_if_needed(spriteS);
-
-	bmpS.transBlitFrom(temp, Common::Point(x, y), TRANSPARENT_COLOR(spriteS));
+	bmp->draw(sprite, Common::Rect(0, 0, sprite->w, sprite->h),
+		Common::Rect(x, y, x + sprite->w, y + sprite->h),
+		false, true, true, -1);
 }
 
 void draw_sprite_vh_flip(BITMAP *bmp, const BITMAP *sprite, int x, int y) {
-	Graphics::ManagedSurface &bmpS = **bmp;
-	Graphics::ManagedSurface &spriteS = **sprite;
-	Graphics::ManagedSurface temp;
-
-	verticallyFlip(temp, spriteS);
-	add_palette_if_needed(spriteS);
-
-	bmpS.transBlitFrom(temp, Common::Point(x, y), TRANSPARENT_COLOR(spriteS), true);
+	bmp->draw(sprite, Common::Rect(0, 0, sprite->w, sprite->h),
+		Common::Rect(x, y, x + sprite->w, y + sprite->h),
+		true, true, true, -1);
 }
 
 void rotate_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, fixed angle) {
diff --git a/engines/ags/lib/allegro/surface.cpp b/engines/ags/lib/allegro/surface.cpp
index aa3296aa4c..45f1109047 100644
--- a/engines/ags/lib/allegro/surface.cpp
+++ b/engines/ags/lib/allegro/surface.cpp
@@ -90,6 +90,114 @@ void BITMAP::floodfill(int x, int y, int color) {
 	AGS3::floodfill(this, x, y, color);
 }
 
+const int SCALE_THRESHOLD = 0x100;
+#define IS_TRANSPARENT(R, G, B) ((R) == 255 && (G) == 0 && (B) == 255)
+
+void BITMAP::draw(const BITMAP *srcBitmap, const Common::Rect &srcRect,
+		const Common::Rect &destRect, bool horizFlip, bool vertFlip,
+		bool skipTrans, int srcAlpha) {
+	assert(format.bytesPerPixel == 2 || format.bytesPerPixel == 4 ||
+		(format.bytesPerPixel == 1 && srcBitmap->format.bytesPerPixel == 1));
+
+	const Graphics::ManagedSurface &src = **srcBitmap;
+	Graphics::ManagedSurface &dest = *_owner;
+	Graphics::Surface destArea = dest.getSubArea(destRect);
+	const int scaleX = SCALE_THRESHOLD * srcRect.width() / destRect.width();
+	const int scaleY = SCALE_THRESHOLD * srcRect.height() / destRect.height();
+	const int xDir = horizFlip ? -1 : 1;
+
+	byte rSrc, gSrc, bSrc, aSrc;
+	byte rDest, gDest, bDest, aDest;
+	uint32 pal[PALETTE_COUNT];
+
+	if (src.format.bytesPerPixel == 1) {
+		for (int i = 0; i < PALETTE_COUNT; ++i)
+			pal[i] = format.RGBToColor(_current_palette[i].r,
+				_current_palette[i].g, _current_palette[i].b);
+		pal[0] = format.RGBToColor(0xff, 0, 0xff);
+	}
+
+	for (int destY = destRect.top, yCtr = 0, scaleYCtr = 0; yCtr < destArea.h;
+			++destY, ++yCtr, scaleYCtr += scaleY) {
+		if (destY < 0 || destY >= h)
+			continue;
+		byte *destP = (byte *)destArea.getBasePtr(0, yCtr);
+		const byte *srcP = (const byte *)src.getBasePtr(
+			horizFlip ? srcRect.right - 1 : srcRect.left,
+			vertFlip ? srcRect.bottom - 1 - scaleYCtr / SCALE_THRESHOLD :
+			srcRect.top + scaleYCtr / SCALE_THRESHOLD);
+
+		// Loop through the pixels of the row
+		for (int destX = destRect.left, xCtr = 0, scaleXCtr = 0; xCtr < destArea.w;
+				++destX, ++xCtr, scaleXCtr += scaleX) {
+			if (destX < 0 || destX >= w)
+				continue;
+
+			const byte *srcVal = srcP + xDir * (scaleXCtr / SCALE_THRESHOLD * src.format.bytesPerPixel);
+			byte *destVal = (byte *)&destP[xCtr * format.bytesPerPixel];
+
+			switch (src.format.bytesPerPixel) {
+			case 1:
+				if (format.bytesPerPixel == 1) {
+					*destVal = *srcVal;
+					continue;
+				}
+				format.colorToARGB(pal[*srcVal], aSrc, rSrc, gSrc, bSrc);
+				break;
+			case 2:
+				src.format.colorToARGB(*(uint16 *)srcVal, aSrc, rSrc, gSrc, bSrc);
+				break;
+			case 4:
+				src.format.colorToARGB(*(uint32 *)srcVal, aSrc, rSrc, gSrc, bSrc);
+				break;
+			default:
+				error("Unknown format");
+			}
+
+			if (srcAlpha != -1)
+				aSrc = srcAlpha;
+			if (aSrc == 0)
+				aSrc = 0xff;
+
+			if (aSrc != 0xff) {
+				// Get the pixel at the destination, to check if it's transparent.
+				// Transparent pixels can be considered to be 0 alph
+				format.colorToARGB(format.bytesPerPixel == 2 ?
+					*(uint16 *)destVal : *(uint32 *)destVal, aDest, rDest, gDest, bDest);
+				if (IS_TRANSPARENT(rDest, gDest, bDest))
+					aDest = 0;
+			} else {
+				// Source is opaque, so just treat destination as transparent
+				aDest = 0;
+			}
+
+			if (aDest != 0 && (aSrc != 0xff || srcAlpha != -1)) {
+				// Alpha blender
+				double sAlpha = (double)aSrc / 255.0;
+				double dAlpha = (double)aDest / 255.0;
+				dAlpha *= (1.0 - sAlpha);
+				rDest = static_cast<uint8>((rSrc * sAlpha + rDest * dAlpha) / (sAlpha + dAlpha));
+				gDest = static_cast<uint8>((gSrc * sAlpha + gDest * dAlpha) / (sAlpha + dAlpha));
+				bDest = static_cast<uint8>((bSrc * sAlpha + bDest * dAlpha) / (sAlpha + dAlpha));
+				aDest = static_cast<uint8>(255. * (sAlpha + dAlpha));
+			} else {
+				rDest = rSrc;
+				gDest = gSrc;
+				bDest = bSrc;
+				aDest = aSrc;
+			}
+
+			if (!(IS_TRANSPARENT(rSrc, gSrc, bSrc) && skipTrans)) {
+				uint32 pixel = format.ARGBToColor(aDest, rDest, gDest, bDest);
+				if (format.bytesPerPixel == 4)
+					*(uint32 *)destVal = pixel;
+				else
+					*(uint16 *)destVal = pixel;
+			}
+		}
+	}
+}
+
 /*-------------------------------------------------------------------*/
 
 /**
@@ -128,9 +236,6 @@ BITMAP *create_bitmap_ex(int color_depth, int width, int height) {
 	}
 
 	BITMAP *bitmap = new Surface(width, height, format);
-	if (color_depth == 8)
-		add_palette_if_needed(bitmap->getSurface());
-
 	return bitmap;
 }
 
diff --git a/engines/ags/lib/allegro/surface.h b/engines/ags/lib/allegro/surface.h
index b366a967ae..257ecc91db 100644
--- a/engines/ags/lib/allegro/surface.h
+++ b/engines/ags/lib/allegro/surface.h
@@ -94,6 +94,13 @@ public:
 	void vLine(int x, int y, int y2, uint32 color) {
 		_owner->vLine(x, y, y2, color);
 	}
+
+	/**
+	 * Draws the passed surface onto this one
+	 */
+	void draw(const BITMAP *srcBitmap, const Common::Rect &srcRect,
+		const Common::Rect &destRect, bool horizFlip, bool vertFlip,
+		bool skipTrans, int srcAlpha);
 };
 
 /**




More information about the Scummvm-git-logs mailing list