Ticket #9141: vid_dec_engines.diff

File vid_dec_engines.diff, 51.6 KB (added by SF/mthreepwood, 16 years ago)

Patch (engines directory) against r49069

  • engines/mohawk/video/cinepak.h

     
    6565        ~CinepakDecoder();
    6666
    6767        Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
     68        Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; }
    6869
    6970private:
    7071        CinepakFrame _curFrame;
  • engines/mohawk/video/rpza.h

     
    3737        ~RPZADecoder() { delete _surface; }
    3838
    3939        Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
     40        Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; }
    4041
    4142private:
    4243        Graphics::Surface *_surface;
  • engines/mohawk/video/smc.h

     
    4343        ~SMCDecoder() { delete _surface; }
    4444
    4545        Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
     46        Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat::createFormatCLUT8(); }
    4647
    4748private:
    4849        Graphics::Surface *_surface;
  • engines/mohawk/video/qtrle.h

     
    3737        ~QTRLEDecoder();
    3838
    3939        Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
     40        Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; }
    4041
    4142private:
    4243        byte _bitsPerPixel;
  • engines/mohawk/jpeg.h

     
    4545        ~JPEGDecoder();
    4646
    4747        Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
     48        Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; }
    4849
    4950private:
    5051        Graphics::PixelFormat _pixelFormat;
  • engines/tucker/sequences.cpp

     
    537537                        }
    538538                        // budttle2.flc is shorter in french version ; start the background music
    539539                        // earlier and skip any sounds effects
    540                         if (_seqNum == 19 && _flicPlayer[0].getFrameCount() == 126) {
     540                        if (_seqNum == 19 && _flicPlayer[0].getFrameCount() == 127) {
    541541                                _soundSeqDataIndex = 6;
    542                                 _frameCounter = 80;
     542                                _frameCounter = 79;
    543543                        }
    544544                }
    545545                (this->*(_updateFunc[_updateFuncIndex].play))();
     
    766766}
    767767
    768768bool AnimationSequencePlayer::decodeNextAnimationFrame(int index) {
    769         bool framesLeft = _flicPlayer[index].decodeNextFrame();
     769        ::Graphics::Surface *surface = _flicPlayer[index].decodeNextFrame();
     770
    770771        if (_seqNum == 19) {
    771                 _flicPlayer[index].copyFrameToBuffer(_offscreenBuffer, 0, 0, kScreenWidth);
     772                for (uint16 y = 0; (y < surface->h) && (y < kScreenHeight); y++)
     773                        memcpy(_offscreenBuffer + y * kScreenWidth, (byte *)surface->pixels + y * surface->pitch, surface->w);
    772774        } else {
    773775                _flicPlayer[index].copyDirtyRectsToBuffer(_offscreenBuffer, kScreenWidth);
    774776        }
     777
    775778        ++_frameCounter;
    776         if (index == 0) {
    777                 if (_flicPlayer[index].paletteChanged()) {
    778                         getRGBPalette(index);
    779                 }
    780         }
    781         return framesLeft;
     779
     780        if (index == 0 && _flicPlayer[index].hasDirtyPalette())
     781                getRGBPalette(index);
     782
     783        return !_flicPlayer[index].endOfVideo();
    782784}
    783785
    784786void AnimationSequencePlayer::loadIntroSeq17_18() {
     
    803805        // The intro credits animation. This uses 2 animations: the foreground one, which
    804806        // is the actual intro credits, and the background one, which is an animation of
    805807        // cogs, and is being replayed when an intro credit appears
    806         if (_flicPlayer[0].getCurFrame() >= 116) {
    807                 if (!_flicPlayer[1].decodeNextFrame()) {
     808        ::Graphics::Surface *surface = 0;
     809
     810        if (_flicPlayer[0].getCurFrame() >= 117) {
     811                surface = _flicPlayer[1].decodeNextFrame();
     812                if (_flicPlayer[1].endOfVideo())
    808813                        _flicPlayer[1].reset();
    809                 }
    810814        }
     815
    811816        bool framesLeft = decodeNextAnimationFrame(0);
    812         for (int i = 0; i < kScreenWidth * kScreenHeight; ++i) {
    813                 if (_offscreenBuffer[i] == 0) {
    814                         _offscreenBuffer[i] = _flicPlayer[1].getPixel(i);
    815                 }
    816         }
    817         if (!framesLeft) {
     817
     818        if (surface)
     819                for (int i = 0; i < kScreenWidth * kScreenHeight; ++i)
     820                        if (_offscreenBuffer[i] == 0)
     821                                _offscreenBuffer[i] = *((byte *)surface->pixels + i);
     822
     823        if (!framesLeft)
    818824                _changeToNextSequence = true;
    819         }
    820825}
    821826
    822827void AnimationSequencePlayer::displayLoadingScreen() {
     
    870875void AnimationSequencePlayer::playIntroSeq3_4() {
    871876        if (!_updateScreenPicture) {
    872877                bool framesLeft = decodeNextAnimationFrame(0);
    873                 if (_flicPlayer[0].getCurFrame() == 706) {
     878                if (_flicPlayer[0].getCurFrame() == 707) {
    874879                        initPicPart4();
    875880                }
    876881                if (!framesLeft) {
     
    909914}
    910915
    911916void AnimationSequencePlayer::drawPic1Part10() {
     917        ::Graphics::Surface *surface = _flicPlayer[0].decodeNextFrame();
     918        _flicPlayer[0].copyDirtyRectsToBuffer(_offscreenBuffer, kScreenWidth);
     919        ++_frameCounter;
     920
     921        if (_flicPlayer[0].hasDirtyPalette())
     922                getRGBPalette(0);
     923
    912924        int offset = 0;
    913925        for (int y = 0; y < kScreenHeight; ++y) {
    914926                for (int x = 0; x < kScreenWidth; ++x) {
    915                         byte color = _flicPlayer[0].getPixel(offset);
    916                         if (color == 0) {
     927                        byte color = *((byte *)surface->pixels + offset);
     928
     929                        if (color == 0)
    917930                                color = _picBufPtr[800 + y * 640 + _updateScreenWidth + x];
    918                         }
     931
    919932                        _offscreenBuffer[offset++] = color;
    920933                }
    921934        }
     
    930943}
    931944
    932945void AnimationSequencePlayer::playIntroSeq9_10() {
    933         bool framesLeft = decodeNextAnimationFrame(0);
    934         if (_flicPlayer[0].getCurFrame() >= 264 && _flicPlayer[0].getCurFrame() <= 295) {
     946        if (_flicPlayer[0].getCurFrame() >= 265 && _flicPlayer[0].getCurFrame() <= 296) {
    935947                drawPic1Part10();
    936948                _updateScreenWidth += 6;
    937         } else if (_flicPlayer[0].getCurFrame() == 984) {
     949        } else if (_flicPlayer[0].getCurFrame() == 985) {
     950                decodeNextAnimationFrame(0);
    938951                drawPic2Part10();
    939         } else if (_flicPlayer[0].getCurFrame() >= 988 && _flicPlayer[0].getCurFrame() <= 996) {
     952        } else if (_flicPlayer[0].getCurFrame() >= 989 && _flicPlayer[0].getCurFrame() <= 997) {
    940953                drawPic1Part10();
    941954                _updateScreenWidth -= 25;
    942955                if (_updateScreenWidth < 0) {
    943956                        _updateScreenWidth = 0;
    944957                }
    945958        }
    946         if (!framesLeft) {
     959
     960        if (_flicPlayer[0].endOfVideo())
    947961                _changeToNextSequence = true;
    948         }
    949962}
    950963
    951964void AnimationSequencePlayer::loadIntroSeq21_22() {
  • engines/saga/scene.h

     
    424424        int DinoStartProc();
    425425        int FTA2StartProc();
    426426        int FTA2EndProc(FTA2Endings whichEnding);
     427        void playMovie(const char *filename);
    427428
    428429        void IHNMLoadCutaways();
    429430        bool checkKey();
  • engines/saga/introproc_saga2.cpp

     
    4040int Scene::DinoStartProc() {
    4141        _vm->_gfx->showCursor(false);
    4242
    43         Graphics::SmackerDecoder *smkDecoder = new Graphics::SmackerDecoder(_vm->_mixer);
    44         Graphics::VideoPlayer *player = new Graphics::VideoPlayer(smkDecoder);
    45         if (smkDecoder->loadFile("testvid.smk"))
    46                 player->playVideo();        // Play introduction
    47         smkDecoder->closeFile();
    48         delete player;
    49         delete smkDecoder;
     43        playMovie("testvid.smk");
    5044
    5145        // HACK: Forcibly quit here
    5246        _vm->quitGame();
     
    5751int Scene::FTA2StartProc() {
    5852        _vm->_gfx->showCursor(false);
    5953
    60         Graphics::SmackerDecoder *smkDecoder = new Graphics::SmackerDecoder(_vm->_mixer);
    61         Graphics::VideoPlayer *player = new Graphics::VideoPlayer(smkDecoder);
    62         if (smkDecoder->loadFile("trimark.smk"))
    63                 player->playVideo();      // Show Ignite logo
    64         smkDecoder->closeFile();
    65         if (smkDecoder->loadFile("intro.smk"))
    66                 player->playVideo();        // Play introduction
    67         smkDecoder->closeFile();
    68         delete player;
    69         delete smkDecoder;
     54        playMovie("trimark.smk");
     55        playMovie("intro.smk");
    7056
    7157        // HACK: Forcibly quit here
    7258        _vm->quitGame();
     
    10086        _vm->_gfx->showCursor(false);
    10187
    10288        // Play ending
    103         Graphics::SmackerDecoder *smkDecoder = new Graphics::SmackerDecoder(_vm->_mixer);
    104         Graphics::VideoPlayer *player = new Graphics::VideoPlayer(smkDecoder);
    105         if (smkDecoder->loadFile(videoName)) {
    106                 player->playVideo();
    107                 smkDecoder->closeFile();
    108         }
    109         delete player;
    110         delete smkDecoder;
     89        playMovie(videoName);
    11190
    11291        return SUCCESS;
    11392}
    11493
     94void Scene::playMovie(const char *filename) {
     95        Graphics::SmackerDecoder *smkDecoder = new Graphics::SmackerDecoder(_vm->_mixer);
     96
     97        if (!smkDecoder->loadFile(filename))
     98                return;
     99
     100        uint16 x = (g_system->getWidth() - smkDecoder->getWidth()) / 2;
     101        uint16 y = (g_system->getHeight() - smkDecoder->getHeight()) / 2;
     102
     103        while (!_vm->shouldQuit() && !smkDecoder->endOfVideo()) {
     104                if (smkDecoder->needsUpdate()) {
     105                        Graphics::Surface *frame = smkDecoder->decodeNextFrame();
     106                        if (frame) {
     107                                _vm->_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
     108
     109                                if (smkDecoder->hasDirtyPalette())
     110                                        smkDecoder->setSystemPalette();
     111
     112                                _vm->_system->updateScreen();
     113                        }
     114                }
     115       
     116                Common::Event event;
     117                while (_vm->_system->getEventManager()->pollEvent(event))
     118                        ;
     119
     120                _vm->_system->delayMillis(10);
     121        }
     122}
     123
    115124} // End of namespace Saga
    116125
    117126#endif
  • engines/sci/console.cpp

     
    222222        if (!_videoFile.empty()) {
    223223                _engine->_gfxCursor->kernelHide();
    224224
     225                Graphics::VideoDecoder *videoDecoder = 0;
     226
    225227                if (_videoFile.hasSuffix(".seq")) {
    226                         SeqDecoder *seqDecoder = new SeqDecoder();
    227                         Graphics::VideoPlayer *player = new Graphics::VideoPlayer(seqDecoder);
    228                         if (seqDecoder->loadFile(_videoFile.c_str(), _videoFrameDelay))
    229                                 player->playVideo();
    230                         else
    231                                 DebugPrintf("Failed to open movie file %s\n", _videoFile.c_str());
    232                         seqDecoder->closeFile();
    233                         delete player;
    234                         delete seqDecoder;
    235                 } else if (_videoFile.hasSuffix(".avi")) {
    236                         Graphics::AviDecoder *aviDecoder = new Graphics::AviDecoder(g_system->getMixer());
    237                         Graphics::VideoPlayer *player = new Graphics::VideoPlayer(aviDecoder);
    238                         if (aviDecoder->loadFile(_videoFile.c_str()))
    239                                 player->playVideo();
    240                         else
    241                                 DebugPrintf("Failed to open movie file %s\n", _videoFile.c_str());
    242                         aviDecoder->closeFile();
    243                         delete player;
    244                         delete aviDecoder;
     228                        videoDecoder = new SeqDecoder();
     229                        ((SeqDecoder *)videoDecoder)->setFrameDelay(_videoFrameDelay);
     230#ifdef ENABLE_SCI32
    245231                } else if (_videoFile.hasSuffix(".vmd")) {
    246 #ifdef ENABLE_SCI32
    247                         VMDDecoder *vmdDecoder = new VMDDecoder(g_system->getMixer());
    248                         Graphics::VideoPlayer *player = new Graphics::VideoPlayer(vmdDecoder);
    249                         if (vmdDecoder->loadFile(_videoFile.c_str()))
    250                                 player->playVideo();
    251                         else
    252                                 DebugPrintf("Failed to open movie file %s\n", _videoFile.c_str());
    253                         vmdDecoder->closeFile();
    254                         delete player;
    255                         delete vmdDecoder;
     232                        videoDecoder = new VMDDecoder(g_system->getMixer());
    256233#endif
     234                } else if (_videoFile.hasSuffix(".avi")) {
     235                        videoDecoder = new Graphics::AviDecoder(g_system->getMixer());
    257236                }
    258237
     238                if (videoDecoder && videoDecoder->loadFile(_videoFile)) {
     239                        uint16 x = (g_system->getWidth() - videoDecoder->getWidth()) / 2;
     240                        uint16 y = (g_system->getHeight() - videoDecoder->getHeight()) / 2;
     241
     242                        while (!g_engine->shouldQuit() && !videoDecoder->endOfVideo()) {                       
     243                                if (videoDecoder->needsUpdate()) {
     244                                        Graphics::Surface *frame = videoDecoder->decodeNextFrame();
     245                                        if (frame) {
     246                                                g_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
     247
     248                                                if (videoDecoder->hasDirtyPalette())
     249                                                        videoDecoder->setSystemPalette();
     250
     251                                                g_system->updateScreen();
     252                                        }
     253                                }
     254
     255                                Common::Event event;
     256                                while (g_system->getEventManager()->pollEvent(event))
     257                                        ;
     258
     259                                g_system->delayMillis(10);
     260                        }
     261               
     262                        delete videoDecoder;
     263                } else
     264                        warning("Could not play video %s\n", _videoFile.c_str());
     265
    259266                _engine->_gfxCursor->kernelShow();
    260 
    261267                _videoFile.clear();
    262268                _videoFrameDelay = 0;
    263269        }
  • engines/sci/engine/kgraphics.cpp

     
    10751075}
    10761076
    10771077reg_t kShowMovie(EngineState *s, int argc, reg_t *argv) {
    1078         bool playedVideo = false;
    1079 
    10801078        // Hide the cursor if it's showing and then show it again if it was
    10811079        // previously visible.
    10821080        bool reshowCursor;
     
    10841082        reshowCursor = g_sci->_gfxCursor->isVisible();
    10851083        if (reshowCursor)
    10861084                g_sci->_gfxCursor->kernelHide();
     1085               
     1086        Graphics::VideoDecoder *videoDecoder = 0;
    10871087
    10881088        if (argv[0].segment != 0) {
    10891089                // DOS SEQ
    10901090                // SEQ's are called with no subops, just the string and delay
    10911091                Common::String filename = s->_segMan->getString(argv[0]);
    1092                 int delay = argv[1].toUint16(); // Time between frames in ticks
    10931092
    10941093                SeqDecoder *seqDecoder = new SeqDecoder();
    1095                 Graphics::VideoPlayer *player = new Graphics::VideoPlayer(seqDecoder);
    1096                 if (seqDecoder->loadFile(filename.c_str(), delay)) {
    1097                         player->playVideo();
    1098                         playedVideo = true;
    1099                 } else {
     1094                seqDecoder->setFrameDelay(argv[1].toUint16());
     1095                videoDecoder = seqDecoder;
     1096               
     1097                if (!videoDecoder->loadFile(filename)) {
    11001098                        warning("Failed to open movie file %s", filename.c_str());
     1099                        delete videoDecoder;
     1100                        videoDecoder = 0;
    11011101                }
    1102                 seqDecoder->closeFile();
    1103                 delete player;
    1104                 delete seqDecoder;
    11051102        } else {
    11061103                // Windows AVI (Macintosh QuickTime? Need to check KQ6 Macintosh)
    11071104                // TODO: This appears to be some sort of subop. case 0 contains the string
     
    11201117                switch (argv[0].toUint16()) {
    11211118                case 0: {
    11221119                        Common::String filename = s->_segMan->getString(argv[1]);
    1123                         Graphics::AviDecoder *aviDecoder = new Graphics::AviDecoder(g_system->getMixer());
    1124                         Graphics::VideoPlayer *player = new Graphics::VideoPlayer(aviDecoder);
    1125                         if (aviDecoder->loadFile(filename.c_str())) {
    1126                                 player->playVideo();
    1127                                 playedVideo = true;
    1128                         } else {
     1120                        videoDecoder = new Graphics::AviDecoder(g_system->getMixer());
     1121
     1122                        if (!videoDecoder->loadFile(filename.c_str())) {
    11291123                                warning("Failed to open movie file %s", filename.c_str());
     1124                                delete videoDecoder;
     1125                                videoDecoder = 0;
    11301126                        }
    1131                         aviDecoder->closeFile();
    1132                         delete player;
    1133                         delete aviDecoder;
    11341127                        break;
    11351128                }
    11361129                default:
     
    11381131                }
    11391132        }
    11401133
    1141         if (playedVideo)
     1134        if (videoDecoder) {
     1135                uint16 x = (g_system->getWidth() - videoDecoder->getWidth()) / 2;
     1136                uint16 y = (g_system->getHeight() - videoDecoder->getHeight()) / 2;
     1137
     1138                while (!g_engine->shouldQuit() && !videoDecoder->endOfVideo()) {                       
     1139                        if (videoDecoder->needsUpdate()) {
     1140                                Graphics::Surface *frame = videoDecoder->decodeNextFrame();
     1141                                if (frame) {
     1142                                        g_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
     1143
     1144                                        if (videoDecoder->hasDirtyPalette())
     1145                                                videoDecoder->setSystemPalette();
     1146
     1147                                        g_system->updateScreen();
     1148                                }
     1149                        }
     1150
     1151                        Common::Event event;
     1152                        while (g_system->getEventManager()->pollEvent(event))
     1153                                ;
     1154
     1155                        g_system->delayMillis(10);
     1156                }
     1157               
     1158                delete videoDecoder;
    11421159                g_sci->_gfxScreen->kernelSyncWithFramebuffer();
     1160        }
    11431161
    11441162        if (reshowCursor)
    11451163                g_sci->_gfxCursor->kernelShow();
  • engines/sci/video/vmd_decoder.h

     
    2929#define GRAPHICS_VIDEO_VMD_DECODER_H
    3030
    3131#include "graphics/video/coktelvideo/coktelvideo.h"
    32 #include "graphics/video/video_player.h"
     32#include "graphics/video/video_decoder.h"
    3333#include "sound/mixer.h"
    3434
    3535namespace Sci {
     
    4949 * - Shivers 2: Harvest of Souls
    5050 * - Torin's Passage
    5151 */
    52 class VMDDecoder : public Graphics::VideoDecoder {
     52class VMDDecoder : public Graphics::FixedRateVideoDecoder {
    5353public:
    5454        VMDDecoder(Audio::Mixer *mixer);
    5555        virtual ~VMDDecoder();
    5656
    5757        uint32 getFrameWaitTime();
    5858
    59         /**
    60          * Load a VMD encoded video file
    61          * @param filename      the filename to load
    62          */
    63         bool loadFile(const char *filename);
     59        bool load(Common::SeekableReadStream &stream);
     60        void close();
    6461
    65         /**
    66          * Close a VMD encoded video file
    67          */
    68         void closeFile();
     62        bool isVideoLoaded() const { return _fileStream != 0; }
     63        uint16 getWidth() const { return _surface->w; }
     64        uint16 getHeight() const { return _surface->h; }
     65        uint32 getFrameCount() const { return _vmdDecoder->getFramesCount(); }
     66        Graphics::Surface *decodeNextFrame();
     67        Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat::createFormatCLUT8(); }
     68        byte *getPalette() { _dirtyPalette = false; return _palette; }
     69        bool hasDirtyPalette() const { return _dirtyPalette; }
    6970
    70         bool decodeNextFrame();
     71protected:
     72        Common::Rational getFrameRate() const { return _vmdDecoder->getFrameRate(); }
    7173
    7274private:
    7375        Graphics::Vmd *_vmdDecoder;
    7476        Audio::Mixer *_mixer;
     77        Graphics::Surface *_surface;
     78        Common::SeekableReadStream *_fileStream;
    7579        byte _palette[256 * 3];
     80        bool _dirtyPalette;
    7681
    77         void getPalette();
     82        void loadPaletteFromVMD();
    7883};
    7984
    8085} // End of namespace Graphics
  • engines/sci/video/seq_decoder.h

     
    2626#ifndef SEQ_DECODER_H
    2727#define SEQ_DECODER_H
    2828
    29 #include "graphics/video/video_player.h"
     29#include "graphics/video/video_decoder.h"
    3030
    3131namespace Sci {
    3232
    3333/**
    3434 * Implementation of the Sierra SEQ decoder, used in KQ6 DOS floppy/CD and GK1 DOS
    3535 */
    36 class SeqDecoder : public Graphics::VideoDecoder {
     36class SeqDecoder : public Graphics::FixedRateVideoDecoder {
    3737public:
    38         SeqDecoder() {}
     38        SeqDecoder();
    3939        virtual ~SeqDecoder();
    4040
    41         /**
    42          * Load a SEQ encoded video file
    43          * @param filename      the filename to load
    44          */
    45         bool loadFile(const char *fileName) { return loadFile(fileName, 10); }
     41        bool load(Common::SeekableReadStream &stream);
     42        void close();
    4643
    47         /**
    48          * Load a SEQ encoded video file
    49          * @param filename      the filename to load
    50          * @param frameDelay the delay between frames, in ticks
    51          */
    52         bool loadFile(const char *fileName, int frameDelay);
     44        void setFrameDelay(int frameDelay) { _frameDelay = frameDelay; }
    5345
    54         /**
    55          * Close a SEQ encoded video file
    56          */
    57         void closeFile();
     46        bool isVideoLoaded() const { return _fileStream != 0; }
     47        uint16 getWidth() const { return 320; }
     48        uint16 getHeight() const { return 200; }
     49        uint32 getFrameCount() const { return _frameCount; }
     50        Graphics::Surface *decodeNextFrame();
     51        Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat::createFormatCLUT8(); }
     52        byte *getPalette() { _dirtyPalette = false; return _palette; }
     53        bool hasDirtyPalette() const { return _dirtyPalette; }
     54 
     55protected:
     56        Common::Rational getFrameRate() const { assert(_frameDelay); return Common::Rational(60, _frameDelay); }
    5857
    59         bool decodeNextFrame();
    60 
    6158private:
    6259        bool decodeFrame(byte *rleData, int rleSize, byte *litData, int litSize, byte *dest, int left, int width, int height, int colorKey);
     60
     61        uint16 _width, _height;
     62        uint16 _frameDelay;
     63        Common::SeekableReadStream *_fileStream;
     64        byte _palette[256 * 3];
     65        bool _dirtyPalette;
     66        uint32 _frameCount;
     67        Graphics::Surface *_surface;
    6368};
    6469
    6570} // End of namespace Sci
  • engines/sci/video/vmd_decoder.cpp

     
    2727
    2828#include "sci/video/vmd_decoder.h"
    2929
    30 #include "common/archive.h"
    3130#include "common/endian.h"
    3231#include "common/util.h"
    3332#include "common/stream.h"
     
    4241
    4342VMDDecoder::VMDDecoder(Audio::Mixer *mixer) : _mixer(mixer) {
    4443        _vmdDecoder = new Graphics::Vmd(new Graphics::PaletteLUT(5, Graphics::PaletteLUT::kPaletteYUV));
     44        _surface = 0;
     45        _dirtyPalette = false;
     46        _fileStream = 0;
    4547}
    4648
    4749VMDDecoder::~VMDDecoder() {
    48         closeFile();
     50        close();
    4951}
    5052
    51 uint32 VMDDecoder::getFrameWaitTime() {
    52         return _vmdDecoder->getFrameWaitTime();
    53 }
     53bool VMDDecoder::load(Common::SeekableReadStream &stream) {
     54        close();
    5455
    55 bool VMDDecoder::loadFile(const char *fileName) {
    56         closeFile();
    57 
    58         _fileStream = SearchMan.createReadStreamForMember(fileName);
    59         if (!_fileStream)
     56        if (!_vmdDecoder->load(stream))
    6057                return false;
    6158
    62         if (!_vmdDecoder->load(*_fileStream))
    63                 return false;
     59        _fileStream = &stream;
    6460
    65         if (_vmdDecoder->getFeatures() & Graphics::CoktelVideo::kFeaturesPalette) {
    66                 getPalette();
    67                 setPalette(_palette);
    68         }
     61        if (_vmdDecoder->getFeatures() & Graphics::CoktelVideo::kFeaturesPalette)
     62                loadPaletteFromVMD();
    6963
    7064        if (_vmdDecoder->getFeatures() & Graphics::CoktelVideo::kFeaturesSound)
    7165                _vmdDecoder->enableSound(*_mixer);
    7266
    73         _videoInfo.width = _vmdDecoder->getWidth();
    74         _videoInfo.height = _vmdDecoder->getHeight();
    75         _videoInfo.frameCount = _vmdDecoder->getFramesCount();
    76         _videoInfo.frameRate = _vmdDecoder->getFrameRate();
    77         _videoInfo.frameDelay = _videoInfo.frameRate * 100;
    78         _videoInfo.currentFrame = -1;
    79         _videoInfo.firstframeOffset = 0;        // not really necessary for VMDs
    80 
    8167        if (_vmdDecoder->hasExtraData())
    8268                warning("This VMD video has extra embedded data, which is currently not handled");
    8369
    84         _videoFrameBuffer = new byte[_videoInfo.width * _videoInfo.height];
    85         memset(_videoFrameBuffer, 0, _videoInfo.width * _videoInfo.height);
    86 
    87         _vmdDecoder->setVideoMemory(_videoFrameBuffer, _videoInfo.width, _videoInfo.height);
    88 
     70        _surface = new Graphics::Surface();
     71        _surface->create(_vmdDecoder->getWidth(), _vmdDecoder->getHeight(), 1);
     72        _vmdDecoder->setVideoMemory((byte *)_surface->pixels, _surface->w, _surface->h);
    8973        return true;
    9074}
    9175
    92 void VMDDecoder::closeFile() {
     76void VMDDecoder::close() {
    9377        if (!_fileStream)
    9478                return;
    9579
     
    9882        delete _fileStream;
    9983        _fileStream = 0;
    10084
    101         delete[] _videoFrameBuffer;
    102         _videoFrameBuffer = 0;
     85        _surface->free();
     86        delete _surface;
     87        _surface = 0;
     88
     89        reset();
    10390}
    10491
    105 bool VMDDecoder::decodeNextFrame() {
    106         _videoInfo.currentFrame++;
    107 
    108         if (_videoInfo.currentFrame == 0)
    109                 _videoInfo.startTime = g_system->getMillis();
    110 
     92Graphics::Surface *VMDDecoder::decodeNextFrame() {
    11193        Graphics::CoktelVideo::State state = _vmdDecoder->nextFrame();
    11294
    113         if (state.flags & Graphics::CoktelVideo::kStatePalette) {
    114                 getPalette();
    115                 setPalette(_palette);
    116         }
     95        if (state.flags & Graphics::CoktelVideo::kStatePalette)
     96                loadPaletteFromVMD();
    11797
    118         return !endOfVideo();
     98        if (_curFrame == -1)
     99                _startTime = g_system->getMillis();
     100
     101        _curFrame++;
     102        return _surface;
    119103}
    120104
    121 void VMDDecoder::getPalette() {
     105void VMDDecoder::loadPaletteFromVMD() {
    122106        const byte *pal = _vmdDecoder->getPalette();
    123107
    124108        for (int i = 0; i < 256; i++) {
     
    126110                _palette[i * 3 + 1] = pal[i * 3 + 1] << 2;
    127111                _palette[i * 3 + 2] = pal[i * 3 + 2] << 2;
    128112        }
     113
     114        _dirtyPalette = true;
    129115}
    130116
    131117} // End of namespace Graphics
  • engines/sci/video/seq_decoder.cpp

     
    3535
    3636namespace Sci {
    3737
    38 // SEQ videos always run at 320x200
    39 #define SCREEN_WIDTH 320
    40 #define SCREEN_HEIGHT 200
    41 
    4238enum seqPalTypes {
    4339        kSeqPalVariable = 0,
    4440        kSeqPalConstant = 1
     
    4945        kSeqFrameDiff = 1
    5046};
    5147
     48SeqDecoder::SeqDecoder() {
     49        _fileStream = 0;
     50        _surface = 0;
     51        _dirtyPalette = false;
     52}
     53
    5254SeqDecoder::~SeqDecoder() {
    53         closeFile();
     55        close();
    5456}
    5557
    56 bool SeqDecoder::loadFile(const char *fileName, int frameDelay) {
    57         closeFile();
     58bool SeqDecoder::load(Common::SeekableReadStream &stream) {
     59        close();
    5860
    59         _fileStream = SearchMan.createReadStreamForMember(fileName);
    60         if (!_fileStream)
    61                 return false;
     61        _fileStream = &stream;
     62        _surface = new Graphics::Surface();
     63        _surface->create(getWidth(), getHeight(), 1);
    6264
    63         // Seek to the first frame
    64         _videoInfo.currentFrame = -1;
     65        _frameCount = _fileStream->readUint16LE();
    6566
    66         _videoInfo.width = SCREEN_WIDTH;
    67         _videoInfo.height = SCREEN_HEIGHT;
    68         _videoInfo.frameCount = _fileStream->readUint16LE();
    69         // Our frameDelay is calculated in 1/100 ms, so we convert it here
    70         _videoInfo.frameDelay = 100 * frameDelay * 1000 / 60;
    71         _videoFrameBuffer = new byte[_videoInfo.width * _videoInfo.height];
    72 
    7367        // Set palette
    7468        int paletteSize = _fileStream->readUint32LE();
    7569
     
    8175        uint16 palColorStart = READ_LE_UINT16(paletteData + 25);
    8276        uint16 palColorCount = READ_LE_UINT16(paletteData + 29);
    8377
    84         byte palette[256 * 4];
    8578        int palOffset = 37;
    8679
    8780        for (uint16 colorNo = palColorStart; colorNo < palColorStart + palColorCount; colorNo++) {
    8881                if (palFormat == kSeqPalVariable)
    8982                        palOffset++;
    90                 palette[colorNo * 4 + 0] = paletteData[palOffset++];
    91                 palette[colorNo * 4 + 1] = paletteData[palOffset++];
    92                 palette[colorNo * 4 + 2] = paletteData[palOffset++];
    93                 palette[colorNo * 4 + 3] = 0;
     83                _palette[colorNo * 3 + 0] = paletteData[palOffset++];
     84                _palette[colorNo * 3 + 1] = paletteData[palOffset++];
     85                _palette[colorNo * 3 + 2] = paletteData[palOffset++];
    9486        }
    9587
    96         g_system->setPalette(palette, 0, 256);
    97 
     88        _dirtyPalette = true;
    9889        delete[] paletteData;
    99 
    100         _videoInfo.firstframeOffset = _fileStream->pos();
    101 
    10290        return true;
    10391}
    10492
    105 void SeqDecoder::closeFile() {
     93void SeqDecoder::close() {
    10694        if (!_fileStream)
    10795                return;
    10896
     97        _frameDelay = 0;
     98
    10999        delete _fileStream;
    110100        _fileStream = 0;
    111101
    112         delete[] _videoFrameBuffer;
    113         _videoFrameBuffer = 0;
     102        _surface->free();
     103        delete _surface;
     104        _surface = 0;
     105
     106        reset();
    114107}
    115108
    116 bool SeqDecoder::decodeNextFrame() {
     109Graphics::Surface *SeqDecoder::decodeNextFrame() {
    117110        int16 frameWidth = _fileStream->readUint16LE();
    118111        int16 frameHeight = _fileStream->readUint16LE();
    119112        int16 frameLeft = _fileStream->readUint16LE();
     
    129122
    130123        _fileStream->seek(offset);
    131124
    132         _videoInfo.currentFrame++;
    133 
    134         if (_videoInfo.currentFrame == 0)
    135                 _videoInfo.startTime = g_system->getMillis();
    136 
    137125        if (frameType == kSeqFrameFull) {
    138                 byte *dst = _videoFrameBuffer + frameTop * SCREEN_WIDTH + frameLeft;
     126                byte *dst = (byte *)_surface->pixels + frameTop * getWidth() + frameLeft;
    139127
    140128                byte *linebuf = new byte[frameWidth];
    141129
    142130                do {
    143131                        _fileStream->read(linebuf, frameWidth);
    144132                        memcpy(dst, linebuf, frameWidth);
    145                         dst += SCREEN_WIDTH;
     133                        dst += getWidth();
    146134                } while (--frameHeight);
    147135
    148136                delete[] linebuf;
    149137        } else {
    150138                byte *buf = new byte[frameSize];
    151139                _fileStream->read(buf, frameSize);
    152                 decodeFrame(buf, rleSize, buf + rleSize, frameSize - rleSize, _videoFrameBuffer + SCREEN_WIDTH * frameTop, frameLeft, frameWidth, frameHeight, colorKey);
     140                decodeFrame(buf, rleSize, buf + rleSize, frameSize - rleSize, (byte *)_surface->pixels + getWidth() * frameTop, frameLeft, frameWidth, frameHeight, colorKey);
    153141                delete[] buf;
    154142        }
    155143
    156         return !endOfVideo();
     144        if (_curFrame == -1)
     145                _startTime = g_system->getMillis();
     146
     147        _curFrame++;
     148        return _surface;
    157149}
    158150
    159151#define WRITE_TO_BUFFER(n) \
    160         if (writeRow * SCREEN_WIDTH + writeCol + (n) > SCREEN_WIDTH * height) { \
     152        if (writeRow * getWidth() + writeCol + (n) > getWidth() * height) { \
    161153                warning("SEQ player: writing out of bounds, aborting"); \
    162154                return false; \
    163155        } \
    164156        if (litPos + (n) > litSize) { \
    165157                warning("SEQ player: reading out of bounds, aborting"); \
    166158        } \
    167         memcpy(dest + writeRow * SCREEN_WIDTH + writeCol, litData + litPos, n);
     159        memcpy(dest + writeRow * getWidth() + writeCol, litData + litPos, n);
    168160
    169161bool SeqDecoder::decodeFrame(byte *rleData, int rleSize, byte *litData, int litSize, byte *dest, int left, int width, int height, int colorKey) {
    170162        int writeRow = 0;
  • engines/sword1/animation.h

     
    2828
    2929#include "graphics/video/dxa_decoder.h"
    3030#include "graphics/video/smk_decoder.h"
    31 #include "graphics/video/video_player.h"
     31#include "graphics/video/video_decoder.h"
    3232
    3333#include "common/array.h"
    3434
     
    6464        DXADecoderWithSound(Audio::Mixer *mixer, Audio::SoundHandle *bgSoundHandle);
    6565        ~DXADecoderWithSound() {}
    6666
    67         int32 getAudioLag();
     67        uint32 getElapsedTime() const;
     68
    6869private:
    6970        Audio::Mixer *_mixer;
    7071        Audio::SoundHandle *_bgSoundHandle;
    7172};
    7273
    73 class MoviePlayer : public Graphics::VideoPlayer {
     74class MoviePlayer {
    7475public:
    7576        MoviePlayer(SwordEngine *vm, Text *textMan, Audio::Mixer *snd, OSystem *system, Audio::SoundHandle *bgSoundHandle, Graphics::VideoDecoder *decoder, DecoderType decoderType);
    7677        virtual ~MoviePlayer();
    7778        bool load(uint32 id);
    7879        void play();
     80
    7981protected:
    8082        SwordEngine *_vm;
    8183        Text *_textMan;
     
    8587        int _textX, _textY, _textWidth, _textHeight;
    8688        DecoderType _decoderType;
    8789
     90        Graphics::VideoDecoder *_decoder;
    8891        Audio::SoundHandle *_bgSoundHandle;
    8992        Audio::AudioStream *_bgSoundStream;
    9093
     94        bool playVideo();
    9195        void performPostProcessing(byte *screen);
     96
     97        byte findBlackPalIndex();
     98        byte findWhitePalIndex();
    9299};
    93100
    94101MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, Audio::Mixer *snd, OSystem *system);
  • engines/sword1/animation.cpp

     
    6868///////////////////////////////////////////////////////////////////////////////
    6969
    7070MoviePlayer::MoviePlayer(SwordEngine *vm, Text *textMan, Audio::Mixer *snd, OSystem *system, Audio::SoundHandle *bgSoundHandle, Graphics::VideoDecoder *decoder, DecoderType decoderType)
    71         : _vm(vm), _textMan(textMan), _snd(snd), _bgSoundHandle(bgSoundHandle), _system(system), VideoPlayer(decoder) {
     71        : _vm(vm), _textMan(textMan), _snd(snd), _bgSoundHandle(bgSoundHandle), _system(system) {
    7272        _bgSoundStream = NULL;
    7373        _decoderType = decoderType;
     74        _decoder = decoder;
    7475}
    7576
    7677MoviePlayer::~MoviePlayer() {
     
    8687        Common::File f;
    8788        char filename[20];
    8889
    89         if (_decoderType == kVideoDecoderDXA) {
     90        if (_decoderType == kVideoDecoderDXA)
    9091                _bgSoundStream = Audio::SeekableAudioStream::openStreamFile(sequenceList[id]);
    91         } else {
     92        else
    9293                _bgSoundStream = NULL;
    93         }
    9494
    9595        if (SwordEngine::_systemVars.showText) {
    9696                sprintf(filename, "%s.txt", sequenceList[id]);
     
    146146}
    147147
    148148void MoviePlayer::play() {
    149         if (_bgSoundStream) {
     149        if (_bgSoundStream)
    150150                _snd->playStream(Audio::Mixer::kSFXSoundType, _bgSoundHandle, _bgSoundStream);
    151         }
     151
    152152        bool terminated = false;
    153153
    154154        _textX = 0;
     
    179179
    180180void MoviePlayer::performPostProcessing(byte *screen) {
    181181        if (!_movieTexts.empty()) {
    182                 if (_decoder->getCurFrame() + 1 == _movieTexts[0]->_startFrame) {
     182                if (_decoder->getCurFrame() == _movieTexts[0]->_startFrame) {
    183183                        _textMan->makeTextSprite(2, (uint8 *)_movieTexts[0]->_text, 600, LETTER_COL);
    184184
    185185                        FrameHeader *frame = _textMan->giveSpriteData(2);
     
    188188                        _textX = 320 - _textWidth / 2;
    189189                        _textY = 420 - _textHeight;
    190190                }
    191                 if (_decoder->getCurFrame() + 1 == _movieTexts[0]->_endFrame) {
     191                if (_decoder->getCurFrame() == _movieTexts[0]->_endFrame) {
    192192                        _textMan->releaseText(2, false);
    193193                        delete _movieTexts.remove_at(0);
    194194                }
     
    205205                        for (x = 0; x < _textWidth; x++) {
    206206                                switch (src[x]) {
    207207                                case BORDER_COL:
    208                                         dst[x] = _decoder->getBlack();
     208                                        dst[x] = findBlackPalIndex();
    209209                                        break;
    210210                                case LETTER_COL:
    211                                         dst[x] = _decoder->getWhite();
     211                                        dst[x] = findWhitePalIndex();
    212212                                        break;
    213213                                }
    214214                        }
     
    228228
    229229                for (y = 0; y < _textHeight; y++) {
    230230                        if (_textY + y < frameY || _textY + y >= frameY + frameHeight) {
    231                                 memset(dst + _textX, _decoder->getBlack(), _textWidth);
     231                                memset(dst + _textX, findBlackPalIndex(), _textWidth);
    232232                        } else {
    233233                                if (frameX > _textX)
    234                                         memset(dst + _textX, _decoder->getBlack(), frameX - _textX);
     234                                        memset(dst + _textX, findBlackPalIndex(), frameX - _textX);
    235235                                if (frameX + frameWidth < _textX + _textWidth)
    236                                         memset(dst + frameX + frameWidth, _decoder->getBlack(), _textX + _textWidth - (frameX + frameWidth));
     236                                        memset(dst + frameX + frameWidth, findBlackPalIndex(), _textX + _textWidth - (frameX + frameWidth));
    237237                        }
    238238
    239239                        dst += _system->getWidth();
     
    244244        }
    245245}
    246246
    247 DXADecoderWithSound::DXADecoderWithSound(Audio::Mixer *mixer, Audio::SoundHandle *bgSoundHandle)
    248         : _mixer(mixer), _bgSoundHandle(bgSoundHandle)  {
     247bool MoviePlayer::playVideo() {
     248        uint16 x = (g_system->getWidth() - _decoder->getWidth()) / 2;
     249        uint16 y = (g_system->getHeight() - _decoder->getHeight()) / 2;
     250
     251        while (!_vm->shouldQuit() && !_decoder->endOfVideo()) {
     252                if (_decoder->needsUpdate()) {
     253                        Graphics::Surface *frame = _decoder->decodeNextFrame();
     254                        if (frame)
     255                                _vm->_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
     256
     257                        if (_decoder->hasDirtyPalette())
     258                                _decoder->setSystemPalette();
     259
     260                        Graphics::Surface *screen = _vm->_system->lockScreen();
     261                        performPostProcessing((byte *)screen->pixels);
     262                        _vm->_system->unlockScreen();
     263                        _vm->_system->updateScreen();
     264                }
     265
     266                Common::Event event;
     267                while (_vm->_system->getEventManager()->pollEvent(event))
     268                        if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) || event.type == Common::EVENT_LBUTTONUP)
     269                                return false;
     270        }
     271
     272        return !_vm->shouldQuit();
    249273}
    250274
    251 int32 DXADecoderWithSound::getAudioLag() {
    252         if (!_fileStream)
    253                 return 0;
     275byte MoviePlayer::findBlackPalIndex() {
     276        return 0;
     277}
    254278
    255         if (!_mixer->isSoundHandleActive(*_bgSoundHandle))
    256                 return 0;
     279byte MoviePlayer::findWhitePalIndex() {
     280        return 0xff;
     281}
    257282
    258         int32 frameDelay = getFrameDelay();
    259         int32 videoTime = (_videoInfo.currentFrame + 1) * frameDelay;
    260         int32 audioTime;
     283DXADecoderWithSound::DXADecoderWithSound(Audio::Mixer *mixer, Audio::SoundHandle *bgSoundHandle)
     284        : _mixer(mixer), _bgSoundHandle(bgSoundHandle)  {
     285}
    261286
    262         const Audio::Timestamp ts = _mixer->getElapsedTime(*_bgSoundHandle);
    263         audioTime = ts.convertToFramerate(100000).totalNumberOfFrames();
     287uint32 DXADecoderWithSound::getElapsedTime() const {
     288        if (_mixer->isSoundHandleActive(*_bgSoundHandle))
     289                return _mixer->getSoundElapsedTime(*_bgSoundHandle);
    264290
    265         return videoTime - audioTime;
     291        return VideoDecoder::getElapsedTime();
    266292}
    267293
    268294///////////////////////////////////////////////////////////////////////////////
  • engines/sword2/animation.h

     
    3030
    3131#include "graphics/video/dxa_decoder.h"
    3232#include "graphics/video/smk_decoder.h"
    33 #include "graphics/video/video_player.h"
     33#include "graphics/video/video_decoder.h"
    3434#include "sound/mixer.h"
    3535
    3636#include "sword2/screen.h"
     
    6363        DXADecoderWithSound(Audio::Mixer *mixer, Audio::SoundHandle *bgSoundHandle);
    6464        ~DXADecoderWithSound() {}
    6565
    66         int32 getAudioLag();
     66        uint32 getElapsedTime() const;
    6767private:
    6868        Audio::Mixer *_mixer;
    6969        Audio::SoundHandle *_bgSoundHandle;
    7070};
    7171
    72 class MoviePlayer : public Graphics::VideoPlayer {
     72class MoviePlayer {
    7373public:
    7474        MoviePlayer(Sword2Engine *vm, Audio::Mixer *snd, OSystem *system, Audio::SoundHandle *bgSoundHandle, Graphics::VideoDecoder *decoder, DecoderType decoderType);
    7575        virtual ~MoviePlayer();
     
    8989        int _textX, _textY;
    9090        DecoderType _decoderType;
    9191
     92        Graphics::VideoDecoder *_decoder;
    9293        Audio::SoundHandle *_bgSoundHandle;
    9394        Audio::AudioStream *_bgSoundStream;
    9495
     
    9697        int _leadOutFrame;
    9798
    9899        void performPostProcessing(byte *screen);
     100        bool playVideo();
    99101
    100102        void openTextObject(uint32 index);
    101103        void closeTextObject(uint32 index, byte *screen);
    102104        void drawTextObject(uint32 index, byte *screen);
     105
     106        byte findBlackPalIndex();
     107        byte findWhitePalIndex();
    103108};
    104109
    105110MoviePlayer *makeMoviePlayer(const char *name, Sword2Engine *vm, Audio::Mixer *snd, OSystem *system);
  • engines/sword2/animation.cpp

     
    4747///////////////////////////////////////////////////////////////////////////////
    4848
    4949MoviePlayer::MoviePlayer(Sword2Engine *vm, Audio::Mixer *snd, OSystem *system, Audio::SoundHandle *bgSoundHandle, Graphics::VideoDecoder *decoder, DecoderType decoderType)
    50         : _vm(vm), _snd(snd), _bgSoundHandle(bgSoundHandle), _system(system), VideoPlayer(decoder) {
     50        : _vm(vm), _snd(snd), _bgSoundHandle(bgSoundHandle), _system(system) {
    5151        _bgSoundStream = NULL;
    5252        _decoderType = decoderType;
     53        _decoder = decoder;
    5354}
    5455
    5556MoviePlayer:: ~MoviePlayer() {
     
    6263 * @param id the id of the file
    6364 */
    6465bool MoviePlayer::load(const char *name) {
    65         if (_decoderType == kVideoDecoderDXA) {
     66        if (_decoderType == kVideoDecoderDXA)
    6667                _bgSoundStream = Audio::SeekableAudioStream::openStreamFile(name);
    67         } else {
     68        else
    6869                _bgSoundStream = NULL;
    69         }
    7070
    7171        _textSurface = NULL;
    7272
     
    9797        _currentMovieText = 0;
    9898        _leadOut = leadOut;
    9999
    100         if (leadIn) {
     100        if (leadIn)
    101101                _vm->_sound->playMovieSound(leadIn, kLeadInSound);
    102         }
    103102
    104         if (_bgSoundStream) {
     103        if (_bgSoundStream)
    105104                _snd->playStream(Audio::Mixer::kSFXSoundType, _bgSoundHandle, _bgSoundStream);
    106         }
    107105
    108106        bool terminated = false;
    109107
     
    186184
    187185                                for (int y = 0; y < text->_textSprite.h; y++) {
    188186                                        if (_textY + y < frameY || _textY + y >= frameY + frameHeight) {
    189                                                 memset(dst + _textX, _decoder->getBlack(), text->_textSprite.w);
     187                                                memset(dst + _textX, findBlackPalIndex(), text->_textSprite.w);
    190188                                        } else {
    191189                                                if (frameX > _textX)
    192                                                         memset(dst + _textX, _decoder->getBlack(), frameX - _textX);
     190                                                        memset(dst + _textX, findBlackPalIndex(), frameX - _textX);
    193191                                                if (frameX + frameWidth < _textX + text->_textSprite.w)
    194                                                         memset(dst + frameX + frameWidth, _decoder->getBlack(), _textX + text->_textSprite.w - (frameX + frameWidth));
     192                                                        memset(dst + frameX + frameWidth, findBlackPalIndex(), _textX + text->_textSprite.w - (frameX + frameWidth));
    195193                                        }
    196194
    197195                                        dst += _system->getWidth();
     
    207205void MoviePlayer::drawTextObject(uint32 index, byte *screen) {
    208206        MovieText *text = &_movieTexts[index];
    209207
    210         byte white = _decoder->getWhite();
    211         byte black = _decoder->getBlack();
     208        byte white = findWhitePalIndex();
     209        byte black = findBlackPalIndex();
    212210
    213211        if (text->_textMem && _textSurface) {
    214212                byte *src = text->_textSprite.data;
     
    240238
    241239void MoviePlayer::performPostProcessing(byte *screen) {
    242240        MovieText *text;
    243         int frame = _decoder->getCurFrame() + 1;
     241        int frame = _decoder->getCurFrame();
    244242
    245243        if (_currentMovieText < _numMovieTexts) {
    246244                text = &_movieTexts[_currentMovieText];
     
    272270        }
    273271}
    274272
    275 DXADecoderWithSound::DXADecoderWithSound(Audio::Mixer *mixer, Audio::SoundHandle *bgSoundHandle)
    276         : _mixer(mixer), _bgSoundHandle(bgSoundHandle)  {
     273bool MoviePlayer::playVideo() {
     274        uint16 x = (g_system->getWidth() - _decoder->getWidth()) / 2;
     275        uint16 y = (g_system->getHeight() - _decoder->getHeight()) / 2;
     276
     277        while (!_vm->shouldQuit() && !_decoder->endOfVideo()) {
     278                if (_decoder->needsUpdate()) {
     279                        Graphics::Surface *frame = _decoder->decodeNextFrame();
     280                        if (frame)
     281                                _vm->_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
     282
     283                        if (_decoder->hasDirtyPalette())
     284                                _decoder->setSystemPalette();
     285
     286                        Graphics::Surface *screen = _vm->_system->lockScreen();
     287                        performPostProcessing((byte *)screen->pixels);
     288                        _vm->_system->unlockScreen();
     289                        _vm->_system->updateScreen();
     290                }
     291
     292                Common::Event event;
     293                while (_vm->_system->getEventManager()->pollEvent(event))
     294                        if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) || event.type == Common::EVENT_LBUTTONUP)
     295                                return false;
     296        }
     297
     298        return !_vm->shouldQuit();
    277299}
    278300
    279 int32 DXADecoderWithSound::getAudioLag() {
    280         if (!_fileStream)
    281                 return 0;
     301byte MoviePlayer::findBlackPalIndex() {
     302        return 0;
     303}
    282304
    283         if (!_mixer->isSoundHandleActive(*_bgSoundHandle))
    284                 return 0;
     305byte MoviePlayer::findWhitePalIndex() {
     306        return 0xff;
     307}
    285308
    286         int32 frameDelay = getFrameDelay();
    287         int32 videoTime = _videoInfo.currentFrame * frameDelay;
    288         int32 audioTime;
     309DXADecoderWithSound::DXADecoderWithSound(Audio::Mixer *mixer, Audio::SoundHandle *bgSoundHandle)
     310        : _mixer(mixer), _bgSoundHandle(bgSoundHandle)  {
     311}
    289312
    290         const Audio::Timestamp ts = _mixer->getElapsedTime(*_bgSoundHandle);
    291         audioTime = ts.convertToFramerate(100000).totalNumberOfFrames();
     313uint32 DXADecoderWithSound::getElapsedTime() const {
     314        if (_mixer->isSoundHandleActive(*_bgSoundHandle))
     315                return _mixer->getSoundElapsedTime(*_bgSoundHandle);
    292316
    293         return videoTime - audioTime;
     317        return VideoDecoder::getElapsedTime();
    294318}
    295319
    296320///////////////////////////////////////////////////////////////////////////////
  • engines/scumm/he/animation_he.h

     
    5656
    5757        void copyFrameToBuffer(byte *dst, int dstType, uint x, uint y, uint pitch);
    5858        void handleNextFrame();
    59 
    60 protected:
    61         virtual void setPalette(byte *pal);
    6259};
    6360
    6461} // End of namespace Scumm
  • engines/scumm/he/script_v90he.cpp

     
    14371437                        }
    14381438                } else if (_videoParams.status == 165) {
    14391439                        // Stop video
    1440                         _moviePlay->closeFile();
     1440                        _moviePlay->close();
    14411441                }
    14421442                break;
    14431443        default:
  • engines/scumm/he/script_v100he.cpp

     
    22542254                        }
    22552255                } else if (_videoParams.status == 19) {
    22562256                        // Stop video
    2257                         _moviePlay->closeFile();
     2257                        _moviePlay->close();
    22582258                }
    22592259                break;
    22602260        default:
  • engines/scumm/he/animation_he.cpp

     
    4646}
    4747
    4848int MoviePlayer::load(const char *filename, int flags, int image) {
    49         if (isVideoLoaded()) {
    50                 closeFile();
    51         }
     49        if (isVideoLoaded())
     50                close();
    5251
    53         if (!loadFile(filename)) {
     52        if (!loadFile(Common::String(filename))) {
    5453                warning("Failed to load video file %s", filename);
    5554                return -1;
    5655        }
     56
    5757        debug(1, "Playing video %s", filename);
    5858
    59         if (flags & 2) {
     59        if (flags & 2)
    6060                _vm->_wiz->createWizEmptyImage(image, 0, 0, getWidth(), getHeight());
    61         }
    6261
    6362        _flags = flags;
    6463        _wizResNum = image;
    65 
    6664        return 0;
    6765}
    6866
     
    7068        uint h = getHeight();
    7169        uint w = getWidth();
    7270
    73         byte *src = _videoFrameBuffer;
     71        Graphics::Surface *surface = decodeNextFrame();
     72        byte *src = (byte *)surface->pixels;
    7473
     74        if (hasDirtyPalette())
     75                _vm->setPaletteFromPtr(getPalette(), 256);
     76
    7577        if (_vm->_game.features & GF_16BIT_COLOR) {
    7678                dst += y * pitch + x * 2;
    7779                do {
     
    102104}
    103105
    104106void MoviePlayer::handleNextFrame() {
    105         if (!isVideoLoaded()) {
     107        if (!isVideoLoaded())
    106108                return;
    107         }
    108109
    109110        VirtScreen *pvs = &_vm->_virtscr[kMainVirtScreen];
    110111
    111         decodeNextFrame();
    112 
    113112        if (_flags & 2) {
    114113                uint8 *dstPtr = _vm->getResourceAddress(rtImage, _wizResNum);
    115114                assert(dstPtr);
     
    129128        }
    130129
    131130        if (endOfVideo())
    132                 closeFile();
     131                close();
    133132}
    134133
    135 void MoviePlayer::setPalette(byte *pal) {
    136         _vm->setPaletteFromPtr(pal, 256);
    137 }
    138 
    139134} // End of namespace Scumm
    140135
    141136#endif // ENABLE_HE
  • engines/agos/animation.h

     
    7272        virtual void handleNextFrame();
    7373        virtual bool processFrame() = 0;
    7474        virtual void startSound() {}
     75
     76protected:
     77        uint32 _firstFrameOffset;
    7578};
    7679
    7780class MoviePlayerDXA : public MoviePlayer, ::Graphics::DXADecoder {
     
    8487        void playVideo();
    8588        void nextFrame();
    8689        virtual void stopVideo();
    87 protected:
    88         void setPalette(byte *pal);
    8990
    9091private:
    9192        void handleNextFrame();
    9293        bool processFrame();
    9394        void startSound();
     95        void copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch);
    9496};
    9597
    9698class MoviePlayerSMK : public MoviePlayer, ::Graphics::SmackerDecoder {
     
    101103        void playVideo();
    102104        void nextFrame();
    103105        virtual void stopVideo();
    104 protected:
    105         void setPalette(byte *pal);
     106
    106107private:
    107108        void handleNextFrame();
    108109        bool processFrame();
    109110        void startSound();
     111        void copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch);
    110112};
    111113
    112114MoviePlayer *makeMoviePlayer(AGOSEngine_Feeble *vm, const char *name);
  • engines/agos/animation.cpp

     
    241241}
    242242
    243243bool MoviePlayerDXA::load() {
    244         char videoName[20];
    245         uint i;
    246 
    247244        if ((_vm->getPlatform() == Common::kPlatformAmiga || _vm->getPlatform() == Common::kPlatformMacintosh) &&
    248245                _vm->_language != Common::EN_ANY) {
    249246                _sequenceNum = 0;
    250                 for (i = 0; i < 90; i++) {
     247                for (uint i = 0; i < 90; i++) {
    251248                        if (!scumm_stricmp(baseName, _sequenceList[i]))
    252249                                _sequenceNum = i;
    253250                }
    254251        }
    255252
    256         sprintf(videoName, "%s.dxa", baseName);
     253        Common::String videoName = Common::String::printf("%s.dxa", baseName);
    257254        if (!loadFile(videoName))
    258                 error("Failed to load video file %s", videoName);
     255                error("Failed to load video file %s", videoName.c_str());
    259256
    260         debug(0, "Playing video %s", videoName);
     257        debug(0, "Playing video %s", videoName.c_str());
    261258
    262259        CursorMan.showMouse(false);
    263260
     261        _firstFrameOffset = _fileStream->pos();
     262
    264263        return true;
    265264}
    266265
     266void MoviePlayerDXA::copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch) {
     267        uint h = getHeight();
     268        uint w = getWidth();
     269
     270        Graphics::Surface *surface = decodeNextFrame();
     271        byte *src = (byte *)surface->pixels;
     272        dst += y * pitch + x;
     273
     274        do {
     275                memcpy(dst, src, w);
     276                dst += pitch;
     277                src += w;
     278        } while (--h);
     279
     280        if (hasDirtyPalette())
     281                setSystemPalette();
     282}
     283
    267284void MoviePlayerDXA::playVideo() {
    268285        // Most of the videos included in the Amiga version, reduced the
    269286        // resoluton to 384 x 280, so require the screen to be cleared,
     
    277294}
    278295
    279296void MoviePlayerDXA::stopVideo() {
    280         closeFile();
     297        close();
    281298        _mixer->stopHandle(_bgSound);
    282299}
    283300
     
    318335}
    319336
    320337void MoviePlayerDXA::nextFrame() {
    321         if (_bgSoundStream && _vm->_mixer->isSoundHandleActive(_bgSound) && (_vm->_mixer->getSoundElapsedTime(_bgSound) * getFrameRate()) / 1000 <= (uint32)getCurFrame()) {
     338        if (_bgSoundStream && _vm->_mixer->isSoundHandleActive(_bgSound) && needsUpdate()) {
    322339                copyFrameToBuffer(_vm->getBackBuf(), 465, 222, _vm->_screenWidth);
    323340                return;
    324341        }
    325342
    326343        if (_vm->_interactiveVideo == TYPE_LOOPING && endOfVideo()) {
    327                 _fileStream->seek(_videoInfo.firstframeOffset);
    328                 _videoInfo.currentFrame = -1;
     344                _fileStream->seek(_firstFrameOffset);
     345                _curFrame = -1;
    329346                startSound();
    330347        }
    331348
    332349        if (!endOfVideo()) {
    333                 decodeNextFrame();
    334350                if (_vm->_interactiveVideo == TYPE_OMNITV) {
    335351                        copyFrameToBuffer(_vm->getBackBuf(), 465, 222, _vm->_screenWidth);
    336352                } else if (_vm->_interactiveVideo == TYPE_LOOPING) {
    337353                        copyFrameToBuffer(_vm->getBackBuf(), (_vm->_screenWidth - getWidth()) / 2, (_vm->_screenHeight - getHeight()) / 2, _vm->_screenWidth);
    338354                }
    339355        } else if (_vm->_interactiveVideo == TYPE_OMNITV) {
    340                 closeFile();
     356                close();
    341357                _vm->_interactiveVideo = 0;
    342358                _vm->_variableArray[254] = 6747;
    343359        }
    344360}
    345361
    346362void MoviePlayerDXA::handleNextFrame() {
    347         decodeNextFrame();
    348363        if (processFrame())
    349364                _vm->_system->updateScreen();
    350365
    351366        MoviePlayer::handleNextFrame();
    352367}
    353368
    354 void MoviePlayerDXA::setPalette(byte *pal) {
    355         byte palette[1024];
    356         byte *p = palette;
    357 
    358         for (int i = 0; i < 256; i++) {
    359                 *p++ = *pal++;
    360                 *p++ = *pal++;
    361                 *p++ = *pal++;
    362                 *p++ = 0;
    363         }
    364 
    365         _vm->_system->setPalette(palette, 0, 256);
    366 }
    367 
    368369bool MoviePlayerDXA::processFrame() {
    369370        Graphics::Surface *screen = _vm->_system->lockScreen();
    370371        copyFrameToBuffer((byte *)screen->pixels, (_vm->_screenWidth - getWidth()) / 2, (_vm->_screenHeight - getHeight()) / 2, _vm->_screenWidth);
    371372        _vm->_system->unlockScreen();
    372373
    373         if ((_bgSoundStream == NULL) || ((int)(_mixer->getSoundElapsedTime(_bgSound) * getFrameRate()) / 1000 <= getCurFrame())) {
     374        Common::Rational soundTime(_mixer->getSoundElapsedTime(_bgSound), 1000);
     375        if ((_bgSoundStream == NULL) || ((int)(soundTime * getFrameRate()) / 1000 < getCurFrame() + 1)) {
    374376
    375377                if (_bgSoundStream && _mixer->isSoundHandleActive(_bgSound)) {
    376                         while (_mixer->isSoundHandleActive(_bgSound) && (_mixer->getSoundElapsedTime(_bgSound) * getFrameRate()) / 1000 <= (uint32)getCurFrame()) {
     378                        while (_mixer->isSoundHandleActive(_bgSound) && ((int) (soundTime * getFrameRate())) < getCurFrame()) {
    377379                                _vm->_system->delayMillis(10);
     380                                soundTime = Common::Rational(_mixer->getSoundElapsedTime(_bgSound), 1000);
    378381                        }
    379382                        // In case the background sound ends prematurely, update
    380383                        // _ticks so that we can still fall back on the no-sound
    381384                        // sync case for the subsequent frames.
    382385                        _ticks = _vm->_system->getMillis();
    383386                } else {
    384                         _ticks += getFrameWaitTime();
     387                        _ticks += getTimeToNextFrame();
    385388                        while (_vm->_system->getMillis() < _ticks)
    386389                                _vm->_system->delayMillis(10);
    387390                }
     
    407410}
    408411
    409412bool MoviePlayerSMK::load() {
    410         char videoName[20];
     413        Common::String videoName = Common::String::printf("%s.smk", baseName);
    411414
    412         sprintf(videoName, "%s.smk", baseName);
    413415        if (!loadFile(videoName))
    414                 error("Failed to load video file %s", videoName);
     416                error("Failed to load video file %s", videoName.c_str());
    415417
    416         debug(0, "Playing video %s", videoName);
     418        debug(0, "Playing video %s", videoName.c_str());
    417419
    418420        CursorMan.showMouse(false);
    419421
     422        _firstFrameOffset = _fileStream->pos();
     423
    420424        return true;
    421425}
    422426
     427void MoviePlayerSMK::copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch) {
     428        uint h = getHeight();
     429        uint w = getWidth();
     430
     431        Graphics::Surface *surface = decodeNextFrame();
     432        byte *src = (byte *)surface->pixels;
     433        dst += y * pitch + x;
     434
     435        do {
     436                memcpy(dst, src, w);
     437                dst += pitch;
     438                src += w;
     439        } while (--h);
     440
     441        if (hasDirtyPalette())
     442                setSystemPalette();
     443}
     444
    423445void MoviePlayerSMK::playVideo() {
    424446        while (!endOfVideo() && !_skipMovie && !_vm->shouldQuit())
    425447                handleNextFrame();
    426448}
    427449
    428450void MoviePlayerSMK::stopVideo() {
    429         closeFile();
     451        close();
    430452}
    431453
    432454void MoviePlayerSMK::startSound() {
    433455}
    434456
    435457void MoviePlayerSMK::handleNextFrame() {
    436         decodeNextFrame();
    437458        processFrame();
    438459
    439460        MoviePlayer::handleNextFrame();
     
    441462
    442463void MoviePlayerSMK::nextFrame() {
    443464        if (_vm->_interactiveVideo == TYPE_LOOPING && endOfVideo()) {
    444                 _fileStream->seek(_videoInfo.firstframeOffset);
    445                 _videoInfo.currentFrame = -1;
     465                _fileStream->seek(_firstFrameOffset);
     466                _curFrame = -1;
    446467        }
    447468
    448469        if (!endOfVideo()) {
     
    453474                        copyFrameToBuffer(_vm->getBackBuf(), (_vm->_screenWidth - getWidth()) / 2, (_vm->_screenHeight - getHeight()) / 2, _vm->_screenWidth);
    454475                }
    455476        } else if (_vm->_interactiveVideo == TYPE_OMNITV) {
    456                 closeFile();
     477                close();
    457478                _vm->_interactiveVideo = 0;
    458479                _vm->_variableArray[254] = 6747;
    459480        }
    460481}
    461482
    462 void MoviePlayerSMK::setPalette(byte *pal) {
    463         byte palette[1024];
    464         byte *p = palette;
    465 
    466         for (int i = 0; i < 256; i++) {
    467                 *p++ = *pal++;
    468                 *p++ = *pal++;
    469                 *p++ = *pal++;
    470                 *p++ = 0;
    471         }
    472 
    473         _vm->_system->setPalette(palette, 0, 256);
    474 }
    475 
    476483bool MoviePlayerSMK::processFrame() {
    477484        Graphics::Surface *screen = _vm->_system->lockScreen();
    478485        copyFrameToBuffer((byte *)screen->pixels, (_vm->_screenWidth - getWidth()) / 2, (_vm->_screenHeight - getHeight()) / 2, _vm->_screenWidth);
    479486        _vm->_system->unlockScreen();
    480487
    481         uint32 waitTime = getFrameWaitTime();
     488        uint32 waitTime = getTimeToNextFrame();
    482489
    483490        if (!waitTime) {
    484491                warning("dropped frame %i", getCurFrame());