[Scummvm-git-logs] scummvm master -> bf785fc8f403981728b895ea6fb271d4e81de3ed
npjg
nathanael.gentrydb8 at gmail.com
Mon Jul 6 15:38:42 UTC 2020
This automated email contains information about 7 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
80cc7ba64f DIRECTOR: Split out stage blitting functions
f89ec907c5 DIRECTOR: Read more fields from bitmap cast
091458b2b5 DIRECTOR: Split out two different sprite focus methods
ca5be75426 DIRECTOR: Optionally force apply a matte mask
5ab3544c5c DIRECTOR: Improve sprite/cast type integration
664acb795d DIRECTOR: Refactor missing surface warning
bf785fc8f4 DIRECTOR: Selectively invert sprites on click
Commit: 80cc7ba64f0f0db2b68c7593fde4026b52784196
https://github.com/scummvm/scummvm/commit/80cc7ba64f0f0db2b68c7593fde4026b52784196
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-07-06T11:37:01-04:00
Commit Message:
DIRECTOR: Split out stage blitting functions
Now there is inkBlitShape, for QuickDraw shapes which do not have surfaces of
their own, and inkBlitSurface, for sprites that do have their own surfaces.
Changed paths:
engines/director/director.h
engines/director/score.cpp
engines/director/score.h
engines/director/stage.cpp
engines/director/stage.h
diff --git a/engines/director/director.h b/engines/director/director.h
index 778472fa04..f87dc07a91 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -104,7 +104,7 @@ struct DirectorPlotData {
Graphics::ManagedSurface *src;
Graphics::ManagedSurface *dst;
Graphics::MacPlotData *macPlot;
- Common::Rect destRect;
+ Common::Rect &destRect;
Common::Point srcPoint;
InkType ink;
@@ -113,8 +113,8 @@ struct DirectorPlotData {
Graphics::MacWindowManager *_wm;
- DirectorPlotData(Graphics::MacWindowManager *wm, Graphics::ManagedSurface *s, Graphics::ManagedSurface *d, InkType i, uint b, uint n) :
- src(s), dst(d), ink(i), backColor(b), macPlot(nullptr), numColors(n), _wm(wm) {
+ DirectorPlotData(Graphics::MacWindowManager *wm, Graphics::ManagedSurface *s, Graphics::ManagedSurface *ds, Common::Rect &dr, InkType i, uint b, uint n) :
+ src(s), dst(ds), ink(i), backColor(b), destRect(dr), macPlot(nullptr), numColors(n), _wm(wm) {
}
};
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 19c7423003..0b4debef38 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -196,6 +196,7 @@ MacShape *Channel::getShape() {
shape->foreColor = _sprite->_foreColor;
shape->backColor = _sprite->_backColor;
shape->lineSize = _sprite->_thickness & 0x3;
+ shape->pattern = _sprite->getPattern();
if (g_director->getVersion() >= 3 && shape->spriteType == kCastMemberSprite) {
if (!_sprite->_cast) {
diff --git a/engines/director/score.h b/engines/director/score.h
index 082319aaea..e1916a8cc4 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -108,6 +108,7 @@ struct MacShape {
byte foreColor;
byte backColor;
int lineSize;
+ uint pattern;
};
struct Channel {
diff --git a/engines/director/stage.cpp b/engines/director/stage.cpp
index ffd88bcf25..3cb969556e 100644
--- a/engines/director/stage.cpp
+++ b/engines/director/stage.cpp
@@ -137,79 +137,77 @@ void Stage::inkBlitFrom(Channel *channel, Common::Rect destRect, Graphics::Manag
Common::Rect srcRect = channel->getBbox();
destRect.clip(srcRect);
- Sprite *sprite = channel->_sprite;
MacShape *ms = channel->getShape();
- DirectorPlotData pd(_wm, channel->getSurface(), blitTo, sprite->_ink, sprite->_backColor, g_director->getPaletteColorCount());
- pd.destRect = destRect;
+ DirectorPlotData pd(_wm, channel->getSurface(), blitTo, destRect, channel->_sprite->_ink, channel->_sprite->_backColor, g_director->getPaletteColorCount());
- // Shapes do not have surfaces of their own, so draw the shape directly upon
- // stage surface.
if (ms) {
- if (ms->foreColor == ms->backColor) {
- delete ms;
- return;
- }
-
- Common::Rect fillRect((int)srcRect.width(), (int)srcRect.height());
- fillRect.moveTo(srcRect.left, srcRect.top);
- Graphics::MacPlotData plotFill(blitTo, nullptr, &g_director->getPatterns(), sprite->getPattern(), srcRect.left, srcRect.top, 1, ms->backColor);
-
- Common::Rect strokeRect(MAX((int)srcRect.width() - ms->lineSize, 0), MAX((int)srcRect.height() - ms->lineSize, 0));
- strokeRect.moveTo(srcRect.left, srcRect.top);
- Graphics::MacPlotData plotStroke(blitTo, nullptr, &g_director->getPatterns(), 1, strokeRect.left, strokeRect.top, ms->lineSize, ms->backColor);
-
- switch (ms->spriteType) {
- case kRectangleSprite:
- pd.macPlot = &plotFill;
- Graphics::drawFilledRect(fillRect, ms->foreColor, inkDrawPixel, &pd);
- // fall through
- case kOutlinedRectangleSprite:
- pd.macPlot = &plotStroke;
- Graphics::drawRect(strokeRect, ms->foreColor, inkDrawPixel, &pd);
- break;
- case kRoundedRectangleSprite:
- pd.macPlot = &plotFill;
- Graphics::drawRoundRect(fillRect, 12, ms->foreColor, true, inkDrawPixel, &pd);
- // fall through
- case kOutlinedRoundedRectangleSprite:
- pd.macPlot = &plotStroke;
- Graphics::drawRoundRect(strokeRect, 12, ms->foreColor, false, inkDrawPixel, &pd);
- break;
- case kOvalSprite:
- pd.macPlot = &plotFill;
- Graphics::drawEllipse(fillRect.left, fillRect.top, fillRect.right, fillRect.bottom, ms->foreColor, true, inkDrawPixel, &plotFill);
- // fall through
- case kOutlinedOvalSprite:
- pd.macPlot = &plotStroke;
- Graphics::drawEllipse(strokeRect.left, strokeRect.top, strokeRect.right, strokeRect.bottom, ms->foreColor, false, inkDrawPixel, &plotStroke);
- break;
- case kLineTopBottomSprite:
- pd.macPlot = &plotStroke;
- Graphics::drawLine(strokeRect.left, strokeRect.top, strokeRect.right, strokeRect.bottom, ms->foreColor, inkDrawPixel, &plotStroke);
- break;
- case kLineBottomTopSprite:
- pd.macPlot = &plotStroke;
- Graphics::drawLine(strokeRect.left, strokeRect.top, strokeRect.right, strokeRect.bottom, ms->foreColor, inkDrawPixel, &plotStroke);
- break;
- default:
- warning("Stage::inkBlitFrom: Expected shape type but got type %d", ms->spriteType);
- }
+ inkBlitShape(&pd, srcRect, ms);
+ } else {
+ inkBlitSurface(&pd, srcRect, channel->getMask());
+ }
+}
- delete ms;
+void Stage::inkBlitShape(DirectorPlotData *pd, Common::Rect &srcRect, MacShape *ms) {
+ if (ms->foreColor == ms->backColor)
return;
+
+ Common::Rect fillRect((int)srcRect.width(), (int)srcRect.height());
+ fillRect.moveTo(srcRect.left, srcRect.top);
+ Graphics::MacPlotData plotFill(pd->dst, nullptr, &g_director->getPatterns(), ms->pattern, srcRect.left, srcRect.top, 1, ms->backColor);
+
+ Common::Rect strokeRect(MAX((int)srcRect.width() - ms->lineSize, 0), MAX((int)srcRect.height() - ms->lineSize, 0));
+ strokeRect.moveTo(srcRect.left, srcRect.top);
+ Graphics::MacPlotData plotStroke(pd->dst, nullptr, &g_director->getPatterns(), 1, strokeRect.left, strokeRect.top, ms->lineSize, ms->backColor);
+
+ switch (ms->spriteType) {
+ case kRectangleSprite:
+ pd->macPlot = &plotFill;
+ Graphics::drawFilledRect(fillRect, ms->foreColor, inkDrawPixel, pd);
+ // fall through
+ case kOutlinedRectangleSprite:
+ pd->macPlot = &plotStroke;
+ Graphics::drawRect(strokeRect, ms->foreColor, inkDrawPixel, pd);
+ break;
+ case kRoundedRectangleSprite:
+ pd->macPlot = &plotFill;
+ Graphics::drawRoundRect(fillRect, 12, ms->foreColor, true, inkDrawPixel, pd);
+ // fall through
+ case kOutlinedRoundedRectangleSprite:
+ pd->macPlot = &plotStroke;
+ Graphics::drawRoundRect(strokeRect, 12, ms->foreColor, false, inkDrawPixel, pd);
+ break;
+ case kOvalSprite:
+ pd->macPlot = &plotFill;
+ Graphics::drawEllipse(fillRect.left, fillRect.top, fillRect.right, fillRect.bottom, ms->foreColor, true, inkDrawPixel, pd);
+ // fall through
+ case kOutlinedOvalSprite:
+ pd->macPlot = &plotStroke;
+ Graphics::drawEllipse(strokeRect.left, strokeRect.top, strokeRect.right, strokeRect.bottom, ms->foreColor, false, inkDrawPixel, pd);
+ break;
+ case kLineTopBottomSprite:
+ pd->macPlot = &plotStroke;
+ Graphics::drawLine(strokeRect.left, strokeRect.top, strokeRect.right, strokeRect.bottom, ms->foreColor, inkDrawPixel, pd);
+ break;
+ case kLineBottomTopSprite:
+ pd->macPlot = &plotStroke;
+ Graphics::drawLine(strokeRect.left, strokeRect.top, strokeRect.right, strokeRect.bottom, ms->foreColor, inkDrawPixel, pd);
+ break;
+ default:
+ warning("Stage::inkBlitFrom: Expected shape type but got type %d", ms->spriteType);
}
- // First, get any masks that might be needed.
- const Graphics::Surface *mask = channel->getMask();
+ delete ms;
+}
- pd.srcPoint.y = MAX(abs(srcRect.top - destRect.top), 0);
- for (int i = 0; i < destRect.height(); i++, pd.srcPoint.y++) {
- pd.srcPoint.x = MAX(abs(srcRect.left - destRect.left), 0);
- const byte *msk = mask ? (const byte *)mask->getBasePtr(pd.srcPoint.x, pd.srcPoint.y) : nullptr;
+void Stage::inkBlitSurface(DirectorPlotData *pd, Common::Rect &srcRect, const Graphics::Surface *mask) {
+ pd->srcPoint.y = MAX(abs(srcRect.top - pd->destRect.top), 0);
+ for (int i = 0; i < pd->destRect.height(); i++, pd->srcPoint.y++) {
+ pd->srcPoint.x = MAX(abs(srcRect.left - pd->destRect.left), 0);
+ const byte *msk = mask ? (const byte *)mask->getBasePtr(pd->srcPoint.x, pd->srcPoint.y) : nullptr;
- for (int j = 0; j < destRect.width(); j++, pd.srcPoint.x++)
- if (!mask || (msk && (sprite->_ink == kInkTypeMatte ? !(*msk++) : *msk++)))
- inkDrawPixel(destRect.left + j, destRect.top + i, 0, &pd);
+ for (int j = 0; j < pd->destRect.width(); j++, pd->srcPoint.x++)
+ if (!mask || (msk && (pd->ink == kInkTypeMatte ? !(*msk++) : *msk++)))
+ inkDrawPixel(pd->destRect.left + j, pd->destRect.top + i, 0, pd);
}
}
diff --git a/engines/director/stage.h b/engines/director/stage.h
index d002e6c7e3..d6e192f7f3 100644
--- a/engines/director/stage.h
+++ b/engines/director/stage.h
@@ -38,6 +38,7 @@ class MacWindowManager;
namespace Director {
struct Channel;
+struct MacShape;
struct TransParams;
class Stage : public Graphics::MacWindow {
@@ -100,7 +101,6 @@ public:
private:
uint _stageColor;
- void inkBlitFrom(Channel *channel, Common::Rect destRect, Graphics::ManagedSurface *blitTo = nullptr);
DirectorEngine *_vm;
Archive *_mainArchive;
@@ -108,6 +108,11 @@ private:
Movie *_currentMovie;
Common::String _currentPath;
Common::StringArray _movieQueue;
+
+private:
+ void inkBlitFrom(Channel *channel, Common::Rect destRect, Graphics::ManagedSurface *blitTo = nullptr);
+ void inkBlitShape(DirectorPlotData *pd, Common::Rect &srcRect, MacShape *ms);
+ void inkBlitSurface(DirectorPlotData *pd, Common::Rect &srcRect, const Graphics::Surface *mask);
};
} // end of namespace Director
Commit: f89ec907c58d69a485a1c38448c1ecc2e22a7195
https://github.com/scummvm/scummvm/commit/f89ec907c58d69a485a1c38448c1ecc2e22a7195
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-07-06T11:37:01-04:00
Commit Message:
DIRECTOR: Read more fields from bitmap cast
Changed paths:
engines/director/cast.cpp
engines/director/castmember.cpp
engines/director/castmember.h
engines/director/types.h
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index ab157d8708..734fdd0b26 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -542,8 +542,7 @@ void Cast::loadSpriteImages() {
bitmapCast->_img = img;
- debugC(4, kDebugImages, "Cast::loadSpriteImages(): id: %d, w: %d, h: %d, flags: %x, bytes: %x, bpp: %d clut: %x",
- imgId, w, h, bitmapCast->_flags, bitmapCast->_bytes, bitmapCast->_bitsPerPixel, bitmapCast->_clut);
+ debugC(4, kDebugImages, "Cast::loadSpriteImages(): id: %d, w: %d, h: %d, flags1: %x, flags2: %x bytes: %x, bpp: %d clut: %x", imgId, w, h, bitmapCast->_flags1, bitmapCast->_flags2, bitmapCast->_bytes, bitmapCast->_bitsPerPixel, bitmapCast->_clut);
}
}
diff --git a/engines/director/castmember.cpp b/engines/director/castmember.cpp
index ad48a36c80..ee9b660321 100644
--- a/engines/director/castmember.cpp
+++ b/engines/director/castmember.cpp
@@ -37,6 +37,7 @@ CastMember::CastMember(Cast* cast, uint16 castId) {
_castId = castId;
_widget = nullptr;
_hilite = false;
+ _autoHilite = false;
_modified = true;
}
@@ -48,13 +49,15 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, Common::ReadStream
_matte = nullptr;
_bytes = 0;
_pitch = 0;
- _flags = 0;
- _clut = 0;
+ _flags1 = 0;
+ _flags2 = 0;
_regX = _regY = 0;
- _bitsPerPixel = 1;
if (version < 4) {
- _flags = stream.readByte(); // region: 0 - auto, 1 - matte, 2 - disabled
+ _flags1 = stream.readByte(); // region: 0 - auto, 1 - matte, 2 - disabled, 8 - no auto
+ if (_flags1 >> 4 == 0x0)
+ _autoHilite = true;
+
_bytes = stream.readUint16();
_initialRect = Movie::readRect(stream);
_boundingRect = Movie::readRect(stream);
@@ -63,17 +66,18 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, Common::ReadStream
if (_bytes & 0x8000) {
_bitsPerPixel = stream.readUint16();
- _clut = stream.readUint16();
+ _clut = (PaletteType)stream.readUint16();
} else {
_bitsPerPixel = 1;
- _clut = 0;
+ _clut = kClutSystemMac;
}
_pitch = _initialRect.width();
if (_pitch % 16)
_pitch += 16 - (_initialRect.width() % 16);
+
} else if (version == 4) {
- _flags = stream.readByte();
+ _flags1 = stream.readByte();
_pitch = stream.readUint16();
_pitch &= 0x0fff;
@@ -89,6 +93,17 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, Common::ReadStream
if (_bitsPerPixel == 1)
_pitch *= 8;
+ _clut = (PaletteType)stream.readUint16();
+ stream.readUint16();
+ /* uint16 unk1 = */ stream.readUint16();
+ stream.readUint16();
+
+ stream.readUint32();
+ stream.readUint32();
+
+ _flags2 = stream.readUint16();
+ _autoHilite = (_flags2 % 4 != 0);
+
int tail = 0;
while (!stream.eos()) {
@@ -116,6 +131,7 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, Common::ReadStream
stream.readUint32();
}
+
_tag = castTag;
}
diff --git a/engines/director/castmember.h b/engines/director/castmember.h
index 7009311592..b68f347aa0 100644
--- a/engines/director/castmember.h
+++ b/engines/director/castmember.h
@@ -74,6 +74,7 @@ public:
bool _modified;
bool _hilite;
+ bool _autoHilite;
Graphics::MacWidget *_widget;
@@ -98,9 +99,10 @@ public:
uint16 _pitch;
uint16 _regX;
uint16 _regY;
- uint8 _flags;
+ uint8 _flags1;
+ uint16 _flags2;
uint16 _bytes;
- uint16 _clut;
+ PaletteType _clut;
uint16 _bitsPerPixel;
diff --git a/engines/director/types.h b/engines/director/types.h
index fd2bbfbb3a..923f506245 100644
--- a/engines/director/types.h
+++ b/engines/director/types.h
@@ -255,6 +255,18 @@ enum TransitionType {
kTransDissolveBits
};
+// TODO: Can there be any more built-in palette types?
+enum PaletteType {
+ kClutSystemMac = 0x0000,
+ kClutSystemWin = 0xff9c,
+ kClutRainbow = 0xffff,
+ kClutGrayscale = 0xfffe,
+ kClutPastels = 0xfffd,
+ kClutVivid = 0xfffc,
+ kClutNTSC = 0xfffb,
+ kClutMetallic = 0xfffa
+};
+
enum {
kCursorDefault,
kCursorMouseDown,
Commit: 091458b2b5b979b6bfd7016eb68ae016b29a1f0e
https://github.com/scummvm/scummvm/commit/091458b2b5b979b6bfd7016eb68ae016b29a1f0e
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-07-06T11:37:01-04:00
Commit Message:
DIRECTOR: Split out two different sprite focus methods
Changed paths:
engines/director/score.cpp
engines/director/sprite.cpp
engines/director/sprite.h
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 0b4debef38..655c7d4f90 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -642,7 +642,7 @@ void Score::screenShot() {
uint16 Score::getSpriteIDFromPos(Common::Point pos, bool onlyActive) {
for (int i = _channels.size() - 1; i >= 0; i--)
- if (_channels[i]->getBbox().contains(pos) && (!onlyActive || _channels[i]->_sprite->isActive()))
+ if (_channels[i]->getBbox().contains(pos) && (!onlyActive || _channels[i]->_sprite->isFocusable()))
return i;
return 0;
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index 691199bdcf..6f5ffb0d80 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -78,12 +78,19 @@ void Sprite::updateCast() {
_cast->setEditable(_editable);
}
-bool Sprite::isActive() {
+bool Sprite::isFocusable() {
if (_moveable || _puppet || _scriptId)
return true;
- if (g_director->getCurrentMovie()->getScriptContext(kCastScript, _castId))
- return true;
+ return false;
+}
+
+bool Sprite::shouldHilite() {
+ if ((_cast && _cast->_autoHilite) || (isQDShape() && _ink == kInkTypeMatte))
+ if (g_director->getVersion() < 4 && !_moveable)
+ if (g_director->getCurrentMovie()->getScriptContext(kScoreScript, _scriptId) ||
+ g_director->getCurrentMovie()->getScriptContext(kCastScript, _castId))
+ return true;
return false;
}
diff --git a/engines/director/sprite.h b/engines/director/sprite.h
index e63c6cb960..20c1dc0393 100644
--- a/engines/director/sprite.h
+++ b/engines/director/sprite.h
@@ -62,7 +62,10 @@ public:
~Sprite();
void updateCast();
- bool isActive();
+
+ bool isFocusable();
+ bool shouldHilite();
+
uint16 getPattern();
void setPattern(uint16 pattern);
Commit: ca5be75426f51fab8a3ad5b2fad37f672504db30
https://github.com/scummvm/scummvm/commit/ca5be75426f51fab8a3ad5b2fad37f672504db30
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-07-06T11:37:01-04:00
Commit Message:
DIRECTOR: Optionally force apply a matte mask
Changed paths:
engines/director/score.cpp
engines/director/score.h
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 655c7d4f90..af9456852f 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -68,9 +68,8 @@ Graphics::ManagedSurface *Channel::getSurface() {
}
}
-const Graphics::Surface *Channel::getMask() {
- switch (_sprite->_ink) {
- case kInkTypeMatte:
+const Graphics::Surface *Channel::getMask(bool forceMatte) {
+ if (_sprite->_ink == kInkTypeMatte || forceMatte) {
// Mattes are only supported in bitmaps for now. Shapes don't need mattes,
// as they already have all non-enclosed white pixels transparent.
// Matte on text has a trivial enough effect to not worry about implementing.
@@ -79,8 +78,7 @@ const Graphics::Surface *Channel::getMask() {
} else {
return nullptr;
}
-
- case kInkTypeMask: {
+ } else if (_sprite->_ink == kInkTypeMask) {
CastMember *member = g_director->getCurrentMovie()->getCastMember(_sprite->_castId + 1);
if (_sprite->_cast && member && member->_initialRect == _sprite->_cast->_initialRect) {
@@ -89,14 +87,9 @@ const Graphics::Surface *Channel::getMask() {
warning("Channel::getMask(): Requested cast mask, but no matching mask was found");
return nullptr;
}
-
- // Silence warning
- break;
}
- default:
- return nullptr;
- }
+ return nullptr;
}
bool Channel::isDirty(Sprite *nextSprite) {
diff --git a/engines/director/score.h b/engines/director/score.h
index e1916a8cc4..94aae24e86 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -127,7 +127,7 @@ struct Channel {
Common::Point getPosition();
MacShape *getShape();
Graphics::ManagedSurface *getSurface();
- const Graphics::Surface *getMask();
+ const Graphics::Surface *getMask(bool forceMatte = false);
void setClean(Sprite *nextSprite, int spriteId);
void addDelta(Common::Point pos);
Commit: 5ab3544c5cae524b7342c3fb331d437a00b96621
https://github.com/scummvm/scummvm/commit/5ab3544c5cae524b7342c3fb331d437a00b96621
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-07-06T11:37:35-04:00
Commit Message:
DIRECTOR: Improve sprite/cast type integration
Now, rather than having a _castType in the sprite, I fixed the issue that might
have made this necessary in the first place -- overloading _castId with the
shape pattern whenever the sprite is a QuickDraw shape. There is now a separate
test function for QuickDraw shapes.
Changed paths:
engines/director/frame.cpp
engines/director/score.cpp
engines/director/sprite.cpp
engines/director/sprite.h
diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index 1c732c6d04..64fef1368b 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -278,7 +278,11 @@ void Frame::readChannels(Common::ReadStreamEndian *stream) {
sprite._thickness = stream->readByte();
sprite._inkData = stream->readByte();
- sprite._castId = stream->readUint16();
+ if (_vm->getVersion() < 4 && sprite.isQDShape()) {
+ sprite._pattern = stream->readUint16();
+ } else {
+ sprite._castId = stream->readUint16();
+ }
sprite._startPoint.y = (int16)stream->readUint16();
sprite._startPoint.x = (int16)stream->readUint16();
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index af9456852f..ef27ca129b 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -55,9 +55,7 @@ Channel::Channel(Sprite *sp) {
_visible = true;
_dirty = true;
- if (_sprite && _sprite->_castType != kCastTypeNull) {
- _sprite->updateCast();
- }
+ _sprite->updateCast();
}
Graphics::ManagedSurface *Channel::getSurface() {
@@ -69,11 +67,14 @@ Graphics::ManagedSurface *Channel::getSurface() {
}
const Graphics::Surface *Channel::getMask(bool forceMatte) {
+ if (!_sprite->_cast)
+ return nullptr;
+
if (_sprite->_ink == kInkTypeMatte || forceMatte) {
// Mattes are only supported in bitmaps for now. Shapes don't need mattes,
// as they already have all non-enclosed white pixels transparent.
// Matte on text has a trivial enough effect to not worry about implementing.
- if (_sprite->_cast && _sprite->_cast->_type == kCastBitmap) {
+ if (_sprite->_cast->_type == kCastBitmap) {
return ((BitmapCastMember *)_sprite->_cast)->getMatte();
} else {
return nullptr;
@@ -81,7 +82,7 @@ const Graphics::Surface *Channel::getMask(bool forceMatte) {
} else if (_sprite->_ink == kInkTypeMask) {
CastMember *member = g_director->getCurrentMovie()->getCastMember(_sprite->_castId + 1);
- if (_sprite->_cast && member && member->_initialRect == _sprite->_cast->_initialRect) {
+ if (member && member->_initialRect == _sprite->_cast->_initialRect) {
return &member->_widget->getSurface()->rawSurface();
} else {
warning("Channel::getMask(): Requested cast mask, but no matching mask was found");
@@ -98,8 +99,7 @@ bool Channel::isDirty(Sprite *nextSprite) {
// cast of the sprite changes.
bool isDirty = _dirty ||
_delta != Common::Point(0, 0) ||
- ((_sprite->_castType != kCastTypeNull) &&
- (_sprite->_cast && _sprite->_cast->isModified()));
+ (_sprite->_cast && _sprite->_cast->isModified());
if (nextSprite) {
isDirty |= _sprite->_castId != nextSprite->_castId ||
@@ -168,7 +168,7 @@ void Channel::addDelta(Common::Point pos) {
Common::Point Channel::getPosition() {
Common::Point res = _currentPoint;
- if (_sprite->_castType == kCastBitmap && _sprite->_cast) {
+ if (_sprite->_cast && _sprite->_cast->_type == kCastBitmap) {
BitmapCastMember *bc = (BitmapCastMember *)(_sprite->_cast);
res += Common::Point(bc->_initialRect.left - bc->_regX,
@@ -179,7 +179,7 @@ Common::Point Channel::getPosition() {
}
MacShape *Channel::getShape() {
- if (_sprite->_castType != kCastShape)
+ if (!_sprite->isQDShape())
return nullptr;
MacShape *shape = new MacShape();
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index 6f5ffb0d80..34d2f70593 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -39,9 +39,10 @@ Sprite::Sprite() {
_enabled = false;
_castId = 0;
+ _pattern = 0;
+
_castIndex = 0;
_spriteType = kInactiveSprite;
- _castType = kCastTypeNull;
_inkData = 0;
_ink = kInkTypeCopy;
_trails = 0;
@@ -70,6 +71,18 @@ Sprite::Sprite() {
Sprite::~Sprite() {
}
+bool Sprite::isQDShape() {
+ return _spriteType == kRectangleSprite ||
+ _spriteType == kRoundedRectangleSprite ||
+ _spriteType == kOvalSprite ||
+ _spriteType == kLineTopBottomSprite ||
+ _spriteType == kLineBottomTopSprite ||
+ _spriteType == kOutlinedRectangleSprite ||
+ _spriteType == kOutlinedRoundedRectangleSprite ||
+ _spriteType == kOutlinedOvalSprite ||
+ _spriteType == kThickLineSprite;
+}
+
void Sprite::updateCast() {
if (!_cast)
return;
@@ -96,30 +109,14 @@ bool Sprite::shouldHilite() {
}
uint16 Sprite::getPattern() {
- switch (_spriteType) {
- case kRectangleSprite:
- case kRoundedRectangleSprite:
- case kOvalSprite:
- case kLineTopBottomSprite:
- case kLineBottomTopSprite:
- case kOutlinedRectangleSprite:
- case kOutlinedRoundedRectangleSprite:
- case kOutlinedOvalSprite:
- return _castId;
-
- case kCastMemberSprite:
- switch (_cast->_type) {
- case kCastShape:
- return ((ShapeCastMember *)_cast)->_pattern;
- break;
- default:
- warning("Sprite::getPattern(): Unhandled cast type: %d", _cast->_type);
- break;
- }
- // fallthrough
- default:
- return 0;
+ if (!_cast) {
+ if (isQDShape())
+ return _pattern;
+ } else if (_cast->_type == kCastShape) {
+ return ((ShapeCastMember *)_cast)->_pattern;
}
+
+ return 0;
}
void Sprite::setPattern(uint16 pattern) {
@@ -132,7 +129,7 @@ void Sprite::setPattern(uint16 pattern) {
case kOutlinedRectangleSprite:
case kOutlinedRoundedRectangleSprite:
case kOutlinedOvalSprite:
- _castId = pattern;
+ _pattern = pattern;
break;
case kCastMemberSprite:
@@ -147,7 +144,6 @@ void Sprite::setPattern(uint16 pattern) {
void Sprite::setCast(uint16 castId) {
CastMember *member = g_director->getCurrentMovie()->getCastMember(castId);
- _castType = kCastTypeNull;
_castId = castId;
if (castId == 0)
@@ -157,10 +153,12 @@ void Sprite::setCast(uint16 castId) {
_cast = member;
if (_cast->_type == kCastText &&
- (_spriteType == kButtonSprite || _spriteType == kCheckboxSprite || _spriteType == kRadioButtonSprite)) {
+ (_spriteType == kButtonSprite ||
+ _spriteType == kCheckboxSprite ||
+ _spriteType == kRadioButtonSprite)) {
// WORKAROUND: In D2/D3 there can be text casts that have button
// information set in the sprite.
- warning("Sprite::updateCast: Working around D2/3 button glitch");
+ warning("Sprite::setCast(): Working around D2/3 button glitch");
delete _cast->_widget;
_cast->_type = kCastButton;
@@ -168,71 +166,19 @@ void Sprite::setCast(uint16 castId) {
((TextCastMember *)_cast)->createWidget();
}
} else {
- warning("Sprite::setCast: CastMember id %d has null member", castId);
- }
-
- if (g_director->getVersion() < 4) {
- switch (_spriteType) {
- case kBitmapSprite:
- _castType = kCastBitmap;
- break;
- case kRectangleSprite:
- case kRoundedRectangleSprite:
- case kOvalSprite:
- case kLineTopBottomSprite:
- case kLineBottomTopSprite:
- case kOutlinedRectangleSprite:
- case kOutlinedRoundedRectangleSprite:
- case kOutlinedOvalSprite:
- case kCastMemberSprite:
- if (_cast) {
- switch (_cast->_type) {
- case kCastButton:
- _castType = kCastButton;
- break;
- default:
- _castType = kCastShape;
- break;
- }
- } else {
- _castType = kCastShape;
- }
- break;
- case kTextSprite:
- _castType = kCastText;
- break;
- case kButtonSprite:
- case kCheckboxSprite:
- case kRadioButtonSprite:
- _castType = kCastButton;
-
- break;
- default:
- warning("Sprite::setCast(): Unhandled sprite type %d", _spriteType);
- break;
- }
- } else {
- if (!member) {
- debugC(1, kDebugImages, "Sprite::setCast(): CastMember id %d not found", _castId);
- } else {
- _castType = member->_type;
- }
+ warning("Sprite::setCast(): CastMember id %d has null member", castId);
}
}
Common::Rect Sprite::getDims() {
Common::Rect result;
- if (_castId == 0) {
- return result;
- }
- if (_castType == kCastShape) {
- // WORKAROUND: Shape widgets not fully implemented.
+ if (!_cast || _cast->_type == kCastShape) {
result = Common::Rect(_width, _height);
+ } else if (_cast->_widget) {
+ result = Common::Rect(_cast->_widget->_dims.width(), _cast->_widget->_dims.height());
} else {
- if (_cast && _cast->_widget) {
- result = Common::Rect(_cast->_widget->_dims.width(), _cast->_widget->_dims.height());
- }
+ warning("Sprite::getDims(): Unable to find sprite dimensions");
}
if (_puppet && _stretch) {
diff --git a/engines/director/sprite.h b/engines/director/sprite.h
index 20c1dc0393..b2e7d4dd7d 100644
--- a/engines/director/sprite.h
+++ b/engines/director/sprite.h
@@ -70,6 +70,7 @@ public:
void setPattern(uint16 pattern);
void setCast(uint16 castid);
+ bool isQDShape();
Common::Rect getDims();
@@ -80,14 +81,14 @@ public:
uint32 _unk3;
bool _enabled;
- uint16 _castId;
uint16 _castIndex;
SpriteType _spriteType;
- CastType _castType;
byte _inkData;
InkType _ink;
uint16 _trails;
+ uint16 _castId;
+ uint16 _pattern;
CastMember *_cast;
byte _thickness;
Commit: 664acb795d23cc506da1eb1b91845fcf3e8390ac
https://github.com/scummvm/scummvm/commit/664acb795d23cc506da1eb1b91845fcf3e8390ac
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-07-06T11:37:35-04:00
Commit Message:
DIRECTOR: Refactor missing surface warning
Changed paths:
engines/director/graphics.cpp
engines/director/stage.cpp
diff --git a/engines/director/graphics.cpp b/engines/director/graphics.cpp
index 0a4528c0ac..666552f169 100644
--- a/engines/director/graphics.cpp
+++ b/engines/director/graphics.cpp
@@ -818,10 +818,10 @@ void inkDrawPixel(int x, int y, int color, void *data) {
*dst = tmpDst;
src = &tmpSrc;
- } else {
- if (!p->src)
+ } else if (!p->src) {
error("Director::inkDrawPixel(): No source surface");
-
+ return;
+ } else {
src = (const byte *)p->src->getBasePtr(p->srcPoint.x, p->srcPoint.y);
}
diff --git a/engines/director/stage.cpp b/engines/director/stage.cpp
index 3cb969556e..098b144951 100644
--- a/engines/director/stage.cpp
+++ b/engines/director/stage.cpp
@@ -142,8 +142,10 @@ void Stage::inkBlitFrom(Channel *channel, Common::Rect destRect, Graphics::Manag
if (ms) {
inkBlitShape(&pd, srcRect, ms);
- } else {
+ } else if (pd.src) {
inkBlitSurface(&pd, srcRect, channel->getMask());
+ } else {
+ warning("Stage::inkBlitFrom: No source surface");
}
}
Commit: bf785fc8f403981728b895ea6fb271d4e81de3ed
https://github.com/scummvm/scummvm/commit/bf785fc8f403981728b895ea6fb271d4e81de3ed
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-07-06T11:37:35-04:00
Commit Message:
DIRECTOR: Selectively invert sprites on click
Changed paths:
engines/director/director.h
engines/director/events.cpp
engines/director/graphics.cpp
engines/director/stage.cpp
engines/director/stage.h
diff --git a/engines/director/director.h b/engines/director/director.h
index f87dc07a91..dc454d27bb 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -107,6 +107,7 @@ struct DirectorPlotData {
Common::Rect &destRect;
Common::Point srcPoint;
+ bool ignoreSrc;
InkType ink;
int numColors;
uint backColor;
@@ -115,6 +116,7 @@ struct DirectorPlotData {
DirectorPlotData(Graphics::MacWindowManager *wm, Graphics::ManagedSurface *s, Graphics::ManagedSurface *ds, Common::Rect &dr, InkType i, uint b, uint n) :
src(s), dst(ds), ink(i), backColor(b), destRect(dr), macPlot(nullptr), numColors(n), _wm(wm) {
+ ignoreSrc = false;
}
};
diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index 77d2ed554b..c36a4abfa7 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -105,6 +105,9 @@ void DirectorEngine::processEvents(bool bufferLingoEvents) {
m->_currentMouseDownSpriteId = spriteId;
m->_currentClickOnSpriteId = spriteId;
+ if (spriteId > 0 && sc->_channels[spriteId]->_sprite->shouldHilite())
+ g_director->getStage()->invertChannel(sc->_channels[spriteId]);
+
m->_lastEventTime = g_director->getMacTicks();
m->_lastClickTime = m->_lastEventTime;
@@ -124,6 +127,9 @@ void DirectorEngine::processEvents(bool bufferLingoEvents) {
if (!sc->getChannelById(m->_currentMouseDownSpriteId)->getBbox().contains(pos))
m->_currentMouseDownSpriteId = 0;
+ if (spriteId > 0 && sc->_channels[spriteId]->_sprite->shouldHilite())
+ g_director->getStage()->invertChannel(sc->_channels[spriteId]);
+
if (!(g_director->_wm->_mode & Graphics::kWMModeButtonDialogStyle))
m->_currentMouseDownSpriteId = spriteId;
diff --git a/engines/director/graphics.cpp b/engines/director/graphics.cpp
index 666552f169..5e4325303a 100644
--- a/engines/director/graphics.cpp
+++ b/engines/director/graphics.cpp
@@ -806,7 +806,11 @@ void inkDrawPixel(int x, int y, int color, void *data) {
dst = (byte *)p->dst->getBasePtr(x, y);
- if (p->macPlot) {
+ if (p->ignoreSrc) {
+ // This fast-track mode is currently used only for inversions on click
+ *dst = ~(*dst);
+ return;
+ } else if (p->macPlot) {
// Get the pixel that macDrawPixel will give us, but store it to apply the
// ink later.
tmpDst = *dst;
diff --git a/engines/director/stage.cpp b/engines/director/stage.cpp
index 098b144951..f2a51480ae 100644
--- a/engines/director/stage.cpp
+++ b/engines/director/stage.cpp
@@ -59,6 +59,14 @@ Stage::~Stage() {
}
}
+void Stage::invertChannel(Channel *channel) {
+ Common::Rect destRect = channel->getBbox();
+ DirectorPlotData pd(_wm, &_surface, &_surface, destRect, kInkTypeMatte, 0, g_director->getPaletteColorCount());
+ pd.ignoreSrc = true;
+
+ inkBlitSurface(&pd, destRect, channel->getMask(true));
+}
+
bool Stage::render(bool forceRedraw, Graphics::ManagedSurface *blitTo) {
if (!blitTo)
blitTo = &_surface;
diff --git a/engines/director/stage.h b/engines/director/stage.h
index d6e192f7f3..b9a055783d 100644
--- a/engines/director/stage.h
+++ b/engines/director/stage.h
@@ -48,6 +48,7 @@ class Stage : public Graphics::MacWindow {
bool render(bool forceRedraw = false, Graphics::ManagedSurface *blitTo = nullptr);
+ void invertChannel(Channel *channel);
void setStageColor(uint stageColor);
void addDirtyRect(const Common::Rect &r);
void mergeDirtyRects();
More information about the Scummvm-git-logs
mailing list