[Scummvm-git-logs] scummvm master -> 21c08536e9ceed58ae678d1d455bb2fd842c5da0

sev- noreply at scummvm.org
Mon Feb 12 10:06:09 UTC 2024


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

Summary:
21c08536e9 DIRECTOR: Manage filmloop composed of other filmloops.


Commit: 21c08536e9ceed58ae678d1d455bb2fd842c5da0
    https://github.com/scummvm/scummvm/commit/21c08536e9ceed58ae678d1d455bb2fd842c5da0
Author: kartiksharmakk (77577353+kartiksharmakk at users.noreply.github.com)
Date: 2024-02-12T11:06:00+01:00

Commit Message:
DIRECTOR: Manage filmloop composed of other filmloops.

This patch adds support for filmloops composed of other filmloops.
It also fixes a bug in the filmloop bbox computation during Sprite::setCast() , we have to create a case kCastFilmLoop to prevent it from going to default case as the default case equates it to dims which is initialrect (0 value) , so the setCast function basically made film loop bbox 0.

Steps to reproduce:

Run the command: ./scummvm --start-movie="ATD\HD\ccTWRRAD.DXR" totaldistortion-win.
After running the command, the fish will now be visible. Previously, it was not being displayed due to lack of nested film loop support.

Changed paths:
    engines/director/cast.cpp
    engines/director/castmember/filmloop.cpp
    engines/director/sprite.cpp


diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index 9a4bc799312..11acf0f5b42 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -121,6 +121,12 @@ CastMember *Cast::getCastMember(int castId, bool load) {
 		_loadMutex = false;
 		result->load();
 		while (!_loadQueue.empty()) {
+			// prevents double loading of a filmloop of filmloop
+			if (_loadQueue.back()->_type == kCastFilmLoop) {
+				CastMember *subfilmloop = _loadQueue.back();
+				_loadQueue.pop_back();
+				subfilmloop->load();
+			}
 			_loadQueue.back()->load();
 			_loadQueue.pop_back();
 		}
diff --git a/engines/director/castmember/filmloop.cpp b/engines/director/castmember/filmloop.cpp
index cf09e467dd5..48a9a8e9c82 100644
--- a/engines/director/castmember/filmloop.cpp
+++ b/engines/director/castmember/filmloop.cpp
@@ -73,34 +73,87 @@ Common::Array<Channel> *FilmLoopCastMember::getSubChannels(Common::Rect &bbox, C
 
 	// get the list of sprite IDs for this frame
 	Common::Array<int> spriteIds;
-	for (auto &iter : _frames[channel->_filmLoopFrame].sprites) {
-		spriteIds.push_back(iter._key);
+	Common::Array<Sprite> subfilmloopsprites;
+	bool subFilmLoops = false;
+	// checking for filmloop at depth
+	for (auto &frameiter : ((FilmLoopCastMember *)channel->_sprite->_cast)->_frames) {
+		for (auto &spriteiter : frameiter.sprites) {
+			if (spriteiter._value._cast) {
+				if (spriteiter._value._cast->_type == kCastFilmLoop) {
+					subfilmloopsprites.push_back(spriteiter._value);
+				}
+			}
+		}
 	}
-	Common::sort(spriteIds.begin(), spriteIds.end());
 
-	// copy the sprites in order to the list
-	for (auto &iter : spriteIds) {
-		Sprite src = _frames[channel->_filmLoopFrame].sprites[iter];
-		if (!src._cast)
-			continue;
-		// translate sprite relative to the global bounding box
-		int16 relX = (src._startPoint.x - _initialRect.left) * widgetRect.width() / _initialRect.width();
-		int16 relY = (src._startPoint.y - _initialRect.top) * widgetRect.height() / _initialRect.height();
-		int16 absX = relX + bbox.left;
-		int16 absY = relY + bbox.top;
-		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;
-		chan._height = height;
-
-		_subchannels.push_back(chan);
+	if (!subfilmloopsprites.empty()) {
+		subFilmLoops = true;
+	}
+	// if a filmloop is composed of filmloops
+	if (subFilmLoops) {
+		for (uint i = 0; i < subfilmloopsprites.size(); i++) {
+			*channel->_sprite = subfilmloopsprites[i];
+			_frames = ((FilmLoopCastMember *)subfilmloopsprites[i]._cast)->_frames;
+			for (uint j = 0; j < _frames.size(); j++) {
+				for (auto &iter : _frames[j].sprites) {
+					spriteIds.push_back(iter._key);
+				}
+				// copy the sprites in order to the list
+				for (auto &iter : spriteIds) {
+					Sprite src = _frames[j].sprites[iter];
+					if (!src._cast)
+						continue;
+					// translate sprite relative to the global bounding box
+					int16 relX = (src._startPoint.x - _initialRect.left) * widgetRect.width() / _initialRect.width();
+					int16 relY = (src._startPoint.y - _initialRect.top) * widgetRect.height() / _initialRect.height();
+					int16 absX = relX + bbox.left;
+					int16 absY = relY + bbox.top;
+					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;
+					chan._height = height;
+
+					_subchannels.push_back(chan);
+				}
+			}
+			subFilmLoops = false;
+		}
+	} else {
 
+		for (auto &iter : _frames[channel->_filmLoopFrame].sprites) {
+			spriteIds.push_back(iter._key);
+		}
+		Common::sort(spriteIds.begin(), spriteIds.end());
+
+		// copy the sprites in order to the list
+		for (auto &iter : spriteIds) {
+			Sprite src = _frames[channel->_filmLoopFrame].sprites[iter];
+			if (!src._cast)
+				continue;
+			// translate sprite relative to the global bounding box
+			int16 relX = (src._startPoint.x - _initialRect.left) * widgetRect.width() / _initialRect.width();
+			int16 relY = (src._startPoint.y - _initialRect.top) * widgetRect.height() / _initialRect.height();
+			int16 absX = relX + bbox.left;
+			int16 absY = relY + bbox.top;
+			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;
+			chan._height = height;
+
+			_subchannels.push_back(chan);
+		}
 	}
 	// Initialise the widgets on all of the subchannels.
 	// This has to be done once the list has been constructed, otherwise
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index e0f555c63a6..d80dd9be03a 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -472,10 +472,12 @@ void Sprite::setCast(CastMemberID memberID) {
 				}
 			}
 			break;
+		case kCastFilmLoop:
 		case kCastShape:
 		case kCastText: 	// fall-through
 			break;
 		default:
+			debugC(3, kDebugImages, "Sprite::setCast(): Setting bbox of castId %s , type: %s to 0", memberID.asString().c_str(), castType2str(_cast->_type));
 			_width = dims.width();
 			_height = dims.height();
 			break;




More information about the Scummvm-git-logs mailing list