예제 #1
0
파일: frame.cpp 프로젝트: Tkachov/scummvm
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();
}
예제 #2
0
void CloudIcon::loadIcon(Graphics::Surface &icon, byte *data, uint32 size) {
	Image::PNGDecoder decoder;
	Common::MemoryReadStream stream(data, size);
	if (!decoder.loadStream(stream))
		error("CloudIcon::loadIcon: error decoding PNG");

	const Graphics::Surface *s = decoder.getSurface();
	return icon.copyFrom(*s);
}
예제 #3
0
void OpenGLTexture::updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) {
#if defined(USE_GLES2) && defined(SCUMM_BIG_ENDIAN)
	// OpenGL ES does not support the GL_UNSIGNED_INT_8_8_8_8_REV texture format
	// we need to byteswap before hand
	Graphics::Surface swappedSurface;
	swappedSurface.copyFrom(*surface);
	byteswapSurface(&swappedSurface);
	updateTexture(&swappedSurface, rect);
	swappedSurface.free();
#else
	updateTexture(surface, rect);
#endif

}
예제 #4
0
bool InputControl::process(uint32 deltaTimeInMillis) {
	if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
		return false;

	if (!_background) {
		_background = _engine->getRenderManager()->getBkgRect(_textRectangle);
	}

	// First see if we need to render the text
	if (_textChanged) {
		// Blit the text using the RenderManager

		Graphics::Surface txt;
		txt.copyFrom(*_background);

		int32 oldTxtWidth = _txtWidth;

		if (!_readOnly || !_focused)
			_txtWidth = _engine->getTextRenderer()->drawText(_currentInputText, _stringInit, txt);
		else
			_txtWidth = _engine->getTextRenderer()->drawText(_currentInputText, _stringChooserInit, txt);

		if (_readOnly || _txtWidth <= _maxTxtWidth)
			_engine->getRenderManager()->blitSurfaceToBkg(txt, _textRectangle.left, _textRectangle.top);
		else {
			// Assume the last character caused the overflow.
			_currentInputText.deleteLastChar();
			_txtWidth = oldTxtWidth;
		}

		txt.free();
	}

	if (_animation && !_readOnly && _focused) {
		if (_animation->endOfVideo())
			_animation->rewind();

		if (_animation->needsUpdate()) {
			const Graphics::Surface *srf = _animation->decodeNextFrame();
			int16 xx = _textRectangle.left + _txtWidth;
			if (xx >= _textRectangle.left + (_textRectangle.width() - (int16)_animation->getWidth()))
				xx = _textRectangle.left + _textRectangle.width() - (int16)_animation->getWidth();
			_engine->getRenderManager()->blitSurfaceToBkg(*srf, xx, _textRectangle.top);
		}
	}

	_textChanged = false;
	return false;
}
예제 #5
0
void Node::update() {
	// First undraw ...
	for (uint i = 0; i < _spotItems.size(); i++) {
		_spotItems[i]->updateUndraw();
	}

	// ... then redraw
	for (uint i = 0; i < _spotItems.size(); i++) {
		_spotItems[i]->updateDraw();
	}

	bool needsUpdate = false;
	for (uint i = 0; i < _effects.size(); i++) {
		needsUpdate |= _effects[i]->update();
	}

	// Apply the effects for all the faces
	for (uint faceId = 0; faceId < 6; faceId++) {
		Face *face = _faces[faceId];

		if (face == 0)
			continue; // No such face in this node

		if (!isFaceVisible(faceId)) {
			continue; // This face is not currently visible
		}

		uint effectsForFace = 0;
		for (uint i = 0; i < _effects.size(); i++) {
			if (_effects[i]->hasFace(faceId))
				effectsForFace++;
		}

		if (effectsForFace == 0)
			continue;
		if (!needsUpdate && !face->isTextureDirty())
			continue;

		// Alloc the target surface if necessary
		if (!face->_finalBitmap) {
			face->_finalBitmap = new Graphics::Surface();
		}
		face->_finalBitmap->copyFrom(*face->_bitmap);

		if (effectsForFace == 1) {
			_effects[0]->applyForFace(faceId, face->_bitmap, face->_finalBitmap);

			face->addTextureDirtyRect(_effects[0]->getUpdateRectForFace(faceId));
		} else if (effectsForFace == 2) {
			// TODO: Keep the same temp surface to avoid heap fragmentation ?
			Graphics::Surface *tmp = new Graphics::Surface();
			tmp->copyFrom(*face->_bitmap);

			_effects[0]->applyForFace(faceId, face->_bitmap, tmp);
			_effects[1]->applyForFace(faceId, tmp, face->_finalBitmap);

			tmp->free();
			delete tmp;

			face->addTextureDirtyRect(_effects[0]->getUpdateRectForFace(faceId));
			face->addTextureDirtyRect(_effects[1]->getUpdateRectForFace(faceId));
		} else {
			error("Unable to render more than 2 effects per faceId (%d)", effectsForFace);
		}
	}
}