diff options
Diffstat (limited to 'engines/wintermute/graphics/transparent_surface.cpp')
-rw-r--r-- | engines/wintermute/graphics/transparent_surface.cpp | 213 |
1 files changed, 106 insertions, 107 deletions
diff --git a/engines/wintermute/graphics/transparent_surface.cpp b/engines/wintermute/graphics/transparent_surface.cpp index 53380a2d55..df6286e37a 100644 --- a/engines/wintermute/graphics/transparent_surface.cpp +++ b/engines/wintermute/graphics/transparent_surface.cpp @@ -34,112 +34,111 @@ namespace Wintermute { #if ENABLE_BILINEAR void TransparentSurface::copyPixelBilinear(float projX, float projY, int dstX, int dstY, const Common::Rect &srcRect, const Common::Rect &dstRect, const TransparentSurface *src, TransparentSurface *dst) { + int srcW = srcRect.width(); + int srcH = srcRect.height(); + int dstW = dstRect.width(); + int dstH = dstRect.height(); - int srcW = srcRect.width(); - int srcH = srcRect.height(); - int dstW = dstRect.width(); - int dstH = dstRect.height(); + assert(dstX >= 0 && dstX < dstW); + assert(dstY >= 0 && dstY < dstH); - assert(dstX >= 0 && dstX < dstW); - assert(dstY >= 0 && dstY < dstH); + float x1 = floor(projX); + float x2 = ceil(projX); + float y1 = floor(projY); + float y2 = ceil(projY); - float x1 = floor(projX); - float x2 = ceil(projX); - float y1 = floor(projY); - float y2 = ceil(projY); + uint32 Q11, Q12, Q21, Q22; - uint32 Q11, Q12, Q21, Q22; + if (x1 >= srcW || x1 < 0 || y1 >= srcH || y1 < 0) { + Q11 = 0; + } else { + Q11 = READ_UINT32((const byte *)src->getBasePtr((int)(x1 + srcRect.left), (int)(y1 + srcRect.top))); + } - if (x1 >= srcW || x1 < 0 || y1 >= srcH || y1 < 0) { - Q11 = 0; - } else { - Q11 = READ_UINT32((const byte *)src->getBasePtr((int)(x1 + srcRect.left),(int)(y1 + srcRect.top))); - } + if (x1 >= srcW || x1 < 0 || y2 >= srcH || y2 < 0) { + Q12 = 0; + } else { + Q12 = READ_UINT32((const byte *)src->getBasePtr((int)(x1 + srcRect.left), (int)(y2 + srcRect.top))); + } - if (x1 >= srcW || x1 < 0 || y2 >= srcH || y2 < 0) { - Q12 = 0; - } else { - Q12 = READ_UINT32((const byte *)src->getBasePtr((int)(x1 + srcRect.left), (int)(y2 + srcRect.top))); - } + if (x2 >= srcW || x2 < 0 || y1 >= srcH || y1 < 0) { + Q21 = 0; + } else { + Q21 = READ_UINT32((const byte *)src->getBasePtr((int)(x2 + srcRect.left), (int)(y1 + srcRect.top))); + } - if (x2 >= srcW || x2 < 0 || y1 >= srcH || y1 < 0) { - Q21 = 0; - } else { - Q21 = READ_UINT32((const byte *)src->getBasePtr((int)(x2 + srcRect.left), (int)(y1 + srcRect.top))); - } + if (x2 >= srcW || x2 < 0 || y2 >= srcH || y2 < 0) { + Q22 = 0; + } else { + Q22 = READ_UINT32((const byte *)src->getBasePtr((int)(x2 + srcRect.left), (int)(y2 + srcRect.top))); + } - if (x2 >= srcW || x2 < 0 || y2 >= srcH || y2 < 0) { - Q22 = 0; - } else { - Q22 = READ_UINT32((const byte *)src->getBasePtr((int)(x2 + srcRect.left), (int)(y2 + srcRect.top))); - } + byte *Q11s = (byte *)&Q11; + byte *Q12s = (byte *)&Q12; + byte *Q21s = (byte *)&Q21; + byte *Q22s = (byte *)&Q22; - byte *Q11s = (byte *)&Q11; - byte *Q12s = (byte *)&Q12; - byte *Q21s = (byte *)&Q21; - byte *Q22s = (byte *)&Q22; - - uint32 color; - byte *dest = (byte *)&color; - - float q11x = (x2 - projX); - float q11y = (y2 - projY); - float q21x = (projX - x1); - float q21y = (y2 - projY); - float q12x = (x2 - projX); - float q12y = (projY - y1); - - if (x1 == x2 && y1 == y2) { - for (int c = 0; c < 4; c++) { - dest[c] = ((float)Q11s[c]); - } - } else { + uint32 color; + byte *dest = (byte *)&color; - if (x1 == x2) { - q11x = 0.5; - q12x = 0.5; - q21x = 0.5; - } else if (y1 == y2) { - q11y = 0.5; - q12y = 0.5; - q21y = 0.5; - } - - for (int c = 0; c < 4; c++) { - dest[c] = (byte)( - ((float)Q11s[c]) * q11x * q11y + - ((float)Q21s[c]) * q21x * q21y + - ((float)Q12s[c]) * q12x * q12y + - ((float)Q22s[c]) * (1.0 - - q11x * q11y - - q21x * q21y - - q12x * q12y) - ); - } - } - WRITE_UINT32((byte *)dst->getBasePtr(dstX + dstRect.left, dstY + dstRect.top), color); + float q11x = (x2 - projX); + float q11y = (y2 - projY); + float q21x = (projX - x1); + float q21y = (y2 - projY); + float q12x = (x2 - projX); + float q12y = (projY - y1); + + if (x1 == x2 && y1 == y2) { + for (int c = 0; c < 4; c++) { + dest[c] = ((float)Q11s[c]); + } + } else { + + if (x1 == x2) { + q11x = 0.5; + q12x = 0.5; + q21x = 0.5; + } else if (y1 == y2) { + q11y = 0.5; + q12y = 0.5; + q21y = 0.5; + } + + for (int c = 0; c < 4; c++) { + dest[c] = (byte)( + ((float)Q11s[c]) * q11x * q11y + + ((float)Q21s[c]) * q21x * q21y + + ((float)Q12s[c]) * q12x * q12y + + ((float)Q22s[c]) * (1.0 - + q11x * q11y - + q21x * q21y - + q12x * q12y) + ); + } + } + WRITE_UINT32((byte *)dst->getBasePtr(dstX + dstRect.left, dstY + dstRect.top), color); } #else void TransparentSurface::copyPixelNearestNeighbor(float projX, float projY, int dstX, int dstY, const Common::Rect &srcRect, const Common::Rect &dstRect, const TransparentSurface *src, TransparentSurface *dst) { - int srcW = srcRect.width(); - int srcH = srcRect.height(); - int dstW = dstRect.width(); - int dstH = dstRect.height(); - - assert(dstX >= 0 && dstX < dstW); - assert(dstY >= 0 && dstY < dstH); - - uint32 color; - - if (projX >= srcW || projX < 0 || projY >= srcH || projY < 0) { - color = 0; - } else { - color = READ_UINT32((const byte *)src->getBasePtr((int)projX, (int)projY)); - } + int srcW = srcRect.width(); + int srcH = srcRect.height(); + int dstW = dstRect.width(); + int dstH = dstRect.height(); + + assert(dstX >= 0 && dstX < dstW); + assert(dstY >= 0 && dstY < dstH); + + uint32 color; + + if (projX >= srcW || projX < 0 || projY >= srcH || projY < 0) { + color = 0; + } else { + color = READ_UINT32((const byte *)src->getBasePtr((int)projX, (int)projY)); + } - WRITE_UINT32((byte *)dst->getBasePtr(dstX, dstY), color); + WRITE_UINT32((byte *)dst->getBasePtr(dstX, dstY), color); } -#endif +#endif byte *TransparentSurface::_lookup = nullptr; @@ -165,7 +164,7 @@ TransparentSurface::TransparentSurface(const Surface &surf, bool copyData) : Sur } } -void doBlitOpaque(byte *ino, byte* outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) { +void doBlitOpaque(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) { byte *in, *out; #ifdef SCUMM_LITTLE_ENDIAN @@ -196,7 +195,7 @@ void TransparentSurface::generateLookup() { } } -void TransparentSurface::doBlitAlpha(byte *ino, byte* outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) { +void TransparentSurface::doBlitAlpha(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) { byte *in, *out; if (!_lookup) { @@ -315,11 +314,11 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p srcImage.h = pPartRect->height(); debug(6, "Blit(%d, %d, %d, [%d, %d, %d, %d], %08x, %d, %d)", posX, posY, flipping, - pPartRect->left, pPartRect->top, pPartRect->width(), pPartRect->height(), color, width, height); + pPartRect->left, pPartRect->top, pPartRect->width(), pPartRect->height(), color, width, height); } else { debug(6, "Blit(%d, %d, %d, [%d, %d, %d, %d], %08x, %d, %d)", posX, posY, flipping, 0, 0, - srcImage.w, srcImage.h, color, width, height); + srcImage.w, srcImage.h, color, width, height); } if (width == -1) @@ -499,12 +498,12 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p } TransparentSurface *TransparentSurface::rotoscale(const TransformStruct &transform) const { - + assert(transform._angle != 0); // This would not be ideal; rotoscale() should never be called in conditional branches where angle = 0 anyway. Point32 newHotspot; Common::Rect srcRect(0, 0, (int16)w, (int16)h); - Rect32 rect = TransformTools::newRect(Rect32 (srcRect), transform, &newHotspot); + Rect32 rect = TransformTools::newRect(Rect32(srcRect), transform, &newHotspot); Common::Rect dstRect(0, 0, (int16)(rect.right - rect.left), (int16)(rect.bottom - rect.top)); TransparentSurface *target = new TransparentSurface(); @@ -526,16 +525,16 @@ TransparentSurface *TransparentSurface::rotoscale(const TransformStruct &transfo int x1 = x - newHotspot.x; int y1 = y - newHotspot.y; - targX = ((x1 * invCos - y1 * invSin)) * kDefaultZoomX / transform._zoom.x + srcRect.left; - targY = ((x1 * invSin + y1 * invCos)) * kDefaultZoomY / transform._zoom.y + srcRect.top; - + targX = ((x1 * invCos - y1 * invSin)) * kDefaultZoomX / transform._zoom.x + srcRect.left; + targY = ((x1 * invSin + y1 * invCos)) * kDefaultZoomY / transform._zoom.y + srcRect.top; + targX += transform._hotspot.x; targY += transform._hotspot.y; - + #if ENABLE_BILINEAR - copyPixelBilinear(targX, targY, x, y, srcRect, dstRect, this, target); + copyPixelBilinear(targX, targY, x, y, srcRect, dstRect, this, target); #else - copyPixelNearestNeighbor(targX, targY, x, y, srcRect, dstRect, this, target); + copyPixelNearestNeighbor(targX, targY, x, y, srcRect, dstRect, this, target); #endif } } @@ -545,7 +544,7 @@ TransparentSurface *TransparentSurface::rotoscale(const TransformStruct &transfo TransparentSurface *TransparentSurface::scale(uint16 newWidth, uint16 newHeight) const { Common::Rect srcRect(0, 0, (int16)w, (int16)h); Common::Rect dstRect(0, 0, (int16)newWidth, (int16)newHeight); - + TransparentSurface *target = new TransparentSurface(); assert(format.bytesPerPixel == 4); @@ -565,9 +564,9 @@ TransparentSurface *TransparentSurface::scale(uint16 newWidth, uint16 newHeight) projX = x / (float)dstW * srcW; projY = y / (float)dstH * srcH; #if ENABLE_BILINEAR - copyPixelBilinear(projX, projY, x, y, srcRect, dstRect, this, target); + copyPixelBilinear(projX, projY, x, y, srcRect, dstRect, this, target); #else - copyPixelNearestNeighbor(projX, projY, x, y, srcRect, dstRect, this, target); + copyPixelNearestNeighbor(projX, projY, x, y, srcRect, dstRect, this, target); #endif } } @@ -600,4 +599,4 @@ void TransparentSurface::applyColorKey(uint8 rKey, uint8 gKey, uint8 bKey, bool } } -} // End of namespace Graphics +} // End of namespace Wintermute |