diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp index e5f9afd3fd9..f7455c53665 100644 --- a/engines/director/sprite.cpp +++ b/engines/director/sprite.cpp @@ -54,6 +54,7 @@ Sprite::Sprite(Frame *frame) { _ink = kInkTypeCopy; _trails = 0; + _matte = nullptr; _cast = nullptr; _thickness = 0; @@ -73,6 +74,7 @@ Sprite::Sprite(Frame *frame) { } Sprite::~Sprite() { + delete _matte; } bool Sprite::isQDShape() { @@ -118,6 +120,86 @@ bool Sprite::isActive() { || _movie->getScriptContext(kCastScript, _castId) != nullptr; } +void Sprite::createQDMatte() { + Graphics::ManagedSurface tmp; + tmp.create(_width, _height, g_director->_pixelformat); + tmp.clear(g_director->_wm->_colorWhite); + + MacShape *ms = new MacShape(); + + ms->ink = _ink; + ms->spriteType = _spriteType; + ms->foreColor = _foreColor; + ms->backColor = _backColor; + ms->lineSize = _thickness & 0x3; + ms->pattern = getPattern(); + + Common::Rect srcRect(_width, _height); + + Common::Rect fillAreaRect((int)srcRect.width(), (int)srcRect.height()); + Graphics::MacPlotData plotFill(&tmp, nullptr, &g_director->getPatterns(), ms->pattern, 0, 0, 1, ms->backColor); + + Common::Rect strokeRect(MAX((int)srcRect.width() - ms->lineSize, 0), MAX((int)srcRect.height() - ms->lineSize, 0)); + Graphics::MacPlotData plotStroke(&tmp, nullptr, &g_director->getPatterns(), 1, 0, 0, ms->lineSize, ms->backColor); + + switch (_spriteType) { + case kRectangleSprite: + Graphics::drawFilledRect(fillAreaRect, g_director->_wm->_colorBlack, g_director->_wm->getDrawPixel(), &plotFill); + // fall through + case kOutlinedRectangleSprite: + Graphics::drawRect(strokeRect, g_director->_wm->_colorBlack, g_director->_wm->getDrawPixel(), &plotStroke); + break; + case kRoundedRectangleSprite: + Graphics::drawRoundRect(fillAreaRect, 12, g_director->_wm->_colorBlack, true, g_director->_wm->getDrawPixel(), &plotFill); + // fall through + case kOutlinedRoundedRectangleSprite: + Graphics::drawRoundRect(strokeRect, 12, g_director->_wm->_colorBlack, false, g_director->_wm->getDrawPixel(), &plotStroke); + break; + case kOvalSprite: + Graphics::drawEllipse(fillAreaRect.left, fillAreaRect.top, fillAreaRect.right, fillAreaRect.bottom, g_director->_wm->_colorBlack, true, g_director->_wm->getDrawPixel(), &plotFill); + // fall through + case kOutlinedOvalSprite: + Graphics::drawEllipse(strokeRect.left, strokeRect.top, strokeRect.right, strokeRect.bottom, g_director->_wm->_colorBlack, false, g_director->_wm->getDrawPixel(), &plotStroke); + break; + case kLineTopBottomSprite: + Graphics::drawLine(strokeRect.left, strokeRect.top, strokeRect.right, strokeRect.bottom, g_director->_wm->_colorBlack, g_director->_wm->getDrawPixel(), &plotStroke); + break; + case kLineBottomTopSprite: + Graphics::drawLine(strokeRect.left, strokeRect.bottom, strokeRect.right, strokeRect.top, g_director->_wm->_colorBlack, g_director->_wm->getDrawPixel(), &plotStroke); + break; + default: + warning("Sprite:createQDMatte Expected shape type but got type %d", _spriteType); + } + + Graphics::Surface managedSurface; + managedSurface.create(_width, _height, g_director->_pixelformat); + managedSurface.copyFrom(tmp); + + _matte = new Graphics::FloodFill(&managedSurface, g_director->_wm->_colorWhite, 0, true); + + for (int yy = 0; yy < managedSurface.h; yy++) { + _matte->addSeed(0, yy); + _matte->addSeed(managedSurface.w - 1, yy); + } + + for (int xx = 0; xx < managedSurface.w; xx++) { + _matte->addSeed(xx, 0); + _matte->addSeed(xx, managedSurface.h - 1); + } + + _matte->fillMask(); + tmp.free(); + managedSurface.free(); +} + +Graphics::Surface *Sprite::getQDMatte() { + if (!isQDShape() || _ink != kInkTypeMatte) + return nullptr; + if (!_matte) + createQDMatte(); + return _matte ? _matte->getMask() : nullptr; +} + bool Sprite::shouldHilite() { if (!isActive()) return false; diff --git a/engines/director/sprite.h b/engines/director/sprite.h index 36df4750d53..02faa8651ba 100644 --- a/engines/director/sprite.h +++ b/engines/director/sprite.h @@ -76,6 +76,8 @@ public: void setCast(uint16 castid); bool isQDShape(); + Graphics::Surface *getQDMatte(); + void createQDMatte(); Frame *_frame; Score *_score; @@ -83,7 +85,7 @@ public: uint16 _scriptId; uint16 _scriptCastIndex; - byte _colorcode; // x40 editable, 0x80 moveable + byte _colorcode; // x40 editable, 0x80 moveable byte _blendAmount; uint32 _unk3; @@ -98,6 +100,8 @@ public: uint16 _pattern; CastMember *_cast; + Graphics::FloodFill *_matte; // matte for quickdraw shape + byte _thickness; Common::Point _startPoint; int16 _width;