[Scummvm-git-logs] scummvm master -> 4bf4e4a4a060c6067ac1656a24a99805d8426f84

sev- noreply at scummvm.org
Sun May 28 12:44:16 UTC 2023


This automated email contains information about 8 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
4a85392dd9 DIRECTOR: Skip palette fades when the source and destination match
9188159114 DIRECTOR: Move draw debugger to Window::render()
bcb502d634 DIRECTOR: Move getRegistrationOffset and getBbox to CastMember
9ec6722b6a DIRECTOR: Remove inkBlitStretchSurface()
96c33ca4e8 DIRECTOR: Fix D5 palette fade times
4090a22782 DIRECTOR: Fix divide by zero
cf886b17e7 DIRECTOR: Fix regression in sprite dragging
4bf4e4a4a0 DIRECTOR: Fixes based on feedback


Commit: 4a85392dd9274481a6d832275143644a41706794
    https://github.com/scummvm/scummvm/commit/4a85392dd9274481a6d832275143644a41706794
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-28T14:44:09+02:00

Commit Message:
DIRECTOR: Skip palette fades when the source and destination match

Fixes menu interactions in The Cute machine.

Changed paths:
    engines/director/score.cpp


diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 870bf54eec8..e8d6d7419f9 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -551,6 +551,7 @@ void Score::update() {
 }
 
 void Score::renderFrame(uint16 frameId, RenderMode mode) {
+	uint32 start = g_system->getMillis(false);
 	// Force cursor update if a new movie's started.
 	if (_window->_newMovieStarted)
 		renderCursor(_movie->getWindow()->getMousePos(), true);
@@ -575,6 +576,8 @@ void Score::renderFrame(uint16 frameId, RenderMode mode) {
 		renderCursor(_movie->getWindow()->getMousePos());
 		_cursorDirty = false;
 	}
+	uint32 end = g_system->getMillis(false);
+	debugC(5, kDebugLoading, "Score::renderFrame() finished in %d millis", end - start);
 }
 
 bool Score::renderTransition(uint16 frameId) {
@@ -694,6 +697,12 @@ bool Score::renderPrePaletteCycle(uint16 frameId, RenderMode mode) {
 		}
 
 		if (_frames[frameId]->_palette.normal) {
+			// If the target palette ID is the same as the previous palette ID,
+			// a normal fade is a no-op.
+			if (_frames[frameId]->_palette.paletteId == g_director->_lastPalette) {
+				return false;
+			}
+
 			// For fade palette transitions, the whole fade happens with
 			// the previous frame's layout.
 			debugC(2, kDebugImages, "Score::renderPrePaletteCycle(): fading palette to %s over %d frames", currentPalette.asString().c_str(), fadeFrames);


Commit: 9188159114d48138683934e3a47362b716b0945f
    https://github.com/scummvm/scummvm/commit/9188159114d48138683934e3a47362b716b0945f
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-28T14:44:09+02:00

Commit Message:
DIRECTOR: Move draw debugger to Window::render()

Changed paths:
    engines/director/castmember/bitmap.cpp
    engines/director/window.cpp


diff --git a/engines/director/castmember/bitmap.cpp b/engines/director/castmember/bitmap.cpp
index 899e5eb8636..52fd50bf632 100644
--- a/engines/director/castmember/bitmap.cpp
+++ b/engines/director/castmember/bitmap.cpp
@@ -373,13 +373,6 @@ void BitmapCastMember::copyStretchImg(Graphics::Surface *surface, const Common::
 	} else {
 		surface->copyFrom(*srcSurf);
 	}
-
-	if (g_director->_debugDraw & kDebugDrawCast) {
-		surface->frameRect(Common::Rect(0, 0, surface->w, surface->h), g_director->_wm->_colorWhite);
-
-		const Graphics::Font *font = FontMan.getFontByUsage(Graphics::FontManager::kConsoleFont);
-		font->drawString(surface, Common::String::format("%d", _castId), 2, 2, 10, g_director->_wm->_colorWhite);
-	}
 }
 
 bool BitmapCastMember::isModified() {
diff --git a/engines/director/window.cpp b/engines/director/window.cpp
index bafb880a168..4cea2b48144 100644
--- a/engines/director/window.cpp
+++ b/engines/director/window.cpp
@@ -180,6 +180,26 @@ bool Window::render(bool forceRedraw, Graphics::ManagedSurface *blitTo) {
 		font->drawString(blitTo, msg, blitTo->w - 2 - width, 2, width , _wm->_colorWhite);
 	}
 
+	if (g_director->_debugDraw & kDebugDrawCast) {
+		for (uint i = 0; i < _currentMovie->getScore()->_channels.size(); i++) {
+			Channel *channel = _currentMovie->getScore()->_channels[i];
+			if (!channel->isEmpty()) {
+				Common::Rect bbox = channel->getBbox();
+				blitTo->frameRect(bbox, g_director->_wm->_colorWhite);
+
+				const Graphics::Font *font = FontMan.getFontByUsage(Graphics::FontManager::kConsoleFont);
+				font->drawString(blitTo, Common::String::format("m: %d, ch: %d", channel->_sprite->_castId.member, i), bbox.left + 2, bbox.top + 2, 128, g_director->_wm->_colorWhite);
+			}
+		}
+
+		const Graphics::Font *font = FontMan.getFontByUsage(Graphics::FontManager::kConsoleFont);
+		Common::String msg = Common::String::format("Frame: %d", g_director->getCurrentMovie()->getScore()->getCurrentFrame());
+		uint32 width = font->getStringWidth(msg);
+
+		blitTo->fillRect(Common::Rect(blitTo->w - 3 - width, 1, blitTo->w - 1, font->getFontHeight() + 1), _wm->_colorBlack);
+		font->drawString(blitTo, msg, blitTo->w - 2 - width, 2, width , _wm->_colorWhite);
+	}
+
 	_dirtyRects.clear();
 	_contentIsDirty = true;
 


Commit: bcb502d634eddc916a9070a3f204fccfda653981
    https://github.com/scummvm/scummvm/commit/bcb502d634eddc916a9070a3f204fccfda653981
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-28T14:44:09+02:00

Commit Message:
DIRECTOR: Move getRegistrationOffset and getBbox to CastMember

Changed paths:
    engines/director/castmember/bitmap.cpp
    engines/director/castmember/bitmap.h
    engines/director/castmember/castmember.cpp
    engines/director/castmember/castmember.h
    engines/director/castmember/digitalvideo.cpp
    engines/director/castmember/digitalvideo.h
    engines/director/castmember/filmloop.cpp
    engines/director/castmember/filmloop.h
    engines/director/channel.cpp
    engines/director/channel.h
    engines/director/events.cpp
    engines/director/lingo/lingo-builtins.cpp
    engines/director/lingo/lingo-the.cpp
    engines/director/score.cpp
    engines/director/sprite.cpp
    engines/director/sprite.h


diff --git a/engines/director/castmember/bitmap.cpp b/engines/director/castmember/bitmap.cpp
index 52fd50bf632..ba3e3f3b356 100644
--- a/engines/director/castmember/bitmap.cpp
+++ b/engines/director/castmember/bitmap.cpp
@@ -675,6 +675,15 @@ void BitmapCastMember::setPicture(Image::ImageDecoder &image, bool adjustSize) {
 	setModified(true);
 }
 
+Common::Point BitmapCastMember::getRegistrationOffset() {
+	return Common::Point(_regX - _initialRect.left, _regY - _initialRect.top);
+}
+
+Common::Point BitmapCastMember::getRegistrationOffset(int16 width, int16 height) {
+	Common::Point offset = getRegistrationOffset();
+	return Common::Point(offset.x * width / _initialRect.width(), offset.y * height / _initialRect.height());
+}
+
 bool BitmapCastMember::hasField(int field) {
 	switch (field) {
 	case kTheDepth:
diff --git a/engines/director/castmember/bitmap.h b/engines/director/castmember/bitmap.h
index ee1efae3f97..9da0882bff5 100644
--- a/engines/director/castmember/bitmap.h
+++ b/engines/director/castmember/bitmap.h
@@ -55,6 +55,9 @@ public:
 	void setPicture(PictureReference &picture);
 	void setPicture(Image::ImageDecoder &image, bool adjustSize);
 
+	Common::Point getRegistrationOffset() override;
+	Common::Point getRegistrationOffset(int16 width, int16 height) override;
+
 	Picture *_picture = nullptr;
 	Graphics::Surface *_ditheredImg;
 	Graphics::FloodFill *_matte;
diff --git a/engines/director/castmember/castmember.cpp b/engines/director/castmember/castmember.cpp
index 2e1c4c29f9d..f14f7b12af8 100644
--- a/engines/director/castmember/castmember.cpp
+++ b/engines/director/castmember/castmember.cpp
@@ -72,6 +72,20 @@ void CastMember::setModified(bool modified) {
 		_isChanged = true;
 }
 
+Common::Rect CastMember::getBbox() {
+	Common::Rect result(_initialRect);
+	Common::Point offset = getRegistrationOffset();
+	result.moveTo(-offset.x, -offset.y);
+	return result;
+}
+
+Common::Rect CastMember::getBbox(int16 width, int16 height) {
+	Common::Rect result(width, height);
+	Common::Point offset = getRegistrationOffset(width, height);
+	result.moveTo(-offset.x, -offset.y);
+	return result;
+}
+
 bool CastMember::hasProp(const Common::String &propName) {
 	Common::String fieldName = Common::String::format("%d%s", kTheCast, propName.c_str());
 	return g_lingo->_theEntityFields.contains(fieldName) && hasField(g_lingo->_theEntityFields[fieldName]->field);
diff --git a/engines/director/castmember/castmember.h b/engines/director/castmember/castmember.h
index 1ac3a103b67..7603dfc12a0 100644
--- a/engines/director/castmember/castmember.h
+++ b/engines/director/castmember/castmember.h
@@ -86,6 +86,11 @@ public:
 
 	virtual Common::String formatInfo() { return Common::String(); };
 
+	virtual Common::Rect getBbox();
+	virtual Common::Rect getBbox(int16 width, int16 height);
+	virtual Common::Point getRegistrationOffset() { return Common::Point(0, 0); }
+	virtual Common::Point getRegistrationOffset(int16 width, int16 height) { return Common::Point(0, 0); }
+
 	CastType _type;
 	Common::Rect _initialRect;
 	Common::Rect _boundingRect;
diff --git a/engines/director/castmember/digitalvideo.cpp b/engines/director/castmember/digitalvideo.cpp
index d299d87502f..40f4028c872 100644
--- a/engines/director/castmember/digitalvideo.cpp
+++ b/engines/director/castmember/digitalvideo.cpp
@@ -324,6 +324,14 @@ Common::String DigitalVideoCastMember::formatInfo() {
 	);
 }
 
+Common::Point DigitalVideoCastMember::getRegistrationOffset() {
+	return Common::Point(_initialRect.width() / 2, _initialRect.height() / 2);
+}
+
+Common::Point DigitalVideoCastMember::getRegistrationOffset(int16 width, int16 height) {
+	return Common::Point(width / 2, height / 2);
+}
+
 bool DigitalVideoCastMember::hasField(int field) {
 	switch (field) {
 	case kTheCenter:
diff --git a/engines/director/castmember/digitalvideo.h b/engines/director/castmember/digitalvideo.h
index f2647b735d5..72b093b8f28 100644
--- a/engines/director/castmember/digitalvideo.h
+++ b/engines/director/castmember/digitalvideo.h
@@ -57,6 +57,9 @@ public:
 
 	Common::String formatInfo() override;
 
+	Common::Point getRegistrationOffset() override;
+	Common::Point getRegistrationOffset(int16 width, int16 height) override;
+
 	Common::String _filename;
 
 	uint32 _vflags;
diff --git a/engines/director/castmember/filmloop.cpp b/engines/director/castmember/filmloop.cpp
index 0074a4f53ad..4d33001b752 100644
--- a/engines/director/castmember/filmloop.cpp
+++ b/engines/director/castmember/filmloop.cpp
@@ -31,6 +31,7 @@
 #include "director/channel.h"
 #include "director/movie.h"
 #include "director/window.h"
+#include "director/castmember/bitmap.h"
 #include "director/castmember/filmloop.h"
 
 namespace Director {
@@ -88,7 +89,7 @@ Common::Array<Channel> *FilmLoopCastMember::getSubChannels(Common::Rect &bbox, C
 		int16 width = src._width * widgetRect.width() / _initialRect.width();
 		int16 height = src._height * widgetRect.height() / _initialRect.height();
 
-		Channel chan(&src);
+		Channel chan(nullptr, &src);
 		chan._currentPoint = Common::Point(absX, absY);
 		chan._width = width;
 		chan._height = height;
@@ -214,7 +215,10 @@ void FilmLoopCastMember::loadFilmLoopData(Common::SeekableReadStreamEndian &stre
 					s->_value._castId.asString().c_str(), s->_value._startPoint.x, s->_value._startPoint.y,
 					s->_value._width, s->_value._height);
 
-			Common::Point topLeft = s->_value._startPoint + s->_value.getRegistrationOffset();
+			Common::Point topLeft = s->_value._startPoint;
+			if (s->_value._cast) {
+				topLeft -= s->_value._cast->getRegistrationOffset(s->_value._width, s->_value._height);
+			}
 			Common::Rect spriteBbox(
 				topLeft.x,
 				topLeft.y,
@@ -353,7 +357,10 @@ void FilmLoopCastMember::loadFilmLoopDataV4(Common::SeekableReadStreamEndian &st
 					s->_value._castId.asString().c_str(), s->_value._startPoint.x, s->_value._startPoint.y,
 					s->_value._width, s->_value._height);
 
-			Common::Point topLeft = s->_value._startPoint + s->_value.getRegistrationOffset();
+			Common::Point topLeft = s->_value._startPoint;
+			if (s->_value._cast) {
+				topLeft -= s->_value._cast->getRegistrationOffset(s->_value._width, s->_value._height);
+			}
 			Common::Rect spriteBbox(
 				topLeft.x,
 				topLeft.y,
@@ -432,4 +439,12 @@ void FilmLoopCastMember::unload() {
 	// No unload necessary.
 }
 
+Common::Point FilmLoopCastMember::getRegistrationOffset() {
+	return Common::Point(_initialRect.width() / 2, _initialRect.height() / 2);
+}
+
+Common::Point FilmLoopCastMember::getRegistrationOffset(int16 width, int16 height) {
+	return Common::Point(width / 2, height / 2);
+}
+
 } // End of namespace Director
diff --git a/engines/director/castmember/filmloop.h b/engines/director/castmember/filmloop.h
index 1085990dc15..ebbebb21023 100644
--- a/engines/director/castmember/filmloop.h
+++ b/engines/director/castmember/filmloop.h
@@ -50,6 +50,9 @@ public:
 	void load() override;
 	void unload() override;
 
+	Common::Point getRegistrationOffset() override;
+	Common::Point getRegistrationOffset(int16 width, int16 height) override;
+
 	bool _enableSound;
 	bool _looping;
 	bool _crop;
diff --git a/engines/director/channel.cpp b/engines/director/channel.cpp
index 52e9c3aabd6..f92f867bda3 100644
--- a/engines/director/channel.cpp
+++ b/engines/director/channel.cpp
@@ -38,7 +38,8 @@
 
 namespace Director {
 
-Channel::Channel(Sprite *sp, int priority) {
+Channel::Channel(Score *sc, Sprite *sp, int priority) {
+	_score = sc;
 	if (!sp)
 		_sprite = nullptr;
 	else
@@ -46,7 +47,6 @@ Channel::Channel(Sprite *sp, int priority) {
 
 	_widget = nullptr;
 	_currentPoint = _sprite ? _sprite->_startPoint : Common::Point(0, 0);
-	_delta = Common::Point(0, 0);
 	_constraint = 0;
 	_mask = nullptr;
 
@@ -73,11 +73,11 @@ Channel::Channel(const Channel &channel) {
 }
 
 Channel& Channel::operator=(const Channel &channel) {
+	_score = channel._score;
 	_sprite = channel._sprite ? new Sprite(*channel._sprite) : nullptr;
 
 	_widget = nullptr;
 	_currentPoint = channel._currentPoint;
-	_delta = channel._delta;
 	_constraint = channel._constraint;
 	_mask = nullptr;
 
@@ -212,7 +212,6 @@ bool Channel::isDirty(Sprite *nextSprite) {
 		return false;
 
 	bool isDirtyFlag = _dirty ||
-		_delta != Common::Point(0, 0) ||
 		(_sprite->_cast && _sprite->_cast->isModified());
 
 	if (_sprite && !_sprite->_puppet) {
@@ -349,21 +348,10 @@ bool Channel::isVideoDirectToStage() {
 Common::Rect Channel::getBbox(bool unstretched) {
 	Common::Rect result(unstretched ? _sprite->_width : _width,
 						unstretched ? _sprite->_height : _height);
-	result.moveTo(getPosition());
-
-	if (_constraint > 0 && _constraint <= g_director->getCurrentMovie()->getScore()->_channels.size()) {
-		Common::Rect constraintBbox = g_director->getCurrentMovie()->getScore()->_channels[_constraint]->getBbox();
-		if (result.top < constraintBbox.top)
-			_currentPoint.y = constraintBbox.top;
-		if (result.left < constraintBbox.left)
-			_currentPoint.x = constraintBbox.left;
-		if (result.top > constraintBbox.bottom)
-			_currentPoint.y = constraintBbox.bottom;
-		if (result.left > constraintBbox.right)
-			_currentPoint.x = constraintBbox.right;
+	if (_sprite->_cast) {
+		result = _sprite->_cast->getBbox(_width, _height);
 	}
-	result.moveTo(getPosition());
-
+	result.translate(_currentPoint.x, _currentPoint.y);
 	return result;
 }
 
@@ -428,9 +416,6 @@ void Channel::setClean(Sprite *nextSprite, int spriteId, bool partial) {
 			previousCastId = _sprite->_castId;
 			replaceSprite(nextSprite);
 		}
-
-		_currentPoint += _delta;
-		_delta = Common::Point(0, 0);
 	}
 
 	// FIXME: organize the logic here.
@@ -575,13 +560,24 @@ void Channel::setBbox(int l, int t, int r, int b) {
 		_width = r - l;
 		_height = b - t;
 
-		_currentPoint.x = (int16)((l + r) / 2);
-		_currentPoint.y = (int16)((t + b) / 2);
-
-		addRegistrationOffset(_currentPoint, true);
+		Common::Rect source(_width, _height);
+		if (_sprite->_cast) {
+			source = _sprite->_cast->getBbox(_width, _height);
+		}
+		_currentPoint.x = (int16)(l - source.left);
+		_currentPoint.y = (int16)(t - source.top);
+	}
+}
 
-		_currentPoint.x -= (int16)((_sprite->_width) / 2);
-		_currentPoint.y -= (int16)((_sprite->_height) / 2);
+void Channel::setPosition(int x, int y) {
+	if (_sprite->_puppet) {
+		Common::Point newPos(x, y);
+		if (_constraint > 0 && _score && _constraint <= _score->_channels.size()) {
+			Common::Rect constraintBbox = _score->_channels[_constraint]->getBbox();
+			newPos.x = MIN(constraintBbox.right, MAX(constraintBbox.left, newPos.x));
+			newPos.y = MIN(constraintBbox.bottom, MAX(constraintBbox.top, newPos.y));
+		}
+		_currentPoint = newPos;
 	}
 }
 
@@ -660,69 +656,6 @@ bool Channel::isTrail() {
 	return _sprite->_trails;
 }
 
-void Channel::addRegistrationOffset(Common::Point &pos, bool subtract) {
-	if (!_sprite->_cast)
-		return;
-
-	switch (_sprite->_cast->_type) {
-	case kCastBitmap:
-		{
-			if (subtract)
-				pos -= _sprite->getRegistrationOffset();
-			else
-				pos += _sprite->getRegistrationOffset();
-		}
-		break;
-	case kCastDigitalVideo:
-	case kCastFilmLoop:
-		pos -= _sprite->getRegistrationOffset();
-	default:
-		break;
-	}
-	return;
-}
-
-void Channel::addDelta(Common::Point pos) {
-	// TODO: Channel should have a pointer to its score
-	if (_sprite->_moveable &&
-			_constraint > 0 &&
-			_constraint < g_director->getCurrentMovie()->getScore()->_channels.size()) {
-		Common::Rect constraintBbox = g_director->getCurrentMovie()->getScore()->_channels[_constraint]->getBbox();
-
-		Common::Rect currentBbox = getBbox();
-		currentBbox.translate(_delta.x + pos.x, _delta.y + pos.y);
-
-		Common::Point regPoint;
-		addRegistrationOffset(regPoint);
-
-		constraintBbox.top += regPoint.y;
-		constraintBbox.bottom -= regPoint.y;
-
-		constraintBbox.left += regPoint.x;
-		constraintBbox.right -= regPoint.x;
-
-		// offset for the boundary
-		constraintBbox.right++;
-		constraintBbox.bottom++;
-
-		if (!constraintBbox.contains(currentBbox)) {
-			if (currentBbox.top < constraintBbox.top) {
-				pos.y += constraintBbox.top - currentBbox.top;
-			} else if (currentBbox.top > constraintBbox.bottom) {
-				pos.y += constraintBbox.bottom;
-			}
-
-			if (currentBbox.left < constraintBbox.left) {
-				pos.x += constraintBbox.left - currentBbox.left;
-			} else if (currentBbox.left > constraintBbox.right) {
-				pos.x += constraintBbox.right;
-			}
-		}
-	}
-
-	_delta += pos;
-}
-
 int Channel::getMouseChar(int x, int y) {
 	if (_sprite->_spriteType != kTextSprite)
 		return -1;
@@ -771,16 +704,6 @@ int Channel::getMouseLine(int x, int y) {
 	return ((Graphics::MacText *)_widget)->getMouseLine(x, y);
 }
 
-Common::Point Channel::getPosition() {
-	Common::Point res = _currentPoint;
-	addRegistrationOffset(res);
-
-	res.x += (_sprite->_width - _width) / 2;
-	res.y += (_sprite->_height - _height) / 2;
-
-	return res;
-}
-
 bool Channel::hasSubChannels() {
 	if ((_sprite->_cast) && (_sprite->_cast->_type == kCastFilmLoop)) {
 		return true;
diff --git a/engines/director/channel.h b/engines/director/channel.h
index 626a0c5975d..a9bad4302e7 100644
--- a/engines/director/channel.h
+++ b/engines/director/channel.h
@@ -34,10 +34,11 @@ namespace Director {
 
 class Sprite;
 class Cursor;
+class Score;
 
 class Channel {
 public:
-	Channel(Sprite *sp, int priority = 0);
+	Channel(Score *sc, Sprite *sp, int priority = 0);
 	Channel(const Channel &channel);
 	Channel& operator=(const Channel &channel);
 	~Channel();
@@ -59,6 +60,7 @@ public:
 	void setWidth(int w);
 	void setHeight(int h);
 	void setBbox(int l, int t, int r, int b);
+	void setPosition(int x, int y);
 	void setCast(CastMemberID memberID);
 	void setClean(Sprite *nextSprite, int spriteId, bool partial = false);
 	void setEditable(bool editable);
@@ -71,7 +73,6 @@ public:
 
 	void updateGlobalAttr();
 
-	void addDelta(Common::Point pos);
 	bool canKeepWidget(CastMemberID castId);
 	bool canKeepWidget(Sprite *currentSprite, Sprite *nextSprite);
 
@@ -86,8 +87,6 @@ public:
 	bool hasSubChannels();
 	Common::Array<Channel> *getSubChannels();
 
-	void addRegistrationOffset(Common::Point &pos, bool subtract = false);
-
 public:
 	Sprite *_sprite;
 	Cursor _cursor;
@@ -97,7 +96,6 @@ public:
 	bool _visible;
 	uint _constraint;
 	Common::Point _currentPoint;
-	Common::Point _delta;
 	Graphics::ManagedSurface *_mask;
 
 	int _priority;
@@ -115,8 +113,7 @@ public:
 
 private:
 	Graphics::ManagedSurface *getSurface();
-	Common::Point getPosition();
-
+	Score *_score;
 };
 
 } // End of namespace Director
diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index e22dc8ce464..f85c62e39d2 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -161,8 +161,12 @@ bool Movie::processEvent(Common::Event &event) {
 		if (_currentDraggedChannel) {
 			if (_currentDraggedChannel->_sprite->_moveable) {
 				pos = _window->getMousePos();
-
-				_currentDraggedChannel->addDelta(pos - _draggingSpritePos);
+				if (!_currentDraggedChannel->_sprite->_trails) {
+					g_director->getCurrentMovie()->getWindow()->addDirtyRect(_currentDraggedChannel->getBbox());
+				}
+				_currentDraggedChannel->setPosition(pos.x, pos.y);
+				_currentDraggedChannel->_dirty = true;
+				g_director->getCurrentMovie()->getWindow()->addDirtyRect(_currentDraggedChannel->getBbox());
 				_draggingSpritePos = pos;
 			} else {
 				_currentDraggedChannel = nullptr;
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 9bef00da406..dddb9bdde9e 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -2699,14 +2699,14 @@ void LB::b_zoomBox(int nargs) {
 	Common::Rect endRect = score->_channels[endSpriteId]->getBbox();
 	if (endRect.isEmpty()) {
 		if ((uint)curFrame + 1 < score->_frames.size()) {
-			Channel endChannel(score->_frames[curFrame + 1]->_sprites[endSpriteId]);
+			Channel endChannel(nullptr, score->_frames[curFrame + 1]->_sprites[endSpriteId]);
 			endRect = endChannel.getBbox();
 		}
 	}
 
 	if (endRect.isEmpty()) {
 		if ((uint)curFrame - 1 > 0) {
-			Channel endChannel(score->_frames[curFrame - 1]->_sprites[endSpriteId]);
+			Channel endChannel(nullptr, score->_frames[curFrame - 1]->_sprites[endSpriteId]);
 			endRect = endChannel.getBbox();
 		}
 	}
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 44d33a6d9cb..28a7fba0145 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -1550,9 +1550,7 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
 			movie->getWindow()->addDirtyRect(channel->getBbox());
 			channel->_dirty = true;
 		}
-
-		channel->_currentPoint.x = d.asPoint().x;
-		channel->_currentPoint.y = d.asPoint().y;
+		channel->setPosition(d.asPoint().x, d.asPoint().y);
 		break;
 	case kTheLocH:
 		if (d.asInt() != channel->_currentPoint.x) {
@@ -1562,7 +1560,7 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
 				movie->getWindow()->addDirtyRect(channel->getBbox());
 				channel->_dirty = true;
 			}
-			channel->_currentPoint.x = d.asInt();
+			channel->setPosition(d.asInt(), channel->_currentPoint.y);
 		}
 		break;
 	case kTheLocV:
@@ -1571,7 +1569,7 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
 				movie->getWindow()->addDirtyRect(channel->getBbox());
 				channel->_dirty = true;
 			}
-			channel->_currentPoint.y = d.asInt();
+			channel->setPosition(channel->_currentPoint.x, d.asInt());
 		}
 		break;
 	case kTheMoveableSprite:
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index e8d6d7419f9..02fbd690375 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -278,7 +278,7 @@ void Score::startPlay() {
 	// All frames in the same movie have the same number of channels
 	if (_playState != kPlayStopped)
 		for (uint i = 0; i < _frames[1]->_sprites.size(); i++)
-			_channels.push_back(new Channel(_frames[1]->_sprites[i], i));
+			_channels.push_back(new Channel(this, _frames[1]->_sprites[i], i));
 
 	if (_vm->getVersion() >= 300)
 		_movie->processEvent(kEventStartMovie);
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index a3c33b5cbcc..39d92e59be2 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -278,37 +278,6 @@ uint32 Sprite::getForeColor() {
 	}
 }
 
-Common::Point Sprite::getRegistrationOffset() {
-	Common::Point result(0, 0);
-	if (!_cast)
-		return result;
-
-	switch (_cast->_type) {
-	case kCastBitmap:
-		{
-			BitmapCastMember *bc = (BitmapCastMember *)(_cast);
-
-			// stretch the offset
-			if (!_stretch && (_width != bc->_initialRect.width() || _height != bc->_initialRect.height())) {
-				result.x = (bc->_initialRect.left - bc->_regX) * _width / bc->_initialRect.width();
-				result.y = (bc->_initialRect.top - bc->_regY) * _height / bc->_initialRect.height();
-			} else {
-				result.x = bc->_initialRect.left - bc->_regX;
-				result.y = bc->_initialRect.top - bc->_regY;
-			}
-		}
-		break;
-	case kCastDigitalVideo:
-	case kCastFilmLoop:
-		result.x = _cast->_initialRect.width() >> 1;
-		result.y = _cast->_initialRect.height() >> 1;
-		break;
-	default:
-		break;
-	}
-	return result;
-}
-
 void Sprite::updateEditable() {
 	if (!_cast)
 		return;
diff --git a/engines/director/sprite.h b/engines/director/sprite.h
index 340cd7f0756..4e7357f81a9 100644
--- a/engines/director/sprite.h
+++ b/engines/director/sprite.h
@@ -83,7 +83,6 @@ public:
 	MacShape *getShape();
 	uint32 getForeColor();
 	uint32 getBackColor();
-	Common::Point getRegistrationOffset();
 
 	Frame *_frame;
 	Score *_score;


Commit: 9ec6722b6a607ed72eb58ce94107792dcecab84d
    https://github.com/scummvm/scummvm/commit/9ec6722b6a607ed72eb58ce94107792dcecab84d
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-28T14:44:09+02:00

Commit Message:
DIRECTOR: Remove inkBlitStretchSurface()

No longer needed, the scaling should happen when updating the widget.

Fixes adjusting sprites with Lingo, such as in DEVO Presents:
Adventures of the Smart Patrol.

Changed paths:
    engines/director/director.h
    engines/director/graphics.cpp
    engines/director/window.cpp


diff --git a/engines/director/director.h b/engines/director/director.h
index 3018c5b774f..11a3043bc79 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -320,7 +320,6 @@ struct DirectorPlotData {
 	uint32 preprocessColor(uint32 src);
 	void inkBlitShape(Common::Rect &srcRect);
 	void inkBlitSurface(Common::Rect &srcRect, const Graphics::Surface *mask);
-	void inkBlitStretchSurface(Common::Rect &srcRect, const Graphics::Surface *mask);
 
 	DirectorPlotData(DirectorEngine *d_, SpriteType s, InkType i, int a, uint32 b, uint32 f) : d(d_), sprite(s), ink(i), alpha(a), backColor(b), foreColor(f) {
 		colorWhite = d->_wm->_colorWhite;
diff --git a/engines/director/graphics.cpp b/engines/director/graphics.cpp
index 3f824f2efb4..5d0f6fd1ac5 100644
--- a/engines/director/graphics.cpp
+++ b/engines/director/graphics.cpp
@@ -675,42 +675,4 @@ void DirectorPlotData::inkBlitSurface(Common::Rect &srcRect, const Graphics::Sur
 
 }
 
-void DirectorPlotData::inkBlitStretchSurface(Common::Rect &srcRect, const Graphics::Surface *mask) {
-	if (!srf)
-		return;
-
-	// TODO: Determine why colourization causes problems in Warlock
-	if (sprite == kTextSprite)
-		applyColor = false;
-
-	int scaleX = SCALE_THRESHOLD * srcRect.width() / destRect.width();
-	int scaleY = SCALE_THRESHOLD * srcRect.height() / destRect.height();
-
-	srcPoint.y = abs(srcRect.top - destRect.top);
-
-	for (int i = 0, scaleYCtr = 0; i < destRect.height(); i++, scaleYCtr += scaleY, srcPoint.y++) {
-		if (d->_wm->_pixelformat.bytesPerPixel == 1) {
-			srcPoint.x = abs(srcRect.left - destRect.left);
-			const byte *msk = mask ? (const byte *)mask->getBasePtr(srcPoint.x, srcPoint.y) : nullptr;
-
-			for (int xCtr = 0, scaleXCtr = 0; xCtr < destRect.width(); xCtr++, scaleXCtr += scaleX, srcPoint.x++) {
-				if (!mask || !(*msk++)) {
-				(d->getInkDrawPixel())(destRect.left + xCtr, destRect.top + i,
-										preprocessColor(*((byte *)srf->getBasePtr(scaleXCtr / SCALE_THRESHOLD, scaleYCtr / SCALE_THRESHOLD))), this);
-				}
-			}
-		} else {
-			srcPoint.x = abs(srcRect.left - destRect.left);
-			const uint32 *msk = mask ? (const uint32 *)mask->getBasePtr(srcPoint.x, srcPoint.y) : nullptr;
-
-			for (int xCtr = 0, scaleXCtr = 0; xCtr < destRect.width(); xCtr++, scaleXCtr += scaleX, srcPoint.x++) {
-				if (!mask || !(*msk++)) {
-				(d->getInkDrawPixel())(destRect.left + xCtr, destRect.top + i,
-										preprocessColor(*((int *)srf->getBasePtr(scaleXCtr / SCALE_THRESHOLD, scaleYCtr / SCALE_THRESHOLD))), this);
-				}
-			}
-		}
-	}
-}
-
 } // End of namespace Director
diff --git a/engines/director/window.cpp b/engines/director/window.cpp
index 4cea2b48144..a1bc99b23e4 100644
--- a/engines/director/window.cpp
+++ b/engines/director/window.cpp
@@ -242,12 +242,7 @@ void Window::inkBlitFrom(Channel *channel, Common::Rect destRect, Graphics::Mana
 	if (pd.ms) {
 		pd.inkBlitShape(srcRect);
 	} else if (pd.srf) {
-		if (channel->isStretched()) {
-			srcRect = channel->getBbox(true);
-			pd.inkBlitStretchSurface(srcRect, channel->getMask());
-		} else {
-			pd.inkBlitSurface(srcRect, channel->getMask());
-		}
+		pd.inkBlitSurface(srcRect, channel->getMask());
 	} else {
 		if (debugChannelSet(kDebugImages, 4)) {
 			CastType castType = channel->_sprite->_cast ? channel->_sprite->_cast->_type : kCastTypeNull;


Commit: 96c33ca4e8a70922925a730db432cd9a87fbee8f
    https://github.com/scummvm/scummvm/commit/96c33ca4e8a70922925a730db432cd9a87fbee8f
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-28T14:44:09+02:00

Commit Message:
DIRECTOR: Fix D5 palette fade times

Changed paths:
    engines/director/palette-fade.h


diff --git a/engines/director/palette-fade.h b/engines/director/palette-fade.h
index f2fd60545cc..d9d956b25e0 100644
--- a/engines/director/palette-fade.h
+++ b/engines/director/palette-fade.h
@@ -164,9 +164,9 @@ static int kFadeColorFrames[30] = {
 };
 
 static int kFadeColorFramesD5[30] = {
-	989, 955, 921, 887, 852, 818, 783, 750, 715, 680,
-	646, 612, 578, 543, 509, 475, 440, 406, 372, 337,
-	303, 269, 234, 200, 166, 131, 97, 63, 28, 1
+	494, 478, 460, 444, 426, 409, 392, 375, 358, 340,
+	323, 306, 289, 272, 254, 238, 220, 203, 186, 168,
+	152, 134, 117, 100, 83, 66, 48, 32, 14, 1
 };
 
 static int kFadeColorWait = 30;


Commit: 4090a22782a0d653a6ade8ea9842d50938e6e1c4
    https://github.com/scummvm/scummvm/commit/4090a22782a0d653a6ade8ea9842d50938e6e1c4
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-28T14:44:09+02:00

Commit Message:
DIRECTOR: Fix divide by zero

Changed paths:
    engines/director/castmember/bitmap.cpp


diff --git a/engines/director/castmember/bitmap.cpp b/engines/director/castmember/bitmap.cpp
index ba3e3f3b356..6640bd021e5 100644
--- a/engines/director/castmember/bitmap.cpp
+++ b/engines/director/castmember/bitmap.cpp
@@ -681,7 +681,7 @@ Common::Point BitmapCastMember::getRegistrationOffset() {
 
 Common::Point BitmapCastMember::getRegistrationOffset(int16 width, int16 height) {
 	Common::Point offset = getRegistrationOffset();
-	return Common::Point(offset.x * width / _initialRect.width(), offset.y * height / _initialRect.height());
+	return Common::Point(offset.x * width / MAX((int16)1, _initialRect.width()), offset.y * height / MAX((int16)1, _initialRect.height()));
 }
 
 bool BitmapCastMember::hasField(int field) {


Commit: cf886b17e7e2d1487f2dc2b72e35d962a6c2b7fe
    https://github.com/scummvm/scummvm/commit/cf886b17e7e2d1487f2dc2b72e35d962a6c2b7fe
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-28T14:44:09+02:00

Commit Message:
DIRECTOR: Fix regression in sprite dragging

Sprites with the movable attribute set do not need to be a puppet.

Changed paths:
    engines/director/channel.cpp
    engines/director/channel.h
    engines/director/events.cpp


diff --git a/engines/director/channel.cpp b/engines/director/channel.cpp
index f92f867bda3..205edb45b7f 100644
--- a/engines/director/channel.cpp
+++ b/engines/director/channel.cpp
@@ -569,8 +569,8 @@ void Channel::setBbox(int l, int t, int r, int b) {
 	}
 }
 
-void Channel::setPosition(int x, int y) {
-	if (_sprite->_puppet) {
+void Channel::setPosition(int x, int y, bool force) {
+	if (_sprite->_puppet || force) {
 		Common::Point newPos(x, y);
 		if (_constraint > 0 && _score && _constraint <= _score->_channels.size()) {
 			Common::Rect constraintBbox = _score->_channels[_constraint]->getBbox();
diff --git a/engines/director/channel.h b/engines/director/channel.h
index a9bad4302e7..92d1c786160 100644
--- a/engines/director/channel.h
+++ b/engines/director/channel.h
@@ -60,7 +60,7 @@ public:
 	void setWidth(int w);
 	void setHeight(int h);
 	void setBbox(int l, int t, int r, int b);
-	void setPosition(int x, int y);
+	void setPosition(int x, int y, bool force = false);
 	void setCast(CastMemberID memberID);
 	void setClean(Sprite *nextSprite, int spriteId, bool partial = false);
 	void setEditable(bool editable);
diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index f85c62e39d2..dc697d9288d 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -164,7 +164,7 @@ bool Movie::processEvent(Common::Event &event) {
 				if (!_currentDraggedChannel->_sprite->_trails) {
 					g_director->getCurrentMovie()->getWindow()->addDirtyRect(_currentDraggedChannel->getBbox());
 				}
-				_currentDraggedChannel->setPosition(pos.x, pos.y);
+				_currentDraggedChannel->setPosition(pos.x, pos.y, true);
 				_currentDraggedChannel->_dirty = true;
 				g_director->getCurrentMovie()->getWindow()->addDirtyRect(_currentDraggedChannel->getBbox());
 				_draggingSpritePos = pos;


Commit: 4bf4e4a4a060c6067ac1656a24a99805d8426f84
    https://github.com/scummvm/scummvm/commit/4bf4e4a4a060c6067ac1656a24a99805d8426f84
Author: Scott Percival (code at moral.net.au)
Date: 2023-05-28T14:44:09+02:00

Commit Message:
DIRECTOR: Fixes based on feedback

Changed paths:
    engines/director/castmember/castmember.cpp
    engines/director/castmember/castmember.h
    engines/director/castmember/filmloop.cpp
    engines/director/castmember/filmloop.h
    engines/director/score.cpp


diff --git a/engines/director/castmember/castmember.cpp b/engines/director/castmember/castmember.cpp
index f14f7b12af8..4b5eb6f848a 100644
--- a/engines/director/castmember/castmember.cpp
+++ b/engines/director/castmember/castmember.cpp
@@ -79,9 +79,9 @@ Common::Rect CastMember::getBbox() {
 	return result;
 }
 
-Common::Rect CastMember::getBbox(int16 width, int16 height) {
-	Common::Rect result(width, height);
-	Common::Point offset = getRegistrationOffset(width, height);
+Common::Rect CastMember::getBbox(int16 currentWidth, int16 currentHeight) {
+	Common::Rect result(currentWidth, currentHeight);
+	Common::Point offset = getRegistrationOffset(currentWidth, currentHeight);
 	result.moveTo(-offset.x, -offset.y);
 	return result;
 }
diff --git a/engines/director/castmember/castmember.h b/engines/director/castmember/castmember.h
index 7603dfc12a0..af16b96b8e8 100644
--- a/engines/director/castmember/castmember.h
+++ b/engines/director/castmember/castmember.h
@@ -86,10 +86,16 @@ public:
 
 	virtual Common::String formatInfo() { return Common::String(); };
 
+	// Return the default bounding box of the cast member. The origin is at the registration offset.
 	virtual Common::Rect getBbox();
-	virtual Common::Rect getBbox(int16 width, int16 height);
+	// Return the bounding box of the cast member, assuming a stretched width and height value.
+	// The origin is at the registration offset.
+	virtual Common::Rect getBbox(int16 currentWidth, int16 currentHeight);
+	// Return the default registration offset. Offset is relative to the top-left corner of the widget.
 	virtual Common::Point getRegistrationOffset() { return Common::Point(0, 0); }
-	virtual Common::Point getRegistrationOffset(int16 width, int16 height) { return Common::Point(0, 0); }
+	// Return the registration offset, assuming a stretched width and height value.
+	// Offset is relative to the top-left corner of the widget.
+	virtual Common::Point getRegistrationOffset(int16 currentWidth, int16 currentHeight) { return Common::Point(0, 0); }
 
 	CastType _type;
 	Common::Rect _initialRect;
diff --git a/engines/director/castmember/filmloop.cpp b/engines/director/castmember/filmloop.cpp
index 4d33001b752..054221ef829 100644
--- a/engines/director/castmember/filmloop.cpp
+++ b/engines/director/castmember/filmloop.cpp
@@ -89,6 +89,9 @@ Common::Array<Channel> *FilmLoopCastMember::getSubChannels(Common::Rect &bbox, C
 		int16 width = src._width * widgetRect.width() / _initialRect.width();
 		int16 height = src._height * widgetRect.height() / _initialRect.height();
 
+		// Film loop frames are constructed as a series of Channels, much like how a normal frame 
+		// is rendered by the Score. We don't include a pointer to the current Score here,
+		// that's only for querying the constraint channel which is not used.
 		Channel chan(nullptr, &src);
 		chan._currentPoint = Common::Point(absX, absY);
 		chan._width = width;
@@ -443,8 +446,8 @@ Common::Point FilmLoopCastMember::getRegistrationOffset() {
 	return Common::Point(_initialRect.width() / 2, _initialRect.height() / 2);
 }
 
-Common::Point FilmLoopCastMember::getRegistrationOffset(int16 width, int16 height) {
-	return Common::Point(width / 2, height / 2);
+Common::Point FilmLoopCastMember::getRegistrationOffset(int16 currentWidth, int16 currentHeight) {
+	return Common::Point(currentWidth / 2, currentHeight / 2);
 }
 
 } // End of namespace Director
diff --git a/engines/director/castmember/filmloop.h b/engines/director/castmember/filmloop.h
index ebbebb21023..aa00ca820a4 100644
--- a/engines/director/castmember/filmloop.h
+++ b/engines/director/castmember/filmloop.h
@@ -51,7 +51,7 @@ public:
 	void unload() override;
 
 	Common::Point getRegistrationOffset() override;
-	Common::Point getRegistrationOffset(int16 width, int16 height) override;
+	Common::Point getRegistrationOffset(int16 currentWidth, int16 currentHeight) override;
 
 	bool _enableSound;
 	bool _looping;
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 02fbd690375..efa8b8033ed 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -1631,13 +1631,13 @@ Common::String Score::formatChannelInfo() {
 		Channel &channel = *_channels[i + 1];
 		Sprite &sprite = *channel._sprite;
 		if (sprite._castId.member) {
-			result += Common::String::format("CH: %-3d castId: %s, visible: %d, [inkData: 0x%02x [ink: %d, trails: %d, line: %d], %dx%d@%d,%d type: %d (%s) fg: %d bg: %d], script: %s, colorcode: 0x%x, blendAmount: 0x%x, unk3: 0x%x, constraint: %d, puppet: %d, stretch: %d\n",
+			result += Common::String::format("CH: %-3d castId: %s, visible: %d, [inkData: 0x%02x [ink: %d, trails: %d, line: %d], %dx%d@%d,%d type: %d (%s) fg: %d bg: %d], script: %s, colorcode: 0x%x, blendAmount: 0x%x, unk3: 0x%x, constraint: %d, puppet: %d, stretch: %d, moveable: %d\n",
 				i + 1, sprite._castId.asString().c_str(), channel._visible, sprite._inkData,
 				sprite._ink, sprite._trails, sprite._thickness, channel._width, channel._height,
 				channel._currentPoint.x, channel._currentPoint.y,
 				sprite._spriteType, spriteType2str(sprite._spriteType), sprite._foreColor, sprite._backColor,
 				sprite._scriptId.asString().c_str(), sprite._colorcode, sprite._blendAmount, sprite._unk3,
-				channel._constraint, sprite._puppet, sprite._stretch);
+				channel._constraint, sprite._puppet, sprite._stretch, sprite._moveable);
 		} else {
 			result += Common::String::format("CH: %-3d castId: 000\n", i + 1);
 		}




More information about the Scummvm-git-logs mailing list