[Scummvm-git-logs] scummvm master -> c4bafa1b50dc627302c98c18f6ebffb6729873e3
antoniou79
noreply at scummvm.org
Tue Feb 3 08:01:22 UTC 2026
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
a30df00176 MYST3: Fixes for scripted movie playback
f66baeba8f MYST3: Fix for rotation of left turntable track
c4bafa1b50 MYST3: Track unused state variables in scripted movies
Commit: a30df001763ff404d8ccc768ce13ffebbf39372d
https://github.com/scummvm/scummvm/commit/a30df001763ff404d8ccc768ce13ffebbf39372d
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2026-02-03T10:01:10+02:00
Commit Message:
MYST3: Fixes for scripted movie playback
This should fix bug #15297
Also should fix noticeable jumps in a few video loops (at the loop point)
Changed paths:
engines/myst3/movie.cpp
engines/myst3/movie.h
engines/myst3/myst3.cpp
engines/myst3/myst3.h
diff --git a/engines/myst3/movie.cpp b/engines/myst3/movie.cpp
index 73c6087c9f5..dd7b1d7bd06 100644
--- a/engines/myst3/movie.cpp
+++ b/engines/myst3/movie.cpp
@@ -234,6 +234,7 @@ ScriptedMovie::ScriptedMovie(Myst3Engine *vm, uint16 id) :
_enabled(false),
_disableWhenComplete(false),
_scriptDriven(false),
+ _isPreloaded(false),
_isLastFrame(false),
_soundHeading(0),
_soundAttenuation(0),
@@ -257,17 +258,49 @@ void ScriptedMovie::drawOverlay() {
Movie::drawOverlay();
}
-void ScriptedMovie::update() {
+void ScriptedMovie::update(bool pauseAtFirstFrame) {
+ int32 effectiveStartFrame = _startFrame;
+ int32 effectiveEndFrame = _endFrame;
+
if (_startFrameVar) {
- _startFrame = _vm->_state->getVar(_startFrameVar);
+ uint16 startFrameVarValue = _vm->_state->getVar(_startFrameVar);
+ if (startFrameVarValue == 0) {
+ effectiveStartFrame = startFrameVarValue;
+ } else {
+ effectiveStartFrame = startFrameVarValue - 1;
+ }
}
if (_endFrameVar) {
- _endFrame = _vm->_state->getVar(_endFrameVar);
+ uint16 endFrameVarValue = _vm->_state->getVar(_endFrameVar);
+ if (endFrameVarValue == 0) {
+ effectiveEndFrame = endFrameVarValue;
+ } else {
+ effectiveEndFrame = endFrameVarValue - 1;
+ }
+ }
+
+ uint32 frameCount = _bink.getFrameCount();
+ if (!effectiveEndFrame || (uint32)effectiveEndFrame >= frameCount) {
+ if ((uint32)effectiveEndFrame == frameCount) {
+ // A special case: if endFrame is equal to frameCount, decrease it by 1,
+ // but also decrease startFrame by 1 (if it wasn't explicitly set by startFrameVar)
+ // Example case: the looping movie 13011 of the swiming jellyfish at node LIFO 11
+ --effectiveEndFrame;
+ if (!_startFrameVar && effectiveStartFrame > 0) {
+ --effectiveStartFrame;
+ }
+ } else {
+ effectiveEndFrame = frameCount - 1;
+ }
}
- if (!_endFrame) {
- _endFrame = _bink.getFrameCount();
+ if (!_startFrameVar && effectiveStartFrame > 0) {
+ --effectiveStartFrame;
+ }
+
+ if (effectiveStartFrame >= effectiveEndFrame) {
+ effectiveStartFrame = effectiveEndFrame;
}
if (_posUVar) {
@@ -293,11 +326,12 @@ void ScriptedMovie::update() {
_enabled = newEnabled;
if (newEnabled) {
+ int currFrame = _bink.getCurFrame();
if (_disableWhenComplete
- || _bink.getCurFrame() < _startFrame
- || _bink.getCurFrame() >= _endFrame
- || _bink.endOfVideo()) {
- _bink.seekToFrame(_startFrame);
+ || currFrame < effectiveStartFrame
+ || currFrame >= effectiveEndFrame
+ || _bink.endOfVideo()) {
+ _bink.seekToFrame(effectiveStartFrame);
_isLastFrame = false;
}
@@ -316,18 +350,35 @@ void ScriptedMovie::update() {
}
if (_enabled) {
+ if (_isPreloaded) {
+ if (pauseAtFirstFrame) {
+ if (!_bink.isPaused()) {
+ _bink.pauseVideo(true);
+ }
+ return;
+ } else {
+ _isPreloaded = false;
+ if (_bink.isPaused()) {
+ _bink.pauseVideo(false);
+ }
+ }
+ }
+
updateVolume();
+ bool drawnAFrame = false; // not taking into account the first frame when enabling the movie (intentional)
if (_nextFrameReadVar) {
int32 nextFrame = _vm->_state->getVar(_nextFrameReadVar);
if (nextFrame > 0 && nextFrame <= (int32)_bink.getFrameCount()) {
// Are we changing frame?
- if (_bink.getCurFrame() != nextFrame - 1) {
+ int currFrame = _bink.getCurFrame();
+ if (currFrame != nextFrame - 1) {
// Don't seek if we just want to display the next frame
- if (_bink.getCurFrame() + 1 != nextFrame - 1) {
+ if (currFrame + 1 != nextFrame - 1) {
_bink.seekToFrame(nextFrame - 1);
}
drawNextFrameToTexture();
+ drawnAFrame = true;
}
_vm->_state->setVar(_nextFrameReadVar, 0);
@@ -335,21 +386,20 @@ void ScriptedMovie::update() {
}
}
- if (!_scriptDriven && (_bink.needsUpdate() || _isLastFrame)) {
+ if (!drawnAFrame && !_scriptDriven && (_bink.needsUpdate() || _isLastFrame)) {
bool complete = false;
if (_isLastFrame) {
_isLastFrame = false;
-
if (_loop) {
- _bink.seekToFrame(_startFrame);
+ _bink.seekToFrame(effectiveStartFrame);
drawNextFrameToTexture();
} else {
complete = true;
}
} else {
drawNextFrameToTexture();
- _isLastFrame = _bink.getCurFrame() == (_endFrame - 1);
+ _isLastFrame = _bink.getCurFrame() == effectiveEndFrame;
}
if (_nextFrameWriteVar) {
@@ -509,7 +559,7 @@ ProjectorMovie::~ProjectorMovie() {
}
}
-void ProjectorMovie::update() {
+void ProjectorMovie::update(bool justFirstFrame) {
if (!_frame) {
// First call, get the alpha channel from the bink file
const Graphics::Surface *frame = _bink.decodeNextFrame();
diff --git a/engines/myst3/movie.h b/engines/myst3/movie.h
index b9743431fd4..e8308c3f34e 100644
--- a/engines/myst3/movie.h
+++ b/engines/myst3/movie.h
@@ -97,7 +97,7 @@ public:
void draw() override;
void drawOverlay() override;
- virtual void update();
+ virtual void update(bool pauseAtFirstFrame = false) ;
void setEndFrameVar(uint16 v) { _endFrameVar = v; }
void setNextFrameReadVar(uint16 v) { _nextFrameReadVar = v; }
@@ -107,6 +107,7 @@ public:
void setPosVVar(uint16 v) { _posVVar = v; }
void setVolumeVar(uint16 v) { _volumeVar = v; }
void setStartFrameVar(uint16 v) { _startFrameVar = v; }
+ void setPreloaded(bool b) { _isPreloaded = b; }
void setCondition(int16 condition) { _condition = condition; }
void setConditionBit(int16 cb) { _conditionBit = cb; }
void setDisableWhenComplete(bool upd) { _disableWhenComplete = upd; }
@@ -124,6 +125,7 @@ protected:
bool _disableWhenComplete;
bool _scriptDriven;
bool _isLastFrame;
+ bool _isPreloaded;
int16 _condition;
uint16 _conditionBit;
@@ -173,7 +175,7 @@ public:
ProjectorMovie(Myst3Engine *vm, uint16 id, Graphics::Surface *background);
virtual ~ProjectorMovie();
- void update();
+ void update(bool pauseAtFirstFrame = false);
private:
Graphics::Surface *_background;
diff --git a/engines/myst3/myst3.cpp b/engines/myst3/myst3.cpp
index bccbf9db312..8f33659004d 100644
--- a/engines/myst3/myst3.cpp
+++ b/engines/myst3/myst3.cpp
@@ -722,7 +722,7 @@ void Myst3Engine::interactWithHoveredElement() {
_sound->playEffect(697, 5);
}
-void Myst3Engine::drawFrame(bool noSwap) {
+void Myst3Engine::drawFrame(bool noSwap, bool pausePreloadedScriptMovies) {
_sound->update();
_gfx->clear();
@@ -755,7 +755,7 @@ void Myst3Engine::drawFrame(bool noSwap) {
}
for (int i = _movies.size() - 1; i >= 0 ; i--) {
- _movies[i]->update();
+ _movies[i]->update(pausePreloadedScriptMovies);
_gfx->renderDrawable(_movies[i], _scene);
}
@@ -1136,6 +1136,11 @@ void Myst3Engine::loadMovie(uint16 id, uint16 condition, bool resetCond, bool lo
_state->setMovieScriptDriven(0);
}
+ if (_state->getMoviePreloadToMemory()) {
+ movie->setPreloaded(_state->getMoviePreloadToMemory());
+ _state->setMoviePreloadToMemory(0);
+ }
+
if (_state->getMovieStartFrameVar()) {
movie->setStartFrameVar(_state->getMovieStartFrameVar());
_state->setMovieStartFrameVar(0);
@@ -1301,8 +1306,7 @@ void Myst3Engine::playSimpleMovie(uint16 id, bool fullframe, bool refreshAmbient
_inputEscapePressedNotConsumed = false;
break;
}
-
- drawFrame();
+ drawFrame(false, true);
}
_drawables.pop_back();
diff --git a/engines/myst3/myst3.h b/engines/myst3/myst3.h
index 7ca4b904358..d84047b8fd8 100644
--- a/engines/myst3/myst3.h
+++ b/engines/myst3/myst3.h
@@ -174,7 +174,7 @@ public:
void animateDirectionChange(float pitch, float heading, uint16 scriptTicks);
void getMovieLookAt(uint16 id, bool start, float &pitch, float &heading);
- void drawFrame(bool noSwap = false);
+ void drawFrame(bool noSwap = false, bool pausePreloadedScriptMovies = false);
void processInput(bool interactive);
void processEventForKeyboardState(const Common::Event &event);
Commit: f66baeba8fb7aaff3743e2b2b3cfcf44d4dee2c4
https://github.com/scummvm/scummvm/commit/f66baeba8fb7aaff3743e2b2b3cfcf44d4dee2c4
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2026-02-03T10:01:10+02:00
Commit Message:
MYST3: Fix for rotation of left turntable track
This is for movie id 12001
It is an original game bug, fixed by tampering with the frames to be played in the problematic segment
Changed paths:
engines/myst3/movie.cpp
diff --git a/engines/myst3/movie.cpp b/engines/myst3/movie.cpp
index dd7b1d7bd06..609ac623fd2 100644
--- a/engines/myst3/movie.cpp
+++ b/engines/myst3/movie.cpp
@@ -375,7 +375,18 @@ void ScriptedMovie::update(bool pauseAtFirstFrame) {
if (currFrame != nextFrame - 1) {
// Don't seek if we just want to display the next frame
if (currFrame + 1 != nextFrame - 1) {
- _bink.seekToFrame(nextFrame - 1);
+ if (getId() == 12001 && nextFrame >= 200 && nextFrame < 250) {
+ // fix glitchy transition for rotation of the left turntable track (movie id 12001),
+ // eg. when the left dial panel has no wood pegs
+ if (nextFrame >= 247) {
+ // values 247 and 248 should stay at the same frame
+ _bink.seekToFrame(248);
+ } else {
+ _bink.seekToFrame(nextFrame + 1);
+ }
+ } else {
+ _bink.seekToFrame(nextFrame - 1);
+ }
}
drawNextFrameToTexture();
drawnAFrame = true;
Commit: c4bafa1b50dc627302c98c18f6ebffb6729873e3
https://github.com/scummvm/scummvm/commit/c4bafa1b50dc627302c98c18f6ebffb6729873e3
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2026-02-03T10:01:10+02:00
Commit Message:
MYST3: Track unused state variables in scripted movies
And also clean up their value, after it's stored in the pertinent movie member variables
This is done mostly for debugging purposes. I do not anticipate that these will become useful in the future, though it's possible.
NOTE: Up to now, the engine did not clean up these state variables, so their values in restored saved games may be stale, during their first next use.
Changed paths:
engines/myst3/movie.cpp
engines/myst3/movie.h
engines/myst3/myst3.cpp
engines/myst3/state.h
diff --git a/engines/myst3/movie.cpp b/engines/myst3/movie.cpp
index 609ac623fd2..499896eab35 100644
--- a/engines/myst3/movie.cpp
+++ b/engines/myst3/movie.cpp
@@ -235,6 +235,9 @@ ScriptedMovie::ScriptedMovie(Myst3Engine *vm, uint16 id) :
_disableWhenComplete(false),
_scriptDriven(false),
_isPreloaded(false),
+ _noFrameSkip(false),
+ _unk147(0),
+ _unk148(0),
_isLastFrame(false),
_soundHeading(0),
_soundAttenuation(0),
diff --git a/engines/myst3/movie.h b/engines/myst3/movie.h
index e8308c3f34e..1597b785df4 100644
--- a/engines/myst3/movie.h
+++ b/engines/myst3/movie.h
@@ -108,6 +108,9 @@ public:
void setVolumeVar(uint16 v) { _volumeVar = v; }
void setStartFrameVar(uint16 v) { _startFrameVar = v; }
void setPreloaded(bool b) { _isPreloaded = b; }
+ void setNoFrameSkip(bool b) { _noFrameSkip = b; }
+ void setUnk147(uint16 v) { _unk147 = v; }
+ void setUnk148(uint16 v) { _unk148 = v; }
void setCondition(int16 condition) { _condition = condition; }
void setConditionBit(int16 cb) { _conditionBit = cb; }
void setDisableWhenComplete(bool upd) { _disableWhenComplete = upd; }
@@ -126,6 +129,9 @@ protected:
bool _scriptDriven;
bool _isLastFrame;
bool _isPreloaded;
+ bool _noFrameSkip;
+ uint16 _unk147;
+ uint16 _unk148;
int16 _condition;
uint16 _conditionBit;
diff --git a/engines/myst3/myst3.cpp b/engines/myst3/myst3.cpp
index 8f33659004d..7fd6626e5ef 100644
--- a/engines/myst3/myst3.cpp
+++ b/engines/myst3/myst3.cpp
@@ -1141,6 +1141,21 @@ void Myst3Engine::loadMovie(uint16 id, uint16 condition, bool resetCond, bool lo
_state->setMoviePreloadToMemory(0);
}
+ if (_state->getMovieNoFrameSkip()) {
+ movie->setNoFrameSkip(_state->getMovieNoFrameSkip());
+ _state->setMovieNoFrameSkip(0);
+ }
+
+ if (_state->getMovieUnk147()) {
+ movie->setUnk147(_state->getMovieUnk147());
+ _state->setMovieUnk147(0);
+ }
+
+ if (_state->getMovieUnk148()) {
+ movie->setUnk148(_state->getMovieUnk148());
+ _state->setMovieUnk148(0);
+ }
+
if (_state->getMovieStartFrameVar()) {
movie->setStartFrameVar(_state->getMovieStartFrameVar());
_state->setMovieStartFrameVar(0);
diff --git a/engines/myst3/state.h b/engines/myst3/state.h
index 9e054570674..dd380006f31 100644
--- a/engines/myst3/state.h
+++ b/engines/myst3/state.h
@@ -158,6 +158,9 @@ public:
DECLARE_VAR(MovieOverrideSubtitles)
DECLARE_VAR(MovieConditionBit)
DECLARE_VAR(MoviePreloadToMemory)
+ DECLARE_VAR(MovieNoFrameSkip)
+ DECLARE_VAR(MovieUnk147)
+ DECLARE_VAR(MovieUnk148)
DECLARE_VAR(MovieScriptDriven)
DECLARE_VAR(MovieNextFrameSetVar)
DECLARE_VAR(MovieNextFrameGetVar)
More information about the Scummvm-git-logs
mailing list