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

sev- noreply at scummvm.org
Wed Sep 24 13:08:14 UTC 2025


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

Summary:
dd68943392 DIRECTOR: Turned frame behaviors into an array for consistency
ec664a273a DIRECTOR: LINGO: Refactored behavior instantiation into separate method
9f0dbe2c62 DIRECTOR: LINGO: Instantiate and destroy script channel behavior
738f9496a6 DIRECTOR: LINGO: Exectue frame script behaviors for D6+
d07f2787b4 DIRECTOR: LINGO: Improved debug output on behavior script deinstantiation
25ec676585 DIRECTOR: Clarified logic for behavior lifetime
e969ddd78a DIRECTOR: LINGO: Silently allow behaviors not having requested handlers


Commit: dd68943392607435229f59eb071ec1929f35997d
    https://github.com/scummvm/scummvm/commit/dd68943392607435229f59eb071ec1929f35997d
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-09-24T15:07:54+02:00

Commit Message:
DIRECTOR: Turned frame behaviors into an array for consistency

Changed paths:
    engines/director/frame.cpp
    engines/director/frame.h
    engines/director/score.cpp


diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index c6065050c1a..06e176c6589 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -58,7 +58,7 @@ Frame::Frame(const Frame &frame) {
 	_numChannels = frame._numChannels;
 	_mainChannels.actionId = frame._mainChannels.actionId;
 	_mainChannels.scriptSpriteListIdx = frame._mainChannels.scriptSpriteListIdx;
-	_mainChannels.behavior = frame._mainChannels.behavior;
+	_mainChannels.behaviors = frame._mainChannels.behaviors;
 	_mainChannels.scriptSpriteInfo = frame._mainChannels.scriptSpriteInfo;
 
 	_mainChannels.transDuration = frame._mainChannels.transDuration;
diff --git a/engines/director/frame.h b/engines/director/frame.h
index a4afe869b29..2f69b4574d4 100644
--- a/engines/director/frame.h
+++ b/engines/director/frame.h
@@ -101,8 +101,8 @@ struct PaletteInfo {
 struct MainChannels {
 	CastMemberID actionId;
 	uint32 scriptSpriteListIdx; // D6+
-	BehaviorElement behavior; 	// D6+
 	SpriteInfo scriptSpriteInfo; // D6+
+	Common::Array<BehaviorElement> behaviors; // D6+
 
 	uint16 transDuration;
 	uint8 transArea; // 1 - Whole Window, 0 - Changing Area
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 3beda1846f3..3ce196aaed1 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -1973,8 +1973,9 @@ void Score::loadFrameSpriteDetails(bool skipLog) {
 		_currentFrame->_mainChannels.scriptSpriteInfo = loadSpriteInfo(_currentFrame->_mainChannels.scriptSpriteListIdx, skipLog);
 
 		stream = getSpriteDetailsStream(_currentFrame->_mainChannels.scriptSpriteListIdx + 1);
+		// We can have only one behavior here
 		if (stream) {
-			_currentFrame->_mainChannels.behavior = loadSpriteBehavior(stream, skipLog);
+			_currentFrame->_mainChannels.behaviors.push_back(loadSpriteBehavior(stream, skipLog));
 			delete stream;
 		}
 	}


Commit: ec664a273a6230fe95080623321144b729765884
    https://github.com/scummvm/scummvm/commit/ec664a273a6230fe95080623321144b729765884
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-09-24T15:07:58+02:00

Commit Message:
DIRECTOR: LINGO: Refactored behavior instantiation into separate method

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


diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index 9251b496867..2a7e4817c44 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -699,6 +699,59 @@ void Score::killScriptInstances(int frameNum) {
 	}
 }
 
+Datum Score::createScriptInstance(BehaviorElement *behavior) {
+	// Instantiate the behavior
+	g_lingo->push(_movie->getScriptContext(kScoreScript, behavior->memberID));
+	LC::call("new", 1, true);
+	Datum inst = g_lingo->pop();
+
+	if (inst.type != OBJECT) {
+		warning("Score::createScriptInstances(): Could not instantiate behavior %s", behavior->toString().c_str());
+		return Datum();
+	}
+
+	debugC(1, kDebugLingoExec, "   Instantiated behavior %s", behavior->toString().c_str());
+
+	// No initializer, we are done
+	if (behavior->initializerIndex == 0)
+		return inst;
+
+	// Evaluate the params
+	g_lingo->push(behavior->initializerParams);
+	LB::b_value(1);
+	g_lingo->execute();
+
+	if (debugChannelSet(5, kDebugLingoExec)) {
+		g_lingo->printStack("  Parsed behavior parameters: ", 0);
+	}
+
+	if (g_lingo->_state->stack.size() == 0) {
+		warning("Score::createScriptInstances(): Could not evaluate initializer params '%s' for behavior %s",
+			behavior->initializerParams.c_str(), behavior->toString().c_str());
+		return inst;
+	}
+
+	Datum proplist = _lingo->pop();
+
+	if (proplist.type != PARRAY) {
+		warning("Score::createScriptInstances(): Could not evaluate initializer params '%s' for behavior %s",
+			behavior->initializerParams.c_str(), behavior->toString().c_str());
+		return inst;
+	}
+
+	debugC(2, kDebugLingoExec, "   Setting %d properties", proplist.u.parr->arr.size());
+
+	for (uint k = 0; k < proplist.u.parr->arr.size(); k++) {
+		Datum key = proplist.u.parr->arr[k].p;
+		Datum val = proplist.u.parr->arr[k].v;
+
+		inst.u.obj->setProp(key.asString(), val);
+	}
+
+	return inst;
+}
+
+
 void Score::createScriptInstances(int frameNum) {
 	if (_version < kFileVer600) // No-op for early Directors
 		return;
@@ -719,58 +772,17 @@ void Score::createScriptInstances(int frameNum) {
 		if (sprite->_behaviors.size() == 0)
 			continue;
 
+		debugC(1, kDebugLingoExec, "Score::createScriptInstances(): Creating script instances for channel %d, %d behaviors", i + 1, sprite->_behaviors.size());
+
 		for (uint j = 0; j < sprite->_behaviors.size(); j++) {
-			// Instantiate the behavior
-			g_lingo->push(_movie->getScriptContext(kScoreScript, sprite->_behaviors[j].memberID));
-			LC::call("new", 1, true);
-			Datum inst = g_lingo->pop();
+			Datum inst = createScriptInstance(&sprite->_behaviors[j]);
 
 			if (inst.type != OBJECT) {
-				warning("Score::createScriptInstances(): Could not instantiate behavior %s for channel %d",
-					sprite->_behaviors[j].toString().c_str(), i + 1);
+				warning("Score::createScriptInstances(): Could not instantiate behavior %s", sprite->_behaviors[j].toString().c_str());
 				continue;
 			}
 
 			channel->_scriptInstanceList.push_back(inst);
-
-			debugC(1, kDebugLingoExec, "Score::createScriptInstances(): Instantiated behavior %s for channel %d",
-				sprite->_behaviors[j].toString().c_str(), i + 1);
-
-			// No initializer, continue
-			if (sprite->_behaviors[j].initializerIndex == 0)
-				continue;
-
-			// Evaluate the params
-			g_lingo->push(sprite->_behaviors[j].initializerParams);
-			LB::b_value(1);
-			g_lingo->execute();
-
-			if (debugChannelSet(5, kDebugLingoExec)) {
-				g_lingo->printStack("  Parsed behavior parameters: ", 0);
-			}
-
-			if (g_lingo->_state->stack.size() == 0) {
-				warning("Score::createScriptInstances(): Could not evaluate initializer params '%s' for behavior %s for channel %d",
-					sprite->_behaviors[j].initializerParams.c_str(), sprite->_behaviors[j].toString().c_str(), i + 1);
-				continue;
-			}
-
-			Datum proplist = _lingo->pop();
-
-			if (proplist.type != PARRAY) {
-				warning("Score::createScriptInstances(): Could not evaluate initializer params '%s' for behavior %s for channel %d",
-					sprite->_behaviors[j].initializerParams.c_str(), sprite->_behaviors[j].toString().c_str(), i + 1);
-				continue;
-			}
-
-			debugC(2, kDebugLingoExec, "   Setting %d properties", proplist.u.parr->arr.size());
-
-			for (uint k = 0; k < proplist.u.parr->arr.size(); k++) {
-				Datum key = proplist.u.parr->arr[k].p;
-				Datum val = proplist.u.parr->arr[k].v;
-
-				channel->_scriptInstanceList[j].u.obj->setProp(key.asString(), val);
-			}
 		}
 	}
 }
diff --git a/engines/director/score.h b/engines/director/score.h
index 72ccaae1b5d..8c450d0288a 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -149,6 +149,7 @@ public:
 	// They live in lingo/lingo-events.cpp
 	void killScriptInstances(int frameNum);
 	void createScriptInstances(int frameNum);
+	Datum createScriptInstance(BehaviorElement *behavior);
 
 private:
 	bool isWaitingForNextFrame();


Commit: 9f0dbe2c6202874f23daba9230c64d9c67c23ca1
    https://github.com/scummvm/scummvm/commit/9f0dbe2c6202874f23daba9230c64d9c67c23ca1
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-09-24T15:07:58+02:00

Commit Message:
DIRECTOR: LINGO: Instantiate and destroy script channel behavior

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


diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index 2a7e4817c44..ef35668897d 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -684,6 +684,12 @@ void Score::killScriptInstances(int frameNum) {
 	if (_version < kFileVer600) // No-op for early Directors
 		return;
 
+	if (frameNum < _currentFrame->_mainChannels.scriptSpriteInfo.startFrame ||
+	    frameNum > _currentFrame->_mainChannels.scriptSpriteInfo.endFrame) {
+		_scriptChannelScriptInstance = Datum();
+		debugC(1, kDebugLingoExec, "Score::killScriptInstances(): Killed script instances for script channel");
+	}
+
 	for (int i = 0; i < (int)_channels.size(); i++) {
 		Channel *channel = _channels[i];
 
@@ -756,6 +762,20 @@ void Score::createScriptInstances(int frameNum) {
 	if (_version < kFileVer600) // No-op for early Directors
 		return;
 
+	if (frameNum >= _currentFrame->_mainChannels.scriptSpriteInfo.startFrame &&
+	    frameNum <= _currentFrame->_mainChannels.scriptSpriteInfo.endFrame) {
+
+		// We have no instantiated script
+		if (_scriptChannelScriptInstance.type != OBJECT) {
+			if (_currentFrame->_mainChannels.behaviors.size() > 0) {
+				debugC(1, kDebugLingoExec, "Score::createScriptInstances(): Creating script instances for script channel, frames [%d-%d]",
+					_currentFrame->_mainChannels.scriptSpriteInfo.startFrame,
+					_currentFrame->_mainChannels.scriptSpriteInfo.endFrame);
+				_scriptChannelScriptInstance = createScriptInstance(&_currentFrame->_mainChannels.behaviors[0]);
+			}
+		}
+	}
+
 	for (int i = 0; i < (int)_channels.size(); i++) {
 		Channel *channel = _channels[i];
 		Sprite *sprite = channel->_sprite;
@@ -772,7 +792,8 @@ void Score::createScriptInstances(int frameNum) {
 		if (sprite->_behaviors.size() == 0)
 			continue;
 
-		debugC(1, kDebugLingoExec, "Score::createScriptInstances(): Creating script instances for channel %d, %d behaviors", i + 1, sprite->_behaviors.size());
+		debugC(1, kDebugLingoExec, "Score::createScriptInstances(): Creating script instances for channel %d, %d behaviors, frames [%d-%d]",
+			i + 1, sprite->_behaviors.size(), channel->_startFrame, channel->_endFrame);
 
 		for (uint j = 0; j < sprite->_behaviors.size(); j++) {
 			Datum inst = createScriptInstance(&sprite->_behaviors[j]);
diff --git a/engines/director/score.h b/engines/director/score.h
index 8c450d0288a..fc6facae37e 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -178,6 +178,7 @@ public:
 	Common::SortedArray<Label *> *_labels;
 	Common::HashMap<uint16, Common::String> _actions;
 	Common::HashMap<uint16, bool> _immediateActions;
+	Datum _scriptChannelScriptInstance;
 
 	Common::Array<Frame *> _scoreCache;
 


Commit: 738f9496a630ad8ea65274a2da5826fd2a7389f7
    https://github.com/scummvm/scummvm/commit/738f9496a630ad8ea65274a2da5826fd2a7389f7
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-09-24T15:07:58+02:00

Commit Message:
DIRECTOR: LINGO: Exectue frame script behaviors for D6+

Changed paths:
    engines/director/lingo/lingo-events.cpp


diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index ef35668897d..defc16f83e8 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -252,10 +252,6 @@ void Movie::resolveScriptEvent(LingoEvent &event) {
 					if (event.behaviorIndex >= 0) {
 						scriptId = sprite->_behaviors[event.behaviorIndex].memberID;
 						initializerParams = sprite->_behaviors[event.behaviorIndex].initializerParams;
-						warning("event: %d, ID: %s, initializerParams: '%s'", event.event, scriptId.asString().c_str(), initializerParams.c_str());
-
-						// TODO: instantiate the behavior script as a child and set its properties
-						// according to the list in initializerParams
 					} else {
 						return;
 					}
@@ -342,6 +338,16 @@ void Movie::resolveScriptEvent(LingoEvent &event) {
 			if (_score->_currentFrame == nullptr)
 				return;
 
+			if (_vm->getVersion() >= 600) {
+				if (_score->_scriptChannelScriptInstance.type == OBJECT) {
+					event.scriptType = kScoreScript;
+					event.scriptId = CastMemberID(); // No ID for the script channel script
+					event.scriptInstance = _score->_scriptChannelScriptInstance.u.obj;
+				}
+				return;
+			}
+
+			// Pre D6
 			CastMemberID scriptId = _score->_currentFrame->_mainChannels.actionId;
 			if (!scriptId.member)
 				return;


Commit: d07f2787b403b1f6b86394f75df214d2a4591e58
    https://github.com/scummvm/scummvm/commit/d07f2787b403b1f6b86394f75df214d2a4591e58
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-09-24T15:07:58+02:00

Commit Message:
DIRECTOR: LINGO: Improved debug output on behavior script deinstantiation

Changed paths:
    engines/director/lingo/lingo-events.cpp


diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index defc16f83e8..b72327db3e8 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -693,7 +693,10 @@ void Score::killScriptInstances(int frameNum) {
 	if (frameNum < _currentFrame->_mainChannels.scriptSpriteInfo.startFrame ||
 	    frameNum > _currentFrame->_mainChannels.scriptSpriteInfo.endFrame) {
 		_scriptChannelScriptInstance = Datum();
-		debugC(1, kDebugLingoExec, "Score::killScriptInstances(): Killed script instances for script channel");
+		debugC(1, kDebugLingoExec, "Score::killScriptInstances(): Killed script instances for script channel. frame %d [%d-%d]",
+			frameNum,
+			_currentFrame->_mainChannels.scriptSpriteInfo.startFrame,
+			_currentFrame->_mainChannels.scriptSpriteInfo.endFrame);
 	}
 
 	for (int i = 0; i < (int)_channels.size(); i++) {
@@ -704,9 +707,11 @@ void Score::killScriptInstances(int frameNum) {
 
 		if (frameNum < channel->_startFrame || frameNum > channel->_endFrame) {
 			channel->_scriptInstanceList.clear();
-			channel->_startFrame = channel->_endFrame = -1;
 
-			debugC(1, kDebugLingoExec, "Score::killScriptInstances(): Killed script instances for channel %d", i + 1);
+			debugC(1, kDebugLingoExec, "Score::killScriptInstances(): Killed script instances for channel %d. frame %d [%d-%d]",
+					i + 1, frameNum, channel->_startFrame, channel->_endFrame);
+
+			channel->_startFrame = channel->_endFrame = -1;
 		}
 	}
 }


Commit: 25ec676585956561697c98685d44bc99a6edf952
    https://github.com/scummvm/scummvm/commit/25ec676585956561697c98685d44bc99a6edf952
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-09-24T15:07:58+02:00

Commit Message:
DIRECTOR: Clarified logic for behavior lifetime

Changed paths:
    engines/director/score.cpp


diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 3ce196aaed1..1f5fd1114b6 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -633,7 +633,7 @@ void Score::update() {
 
 	// Kill behaviors if they are going to expire next frame
 	if (!_vm->_playbackPaused)
-		killScriptInstances(_curFrameNumber + 1);
+		killScriptInstances(_nextFrame ? _nextFrame : _curFrameNumber + 1);
 
 	// change current frame and load frame data, if required
 	updateCurrentFrame();


Commit: e969ddd78a18dc4ac2de5c6a10148110b26a3b0d
    https://github.com/scummvm/scummvm/commit/e969ddd78a18dc4ac2de5c6a10148110b26a3b0d
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-09-24T15:07:58+02:00

Commit Message:
DIRECTOR: LINGO: Silently allow behaviors not having requested handlers

If we call without these checks, we have tons of red herring warnings
"Call to undefined handler XX"

Changed paths:
    engines/director/lingo/lingo-events.cpp


diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index b72327db3e8..8b18b0e6505 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -659,8 +659,12 @@ bool Lingo::processEvent(LEvent event, ScriptType st, CastMemberID scriptId, int
 
 	if (g_director->getVersion() >= 600 && st == kScoreScript && obj) {
 		push(Datum(obj));
-		LC::call(_eventHandlerTypes[event], 1, false);
-		return execute();
+		if (obj->getMethod(_eventHandlerTypes[event]).type != VOIDSYM) {
+			LC::call(_eventHandlerTypes[event], 1, false);
+			return execute();
+		} else {
+			return true;
+		}
 	}
 
 	ScriptContext *script = g_director->getCurrentMovie()->getScriptContext(st, scriptId);




More information about the Scummvm-git-logs mailing list