[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