[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