aboutsummaryrefslogtreecommitdiff
path: root/video/coktel_decoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'video/coktel_decoder.cpp')
-rw-r--r--video/coktel_decoder.cpp166
1 files changed, 134 insertions, 32 deletions
diff --git a/video/coktel_decoder.cpp b/video/coktel_decoder.cpp
index 0c7ade1b8a..6a60b0e7d7 100644
--- a/video/coktel_decoder.cpp
+++ b/video/coktel_decoder.cpp
@@ -53,7 +53,8 @@ CoktelDecoder::CoktelDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundT
_mixer(mixer), _soundType(soundType), _width(0), _height(0), _x(0), _y(0),
_defaultX(0), _defaultY(0), _features(0), _frameCount(0), _paletteDirty(false),
_ownSurface(true), _frameRate(12), _hasSound(false), _soundEnabled(false),
- _soundStage(kSoundNone), _audioStream(0) {
+ _soundStage(kSoundNone), _audioStream(0), _startTime(0), _pauseStartTime(0),
+ _isPaused(false) {
assert(_mixer);
@@ -261,6 +262,10 @@ bool CoktelDecoder::isPaletted() const {
return true;
}
+int CoktelDecoder::getCurFrame() const {
+ return _curFrame;
+}
+
void CoktelDecoder::close() {
disableSound();
freeSurface();
@@ -273,9 +278,14 @@ void CoktelDecoder::close() {
_features = 0;
- _frameCount = 0;
+ _curFrame = -1;
+ _frameCount = 0;
+
+ _startTime = 0;
_hasSound = false;
+
+ _isPaused = false;
}
uint16 CoktelDecoder::getWidth() const {
@@ -291,6 +301,7 @@ uint32 CoktelDecoder::getFrameCount() const {
}
const byte *CoktelDecoder::getPalette() {
+ _paletteDirty = false;
return _palette;
}
@@ -625,14 +636,45 @@ Common::Rational CoktelDecoder::getFrameRate() const {
return _frameRate;
}
+uint32 CoktelDecoder::getTimeToNextFrame() const {
+ if (endOfVideo() || _curFrame < 0)
+ return 0;
+
+ uint32 elapsedTime = g_system->getMillis() - _startTime;
+ uint32 nextFrameStartTime = (Common::Rational((_curFrame + 1) * 1000) / getFrameRate()).toInt();
+
+ if (nextFrameStartTime <= elapsedTime)
+ return 0;
+
+ return nextFrameStartTime - elapsedTime;
+}
+
uint32 CoktelDecoder::getStaticTimeToNextFrame() const {
return (1000 / _frameRate).toInt();
}
+void CoktelDecoder::pauseVideo(bool pause) {
+ if (_isPaused != pause) {
+ if (_isPaused) {
+ // Add the time we were paused to the initial starting time
+ _startTime += g_system->getMillis() - _pauseStartTime;
+ } else {
+ // Store the time we paused for use later
+ _pauseStartTime = g_system->getMillis();
+ }
+
+ _isPaused = pause;
+ }
+}
+
inline void CoktelDecoder::unsignedToSigned(byte *buffer, int length) {
while (length-- > 0) *buffer++ ^= 0x80;
}
+bool CoktelDecoder::endOfVideo() const {
+ return !isVideoLoaded() || (getCurFrame() >= (int32)getFrameCount() - 1);
+}
+
PreIMDDecoder::PreIMDDecoder(uint16 width, uint16 height,
Audio::Mixer *mixer, Audio::Mixer::SoundType soundType) : CoktelDecoder(mixer, soundType),
@@ -705,8 +747,6 @@ bool PreIMDDecoder::loadStream(Common::SeekableReadStream *stream) {
}
void PreIMDDecoder::close() {
- reset();
-
CoktelDecoder::close();
delete _stream;
@@ -1159,8 +1199,6 @@ bool IMDDecoder::loadFrameTables(uint32 framePosPos, uint32 frameCoordsPos) {
}
void IMDDecoder::close() {
- reset();
-
CoktelDecoder::close();
delete _stream;
@@ -1225,8 +1263,6 @@ void IMDDecoder::processFrame() {
_dirtyRects.clear();
- _paletteDirty = false;
-
uint32 cmd = 0;
bool hasNextCmd = false;
bool startSound = false;
@@ -1273,7 +1309,7 @@ void IMDDecoder::processFrame() {
// Set palette
if (cmd == kCommandPalette) {
_stream->skip(2);
-
+
_paletteDirty = true;
for (int i = 0; i < 768; i++)
@@ -1322,7 +1358,7 @@ void IMDDecoder::processFrame() {
// Start the audio stream if necessary
if (startSound && _soundEnabled) {
_mixer->playStream(_soundType, &_audioHandle, _audioStream,
- -1, getVolume(), getBalance(), DisposeAfterUse::NO);
+ -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
_soundStage = kSoundPlaying;
}
@@ -1504,16 +1540,6 @@ Graphics::PixelFormat IMDDecoder::getPixelFormat() const {
return Graphics::PixelFormat::createFormatCLUT8();
}
-void IMDDecoder::updateVolume() {
- if (g_system->getMixer()->isSoundHandleActive(_audioHandle))
- g_system->getMixer()->setChannelVolume(_audioHandle, getVolume());
-}
-
-void IMDDecoder::updateBalance() {
- if (g_system->getMixer()->isSoundHandleActive(_audioHandle))
- g_system->getMixer()->setChannelBalance(_audioHandle, getBalance());
-}
-
VMDDecoder::File::File() {
offset = 0;
@@ -1552,7 +1578,7 @@ VMDDecoder::VMDDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundType) :
_soundLastFilledFrame(0), _audioFormat(kAudioFormat8bitRaw),
_hasVideo(false), _videoCodec(0), _blitMode(0), _bytesPerPixel(0),
_firstFramePos(0), _videoBufferSize(0), _externalCodec(false), _codec(0),
- _subtitle(-1), _isPaletted(true) {
+ _subtitle(-1), _isPaletted(true), _autoStartSound(true) {
_videoBuffer [0] = 0;
_videoBuffer [1] = 0;
@@ -2014,8 +2040,6 @@ bool VMDDecoder::readFiles() {
}
void VMDDecoder::close() {
- reset();
-
CoktelDecoder::close();
delete _stream;
@@ -2095,7 +2119,6 @@ void VMDDecoder::processFrame() {
_dirtyRects.clear();
- _paletteDirty = false;
_subtitle = -1;
bool startSound = false;
@@ -2215,8 +2238,9 @@ void VMDDecoder::processFrame() {
if (startSound && _soundEnabled) {
if (_hasSound && _audioStream) {
- _mixer->playStream(_soundType, &_audioHandle, _audioStream,
- -1, getVolume(), getBalance(), DisposeAfterUse::NO);
+ if (_autoStartSound)
+ _mixer->playStream(_soundType, &_audioHandle, _audioStream,
+ -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
_soundStage = kSoundPlaying;
} else
_soundStage = kSoundNone;
@@ -2742,14 +2766,92 @@ bool VMDDecoder::isPaletted() const {
return _isPaletted;
}
-void VMDDecoder::updateVolume() {
- if (g_system->getMixer()->isSoundHandleActive(_audioHandle))
- g_system->getMixer()->setChannelVolume(_audioHandle, getVolume());
+void VMDDecoder::setAutoStartSound(bool autoStartSound) {
+ _autoStartSound = autoStartSound;
+}
+
+AdvancedVMDDecoder::AdvancedVMDDecoder(Audio::Mixer::SoundType soundType) {
+ _decoder = new VMDDecoder(g_system->getMixer(), soundType);
+ _decoder->setAutoStartSound(false);
+}
+
+AdvancedVMDDecoder::~AdvancedVMDDecoder() {
+ close();
+ delete _decoder;
+}
+
+bool AdvancedVMDDecoder::loadStream(Common::SeekableReadStream *stream) {
+ close();
+
+ if (!_decoder->loadStream(stream))
+ return false;
+
+ if (_decoder->hasVideo()) {
+ _videoTrack = new VMDVideoTrack(_decoder);
+ addTrack(_videoTrack);
+ }
+
+ if (_decoder->hasSound()) {
+ _audioTrack = new VMDAudioTrack(_decoder);
+ addTrack(_audioTrack);
+ }
+
+ return true;
+}
+
+void AdvancedVMDDecoder::close() {
+ VideoDecoder::close();
+ _decoder->close();
+}
+
+AdvancedVMDDecoder::VMDVideoTrack::VMDVideoTrack(VMDDecoder *decoder) : _decoder(decoder) {
+}
+
+uint16 AdvancedVMDDecoder::VMDVideoTrack::getWidth() const {
+ return _decoder->getWidth();
+}
+
+uint16 AdvancedVMDDecoder::VMDVideoTrack::getHeight() const {
+ return _decoder->getHeight();
+}
+
+Graphics::PixelFormat AdvancedVMDDecoder::VMDVideoTrack::getPixelFormat() const {
+ return _decoder->getPixelFormat();
+}
+
+int AdvancedVMDDecoder::VMDVideoTrack::getCurFrame() const {
+ return _decoder->getCurFrame();
+}
+
+int AdvancedVMDDecoder::VMDVideoTrack::getFrameCount() const {
+ return _decoder->getFrameCount();
+}
+
+const Graphics::Surface *AdvancedVMDDecoder::VMDVideoTrack::decodeNextFrame() {
+ return _decoder->decodeNextFrame();
+}
+
+const byte *AdvancedVMDDecoder::VMDVideoTrack::getPalette() const {
+ return _decoder->getPalette();
+}
+
+bool AdvancedVMDDecoder::VMDVideoTrack::hasDirtyPalette() const {
+ return _decoder->hasDirtyPalette();
+}
+
+Common::Rational AdvancedVMDDecoder::VMDVideoTrack::getFrameRate() const {
+ return _decoder->getFrameRate();
+}
+
+AdvancedVMDDecoder::VMDAudioTrack::VMDAudioTrack(VMDDecoder *decoder) : _decoder(decoder) {
+}
+
+Audio::Mixer::SoundType AdvancedVMDDecoder::VMDAudioTrack::getSoundType() const {
+ return _decoder->_soundType;
}
-void VMDDecoder::updateBalance() {
- if (g_system->getMixer()->isSoundHandleActive(_audioHandle))
- g_system->getMixer()->setChannelBalance(_audioHandle, getBalance());
+Audio::AudioStream *AdvancedVMDDecoder::VMDAudioTrack::getAudioStream() const {
+ return _decoder->_audioStream;
}
} // End of namespace Video