aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorEinar Johan Trøan Sømåen2013-08-20 18:00:17 +0200
committerEinar Johan Trøan Sømåen2013-08-20 18:00:17 +0200
commitea19c4162d24d6bf32246671aa5fab285ca7ad39 (patch)
treec68e7abd03d4e95c95d10eed3696bce9150ba03e /engines
parente824ebaa44a2b6c97fd98e404588e72f520e53a7 (diff)
downloadscummvm-rg350-ea19c4162d24d6bf32246671aa5fab285ca7ad39.tar.gz
scummvm-rg350-ea19c4162d24d6bf32246671aa5fab285ca7ad39.tar.bz2
scummvm-rg350-ea19c4162d24d6bf32246671aa5fab285ca7ad39.zip
WINTERMUTE: Add binary alpha-blitting.
For now, no RLE, or anything, but the infrastructure for it is put in place here.
Diffstat (limited to 'engines')
-rw-r--r--engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp18
-rw-r--r--engines/wintermute/base/gfx/osystem/base_surface_osystem.h4
-rw-r--r--engines/wintermute/base/gfx/osystem/render_ticket.cpp17
-rw-r--r--engines/wintermute/graphics/transform_struct.h6
-rw-r--r--engines/wintermute/graphics/transparent_surface.cpp41
-rw-r--r--engines/wintermute/graphics/transparent_surface.h8
6 files changed, 71 insertions, 23 deletions
diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
index aed0129b3a..6506abd29c 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
@@ -48,7 +48,7 @@ namespace Wintermute {
BaseSurfaceOSystem::BaseSurfaceOSystem(BaseGame *inGame) : BaseSurface(inGame) {
_surface = new Graphics::Surface();
_alphaMask = nullptr;
- _alphaType = ALPHA_FULL;
+ _alphaType = TransparentSurface::ALPHA_FULL;
_lockPixels = nullptr;
_lockPitch = 0;
_loaded = false;
@@ -71,10 +71,10 @@ BaseSurfaceOSystem::~BaseSurfaceOSystem() {
renderer->invalidateTicketsFromSurface(this);
}
-AlphaType hasTransparencyType(const Graphics::Surface *surf) {
+TransparentSurface::AlphaType hasTransparencyType(const Graphics::Surface *surf) {
if (surf->format.bytesPerPixel != 4) {
warning("hasTransparencyType:: non 32 bpp surface passed as argument");
- return ALPHA_OPAQUE;
+ return TransparentSurface::ALPHA_OPAQUE;
}
uint8 r, g, b, a;
bool seenAlpha = false;
@@ -96,11 +96,11 @@ AlphaType hasTransparencyType(const Graphics::Surface *surf) {
}
}
if (seenFullAlpha) {
- return ALPHA_FULL;
+ return TransparentSurface::ALPHA_FULL;
} else if (seenAlpha) {
- return ALPHA_BINARY;
+ return TransparentSurface::ALPHA_BINARY;
} else {
- return ALPHA_OPAQUE;
+ return TransparentSurface::ALPHA_OPAQUE;
}
}
@@ -438,7 +438,7 @@ bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect,
// But no checking is in place for that yet.
// Optimize by not doing alpha-blits if we lack alpha
- if (_alphaType == ALPHA_OPAQUE && !transform._alphaDisable) {
+ if (_alphaType == TransparentSurface::ALPHA_OPAQUE && !transform._alphaDisable) {
transform._alphaDisable = true;
}
@@ -457,9 +457,9 @@ bool BaseSurfaceOSystem::putSurface(const Graphics::Surface &surface, bool hasAl
_surface->free();
_surface->copyFrom(surface);
if (hasAlpha) {
- _alphaType = ALPHA_FULL;
+ _alphaType = TransparentSurface::ALPHA_FULL;
} else {
- _alphaType = ALPHA_OPAQUE;
+ _alphaType = TransparentSurface::ALPHA_OPAQUE;
}
BaseRenderOSystem *renderer = static_cast<BaseRenderOSystem *>(_gameRef->_renderer);
renderer->invalidateTicketsFromSurface(this);
diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.h b/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
index ad1e9cf737..6cf19d00fb 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
@@ -30,6 +30,7 @@
#define WINTERMUTE_BASE_SURFACESDL_H
#include "graphics/surface.h"
+#include "engines/wintermute/graphics/transparent_surface.h"
#include "engines/wintermute/base/gfx/base_surface.h"
#include "common/list.h"
@@ -81,6 +82,7 @@ public:
return _height;
}
+ TransparentSurface::AlphaType getAlphaType() const { return _alphaType; }
private:
Graphics::Surface *_surface;
bool _loaded;
@@ -90,7 +92,7 @@ private:
uint32 getPixelAt(Graphics::Surface *surface, int x, int y);
uint32 _rotation;
- AlphaType _alphaType;
+ TransparentSurface::AlphaType _alphaType;
void *_lockPixels;
int _lockPitch;
byte *_alphaMask;
diff --git a/engines/wintermute/base/gfx/osystem/render_ticket.cpp b/engines/wintermute/base/gfx/osystem/render_ticket.cpp
index 98739e0778..b1720c1b0b 100644
--- a/engines/wintermute/base/gfx/osystem/render_ticket.cpp
+++ b/engines/wintermute/base/gfx/osystem/render_ticket.cpp
@@ -28,6 +28,7 @@
#include "engines/wintermute/base/gfx/osystem/render_ticket.h"
+#include "engines/wintermute/base/gfx/osystem/base_surface_osystem.h"
#include "engines/wintermute/graphics/transform_tools.h"
#include "common/textconsole.h"
@@ -104,7 +105,13 @@ void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface) const {
clipRect.setWidth(getSurface()->w);
clipRect.setHeight(getSurface()->h);
- src._enableAlphaBlit = !_transform._alphaDisable;
+ if (_owner) {
+ if (_transform._alphaDisable) {
+ src._alphaMode = TransparentSurface::ALPHA_OPAQUE;
+ } else {
+ src._alphaMode = _owner->getAlphaType();
+ }
+ }
src.blit(*_targetSurface, _dstRect.left, _dstRect.top, _transform._flip, &clipRect, _transform._rgbaMod, clipRect.width(), clipRect.height());
}
@@ -118,7 +125,13 @@ void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface, Common::Rect
clipRect->setHeight(getSurface()->h);
}
- src._enableAlphaBlit = !_transform._alphaDisable;
+ if (_owner) {
+ if (_transform._alphaDisable) {
+ src._alphaMode = TransparentSurface::ALPHA_OPAQUE;
+ } else {
+ src._alphaMode = _owner->getAlphaType();
+ }
+ }
src.blit(*_targetSurface, dstRect->left, dstRect->top, _transform._flip, clipRect, _transform._rgbaMod, clipRect->width(), clipRect->height());
if (doDelete) {
delete clipRect;
diff --git a/engines/wintermute/graphics/transform_struct.h b/engines/wintermute/graphics/transform_struct.h
index f4f97d1ea9..a54c4cc5d0 100644
--- a/engines/wintermute/graphics/transform_struct.h
+++ b/engines/wintermute/graphics/transform_struct.h
@@ -42,12 +42,6 @@ const int32 kDefaultOffsetX = 0;
const int32 kDefaultOffsetY = 0;
const int32 kDefaultAngle = 0;
-enum AlphaType {
- ALPHA_OPAQUE = 0,
- ALPHA_BINARY = 1,
- ALPHA_FULL = 2
-};
-
struct TransformStruct {
private:
void init(Point32 zoom, uint32 angle, Point32 hotspot, bool alphaDisable, TSpriteBlendMode blendMode, uint32 alpha, bool mirrorX, bool mirrorY, Point32 offset);
diff --git a/engines/wintermute/graphics/transparent_surface.cpp b/engines/wintermute/graphics/transparent_surface.cpp
index 9539b68c85..249d30f7d9 100644
--- a/engines/wintermute/graphics/transparent_surface.cpp
+++ b/engines/wintermute/graphics/transparent_surface.cpp
@@ -140,9 +140,9 @@ void TransparentSurface::copyPixelNearestNeighbor(float projX, float projY, int
}
#endif
-TransparentSurface::TransparentSurface() : Surface(), _enableAlphaBlit(true) {}
+TransparentSurface::TransparentSurface() : Surface(), _alphaMode(ALPHA_FULL) {}
-TransparentSurface::TransparentSurface(const Surface &surf, bool copyData) : Surface(), _enableAlphaBlit(true) {
+TransparentSurface::TransparentSurface(const Surface &surf, bool copyData) : Surface(), _alphaMode(ALPHA_FULL) {
if (copyData) {
copyFrom(surf);
} else {
@@ -179,6 +179,37 @@ void doBlitOpaque(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pit
}
}
+void doBlitBinary(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
+ byte *in, *out;
+
+#ifdef SCUMM_LITTLE_ENDIAN
+ const int aIndex = 0;
+#else
+ const int aIndex = 3;
+#endif
+ const int aShift = 0;//img->format.aShift;
+
+ for (uint32 i = 0; i < height; i++) {
+ out = outo;
+ in = ino;
+ for (uint32 j = 0; j < width; j++) {
+ uint32 pix = *(uint32 *)in;
+ int a = (pix >> aShift) & 0xff;
+ in += inStep;
+
+ if (a == 0) { // Full transparency
+ out += 4;
+ } else { // Full opacity (Any value not exactly 0 is Opaque here)
+ *(uint32 *)out = pix;
+ out[aIndex] = 0xFF;
+ out += 4;
+ }
+ }
+ outo += pitch;
+ ino += inoStep;
+ }
+}
+
void doBlitAlpha(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
byte *in, *out;
@@ -388,9 +419,11 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
const int rShiftTarget = 24;//target.format.rShift;
if (ca == 255 && cb == 255 && cg == 255 && cr == 255) {
- if (_enableAlphaBlit) {
+ if (_alphaMode == ALPHA_FULL) {
doBlitAlpha(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
- } else {
+ } else if (_alphaMode == ALPHA_BINARY) {
+ doBlitBinary(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
+ } else if (_alphaMode == ALPHA_OPAQUE) {
doBlitOpaque(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
}
} else {
diff --git a/engines/wintermute/graphics/transparent_surface.h b/engines/wintermute/graphics/transparent_surface.h
index 828c4dd9a9..598aaa55d7 100644
--- a/engines/wintermute/graphics/transparent_surface.h
+++ b/engines/wintermute/graphics/transparent_surface.h
@@ -75,7 +75,13 @@ struct TransparentSurface : public Graphics::Surface {
FLIP_VH = FLIP_H | FLIP_V
};
- bool _enableAlphaBlit;
+ enum AlphaType {
+ ALPHA_OPAQUE = 0,
+ ALPHA_BINARY = 1,
+ ALPHA_FULL = 2
+ };
+
+ AlphaType _alphaMode;
/**
@brief renders the surface to another surface