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

sev- noreply at scummvm.org
Wed Jul 15 21:02:58 UTC 2026


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

Summary:
df4e2580bc DIRECTOR: Bind digital-video channel before applying sprite properties
f8d604dfc2 DIRECTOR: Decode off-screen digital videos used as timing clocks


Commit: df4e2580bcc6818f6197e2cd28d39a42b89ea864
    https://github.com/scummvm/scummvm/commit/df4e2580bcc6818f6197e2cd28d39a42b89ea864
Author: Gianluca Boiano (morf3089 at gmail.com)
Date: 2026-07-15T23:02:54+02:00

Commit Message:
DIRECTOR: Bind digital-video channel before applying sprite properties

setTheSprite() applied `the movieRate`/`movieTime`/`stopTime` to a
digital-video cast member before its channel was bound, so the setters
dereferenced a null channel and decoder.

Fixes crash at the intro concert video in opera fatal (OPERA.EXE plays
opera\intro\intro, CON0822.MOV)

Changed paths:
    engines/director/castmember/digitalvideo.cpp
    engines/director/lingo/lingo-the.cpp


diff --git a/engines/director/castmember/digitalvideo.cpp b/engines/director/castmember/digitalvideo.cpp
index 883137ef2a8..e4fcd3d600d 100644
--- a/engines/director/castmember/digitalvideo.cpp
+++ b/engines/director/castmember/digitalvideo.cpp
@@ -561,9 +561,14 @@ uint DigitalVideoCastMember::getMovieTotalTime() {
 }
 
 void DigitalVideoCastMember::seekMovie(int stamp) {
-	if (!_video)
+	if (!_channel)
 		return;
 
+	if (!_video || !_video->isVideoLoaded()) {
+		if (!loadVideoFromCast())
+			return;
+	}
+
 	_channel->_startTime = stamp;
 
 	Audio::Timestamp dur = _video->getDuration();
@@ -578,9 +583,14 @@ void DigitalVideoCastMember::seekMovie(int stamp) {
 }
 
 void DigitalVideoCastMember::setStopTime(int stamp) {
-	if (!_video)
+	if (!_channel)
 		return;
 
+	if (!_video || !_video->isVideoLoaded()) {
+		if (!loadVideoFromCast())
+			return;
+	}
+
 	_channel->_stopTime = stamp;
 
 	Audio::Timestamp dur = _video->getDuration();
@@ -589,9 +599,14 @@ void DigitalVideoCastMember::setStopTime(int stamp) {
 }
 
 void DigitalVideoCastMember::setMovieRate(double rate) {
-	if (!_video)
+	if (!_channel)
 		return;
 
+	if (!_video || !_video->isVideoLoaded()) {
+		if (!loadVideoFromCast())
+			return;
+	}
+
 	_channel->_movieRate = rate;
 
 	if (rate < 0.0)
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index fc469c70e70..05819b2f74b 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -2036,16 +2036,18 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
 		break;
 	case kTheMovieRate:
 		channel->_movieRate = d.asFloat();
-		if (sprite->_cast && sprite->_cast->_type == kCastDigitalVideo)
+		if (sprite->_cast && sprite->_cast->_type == kCastDigitalVideo) {
+			((DigitalVideoCastMember *)sprite->_cast)->setChannel(channel);
 			((DigitalVideoCastMember *)sprite->_cast)->setMovieRate(channel->_movieRate);
-		else
+		} else
 			warning("Setting movieTime for non-digital video");
 		break;
 	case kTheMovieTime:
 		channel->_movieTime = d.asInt();
-		if (sprite->_cast->_type == kCastDigitalVideo)
+		if (sprite->_cast && sprite->_cast->_type == kCastDigitalVideo) {
+			((DigitalVideoCastMember *)sprite->_cast)->setChannel(channel);
 			((DigitalVideoCastMember *)sprite->_cast)->seekMovie(channel->_movieTime);
-		else
+		} else
 			warning("Setting movieTime for non-digital video");
 		break;
 	case kThePattern:
@@ -2080,16 +2082,18 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
 		break;
 	case kTheStartTime:
 		channel->_startTime = d.asInt();
-		if (sprite->_cast->_type == kCastDigitalVideo)
+		if (sprite->_cast && sprite->_cast->_type == kCastDigitalVideo) {
+			((DigitalVideoCastMember *)sprite->_cast)->setChannel(channel);
 			((DigitalVideoCastMember *)sprite->_cast)->seekMovie(channel->_startTime);
-		else
+		} else
 			warning("Setting startTime for non-digital video");
 		break;
 	case kTheStopTime:
 		channel->_stopTime = d.asInt();
-		if (sprite->_cast->_type == kCastDigitalVideo)
+		if (sprite->_cast && sprite->_cast->_type == kCastDigitalVideo) {
+			((DigitalVideoCastMember *)sprite->_cast)->setChannel(channel);
 			((DigitalVideoCastMember *)sprite->_cast)->setStopTime(channel->_stopTime);
-		else
+		} else
 			warning("Setting stopTime for non-digital video");
 		break;
 	case kTheStretch:


Commit: f8d604dfc24d7fa40961d10879f5a586f4bdcc6c
    https://github.com/scummvm/scummvm/commit/f8d604dfc24d7fa40961d10879f5a586f4bdcc6c
Author: Gianluca Boiano (morf3089 at gmail.com)
Date: 2026-07-15T23:02:54+02:00

Commit Message:
DIRECTOR: Decode off-screen digital videos used as timing clocks

A zero-sized video sprite is never rendered, so createWidget() returned
before decoding a frame and left a playing decoder unpumped; its
audio-mastered clock then stalled after the initial buffer.

Fixes the frozen, silent intro in opera fatal, which advances scenes from
`the movieTime` of the off-stage CON0822.MOV (opera\intro\intro)

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


diff --git a/engines/director/castmember/digitalvideo.cpp b/engines/director/castmember/digitalvideo.cpp
index e4fcd3d600d..09828990c33 100644
--- a/engines/director/castmember/digitalvideo.cpp
+++ b/engines/director/castmember/digitalvideo.cpp
@@ -478,9 +478,13 @@ Graphics::MacWidget *DigitalVideoCastMember::createWidget(Common::Rect &bbox, Ch
 		}
 	}
 
-	// Zero-sized bbox: nothing to render, and scaling to it would divide by zero.
-	if (bbox.width() <= 0 || bbox.height() <= 0)
+	// Zero-sized bbox: nothing to render. Still pump the decoder so an
+	// invisible video used only as a timing/audio clock keeps advancing.
+	if (bbox.width() <= 0 || bbox.height() <= 0) {
+		if (_channel && _channel->_movieRate != 0.0 && _video->needsUpdate())
+			_video->decodeNextFrame();
 		return nullptr;
+	}
 
 	Graphics::MacWidget *widget = new Graphics::MacWidget(g_director->getCurrentWindow()->getMacWindow(), bbox.left, bbox.top, bbox.width(), bbox.height(), g_director->_wm, false);
 




More information about the Scummvm-git-logs mailing list