[Scummvm-git-logs] scummvm master -> f6157c53016024f5d60b7b0f6068608313d8cb78

fracturehill noreply at scummvm.org
Fri Aug 25 11:20:35 UTC 2023


This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
6303a5b0b7 NANCY: Implement PlayDigiSoundCC record type
21ccd1d783 NANCY: Properly handle empty video frames
f6157c5301 NANCY: Correctly render type 2 AVF frames


Commit: 6303a5b0b712b32d25dccf2df2b93dc8bd836a47
    https://github.com/scummvm/scummvm/commit/6303a5b0b712b32d25dccf2df2b93dc8bd836a47
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-08-25T14:19:47+03:00

Commit Message:
NANCY: Implement PlayDigiSoundCC record type

Added support for PlayDigiSoundCC, which plays a sound
file and displays text in the textbox. First introduced in nancy5.

Changed paths:
    engines/nancy/action/arfactory.cpp
    engines/nancy/action/recordtypes.cpp
    engines/nancy/action/recordtypes.h


diff --git a/engines/nancy/action/arfactory.cpp b/engines/nancy/action/arfactory.cpp
index 27dd6ca6f86..141d2289f87 100644
--- a/engines/nancy/action/arfactory.cpp
+++ b/engines/nancy/action/arfactory.cpp
@@ -175,6 +175,8 @@ ActionRecord *ActionManager::createActionRecord(uint16 type) {
 		return new StopSound();
 	case 155:
 		return new StopSound(); // StopAndUnloadSound, but we always unload
+	case 157:
+		return new PlayDigiSoundCC();
 	case 160:
 		return new HintSystem();
 	case 170:
diff --git a/engines/nancy/action/recordtypes.cpp b/engines/nancy/action/recordtypes.cpp
index 8747b847d1b..dff33d64a22 100644
--- a/engines/nancy/action/recordtypes.cpp
+++ b/engines/nancy/action/recordtypes.cpp
@@ -606,6 +606,25 @@ void PlayDigiSoundAndDie::execute() {
 	}
 }
 
+void PlayDigiSoundCC::readData(Common::SeekableReadStream &stream) {
+	PlayDigiSoundAndDie::readData(stream);
+
+	uint16 textSize = stream.readUint16LE();
+	if (textSize) {
+		char *strBuf = new char[textSize];
+		stream.read(strBuf, textSize);
+		UI::Textbox::assembleTextLine(strBuf, _ccText, textSize);
+		delete[] strBuf;
+	}
+}
+
+void PlayDigiSoundCC::execute() {
+	if (_state == kBegin) {
+		NancySceneState.getTextbox().addTextLine(_ccText);
+	}
+	PlayDigiSoundAndDie::execute();
+}
+
 void PlaySoundPanFrameAnchorAndDie::readData(Common::SeekableReadStream &stream) {
 	_sound.readDIGI(stream);
 	stream.skip(2);
diff --git a/engines/nancy/action/recordtypes.h b/engines/nancy/action/recordtypes.h
index 00314353c71..0700f3f4135 100644
--- a/engines/nancy/action/recordtypes.h
+++ b/engines/nancy/action/recordtypes.h
@@ -424,6 +424,17 @@ protected:
 	Common::String getRecordTypeName() const override { return "PlayDigiSoundAndDie"; }
 };
 
+class PlayDigiSoundCC : public PlayDigiSoundAndDie {
+public:
+	void readData(Common::SeekableReadStream &stream) override;
+	void execute() override;
+
+	Common::String _ccText;
+
+protected:
+	Common::String getRecordTypeName() const override { return "PlayDigiSoundCC"; }
+};
+
 class PlaySoundPanFrameAnchorAndDie : public ActionRecord {
 public:
 	void readData(Common::SeekableReadStream &stream) override;


Commit: 21ccd1d7831691fe2d67d072fea117a6a3c74d85
    https://github.com/scummvm/scummvm/commit/21ccd1d7831691fe2d67d072fea117a6a3c74d85
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-08-25T14:19:47+03:00

Commit Message:
NANCY: Properly handle empty video frames

Fixed support for empty video frames in AVF type 2 videos.
This makes all AVF videos properly seekable.

Changed paths:
    engines/nancy/video.cpp
    engines/nancy/video.h


diff --git a/engines/nancy/video.cpp b/engines/nancy/video.cpp
index ea212e2757c..3804d91b421 100644
--- a/engines/nancy/video.cpp
+++ b/engines/nancy/video.cpp
@@ -130,8 +130,7 @@ bool AVFDecoder::atEnd() const {
 AVFDecoder::AVFVideoTrack::AVFVideoTrack(Common::SeekableReadStream *stream, uint32 chunkFileFormat, CacheHint cacheHint) {
 	assert(stream);
 	_fileStream = stream;
-	_curFrame = -1;
-	_refFrame = -1;
+	_curFrame = 0;
 	_reversed = false;
 	_dec = new Decompressor;
 
@@ -202,7 +201,6 @@ AVFDecoder::AVFVideoTrack::~AVFVideoTrack() {
 }
 
 bool AVFDecoder::AVFVideoTrack::seek(const Audio::Timestamp &time) {
-	// TODO this will almost definitely break video type 2
 	_curFrame = getFrameAtTime(time);
 	return true;
 }
@@ -269,8 +267,7 @@ bool AVFDecoder::AVFVideoTrack::decode(byte *outBuf, uint32 frameSize, Common::R
 const Graphics::Surface *AVFDecoder::AVFVideoTrack::decodeFrame(uint frameNr) {
 	if (frameNr < _frameCache.size() && _frameCache[frameNr].getPixels()) {
 		// Frame is cached, return a pointer to it
-		_surface = &_frameCache[frameNr];
-		return _surface;
+		return &_frameCache[frameNr];
 	}
 
 	if (frameNr >= _chunkInfo.size()) {
@@ -280,19 +277,19 @@ const Graphics::Surface *AVFDecoder::AVFVideoTrack::decodeFrame(uint frameNr) {
 
 	const ChunkInfo &info = _chunkInfo[frameNr];
 
-	if (info.type == 2 && (_refFrame == -1 || _refFrame != (int)frameNr - 1)) {
-		warning("Cannot decode frame %d, reference frame is invalid", frameNr);
-		return nullptr;
-	}
-
 	if (!info.size && !info.compressedSize) {
 		if (info.type != 2) {
 			warning("Found empty frame %d of type %d", frameNr, info.type);
 			return nullptr;
 		}
-		// Return previous frame
-		_refFrame = frameNr;
-		return _surface;
+
+		// Type 2 empty frames are valid. We recursively call decodeFrame until
+		// we find a valid previous frame, or arrive at the beginning of the video
+		if (frameNr != 0) {
+			return decodeFrame(frameNr - 1);
+		} else {
+			return nullptr;
+		}
 	}
 
 	Graphics::Surface &frameInCache = _frameCache[frameNr];
@@ -336,13 +333,11 @@ const Graphics::Surface *AVFDecoder::AVFVideoTrack::decodeFrame(uint frameNr) {
 		delete[] decompBuf;
 	}
 
-	_refFrame = frameNr;
-	_surface = &frameInCache;
-	return _surface;
+	return &frameInCache;
 }
 
 const Graphics::Surface *AVFDecoder::AVFVideoTrack::decodeNextFrame() {
-	return decodeFrame(_reversed ? _curFrame-- : ++_curFrame);
+	return decodeFrame(_reversed ? _curFrame-- : _curFrame++);
 }
 
 } // End of namespace Nancy
diff --git a/engines/nancy/video.h b/engines/nancy/video.h
index b0e87cd52ed..93db53aa6c4 100644
--- a/engines/nancy/video.h
+++ b/engines/nancy/video.h
@@ -51,7 +51,6 @@ public:
 	void addFrameTime(const uint16 timeToAdd);
 	bool atEnd() const;
 
-
 private:
 	CacheHint _cacheHint;
 	class AVFVideoTrack : public FixedRateVideoTrack {
@@ -95,8 +94,6 @@ private:
 		int _curFrame;
 		uint _frameCount;
 		uint32 _frameTime;
-		Graphics::Surface *_surface;
-		int _refFrame;
 		Common::Array<ChunkInfo> _chunkInfo;
 		Decompressor *_dec;
 		bool _reversed;


Commit: f6157c53016024f5d60b7b0f6068608313d8cb78
    https://github.com/scummvm/scummvm/commit/f6157c53016024f5d60b7b0f6068608313d8cb78
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-08-25T14:19:47+03:00

Commit Message:
NANCY: Correctly render type 2 AVF frames

Changed paths:
    engines/nancy/video.cpp


diff --git a/engines/nancy/video.cpp b/engines/nancy/video.cpp
index 3804d91b421..53429343d7a 100644
--- a/engines/nancy/video.cpp
+++ b/engines/nancy/video.cpp
@@ -264,7 +264,7 @@ bool AVFDecoder::AVFVideoTrack::decode(byte *outBuf, uint32 frameSize, Common::R
 	return true;
 }
 
-const Graphics::Surface *AVFDecoder::AVFVideoTrack::decodeFrame(uint frameNr) {
+const Graphics::Surface *AVFDecoder::AVFVideoTrack::decodeFrame(uint frameNr)  {
 	if (frameNr < _frameCache.size() && _frameCache[frameNr].getPixels()) {
 		// Frame is cached, return a pointer to it
 		return &_frameCache[frameNr];
@@ -325,6 +325,16 @@ const Graphics::Surface *AVFDecoder::AVFVideoTrack::decodeFrame(uint frameNr) {
 	}
 
 	if (info.type != 0) {
+		if (info.type == 2 && frameNr != 0) {
+			// Type 2 frames are incomplete, and only contain the pixels
+			// that are different from the last valid frame. Thus, we need 
+			// to decode the previous frame and copy its contents to the new one's
+			const Graphics::Surface *refFrame = decodeFrame(frameNr - 1);
+			if (refFrame) {
+				Graphics::copyBlit((byte *)frameInCache.getPixels(), (const byte *)refFrame->getPixels(),
+					frameInCache.pitch, refFrame->pitch, frameInCache.w, frameInCache.h, frameInCache.format.bytesPerPixel);
+			}
+		}
 		Common::MemoryReadStream decompStr(decompBuf, info.size);
 		decode((byte *)frameInCache.getPixels(), _frameSize, decompStr);
 	}




More information about the Scummvm-git-logs mailing list