[Scummvm-git-logs] scummvm master -> 675d8514760e82d828f305ff68f7bce5a23ccb95

dreammaster dreammaster at scummvm.org
Sat Feb 20 22:37:48 UTC 2021


This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
c53fb72922 GRAPHICS: Better 32-bit surface handling in ManagedSurface
3ad8c5cb03 AGS: Drawing fixes for blitting and sprites
675d851476 AGS: Shift BITMAP & Surface into it's own file


Commit: c53fb729225416d77ba782bcf4e0e79269c46b34
    https://github.com/scummvm/scummvm/commit/c53fb729225416d77ba782bcf4e0e79269c46b34
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-02-20T14:37:29-08:00

Commit Message:
GRAPHICS: Better 32-bit surface handling in ManagedSurface

Fixes several issues dealing with 32-bit surfaces, such as
- transBlitFrom between 32-bit surfaces
- 32-bit surfaces where the alpha channel is explicitly turned off
- Alpha blending when dest pixels are the transparent color
- Specifying colors to fill, line routines without alpha

Changed paths:
    graphics/managed_surface.cpp
    graphics/managed_surface.h


diff --git a/graphics/managed_surface.cpp b/graphics/managed_surface.cpp
index bf1f306a59..8d088f8da8 100644
--- a/graphics/managed_surface.cpp
+++ b/graphics/managed_surface.cpp
@@ -114,6 +114,11 @@ void ManagedSurface::create(uint16 width, uint16 height, const PixelFormat &pixe
 	free();
 	_innerSurface.create(width, height, pixelFormat);
 
+	// For pixel formats with an alpha channel, we need to do a clear
+	// so that all the pixels will have full alpha (0xff)
+	if (pixelFormat.aBits() != 0)
+		clear(0);
+
 	_disposeAfterUse = DisposeAfterUse::YES;
 	markAllDirty();
 }
@@ -451,13 +456,7 @@ static byte *createPaletteLookup(const uint32 *srcPalette, const uint32 *dstPale
 template<typename TSRC, typename TDEST>
 void transBlitPixel(TSRC srcVal, TDEST &destVal, const Graphics::PixelFormat &srcFormat, const Graphics::PixelFormat &destFormat,
 		uint overrideColor, uint srcAlpha, const uint32 *srcPalette, const byte *lookup) {
-	if (srcFormat == destFormat && srcAlpha == 0xff) {
-		// Matching formats, so we can do a straight copy
-		destVal = overrideColor ? overrideColor : srcVal;
-		return;
-	}
-
-	// Otherwise we have to manually decode and re-encode each pixel
+	// Decode and re-encode each pixel
 	byte aSrc, rSrc, gSrc, bSrc;
 	if (srcFormat.bytesPerPixel == 1) {
 		assert(srcPalette != nullptr);	// Catch the cases when palette is missing
@@ -513,12 +512,13 @@ void transBlitPixel<byte, byte>(byte srcVal, byte &destVal, const Graphics::Pixe
 }
 
 template<typename TSRC, typename TDEST>
-void transBlit(const Surface &src, const Common::Rect &srcRect, Surface &dest, const Common::Rect &destRect,
+void transBlit(const Surface &src, const Common::Rect &srcRect, ManagedSurface &dest, const Common::Rect &destRect,
 		TSRC transColor, bool flipped, uint overrideColor, uint srcAlpha, const uint32 *srcPalette,
 		const uint32 *dstPalette, const Surface *mask, bool maskOnly) {
 	int scaleX = SCALE_THRESHOLD * srcRect.width() / destRect.width();
 	int scaleY = SCALE_THRESHOLD * srcRect.height() / destRect.height();
-	byte rt1 = 0, gt1 = 0, bt1 = 0, rt2 = 0, gt2 = 0, bt2 = 0;
+	byte rst = 0, gst = 0, bst = 0, rdt = 0, gdt = 0, bdt = 0;
+	byte r = 0, g = 0, b = 0;
 
 	byte *lookup = nullptr;
 	if (srcPalette && dstPalette)
@@ -526,9 +526,13 @@ void transBlit(const Surface &src, const Common::Rect &srcRect, Surface &dest, c
 
 	// If we're dealing with a 32-bit source surface, we need to split up the RGB,
 	// since we'll want to find matching RGB pixels irrespective of the alpha
-	bool isTrans32 = src.format.bytesPerPixel == 4 && transColor != (uint32)-1 && transColor > 0;
-	if (isTrans32) {
-		src.format.colorToRGB(transColor, rt1, gt1, bt1);
+	bool isSrcTrans32 = src.format.aBits() != 0 && transColor != (uint32)-1 && transColor > 0;
+	if (isSrcTrans32) {
+		src.format.colorToRGB(transColor, rst, gst, bst);
+	}
+	bool isDestTrans32 = dest.format.aBits() != 0 && dest.hasTransparentColor();
+	if (isDestTrans32) {
+		dest.format.colorToRGB(dest.getTransparentColor(), rdt, gdt, bdt);
 	}
 
 	// Loop through drawing output lines
@@ -549,9 +553,23 @@ void transBlit(const Surface &src, const Common::Rect &srcRect, Surface &dest, c
 				continue;
 
 			TSRC srcVal = srcLine[flipped ? src.w - scaleXCtr / SCALE_THRESHOLD - 1 : scaleXCtr / SCALE_THRESHOLD];
-			if (isTrans32 && !maskOnly) {
-				src.format.colorToRGB(srcVal, rt2, gt2, bt2);
-				if (rt1 == rt2 && gt1 == gt2 && bt1 == bt2)
+			TDEST &destVal = destLine[xCtr];
+
+			dest.format.colorToRGB(destVal, r, g, b);
+
+			// Check if dest pixel is transparent
+			bool isDestPixelTrans = false;
+			if (isDestTrans32) {
+				dest.format.colorToRGB(destVal, r, g, b);
+				if (rdt == r && gdt == g && bdt == b)
+					isDestPixelTrans = true;
+			} else if (dest.hasTransparentColor()) {
+				isDestPixelTrans = destVal == dest.getTransparentColor();
+			}
+
+			if (isSrcTrans32 && !maskOnly) {
+				src.format.colorToRGB(srcVal, r, g, b);
+				if (rst == r && gst == g && bst == b)
 					continue;
 
 			} else if (srcVal == transColor && !maskOnly)
@@ -562,9 +580,17 @@ void transBlit(const Surface &src, const Common::Rect &srcRect, Surface &dest, c
 				if (!mskVal)
 					continue;
 
-				transBlitPixel<TSRC, TDEST>(srcVal, destLine[xCtr], src.format, dest.format, overrideColor, mskVal, srcPalette, lookup);
+				if (isDestPixelTrans)
+					// Remove transparent color on dest so it isn't alpha blended
+					destVal = 0;
+
+				transBlitPixel<TSRC, TDEST>(srcVal, destVal, src.format, dest.format, overrideColor, mskVal, srcPalette, lookup);
 			} else {
-				transBlitPixel<TSRC, TDEST>(srcVal, destLine[xCtr], src.format, dest.format, overrideColor, srcAlpha, srcPalette, lookup);
+				if (isDestPixelTrans)
+					// Remove transparent color on dest so it isn't alpha blended
+					destVal = 0;
+
+				transBlitPixel<TSRC, TDEST>(srcVal, destVal, src.format, dest.format, overrideColor, srcAlpha, srcPalette, lookup);
 			}
 		}
 	}
@@ -574,7 +600,7 @@ void transBlit(const Surface &src, const Common::Rect &srcRect, Surface &dest, c
 
 #define HANDLE_BLIT(SRC_BYTES, DEST_BYTES, SRC_TYPE, DEST_TYPE) \
 	if (src.format.bytesPerPixel == SRC_BYTES && format.bytesPerPixel == DEST_BYTES) \
-		transBlit<SRC_TYPE, DEST_TYPE>(src, srcRect, _innerSurface, destRect, transColor, flipped, overrideColor, srcAlpha, srcPalette, dstPalette, mask, maskOnly); \
+		transBlit<SRC_TYPE, DEST_TYPE>(src, srcRect, *this, destRect, transColor, flipped, overrideColor, srcAlpha, srcPalette, dstPalette, mask, maskOnly); \
 	else
 
 void ManagedSurface::transBlitFromInner(const Surface &src, const Common::Rect &srcRect,
@@ -616,9 +642,18 @@ void ManagedSurface::addDirtyRect(const Common::Rect &r) {
 	}
 }
 
+uint32 ManagedSurface::addAlphaToColor(uint32 color) {
+	if (format.aBits() == 0)
+		return color;
+
+	byte r, g, b;
+	format.colorToRGB(color, r, g, b);
+	return format.ARGBToColor(0xff, r, g, b);
+}
+
 void ManagedSurface::clear(uint color) {
 	if (!empty())
-		fillRect(getBounds(), color);
+		fillRect(getBounds(), addAlphaToColor(color));
 }
 
 void ManagedSurface::setPalette(const byte *colors, uint start, uint num) {
diff --git a/graphics/managed_surface.h b/graphics/managed_surface.h
index 80ef2c5669..531e4ba26b 100644
--- a/graphics/managed_surface.h
+++ b/graphics/managed_surface.h
@@ -91,6 +91,12 @@ protected:
 	 */
 	virtual void addDirtyRect(const Common::Rect &r);
 
+	/**
+	 * Adds a full solid alpha to the passed color for surfaces that have
+	 * an alpha channel
+	 */
+	uint32 addAlphaToColor(uint32 color);
+
 	/**
 	 * Inner method for blitting.
 	 */
@@ -507,7 +513,7 @@ public:
 	 * Draw a line.
 	 */
 	void drawLine(int x0, int y0, int x1, int y1, uint32 color) {
-		_innerSurface.drawLine(x0, y0, x1, y1, color);
+		_innerSurface.drawLine(x0, y0, x1, y1, addAlphaToColor(color));
 		addDirtyRect(Common::Rect(MIN(x0, x1), MIN(y0, y1), MAX(x0, x1), MAX(y0, y1)));
 	}
 
@@ -515,7 +521,7 @@ public:
 	 * Draw a thick line.
 	 */
 	void drawThickLine(int x0, int y0, int x1, int y1, int penX, int penY, uint32 color) {
-		_innerSurface.drawThickLine(x0, y0, x1, y1, penX, penY, color);
+		_innerSurface.drawThickLine(x0, y0, x1, y1, penX, penY, addAlphaToColor(color));
 		addDirtyRect(Common::Rect(MIN(x0, x1 + penX), MIN(y0, y1 + penY), MAX(x0, x1 + penX), MAX(y0, y1 + penY)));
 	}
 
@@ -523,7 +529,7 @@ public:
 	 * Draw a horizontal line.
 	 */
 	void hLine(int x, int y, int x2, uint32 color) {
-		_innerSurface.hLine(x, y, x2, color);
+		_innerSurface.hLine(x, y, x2, addAlphaToColor(color));
 		addDirtyRect(Common::Rect(x, y, x2 + 1, y + 1));
 	}
 
@@ -531,7 +537,7 @@ public:
 	 * Draw a vertical line.
 	 */
 	void vLine(int x, int y, int y2, uint32 color) {
-		_innerSurface.vLine(x, y, y2, color);
+		_innerSurface.vLine(x, y, y2, addAlphaToColor(color));
 		addDirtyRect(Common::Rect(x, y, x + 1, y2 + 1));
 	}
 
@@ -539,7 +545,7 @@ public:
 	 * Fill a rect with a given color.
 	 */
 	void fillRect(Common::Rect r, uint32 color) {
-		_innerSurface.fillRect(r, color);
+		_innerSurface.fillRect(r, addAlphaToColor(color));
 		addDirtyRect(r);
 	}
 
@@ -547,7 +553,7 @@ public:
 	 * Draw a frame around a specified rect.
 	 */
 	void frameRect(const Common::Rect &r, uint32 color) {
-		_innerSurface.frameRect(r, color);
+		_innerSurface.frameRect(r, addAlphaToColor(color));
 		addDirtyRect(r);
 	}
 


Commit: 3ad8c5cb035e17171dff4c21722e8a0d74d45d69
    https://github.com/scummvm/scummvm/commit/3ad8c5cb035e17171dff4c21722e8a0d74d45d69
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-02-20T14:37:29-08:00

Commit Message:
AGS: Drawing fixes for blitting and sprites

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


diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp
index f07aaa97ee..fd33148f19 100644
--- a/engines/ags/ags.cpp
+++ b/engines/ags/ags.cpp
@@ -386,7 +386,7 @@ SaveStateList AGSEngine::listSaves() const {
 }
 
 void AGSEngine::setGraphicsMode(size_t w, size_t h) {
-	Graphics::PixelFormat FORMAT(4, 8, 8, 8, 8, 16, 8, 0, 24);
+	Graphics::PixelFormat FORMAT(4, 8, 8, 8, 8, 24, 16, 8, 0);
 	initGraphics(w, h, &FORMAT);
 
 	_rawScreen = new Graphics::Screen();
diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp
index cc9993138c..d17819190c 100644
--- a/engines/ags/lib/allegro/gfx.cpp
+++ b/engines/ags/lib/allegro/gfx.cpp
@@ -241,18 +241,37 @@ void add_palette_if_needed(Graphics::ManagedSurface &surf) {
 	}
 }
 
+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 (dynamic_cast<Graphics::Screen *>(&destS) != nullptr) {
-		destS.blitFrom(srcS, Common::Rect(src_x, src_y, src_x + width, src_y + height),
-			Common::Point(dst_x, dst_y));
-	} else {
+	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);
 	}
 }
 
@@ -293,7 +312,18 @@ void draw_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y) {
 
 	add_palette_if_needed(spriteS);
 
-	bmpS.transBlitFrom(spriteS, Common::Point(x, y), TRANSPARENT_COLOR(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));
+	}
 }
 
 void stretch_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int w, int h) {
@@ -302,8 +332,20 @@ void stretch_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int w, int
 
 	add_palette_if_needed(spriteS);
 
-	bmpS.transBlitFrom(spriteS, Common::Rect(0, 0, sprite->w, sprite->h),
-		Common::Rect(x, y, x + w, y + h));
+	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));
+	}
 }
 
 void draw_trans_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y) {
@@ -317,55 +359,29 @@ void draw_trans_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y) {
 		// 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 spr;
-		spr.format = sprite->format;
-		spr.format.aLoss = 8;
-		spr.format.aShift = 0;
-		spr.setPixels(sprite->getPixels());
-		spr.w = sprite->w;
-		spr.h = sprite->h;
-		spr.pitch = sprite->pitch;
-
-		bmp->getSurface().transBlitFrom(spr, Common::Rect(0, 0, spr.w, spr.h),
-			Common::Rect(x, y, x + spr.w, y + spr.h), TRANSPARENT_COLOR(*sprite),
+		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);
 	}
 }
 
 void draw_lit_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int color) {
-	// TODO: For now, only 32-bit bitmaps
 	assert(sprite->format.bytesPerPixel == 4 && bmp->format.bytesPerPixel == 4);
-	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;
+	assert(color >= 0 && color <= 255);
 
-		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) {
-			if (x < 0 || x >= bmp->w)
-				continue;
-
-			// Get the source and dest pixels
-			sprite->format.colorToARGB(*srcP, aSrc, rSrc, gSrc, bSrc);
-			bmp->format.colorToRGB(*destP, rDest, gDest, bDest);
-
-			if (rSrc == 255 && gSrc == 0 && bSrc == 255)
-				// Skip transparent pixels
-				continue;
-
-			// Blend the two
-			rDest = static_cast<byte>((rSrc * alpha) + (rDest * (1.0 - alpha)));
-			gDest = static_cast<byte>((gSrc * alpha) + (gDest * (1.0 - alpha)));
-			bDest = static_cast<byte>((bSrc * alpha) + (bDest * (1.0 - alpha)));
+	Graphics::ManagedSurface temp;
+	Graphics::ManagedSurface &src = **sprite;
+	stripAlpha(src, temp);
 
-			*destP = bmp->format.RGBToColor(rDest, gDest, bDest);
-		}
-	}
+	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, color);
 }
 
 void draw_sprite_h_flip(BITMAP *bmp, const BITMAP *sprite, int x, int y) {


Commit: 675d8514760e82d828f305ff68f7bce5a23ccb95
    https://github.com/scummvm/scummvm/commit/675d8514760e82d828f305ff68f7bce5a23ccb95
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-02-20T14:37:29-08:00

Commit Message:
AGS: Shift BITMAP & Surface into it's own file

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


diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp
index d17819190c..fd88e44c19 100644
--- a/engines/ags/lib/allegro/gfx.cpp
+++ b/engines/ags/lib/allegro/gfx.cpp
@@ -39,84 +39,6 @@ int color_conversion;
 // Arbitrary RGBA tuplet that should never be encountered
 #define NO_TRANSPARENT_COLOR 0x88888888
 
-/*-------------------------------------------------------------------*/
-
-BITMAP::BITMAP(Graphics::ManagedSurface *owner) : _owner(owner),
-		w(owner->w), h(owner->h), pitch(owner->pitch), format(owner->format),
-		clip(false), ct(0), cl(0), cr(owner->w), cb(owner->h) {
-	line.resize(h);
-	for (uint y = 0; y < h; ++y)
-		line[y] = (byte *)_owner->getBasePtr(0, y);
-}
-
-int BITMAP::getpixel(int x, int y) const {
-	if (x < 0 || y < 0 || x >= w || y >= h)
-		return -1;
-
-	const byte *pixel = (const byte *)getBasePtr(x, y);
-	if (format.bytesPerPixel == 1)
-		return *pixel;
-	else if (format.bytesPerPixel == 2)
-		return *(const uint16 *)pixel;
-	else
-		return *(const uint32 *)pixel;
-}
-
-void BITMAP::circlefill(int x, int y, int radius, int color) {
-	int cx = 0;
-	int cy = radius;
-	int df = 1 - radius;
-	int d_e = 3;
-	int d_se = -2 * radius + 5;
-
-	do {
-		_owner->hLine(x - cy, y - cx, x + cy, color);
-
-		if (cx)
-			_owner->hLine(x - cy, y + cx, x + cy, color);
-
-		if (df < 0) {
-			df += d_e;
-			d_e += 2;
-			d_se += 2;
-		} else {
-			if (cx != cy) {
-				_owner->hLine(x - cx, y - cy, x + cx, color);
-
-				if (cy)
-					_owner->hLine(x - cx, y + cy, x + cx, color);
-			}
-
-			df += d_se;
-			d_e += 2;
-			d_se += 4;
-			cy--;
-		}
-
-		cx++;
-
-	} while (cx <= cy);
-}
-
-void BITMAP::floodfill(int x, int y, int color) {
-	AGS3::floodfill(this, x, y, color);
-}
-
-/*-------------------------------------------------------------------*/
-
-/**
- * Dervied screen surface
- */
-class Screen : public Graphics::Screen, public BITMAP {
-public:
-	Screen() : Graphics::Screen(), BITMAP(this) {}
-	Screen(int width, int height) : Graphics::Screen(width, height), BITMAP(this) {}
-	Screen(int width, int height, const Graphics::PixelFormat &pixelFormat) :
-		Graphics::Screen(width, height, pixelFormat), BITMAP(this) {}
-	~Screen() override {}
-};
-
-
 /*-------------------------------------------------------------------*/
 
 void set_color_conversion(int mode) {
@@ -136,51 +58,6 @@ int set_gfx_mode(int card, int w, int h, int v_w, int v_h) {
 	return 0;
 }
 
-BITMAP *create_bitmap(int width, int height) {
-	return new Surface(width, height);
-}
-
-BITMAP *create_bitmap_ex(int color_depth, int width, int height) {
-	Graphics::PixelFormat format;
-
-	switch (color_depth) {
-	case 8:
-		format = Graphics::PixelFormat::createFormatCLUT8();
-		break;
-	case 16:
-		format = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
-		break;
-	case 32:
-		format = Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24);
-		break;
-	default:
-		error("Invalid color depth");
-	}
-
-	BITMAP *bitmap = new Surface(width, height, format);
-	if (color_depth == 8)
-		add_palette_if_needed(bitmap->getSurface());
-
-	return bitmap;
-}
-
-BITMAP *create_sub_bitmap(BITMAP *parent, int x, int y, int width, int height) {
-	Graphics::ManagedSurface &surf = **parent;
-	return new Surface(surf, Common::Rect(x, y, x + width, y + height));
-}
-
-BITMAP *create_video_bitmap(int width, int height) {
-	return new Screen(width, height);
-}
-
-BITMAP *create_system_bitmap(int width, int height) {
-	return create_bitmap(width, height);
-}
-
-void destroy_bitmap(BITMAP *bitmap) {
-	delete bitmap;
-}
-
 void set_clip_rect(BITMAP *bitmap, int x1, int y1, int x2, int y2) {
 	bitmap->cl = x1;
 	bitmap->ct = y1;
diff --git a/engines/ags/lib/allegro/gfx.h b/engines/ags/lib/allegro/gfx.h
index 91c9f62ce1..a25a893b4b 100644
--- a/engines/ags/lib/allegro/gfx.h
+++ b/engines/ags/lib/allegro/gfx.h
@@ -26,6 +26,7 @@
 #include "graphics/managed_surface.h"
 #include "ags/lib/allegro/base.h"
 #include "ags/lib/allegro/fixed.h"
+#include "ags/lib/allegro/surface.h"
 #include "common/array.h"
 
 namespace AGS3 {
@@ -173,111 +174,10 @@ namespace AGS3 {
                                              COLORCONV_32A_TO_16 |       \
                                              COLORCONV_32A_TO_24))
 
-class BITMAP {
-private:
-	Graphics::ManagedSurface *_owner;
-public:
-	uint16 &w, &h, &pitch;
-	Graphics::PixelFormat &format;
-	bool clip;
-	int ct, cb, cl, cr;
-	Common::Array<byte *> line;
-public:
-	BITMAP(Graphics::ManagedSurface *owner);
-	virtual ~BITMAP() {
-	}
-
-	Graphics::ManagedSurface &operator*() const {
-		return *_owner;
-	}
-	Graphics::ManagedSurface &getSurface() {
-		return *_owner;
-	}
-	const Graphics::ManagedSurface &getSurface() const {
-		return *_owner;
-	}
-
-	unsigned char *getPixels() const {
-		return (unsigned char *)_owner->getPixels();
-	}
-
-	unsigned char *getBasePtr(uint16 x, uint16 y) const {
-		return (unsigned char *)_owner->getBasePtr(x, y);
-	}
-
-	uint getTransparentColor() const {
-		return format.RGBToColor(255, 0, 255);
-	}
-
-	int getpixel(int x, int y) const;
-
-	void clear() {
-		_owner->clear();
-	}
-
-	/**
-	 * Draws a solid filled in circle
-	 */
-	void circlefill(int x, int y, int radius, int color);
-
-	/**
-	 * Fills an enclosed area starting at a given point
-	 */
-	void floodfill(int x, int y, int color);
-
-	/**
-	 * Draw a horizontal line
-	 */
-	void hLine(int x, int y, int x2, uint32 color) {
-		_owner->hLine(x, y, x2, color);
-	}
-
-	/**
-	 * Draw a vertical line.
-	 */
-	void vLine(int x, int y, int y2, uint32 color) {
-		_owner->vLine(x, y, y2, color);
-	}
-};
-
-/**
- * Derived surface class
- */
-class Surface : public Graphics::ManagedSurface, public BITMAP {
-public:
-	Surface() : Graphics::ManagedSurface(), BITMAP(this) {
-	}
-	Surface(const Graphics::ManagedSurface &surf) : Graphics::ManagedSurface(surf), BITMAP(this) {
-	}
-	Surface(int width, int height) : Graphics::ManagedSurface(width, height), BITMAP(this) {
-	}
-	Surface(int width, int height, const Graphics::PixelFormat &pixelFormat) :
-			Graphics::ManagedSurface(width, height, pixelFormat), BITMAP(this) {
-		// Allegro uses 255, 0, 255 RGB as the transparent color
-		if (pixelFormat.bytesPerPixel == 4)
-			setTransparentColor(pixelFormat.RGBToColor(255, 0, 255));
-	}
-	Surface(Graphics::ManagedSurface &surf, const Common::Rect &bounds) :
-			Graphics::ManagedSurface(surf, bounds), BITMAP(this) {
-		// Allegro uses 255, 0, 255 RGB as the transparent color
-		if (surf.format.bytesPerPixel == 4)
-			setTransparentColor(surf.format.RGBToColor(255, 0, 255));
-	}
-	~Surface() override {
-	}
-};
-
-
 AL_FUNC(void, set_color_conversion, (int mode));
 AL_FUNC(int, get_color_conversion, ());
 AL_FUNC(int, set_gfx_mode, (int card, int w, int h, int v_w, int v_h));
-AL_FUNC(BITMAP *, create_bitmap, (int width, int height));
-AL_FUNC(BITMAP *, create_bitmap_ex, (int color_depth, int width, int height));
-AL_FUNC(BITMAP *, create_sub_bitmap, (BITMAP *parent, int x, int y, int width, int height));
-AL_FUNC(BITMAP *, create_video_bitmap, (int width, int height));
-AL_FUNC(BITMAP *, create_system_bitmap, (int width, int height));
 
-AL_FUNC(void, destroy_bitmap, (BITMAP *bitmap));
 AL_FUNC(void, set_clip_rect, (BITMAP *bitmap, int x1, int y1, int x2, int y2));
 AL_FUNC(void, add_clip_rect, (BITMAP *bitmap, int x1, int y1, int x2, int y2));
 AL_FUNC(void, get_clip_rect, (BITMAP *bitmap, int *x1, int *y1, int *x2, int *y2));
diff --git a/engines/ags/lib/allegro/surface.cpp b/engines/ags/lib/allegro/surface.cpp
new file mode 100644
index 0000000000..aa3296aa4c
--- /dev/null
+++ b/engines/ags/lib/allegro/surface.cpp
@@ -0,0 +1,154 @@
+/* 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 "ags/lib/allegro/gfx.h"
+#include "ags/lib/allegro/color.h"
+#include "ags/lib/allegro/flood.h"
+#include "ags/ags.h"
+#include "common/textconsole.h"
+#include "graphics/screen.h"
+
+namespace AGS3 {
+
+BITMAP::BITMAP(Graphics::ManagedSurface *owner) : _owner(owner),
+		w(owner->w), h(owner->h), pitch(owner->pitch), format(owner->format),
+		clip(false), ct(0), cl(0), cr(owner->w), cb(owner->h) {
+	line.resize(h);
+	for (uint y = 0; y < h; ++y)
+		line[y] = (byte *)_owner->getBasePtr(0, y);
+}
+
+int BITMAP::getpixel(int x, int y) const {
+	if (x < 0 || y < 0 || x >= w || y >= h)
+		return -1;
+
+	const byte *pixel = (const byte *)getBasePtr(x, y);
+	if (format.bytesPerPixel == 1)
+		return *pixel;
+	else if (format.bytesPerPixel == 2)
+		return *(const uint16 *)pixel;
+	else
+		return *(const uint32 *)pixel;
+}
+
+void BITMAP::circlefill(int x, int y, int radius, int color) {
+	int cx = 0;
+	int cy = radius;
+	int df = 1 - radius;
+	int d_e = 3;
+	int d_se = -2 * radius + 5;
+
+	do {
+		_owner->hLine(x - cy, y - cx, x + cy, color);
+
+		if (cx)
+			_owner->hLine(x - cy, y + cx, x + cy, color);
+
+		if (df < 0) {
+			df += d_e;
+			d_e += 2;
+			d_se += 2;
+		} else {
+			if (cx != cy) {
+				_owner->hLine(x - cx, y - cy, x + cx, color);
+
+				if (cy)
+					_owner->hLine(x - cx, y + cy, x + cx, color);
+			}
+
+			df += d_se;
+			d_e += 2;
+			d_se += 4;
+			cy--;
+		}
+
+		cx++;
+
+	} while (cx <= cy);
+}
+
+void BITMAP::floodfill(int x, int y, int color) {
+	AGS3::floodfill(this, x, y, color);
+}
+
+/*-------------------------------------------------------------------*/
+
+/**
+ * Dervied screen surface
+ */
+class Screen : public Graphics::Screen, public BITMAP {
+public:
+	Screen() : Graphics::Screen(), BITMAP(this) {}
+	Screen(int width, int height) : Graphics::Screen(width, height), BITMAP(this) {}
+	Screen(int width, int height, const Graphics::PixelFormat &pixelFormat) :
+		Graphics::Screen(width, height, pixelFormat), BITMAP(this) {}
+	~Screen() override {}
+};
+
+/*-------------------------------------------------------------------*/
+
+BITMAP *create_bitmap(int width, int height) {
+	return new Surface(width, height);
+}
+
+BITMAP *create_bitmap_ex(int color_depth, int width, int height) {
+	Graphics::PixelFormat format;
+
+	switch (color_depth) {
+	case 8:
+		format = Graphics::PixelFormat::createFormatCLUT8();
+		break;
+	case 16:
+		format = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
+		break;
+	case 32:
+		format = Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24);
+		break;
+	default:
+		error("Invalid color depth");
+	}
+
+	BITMAP *bitmap = new Surface(width, height, format);
+	if (color_depth == 8)
+		add_palette_if_needed(bitmap->getSurface());
+
+	return bitmap;
+}
+
+BITMAP *create_sub_bitmap(BITMAP *parent, int x, int y, int width, int height) {
+	Graphics::ManagedSurface &surf = **parent;
+	return new Surface(surf, Common::Rect(x, y, x + width, y + height));
+}
+
+BITMAP *create_video_bitmap(int width, int height) {
+	return new Screen(width, height);
+}
+
+BITMAP *create_system_bitmap(int width, int height) {
+	return create_bitmap(width, height);
+}
+
+void destroy_bitmap(BITMAP *bitmap) {
+	delete bitmap;
+}
+
+} // namespace AGS3
diff --git a/engines/ags/lib/allegro/surface.h b/engines/ags/lib/allegro/surface.h
new file mode 100644
index 0000000000..b366a967ae
--- /dev/null
+++ b/engines/ags/lib/allegro/surface.h
@@ -0,0 +1,135 @@
+/* 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.
+ *
+ */
+
+#ifndef AGS_LIB_ALLEGRO_SURFACE_H
+#define AGS_LIB_ALLEGRO_SURFACE_H
+
+#include "graphics/managed_surface.h"
+#include "ags/lib/allegro/base.h"
+#include "common/array.h"
+
+namespace AGS3 {
+
+class BITMAP {
+private:
+	Graphics::ManagedSurface *_owner;
+public:
+	uint16 &w, &h, &pitch;
+	Graphics::PixelFormat &format;
+	bool clip;
+	int ct, cb, cl, cr;
+	Common::Array<byte *> line;
+public:
+	BITMAP(Graphics::ManagedSurface *owner);
+	virtual ~BITMAP() {
+	}
+
+	Graphics::ManagedSurface &operator*() const {
+		return *_owner;
+	}
+	Graphics::ManagedSurface &getSurface() {
+		return *_owner;
+	}
+	const Graphics::ManagedSurface &getSurface() const {
+		return *_owner;
+	}
+
+	unsigned char *getPixels() const {
+		return (unsigned char *)_owner->getPixels();
+	}
+
+	unsigned char *getBasePtr(uint16 x, uint16 y) const {
+		return (unsigned char *)_owner->getBasePtr(x, y);
+	}
+
+	uint getTransparentColor() const {
+		return format.RGBToColor(255, 0, 255);
+	}
+
+	int getpixel(int x, int y) const;
+
+	void clear() {
+		_owner->clear();
+	}
+
+	/**
+	 * Draws a solid filled in circle
+	 */
+	void circlefill(int x, int y, int radius, int color);
+
+	/**
+	 * Fills an enclosed area starting at a given point
+	 */
+	void floodfill(int x, int y, int color);
+
+	/**
+	 * Draw a horizontal line
+	 */
+	void hLine(int x, int y, int x2, uint32 color) {
+		_owner->hLine(x, y, x2, color);
+	}
+
+	/**
+	 * Draw a vertical line.
+	 */
+	void vLine(int x, int y, int y2, uint32 color) {
+		_owner->vLine(x, y, y2, color);
+	}
+};
+
+/**
+ * Derived surface class
+ */
+class Surface : public Graphics::ManagedSurface, public BITMAP {
+public:
+	Surface() : Graphics::ManagedSurface(), BITMAP(this) {
+	}
+	Surface(const Graphics::ManagedSurface &surf) : Graphics::ManagedSurface(surf), BITMAP(this) {
+	}
+	Surface(int width, int height) : Graphics::ManagedSurface(width, height), BITMAP(this) {
+	}
+	Surface(int width, int height, const Graphics::PixelFormat &pixelFormat) :
+			Graphics::ManagedSurface(width, height, pixelFormat), BITMAP(this) {
+		// Allegro uses 255, 0, 255 RGB as the transparent color
+		if (pixelFormat.bytesPerPixel == 4)
+			setTransparentColor(pixelFormat.RGBToColor(255, 0, 255));
+	}
+	Surface(Graphics::ManagedSurface &surf, const Common::Rect &bounds) :
+			Graphics::ManagedSurface(surf, bounds), BITMAP(this) {
+		// Allegro uses 255, 0, 255 RGB as the transparent color
+		if (surf.format.bytesPerPixel == 4)
+			setTransparentColor(surf.format.RGBToColor(255, 0, 255));
+	}
+	~Surface() override {
+	}
+};
+
+BITMAP *create_bitmap(int width, int height);
+BITMAP *create_bitmap_ex(int color_depth, int width, int height);
+BITMAP *create_sub_bitmap(BITMAP *parent, int x, int y, int width, int height);
+BITMAP *create_video_bitmap(int width, int height);
+BITMAP *create_system_bitmap(int width, int height);
+void destroy_bitmap(BITMAP *bitmap);
+
+} // namespace AGS3
+
+#endif
diff --git a/engines/ags/module.mk b/engines/ags/module.mk
index 23bff060d5..9e571bf333 100644
--- a/engines/ags/module.mk
+++ b/engines/ags/module.mk
@@ -24,6 +24,7 @@ MODULE_OBJS = \
 	lib/allegro/keyboard.o \
 	lib/allegro/math.o \
 	lib/allegro/mouse.o \
+	lib/allegro/surface.o \
 	lib/allegro/system.o \
 	lib/allegro/unicode.o \
 	lib/hq2x/hq2x3x.o \




More information about the Scummvm-git-logs mailing list