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

sev- noreply at scummvm.org
Mon Sep 29 23:22:06 UTC 2025


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:
efd36c373e DIRECTOR: Implement D6+ tempo differences


Commit: efd36c373e2a875ae103d1940bcdd9114cbe5a25
    https://github.com/scummvm/scummvm/commit/efd36c373e2a875ae103d1940bcdd9114cbe5a25
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-09-30T01:21:32+02:00

Commit Message:
DIRECTOR: Implement D6+ tempo differences

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


diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index 06e176c6589..8483184aa06 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -72,7 +72,7 @@ Frame::Frame(const Frame &frame) {
 	_mainChannels.palette = frame._mainChannels.palette;
 	_mainChannels.tempo = frame._mainChannels.tempo;
 	_mainChannels.tempoSpriteListIdx = frame._mainChannels.tempoSpriteListIdx;
-	_mainChannels.tempoD6Flags = frame._mainChannels.tempoD6Flags;
+	_mainChannels.tempoCuePoint = frame._mainChannels.tempoCuePoint;
 	_mainChannels.tempoSpriteInfo = frame._mainChannels.tempoSpriteInfo;
 
 	_mainChannels.scoreCachedTempo = frame._mainChannels.scoreCachedTempo;
@@ -1262,7 +1262,7 @@ void Frame::readMainChannelsD6(Common::MemoryReadStreamEndian &stream, uint16 of
 			_mainChannels.tempoSpriteListIdx = stream.readUint16();
 			break;
 		case 24+4:
-			_mainChannels.tempoD6Flags = stream.readUint16();
+			_mainChannels.tempoCuePoint = stream.readUint16();
 			break;
 		case 24+6:
 			_mainChannels.tempo = stream.readByte();
@@ -1427,7 +1427,7 @@ void Frame::writeMainChannelsD6(Common::SeekableWriteStream *writeStream) {
 
 	// Tempo
 	writeStream->writeUint32BE(_mainChannels.tempoSpriteListIdx);			// 24+0
-	writeStream->writeUint16BE(_mainChannels.tempoD6Flags);					// 24+4
+	writeStream->writeUint16BE(_mainChannels.tempoCuePoint);					// 24+4
 	writeStream->writeByte(_mainChannels.tempo);							// 24+6
 	writeStream->writeByte(_mainChannels.colorTempo);						// 24+7
 	writePadding(writeStream, 16);											// 24+8
@@ -1720,7 +1720,7 @@ void Frame::readMainChannelsD7(Common::MemoryReadStreamEndian &stream, uint16 of
 			_mainChannels.tempoSpriteListIdx = stream.readUint16();
 			break;
 		case 48+4:
-			_mainChannels.tempoD6Flags = stream.readUint16();
+			_mainChannels.tempoCuePoint = stream.readUint16();
 			break;
 		case 48+6:
 			_mainChannels.tempo = stream.readByte();
@@ -1878,7 +1878,7 @@ void Frame::writeMainChannelsD7(Common::SeekableWriteStream *writeStream) {
 
 	// Tempo
 	writeStream->writeUint32BE(_mainChannels.tempoSpriteListIdx);			// 48+0
-	writeStream->writeUint16BE(_mainChannels.tempoD6Flags);					// 48+4
+	writeStream->writeUint16BE(_mainChannels.tempoCuePoint);					// 48+4
 	writeStream->writeByte(_mainChannels.tempo);							// 48+6
 	writeStream->writeByte(_mainChannels.colorTempo);						// 48+7
 	writePadding(writeStream, 40);											// 48+8
diff --git a/engines/director/frame.h b/engines/director/frame.h
index 2f69b4574d4..cb44d81a7c9 100644
--- a/engines/director/frame.h
+++ b/engines/director/frame.h
@@ -115,7 +115,7 @@ struct MainChannels {
 	PaletteInfo palette;
 	uint8 tempo;
 	uint32 tempoSpriteListIdx; // D6+
-	uint16 tempoD6Flags;
+	uint16 tempoCuePoint;
 	SpriteInfo tempoSpriteInfo; // D6+
 
 	uint8 scoreCachedTempo;
@@ -150,7 +150,7 @@ struct MainChannels {
 
 		tempo = 0;
 		tempoSpriteListIdx = 0;
-		tempoD6Flags = 0;
+		tempoCuePoint = 0;
 
 		scoreCachedTempo = 0;
 
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 7c79a7d5037..3e736039bff 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -76,6 +76,7 @@ Score::Score(Movie *movie) {
 	_nextFrameDelay = 0;
 	_lastTempo = 0;
 	_waitForChannel = 0;
+	_waitForChannelCue = 0;
 	_waitForVideoChannel = 0;
 	_cursorDirty = false;
 	_waitForClick = false;
@@ -408,6 +409,11 @@ bool Score::isWaitingForNextFrame() {
 	bool goingTo = _nextFrame && _nextFrame != _curFrameNumber;
 
 	if (_waitForChannel) {
+		if (_waitForChannelCue != 0) {
+			 // -1: next, -2: end, else specific cue point
+			 warning("STUB: Implement waiting for sound channel %d cue point %d", _waitForChannel, _waitForChannelCue);
+		}
+
 		if (_soundManager->isChannelActive(_waitForChannel) && !goingTo) {
 			keepWaiting = true;
 		} else {
@@ -531,48 +537,88 @@ void Score::updateNextFrameTime() {
 	}
 
 	if (tempo) {
-		const bool waitForClickOnly = _version < kFileVer300;
-		int maxDelay = 60;
-		if (_version < kFileVer300) {
-			maxDelay = 120;
-		} else if (_version < kFileVer400) {
-			// Director 3 has a slider that goes up to 120, but any value
-			// beyond 95 gets converted into a video wait instruction.
-			maxDelay = 95;
-		}
-		if (tempo >= 256 - maxDelay) {
-			// Delay
-			_nextFrameTime = g_system->getMillis() + (256 - tempo) * 1000;
-			debugC(5, kDebugEvents, "Score::updateNextFrameTime(): setting _nextFrameTime to %d based on a delay of %d", _nextFrameTime, 256 - tempo);
-		} else if (tempo <= 120) {
-			// FPS
-			_currentFrameRate = tempo;
-			if (g_director->_fpsLimit)
-				_currentFrameRate = MIN(g_director->_fpsLimit, _currentFrameRate);
-			_nextFrameTime = g_system->getMillis() + 1000.0 / (float)_currentFrameRate;
-			debugC(5, kDebugEvents, "Score::updateNextFrameTime(): setting _nextFrameTime to %d based on a framerate of %d", _nextFrameTime, _currentFrameRate);
-		} else {
-			if (tempo == 128) {
-				_waitForClick = true;
-				_waitForClickCursor = false;
-				renderCursor(_movie->getWindow()->getMousePos());
-				debugC(5, kDebugEvents, "Score::updateNextFrameTime(): waiting for mouse click before next frame");
-			} else if (!waitForClickOnly && tempo == 135) {
+		if (_version < kFileVer600) {
+			const bool waitForClickOnly = _version < kFileVer300;
+			int maxDelay = 60;
+			if (_version < kFileVer300) {
+				maxDelay = 120;
+			} else if (_version < kFileVer400) {
+				// Director 3 has a slider that goes up to 120, but any value
+				// beyond 95 gets converted into a video wait instruction.
+				maxDelay = 95;
+			}
+			if (tempo >= 256 - maxDelay) {
+				// Delay
+				_nextFrameTime = g_system->getMillis() + (256 - tempo) * 1000;
+				debugC(5, kDebugEvents, "Score::updateNextFrameTime(): setting _nextFrameTime to %d based on a delay of %d", _nextFrameTime, 256 - tempo);
+			} else if (tempo <= 120) {
+				// FPS
+				_currentFrameRate = tempo;
+				if (g_director->_fpsLimit)
+					_currentFrameRate = MIN(g_director->_fpsLimit, _currentFrameRate);
+				_nextFrameTime = g_system->getMillis() + 1000.0 / (float)_currentFrameRate;
+				debugC(5, kDebugEvents, "Score::updateNextFrameTime(): setting _nextFrameTime to %d based on a framerate of %d", _nextFrameTime, _currentFrameRate);
+			} else {
+				if (tempo == 128) {
+					_waitForClick = true;
+					_waitForClickCursor = false;
+					renderCursor(_movie->getWindow()->getMousePos());
+					debugC(5, kDebugEvents, "Score::updateNextFrameTime(): waiting for mouse click before next frame");
+				} else if (!waitForClickOnly && tempo == 135) {
+					// Wait for sound channel 1
+					_waitForChannel = 1;
+					debugC(5, kDebugEvents, "Score::updateNextFrameTime(): waiting for sound channel 1 before next frame");
+				} else if (!waitForClickOnly && tempo == 134) {
+					// Wait for sound channel 2
+					_waitForChannel = 2;
+					debugC(5, kDebugEvents, "Score::updateNextFrameTime(): waiting for sound channel 2 before next frame");
+				} else if (!waitForClickOnly && tempo >= 136 && tempo <= 135 + _numChannelsDisplayed) {
+					// Wait for a digital video in a channel to finish playing
+					_waitForVideoChannel = tempo - 135;
+					debugC(5, kDebugEvents, "Score::updateNextFrameTime(): waiting for video in channel %d before next frame", _waitForVideoChannel);
+				} else {
+					warning("Score::updateNextFrameTime(): Unhandled tempo instruction: %d", tempo);
+				}
+				_nextFrameTime = g_system->getMillis();
+			}
+		} else { // D6+
+			int16 tempoCuePoint = _currentFrame->_mainChannels.tempoCuePoint;
+
+			if (tempo == 255) {
 				// Wait for sound channel 1
 				_waitForChannel = 1;
-				debugC(5, kDebugEvents, "Score::updateNextFrameTime(): waiting for sound channel 1 before next frame");
-			} else if (!waitForClickOnly && tempo == 134) {
+				_waitForChannelCue = tempoCuePoint; // -1: next, -2: end, else specific cue point
+				debugC(5, kDebugEvents, "Score::updateNextFrameTime(): waiting for sound channel 1, cue point %d before next frame", _waitForChannelCue);
+				_nextFrameTime = g_system->getMillis();
+			} else if (tempo == 254) {
 				// Wait for sound channel 2
 				_waitForChannel = 2;
-				debugC(5, kDebugEvents, "Score::updateNextFrameTime(): waiting for sound channel 2 before next frame");
-			} else if (!waitForClickOnly && tempo >= 136 && tempo <= 135 + _numChannelsDisplayed) {
+				_waitForChannelCue = tempoCuePoint;
+				debugC(5, kDebugEvents, "Score::updateNextFrameTime(): waiting for sound channel 2, cue point %d before next frame", _waitForChannelCue);
+				_nextFrameTime = g_system->getMillis();
+			} else if (tempo == 248) {
+				_waitForClick = true;
+				_waitForClickCursor = false;
+				renderCursor(_movie->getWindow()->getMousePos());
+				debugC(5, kDebugEvents, "Score::updateNextFrameTime(): waiting for mouse click before next frame");
+				_nextFrameTime = g_system->getMillis();
+			} else if (tempo == 247) {
+				// Delay
+				_nextFrameTime = g_system->getMillis() + tempoCuePoint * 1000;
+				debugC(5, kDebugEvents, "Score::updateNextFrameTime(): setting _nextFrameTime to %d based on a delay of %d", _nextFrameTime, tempoCuePoint);
+			} else if (tempo == 246) {
+				// FPS
+				_currentFrameRate = tempoCuePoint;
+				if (g_director->_fpsLimit)
+					_currentFrameRate = MIN(g_director->_fpsLimit, _currentFrameRate);
+				_nextFrameTime = g_system->getMillis() + 1000.0 / (float)_currentFrameRate;
+				debugC(5, kDebugEvents, "Score::updateNextFrameTime(): setting _nextFrameTime to %d based on a framerate of %d", _nextFrameTime, _currentFrameRate);
+			} else {
 				// Wait for a digital video in a channel to finish playing
-				_waitForVideoChannel = tempo - 135;
+				_waitForVideoChannel = tempo;
 				debugC(5, kDebugEvents, "Score::updateNextFrameTime(): waiting for video in channel %d before next frame", _waitForVideoChannel);
-			} else {
-				warning("Score::updateNextFrameTime(): Unhandled tempo instruction: %d", tempo);
+				_nextFrameTime = g_system->getMillis();
 			}
-			_nextFrameTime = g_system->getMillis();
 		}
 	} else {
 		_nextFrameTime = g_system->getMillis() + 1000.0 / (float)_currentFrameRate;
diff --git a/engines/director/score.h b/engines/director/score.h
index 5a4eda987c2..3c67966bf43 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -219,6 +219,7 @@ public:
 	uint32 _nextFrameDelay;
 	int _lastTempo;
 	int _waitForChannel;
+	int _waitForChannelCue;
 	int _waitForVideoChannel;
 	bool _waitForClick;
 	bool _waitForClickCursor;




More information about the Scummvm-git-logs mailing list