[Scummvm-git-logs] scummvm master -> 81290f304fbaa02d93f7fcbc2bc8efb233bc05fd
fracturehill
noreply at scummvm.org
Mon Sep 25 11:37:52 UTC 2023
This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
60ffa2ee81 NANCY: Adjust SecondaryMovie timing
fdbd8b248d NANCY: Stop record processing after changing scene
a91230f57f NANCY: Fix hotspot overlap in nancy4 puzzle
0a4b4415e0 NANCY: Fix Coverity issues
81290f304f NANCY: Render last frame of reversed video
Commit: 60ffa2ee81fdf1a4545eebf7ffdb25cd78cc136b
https://github.com/scummvm/scummvm/commit/60ffa2ee81fdf1a4545eebf7ffdb25cd78cc136b
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-09-25T14:37:37+03:00
Commit Message:
NANCY: Adjust SecondaryMovie timing
Added an improvement to the ActionRecord processing
code that fixes timing-related issues with secondary movies.
As a result, movies are now better-synchronized than they
ever were in the original engine.
Changed paths:
engines/nancy/action/actionmanager.cpp
engines/nancy/action/actionmanager.h
engines/nancy/action/secondarymovie.h
engines/nancy/sound.cpp
engines/nancy/sound.h
diff --git a/engines/nancy/action/actionmanager.cpp b/engines/nancy/action/actionmanager.cpp
index abc284a9909..6b625912cb1 100644
--- a/engines/nancy/action/actionmanager.cpp
+++ b/engines/nancy/action/actionmanager.cpp
@@ -33,6 +33,9 @@
#include "engines/nancy/action/actionmanager.h"
#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/secondarymovie.h"
+#include "engines/nancy/action/soundrecords.h"
+
#include "engines/nancy/state/scene.h"
namespace Nancy {
namespace Action {
@@ -233,6 +236,8 @@ ActionRecord *ActionManager::createAndLoadNewRecord(Common::SeekableReadStream &
}
void ActionManager::processActionRecords() {
+ _activatedRecordsThisFrame.clear();
+
for (auto record : _records) {
if (record->_isDone) {
continue;
@@ -246,10 +251,16 @@ void ActionManager::processActionRecords() {
}
if (record->_isActive) {
+ if(record->_state == ActionRecord::kBegin) {
+ _activatedRecordsThisFrame.push_back(record);
+ }
+
record->execute();
}
}
+ synchronizeMovieWithSound();
+
debugDrawHotspots();
}
@@ -535,6 +546,59 @@ void ActionManager::synchronize(Common::Serializer &ser) {
}
}
+void ActionManager::synchronizeMovieWithSound() {
+ // Improvement:
+
+ // The original engine had really bad timing issues with AVF videos,
+ // as it set the next frame time by adding the frame length to the current evaluation
+ // time, instead of to the time the previous frame was drawn. As a result, all
+ // movie (and SecondaryVideos) frames play about 12 ms slower than they should.
+ // This results in some unfortunate issues in nancy4: if we do as the original
+ // engine did and just make frames 12 ms slower, some dialogue scenes (like scene 1400)
+ // are very visibly not in sync; also, the entire videocam sequence suffers from
+ // visible stitches where the scene changes not at the time it was intended to.
+ // On the other hand, if instead we don't add those 12ms, that same videocam
+ // sequence has a really nasty sound cutoff in the middle of a character speaking.
+
+ // This function intends to fix this issue by subtly manipulating the playback rate
+ // of the movie so its length ends up matching that of the sound; if the sound rate was
+ // changed instead, we would get slightly off-pitch dialogue, which would be undesirable.
+
+ // The heuristic for catching these cases relies on the scene having a movie and a sound
+ // record start at the same frame, and have a (valid) scene change to the same scene.
+ PlaySecondaryMovie *movie = nullptr;
+ PlayDigiSound *sound = nullptr;
+
+ for (uint i = 0; i < _activatedRecordsThisFrame.size(); ++i) {
+ byte type = _activatedRecordsThisFrame[i]->_type;
+ // Rely on _type for cheaper type check
+ if (type == 53) {
+ movie = (PlaySecondaryMovie *)_activatedRecordsThisFrame[i];
+ } else if (type == 150 || type == 151 || type == 157) {
+ sound = (PlayDigiSound *)_activatedRecordsThisFrame[i];
+ }
+
+ if (movie && sound) {
+ break;
+ }
+ }
+
+ if (movie && sound) {
+ // A movie and a sound both got activated this frame, check if their scene changes match
+ if ( movie->_videoSceneChange == PlaySecondaryMovie::kMovieSceneChange &&
+ movie->_sceneChange.sceneID == sound->_sceneChange.sceneID &&
+ movie->_sceneChange.sceneID != 9999) {
+ // They match, check how long the sound is...
+ Audio::Timestamp length = g_nancy->_sound->getLength(sound->_sound);
+
+ if (length.msecs() != 0) {
+ // ..and set the movie's playback speed to match
+ movie->_decoder.setRate(Common::Rational(movie->_decoder.getDuration().msecs(), length.msecs()));
+ }
+ }
+ }
+}
+
void ActionManager::debugDrawHotspots() {
// Draws a rectangle around (non-puzzle) hotspots as well as the id
// and type of the owning ActionRecord. Hardcoded to font 0 since that's
diff --git a/engines/nancy/action/actionmanager.h b/engines/nancy/action/actionmanager.h
index 1bfad205dfa..8f410cc13dd 100644
--- a/engines/nancy/action/actionmanager.h
+++ b/engines/nancy/action/actionmanager.h
@@ -75,9 +75,12 @@ protected:
static ActionRecord *createActionRecord(uint16 type);
static ActionRecord *createAndLoadNewRecord(Common::SeekableReadStream &inputData);
+ void synchronizeMovieWithSound();
+
void debugDrawHotspots();
Common::Array<ActionRecord *> _records;
+ Common::Array<ActionRecord *> _activatedRecordsThisFrame;
};
} // End of namespace Action
diff --git a/engines/nancy/action/secondarymovie.h b/engines/nancy/action/secondarymovie.h
index 856ec830f35..0e7d079fd38 100644
--- a/engines/nancy/action/secondarymovie.h
+++ b/engines/nancy/action/secondarymovie.h
@@ -79,11 +79,12 @@ public:
SceneChangeDescription _sceneChange;
Common::Array<SecondaryVideoDescription> _videoDescs;
+ AVFDecoder _decoder;
+
protected:
Common::String getRecordTypeName() const override { return "PlaySecondaryMovie"; }
bool isViewportRelative() const override { return true; }
- AVFDecoder _decoder;
Graphics::ManagedSurface _fullFrame;
int _curViewportFrame = -1;
bool _isFinished = false;
diff --git a/engines/nancy/sound.cpp b/engines/nancy/sound.cpp
index fb0b9eb6a17..b348387ced1 100644
--- a/engines/nancy/sound.cpp
+++ b/engines/nancy/sound.cpp
@@ -569,6 +569,26 @@ void SoundManager::setRate(const Common::String &chunkName, uint32 rate) {
setRate(_commonSounds[chunkName], rate);
}
+Audio::Timestamp SoundManager::getLength(uint16 channelID) {
+ if (channelID >= _channels.size() || _channels[channelID].stream == nullptr) {
+ return Audio::Timestamp();
+ }
+
+ return _channels[channelID].stream->getLength().convertToFramerate(getRate(channelID));
+}
+
+Audio::Timestamp SoundManager::getLength(const SoundDescription &description) {
+ if (description.name != "NO SOUND") {
+ return getLength(description.channelID);
+ }
+
+ return Audio::Timestamp();
+}
+
+Audio::Timestamp SoundManager::getLength(const Common::String &chunkName) {
+ return getLength(_commonSounds[chunkName]);
+}
+
void SoundManager::recalculateSoundEffects() {
_shouldRecalculate = true;
diff --git a/engines/nancy/sound.h b/engines/nancy/sound.h
index 2062d50ca8f..ea9a32f18e9 100644
--- a/engines/nancy/sound.h
+++ b/engines/nancy/sound.h
@@ -113,6 +113,10 @@ public:
void setRate(const SoundDescription &description, uint32 rate);
void setRate(const Common::String &chunkName, uint32 rate);
+ Audio::Timestamp getLength(uint16 channelID);
+ Audio::Timestamp getLength(const SoundDescription &description);
+ Audio::Timestamp getLength(const Common::String &chunkName);
+
void soundEffectMaintenance();
void recalculateSoundEffects();
Commit: fdbd8b248d80f97af8312468237dfd0df486d594
https://github.com/scummvm/scummvm/commit/fdbd8b248d80f97af8312468237dfd0df486d594
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-09-25T14:37:37+03:00
Commit Message:
NANCY: Stop record processing after changing scene
Further ActionRecords now stop being processed as soon as
changeScene() is called, instead of getting one last frame
of processing. This fixes nancy4 scene 5708, where clicking
the gate circle would previously activate a sound effect
that it shouldn't
Changed paths:
engines/nancy/action/actionmanager.cpp
diff --git a/engines/nancy/action/actionmanager.cpp b/engines/nancy/action/actionmanager.cpp
index 6b625912cb1..1cd82940aab 100644
--- a/engines/nancy/action/actionmanager.cpp
+++ b/engines/nancy/action/actionmanager.cpp
@@ -257,10 +257,14 @@ void ActionManager::processActionRecords() {
record->execute();
}
+
+ if (NancySceneState._state == State::Scene::kLoad) {
+ // changeScene() must have been called, abort any further processing
+ return;
+ }
}
synchronizeMovieWithSound();
-
debugDrawHotspots();
}
Commit: a91230f57f730f596df77b0b2ea47c5088078302
https://github.com/scummvm/scummvm/commit/a91230f57f730f596df77b0b2ea47c5088078302
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-09-25T14:37:37+03:00
Commit Message:
NANCY: Fix hotspot overlap in nancy4 puzzle
Fixed an issue in nancy4 scene 4308, where a separate exit
record's hotspot overlaps the levers' hotspots and causes
an incorrect sfx on exit.
Changed paths:
engines/nancy/action/puzzle/turningpuzzle.cpp
diff --git a/engines/nancy/action/puzzle/turningpuzzle.cpp b/engines/nancy/action/puzzle/turningpuzzle.cpp
index e2a92e69532..22a8387dedb 100644
--- a/engines/nancy/action/puzzle/turningpuzzle.cpp
+++ b/engines/nancy/action/puzzle/turningpuzzle.cpp
@@ -273,6 +273,9 @@ void TurningPuzzle::handleInput(NancyInput &input) {
g_nancy->_sound->playSound(_turnSound);
_objectCurrentlyTurning = i;
}
+
+ // fixes nancy4 scene 4308
+ input.eatMouseInput();
return;
}
Commit: 0a4b4415e00ca91297e29c15d010c6fafee623f2
https://github.com/scummvm/scummvm/commit/0a4b4415e00ca91297e29c15d010c6fafee623f2
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-09-25T14:37:37+03:00
Commit Message:
NANCY: Fix Coverity issues
Changed paths:
engines/nancy/console.cpp
engines/nancy/enginedata.h
engines/nancy/misc/hypertext.h
diff --git a/engines/nancy/console.cpp b/engines/nancy/console.cpp
index 59fc9b85d91..fc2598e90bc 100644
--- a/engines/nancy/console.cpp
+++ b/engines/nancy/console.cpp
@@ -606,7 +606,10 @@ bool NancyConsole::Cmd_listActionRecords(int argc, const char **argv) {
Common::Queue<Common::String> unknownDescs;
Common::SeekableReadStream *chunk;
IFF sceneIFF("S" + s);
- sceneIFF.load();
+ if (!sceneIFF.load()) {
+ debugPrintf("Invalid scene S%s\n", argv[1]);
+ return true;
+ }
while (chunk = sceneIFF.getChunkStream("ACT", records.size()), chunk != nullptr) {
ActionRecord *rec = ActionManager::createAndLoadNewRecord(*chunk);
diff --git a/engines/nancy/enginedata.h b/engines/nancy/enginedata.h
index 7a54dedf738..0b6b416cb77 100644
--- a/engines/nancy/enginedata.h
+++ b/engines/nancy/enginedata.h
@@ -61,7 +61,10 @@ struct BSUM : public EngineData {
Common::Rect clockHighlightSrc;
// Transparent color
- byte paletteTrans, rTrans, gTrans, bTrans;
+ byte paletteTrans = 0;
+ byte rTrans = 0;
+ byte gTrans = 0;
+ byte bTrans = 0;
uint16 horizontalEdgesSize;
uint16 verticalEdgesSize;
diff --git a/engines/nancy/misc/hypertext.h b/engines/nancy/misc/hypertext.h
index fd31e89fa57..a94138cc0bc 100644
--- a/engines/nancy/misc/hypertext.h
+++ b/engines/nancy/misc/hypertext.h
@@ -32,6 +32,8 @@ namespace Misc {
class HypertextParser {
public:
HypertextParser() :
+ _backgroundColor(0),
+ _highlightBackgroundColor(0),
_numDrawnLines(0),
_drawnTextHeight(0),
_needsTextRedraw(false),
Commit: 81290f304fbaa02d93f7fcbc2bc8efb233bc05fd
https://github.com/scummvm/scummvm/commit/81290f304fbaa02d93f7fcbc2bc8efb233bc05fd
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-09-25T14:37:37+03:00
Commit Message:
NANCY: Render last frame of reversed video
Fixed the same off-by-one error that was previously
plaguing the AVF decoder when playing normally, but
this time for reverse playback as well.
Changed paths:
engines/nancy/action/secondaryvideo.cpp
engines/nancy/video.cpp
engines/nancy/video.h
diff --git a/engines/nancy/action/secondaryvideo.cpp b/engines/nancy/action/secondaryvideo.cpp
index 0f4b372ca2e..dcb3b98969d 100644
--- a/engines/nancy/action/secondaryvideo.cpp
+++ b/engines/nancy/action/secondaryvideo.cpp
@@ -109,7 +109,7 @@ void PlaySecondaryVideo::updateGraphics() {
if (lastAnimationFrame > -1 &&
(_decoder.atEnd() ||
- _decoder.getCurFrame() == lastAnimationFrame + (_decoder.getRate().getNumerator() > 0 ? 1 : -1))) {
+ _decoder.getCurFrame() == lastAnimationFrame)) {
if (_hoverState == kNoHover) {
_decoder.seekToFrame(_loopFirstFrame);
} else {
diff --git a/engines/nancy/video.cpp b/engines/nancy/video.cpp
index a4f90229b79..e72b74769f7 100644
--- a/engines/nancy/video.cpp
+++ b/engines/nancy/video.cpp
@@ -212,7 +212,7 @@ bool AVFDecoder::AVFVideoTrack::setReverse(bool reverse) {
bool AVFDecoder::AVFVideoTrack::endOfTrack() const {
if (_reversed)
- return _curFrame < 0;
+ return _curFrame <= 0;
return _curFrame >= getFrameCount();
}
diff --git a/engines/nancy/video.h b/engines/nancy/video.h
index bc260e7673c..0add8f5760d 100644
--- a/engines/nancy/video.h
+++ b/engines/nancy/video.h
@@ -63,7 +63,7 @@ private:
uint16 getWidth() const override { return _width; }
uint16 getHeight() const override { return _height; }
Graphics::PixelFormat getPixelFormat() const override { return _pixelFormat; }
- int getCurFrame() const override { return _curFrame - 1; }
+ int getCurFrame() const override { return _reversed ? _curFrame : _curFrame - 1; }
int getFrameCount() const override { return _frameCount; }
bool isSeekable() const override { return true; }
bool seek(const Audio::Timestamp &time) override;
More information about the Scummvm-git-logs
mailing list