[Scummvm-git-logs] scummvm master -> 13be0648f0dcad6bc0849e4c31bfae9acffa9180

bluegr noreply at scummvm.org
Tue Jan 25 15:57:40 UTC 2022


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

Summary:
13be0648f0 TRECISION: Refactor the video decoder classes


Commit: 13be0648f0dcad6bc0849e4c31bfae9acffa9180
    https://github.com/scummvm/scummvm/commit/13be0648f0dcad6bc0849e4c31bfae9acffa9180
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2022-01-25T17:57:08+02:00

Commit Message:
TRECISION: Refactor the video decoder classes

Change NightlongVideoDecoder to be a base class. This allows us to
remove it as an intermediate class and cleanly separate the PC Smacker
from the Amiga video decoder

Changed paths:
    engines/trecision/animmanager.cpp
    engines/trecision/video.cpp
    engines/trecision/video.h


diff --git a/engines/trecision/animmanager.cpp b/engines/trecision/animmanager.cpp
index a01284bb62b..125c92e58a3 100644
--- a/engines/trecision/animmanager.cpp
+++ b/engines/trecision/animmanager.cpp
@@ -66,33 +66,38 @@ AnimManager::~AnimManager() {
 }
 
 void AnimManager::playMovie(const Common::String &filename, int startFrame, int endFrame, bool singleChoice) {
-	NightlongVideoDecoder *smkDecoder = new NightlongVideoDecoder(_vm->isAmiga());
+	NightlongVideoDecoder *videoDecoder;
 
-	if (!smkDecoder->loadFile(filename)) {
+	if (!_vm->isAmiga())
+		videoDecoder = new NightlongSmackerDecoder();
+	else
+		videoDecoder = new NightlongAmigaDecoder();
+
+	if (!videoDecoder->loadFile(filename)) {
 		warning("playMovie: File %s not found", filename.c_str());
-		delete smkDecoder;
+		delete videoDecoder;
 		_vm->_dialogMgr->afterChoice();
 		return;
 	}
 
 	Common::Event event;
 	bool skipVideo = false;
-	uint16 x = (g_system->getWidth() - smkDecoder->getWidth()) / 2;
-	uint16 y = (g_system->getHeight() - smkDecoder->getHeight()) / 2;
+	uint16 x = (g_system->getWidth() - videoDecoder->getWidth()) / 2;
+	uint16 y = (g_system->getHeight() - videoDecoder->getHeight()) / 2;
 	_vm->_drawText._text.clear();
 
-	smkDecoder->start();
+	videoDecoder->start();
 
 	// WORKAROUND: If the video has a single choice, and it starts from
 	// the beginning, ignore the calculated end frame and play all of it
-	if (singleChoice && startFrame < 10 && endFrame < (int)smkDecoder->getFrameCount() - 1)
-		endFrame = smkDecoder->getFrameCount() - 1;
+	if (singleChoice && startFrame < 10 && endFrame < (int)videoDecoder->getFrameCount() - 1)
+		endFrame = videoDecoder->getFrameCount() - 1;
 
-	setVideoRange(smkDecoder, startFrame, endFrame);
+	setVideoRange(videoDecoder, startFrame, endFrame);
 
-	while (!_vm->shouldQuit() && startFrame != endFrame && !smkDecoder->endOfVideo() && !skipVideo) {
-		if (smkDecoder->needsUpdate()) {
-			drawFrame(smkDecoder, x, y, true);
+	while (!_vm->shouldQuit() && startFrame != endFrame && !videoDecoder->endOfVideo() && !skipVideo) {
+		if (videoDecoder->needsUpdate()) {
+			drawFrame(videoDecoder, x, y, true);
 		}
 
 		while (_vm->getEventManager()->pollEvent(event)) {
@@ -103,7 +108,7 @@ void AnimManager::playMovie(const Common::String &filename, int startFrame, int
 		g_system->delayMillis(10);
 	}
 
-	delete smkDecoder;
+	delete videoDecoder;
 
 	_vm->_mouseLeftBtn = _vm->_mouseRightBtn = false;
 	_vm->freeKey();
@@ -171,7 +176,10 @@ void AnimManager::openSmkAnim(int slot, const Common::String &name) {
 }
 
 void AnimManager::openSmk(int slot, Common::SeekableReadStream *stream) {
-	_animations[slot] = new NightlongVideoDecoder(_vm->isAmiga());
+	if (!_vm->isAmiga())
+		_animations[slot] = new NightlongSmackerDecoder();
+	else
+		_animations[slot] = new NightlongAmigaDecoder();
 
 	if (!_animations[slot]->loadStream(stream)) {
 		warning("Invalid SMK file");
@@ -409,33 +417,33 @@ bool AnimManager::shouldShowAnim(int animation, Common::Rect curRect) {
 }
 
 void AnimManager::drawSmkBackgroundFrame(int animation) {
-	NightlongVideoDecoder *smkDecoder = _animations[kSmackerBackground];
-	if (smkDecoder == nullptr)
+	NightlongVideoDecoder *videoDecoder = _animations[kSmackerBackground];
+	if (videoDecoder == nullptr)
 		return;
-	const Graphics::Surface *frame = smkDecoder->decodeNextFrame();
+	const Graphics::Surface *frame = videoDecoder->decodeNextFrame();
 	if (!frame)
 		return;
 
-	const Common::Rect *lastRect = smkDecoder->getNextDirtyRect();
-	const byte *palette = smkDecoder->getPalette();
+	const Common::Rect *lastRect = videoDecoder->getNextDirtyRect();
+	const byte *palette = videoDecoder->getPalette();
 
-	if (smkDecoder->getCurFrame() == 0 && shouldShowAnim(animation, *lastRect) && !_bgAnimRestarted) {
+	if (videoDecoder->getCurFrame() == 0 && shouldShowAnim(animation, *lastRect) && !_bgAnimRestarted) {
 		_vm->_graphicsMgr->blitToScreenBuffer(frame, 0, TOP, palette, true);
 	} else {
 		while (lastRect) {
-			if (smkDecoder->getCurFrame() > 0 && shouldShowAnim(animation, *lastRect)) {
+			if (videoDecoder->getCurFrame() > 0 && shouldShowAnim(animation, *lastRect)) {
 				Graphics::Surface anim = frame->getSubArea(*lastRect);
 				_vm->_graphicsMgr->blitToScreenBuffer(&anim, lastRect->left, lastRect->top + TOP, palette, true);
 			}
 
-			lastRect = smkDecoder->getNextDirtyRect();
+			lastRect = videoDecoder->getNextDirtyRect();
 		}
 	}
 }
 
 void AnimManager::drawSmkIconFrame(uint16 startIcon, uint16 iconNum) {
-	NightlongVideoDecoder *smkDecoder = _animations[kSmackerIcon];
-	if (smkDecoder == nullptr)
+	NightlongVideoDecoder *videoDecoder = _animations[kSmackerIcon];
+	if (videoDecoder == nullptr)
 		return;
 
 	int stx = ICONMARGSX;
@@ -453,11 +461,14 @@ void AnimManager::drawSmkIconFrame(uint16 startIcon, uint16 iconNum) {
 	if (a == ICONSHOWN)
 		return;
 
-	const Graphics::Surface *frame = smkDecoder->decodeNextFrame();
-	_vm->_graphicsMgr->copyToScreenBuffer(frame, stx, FIRSTLINE, smkDecoder->getPalette());
+	const Graphics::Surface *frame = videoDecoder->decodeNextFrame();
+	if (!frame)
+		return;
+
+	_vm->_graphicsMgr->copyToScreenBuffer(frame, stx, FIRSTLINE, videoDecoder->getPalette());
 
-	if (smkDecoder->endOfVideo())
-		smkDecoder->rewind();
+	if (videoDecoder->endOfVideo())
+		videoDecoder->rewind();
 }
 
 void AnimManager::drawSmkActionFrame() {
diff --git a/engines/trecision/video.cpp b/engines/trecision/video.cpp
index 727d0f72339..b47a34f0be6 100644
--- a/engines/trecision/video.cpp
+++ b/engines/trecision/video.cpp
@@ -39,160 +39,6 @@
 
 namespace Trecision {
 
-NightlongVideoDecoder::NightlongVideoDecoder(bool isAmiga) {
-	_isAmiga = isAmiga;
-	_smkDecoder = !isAmiga ? new NightlongSmackerDecoder() : nullptr;
-	_mixer = g_system->getMixer();
-}
-
-NightlongVideoDecoder::~NightlongVideoDecoder() {
-	delete _smkDecoder;
-
-	if (_mixer->isSoundHandleActive(_amigaSoundHandle))
-		_mixer->stopHandle(_amigaSoundHandle);
-}
-
-bool NightlongVideoDecoder::loadFile(const Common::Path &filename) {
-	if (!_isAmiga)
-		return _smkDecoder->loadFile(filename);
-	else {
-		// TODO: Amiga video format
-
-		// Load the video's audio track
-		Common::File *stream = new Common::File();
-		Common::String file = filename.toString();
-		stream->open("a" + file);
-
-		if (stream->isOpen()) {
-			Audio::SeekableAudioStream *sound = Audio::makeRawStream(stream, 11025, 0, DisposeAfterUse::YES);
-
-			_mixer->playStream(
-				Audio::Mixer::kSFXSoundType,
-				&_amigaSoundHandle,
-				sound);
-
-			return true;
-		} else {
-			delete stream;
-			return false;
-		}	
-	}
-}
-
-bool NightlongVideoDecoder::loadStream(Common::SeekableReadStream *stream) {
-	if (!_isAmiga)
-		return _smkDecoder->loadStream(stream);
-	else
-		return false;	// TODO: Amiga videos
-}
-
-void NightlongVideoDecoder::muteTrack(uint track, bool mute) {
-	if (!_isAmiga)
-		_smkDecoder->muteTrack(track, mute);
-	// TODO: Amiga videos
-}
-
-void NightlongVideoDecoder::setMute(bool mute) {
-	if (!_isAmiga)
-		_smkDecoder->setMute(mute);
-	// TODO: Amiga videos
-}
-
-bool NightlongVideoDecoder::forceSeekToFrame(uint frame) {
-	if (!_isAmiga)
-		return _smkDecoder->forceSeekToFrame(frame);
-	else
-		return false;	// TODO: Amiga videos
-}
-
-bool NightlongVideoDecoder::endOfFrames() const {
-	if (!_isAmiga)
-		return _smkDecoder->endOfFrames();
-	else
-		return !_mixer->isSoundHandleActive(_amigaSoundHandle);	// HACK, since we only play the audio for now
-}
-
-int NightlongVideoDecoder::getCurFrame() const {
-	if (!_isAmiga)
-		return _smkDecoder->getCurFrame();
-	else
-		return 0;	// TODO: Amiga videos
-}
-
-uint16 NightlongVideoDecoder::getWidth() const {
-	if (!_isAmiga)
-		return _smkDecoder->getWidth();
-	else
-		return 0;	// TODO: Amiga videos
-}
-
-uint16 NightlongVideoDecoder::getHeight() const {
-	if (!_isAmiga)
-		return _smkDecoder->getHeight();
-	else
-		return 0;	// TODO: Amiga videos
-}
-
-const Graphics::Surface *NightlongVideoDecoder::decodeNextFrame() {
-	if (!_isAmiga)
-		return _smkDecoder->decodeNextFrame();
-	else
-		return nullptr;	// TODO: Amiga videos
-}
-
-uint32 NightlongVideoDecoder::getFrameCount() const {
-	if (!_isAmiga)
-		return _smkDecoder->getFrameCount();
-	else
-		return 10;	// TODO: Amiga videos. Anything > 1 to keep playing till the audio is done
-}
-
-const byte *NightlongVideoDecoder::getPalette() {
-	if (!_isAmiga)
-		return _smkDecoder->getPalette();
-	else
-		return nullptr;	// TODO: Amiga videos
-}
-
-void NightlongVideoDecoder::start() {
-	if (!_isAmiga)
-		_smkDecoder->start();
-	// TODO: Amiga videos
-}
-
-void NightlongVideoDecoder::rewind() {
-	if (!_isAmiga)
-		_smkDecoder->rewind();
-	// TODO: Amiga videos
-}
-
-bool NightlongVideoDecoder::needsUpdate() const {
-	if (!_isAmiga)
-		return _smkDecoder->needsUpdate();
-	else
-		return false;	// TODO: Amiga videos
-}
-
-void NightlongVideoDecoder::setEndFrame(uint frame) {
-	if (!_isAmiga)
-		_smkDecoder->setEndFrame(frame);
-	// TODO: Amiga videos
-}
-
-bool NightlongVideoDecoder::endOfVideo() const {
-	if (!_isAmiga)
-		return _smkDecoder->endOfVideo();
-	else
-		return false;	// TODO: Amiga videos
-}
-
-const Common::Rect *NightlongVideoDecoder::getNextDirtyRect() {
-	if (!_isAmiga)
-		return _smkDecoder->getNextDirtyRect();
-	else
-		return nullptr;	// TODO: Amiga videos
-}
-
 bool NightlongSmackerDecoder::loadStream(Common::SeekableReadStream *stream) {
 	if (!SmackerDecoder::loadStream(stream))
 		return false;
@@ -271,4 +117,107 @@ bool NightlongSmackerDecoder::endOfFrames() const {
 	return getCurFrame() >= (int32)getFrameCount() - 1;
 }
 
+// ----------------------------------------------------------------------------
+
+NightlongAmigaDecoder::AmigaVideoTrack::AmigaVideoTrack(const Common::String &fileName) {
+	memset(_palette, 0, sizeof(_palette));
+
+	Common::File *stream = new Common::File();
+	stream->open(fileName);
+
+	if (!stream->isOpen())
+		return;
+
+	_curFrame = 0;
+	_frameCount = 10; // TODO: Anything > 1 to keep playing till the audio is done
+
+	// TODO: some videos have more than 256 entries
+	/*uint16 palEntries = stream->readUint16LE();
+	stream->skip(2); // unknown
+	for (uint16 i = 0; i < palEntries; i++) {
+		_palette[i * 3] = stream->readByte();
+		_palette[i * 3 + 1] = stream->readByte();
+		_palette[i * 3 + 2] = stream->readByte();
+		stream->skip(1); // unused alpha channel
+	}*/
+
+	delete stream;
+}
+
+uint16 NightlongAmigaDecoder::AmigaVideoTrack::getWidth() const {
+	// TODO
+	return 0;
+}
+
+uint16 NightlongAmigaDecoder::AmigaVideoTrack::getHeight() const {
+	// TODO
+	return 0;
+}
+
+Graphics::PixelFormat NightlongAmigaDecoder::AmigaVideoTrack::getPixelFormat() const {
+	// TODO
+	return g_system->getScreenFormat();
+}
+
+uint32 NightlongAmigaDecoder::AmigaVideoTrack::getNextFrameStartTime() const {
+	// TODO
+	return 0;
+}
+
+const Graphics::Surface *NightlongAmigaDecoder::AmigaVideoTrack::decodeNextFrame() {
+	// TODO
+	return nullptr;
+}
+
+NightlongAmigaDecoder::AmigaAudioTrack::AmigaAudioTrack(const Common::String &fileName) :
+	AudioTrack(Audio::Mixer::SoundType::kSFXSoundType) {
+	Common::File *stream = new Common::File();
+	stream->open(fileName);
+	_audioStream = Audio::makeRawStream(stream, 11025, 0, DisposeAfterUse::YES);
+}
+
+void NightlongAmigaDecoder::readNextPacket() {
+	AmigaVideoTrack *videoTrack = (AmigaVideoTrack *)getTrack(0);
+
+	if (videoTrack->endOfTrack())
+		return;
+
+	// TODO
+}
+
+bool NightlongAmigaDecoder::loadStream(Common::SeekableReadStream *stream) {
+	Common::File *file = dynamic_cast<Common::File *>(stream);
+	if (!file)
+		return false;
+	Common::String fileName = file->getName();
+	addTrack(new AmigaVideoTrack(fileName));
+	if (Common::File::exists("a" + fileName))
+		addTrack(new AmigaAudioTrack("a" + fileName));
+
+	return true;
+}
+
+void NightlongAmigaDecoder::muteTrack(uint track, bool mute) {
+	// TODO
+}
+
+void NightlongAmigaDecoder::setMute(bool mute) {
+	// TODO
+}
+
+bool NightlongAmigaDecoder::forceSeekToFrame(uint frame) {
+	// TODO
+	return false;
+}
+
+const Common::Rect *NightlongAmigaDecoder::getNextDirtyRect() {
+	// TODO
+	return &_lastDirtyRect;
+}
+
+bool NightlongAmigaDecoder::endOfFrames() const {
+	//return getCurFrame() >= (int32)getFrameCount() - 1;
+	return true;
+}
+
 } // namespace Trecision
diff --git a/engines/trecision/video.h b/engines/trecision/video.h
index 19c9b1bdd5f..3cd679b83ce 100644
--- a/engines/trecision/video.h
+++ b/engines/trecision/video.h
@@ -32,46 +32,64 @@ namespace Trecision {
 
 class TrecisionEngine;
 
-class NightlongSmackerDecoder : public Video::SmackerDecoder {
+class NightlongVideoDecoder : public Video::SmackerDecoder {
+public:
+	virtual void muteTrack(uint track, bool mute) {}
+	virtual void setMute(bool mute) {}
+	virtual bool forceSeekToFrame(uint frame) { return false; }
+	virtual bool endOfFrames() const { return false; }
+};
+
+class NightlongSmackerDecoder : public NightlongVideoDecoder {
 public:
 	bool loadStream(Common::SeekableReadStream *stream) override;
-	void muteTrack(uint track, bool mute);
-	void setMute(bool mute);
-	bool forceSeekToFrame(uint frame);
-	bool endOfFrames() const;
+	void muteTrack(uint track, bool mute) override;
+	void setMute(bool mute) override;
+	bool forceSeekToFrame(uint frame) override;
+	bool endOfFrames() const override;
 };
 
-class NightlongVideoDecoder {
+class NightlongAmigaDecoder : public NightlongVideoDecoder {
 public:
-	NightlongVideoDecoder(bool isAmiga);
-	~NightlongVideoDecoder();
-	bool loadStream(Common::SeekableReadStream *stream);
-	void muteTrack(uint track, bool mute);
-	void setMute(bool mute);
-	bool forceSeekToFrame(uint frame);
-	bool endOfFrames() const;
+	bool loadStream(Common::SeekableReadStream *stream) override;
+	void muteTrack(uint track, bool mute) override;
+	void setMute(bool mute) override;
+	bool forceSeekToFrame(uint frame) override;
+	bool endOfFrames() const override;
+	const Common::Rect *getNextDirtyRect() override;
 
-	// VideoDecoder functions
-	int getCurFrame() const;
-	uint16 getWidth() const;
-	uint16 getHeight() const;
-	const Graphics::Surface *decodeNextFrame();
-	uint32 getFrameCount() const;
-	const byte *getPalette();
-	void start();
-	void rewind();
-	bool needsUpdate() const;
-	void setEndFrame(uint frame);
-	bool endOfVideo() const;
+private:
+	Common::Rect _lastDirtyRect;
 
-	bool loadFile(const Common::Path &filename);
-	const Common::Rect *getNextDirtyRect();
+	void readNextPacket() override;
 
-private:
-	bool _isAmiga;
-	NightlongSmackerDecoder *_smkDecoder;
-	Audio::SoundHandle _amigaSoundHandle;
-	Audio::Mixer *_mixer;
+	class AmigaVideoTrack : public VideoTrack {
+	public:
+		AmigaVideoTrack(const Common::String &fileName);
+
+	private:
+		byte _palette[3 * 256];
+		int _curFrame;
+		uint32 _frameCount;
+
+		uint16 getWidth() const override;
+		uint16 getHeight() const override;
+		Graphics::PixelFormat getPixelFormat() const override;
+		int getCurFrame() const override { return _curFrame; }
+		uint32 getNextFrameStartTime() const override;
+		const Graphics::Surface *decodeNextFrame() override;
+		int getFrameCount() const override { return _frameCount; }
+		const byte *getPalette() const override { return _palette; }
+		bool hasDirtyPalette() const override { return true; }
+	};
+
+	class AmigaAudioTrack : public AudioTrack {
+	public:
+		AmigaAudioTrack(const Common::String &fileName);
+	private:
+		Audio::AudioStream *getAudioStream() const override { return _audioStream; }
+		Audio::AudioStream *_audioStream;
+	};
 };
 
 } // End of namespace Trecision




More information about the Scummvm-git-logs mailing list