[Scummvm-git-logs] scummvm master -> 7e41b273eda6c408d6239e5e88253e0f211d7c63
mduggan
noreply at scummvm.org
Sat Aug 8 04:21:35 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:
7e41b273ed DGDS: Fix dialog timing on Willy Beamish CD
Commit: 7e41b273eda6c408d6239e5e88253e0f211d7c63
https://github.com/scummvm/scummvm/commit/7e41b273eda6c408d6239e5e88253e0f211d7c63
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2026-08-08T14:19:27+10:00
Commit Message:
DGDS: Fix dialog timing on Willy Beamish CD
There were a few issues in the way dialogs were being timed in the CD version
of Willy Beamish - when they would be run as exclusive, when they were cleared,
and how delays were being handled. This seems to fix most of the issues and
they run more sensibly.
This fixes #16583.
Changed paths:
engines/dgds/head.cpp
engines/dgds/head.h
engines/dgds/scene.cpp
engines/dgds/ttm.cpp
diff --git a/engines/dgds/head.cpp b/engines/dgds/head.cpp
index 177b6eb46cf..a932de24a4a 100644
--- a/engines/dgds/head.cpp
+++ b/engines/dgds/head.cpp
@@ -209,7 +209,7 @@ void CDSTTMInterpreter::handleOperation(TTMEnviro &env_, TTMSeq &seq, uint16 op,
// TODO: Probably should do this accounting (as well as timeCut and dialogs)
// in game frames, not millis.
int16 delayMillis = (int16)round(ivals[0] * MS_PER_FRAME);
- env._cdsDelay = MAX(env._cdsDelay, delayMillis);
+ env._cdsDelay = delayMillis;
break;
}
case 0x1050: // SELECT BMP: id:int [0]
@@ -229,7 +229,7 @@ void CDSTTMInterpreter::handleOperation(TTMEnviro &env_, TTMSeq &seq, uint16 op,
seq._gotoFrame = findGOTOTarget(env, seq, ivals[0]);
break;
case 0x3300: // CDS GOSUB - first 2 args are ignored by original
- if (!env._cdsJumped && seq._gotoFrame + ivals[2] != seq._currentFrame && seq._gotoFrame >= 0) {
+ if (!env._cdsJumped && seq._gotoFrame + ivals[2] != seq._currentFrame && seq._gotoFrame >= 0) {
env._cdsJumped = true;
int64 prevPos = env.scr->pos();
int16 currentFrame = seq._currentFrame;
@@ -432,7 +432,7 @@ bool Conversation::runScriptFrame(int16 frameNum) {
return _ttmScript->run(_ttmEnv, *seq);
}
-void Conversation::checkAndRunScript() {
+void Conversation::checkAndRunScript(bool updateDelay) {
if (!_ttmScript || _finished)
return;
@@ -445,9 +445,13 @@ void Conversation::checkAndRunScript() {
runScriptFrame(_tempFrameNum);
}
runScriptFrame(_ttmEnv._cdsFrame);
+
+ if (!updateDelay)
+ return;
+
if (_ttmEnv._cdsDelay > 0) {
_nextExecMs = _thisFrameMs + _ttmEnv._cdsDelay;
- debug(10, "CDS: This fame %d. Next frame will be on or after %d", _thisFrameMs, _nextExecMs);
+ debug(10, "CDS: This frame ms %d. Next frame will be on or after %d. ", _thisFrameMs, _nextExecMs);
_ttmEnv._cdsDelay = -1;
} else {
_nextExecMs = 0;
@@ -504,7 +508,7 @@ void Conversation::pumpMessages() {
}
}
-void Conversation::runScript() {
+void Conversation::runScript(bool exclusive) {
if (!_ttmScript)
return;
@@ -515,7 +519,7 @@ void Conversation::runScript() {
// If not, just run the script at the same time as it's supposed to animate over
// the top of the other game movements.
//
- if (_haveHeadData)
+ if (_haveHeadData || exclusive)
runScriptExclusive();
else
runScriptStep();
@@ -527,13 +531,18 @@ void Conversation::runScriptStep() {
if (_runTempFrame == -1)
_runTempFrame = 2;
- if (!isScriptRunning())
+ if (!isScriptRunning()) {
+ if (_ttmScript && _ttmEnv._cdsFrame >= _ttmEnv._totalFrames)
+ _finished = true;
return;
+ }
_thisFrameMs = engine->getThisFrameMs();
if (!_nextExecMs || _nextExecMs <= _thisFrameMs) {
incrementFrame();
- checkAndRunScript();
+ checkAndRunScript(true);
+ } else {
+ checkAndRunScript(false);
}
}
@@ -587,7 +596,7 @@ void Conversation::runScriptExclusive() {
if (!_nextExecMs || _nextExecMs <= _thisFrameMs) {
incrementFrame();
- checkAndRunScript();
+ checkAndRunScript(true);
// Redraw active dialogs eg to make sure thought bubble dots are
// over the moving heads
diff --git a/engines/dgds/head.h b/engines/dgds/head.h
index 1e1fdbc3c31..5d911ad6794 100644
--- a/engines/dgds/head.h
+++ b/engines/dgds/head.h
@@ -145,7 +145,7 @@ public:
~Conversation();
void unloadData();
- void runScript();
+ void runScript(bool exclusive);
void loadData(uint16 num, uint16 num2, int16 sub, bool haveHeadData);
bool isForDlg(const Dialog *dlg) const;
bool isFinished() const { return _finished; }
@@ -164,7 +164,7 @@ private:
uint32 _nextExecMs;
bool runScriptFrame(int16 frameNum);
- void checkAndRunScript();
+ void checkAndRunScript(bool updateDelay);
void incrementFrame();
bool isScriptRunning();
void pumpMessages();
diff --git a/engines/dgds/scene.cpp b/engines/dgds/scene.cpp
index a83096e7da9..dd72b8aae96 100644
--- a/engines/dgds/scene.cpp
+++ b/engines/dgds/scene.cpp
@@ -891,8 +891,10 @@ void SDSScene::drawAndUpdateHeads(Graphics::ManagedSurface &dst) {
tds.drawAndUpdateVisibleHeads(dst);
}
- if (_conversation.isForDlg(getVisibleDialog())) {
- _conversation.runScript();
+ const Dialog *visibleDlg = getVisibleDialog();
+ if (_conversation.isForDlg(visibleDlg)) {
+ bool exclusive = visibleDlg->hasFlag(kDlgFlagLo8);
+ _conversation.runScript(exclusive);
}
}
@@ -1063,7 +1065,7 @@ bool SDSScene::checkDialogActive() {
if (action) {
// Play the response voice acting script.
_conversation.loadData(dlg._fileNum, dlg._num, action->num, haveHeadData);
- _conversation.runScript();
+ _conversation.runScript(false);
// Take a copy of the dialog because the actions might change the scene
Dialog dlgCopy = dlg;
diff --git a/engines/dgds/ttm.cpp b/engines/dgds/ttm.cpp
index 36ed1bc4fce..5504761cfeb 100644
--- a/engines/dgds/ttm.cpp
+++ b/engines/dgds/ttm.cpp
@@ -252,6 +252,7 @@ const char *TTMInterpreter::ttmOpName(uint16 op) {
case 0xc0e0: return "FADE SONG";
case 0xc0f0: return "SONG CONTROLLER??";
case 0xc100: return "SAMPLE VOL";
+ case 0xc200: return "UNKNOWN 0xC200 RAW SFX ??";
case 0xc210: return "LOAD RAW SFX";
case 0xc220: return "PLAY RAW SFX";
case 0xc240: return "STOP RAW SFX";
More information about the Scummvm-git-logs
mailing list