[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