void Frame::drawMatteSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect) { // Like background trans, but all white pixels NOT ENCLOSED by coloured pixels are transparent Graphics::Surface tmp; tmp.copyFrom(sprite); // Searching white color in the corners int whiteColor = -1; for (int corner = 0; corner < 4; corner++) { int x = (corner & 0x1) ? tmp.w - 1 : 0; int y = (corner & 0x2) ? tmp.h - 1 : 0; byte color = *(byte *)tmp.getBasePtr(x, y); if (_vm->getPalette()[color * 3 + 0] == 0xff && _vm->getPalette()[color * 3 + 1] == 0xff && _vm->getPalette()[color * 3 + 2] == 0xff) { whiteColor = color; break; } } if (whiteColor == -1) { debugC(1, kDebugImages, "No white color for Matte image"); for (int yy = 0; yy < tmp.h; yy++) { const byte *src = (const byte *)tmp.getBasePtr(0, yy); byte *dst = (byte *)target.getBasePtr(drawRect.left, drawRect.top + yy); for (int xx = 0; xx < drawRect.width(); xx++, src++, dst++) *dst = *src; } } else { Graphics::FloodFill ff(&tmp, whiteColor, 0, true); for (int yy = 0; yy < tmp.h; yy++) { ff.addSeed(0, yy); ff.addSeed(tmp.w - 1, yy); } for (int xx = 0; xx < tmp.w; xx++) { ff.addSeed(xx, 0); ff.addSeed(xx, tmp.h - 1); } ff.fillMask(); for (int yy = 0; yy < tmp.h; yy++) { const byte *src = (const byte *)tmp.getBasePtr(0, yy); const byte *mask = (const byte *)ff.getMask()->getBasePtr(0, yy); byte *dst = (byte *)target.getBasePtr(drawRect.left, drawRect.top + yy); for (int xx = 0; xx < drawRect.width(); xx++, src++, dst++, mask++) if (*mask == 0) *dst = *src; } } tmp.free(); }
static void drawPixelInverted(int x, int y, int color, void *data) { Graphics::ManagedSurface *surface = (Graphics::ManagedSurface *)data; if (x >= 0 && x < surface->w && y >= 0 && y < surface->h) { byte *p = (byte *)surface->getBasePtr(x, y); *p = *p == kColorWhite ? kColorBlack : kColorWhite; } }
void Frame::drawGhostSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect) { uint8 skipColor = _vm->getPaletteColorCount() - 1; for (int ii = 0; ii < sprite.h; ii++) { const byte *src = (const byte *)sprite.getBasePtr(0, ii); byte *dst = (byte *)target.getBasePtr(drawRect.left, drawRect.top + ii); for (int j = 0; j < drawRect.width(); j++) { if ((getSpriteIDFromPos(Common::Point(drawRect.left + j, drawRect.top + ii)) != 0) && (*src != skipColor)) *dst = (_vm->getPaletteColorCount() - 1) - *src; //Oposite color src++; dst++; } } }
void Frame::drawBackgndTransSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect) { uint8 skipColor = _vm->getPaletteColorCount() - 1; //FIXME is it always white (last entry in pallette) ? for (int ii = 0; ii < sprite.h; ii++) { const byte *src = (const byte *)sprite.getBasePtr(0, ii); byte *dst = (byte *)target.getBasePtr(drawRect.left, drawRect.top + ii); for (int j = 0; j < drawRect.width(); j++) { if (*src != skipColor) *dst = *src; src++; dst++; } } }
void AVISurface::copyMovieFrame(const Graphics::Surface &src, Graphics::ManagedSurface &dest) { // WORKAROUND: Handle rare cases where frame sizes don't match the video size Common::Rect copyRect(0, 0, MIN(src.w, dest.w), MIN(src.h, dest.h)); if (src.format.bytesPerPixel == 1) { // Paletted 8-bit, so convert to 16-bit and copy over const byte *palette = _decoder->getPalette(); if (palette) { Graphics::Surface *s = src.convertTo(dest.format, palette); dest.blitFrom(*s, copyRect, Common::Point(0, 0)); s->free(); delete s; } } else if (src.format.bytesPerPixel == 2) { // Source is already 16-bit, with no alpha, so do a straight copy dest.blitFrom(src, copyRect, Common::Point(0, 0)); } else { // Source is 32-bit which may have transparent pixels. Copy over each // pixel, replacing transparent pixels with the special transparency color byte a, r, g, b; assert(src.format.bytesPerPixel == 4 && dest.format.bytesPerPixel == 2); uint16 transPixel = _videoSurface->getTransparencyColor(); for (uint y = 0; y < MIN(src.h, dest.h); ++y) { const uint32 *pSrc = (const uint32 *)src.getBasePtr(0, y); uint16 *pDest = (uint16 *)dest.getBasePtr(0, y); for (uint x = 0; x < MIN(src.w, dest.w); ++x, ++pSrc, ++pDest) { src.format.colorToARGB(*pSrc, a, r, g, b); assert(a == 0 || a == 0xff); *pDest = (a == 0) ? transPixel : dest.format.RGBToColor(r, g, b); } } } }
void Design::drawBitmap(Graphics::ManagedSurface *surface, Common::SeekableReadStream &in) { int numBytes = in.readSint16BE(); int y1 = in.readSint16BE(); int x1 = in.readSint16BE(); int y2 = in.readSint16BE(); int x2 = in.readSint16BE(); int w = x2 - x1; int h = y2 - y1; Graphics::ManagedSurface tmp; tmp.create(w, h, Graphics::PixelFormat::createFormatCLUT8()); numBytes -= 10; int x = 0, y = 0; while (numBytes > 0 && y < h) { int n = in.readSByte(); int count; int b = 0; int state = 0; numBytes--; if ((n >= 0) && (n <= 127)) { // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. count = n + 1; state = 1; } else if ((n >= -127) && (n <= -1)) { // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. b = in.readByte(); numBytes--; count = -n + 1; state = 2; } else { // Else if n is -128, noop. count = 0; } for (int i = 0; i < count && y < h; i++) { byte color = 0; if (state == 1) { color = in.readByte(); numBytes--; } else if (state == 2) color = b; for (int c = 0; c < 8; c++) { if (_boundsCalculationMode) { adjustBounds(x1 + x, y1 + y); } else if (x1 + x >= 0 && x1 + x < surface->w && y1 + y >= 0 && y1 + y < surface->h) *((byte *)tmp.getBasePtr(x, y)) = (color & (1 << (7 - c % 8))) ? kColorBlack : kColorWhite; x++; if (x == w) { y++; x = 0; break; } } } } in.skip(numBytes); if (_boundsCalculationMode) return; FloodFill ff(&tmp, kColorWhite, kColorGreen); for (int yy = 0; yy < h; yy++) { ff.addSeed(0, yy); ff.addSeed(w - 1, yy); } for (int xx = 0; xx < w; xx++) { ff.addSeed(xx, 0); ff.addSeed(xx, h - 1); } ff.fill(); for (y = 0; y < h && y1 + y < surface->h; y++) { byte *src = (byte *)tmp.getBasePtr(0, y); byte *dst = (byte *)surface->getBasePtr(x1, y1 + y); for (x = 0; x < w; x++) { if (*src != kColorGreen) *dst = *src; src++; dst++; } } tmp.free(); }