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

sev- noreply at scummvm.org
Thu Jul 16 18:07:09 UTC 2026


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

Summary:
c578826660 DIRECTOR: Guard film loop accessors against unloaded score


Commit: c578826660a74de9ba80309b465209cb959a5c4b
    https://github.com/scummvm/scummvm/commit/c578826660a74de9ba80309b465209cb959a5c4b
Author: Gianluca Boiano (morf3089 at gmail.com)
Date: 2026-07-16T20:07:04+02:00

Commit Message:
DIRECTOR: Guard film loop accessors against unloaded score

Film loops are stubbed for D8.5+, leaving _score null after load().

Fixes segfaults rendering DATA/login.dcr in loewe7

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


diff --git a/engines/director/castmember/filmloop.cpp b/engines/director/castmember/filmloop.cpp
index 0cff9c8ec7d..ce5c92e69df 100644
--- a/engines/director/castmember/filmloop.cpp
+++ b/engines/director/castmember/filmloop.cpp
@@ -88,7 +88,7 @@ FilmLoopCastMember::~FilmLoopCastMember() {
 }
 
 bool FilmLoopCastMember::isModified() {
-	if (_score->_scoreCache.size())
+	if (_score && _score->_scoreCache.size())
 		return true;
 
 	if (_initialRect.width() && _initialRect.height())
@@ -102,8 +102,8 @@ Common::Array<Channel> *FilmLoopCastMember::getSubChannels(Common::Rect &bbox, u
 
 	_subchannels.clear();
 
-	if (frame >= _score->_scoreCache.size()) {
-		warning("FilmLoopCastMember::getSubChannels(): Film loop frame %d requested, only %d available", frame, _score->_scoreCache.size());
+	if (!_score || frame >= _score->_scoreCache.size()) {
+		warning("FilmLoopCastMember::getSubChannels(): Film loop frame %d requested, only %d available", frame, _score ? _score->_scoreCache.size() : 0);
 		return &_subchannels;
 	}
 
@@ -180,8 +180,8 @@ Common::Array<Channel> *FilmLoopCastMember::getSubChannels(Common::Rect &bbox, u
 }
 
 CastMemberID FilmLoopCastMember::getSubChannelSound1(uint frame) {
-	if (frame >= _score->_scoreCache.size()) {
-		warning("FilmLoopCastMember::getSubChannelSound1(): Film loop frame %d requested, only %d available", frame, _score->_scoreCache.size());
+	if (!_score || frame >= _score->_scoreCache.size()) {
+		warning("FilmLoopCastMember::getSubChannelSound1(): Film loop frame %d requested, only %d available", frame, _score ? _score->_scoreCache.size() : 0);
 		return CastMemberID();
 	}
 
@@ -189,8 +189,8 @@ CastMemberID FilmLoopCastMember::getSubChannelSound1(uint frame) {
 }
 
 CastMemberID FilmLoopCastMember::getSubChannelSound2(uint frame) {
-	if (frame >= _score->_scoreCache.size()) {
-		warning("FilmLoopCastMember::getSubChannelSound2(): Film loop frame %d requested, only %d available", frame, _score->_scoreCache.size());
+	if (!_score || frame >= _score->_scoreCache.size()) {
+		warning("FilmLoopCastMember::getSubChannelSound2(): Film loop frame %d requested, only %d available", frame, _score ? _score->_scoreCache.size() : 0);
 		return CastMemberID();
 	}
 
@@ -295,6 +295,10 @@ void FilmLoopCastMember::writeSCVWResource(Common::SeekableWriteStream *writeStr
 	if (!_loaded) {
 		load();
 	}
+	if (!_score) {
+		warning("FilmLoopCastMember::writeSCVWResource: Film loop has no score, skipping");
+		return;
+	}
 
 	uint32 channelSize = 0;
 	if (_cast->_version >= kFileVer400 && _cast->_version < kFileVer500) {
@@ -389,6 +393,8 @@ uint32 FilmLoopCastMember::getSCVWResourceSize() {
 	}
 
 	uint32 framesSize = 0;
+	if (!_score)
+		return 0;
 	for (Frame *frame : _score->_scoreCache) {
 		// Frame size
 		framesSize += 2;
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 39e6864af10..53188d9726d 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -911,7 +911,7 @@ void Score::incrementFilmLoops() {
 	for (auto &it : _channels) {
 		if (it->_sprite->_cast && (it->_sprite->_cast->_type == kCastFilmLoop || it->_sprite->_cast->_type == kCastMovie)) {
 			FilmLoopCastMember *fl = ((FilmLoopCastMember *)it->_sprite->_cast);
-			if (!fl->_score->_scoreCache.empty()) {
+			if (fl->_score && !fl->_score->_scoreCache.empty()) {
 				if (fl->_looping) {
 					it->_filmLoopFrame += 1;
 					it->_filmLoopFrame %= fl->_score->_scoreCache.size();




More information about the Scummvm-git-logs mailing list