[Scummvm-git-logs] scummvm master -> 6ef6950299fdd8f3882c9c9c4d12d5eb50b9acd4
fracturehill
noreply at scummvm.org
Fri Mar 17 19:50:52 UTC 2023
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:
6b2780b464 NANCY: Fix secondary movie scene change trigger
62d7cd5792 NANCY: Complete reading of primary video data
ff642056b4 NANCY: Add support for uncompressed video
6ef6950299 NANCY: Fix PaletteNextScene
Commit: 6b2780b464ba0dbd79a831c1fd8ca593e1dd4b6c
https://github.com/scummvm/scummvm/commit/6b2780b464ba0dbd79a831c1fd8ca593e1dd4b6c
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-17T21:32:22+02:00
Commit Message:
NANCY: Fix secondary movie scene change trigger
Fixed the way secondary movies trigger their scene changes to fix
issues that arise with reverse video playback.
Changed paths:
engines/nancy/action/secondarymovie.cpp
diff --git a/engines/nancy/action/secondarymovie.cpp b/engines/nancy/action/secondarymovie.cpp
index 5e0d2d01c58..f75e93b14fa 100644
--- a/engines/nancy/action/secondarymovie.cpp
+++ b/engines/nancy/action/secondarymovie.cpp
@@ -149,10 +149,14 @@ void PlaySecondaryMovie::updateGraphics() {
if ((_decoder.getCurFrame() == _lastFrame && _playDirection == kPlayMovieForward) ||
(_decoder.getCurFrame() == _firstFrame && _playDirection == kPlayMovieReverse) ||
_decoder.atEnd()) {
+
+ // Stop the video and block it from starting again, but also wait for
+ // sound to end before changing state
+ _decoder.stop();
+ _isFinished = true;
+
if (!g_nancy->_sound->isSoundPlaying(_sound)) {
g_nancy->_sound->stopSound(_sound);
- _decoder.stop();
- _isFinished = true;
_state = kActionTrigger;
}
}
Commit: 62d7cd57928fa5654440645260b5ac6db9883ced
https://github.com/scummvm/scummvm/commit/62d7cd57928fa5654440645260b5ac6db9883ced
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-17T21:32:22+02:00
Commit Message:
NANCY: Complete reading of primary video data
Implemented the scene branch structs in primary video. Fixed the
evaluation of primary video flags so conditions with an orFlag
work correctly.
Changed paths:
engines/nancy/action/primaryvideo.cpp
engines/nancy/action/primaryvideo.h
diff --git a/engines/nancy/action/primaryvideo.cpp b/engines/nancy/action/primaryvideo.cpp
index 660f0cad381..21954b95d20 100644
--- a/engines/nancy/action/primaryvideo.cpp
+++ b/engines/nancy/action/primaryvideo.cpp
@@ -37,14 +37,14 @@
namespace Nancy {
namespace Action {
-void PlayPrimaryVideoChan0::ConditionFlag::read(Common::SeekableReadStream &stream) {
+void PlayPrimaryVideoChan0::PrimaryVideoFlag::read(Common::SeekableReadStream &stream) {
type = stream.readByte();
flag.label = stream.readSint16LE();
flag.flag = stream.readByte();
orFlag = stream.readByte();
}
-bool PlayPrimaryVideoChan0::ConditionFlag::isSatisfied() const {
+bool PlayPrimaryVideoChan0::PrimaryVideoFlag::isSatisfied() const {
switch (type) {
case kFlagEvent:
return NancySceneState.getEventFlag(flag);
@@ -55,7 +55,7 @@ bool PlayPrimaryVideoChan0::ConditionFlag::isSatisfied() const {
}
}
-void PlayPrimaryVideoChan0::ConditionFlag::set() const {
+void PlayPrimaryVideoChan0::PrimaryVideoFlag::set() const {
switch (type) {
case kFlagEvent:
NancySceneState.setEventFlag(flag);
@@ -73,36 +73,42 @@ void PlayPrimaryVideoChan0::ConditionFlag::set() const {
}
}
-void PlayPrimaryVideoChan0::ConditionFlags::read(Common::SeekableReadStream &stream) {
+void PlayPrimaryVideoChan0::PrimaryVideoFlags::read(Common::SeekableReadStream &stream) {
uint16 numFlags = stream.readUint16LE();
- conditionFlags.reserve(numFlags);
+ conditionFlags.resize(numFlags);
for (uint i = 0; i < numFlags; ++i) {
- conditionFlags.push_back(ConditionFlag());
- conditionFlags.back().read(stream);
+ conditionFlags[i].read(stream);
}
}
-bool PlayPrimaryVideoChan0::ConditionFlags::isSatisfied() const {
- bool orFlag = false;
+bool PlayPrimaryVideoChan0::PrimaryVideoFlags::isSatisfied() const {
+ Common::Array<bool> conditionsMet(conditionFlags.size(), false);
for (uint i = 0; i < conditionFlags.size(); ++i) {
- const ConditionFlag &cur = conditionFlags[i];
+ if (conditionFlags[i].isSatisfied()) {
+ conditionsMet[i] = true;
+ }
- if (!cur.isSatisfied()) {
- if (orFlag) {
- return false;
- } else {
- orFlag = true;
+ if (conditionFlags[i].orFlag && i < conditionFlags.size() - 1) {
+ if (conditionsMet[i] == true) {
+ conditionsMet[i + 1] = true;
+ ++i;
+ } else if (conditionFlags[i + 1].isSatisfied()) {
+ conditionsMet[i] = true;
+ conditionsMet[i + 1] = true;
+ ++i;
}
}
}
- if (orFlag) {
- return false;
- } else {
- return true;
+ for (uint i = 0; i < conditionsMet.size(); ++i) {
+ if (conditionsMet[i] == false) {
+ return false;
+ }
}
+
+ return true;
}
PlayPrimaryVideoChan0::~PlayPrimaryVideoChan0() {
@@ -214,15 +220,17 @@ void PlayPrimaryVideoChan0::readData(Common::SeekableReadStream &stream) {
delete[] rawText;
uint16 numSceneBranchStructs = stream.readUint16LE();
- if (numSceneBranchStructs > 0) {
- // TODO
+ _sceneBranchStructs.resize(numSceneBranchStructs);
+ for (uint i = 0; i < numSceneBranchStructs; ++i) {
+ _sceneBranchStructs[i].conditions.read(stream);
+ _sceneBranchStructs[i].sceneChange.readData(stream, g_nancy->getGameType() == kGameTypeVampire);
+ stream.skip(0x32);
}
uint16 numFlagsStructs = stream.readUint16LE();
- _flagsStructs.reserve(numFlagsStructs);
- for (uint16 i = 0; i < numFlagsStructs; ++i) {
- _flagsStructs.push_back(FlagsStruct());
- FlagsStruct &flagsStruct = _flagsStructs.back();
+ _flagsStructs.resize(numFlagsStructs);
+ for (uint i = 0; i < numFlagsStructs; ++i) {
+ FlagsStruct &flagsStruct = _flagsStructs[i];
flagsStruct.conditions.read(stream);
flagsStruct.flagToSet.type = stream.readByte();
flagsStruct.flagToSet.flag.label = stream.readSint16LE();
@@ -365,7 +373,12 @@ void PlayPrimaryVideoChan0::execute() {
if (_pickedResponse != -1) {
NancySceneState.changeScene(_responses[_pickedResponse].sceneChange);
} else {
- // Evaluate scene branch structs here
+ for (uint i = 0; i < _sceneBranchStructs.size(); ++i) {
+ if (_sceneBranchStructs[i].conditions.isSatisfied()) {
+ NancySceneState.changeScene(_sceneBranchStructs[i].sceneChange);
+ break;
+ }
+ }
if (_defaultNextScene == kDefaultNextSceneEnabled) {
NancySceneState.changeScene(_sceneChange);
diff --git a/engines/nancy/action/primaryvideo.h b/engines/nancy/action/primaryvideo.h
index 0ae0532f1fc..501556bd792 100644
--- a/engines/nancy/action/primaryvideo.h
+++ b/engines/nancy/action/primaryvideo.h
@@ -36,7 +36,7 @@ namespace Action {
// ActionRecord subclass that handles all NPC dialog and nancy1's intro video
class PlayPrimaryVideoChan0 : public ActionRecord, public RenderObject {
-struct ConditionFlag {
+struct PrimaryVideoFlag {
byte type;
FlagDescription flag;
byte orFlag;
@@ -46,15 +46,15 @@ struct ConditionFlag {
void set() const;
};
-struct ConditionFlags {
- Common::Array<ConditionFlag> conditionFlags;
+struct PrimaryVideoFlags {
+ Common::Array<PrimaryVideoFlag> conditionFlags;
void read(Common::SeekableReadStream &stream);
bool isSatisfied() const;
};
struct ResponseStruct {
- ConditionFlags conditionFlags; // 0x01
+ PrimaryVideoFlags conditionFlags; // 0x01
Common::String text; // 0x06
Common::String soundName; // 0x196
SceneChangeDescription sceneChange; // 0x1A0
@@ -64,8 +64,13 @@ struct ResponseStruct {
};
struct FlagsStruct {
- ConditionFlags conditions;
- ConditionFlag flagToSet;
+ PrimaryVideoFlags conditions;
+ PrimaryVideoFlag flagToSet;
+};
+
+struct SceneBranchStruct {
+ PrimaryVideoFlags conditions;
+ SceneChangeDescription sceneChange;
};
public:
@@ -105,6 +110,7 @@ public:
Common::Array<ResponseStruct> _responses;
Common::Array<FlagsStruct> _flagsStructs;
+ Common::Array<SceneBranchStruct> _sceneBranchStructs;
AVFDecoder _decoder;
Commit: ff642056b432f45501b23bb76ff0f2db22d1edb2
https://github.com/scummvm/scummvm/commit/ff642056b432f45501b23bb76ff0f2db22d1edb2
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-17T21:32:24+02:00
Commit Message:
NANCY: Add support for uncompressed video
Added support for the extremely rare case where an AVF video
would be uncompressed.
Changed paths:
engines/nancy/video.cpp
engines/nancy/video.h
diff --git a/engines/nancy/video.cpp b/engines/nancy/video.cpp
index b7b13095200..d03f685225b 100644
--- a/engines/nancy/video.cpp
+++ b/engines/nancy/video.cpp
@@ -100,6 +100,7 @@ AVFDecoder::AVFVideoTrack::AVFVideoTrack(Common::SeekableReadStream *stream, uin
_frameTime = stream->readUint32LE();
byte comp = stream->readByte();
+ _compressed = comp == 2;
uint formatHi = chunkFileFormat >> 16;
@@ -107,7 +108,7 @@ AVFDecoder::AVFVideoTrack::AVFVideoTrack(Common::SeekableReadStream *stream, uin
stream->skip(1);
}
- if (comp != 2)
+ if (comp != 1 && comp != 2)
error("Unknown compression type %d found in AVF", comp);
_surface = new Graphics::Surface();
@@ -247,27 +248,38 @@ const Graphics::Surface *AVFDecoder::AVFVideoTrack::decodeFrame(uint frameNr) {
warning("Decompressed size %d exceeds frame size %d", info.size, _frameSize);
return nullptr;
}
+
+ decompBuf = (byte *)_surface->getPixels();
} else {
// For types 1 and 2, we decompress to a temp buffer for decoding
decompBuf = new byte[info.size];
}
-
- Common::MemoryWriteStream output((info.type == 0 ? (byte *)_surface->getPixels() : decompBuf), info.size);
+
Common::SeekableSubReadStream input(_fileStream, info.offset, info.offset + info.compressedSize);
- if (!_dec->decompress(input, output)) {
- warning("Failed to decompress frame %d", frameNr);
- delete[] decompBuf;
- return nullptr;
- }
+ if (_compressed) {
+ Common::MemoryWriteStream output(decompBuf, info.size);
+
+ if (!_dec->decompress(input, output)) {
+ warning("Failed to decompress frame %d", frameNr);
+ delete[] decompBuf;
+ return nullptr;
+ }
+ } else {
+ // No compression, just copy the data
+ input.read(decompBuf, info.size);
+ }
if (info.type != 0) {
Common::MemoryReadStream decompStr(decompBuf, info.size);
decode((byte *)_surface->getPixels(), _frameSize, decompStr);
}
+ if (info.type != 0) {
+ delete[] decompBuf;
+ }
+
_refFrame = frameNr;
- delete[] decompBuf;
return _surface;
}
diff --git a/engines/nancy/video.h b/engines/nancy/video.h
index ea93ffe62fb..9fa1f4e8047 100644
--- a/engines/nancy/video.h
+++ b/engines/nancy/video.h
@@ -92,6 +92,7 @@ private:
Common::Array<ChunkInfo> _chunkInfo;
Decompressor *_dec;
bool _reversed;
+ bool _compressed;
};
};
Commit: 6ef6950299fdd8f3882c9c9c4d12d5eb50b9acd4
https://github.com/scummvm/scummvm/commit/6ef6950299fdd8f3882c9c9c4d12d5eb50b9acd4
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-17T21:32:25+02:00
Commit Message:
NANCY: Fix PaletteNextScene
Fixed the handling of scene changes so the PaletteNextScene
action record does its job correctly.
Changed paths:
engines/nancy/commontypes.h
engines/nancy/state/scene.cpp
engines/nancy/state/scene.h
diff --git a/engines/nancy/commontypes.h b/engines/nancy/commontypes.h
index 40d62138890..9c181137b26 100644
--- a/engines/nancy/commontypes.h
+++ b/engines/nancy/commontypes.h
@@ -113,7 +113,7 @@ struct SceneChangeDescription {
uint16 verticalOffset = 0;
uint16 continueSceneSound = kLoadSceneSound;
- int8 paletteID = 0; // TVD only
+ int8 paletteID = -1; // TVD only
void readData(Common::SeekableReadStream &stream, bool longFormat = false);
};
diff --git a/engines/nancy/state/scene.cpp b/engines/nancy/state/scene.cpp
index 60747578177..6b9de304881 100644
--- a/engines/nancy/state/scene.cpp
+++ b/engines/nancy/state/scene.cpp
@@ -174,7 +174,7 @@ void Scene::onStateExit() {
_gameStateRequested = NancyState::kNone;
}
-void Scene::changeScene(uint16 id, uint16 frame, uint16 verticalOffset, byte continueSceneSound, byte paletteID) {
+void Scene::changeScene(uint16 id, uint16 frame, uint16 verticalOffset, byte continueSceneSound, int8 paletteID) {
if (id == 9999) {
return;
}
@@ -182,8 +182,12 @@ void Scene::changeScene(uint16 id, uint16 frame, uint16 verticalOffset, byte con
_sceneState.nextScene.sceneID = id;
_sceneState.nextScene.frameID = frame;
_sceneState.nextScene.verticalOffset = verticalOffset;
- _sceneState.nextScene.paletteID = paletteID;
_sceneState.continueSceneSound = continueSceneSound;
+
+ if (paletteID != -1) {
+ _sceneState.nextScene.paletteID = paletteID;
+ }
+
_state = kLoad;
}
@@ -561,7 +565,7 @@ void Scene::load() {
_sceneState.currentScene.verticalOffset,
_sceneState.summary.panningType,
_sceneState.summary.videoFormat,
- _sceneState.summary.palettes.size() ? _sceneState.summary.palettes[_sceneState.currentScene.paletteID] : Common::String());
+ _sceneState.summary.palettes.size() ? _sceneState.summary.palettes[(byte)_sceneState.currentScene.paletteID] : Common::String());
if (_viewport.getFrameCount() <= 1) {
_viewport.disableEdges(kLeft | kRight);
diff --git a/engines/nancy/state/scene.h b/engines/nancy/state/scene.h
index 4a0c9692c9c..cbcce1951b2 100644
--- a/engines/nancy/state/scene.h
+++ b/engines/nancy/state/scene.h
@@ -118,7 +118,7 @@ public:
void onStateEnter() override;
void onStateExit() override;
- void changeScene(uint16 id, uint16 frame, uint16 verticalOffset, byte continueSceneSound, byte paletteID = 0);
+ void changeScene(uint16 id, uint16 frame, uint16 verticalOffset, byte continueSceneSound, int8 paletteID = -1);
void changeScene(const SceneChangeDescription &sceneDescription);
void pushScene();
void popScene();
More information about the Scummvm-git-logs
mailing list