[Scummvm-git-logs] scummvm master -> 257804824a280488ba59a254aa8c01db6fe1c68f
sev-
noreply at scummvm.org
Thu Feb 27 20:01:08 UTC 2025
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
3970ef4465 DIRECTOR: Add detection entry for cybergrannies
29e2397bf8 DIRECTOR: LINGO: Improve accuracy of "play done"
34a60f7911 DIRECTOR: Only clean sprites when there has been a frame swap
257804824a DIRECTOR: Fix getting the blend of sprite
Commit: 3970ef44654d57eed1092c145357c152ae57a736
https://github.com/scummvm/scummvm/commit/3970ef44654d57eed1092c145357c152ae57a736
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-27T21:01:03+01:00
Commit Message:
DIRECTOR: Add detection entry for cybergrannies
Changed paths:
engines/director/detection_tables.h
diff --git a/engines/director/detection_tables.h b/engines/director/detection_tables.h
index a284db2a4dd..1f742735834 100644
--- a/engines/director/detection_tables.h
+++ b/engines/director/detection_tables.h
@@ -129,6 +129,7 @@ static const PlainGameDescriptor directorGames[] = {
{ "csidarkmotives", "CSI: Crime Scene Investigation - Dark Motives" },
{ "csimiami", "CSI: Miami" },
{ "cutemachine", "The Cute machine" },
+ { "cybergrannies", "Cyber Grannies" },
{ "daedalus", "The Daedalus Encounter" },
{ "darkeye", "The Dark Eye" },
{ "dazzeloids", "Dazzeloids" },
@@ -6555,6 +6556,9 @@ static const DirectorGameDescription gameDescriptions[] = {
MACGAME1("crystalskull", "", "Crystal Skull", "c148f66ae3511fb88733102aa27efe7e", 719459, 501),
WINGAME1t("crystalskull", "", "CRYS32.EXE", "3f5fd025e808943e1fa9b91ce63ef9b7", 1410495, 501),
+ MACGAME1("cybergrannies", "", "Cyber Grannies", "r:231d3041df162be4a0ddd36a74eb03b6", 719337, 501),
+ WINGAME1("cybergrannies", "", "GRANNIES.EXE", "t:2bbebcd580ab1c80f4488d1d2bd0ddbb", 3281215, 501),
+
MACGAME1f_l("darlun", "", "DARLUN", "4bc4f93f5c5169de9f2fee12071a68b9", 717372, Common::JA_JPN, 501, GF_32BPP),
WINGAME1tf_l("darlun", "", "DARLUN_P.EXE", "713a7ef3728ed1952745d204e520972a", 1440286, Common::JA_JPN, 501, GF_32BPP),
Commit: 29e2397bf86de45243da4530c1dac3f567124dd9
https://github.com/scummvm/scummvm/commit/29e2397bf86de45243da4530c1dac3f567124dd9
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-27T21:01:03+01:00
Commit Message:
DIRECTOR: LINGO: Improve accuracy of "play done"
After a script reaches "play done", that script gets aborted.
The Lingo frozen play script (aka the script that initially invoked
play) will be thawed before stopMovie.
Fixes director-tests/D4-unit/T_PLAY01.DIR.
Fixes movie switching in Cyber Grannies.
Changed paths:
engines/director/lingo/lingo-funcs.cpp
engines/director/lingo/lingo.cpp
engines/director/score.cpp
engines/director/score.h
engines/director/window.cpp
diff --git a/engines/director/lingo/lingo-funcs.cpp b/engines/director/lingo/lingo-funcs.cpp
index 5292fb1cb0a..76bedbb6bd2 100644
--- a/engines/director/lingo/lingo-funcs.cpp
+++ b/engines/director/lingo/lingo-funcs.cpp
@@ -55,7 +55,10 @@ void Lingo::func_goto(Datum &frame, Datum &movie, bool calledfromgo) {
// If there isn't already frozen Lingo (e.g. from a previous func_goto we haven't yet unfrozen),
// freeze this script context. We'll return to it after entering the next frame.
- g_lingo->_freezeState = true;
+
+ // Returning from a script with "play done" does not freeze the state. Instead it obliterates it.
+ if (!g_lingo->_playDone)
+ g_lingo->_freezeState = true;
if (movie.type != VOID) {
Common::String movieFilenameRaw = movie.asString();
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 18356d0bff1..86a75f76766 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -618,7 +618,7 @@ Common::String Lingo::formatFunctionBody(Symbol &sym) {
bool Lingo::execute(int targetFrame) {
uint localCounter = 0;
- while (!_abort && !_freezeState && _state->script && (*_state->script)[_state->pc] != STOP) {
+ while (!_abort && !_freezeState && !_playDone && _state->script && (*_state->script)[_state->pc] != STOP) {
if (targetFrame != -1 && (int)_state->callstack.size() == targetFrame)
break;
@@ -698,7 +698,8 @@ bool Lingo::execute(int targetFrame) {
} else if (_freezeState) {
debugC(5, kDebugLingoExec, "Lingo::execute(): Context is frozen, pausing execution");
freezeState();
- } else if (_abort || _vm->getCurrentMovie()->getScore()->_playState == kPlayStopped) {
+ // Returning from a script with "play done" does not freeze the state. Instead it obliterates it.
+ } else if (_abort || _playDone || _vm->getCurrentMovie()->getScore()->_playState == kPlayStopped) {
// Clean up call stack
while (_state->callstack.size()) {
popContext(true);
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 4dbaddd2c3b..7d9255ea17b 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -133,7 +133,7 @@ bool Score::processImmediateFrameScript(Common::String s, int id) {
return false;
}
-bool Score::processFrozenScripts(bool recursion, int count) {
+bool Score::processFrozenPlayScript() {
// Unfreeze the play script if the special flag is set
if (g_lingo->_playDone) {
g_lingo->_playDone = false;
@@ -142,15 +142,22 @@ bool Score::processFrozenScripts(bool recursion, int count) {
g_lingo->switchStateFromWindow();
bool completed = g_lingo->execute();
if (!completed) {
- debugC(3, kDebugLingoExec, "Score::processFrozenScripts(): State froze again mid-thaw, interrupting");
+ debugC(3, kDebugLingoExec, "Score::processFrozenPlayScript(): State froze again mid-thaw, interrupting");
return false;
} else if (currentScript == g_lingo->_currentInputEvent) {
// script that just completed was the current input event, clear the flag
- debugC(3, kDebugEvents, "Score::processFrozenScripts(): Input event completed");
+ debugC(3, kDebugEvents, "Score::processFrozenPlayScript(): Input event completed");
g_lingo->_currentInputEvent = Symbol();
}
}
}
+ return true;
+}
+
+
+bool Score::processFrozenScripts(bool recursion, int count) {
+ if (!processFrozenPlayScript())
+ return false;
// Unfreeze any in-progress scripts and attempt to run them
// to completion.
@@ -380,22 +387,26 @@ bool Score::isWaitingForNextFrame() {
bool keepWaiting = false;
debugC(8, kDebugEvents, "Score::isWaitingForNextFrame(): nextFrameTime: %d, time: %d, sound: %d, click: %d, video: %d", _nextFrameTime, g_system->getMillis(false), _waitForChannel, _waitForClick, _waitForVideoChannel);
+ bool goingTo = _nextFrame && _nextFrame != _curFrameNumber;
+
if (_waitForChannel) {
- if (_soundManager->isChannelActive(_waitForChannel)) {
+ if (_soundManager->isChannelActive(_waitForChannel) && !goingTo) {
keepWaiting = true;
} else {
_waitForChannel = 0;
}
} else if (_waitForClick) {
- if (g_system->getMillis() >= _nextFrameTime + 1000) {
- _waitForClickCursor = !_waitForClickCursor;
- renderCursor(_movie->getWindow()->getMousePos());
- _nextFrameTime = g_system->getMillis();
+ if (!goingTo) {
+ if (g_system->getMillis() >= _nextFrameTime + 1000) {
+ _waitForClickCursor = !_waitForClickCursor;
+ renderCursor(_movie->getWindow()->getMousePos());
+ _nextFrameTime = g_system->getMillis();
+ }
+ keepWaiting = true;
}
- keepWaiting = true;
} else if (_waitForVideoChannel) {
Channel *movieChannel = _channels[_waitForVideoChannel];
- if (movieChannel->isActiveVideo() && movieChannel->_movieRate != 0.0) {
+ if (movieChannel->isActiveVideo() && movieChannel->_movieRate != 0.0 && !goingTo) {
keepWaiting = true;
} else {
_waitForVideoChannel = 0;
diff --git a/engines/director/score.h b/engines/director/score.h
index 6cd1e551d7d..1bfe35b91f6 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -133,6 +133,7 @@ public:
void playSoundChannel(bool puppetOnly);
Common::String formatChannelInfo();
+ bool processFrozenPlayScript();
private:
bool isWaitingForNextFrame();
diff --git a/engines/director/window.cpp b/engines/director/window.cpp
index 9cb4387767a..d9d17aff167 100644
--- a/engines/director/window.cpp
+++ b/engines/director/window.cpp
@@ -512,6 +512,8 @@ bool Window::loadNextMovie() {
bool Window::step() {
// finish last movie
if (_currentMovie && _currentMovie->getScore()->_playState == kPlayStopped) {
+ // attempt to thaw the lingo play state, if required
+ _currentMovie->getScore()->processFrozenPlayScript();
debugC(5, kDebugEvents, "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
debugC(5, kDebugEvents, "@@@@ Finishing movie '%s' in '%s'", utf8ToPrintable(_currentMovie->getMacName()).c_str(), _currentPath.c_str());
debugC(5, kDebugEvents, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
Commit: 34a60f7911edab06b99b5c7e275c4afae9639b1c
https://github.com/scummvm/scummvm/commit/34a60f7911edab06b99b5c7e275c4afae9639b1c
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-27T21:01:03+01:00
Commit Message:
DIRECTOR: Only clean sprites when there has been a frame swap
Most of the time we'll be looping to the same frame, where we want
to update the sprites, but not clobber them with the contents of the
current frame.
Fixes the paint splodges on the easel in the A room of Cyber Grannies.
Fixes the menu system in Cosmology of Kyoto.
Changed paths:
engines/director/score.cpp
engines/director/score.h
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 7d9255ea17b..1b8891e54bd 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -325,6 +325,8 @@ void Score::startPlay() {
for (uint i = 0; i < _currentFrame->_sprites.size(); i++)
_channels.push_back(new Channel(this, _currentFrame->_sprites[i], i));
+ updateSprites(kRenderForceUpdate, true);
+
if (_vm->getVersion() >= 300)
_movie->processEvent(kEventStartMovie);
}
@@ -479,7 +481,7 @@ void Score::updateCurrentFrame() {
loadFrame(nextFrameNumberToLoad, true);
// finally, update the channels and buffer any dirty rectangles
- updateSprites();
+ updateSprites(kRenderModeNormal, true);
}
return;
}
@@ -781,7 +783,7 @@ void Score::incrementFilmLoops() {
}
}
-void Score::updateSprites(RenderMode mode) {
+void Score::updateSprites(RenderMode mode, bool withClean) {
if (_window->_newMovieStarted)
mode = kRenderForceUpdate;
@@ -816,7 +818,9 @@ void Score::updateSprites(RenderMode mode) {
nextSprite->setCast(nextSprite->_castId);
}
- channel->setClean(nextSprite);
+ // Only clean out the channel if we're moving to a different frame
+ if (withClean)
+ channel->setClean(nextSprite);
invalidCastMember = currentSprite ? (currentSprite->_spriteType == kCastMemberSprite && currentSprite->_cast == nullptr) : false;
// Check again to see if a video has just been started by setClean.
if (channel->isActiveVideo())
diff --git a/engines/director/score.h b/engines/director/score.h
index 1bfe35b91f6..784841b786b 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -120,7 +120,7 @@ public:
bool renderTransition(uint16 frameId, RenderMode mode);
void renderFrame(uint16 frameId, RenderMode mode = kRenderModeNormal);
void incrementFilmLoops();
- void updateSprites(RenderMode mode = kRenderModeNormal);
+ void updateSprites(RenderMode mode = kRenderModeNormal, bool withClean = false);
bool renderPrePaletteCycle(RenderMode mode = kRenderModeNormal);
void setLastPalette();
bool isPaletteColorCycling();
Commit: 257804824a280488ba59a254aa8c01db6fe1c68f
https://github.com/scummvm/scummvm/commit/257804824a280488ba59a254aa8c01db6fe1c68f
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-27T21:01:03+01:00
Commit Message:
DIRECTOR: Fix getting the blend of sprite
Fixes the three toads viewable through the telescope of the T room of
Cyber Grannies.
Changed paths:
engines/director/lingo/lingo-the.cpp
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index ee6338cfba2..50392c4636d 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -1475,7 +1475,7 @@ Datum Lingo::getTheSprite(Datum &id1, int field) {
d = (int)g_director->transformColor(sprite->_backColor);
break;
case kTheBlend:
- d = (255 - sprite->_blendAmount) * 255 / 100;
+ d = (255 - sprite->_blendAmount) * 100 / 255;
break;
case kTheBottom:
d = channel->getBbox().bottom;
More information about the Scummvm-git-logs
mailing list