diff options
-rw-r--r-- | engines/agos/animation.cpp | 80 | ||||
-rw-r--r-- | engines/agos/animation.h | 5 | ||||
-rw-r--r-- | engines/sword1/animation.cpp | 74 | ||||
-rw-r--r-- | engines/sword1/animation.h | 32 | ||||
-rw-r--r-- | engines/sword1/logic.cpp | 2 | ||||
-rw-r--r-- | engines/sword2/animation.cpp | 62 | ||||
-rw-r--r-- | engines/sword2/animation.h | 30 | ||||
-rw-r--r-- | engines/sword2/function.cpp | 2 | ||||
-rw-r--r-- | video/dxa_decoder.cpp | 130 | ||||
-rw-r--r-- | video/dxa_decoder.h | 102 |
10 files changed, 215 insertions, 304 deletions
diff --git a/engines/agos/animation.cpp b/engines/agos/animation.cpp index 3e8488d7d5..ec8293c91f 100644 --- a/engines/agos/animation.cpp +++ b/engines/agos/animation.cpp @@ -260,9 +260,6 @@ bool MoviePlayerDXA::load() { debug(0, "Playing video %s", videoName.c_str()); CursorMan.showMouse(false); - - _firstFrameOffset = _fileStream->pos(); - return true; } @@ -302,35 +299,6 @@ void MoviePlayerDXA::stopVideo() { } void MoviePlayerDXA::startSound() { - uint32 offset, size; - - if (getSoundTag() == MKTAG('W','A','V','E')) { - size = _fileStream->readUint32BE(); - - if (_sequenceNum) { - Common::File in; - - _fileStream->seek(size, SEEK_CUR); - - in.open("audio.wav"); - if (!in.isOpen()) { - error("Can't read offset file 'audio.wav'"); - } - - in.seek(_sequenceNum * 8, SEEK_SET); - offset = in.readUint32LE(); - size = in.readUint32LE(); - - in.seek(offset, SEEK_SET); - _bgSoundStream = Audio::makeWAVStream(in.readStream(size), DisposeAfterUse::YES); - in.close(); - } else { - _bgSoundStream = Audio::makeWAVStream(_fileStream->readStream(size), DisposeAfterUse::YES); - } - } else { - _bgSoundStream = Audio::SeekableAudioStream::openStreamFile(baseName); - } - if (_bgSoundStream != NULL) { _vm->_mixer->stopHandle(_bgSound); _vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_bgSound, _bgSoundStream, -1, getVolume(), getBalance()); @@ -344,8 +312,7 @@ void MoviePlayerDXA::nextFrame() { } if (_vm->_interactiveVideo == TYPE_LOOPING && endOfVideo()) { - _fileStream->seek(_firstFrameOffset); - _curFrame = -1; + rewind(); startSound(); } @@ -374,13 +341,15 @@ bool MoviePlayerDXA::processFrame() { copyFrameToBuffer((byte *)screen->pixels, (_vm->_screenWidth - getWidth()) / 2, (_vm->_screenHeight - getHeight()) / 2, screen->pitch); _vm->_system->unlockScreen(); - Common::Rational soundTime(_mixer->getSoundElapsedTime(_bgSound), 1000); - if ((_bgSoundStream == NULL) || ((soundTime * getFrameRate()).toInt() / 1000 < getCurFrame() + 1)) { + uint32 soundTime = _mixer->getSoundElapsedTime(_bgSound); + uint32 nextFrameStartTime = ((Video::AdvancedVideoDecoder::VideoTrack *)getTrack(0))->getNextFrameStartTime(); + + if ((_bgSoundStream == NULL) || soundTime < nextFrameStartTime) { if (_bgSoundStream && _mixer->isSoundHandleActive(_bgSound)) { - while (_mixer->isSoundHandleActive(_bgSound) && (soundTime * getFrameRate()).toInt() < getCurFrame()) { + while (_mixer->isSoundHandleActive(_bgSound) && soundTime < nextFrameStartTime) { _vm->_system->delayMillis(10); - soundTime = Common::Rational(_mixer->getSoundElapsedTime(_bgSound), 1000); + soundTime = _mixer->getSoundElapsedTime(_bgSound); } // In case the background sound ends prematurely, update // _ticks so that we can still fall back on the no-sound @@ -399,14 +368,35 @@ bool MoviePlayerDXA::processFrame() { return false; } -void MoviePlayerDXA::updateVolume() { - if (g_system->getMixer()->isSoundHandleActive(_bgSound)) - g_system->getMixer()->setChannelVolume(_bgSound, getVolume()); -} +void MoviePlayerDXA::readSoundData(Common::SeekableReadStream *stream) { + uint32 tag = stream->readUint32BE(); + + if (tag == MKTAG('W','A','V','E')) { + uint32 size = stream->readUint32BE(); + + if (_sequenceNum) { + Common::File in; + + stream->skip(size); + + in.open("audio.wav"); + if (!in.isOpen()) { + error("Can't read offset file 'audio.wav'"); + } + + in.seek(_sequenceNum * 8, SEEK_SET); + uint32 offset = in.readUint32LE(); + size = in.readUint32LE(); -void MoviePlayerDXA::updateBalance() { - if (g_system->getMixer()->isSoundHandleActive(_bgSound)) - g_system->getMixer()->setChannelBalance(_bgSound, getBalance()); + in.seek(offset, SEEK_SET); + _bgSoundStream = Audio::makeWAVStream(in.readStream(size), DisposeAfterUse::YES); + in.close(); + } else { + _bgSoundStream = Audio::makeWAVStream(stream->readStream(size), DisposeAfterUse::YES); + } + } else { + _bgSoundStream = Audio::SeekableAudioStream::openStreamFile(baseName); + } } /////////////////////////////////////////////////////////////////////////////// diff --git a/engines/agos/animation.h b/engines/agos/animation.h index 37a666b201..9e31fced6d 100644 --- a/engines/agos/animation.h +++ b/engines/agos/animation.h @@ -81,16 +81,13 @@ public: virtual void stopVideo(); protected: - // VideoDecoder API - void updateVolume(); - void updateBalance(); + void readSoundData(Common::SeekableReadStream *stream); private: void handleNextFrame(); bool processFrame(); void startSound(); void copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch); - uint32 _firstFrameOffset; }; class MoviePlayerSMK : public MoviePlayer, Video::SmackerDecoder { diff --git a/engines/sword1/animation.cpp b/engines/sword1/animation.cpp index 8f863d1e09..70f1e5dc03 100644 --- a/engines/sword1/animation.cpp +++ b/engines/sword1/animation.cpp @@ -37,6 +37,7 @@ #include "gui/message.h" +#include "video/dxa_decoder.h" #include "video/psx_decoder.h" #include "video/smk_decoder.h" @@ -96,9 +97,8 @@ static const char *const sequenceListPSX[20] = { // Basic movie player /////////////////////////////////////////////////////////////////////////////// -MoviePlayer::MoviePlayer(SwordEngine *vm, Text *textMan, ResMan *resMan, Audio::Mixer *snd, OSystem *system, Audio::SoundHandle *bgSoundHandle, Video::VideoDecoder *decoder, DecoderType decoderType) - : _vm(vm), _textMan(textMan), _resMan(resMan), _snd(snd), _bgSoundHandle(bgSoundHandle), _system(system) { - _bgSoundStream = NULL; +MoviePlayer::MoviePlayer(SwordEngine *vm, Text *textMan, ResMan *resMan, OSystem *system, Video::VideoDecoder *decoder, DecoderType decoderType) + : _vm(vm), _textMan(textMan), _resMan(resMan), _system(system) { _decoderType = decoderType; _decoder = decoder; @@ -107,7 +107,6 @@ MoviePlayer::MoviePlayer(SwordEngine *vm, Text *textMan, ResMan *resMan, Audio:: } MoviePlayer::~MoviePlayer() { - delete _bgSoundHandle; delete _decoder; } @@ -116,16 +115,12 @@ MoviePlayer::~MoviePlayer() { * @param id the id of the file */ bool MoviePlayer::load(uint32 id) { - Common::File f; Common::String filename; - if (_decoderType == kVideoDecoderDXA) - _bgSoundStream = Audio::SeekableAudioStream::openStreamFile(sequenceList[id]); - else - _bgSoundStream = NULL; - if (SwordEngine::_systemVars.showText) { + Common::File f; filename = Common::String::format("%s.txt", sequenceList[id]); + if (f.open(filename)) { Common::String line; int lineNo = 0; @@ -169,7 +164,6 @@ bool MoviePlayer::load(uint32 id) { _movieTexts.push_back(MovieText(startFrame, endFrame, ptr, color)); lastEnd = endFrame; } - f.close(); } } @@ -179,13 +173,6 @@ bool MoviePlayer::load(uint32 id) { break; case kVideoDecoderSMK: filename = Common::String::format("%s.smk", sequenceList[id]); - - if (_decoder->loadFile(filename)) { - ((Video::AdvancedVideoDecoder *)_decoder)->start(); // TODO: Remove after new API is complete - return true; - } else { - return false; - } break; case kVideoDecoderPSX: filename = Common::String::format("%s.str", (_vm->_systemVars.isDemo) ? sequenceList[id] : sequenceListPSX[id]); @@ -205,30 +192,27 @@ bool MoviePlayer::load(uint32 id) { break; } - return _decoder->loadFile(filename.c_str()); -} + if (!_decoder->loadFile(filename)) + return false; -void MoviePlayer::play() { - if (_bgSoundStream) - _snd->playStream(Audio::Mixer::kSFXSoundType, _bgSoundHandle, _bgSoundStream); + // For DXA, also add the external sound file + if (_decoderType == kVideoDecoderDXA) + ((Video::AdvancedVideoDecoder *)_decoder)->addStreamFileTrack(sequenceList[id]); - bool terminated = false; + ((Video::AdvancedVideoDecoder *)_decoder)->start(); // TODO: Remove after new API is complete + return true; +} +void MoviePlayer::play() { _textX = 0; _textY = 0; - terminated = !playVideo(); - - if (terminated) - _snd->stopHandle(*_bgSoundHandle); + playVideo(); _textMan->releaseText(2, false); _movieTexts.clear(); - while (_snd->isSoundHandleActive(*_bgSoundHandle)) - _system->delayMillis(100); - // It's tempting to call _screen->fullRefresh() here to restore the old // palette. However, that causes glitches with DXA movies, where the // previous location would be momentarily drawn, before switching to @@ -514,24 +498,12 @@ void MoviePlayer::drawFramePSX(const Graphics::Surface *frame) { scaledFrame.free(); } -DXADecoderWithSound::DXADecoderWithSound(Audio::Mixer *mixer, Audio::SoundHandle *bgSoundHandle) - : _mixer(mixer), _bgSoundHandle(bgSoundHandle) { -} - -uint32 DXADecoderWithSound::getTime() const { - if (_mixer->isSoundHandleActive(*_bgSoundHandle)) - return _mixer->getSoundElapsedTime(*_bgSoundHandle); - - return DXADecoder::getTime(); -} - /////////////////////////////////////////////////////////////////////////////// // Factory function for creating the appropriate cutscene player /////////////////////////////////////////////////////////////////////////////// -MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, ResMan *resMan, Audio::Mixer *snd, OSystem *system) { +MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, ResMan *resMan, OSystem *system) { Common::String filename; - Audio::SoundHandle *bgSoundHandle = new Audio::SoundHandle; // For the PSX version, we'll try the PlayStation stream files if (vm->isPsx()) { @@ -542,7 +514,7 @@ MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, ResMan * #ifdef USE_RGB_COLOR // All BS1 PSX videos run the videos at 2x speed Video::VideoDecoder *psxDecoder = new Video::PSXStreamDecoder(Video::PSXStreamDecoder::kCD2x); - return new MoviePlayer(vm, textMan, resMan, snd, system, bgSoundHandle, psxDecoder, kVideoDecoderPSX); + return new MoviePlayer(vm, textMan, resMan, system, psxDecoder, kVideoDecoderPSX); #else GUI::MessageDialog dialog(Common::String::format(_("PSX stream cutscene '%s' cannot be played in paletted mode"), filename.c_str()), _("OK")); dialog.runModal(); @@ -555,19 +527,19 @@ MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, ResMan * if (Common::File::exists(filename)) { Video::SmackerDecoder *smkDecoder = new Video::SmackerDecoder(); - return new MoviePlayer(vm, textMan, resMan, snd, system, bgSoundHandle, smkDecoder, kVideoDecoderSMK); + return new MoviePlayer(vm, textMan, resMan, system, smkDecoder, kVideoDecoderSMK); } filename = Common::String::format("%s.dxa", sequenceList[id]); if (Common::File::exists(filename)) { #ifdef USE_ZLIB - DXADecoderWithSound *dxaDecoder = new DXADecoderWithSound(snd, bgSoundHandle); - return new MoviePlayer(vm, textMan, resMan, snd, system, bgSoundHandle, dxaDecoder, kVideoDecoderDXA); + Video::VideoDecoder *dxaDecoder = new Video::DXADecoder(); + return new MoviePlayer(vm, textMan, resMan, system, dxaDecoder, kVideoDecoderDXA); #else GUI::MessageDialog dialog(_("DXA cutscenes found but ScummVM has been built without zlib support"), _("OK")); dialog.runModal(); - return NULL; + return 0; #endif } @@ -577,7 +549,7 @@ MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, ResMan * if (Common::File::exists(filename)) { GUI::MessageDialog dialog(_("MPEG2 cutscenes are no longer supported"), _("OK")); dialog.runModal(); - return NULL; + return 0; } if (!vm->isPsx() || scumm_stricmp(sequenceList[id], "enddemo") != 0) { @@ -586,7 +558,7 @@ MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, ResMan * dialog.runModal(); } - return NULL; + return 0; } } // End of namespace Sword1 diff --git a/engines/sword1/animation.h b/engines/sword1/animation.h index c2ed86a1a3..d0c61f5eb3 100644 --- a/engines/sword1/animation.h +++ b/engines/sword1/animation.h @@ -23,16 +23,19 @@ #ifndef SWORD1_ANIMATION_H #define SWORD1_ANIMATION_H -#include "video/dxa_decoder.h" -#include "video/video_decoder.h" - #include "common/list.h" -#include "audio/audiostream.h" - #include "sword1/screen.h" #include "sword1/sound.h" +namespace Graphics { +struct Surface; +} + +namespace Video { +class VideoDecoder; +} + namespace Sword1 { enum DecoderType { @@ -55,21 +58,9 @@ public: } }; -class DXADecoderWithSound : public Video::DXADecoder { -public: - DXADecoderWithSound(Audio::Mixer *mixer, Audio::SoundHandle *bgSoundHandle); - ~DXADecoderWithSound() {} - - uint32 getTime() const; - -private: - Audio::Mixer *_mixer; - Audio::SoundHandle *_bgSoundHandle; -}; - class MoviePlayer { public: - MoviePlayer(SwordEngine *vm, Text *textMan, ResMan *resMan, Audio::Mixer *snd, OSystem *system, Audio::SoundHandle *bgSoundHandle, Video::VideoDecoder *decoder, DecoderType decoderType); + MoviePlayer(SwordEngine *vm, Text *textMan, ResMan *resMan, OSystem *system, Video::VideoDecoder *decoder, DecoderType decoderType); virtual ~MoviePlayer(); bool load(uint32 id); void play(); @@ -78,7 +69,6 @@ protected: SwordEngine *_vm; Text *_textMan; ResMan *_resMan; - Audio::Mixer *_snd; OSystem *_system; Common::List<MovieText> _movieTexts; int _textX, _textY, _textWidth, _textHeight; @@ -88,8 +78,6 @@ protected: DecoderType _decoderType; Video::VideoDecoder *_decoder; - Audio::SoundHandle *_bgSoundHandle; - Audio::AudioStream *_bgSoundStream; bool playVideo(); void performPostProcessing(byte *screen); @@ -100,7 +88,7 @@ protected: void convertColor(byte r, byte g, byte b, float &h, float &s, float &v); }; -MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, ResMan *resMan, Audio::Mixer *snd, OSystem *system); +MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, ResMan *resMan, OSystem *system); } // End of namespace Sword1 diff --git a/engines/sword1/logic.cpp b/engines/sword1/logic.cpp index 8e04861edf..757d768780 100644 --- a/engines/sword1/logic.cpp +++ b/engines/sword1/logic.cpp @@ -959,7 +959,7 @@ int Logic::fnPlaySequence(Object *cpt, int32 id, int32 sequenceId, int32 d, int3 // meantime, we don't want any looping sound effects still playing. _sound->quitScreen(); - MoviePlayer *player = makeMoviePlayer(sequenceId, _vm, _textMan, _resMan, _mixer, _system); + MoviePlayer *player = makeMoviePlayer(sequenceId, _vm, _textMan, _resMan, _system); if (player) { _screen->clearScreen(); if (player->load(sequenceId)) diff --git a/engines/sword2/animation.cpp b/engines/sword2/animation.cpp index e257ec9029..e603925e73 100644 --- a/engines/sword2/animation.cpp +++ b/engines/sword2/animation.cpp @@ -40,6 +40,7 @@ #include "gui/message.h" +#include "video/dxa_decoder.h" #include "video/smk_decoder.h" #include "video/psx_decoder.h" @@ -51,9 +52,8 @@ namespace Sword2 { // Basic movie player /////////////////////////////////////////////////////////////////////////////// -MoviePlayer::MoviePlayer(Sword2Engine *vm, Audio::Mixer *snd, OSystem *system, Audio::SoundHandle *bgSoundHandle, Video::VideoDecoder *decoder, DecoderType decoderType) - : _vm(vm), _snd(snd), _bgSoundHandle(bgSoundHandle), _system(system) { - _bgSoundStream = NULL; +MoviePlayer::MoviePlayer(Sword2Engine *vm, OSystem *system, Video::VideoDecoder *decoder, DecoderType decoderType) + : _vm(vm), _system(system) { _decoderType = decoderType; _decoder = decoder; @@ -62,7 +62,6 @@ MoviePlayer::MoviePlayer(Sword2Engine *vm, Audio::Mixer *snd, OSystem *system, A } MoviePlayer::~MoviePlayer() { - delete _bgSoundHandle; delete _decoder; } @@ -75,11 +74,6 @@ bool MoviePlayer::load(const char *name) { if (_vm->shouldQuit()) return false; - if (_decoderType == kVideoDecoderDXA) - _bgSoundStream = Audio::SeekableAudioStream::openStreamFile(name); - else - _bgSoundStream = NULL; - _textSurface = NULL; Common::String filename; @@ -89,13 +83,6 @@ bool MoviePlayer::load(const char *name) { break; case kVideoDecoderSMK: filename = Common::String::format("%s.smk", name); - - if (_decoder->loadFile(filename)) { - ((Video::AdvancedVideoDecoder *)_decoder)->start(); // TODO: Remove after new API is complete - return true; - } else { - return false; - } break; case kVideoDecoderPSX: filename = Common::String::format("%s.str", name); @@ -114,7 +101,15 @@ bool MoviePlayer::load(const char *name) { } } - return _decoder->loadFile(filename.c_str()); + if (!_decoder->loadFile(filename)) + return false; + + // For DXA, also add the external sound file + if (_decoderType == kVideoDecoderDXA) + ((Video::AdvancedVideoDecoder *)_decoder)->addStreamFileTrack(name); + + ((Video::AdvancedVideoDecoder *)_decoder)->start(); // TODO: Remove after new API is complete + return true; } void MoviePlayer::play(MovieText *movieTexts, uint32 numMovieTexts, uint32 leadIn, uint32 leadOut) { @@ -130,24 +125,15 @@ void MoviePlayer::play(MovieText *movieTexts, uint32 numMovieTexts, uint32 leadI if (leadIn) _vm->_sound->playMovieSound(leadIn, kLeadInSound); - if (_bgSoundStream) - _snd->playStream(Audio::Mixer::kSFXSoundType, _bgSoundHandle, _bgSoundStream); - - bool terminated = false; - - terminated = !playVideo(); + bool terminated = !playVideo(); closeTextObject(_currentMovieText, NULL, 0); if (terminated) { - _snd->stopHandle(*_bgSoundHandle); _vm->_sound->stopMovieSounds(); _vm->_sound->stopSpeech(); } - while (_snd->isSoundHandleActive(*_bgSoundHandle)) - _system->delayMillis(100); - if (_decoderType == kVideoDecoderPSX) { // Need to jump back to paletted color initGraphics(640, 480, true); @@ -414,31 +400,19 @@ void MoviePlayer::drawFramePSX(const Graphics::Surface *frame) { scaledFrame.free(); } -DXADecoderWithSound::DXADecoderWithSound(Audio::Mixer *mixer, Audio::SoundHandle *bgSoundHandle) - : _mixer(mixer), _bgSoundHandle(bgSoundHandle) { -} - -uint32 DXADecoderWithSound::getTime() const { - if (_mixer->isSoundHandleActive(*_bgSoundHandle)) - return _mixer->getSoundElapsedTime(*_bgSoundHandle); - - return DXADecoder::getTime(); -} - /////////////////////////////////////////////////////////////////////////////// // Factory function for creating the appropriate cutscene player /////////////////////////////////////////////////////////////////////////////// -MoviePlayer *makeMoviePlayer(const char *name, Sword2Engine *vm, Audio::Mixer *snd, OSystem *system, uint32 frameCount) { +MoviePlayer *makeMoviePlayer(const char *name, Sword2Engine *vm, OSystem *system, uint32 frameCount) { Common::String filename; - Audio::SoundHandle *bgSoundHandle = new Audio::SoundHandle; filename = Common::String::format("%s.str", name); if (Common::File::exists(filename)) { #ifdef USE_RGB_COLOR Video::VideoDecoder *psxDecoder = new Video::PSXStreamDecoder(Video::PSXStreamDecoder::kCD2x, frameCount); - return new MoviePlayer(vm, snd, system, bgSoundHandle, psxDecoder, kVideoDecoderPSX); + return new MoviePlayer(vm, system, psxDecoder, kVideoDecoderPSX); #else GUI::MessageDialog dialog(_("PSX cutscenes found but ScummVM has been built without RGB color support"), _("OK")); dialog.runModal(); @@ -450,15 +424,15 @@ MoviePlayer *makeMoviePlayer(const char *name, Sword2Engine *vm, Audio::Mixer *s if (Common::File::exists(filename)) { Video::SmackerDecoder *smkDecoder = new Video::SmackerDecoder(); - return new MoviePlayer(vm, snd, system, bgSoundHandle, smkDecoder, kVideoDecoderSMK); + return new MoviePlayer(vm, system, smkDecoder, kVideoDecoderSMK); } filename = Common::String::format("%s.dxa", name); if (Common::File::exists(filename)) { #ifdef USE_ZLIB - DXADecoderWithSound *dxaDecoder = new DXADecoderWithSound(snd, bgSoundHandle); - return new MoviePlayer(vm, snd, system, bgSoundHandle, dxaDecoder, kVideoDecoderDXA); + Video::DXADecoder *dxaDecoder = new Video::DXADecoder(); + return new MoviePlayer(vm, system, dxaDecoder, kVideoDecoderDXA); #else GUI::MessageDialog dialog(_("DXA cutscenes found but ScummVM has been built without zlib support"), _("OK")); dialog.runModal(); diff --git a/engines/sword2/animation.h b/engines/sword2/animation.h index 3d5c42b7f7..b2a243b2ca 100644 --- a/engines/sword2/animation.h +++ b/engines/sword2/animation.h @@ -25,12 +25,16 @@ #ifndef SWORD2_ANIMATION_H #define SWORD2_ANIMATION_H -#include "video/dxa_decoder.h" -#include "video/video_decoder.h" -#include "audio/mixer.h" - #include "sword2/screen.h" +namespace Graphics { +struct Surface; +} + +namespace Video { +class VideoDecoder; +} + namespace Sword2 { enum DecoderType { @@ -55,20 +59,9 @@ struct MovieText { } }; -class DXADecoderWithSound : public Video::DXADecoder { -public: - DXADecoderWithSound(Audio::Mixer *mixer, Audio::SoundHandle *bgSoundHandle); - ~DXADecoderWithSound() {} - - uint32 getTime() const; -private: - Audio::Mixer *_mixer; - Audio::SoundHandle *_bgSoundHandle; -}; - class MoviePlayer { public: - MoviePlayer(Sword2Engine *vm, Audio::Mixer *snd, OSystem *system, Audio::SoundHandle *bgSoundHandle, Video::VideoDecoder *decoder, DecoderType decoderType); + MoviePlayer(Sword2Engine *vm, OSystem *system, Video::VideoDecoder *decoder, DecoderType decoderType); virtual ~MoviePlayer(); bool load(const char *name); @@ -76,7 +69,6 @@ public: protected: Sword2Engine *_vm; - Audio::Mixer *_snd; OSystem *_system; MovieText *_movieTexts; uint32 _numMovieTexts; @@ -87,8 +79,6 @@ protected: DecoderType _decoderType; Video::VideoDecoder *_decoder; - Audio::SoundHandle *_bgSoundHandle; - Audio::AudioStream *_bgSoundStream; uint32 _leadOut; int _leadOutFrame; @@ -105,7 +95,7 @@ protected: uint32 getWhiteColor(); }; -MoviePlayer *makeMoviePlayer(const char *name, Sword2Engine *vm, Audio::Mixer *snd, OSystem *system, uint32 frameCount); +MoviePlayer *makeMoviePlayer(const char *name, Sword2Engine *vm, OSystem *system, uint32 frameCount); } // End of namespace Sword2 diff --git a/engines/sword2/function.cpp b/engines/sword2/function.cpp index 836b252d6c..07fcaa094b 100644 --- a/engines/sword2/function.cpp +++ b/engines/sword2/function.cpp @@ -2139,7 +2139,7 @@ int32 Logic::fnPlaySequence(int32 *params) { uint32 frameCount = Sword2Engine::isPsx() ? params[1] : 0; - _moviePlayer = makeMoviePlayer(filename, _vm, _vm->_mixer, _vm->_system, frameCount); + _moviePlayer = makeMoviePlayer(filename, _vm, _vm->_system, frameCount); if (_moviePlayer && _moviePlayer->load(filename)) { _moviePlayer->play(_sequenceTextList, _sequenceTextLines, _smackerLeadIn, _smackerLeadOut); diff --git a/video/dxa_decoder.cpp b/video/dxa_decoder.cpp index 7d1112a59c..5ac9bd2088 100644 --- a/video/dxa_decoder.cpp +++ b/video/dxa_decoder.cpp @@ -37,41 +37,43 @@ namespace Video { DXADecoder::DXADecoder() { - _fileStream = 0; - _surface = 0; - _dirtyPalette = false; +} - _frameBuffer1 = 0; - _frameBuffer2 = 0; - _scaledBuffer = 0; +DXADecoder::~DXADecoder() { + close(); +} - _inBuffer = 0; - _inBufferSize = 0; +bool DXADecoder::loadStream(Common::SeekableReadStream *stream) { + close(); - _decompBuffer = 0; - _decompBufferSize = 0; + uint32 tag = stream->readUint32BE(); - _width = 0; - _height = 0; + if (tag != MKTAG('D','E','X','A')) { + close(); + return false; + } - _frameSize = 0; - _frameCount = 0; - _frameRate = 0; + DXAVideoTrack *track = new DXAVideoTrack(stream); + addTrack(track); - _scaleMode = S_NONE; -} + readSoundData(stream); -DXADecoder::~DXADecoder() { - close(); + track->setFrameStartPos(); + return true; } -bool DXADecoder::loadStream(Common::SeekableReadStream *stream) { - close(); +void DXADecoder::readSoundData(Common::SeekableReadStream *stream) { + // Skip over the tag by default + stream->readUint32BE(); +} +DXADecoder::DXAVideoTrack::DXAVideoTrack(Common::SeekableReadStream *stream) { _fileStream = stream; - - uint32 tag = _fileStream->readUint32BE(); - assert(tag == MKTAG('D','E','X','A')); + _curFrame = -1; + _frameStartOffset = 0; + _decompBuffer = 0; + _inBuffer = 0; + memset(_palette, 0, 256 * 3); uint8 flags = _fileStream->readByte(); _frameCount = _fileStream->readUint16BE(); @@ -105,18 +107,14 @@ bool DXADecoder::loadStream(Common::SeekableReadStream *stream) { _frameSize = _width * _height; _decompBufferSize = _frameSize; - _frameBuffer1 = (uint8 *)malloc(_frameSize); + _frameBuffer1 = new byte[_frameSize]; memset(_frameBuffer1, 0, _frameSize); - _frameBuffer2 = (uint8 *)malloc(_frameSize); + _frameBuffer2 = new byte[_frameSize]; memset(_frameBuffer2, 0, _frameSize); - if (!_frameBuffer1 || !_frameBuffer2) - error("DXADecoder: Error allocating frame buffers (size %u)", _frameSize); _scaledBuffer = 0; if (_scaleMode != S_NONE) { - _scaledBuffer = (uint8 *)malloc(_frameSize); - if (!_scaledBuffer) - error("Error allocating scale buffer (size %u)", _frameSize); + _scaledBuffer = new byte[_frameSize]; memset(_scaledBuffer, 0, _frameSize); } @@ -148,36 +146,33 @@ bool DXADecoder::loadStream(Common::SeekableReadStream *stream) { } while (tag != 0); } #endif - - // Read the sound header - _soundTag = _fileStream->readUint32BE(); - - return true; } -void DXADecoder::close() { - if (!_fileStream) - return; - +DXADecoder::DXAVideoTrack::~DXAVideoTrack() { delete _fileStream; - _fileStream = 0; - delete _surface; - _surface = 0; + delete[] _frameBuffer1; + delete[] _frameBuffer2; + delete[] _scaledBuffer; + delete[] _inBuffer; + delete[] _decompBuffer; +} - free(_frameBuffer1); - free(_frameBuffer2); - free(_scaledBuffer); - free(_inBuffer); - free(_decompBuffer); +bool DXADecoder::DXAVideoTrack::rewind() { + _curFrame = -1; + _fileStream->seek(_frameStartOffset); + return true; +} - _inBuffer = 0; - _decompBuffer = 0; +Graphics::PixelFormat DXADecoder::DXAVideoTrack::getPixelFormat() const { + return _surface->format; +} - reset(); +void DXADecoder::DXAVideoTrack::setFrameStartPos() { + _frameStartOffset = _fileStream->pos(); } -void DXADecoder::decodeZlib(byte *data, int size, int totalSize) { +void DXADecoder::DXAVideoTrack::decodeZlib(byte *data, int size, int totalSize) { #ifdef USE_ZLIB unsigned long dstLen = totalSize; Common::uncompress(data, &dstLen, _inBuffer, size); @@ -187,14 +182,13 @@ void DXADecoder::decodeZlib(byte *data, int size, int totalSize) { #define BLOCKW 4 #define BLOCKH 4 -void DXADecoder::decode12(int size) { +void DXADecoder::DXAVideoTrack::decode12(int size) { #ifdef USE_ZLIB - if (_decompBuffer == NULL) { - _decompBuffer = (byte *)malloc(_decompBufferSize); + if (!_decompBuffer) { + _decompBuffer = new byte[_decompBufferSize]; memset(_decompBuffer, 0, _decompBufferSize); - if (_decompBuffer == NULL) - error("Error allocating decomp buffer (size %u)", _decompBufferSize); } + /* decompress the input data */ decodeZlib(_decompBuffer, size, _decompBufferSize); @@ -287,15 +281,13 @@ void DXADecoder::decode12(int size) { #endif } -void DXADecoder::decode13(int size) { +void DXADecoder::DXAVideoTrack::decode13(int size) { #ifdef USE_ZLIB uint8 *codeBuf, *dataBuf, *motBuf, *maskBuf; - if (_decompBuffer == NULL) { - _decompBuffer = (byte *)malloc(_decompBufferSize); + if (!_decompBuffer) { + _decompBuffer = new byte[_decompBufferSize]; memset(_decompBuffer, 0, _decompBufferSize); - if (_decompBuffer == NULL) - error("Error allocating decomp buffer (size %u)", _decompBufferSize); } /* decompress the input data */ @@ -475,7 +467,7 @@ void DXADecoder::decode13(int size) { #endif } -const Graphics::Surface *DXADecoder::decodeNextFrame() { +const Graphics::Surface *DXADecoder::DXAVideoTrack::decodeNextFrame() { uint32 tag = _fileStream->readUint32BE(); if (tag == MKTAG('C','M','A','P')) { _fileStream->read(_palette, 256 * 3); @@ -486,11 +478,10 @@ const Graphics::Surface *DXADecoder::decodeNextFrame() { if (tag == MKTAG('F','R','A','M')) { byte type = _fileStream->readByte(); uint32 size = _fileStream->readUint32BE(); - if ((_inBuffer == NULL) || (_inBufferSize < size)) { - free(_inBuffer); - _inBuffer = (byte *)malloc(size); - if (_inBuffer == NULL) - error("Error allocating input buffer (size %u)", size); + + if (!_inBuffer || _inBufferSize < size) { + delete[] _inBuffer; + _inBuffer = new byte[size]; memset(_inBuffer, 0, size); _inBufferSize = size; } @@ -551,9 +542,6 @@ const Graphics::Surface *DXADecoder::decodeNextFrame() { _curFrame++; - if (_curFrame == 0) - _startTime = g_system->getMillis(); - return _surface; } diff --git a/video/dxa_decoder.h b/video/dxa_decoder.h index d13cd3076c..a0caca4b95 100644 --- a/video/dxa_decoder.h +++ b/video/dxa_decoder.h @@ -41,62 +41,74 @@ namespace Video { * - sword1 * - sword2 */ -class DXADecoder : public FixedRateVideoDecoder { +class DXADecoder : public AdvancedVideoDecoder { public: DXADecoder(); virtual ~DXADecoder(); bool loadStream(Common::SeekableReadStream *stream); - void close(); - - bool isVideoLoaded() const { return _fileStream != 0; } - uint16 getWidth() const { return _width; } - uint16 getHeight() const { return _height; } - uint32 getFrameCount() const { return _frameCount; } - const Graphics::Surface *decodeNextFrame(); - Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat::createFormatCLUT8(); } - const byte *getPalette() { _dirtyPalette = false; return _palette; } - bool hasDirtyPalette() const { return _dirtyPalette; } +protected: /** - * Get the sound chunk tag of the loaded DXA file + * Read the sound data out of the given DXA stream */ - uint32 getSoundTag() { return _soundTag; } - -protected: - Common::Rational getFrameRate() const { return _frameRate; } - - Common::SeekableReadStream *_fileStream; + virtual void readSoundData(Common::SeekableReadStream *stream); private: - void decodeZlib(byte *data, int size, int totalSize); - void decode12(int size); - void decode13(int size); - - enum ScaleMode { - S_NONE, - S_INTERLACED, - S_DOUBLE + class DXAVideoTrack : public FixedRateVideoTrack { + public: + DXAVideoTrack(Common::SeekableReadStream *stream); + ~DXAVideoTrack(); + + bool isRewindable() const { return true; } + bool rewind(); + + uint16 getWidth() const { return _width; } + uint16 getHeight() const { return _height; } + Graphics::PixelFormat getPixelFormat() const; + int getCurFrame() const { return _curFrame; } + int getFrameCount() const { return _frameCount; } + const Graphics::Surface *decodeNextFrame(); + const byte *getPalette() const { _dirtyPalette = false; return _palette; } + bool hasDirtyPalette() const { return _dirtyPalette; } + + void setFrameStartPos(); + + protected: + Common::Rational getFrameRate() const { return _frameRate; } + + private: + void decodeZlib(byte *data, int size, int totalSize); + void decode12(int size); + void decode13(int size); + + enum ScaleMode { + S_NONE, + S_INTERLACED, + S_DOUBLE + }; + + Common::SeekableReadStream *_fileStream; + Graphics::Surface *_surface; + + byte *_frameBuffer1; + byte *_frameBuffer2; + byte *_scaledBuffer; + byte *_inBuffer; + uint32 _inBufferSize; + byte *_decompBuffer; + uint32 _decompBufferSize; + uint16 _curHeight; + uint32 _frameSize; + ScaleMode _scaleMode; + uint16 _width, _height; + uint32 _frameRate; + uint32 _frameCount; + byte _palette[256 * 3]; + mutable bool _dirtyPalette; + int _curFrame; + uint32 _frameStartOffset; }; - - Graphics::Surface *_surface; - byte _palette[256 * 3]; - bool _dirtyPalette; - - byte *_frameBuffer1; - byte *_frameBuffer2; - byte *_scaledBuffer; - byte *_inBuffer; - uint32 _inBufferSize; - byte *_decompBuffer; - uint32 _decompBufferSize; - uint16 _curHeight; - uint32 _frameSize; - ScaleMode _scaleMode; - uint32 _soundTag; - uint16 _width, _height; - uint32 _frameRate; - uint32 _frameCount; }; } // End of namespace Video |