[Scummvm-git-logs] scummvm master -> d3c7c3cbc830d5b8ba287c67f17d25f52d287bb1

moralrecordings code at moral.net.au
Sat May 23 13:34:39 UTC 2020


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

Summary:
14d5b982d5 DIRECTOR: LINGO: Buffer events when calling b_updateStage
7be0816f3f DIRECTOR: Move sprite bounding box calculation into class method
d3c7c3cbc8 DIRECTOR: Simplify dirty sprite check


Commit: 14d5b982d5ac9bd6a9dfc1c13982a2947da4ec61
    https://github.com/scummvm/scummvm/commit/14d5b982d5ac9bd6a9dfc1c13982a2947da4ec61
Author: Scott Percival (code at moral.net.au)
Date: 2020-05-23T21:33:50+08:00

Commit Message:
DIRECTOR: LINGO: Buffer events when calling b_updateStage

Changed paths:
    engines/director/lingo/lingo-builtins.cpp


diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 2d7944e04c..e72924e119 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -1817,8 +1817,8 @@ void LB::b_updateStage(int nargs) {
 		return;
 	}
 
-	score->renderFrame( score->getCurrentFrame(), false, true);
-	processQuitEvent();
+	score->renderFrame(score->getCurrentFrame(), false, true);
+	g_director->processEvents(true);
 
 	if (debugChannelSet(-1, kDebugFewFramesOnly))
 		score->_framesRan++;


Commit: 7be0816f3fc7d5d98c84650c35c9821c14d2b35d
    https://github.com/scummvm/scummvm/commit/7be0816f3fc7d5d98c84650c35c9821c14d2b35d
Author: Scott Percival (code at moral.net.au)
Date: 2020-05-23T21:33:51+08:00

Commit Message:
DIRECTOR: Move sprite bounding box calculation into class method

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 632d8d80bd..7eb3a2f362 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -773,122 +773,7 @@ void Score::setSpriteBboxes() {
 	for (uint16 i = 0; i < _frames.size(); i++) {
 		for (uint16 j = 0; j < _frames[i]->_sprites.size(); j++) {
 			Sprite *sp = _frames[i]->_sprites[j];
-
-			if (sp->_castId == 0)
-				continue;
-
-			CastType castType = sp->_castType;
-
-			switch (castType) {
-			case kCastShape:
-				sp->_startBbox = Common::Rect(sp->_currentPoint.x,
-											  sp->_currentPoint.y,
-											  sp->_currentPoint.x + sp->_width,
-											  sp->_currentPoint.y + sp->_height);
-				break;
-			case kCastRTE:
-			case kCastText: {
-				TextCast *textCast = (TextCast*)sp->_cast;
-				int x = sp->_currentPoint.x; // +rectLeft;
-				int y = sp->_currentPoint.y; // +rectTop;
-				int height = textCast->_initialRect.height(); //_sprites[spriteId]->_height;
-				int width;
-				Common::Rect *textRect = NULL;
-
-				if (_vm->getVersion() >= 4) {
-					// where does textRect come from?
-					if (textRect == NULL) {
-						width = textCast->_initialRect.right;
-					} else {
-						width = textRect->width();
-					}
-				} else {
-					width = textCast->_initialRect.width(); //_sprites[spriteId]->_width;
-				}
-
-				sp->_startBbox = Common::Rect(x, y, x + width, y + height);
-				break;
-			}
-			case kCastButton: {
-				uint16 castId = sp->_castId;
-
-				// This may not be a button cast. It could be a textcast with the
-				// channel forcing it to be a checkbox or radio button!
-				ButtonCast *button = (ButtonCast *)_vm->getCurrentScore()->_loadedCast->getVal(castId);
-
-				// Sometimes, at least in the D3 Workshop Examples, these buttons are
-				// just TextCast. If they are, then we just want to use the spriteType
-				// as the button type. If they are full-bown Cast members, then use the
-				// actual cast member type.
-				int buttonType = sp->_spriteType;
-				if (buttonType == kCastMemberSprite) {
-					switch (button->_buttonType) {
-					case kTypeCheckBox:
-						buttonType = kCheckboxSprite;
-						break;
-					case kTypeButton:
-						buttonType = kButtonSprite;
-						break;
-					case kTypeRadio:
-						buttonType = kRadioButtonSprite;
-						break;
-					}
-				}
-
-				uint32 rectLeft = button->_initialRect.left;
-				uint32 rectTop = button->_initialRect.top;
-
-				int x = sp->_currentPoint.x;
-				int y = sp->_currentPoint.y;
-
-				if (_vm->getVersion() > 3) {
-					x += rectLeft;
-					y += rectTop;
-				}
-
-				int height = button->_initialRect.height();
-				int width = button->_initialRect.width() + 3;
-
-				switch (buttonType) {
-				case kCheckboxSprite:
-					// Magic numbers: checkbox square need to move left about 5px from
-					// text and 12px side size (D4)
-					sp->_startBbox = Common::Rect(x, y + 2, x + 12, y + 14);
-					break;
-				case kButtonSprite:
-					sp->_startBbox = Common::Rect(x, y, x + width, y + height + 3);
-					break;
-				case kRadioButtonSprite:
-					sp->_startBbox = Common::Rect(x, y + 2, x + 12, y + 14);
-					break;
-				default:
-					warning("Score::setSpriteBboxes: Unknown buttonType");
-				}
-				break;
-			}
-			case kCastBitmap: {
-				BitmapCast *bc = (BitmapCast *)sp->_cast;
-
-				int32 regX = bc->_regX;
-				int32 regY = bc->_regY;
-				int32 rectLeft = bc->_initialRect.left;
-				int32 rectTop = bc->_initialRect.top;
-
-				int x = sp->_currentPoint.x - regX + rectLeft;
-				int y = sp->_currentPoint.y - regY + rectTop;
-				int height = sp->_height;
-				int width = _vm->getVersion() > 4 ? bc->_initialRect.width() : sp->_width;
-
-				// If one of the dimensions is invalid, invalidate whole thing
-				if (width == 0 || height == 0)
-					width = height = 0;
-
-				sp->_startBbox = Common::Rect(x, y, x + width, y + height);
-				break;
-			}
-			default:
-				warning("Score::setSpriteBboxes(): Unhandled cast type: %d, frame %d, channel %d", castType, i, j);
-			}
+			sp->_startBbox = sp->getBbox();
 			sp->_currentBbox = sp->_startBbox;
 			sp->_dirtyBbox = sp->_startBbox;
 		}
@@ -1848,6 +1733,10 @@ void Score::renderFrame(uint16 frameId, bool forceUpdate, bool updateStageOnly)
 		else
 			nextSprite = currentFrame->_sprites[i];
 
+		// A sprite needs to be updated if one of the following happens:
+		// - The dimensions/bounding box of the sprite has changed (_dirty flag set)
+		// - The cast member ID of the sprite has changed (_dirty flag set)
+		// - The sprite slot from the current frame is different (cast member ID or bounding box) from the cached sprite slot
 		bool needsUpdate = (currentSprite->_currentBbox != nextSprite->_currentBbox || currentSprite->_currentBbox != currentSprite->_dirtyBbox);
 
 		if (needsUpdate || forceUpdate)
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index 0f8b203f1e..2605d56b5f 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -45,6 +45,7 @@ Sprite::Sprite() {
 	_cast = nullptr;
 
 	_thickness = 0;
+	_dirty = false;
 	_width = 0;
 	_height = 0;
 	_constraint = 0;
@@ -167,6 +168,125 @@ void Sprite::setCast(uint16 castId) {
 			_castType = member->_type;
 		}
 	}
+	_dirty = true;
+}
+
+Common::Rect Sprite::getBbox() {
+	Common::Rect result;
+	if (_castId == 0) {
+		warning("Sprite::getBbox(): attempted to get bbox for null cast member");
+		return result;
+	}
+
+	switch (_castType) {
+	case kCastShape:
+		result = Common::Rect(_currentPoint.x,
+								_currentPoint.y,
+								_currentPoint.x + _width,
+								_currentPoint.y + _height);
+		break;
+	case kCastRTE:
+	case kCastText: {
+		TextCast *textCast = (TextCast*)_cast;
+		int x = _currentPoint.x; // +rectLeft;
+		int y = _currentPoint.y; // +rectTop;
+		int height = textCast->_initialRect.height(); //_sprites[spriteId]->_height;
+		int width;
+		Common::Rect *textRect = NULL;
+
+		if (g_director->getVersion() >= 4) {
+			// where does textRect come from?
+			if (textRect == NULL) {
+				width = textCast->_initialRect.right;
+			} else {
+				width = textRect->width();
+			}
+		} else {
+			width = textCast->_initialRect.width(); //_sprites[spriteId]->_width;
+		}
+
+		result = Common::Rect(x, y, x + width, y + height);
+		break;
+	}
+	case kCastButton: {
+		// This may not be a button cast. It could be a textcast with the
+		// channel forcing it to be a checkbox or radio button!
+		ButtonCast *button = (ButtonCast *)_cast;
+
+		// Sometimes, at least in the D3 Workshop Examples, these buttons are
+		// just TextCast. If they are, then we just want to use the spriteType
+		// as the button type. If they are full-bown Cast members, then use the
+		// actual cast member type.
+		int buttonType = _spriteType;
+		if (buttonType == kCastMemberSprite) {
+			switch (button->_buttonType) {
+			case kTypeCheckBox:
+				buttonType = kCheckboxSprite;
+				break;
+			case kTypeButton:
+				buttonType = kButtonSprite;
+				break;
+			case kTypeRadio:
+				buttonType = kRadioButtonSprite;
+				break;
+			}
+		}
+
+		uint32 rectLeft = button->_initialRect.left;
+		uint32 rectTop = button->_initialRect.top;
+
+		int x = _currentPoint.x;
+		int y = _currentPoint.y;
+
+		if (g_director->getVersion() > 3) {
+			x += rectLeft;
+			y += rectTop;
+		}
+
+		int height = button->_initialRect.height();
+		int width = button->_initialRect.width() + 3;
+
+		switch (buttonType) {
+		case kCheckboxSprite:
+			// Magic numbers: checkbox square need to move left about 5px from
+			// text and 12px side size (D4)
+			_startBbox = Common::Rect(x, y + 2, x + 12, y + 14);
+			break;
+		case kButtonSprite:
+			_startBbox = Common::Rect(x, y, x + width, y + height + 3);
+			break;
+		case kRadioButtonSprite:
+			_startBbox = Common::Rect(x, y + 2, x + 12, y + 14);
+			break;
+		default:
+			warning("Score::getBbox(): Unknown buttonType");
+		}
+		break;
+	}
+	case kCastBitmap: {
+		BitmapCast *bc = (BitmapCast *)_cast;
+
+		int32 regX = bc->_regX;
+		int32 regY = bc->_regY;
+		int32 rectLeft = bc->_initialRect.left;
+		int32 rectTop = bc->_initialRect.top;
+
+		int x = _currentPoint.x - regX + rectLeft;
+		int y = _currentPoint.y - regY + rectTop;
+		int height = _height;
+		int width = g_director->getVersion() > 4 ? bc->_initialRect.width() : _width;
+
+		// If one of the dimensions is invalid, invalidate whole thing
+		if (width == 0 || height == 0)
+			width = height = 0;
+
+		result = Common::Rect(x, y, x + width, y + height);
+		break;
+	}
+	default:
+		warning("Sprite::getBbox(): Unhandled cast type: %d", _castType);
+	}
+	return result;
 }
 
 
diff --git a/engines/director/sprite.h b/engines/director/sprite.h
index 7a70feb7c4..f342e4a3d0 100644
--- a/engines/director/sprite.h
+++ b/engines/director/sprite.h
@@ -67,6 +67,8 @@ public:
 
 	void setCast(uint16 castid);
 
+	Common::Rect getBbox();
+
 	uint16 _scriptId;
 	uint16 _scriptCastIndex;
 	byte _colorcode;  // x40 editable, 0x80 moveable
@@ -85,6 +87,7 @@ public:
 	Cast *_cast;
 
 	byte _thickness;
+	bool _dirty;
 	Common::Point _startPoint;
 	Common::Point _currentPoint;
 	Common::Rect _startBbox;


Commit: d3c7c3cbc830d5b8ba287c67f17d25f52d287bb1
    https://github.com/scummvm/scummvm/commit/d3c7c3cbc830d5b8ba287c67f17d25f52d287bb1
Author: Scott Percival (code at moral.net.au)
Date: 2020-05-23T21:33:51+08:00

Commit Message:
DIRECTOR: Simplify dirty sprite check

Changed paths:
    engines/director/events.cpp
    engines/director/lingo/lingo-the.cpp
    engines/director/score.cpp
    engines/director/sprite.h


diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index 6af7ef8ed4..836df726b6 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -87,7 +87,7 @@ void DirectorEngine::processEvents(bool bufferLingoEvents) {
 						Common::Point delta = pos - _draggingSpritePos;
 						draggedSprite->_currentPoint.x += delta.x;
 						draggedSprite->_currentPoint.y += delta.y;
-						draggedSprite->_dirtyBbox.translate(delta.x, delta.y);
+						draggedSprite->_dirty = true;
 						_draggingSpritePos = pos;
 					} else {
 						releaseDraggedSprite();
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 8e1d4008ec..18323bc9b6 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -717,7 +717,6 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
 		sprite->_moveable = d.asInt();
 		if (!d.u.i) {
 			sprite->_currentPoint = sprite->_startPoint;
-			sprite->_dirtyBbox = sprite->_startBbox;
 		}
 		break;
 	case kTheMovieRate:
@@ -733,7 +732,6 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
 		sprite->_puppet = d.asInt();
 		if (!d.u.i) {
 			sprite->_currentPoint = sprite->_startPoint;
-			sprite->_dirtyBbox = sprite->_startBbox;
 		}
 		break;
 	case kTheStartTime:
@@ -764,6 +762,7 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
 	default:
 		warning("Lingo::setTheSprite(): Unprocessed setting field \"%s\" of sprite", field2str(field));
 	}
+	sprite->_dirty = true;
 }
 
 Datum Lingo::getTheCast(Datum &id1, int field) {
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 7eb3a2f362..f5d663b8e5 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -770,12 +770,12 @@ void Score::setSpriteCasts() {
 }
 
 void Score::setSpriteBboxes() {
+	// Initialise the sprite cache for all the initial bounding boxes
 	for (uint16 i = 0; i < _frames.size(); i++) {
 		for (uint16 j = 0; j < _frames[i]->_sprites.size(); j++) {
 			Sprite *sp = _frames[i]->_sprites[j];
 			sp->_startBbox = sp->getBbox();
 			sp->_currentBbox = sp->_startBbox;
-			sp->_dirtyBbox = sp->_startBbox;
 		}
 	}
 }
@@ -1737,7 +1737,8 @@ void Score::renderFrame(uint16 frameId, bool forceUpdate, bool updateStageOnly)
 		// - The dimensions/bounding box of the sprite has changed (_dirty flag set)
 		// - The cast member ID of the sprite has changed (_dirty flag set)
 		// - The sprite slot from the current frame is different (cast member ID or bounding box) from the cached sprite slot
-		bool needsUpdate = (currentSprite->_currentBbox != nextSprite->_currentBbox || currentSprite->_currentBbox != currentSprite->_dirtyBbox);
+		// (maybe we have to compare all the sprite attributes, not just these two?)
+		bool needsUpdate = currentSprite->_dirty || currentSprite->_castId != nextSprite->_castId || currentSprite->_currentBbox != nextSprite->_currentBbox;
 
 		if (needsUpdate || forceUpdate)
 			unrenderSprite(i);
@@ -1776,7 +1777,8 @@ void Score::unrenderSprite(uint16 spriteId) {
 		_surface->fillRect(currentSprite->_currentBbox, _stageColor);
 	}
 
-	currentSprite->_currentBbox = currentSprite->_dirtyBbox;
+	currentSprite->_currentBbox = currentSprite->getBbox();
+	currentSprite->_dirty = false;
 }
 
 void Score::renderSprite(uint16 id) {
diff --git a/engines/director/sprite.h b/engines/director/sprite.h
index f342e4a3d0..c0f11922d9 100644
--- a/engines/director/sprite.h
+++ b/engines/director/sprite.h
@@ -92,7 +92,6 @@ public:
 	Common::Point _currentPoint;
 	Common::Rect _startBbox;
 	Common::Rect _currentBbox;
-	Common::Rect _dirtyBbox;
 	uint16 _width;
 	uint16 _height;
 	// TODO: default constraint = 0, if turned on, sprite is constrainted to the bounding rect




More information about the Scummvm-git-logs mailing list