[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