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

sev- noreply at scummvm.org
Thu Sep 18 22:38:57 UTC 2025


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:
5696396d84 DIRECTOR: Added sciptInstanceList and its cleanup logic
e82beb0041 DIRECTOR: Added initial logic for scriptInstance instantiation


Commit: 5696396d845e49952eee11b4692fa7d7418f3f5c
    https://github.com/scummvm/scummvm/commit/5696396d845e49952eee11b4692fa7d7418f3f5c
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-09-19T00:37:23+02:00

Commit Message:
DIRECTOR: Added sciptInstanceList and its cleanup logic

Changed paths:
    engines/director/channel.cpp
    engines/director/channel.h
    engines/director/lingo/lingo-funcs.cpp
    engines/director/score.cpp
    engines/director/score.h


diff --git a/engines/director/channel.cpp b/engines/director/channel.cpp
index 8153ba40009..dd89e906656 100644
--- a/engines/director/channel.cpp
+++ b/engines/director/channel.cpp
@@ -603,6 +603,11 @@ void Channel::replaceSprite(Sprite *nextSprite) {
 		_sprite->_width = width;
 		_sprite->_height = height;
 	}
+
+	if (g_director->getVersion() >= 600) {
+		_startFrame = nextSprite->_spriteInfo.startFrame;
+		_endFrame = nextSprite->_spriteInfo.endFrame;
+	}
 }
 
 void Channel::setPosition(int x, int y, bool force) {
diff --git a/engines/director/channel.h b/engines/director/channel.h
index 135d5ef5bf7..8eab04129ad 100644
--- a/engines/director/channel.h
+++ b/engines/director/channel.h
@@ -121,6 +121,10 @@ public:
 
 	Common::Rect _rollOverBbox;
 
+	int _startFrame;
+	int _endFrame;
+	Common::Array<BehaviorElement> _scriptInstanceList;  // FIXME: Need to be true instantiations
+
 private:
 	Graphics::ManagedSurface *getSurface();
 	Score *_score;
diff --git a/engines/director/lingo/lingo-funcs.cpp b/engines/director/lingo/lingo-funcs.cpp
index 96b318ef69c..d63970ef3a4 100644
--- a/engines/director/lingo/lingo-funcs.cpp
+++ b/engines/director/lingo/lingo-funcs.cpp
@@ -105,6 +105,10 @@ void Lingo::func_goto(Datum &frame, Datum &movie, bool calledfromgo) {
 		debugC(3, kDebugLingoExec, "Lingo::func_goto(): going to frame %d", frame.asInt());
 		score->setCurrentFrame(frame.asInt());
 	}
+
+	// Since the frames are not going to be consecutive, we might run into
+	// an endge case, so better kill behaviors proactively.
+	score->killScriptInstances(score->getNextFrame());
 }
 
 void Lingo::func_gotoloop() {
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index b9a3eb41a4e..63c1dabc60e 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -439,8 +439,7 @@ void Score::updateCurrentFrame() {
 			// With the advent of demand loading frames and due to partial updates, we rebuild our channel data
 			// when jumping.
 			nextFrameNumberToLoad = _nextFrame;
-		}
-		else if (!_window->_newMovieStarted)
+		} else if (!_window->_newMovieStarted)
 			nextFrameNumberToLoad = (_curFrameNumber+1);
 	}
 
@@ -632,6 +631,10 @@ void Score::update() {
 		return;
 	}
 
+	// Kill behaviors if they are going to expire next frame
+	if (!_vm->_playbackPaused)
+		killScriptInstances(_curFrameNumber + 1);
+
 	// change current frame and load frame data, if required
 	updateCurrentFrame();
 
@@ -2438,4 +2441,18 @@ Common::MemoryReadStreamEndian *Score::getSpriteDetailsStream(int spriteIdx) {
 	return stream;
 }
 
+void Score::killScriptInstances(int frameNum) {
+	if (_version < kFileVer600) // No-op for early Directors
+		return;
+
+	for (int i = 0; i < (int)_channels.size(); i++) {
+		if (frameNum < _channels[i]->_startFrame || frameNum > _channels[i]->_endFrame) {
+			_channels[i]->_scriptInstanceList.clear();
+			_channels[i]->_startFrame = _channels[i]->_endFrame = -1;
+
+			debugC(4, kDebugLingoExec, "Score::killBehaviors(): Killed behaviors for channel %d", i + 1);
+		}
+	}
+}
+
 } // End of namespace Director
diff --git a/engines/director/score.h b/engines/director/score.h
index 659e1a0a9ed..00ca9757af5 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -146,6 +146,8 @@ public:
 
 	Common::MemoryReadStreamEndian *getSpriteDetailsStream(int spriteIdx);
 
+	void killScriptInstances(int frameNumber);
+
 private:
 	bool isWaitingForNextFrame();
 	void updateCurrentFrame();


Commit: e82beb00411f690bd75d8d4686af81e368a8bf6b
    https://github.com/scummvm/scummvm/commit/e82beb00411f690bd75d8d4686af81e368a8bf6b
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-09-19T00:38:22+02:00

Commit Message:
DIRECTOR: Added initial logic for scriptInstance instantiation

It does not get invoked prooperly yet, as the channel somehow does
not yet contain startFrame/endFrame values

Changed paths:
    engines/director/channel.cpp
    engines/director/score.cpp
    engines/director/score.h
    engines/director/sprite.cpp


diff --git a/engines/director/channel.cpp b/engines/director/channel.cpp
index dd89e906656..33198d0cef7 100644
--- a/engines/director/channel.cpp
+++ b/engines/director/channel.cpp
@@ -62,6 +62,9 @@ Channel::Channel(Score *sc, Sprite *sp, int priority) {
 
 	_visible = true;
 	_dirty = true;
+
+	_startFrame = -1;
+	_endFrame = -1;
 }
 
 Channel::Channel(const Channel &channel) {
@@ -88,6 +91,9 @@ Channel& Channel::operator=(const Channel &channel) {
 	_visible = channel._visible;
 	_dirty = channel._dirty;
 
+	_startFrame = channel._startFrame;
+	_endFrame = channel._endFrame;
+
 	return *this;
 }
 
@@ -605,8 +611,8 @@ void Channel::replaceSprite(Sprite *nextSprite) {
 	}
 
 	if (g_director->getVersion() >= 600) {
-		_startFrame = nextSprite->_spriteInfo.startFrame;
-		_endFrame = nextSprite->_spriteInfo.endFrame;
+		_startFrame = _sprite->_spriteInfo.startFrame;
+		_endFrame = _sprite->_spriteInfo.endFrame;
 	}
 }
 
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 63c1dabc60e..29da9c9dd10 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -2013,7 +2013,6 @@ void Score::loadFrameSpriteDetails(bool skipLog) {
 	}
 }
 
-
 void Score::seekToMemberInList(int frameNum) {
 	if (frameNum < 1 || frameNum >= _numOfFrames) {
 		warning("Score::seekToMemberInList(): frameNum %d out of bounds [1, %d)", frameNum, _numOfFrames);
@@ -2073,6 +2072,8 @@ bool Score::loadFrame(int frameNum, bool loadCast) {
 	if (loadCast) {
 		// Load frame cast
 		setSpriteCasts();
+
+		createScriptInstances(_curFrameNumber);
 	}
 
 	return true;
@@ -2446,11 +2447,40 @@ void Score::killScriptInstances(int frameNum) {
 		return;
 
 	for (int i = 0; i < (int)_channels.size(); i++) {
-		if (frameNum < _channels[i]->_startFrame || frameNum > _channels[i]->_endFrame) {
-			_channels[i]->_scriptInstanceList.clear();
-			_channels[i]->_startFrame = _channels[i]->_endFrame = -1;
+		Channel *channel = _channels[i];
+
+		if (channel->_scriptInstanceList.size() == 0)
+			continue;
+
+		if (frameNum < channel->_startFrame || frameNum > channel->_endFrame) {
+			channel->_scriptInstanceList.clear();
+			channel->_startFrame = channel->_endFrame = -1;
+
+			debugC(1, kDebugLingoExec, "Score::killBehaviors(): Killed behaviors for channel %d", i + 1);
+		}
+	}
+}
 
-			debugC(4, kDebugLingoExec, "Score::killBehaviors(): Killed behaviors for channel %d", i + 1);
+void Score::createScriptInstances(int frameNum) {
+	if (_version < kFileVer600) // No-op for early Directors
+		return;
+
+	for (int i = 0; i < (int)_channels.size(); i++) {
+		Channel *channel = _channels[i];
+		Sprite *sprite = channel->_sprite;
+
+		if (frameNum >= channel->_startFrame && frameNum <= channel->_endFrame) {
+			// We create scriptInstance only for new sprites
+			if (channel->_scriptInstanceList.size() == 0) {
+				if (sprite->_behaviors.size() > 0) {
+					for (uint j = 0; j < sprite->_behaviors.size(); j++) {
+						// TODO: Here we should do proper instantiation
+						channel->_scriptInstanceList.push_back(sprite->_behaviors[j]);
+						debugC(1, kDebugLingoExec, "Score::createBehaviors(): Created behavior %s for channel %d",
+							sprite->_behaviors[j].toString().c_str(), i + 1);
+					}
+				}
+			}
 		}
 	}
 }
diff --git a/engines/director/score.h b/engines/director/score.h
index 00ca9757af5..02b77b868f9 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -146,7 +146,8 @@ public:
 
 	Common::MemoryReadStreamEndian *getSpriteDetailsStream(int spriteIdx);
 
-	void killScriptInstances(int frameNumber);
+	void killScriptInstances(int frameNum);
+	void createScriptInstances(int frameNum);
 
 private:
 	bool isWaitingForNextFrame();
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index c17eb8b3ec7..510794d073d 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -127,6 +127,7 @@ Sprite& Sprite::operator=(const Sprite &sprite) {
 	_volume = sprite._volume;
 	_stretch = sprite._stretch;
 
+	_spriteInfo = sprite._spriteInfo;
 	_spriteListIdx = sprite._spriteListIdx;
 
 	_flags = sprite._flags;




More information about the Scummvm-git-logs mailing list