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(); }
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); }
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 }
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; }
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); } } }