Example #1
0
void Frame::renderButton(Graphics::ManagedSurface &surface, uint16 spriteId) {
	renderText(surface, spriteId);

	uint16 castID = _sprites[spriteId]->_castId;
	ButtonCast *button = static_cast<ButtonCast *>(_vm->_currentScore->_casts[castID]);

	uint32 rectLeft = button->initialRect.left;
	uint32 rectTop = button->initialRect.top;

	int x = _sprites[spriteId]->_startPoint.x + rectLeft;
	int y = _sprites[spriteId]->_startPoint.y + rectTop;
	int height = _sprites[spriteId]->_height;
	int width = _sprites[spriteId]->_width;

	switch (button->buttonType) {
	case kTypeCheckBox:
		//Magic numbers: checkbox square need to move left about 5px from text and 12px side size (d4)
		surface.frameRect(Common::Rect(x - 17, y, x + 12, y + 12), 0);
		break;
	case kTypeButton:
		surface.frameRect(Common::Rect(x, y, x + width, y + height), 0);
		break;
	case kTypeRadio:
		warning("STUB: renderButton: kTypeRadio");
		break;
	}
}
Example #2
0
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();
}
Example #3
0
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;
	}
}
Example #4
0
Graphics::ManagedSurface *AVISurface::duplicateTransparency() const {
	if (_streamCount <= 1) {
		return nullptr;
	} else {
		Graphics::ManagedSurface *dest = new Graphics::ManagedSurface(_movieFrameSurface[1]->w,
			_movieFrameSurface[1]->h, Graphics::PixelFormat::createFormatCLUT8());
		dest->blitFrom(*_movieFrameSurface[1]);
		return dest;
	}
}
Example #5
0
Graphics::ManagedSurface *AVISurface::duplicateSecondaryFrame() const {
	if (_streamCount <= 1) {
		return nullptr;
	} else {
		Graphics::ManagedSurface *dest = new Graphics::ManagedSurface(_movieFrameSurface[1]->w,
			_movieFrameSurface[1]->h, _movieFrameSurface[1]->format);
		dest->blitFrom(*_movieFrameSurface[1]);
		return dest;
	}
}
Example #6
0
void CommandButton::draw(Graphics::ManagedSurface &surface) const {

	uint colorFill = _selected ? kColorBlack : kColorWhite;
	uint colorText = _selected ? kColorWhite : kColorBlack;

	surface.fillRect(_data.bounds, colorFill);
	surface.frameRect(_data.bounds, kColorBlack);

	if (_data.titleLength > 0) {
		const Graphics::Font &font = _gui->getCurrentFont();
		Common::String title(_data.title);
		font.drawString(
			&surface,
			title,
			_data.bounds.left,
			_data.bounds.top,
			_data.bounds.right - _data.bounds.left,
			colorText,
			Graphics::kTextAlignCenter);
	}
}
Example #7
0
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++;
		}
	}
}
Example #8
0
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);
			}
		}
	}
}
Example #9
0
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++;
		}
	}
}
Example #10
0
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();
}
Example #11
0
void Frame::renderText(Graphics::ManagedSurface &surface, uint16 spriteID) {
	uint16 castID = _sprites[spriteID]->_castId;

	TextCast *textCast = static_cast<TextCast *>(_vm->_currentScore->_casts[castID]);
	Common::SeekableSubReadStreamEndian *textStream;

	if (_vm->_currentScore->_movieArchive->hasResource(MKTAG('S','T','X','T'), castID + 1024)) {
		textStream = _vm->_currentScore->_movieArchive->getResource(MKTAG('S','T','X','T'), castID + 1024);
	} else {
		textStream = _vm->getSharedSTXT()->getVal(spriteID + 1024);
	}
	/*uint32 unk1 = */ textStream->readUint32();
	uint32 strLen = textStream->readUint32();
	/*uin32 dataLen = */ textStream->readUint32();
	Common::String text;

	for (uint32 i = 0; i < strLen; i++) {
		byte ch = textStream->readByte();
		if (ch == 0x0d) {
			ch = '\n';
		}
		text += ch;
	}

	uint32 rectLeft = static_cast<TextCast *>(_sprites[spriteID]->_cast)->initialRect.left;
	uint32 rectTop = static_cast<TextCast *>(_sprites[spriteID]->_cast)->initialRect.top;

	int x = _sprites[spriteID]->_startPoint.x + rectLeft;
	int y = _sprites[spriteID]->_startPoint.y + rectTop;
	int height = _sprites[spriteID]->_height;
	int width = _sprites[spriteID]->_width;

	const char *fontName;

	if (_vm->_currentScore->_fontMap.contains(textCast->fontId)) {
		fontName = _vm->_currentScore->_fontMap[textCast->fontId].c_str();
	} else if ((fontName = _vm->_wm->getFontName(textCast->fontId, textCast->fontSize)) == NULL) {
		warning("Unknown font id %d, falling back to default", textCast->fontId);
		fontName = _vm->_wm->getFontName(0, 12);
	}

	const Graphics::Font *font = _vm->_wm->getFont(fontName, Graphics::FontManager::kBigGUIFont);

	font->drawString(&surface, text, x, y, width, 0);

	if (textCast->borderSize != kSizeNone) {
		uint16 size = textCast->borderSize;

		//Indent from borders, measured in d4
		x -= 1;
		y -= 4;

		height += 4;
		width += 1;

		while (size) {
			surface.frameRect(Common::Rect(x, y, x + height, y + width), 0);
			x--;
			y--;
			height += 2;
			width += 2;
			size--;
		}
	}

	if (textCast->gutterSize != kSizeNone) {
		x -= 1;
		y -= 4;

		height += 4;
		width += 1;
		uint16 size = textCast->gutterSize;

		surface.frameRect(Common::Rect(x, y, x + height, y + width), 0);

		while (size) {
			surface.drawLine(x + width, y, x + width, y + height, 0);
			surface.drawLine(x, y + height, x + width, y + height, 0);
			x++;
			y++;
			size--;
		}
	}
}
Example #12
0
void Frame::renderSprites(Graphics::ManagedSurface &surface, bool renderTrail) {
	for (uint16 i = 0; i < CHANNEL_COUNT; i++) {
		if (_sprites[i]->_enabled) {
			if ((_sprites[i]->_trails == 0 && renderTrail) || (_sprites[i]->_trails == 1 && !renderTrail))
				continue;

			Cast *cast;
			if (!_vm->_currentScore->_casts.contains(_sprites[i]->_castId)) {
				if (!_vm->getSharedCasts()->contains(_sprites[i]->_castId)) {
					warning("Cast id %d not found", _sprites[i]->_castId);
					continue;
				} else {
					cast = _vm->getSharedCasts()->getVal(_sprites[i]->_castId);
				}
			} else {
				cast = _vm->_currentScore->_casts[_sprites[i]->_castId];
			}

			if (cast->type == kCastText) {
				renderText(surface, i);
				continue;
			}

			Image::ImageDecoder *img = getImageFrom(_sprites[i]->_castId);

			if (!img) {
				warning("Image with id %d not found", _sprites[i]->_castId);
				continue;
			}

			if (!img->getSurface()) {
				//TODO
				//BMPDecoder doesnt cover all BITD resources (not all have first two bytes 'BM')
				//Some BITD's first two bytes 0x6 0x0
				warning("Can not load image %d", _sprites[i]->_castId);
				continue;
			}

			uint32 regX = static_cast<BitmapCast *>(_sprites[i]->_cast)->regX;
			uint32 regY = static_cast<BitmapCast *>(_sprites[i]->_cast)->regY;
			uint32 rectLeft = static_cast<BitmapCast *>(_sprites[i]->_cast)->initialRect.left;
			uint32 rectTop = static_cast<BitmapCast *>(_sprites[i]->_cast)->initialRect.top;

			int x = _sprites[i]->_startPoint.x - regX + rectLeft;
			int y = _sprites[i]->_startPoint.y - regY + rectTop;
			int height = _sprites[i]->_height;
			int width = _sprites[i]->_width;

			Common::Rect drawRect = Common::Rect(x, y, x + width, y + height);
			_drawRects.push_back(drawRect);

			switch (_sprites[i]->_ink) {
			case kInkTypeCopy:
				surface.blitFrom(*img->getSurface(), Common::Point(x, y));
				break;
			case kInkTypeTransparent:
				//FIXME: is it always white (last entry in pallette)?
				surface.transBlitFrom(*img->getSurface(), Common::Point(x, y), _vm->getPaletteColorCount() - 1);
				break;
			case kInkTypeBackgndTrans:
				drawBackgndTransSprite(surface, *img->getSurface(), drawRect);
				break;
			case kInkTypeMatte:
				drawMatteSprite(surface, *img->getSurface(), drawRect);
				break;
			case kInkTypeGhost:
				drawGhostSprite(surface, *img->getSurface(), drawRect);
				break;
			case kInkTypeReverse:
				drawReverseSprite(surface, *img->getSurface(), drawRect);
				break;
			default:
				warning("Unhandled ink type %d", _sprites[i]->_ink);
				surface.blitFrom(*img->getSurface(), Common::Point(x, y));
				break;
			}
		}
	}
}
Example #13
0
void MacWindow::drawBorder() {
	_borderIsDirty = false;

	bool active = _active, scrollable = _scrollable, closeable = _active, drawTitle = !_title.empty();
	const int size = kBorderWidth;
	int x = 0;
	int y = 0;
	int width = _borderSurface.w;
	int height = _borderSurface.h;
	Graphics::ManagedSurface *g = &_borderSurface;

	// We draw rect with outer kColorGreen2 and inner kColorGreen, so on 2 passes we cut out
	// scene by external shape of the border
	int sz = kBorderWidth / 2;
	g->clear(kColorGreen2);
	g->fillRect(Common::Rect(sz, sz, width - sz, height - sz), kColorGreen);

	drawBox(g, x,                    y,                     size,                 size);
	drawBox(g, x + width - size - 1, y,                     size,                 size);
	drawBox(g, x + width - size - 1, y + height - size - 1, size,                 size);
	drawBox(g, x,                    y + height - size - 1, size,                 size);
	drawBox(g, x + size,             y + 2,                 width - 2 * size - 1, size - 4);
	drawBox(g, x + size,             y + height - size + 1, width - 2 * size - 1, size - 4);
	drawBox(g, x + 2,                y + size,              size - 4,             height - 2 * size - 1);
	drawBox(g, x + width - size + 1, y + size,              size - 4,             height - 2 * size - 1);

	if (active) {
		fillRect(g, x + size, y + 5,           width - 2 * size - 1, 8, kColorBlack);
		fillRect(g, x + size, y + height - 13, width - 2 * size - 1, 8, kColorBlack);
		fillRect(g, x + 5,    y + size,        8,                    height - 2 * size - 1, kColorBlack);
		if (!scrollable) {
			fillRect(g, x + width - 13, y + size, 8, height - 2 * size - 1, kColorBlack);
		} else {
			int x1 = x + width - 15;
			int y1 = y + size + 1;

			for (int yy = 0; yy < ARROW_H; yy++) {
				for (int xx = 0; xx < ARROW_W; xx++)
					g->hLine(x1 + xx, y1 + yy, x1 + xx, (arrowPixels[yy][xx] != 0 ? kColorBlack : kColorWhite));
			}

			fillRect(g, x + width - 13, y + size + ARROW_H, 8, height - 2 * size - 1 - ARROW_H * 2, kColorBlack);

			y1 += height - 2 * size - ARROW_H - 2;
			for (int yy = 0; yy < ARROW_H; yy++) {
				for (int xx = 0; xx < ARROW_W; xx++)
					g->hLine(x1 + xx, y1 + yy, x1 + xx, (arrowPixels[ARROW_H - yy - 1][xx] != 0 ? kColorBlack : kColorWhite));
			}

			if (_highlightedPart == kBorderScrollUp || _highlightedPart == kBorderScrollDown) {
				int rx1 = x + width - kBorderWidth + 2;
				int ry1 = y + size + _dims.height() * _scrollPos;
				int rx2 = rx1 + size - 4;
				int ry2 = ry1 + _dims.height() * _scrollSize;
				Common::Rect rr(rx1, ry1, rx2, ry2);

				Graphics::drawFilledRect(rr, kColorBlack, drawPixelInverted, g);
			}
		}
		if (closeable) {
			if (_highlightedPart == kBorderCloseButton) {
				fillRect(g, x + 6, y + 6, 6, 6, kColorBlack);
			} else {
				drawBox(g, x + 5, y + 5, 7, 7);
			}
		}
	}

	if (drawTitle) {
		const Graphics::Font *font = getTitleFont();
		int yOff = _wm->hasBuiltInFonts() ? 3 : 1;

		int w = font->getStringWidth(_title) + 10;
		int maxWidth = width - size * 2 - 7;
		if (w > maxWidth)
			w = maxWidth;
		drawBox(g, x + (width - w) / 2, y, w, size);
		font->drawString(g, _title, x + (width - w) / 2 + 5, y + yOff, w, kColorBlack);
	}
}