Ticket #8948: bs-patch.patch

File bs-patch.patch, 40.0 KB (added by bluegr, 16 years ago)

Improved patch by thebluegr/md5

  • engines/sword1/animation.cpp

     
    2727#include "common/file.h"
    2828#include "sword1/sword1.h"
    2929#include "sword1/animation.h"
    30 #include "sword1/credits.h"
    3130#include "sword1/text.h"
    3231#include "sound/vorbis.h"
    3332
     
    3635#include "common/str.h"
    3736#include "common/events.h"
    3837#include "common/system.h"
     38#include "common/list.h"
    3939#include "graphics/surface.h"
    4040
     41#include "gui/message.h"
     42
    4143namespace Sword1 {
    4244
    4345static const char *sequenceList[20] = {
     
    6769// Basic movie player
    6870///////////////////////////////////////////////////////////////////////////////
    6971
    70 MoviePlayer::MoviePlayer(SwordEngine *vm, Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system)
    71         : _vm(vm), _screen(screen), _textMan(textMan), _snd(snd), _system(system) {
     72MoviePlayer::MoviePlayer(SwordEngine *vm, Text *textMan, Audio::Mixer *snd, OSystem *system, Audio::SoundHandle *bgSoundHandle, Graphics::VideoDecoder *decoder, DecoderType decoderType)
     73        : _vm(vm), _textMan(textMan), _snd(snd), _bgSoundHandle(bgSoundHandle), _system(system), VideoPlayer(decoder) {
    7274        _bgSoundStream = NULL;
    73         _ticks = 0;
    74         _black = 1;
    75         _white = 255;
    76         _currentFrame = 0;
    77         _forceFrame = false;
    78         _framesSkipped = 0;
     75        _decoderType = decoderType;
    7976}
    8077
    8178MoviePlayer::~MoviePlayer(void) {
     79        delete(_decoder);
    8280}
    8381
    84 void MoviePlayer::updatePalette(byte *pal, bool packed) {
    85         byte palette[4 * 256];
    86         byte *p = palette;
    87 
    88         uint32 maxWeight = 0;
    89         uint32 minWeight = 0xFFFFFFFF;
    90 
    91         for (int i = 0; i < 256; i++) {
    92                 int r = *pal++;
    93                 int g = *pal++;
    94                 int b = *pal++;
    95 
    96                 if (!packed)
    97                         pal++;
    98 
    99                 uint32 weight = 3 * r * r + 6 * g * g + 2 * b * b;
    100 
    101                 if (weight >= maxWeight) {
    102                         _white = i;
    103                         maxWeight = weight;
    104                 }
    105 
    106                 if (weight <= minWeight) {
    107                         _black = i;
    108                         minWeight = i;
    109                 }
    110 
    111                 *p++ = r;
    112                 *p++ = g;
    113                 *p++ = b;
    114                 *p++ = 0;
    115         }
    116 
    117         _system->setPalette(palette, 0, 256);
    118         _forceFrame = true;
    119 }
    120 
    121 void MoviePlayer::handleScreenChanged(void) {
    122 }
    123 
    124 bool MoviePlayer::initOverlays(uint32 id) {
    125         return true;
    126 }
    127 
    128 bool MoviePlayer::checkSkipFrame(void) {
    129         if (_forceFrame) {
    130                 _forceFrame = false;
    131                 return false;
    132         }
    133         if (_framesSkipped > 10) {
    134                 warning("Forced frame %d to be displayed", _currentFrame);
    135                 _framesSkipped = 0;
    136                 return false;
    137         }
    138         if (_bgSoundStream) {
    139                 if ((_snd->getSoundElapsedTime(_bgSoundHandle) * 12) / 1000 < _currentFrame + 1)
    140                         return false;
    141         } else {
    142                 if (_system->getMillis() <= _ticks)
    143                         return false;
    144         }
    145         _framesSkipped++;
    146         return true;
    147 }
    148 
    149 bool MoviePlayer::syncFrame(void) {
    150         _ticks += 83;
    151         if (checkSkipFrame()) {
    152                 warning("Skipped frame %d", _currentFrame);
    153                 return false;
    154         }
    155         if (_bgSoundStream) {
    156                 while (_snd->isSoundHandleActive(_bgSoundHandle) && (_snd->getSoundElapsedTime(_bgSoundHandle) * 12) / 1000 < _currentFrame) {
    157                         _system->delayMillis(10);
    158                 }
    159 
    160                 // In case the background sound ends prematurely, update _ticks
    161                 // so that we can still fall back on the no-sound sync case for
    162                 // the subsequent frames.
    163 
    164                 _ticks = _system->getMillis();
    165         } else {
    166                 while (_system->getMillis() < _ticks) {
    167                         _system->delayMillis(10);
    168                 }
    169         }
    170         return true;
    171 }
    172 
    17382/**
    17483 * Plays an animated cutscene.
    17584 * @param id the id of the file
     
    17887        Common::File f;
    17988        char fileName[20];
    18089
    181         _id = id;
    182         _bgSoundStream = NULL;
     90        if (_decoderType == kVideoDecoderDXA) {
     91                _bgSoundStream = Audio::AudioStream::openStreamFile(sequenceList[id]);
     92        } else {
     93                _bgSoundStream = NULL;
     94        }
    18395
    18496        if (SwordEngine::_systemVars.showText) {
    18597                sprintf(fileName, "%s.txt", sequenceList[id]);
     
    221133                }
    222134        }
    223135
    224         if (SwordEngine::_systemVars.cutscenePackVersion == 1) {
    225                 if ((id == SEQ_INTRO) || (id == SEQ_FINALE) || (id == SEQ_HISTORY) || (id == SEQ_FERRARI)) {
    226 #ifdef USE_VORBIS
    227                         // these sequences are language specific
    228                         sprintf(fileName, "%s.snd", sequenceList[id]);
    229                         Common::File *oggSource = new Common::File();
    230                         if (oggSource->open(fileName)) {
    231                                 SplittedAudioStream *sStream = new SplittedAudioStream();
    232                                 uint32 numSegs = oggSource->readUint32LE(); // number of audio segments, either 1 or 2.
    233                                 // for each segment and each of the 7 languages, we've got fileoffset and size
    234                                 uint32 *header = (uint32*)malloc(numSegs * 7 * 2 * 4);
    235                                 for (uint32 cnt = 0; cnt < numSegs * 7 * 2; cnt++)
    236                                         header[cnt] = oggSource->readUint32LE();
    237                                 for (uint32 segCnt = 0; segCnt < numSegs; segCnt++) {
    238                                         oggSource->seek( header[SwordEngine::_systemVars.language * 2 + 0 + segCnt * 14]);
    239                                         uint32 segSize = header[SwordEngine::_systemVars.language * 2 + 1 + segCnt * 14];
    240                                         Common::MemoryReadStream *stream = oggSource->readStream(segSize);
    241                                         Audio::AudioStream *apStream = Audio::makeVorbisStream(stream, true);
    242                                         if (!apStream)
    243                                                 error("Can't create Vorbis Stream from file %s", fileName);
    244                                         sStream->appendStream(apStream);
    245                                 }
    246                                 free(header);
    247                                 _bgSoundStream = sStream;
    248                         } else
    249                                 warning("Sound file \"%s\" not found", fileName);
    250                         delete oggSource;
     136        char filename[20];
     137        switch (_decoderType) {
     138        case kVideoDecoderDXA:
     139                snprintf(filename, sizeof(filename), "%s.dxa", sequenceList[id]);
     140                break;
     141#ifdef USE_SWORD_SMACKS
     142        case kVideoDecoderSMK:
     143                snprintf(filename, sizeof(filename), "%s.smk", sequenceList[id]);
     144                break;
    251145#endif
    252                         initOverlays(id);
    253                 }
    254146        }
     147
     148        if (_decoder->loadFile(filename)) {
     149                // The Broken Sword games always use external audio tracks.
     150                if (_decoder->readSoundHeader() != MKID_BE('NULL'))
     151                        return false;
     152        } else {
     153                return false;
     154        }
     155
    255156        return true;
    256157}
    257158
    258159void MoviePlayer::play(void) {
    259         _screen->clearScreen();
    260         _framesSkipped = 0;
    261         _ticks = _system->getMillis();
    262         _bgSoundStream = Audio::AudioStream::openStreamFile(sequenceList[_id]);
    263160        if (_bgSoundStream) {
    264                 _snd->playInputStream(Audio::Mixer::kSFXSoundType, &_bgSoundHandle, _bgSoundStream);
     161                _snd->playInputStream(Audio::Mixer::kSFXSoundType, _bgSoundHandle, _bgSoundStream);
    265162        }
    266         _currentFrame = 0;
    267163        bool terminated = false;
    268         Common::EventManager *eventMan = _system->getEventManager();
    269         while (!terminated && decodeFrame()) {
    270                 if (!_movieTexts.empty()) {
    271                         if (_currentFrame == _movieTexts[0]->_startFrame) {
    272                                 _textMan->makeTextSprite(2, (uint8 *)_movieTexts[0]->_text, 600, LETTER_COL);
    273164
    274                                 FrameHeader *frame = _textMan->giveSpriteData(2);
    275                                 _textWidth = frame->width;
    276                                 _textHeight = frame->height;
    277                                 _textX = 320 - _textWidth / 2;
    278                                 _textY = 420 - _textHeight;
    279                         }
    280                         if (_currentFrame == _movieTexts[0]->_endFrame) {
    281                                 _textMan->releaseText(2, false);
    282                                 delete _movieTexts.remove_at(0);
    283                         }
    284                 }
    285                 processFrame();
    286                 if (syncFrame())
    287                         updateScreen();
    288                 _currentFrame++;
    289                 Common::Event event;
    290                 while (eventMan->pollEvent(event)) {
    291                         switch (event.type) {
    292                         case Common::EVENT_SCREEN_CHANGED:
    293                                 handleScreenChanged();
    294                                 break;
    295                         case Common::EVENT_KEYDOWN:
    296                                 if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
    297                                         terminated = true;
    298                                 break;
    299                         default:
    300                                 break;
    301                         }
    302                 }
    303                 if (_vm->shouldQuit())
    304                         terminated = true;
    305         }
     165        Common::List<Common::Event> stopEvents;
     166        Common::Event stopEvent;
     167        stopEvents.clear();
     168        stopEvent.type = Common::EVENT_KEYDOWN;
     169        stopEvent.kbd = Common::KEYCODE_ESCAPE;
     170        stopEvents.push_back(stopEvent);
    306171
     172        terminated = !playVideo(&stopEvents);
     173
    307174        if (terminated)
    308                 _snd->stopHandle(_bgSoundHandle);
     175                _snd->stopHandle(*_bgSoundHandle);
    309176
    310177        _textMan->releaseText(2, false);
    311178
    312179        while (!_movieTexts.empty())
    313180                delete _movieTexts.remove_at(_movieTexts.size() - 1);
    314181
    315         while (_snd->isSoundHandleActive(_bgSoundHandle))
     182        while (_snd->isSoundHandleActive(*_bgSoundHandle))
    316183                _system->delayMillis(100);
    317184
    318185        // It's tempting to call _screen->fullRefresh() here to restore the old
     
    322189
    323190        byte pal[3 * 256];
    324191        memset(pal, 0, sizeof(pal));
    325         updatePalette(pal, true);
     192        _system->setPalette(pal, 0, 255);
    326193}
    327194
    328 SplittedAudioStream::SplittedAudioStream(void) {
    329         _queue = NULL;
    330 }
     195void MoviePlayer::performPostProcessing(byte *screen) {
     196        if (!_movieTexts.empty()) {
     197                if (_decoder->getCurFrame() == _movieTexts[0]->_startFrame) {
     198                        _textMan->makeTextSprite(2, (uint8 *)_movieTexts[0]->_text, 600, LETTER_COL);
    331199
    332 SplittedAudioStream::~SplittedAudioStream(void) {
    333         while (_queue) {
    334                 delete _queue->stream;
    335                 FileQueue *que = _queue->next;
    336                 delete _queue;
    337                 _queue = que;
    338         }
    339 }
    340 
    341 int SplittedAudioStream::getRate(void) const {
    342         if (_queue)
    343                 return _queue->stream->getRate();
    344         else
    345                 return 22050;
    346 }
    347 
    348 void SplittedAudioStream::appendStream(Audio::AudioStream *stream) {
    349         FileQueue **que = &_queue;
    350         while (*que)
    351                 que = &((*que)->next);
    352         *que = new FileQueue;
    353         (*que)->stream = stream;
    354         (*que)->next = NULL;
    355 }
    356 
    357 bool SplittedAudioStream::endOfData(void) const {
    358         if (_queue)
    359                 return _queue->stream->endOfData();
    360         else
    361                 return true;
    362 }
    363 
    364 bool SplittedAudioStream::isStereo(void) const {
    365         if (_queue)
    366                 return _queue->stream->isStereo();
    367         else
    368                 return false; // all the BS1 files are mono, anyways.
    369 }
    370 
    371 int SplittedAudioStream::readBuffer(int16 *buffer, const int numSamples) {
    372         int retVal = 0;
    373         int needSamples = numSamples;
    374         while (needSamples && _queue) {
    375                 int retSmp = _queue->stream->readBuffer(buffer, needSamples);
    376                 needSamples -= retSmp;
    377                 retVal += retSmp;
    378                 buffer += retSmp;
    379                 if (_queue->stream->endOfData()) {
    380                         delete _queue->stream;
    381                         FileQueue *que = _queue->next;
    382                         delete _queue;
    383                         _queue = que;
     200                        FrameHeader *frame = _textMan->giveSpriteData(2);
     201                        _textWidth = frame->width;
     202                        _textHeight = frame->height;
     203                        _textX = 320 - _textWidth / 2;
     204                        _textY = 420 - _textHeight;
    384205                }
     206                if (_decoder->getCurFrame() == _movieTexts[0]->_endFrame) {
     207                        _textMan->releaseText(2, false);
     208                        delete _movieTexts.remove_at(0);
     209                }
    385210        }
    386         return retVal;
    387 }
    388211
    389 #ifdef USE_ZLIB
    390 
    391 ///////////////////////////////////////////////////////////////////////////////
    392 // Movie player for the new DXA movies
    393 ///////////////////////////////////////////////////////////////////////////////
    394 
    395 MoviePlayerDXA::MoviePlayerDXA(SwordEngine *vm, Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system)
    396         : MoviePlayer(vm, screen, textMan, snd, system) {
    397         debug(0, "Creating DXA cutscene player");
    398 }
    399 
    400 MoviePlayerDXA::~MoviePlayerDXA(void) {
    401         closeFile();
    402 }
    403 
    404 bool MoviePlayerDXA::load(uint32 id) {
    405         if (!MoviePlayer::load(id))
    406                 return false;
    407 
    408         char filename[20];
    409         snprintf(filename, sizeof(filename), "%s.dxa", sequenceList[id]);
    410         if (loadFile(filename)) {
    411                 // The Broken Sword games always use external audio tracks.
    412                 if (_fileStream->readUint32BE() != MKID_BE('NULL'))
    413                         return false;
    414                 _frameWidth = getWidth();
    415                 _frameHeight = getHeight();
    416                 _frameX = (640 - _frameWidth) / 2;
    417                 _frameY = (480 - _frameHeight) / 2;
    418                 return true;
    419         }
    420         return false;
    421 }
    422 
    423 bool MoviePlayerDXA::initOverlays(uint32 id) {
    424         // TODO
    425         return true;
    426 }
    427 
    428 void MoviePlayerDXA::setPalette(byte *pal) {
    429         updatePalette(pal, true);
    430 }
    431 
    432 bool MoviePlayerDXA::decodeFrame(void) {
    433         if ((uint32)_currentFrame < (uint32)getFrameCount()) {
    434                 decodeNextFrame();
    435                 return true;
    436         }
    437         return false;
    438 }
    439 
    440 void MoviePlayerDXA::processFrame(void) {
    441 }
    442 
    443 void MoviePlayerDXA::updateScreen(void) {
    444         Graphics::Surface *frameBuffer = _system->lockScreen();
    445         copyFrameToBuffer((byte *)frameBuffer->pixels, _frameX, _frameY, _frameWidth);
    446 
    447         // TODO: Handle the advanced cutscene packs. Do they really exist?
    448 
    449         // We cannot draw the text to _drawBuffer, since that's one of the
    450         // decoder's internal buffers, and besides it may be much smaller than
    451         // the screen, so it's possible that the subtitles don't fit on it.
    452         // Instead, we get the frame buffer from the backend, after copying the
    453         // frame to it, and draw on that.
    454 
    455212        if (_textMan->giveSpriteData(2)) {
    456213                byte *src = (byte *)_textMan->giveSpriteData(2) + sizeof(FrameHeader);
    457                 byte *dst = (byte *)frameBuffer->getBasePtr(_textX, _textY);
     214                byte *dst = screen + _textY * _decoder->getWidth() + _textX * 1;
    458215
    459216                for (int y = 0; y < _textHeight; y++) {
    460217                        for (int x = 0; x < _textWidth; x++) {
    461218                                switch (src[x]) {
    462219                                case BORDER_COL:
    463                                         dst[x] = _black;
     220                                        dst[x] = _decoder->getBlack();
    464221                                        break;
    465222                                case LETTER_COL:
    466                                         dst[x] = _white;
     223                                        dst[x] = _decoder->getWhite();
    467224                                        break;
    468225                                }
    469226                        }
    470227                        src += _textWidth;
    471                         dst += frameBuffer->pitch;
     228                        dst += _decoder->getWidth();
    472229                }
    473 
    474230        }
    475 
    476         _system->unlockScreen();
    477 
    478         _system->updateScreen();
    479231}
    480232
    481 #endif
    482 
    483 #ifdef USE_MPEG2
    484 
    485 ///////////////////////////////////////////////////////////////////////////////
    486 // Movie player for the old MPEG movies
    487 ///////////////////////////////////////////////////////////////////////////////
    488 
    489 MoviePlayerMPEG::MoviePlayerMPEG(SwordEngine *vm, Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system)
    490         : MoviePlayer(vm, screen, textMan, snd, system) {
    491 #ifdef BACKEND_8BIT
    492         debug(0, "Creating MPEG cutscene player (8-bit)");
    493 #else
    494         debug(0, "Creating MPEG cutscene player (16-bit)");
    495 #endif
    496         for (uint8 cnt = 0; cnt < INTRO_LOGO_OVLS; cnt++)
    497                 _logoOvls[cnt] = NULL;
    498         _introPal = NULL;
    499         _anim = NULL;
     233DXAPlayerWithSound::DXAPlayerWithSound(Audio::Mixer *mixer, Audio::SoundHandle *bgSoundHandle)
     234        : _mixer(mixer), _bgSoundHandle(bgSoundHandle)  {
    500235}
    501236
    502 MoviePlayerMPEG::~MoviePlayerMPEG(void) {
    503         free(_introPal);
    504         for (uint8 cnt = 0; cnt < INTRO_LOGO_OVLS; cnt++)
    505                 free(_logoOvls[cnt]);
    506         delete _anim;
    507 }
     237int32 DXAPlayerWithSound::getAudioLag() {
     238        if (!_fileStream)
     239                return 0;
    508240
    509 void MoviePlayerMPEG::handleScreenChanged(void) {
    510         _anim->handleScreenChanged();
    511 }
     241        int32 frameDelay = getFrameDelay();
     242        int32 videoTime = _videoInfo.currentFrame * frameDelay;
     243        int32 audioTime;
    512244
    513 void MoviePlayerMPEG::insertOverlay(OverlayColor *buf, uint8 *ovl, OverlayColor *pal) {
    514         if (ovl != NULL)
    515                 for (uint32 cnt = 0; cnt < 640 * 400; cnt++)
    516                         if (ovl[cnt])
    517                                 buf[cnt] = pal[ovl[cnt]];
    518 }
     245        audioTime = (((int32) _mixer->getSoundElapsedTime(*_bgSoundHandle)) * 100);
    519246
    520 bool MoviePlayerMPEG::load(uint32 id) {
    521         if (MoviePlayer::load(id)) {
    522                 _anim = new AnimationState(this, _screen, _system);
    523                 return _anim->init(sequenceList[id]);
    524         }
    525         return false;
     247        return videoTime - audioTime;
    526248}
    527249
    528 bool MoviePlayerMPEG::initOverlays(uint32 id) {
    529         if (id == SEQ_INTRO) {
    530                 ArcFile ovlFile;
    531                 if (!ovlFile.open("intro.dat")) {
    532                         warning("\"intro.dat\" not found");
    533                         return false;
    534                 }
    535                 ovlFile.enterPath(SwordEngine::_systemVars.language);
    536                 for (uint8 fcnt = 0; fcnt < 12; fcnt++) {
    537                         _logoOvls[fcnt] = ovlFile.decompressFile(fcnt);
    538                         if (fcnt > 0)
    539                                 for (uint32 cnt = 0; cnt < 640 * 400; cnt++)
    540                                         if (_logoOvls[fcnt - 1][cnt] && !_logoOvls[fcnt][cnt])
    541                                                 _logoOvls[fcnt][cnt] = _logoOvls[fcnt - 1][cnt];
    542                 }
    543                 uint8 *pal = ovlFile.fetchFile(12);
    544                 _introPal = (OverlayColor *)malloc(256 * sizeof(OverlayColor));
    545                 Graphics::PixelFormat format = _system->getOverlayFormat();
    546                 for (uint16 cnt = 0; cnt < 256; cnt++)
    547                         _introPal[cnt] = Graphics::RGBToColor(pal[cnt * 3 + 0], pal[cnt * 3 + 1], pal[cnt * 3 + 2], format);
    548         }
    549 
    550         return true;
    551 }
    552 
    553 bool MoviePlayerMPEG::decodeFrame(void) {
    554         return _anim->decodeFrame();
    555 }
    556 
    557 void MoviePlayerMPEG::updateScreen(void) {
    558         _anim->updateScreen();
    559 }
    560 
    561 void MoviePlayerMPEG::processFrame(void) {
    562 #ifndef BACKEND_8BIT
    563         if ((_id != 4) || (SwordEngine::_systemVars.cutscenePackVersion == 0))
    564                 return;
    565         OverlayColor *buf = _anim->giveRgbBuffer();
    566         if ((_currentFrame > 397) && (_currentFrame < 444)) { // Broken Sword Logo
    567                 if (_currentFrame <= 403)
    568                         insertOverlay(buf, _logoOvls[_currentFrame - 398], _introPal); // fade up
    569                 else if (_currentFrame <= 437)
    570                         insertOverlay(buf, _logoOvls[(_currentFrame - 404) % 6 + 6], _introPal); // animation
    571                 else {
    572                         insertOverlay(buf, _logoOvls[5 - (_currentFrame - 438)], _introPal); // fade down
    573                 }
    574         }
    575 #endif
    576 }
    577 
    578 AnimationState::AnimationState(MoviePlayer *player, Screen *screen, OSystem *system)
    579         : BaseAnimationState(system, 640, 400), _player(player), _screen(screen) {
    580 }
    581 
    582 AnimationState::~AnimationState(void) {
    583 }
    584 
    585 #ifdef BACKEND_8BIT
    586 void AnimationState::setPalette(byte *pal) {
    587         _player->updatePalette(pal, false);
    588 }
    589 #endif
    590 
    591 void AnimationState::drawYUV(int width, int height, byte *const *dat) {
    592         _frameWidth = width;
    593         _frameHeight = height;
    594 
    595 #ifdef BACKEND_8BIT
    596         _screen->plotYUV(_lut, width, height, dat);
    597 #else
    598         plotYUV(width, height, dat);
    599 #endif
    600 }
    601 
    602 OverlayColor *AnimationState::giveRgbBuffer(void) {
    603 #ifdef BACKEND_8BIT
    604         return NULL;
    605 #else
    606         return _overlay;
    607 #endif
    608 }
    609 
    610 Audio::AudioStream *AnimationState::createAudioStream(const char *name, void *arg) {
    611         if (arg)
    612                 return (Audio::AudioStream*)arg;
    613         else
    614                 return Audio::AudioStream::openStreamFile(name);
    615 }
    616 
    617 #endif
    618 
    619250///////////////////////////////////////////////////////////////////////////////
    620251// Factory function for creating the appropriate cutscene player
    621252///////////////////////////////////////////////////////////////////////////////
    622253
    623 MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system) {
    624 #if defined(USE_ZLIB) || defined(USE_MPEG2)
     254MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, Audio::Mixer *snd, OSystem *system) {
    625255        char filename[20];
     256        char buf[60];
     257        Audio::SoundHandle bgSoundHandle;
     258
     259#ifdef USE_SWORD_SMACKS
     260        snprintf(filename, sizeof(filename), "%s.smk", sequenceList[id]);
     261
     262        if (Common::File::exists(filename)) {
     263                Graphics::SMKPlayer *smkDecoder = new Graphics::SMKPlayer(snd);
     264                return new MoviePlayer(vm, textMan, snd, system, &bgSoundHandle, smkDecoder, kVideoDecoderSMK);
     265        }
    626266#endif
    627267
    628 #ifdef USE_ZLIB
    629268        snprintf(filename, sizeof(filename), "%s.dxa", sequenceList[id]);
    630269
    631270        if (Common::File::exists(filename)) {
    632                 return new MoviePlayerDXA(vm, screen, textMan, snd, system);
    633         }
     271#ifdef USE_ZLIB
     272                DXAPlayerWithSound *dxaDecoder = new DXAPlayerWithSound(snd, &bgSoundHandle);
     273                return new MoviePlayer(vm, textMan, snd, system, &bgSoundHandle, dxaDecoder, kVideoDecoderDXA);
     274#else
     275                GUI::MessageDialog dialog("DXA cutscenes found but ScummVM has been built without zlib support", "OK");
     276                dialog.runModal();
     277                return NULL;
    634278#endif
     279        }
    635280
    636 #ifdef USE_MPEG2
     281        // Old MPEG2 cutscenes
    637282        snprintf(filename, sizeof(filename), "%s.mp2", sequenceList[id]);
    638283
    639284        if (Common::File::exists(filename)) {
    640                 return new MoviePlayerMPEG(vm, screen, textMan, snd, system);
     285                GUI::MessageDialog dialog("MPEG2 cutscenes are no longer supported", "OK");
     286                dialog.runModal();
     287                return NULL;
    641288        }
    642 #endif
    643289
     290        sprintf(buf, "Cutscene '%s' not found", sequenceList[id]);
     291        GUI::MessageDialog dialog(buf, "OK");
     292        dialog.runModal();
     293
    644294        return NULL;
    645295}
    646296
  • engines/sword1/animation.h

     
    2727#define SWORD1_ANIMATION_H
    2828
    2929#include "graphics/video/dxa_player.h"
    30 #include "graphics/video/mpeg_player.h"
     30#ifdef USE_SWORD_SMACKS
     31#include "graphics/video/smk_player.h"
     32#endif
     33#include "graphics/video/video_player.h"
    3134
    3235#include "sword1/screen.h"
    3336#include "sword1/sound.h"
     
    3538
    3639namespace Sword1 {
    3740
    38 enum {
    39         SEQ_FERRARI = 0,
    40         SEQ_LADDER,
    41         SEQ_STEPS,
    42         SEQ_SEWER,
    43         SEQ_INTRO,
    44         SEQ_RIVER,
    45         SEQ_TRUCK,
    46         SEQ_GRAVE,
    47         SEQ_MONTFCON,
    48         SEQ_TAPESTRY,
    49         SEQ_IRELAND,
    50         SEQ_FINALE,
    51         SEQ_HISTORY,
    52         SEQ_SPANISH,
    53         SEQ_WELL,
    54         SEQ_CANDLE,
    55         SEQ_GEODROP,
    56         SEQ_VULTURE,
    57         SEQ_ENDDEMO,
    58         SEQ_CREDITS
     41enum DecoderType {
     42        kVideoDecoderDXA = 0,
     43        kVideoDecoderSMK = 1
    5944};
    6045
    61 #define INTRO_LOGO_OVLS 12
    62 #define INTRO_TEXT_OVLS 8
    63 
    6446class MovieText {
    6547public:
    6648        uint16 _startFrame;
     
    7658        }
    7759};
    7860
    79 class MoviePlayer {
     61class DXAPlayerWithSound : public Graphics::DXAPlayer {
    8062public:
    81         MoviePlayer(SwordEngine *vm, Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system);
     63        DXAPlayerWithSound(Audio::Mixer *mixer, Audio::SoundHandle *bgSoundHandle);
     64        ~DXAPlayerWithSound() {}
     65
     66        int32 getAudioLag();
     67private:
     68        Audio::Mixer *_mixer;
     69        Audio::SoundHandle *_bgSoundHandle;
     70};
     71
     72class MoviePlayer : public Graphics::VideoPlayer {
     73public:
     74        MoviePlayer(SwordEngine *vm, Text *textMan, Audio::Mixer *snd, OSystem *system, Audio::SoundHandle *bgSoundHandle, Graphics::VideoDecoder *decoder, DecoderType decoderType);
    8275        virtual ~MoviePlayer(void);
    83         virtual bool load(uint32 id);
     76        bool load(uint32 id);
    8477        void play(void);
    85         void updatePalette(byte *pal, bool packed = true);
    86 private:
    87         bool checkSkipFrame(void);
    8878protected:
    8979        SwordEngine *_vm;
    90         Screen *_screen;
    9180        Text *_textMan;
    9281        Audio::Mixer *_snd;
    9382        OSystem *_system;
    9483        Common::Array<MovieText *> _movieTexts;
    9584        int _textX, _textY, _textWidth, _textHeight;
    96         byte _black, _white;
     85        DecoderType _decoderType;
    9786
    98         uint32 _id;
    99 
    100         uint _currentFrame;
    101         int _framesSkipped;
    102         bool _forceFrame;
    103 
    104         int _frameWidth, _frameHeight;
    105         int _frameX, _frameY;
    106 
    107         Audio::SoundHandle _bgSoundHandle;
     87        Audio::SoundHandle *_bgSoundHandle;
    10888        Audio::AudioStream *_bgSoundStream;
    109         uint32 _ticks;
    11089
    111         virtual void handleScreenChanged(void);
    112         virtual bool initOverlays(uint32 id);
    113         virtual bool decodeFrame(void) = 0;
    114         virtual void processFrame(void) = 0;
    115         virtual bool syncFrame(void);
    116         virtual void updateScreen(void) = 0;
     90        void performPostProcessing(byte *screen);
    11791};
    11892
    119 #ifdef USE_ZLIB
     93MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, Audio::Mixer *snd, OSystem *system);
    12094
    121 class MoviePlayerDXA : public MoviePlayer, ::Graphics::DXAPlayer {
    122 protected:
    123         virtual void setPalette(byte *pal);
    124 public:
    125         MoviePlayerDXA(SwordEngine *vm, Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system);
    126         virtual ~MoviePlayerDXA(void);
    127         bool load(uint32 id);
    128 protected:
    129         bool initOverlays(uint32 id);
    130         bool decodeFrame(void);
    131         void processFrame(void);
    132         void updateScreen(void);
    133 };
    134 
    135 #endif
    136 
    137 #ifdef USE_MPEG2
    138 
    139 class AnimationState : public Graphics::BaseAnimationState {
    140 private:
    141         MoviePlayer *_player;
    142         Screen *_screen;
    143 
    144 public:
    145         AnimationState(MoviePlayer *player, Screen *screen, OSystem *system);
    146         ~AnimationState(void);
    147         OverlayColor *giveRgbBuffer(void);
    148 
    149 private:
    150         void drawYUV(int width, int height, byte *const *dat);
    151 
    152 #ifdef BACKEND_8BIT
    153         void setPalette(byte *pal);
    154 #endif
    155 
    156 protected:
    157         virtual Audio::AudioStream *createAudioStream(const char *name, void *arg);
    158 };
    159 
    160 class MoviePlayerMPEG : public MoviePlayer {
    161 public:
    162         MoviePlayerMPEG(SwordEngine *vm, Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system);
    163         virtual ~MoviePlayerMPEG(void);
    164         bool load(uint32 id);
    165 protected:
    166         void insertOverlay(OverlayColor *buf, uint8 *ovl, OverlayColor *pal);
    167         AnimationState *_anim;
    168         OverlayColor *_introPal;
    169         uint8 *_logoOvls[INTRO_LOGO_OVLS];
    170 
    171         bool initOverlays(uint32 id);
    172         bool decodeFrame(void);
    173         void processFrame(void);
    174         void updateScreen(void);
    175         void handleScreenChanged(void);
    176 };
    177 
    178 #endif
    179 
    180 struct FileQueue {
    181         Audio::AudioStream *stream;
    182         FileQueue *next;
    183 };
    184 
    185 class SplittedAudioStream : public Audio::AudioStream {
    186 public:
    187         SplittedAudioStream(void);
    188         ~SplittedAudioStream(void);
    189         void appendStream(Audio::AudioStream *stream);
    190         virtual int readBuffer(int16 *buffer, const int numSamples);
    191         virtual bool isStereo(void) const;
    192         virtual bool endOfData(void) const;
    193         virtual int getRate(void) const;
    194 private:
    195         FileQueue *_queue;
    196 };
    197 
    198 MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system);
    199 
    20095} // End of namespace Sword1
    20196
    20297#endif
  • engines/sword1/logic.cpp

     
    4141#include "sword1/music.h"
    4242#include "sword1/swordres.h"
    4343#include "sword1/animation.h"
    44 #include "sword1/credits.h"
    4544
    4645#include "sword1/debug.h"
    4746
     
    960959        // meantime, we don't want any looping sound effects still playing.
    961960        _sound->quitScreen();
    962961
    963         if ((SwordEngine::_systemVars.cutscenePackVersion == 1) && (sequenceId == SEQ_CREDITS)) {
    964                 CreditsPlayer player(_system, _mixer);
    965                 player.play();
    966         } else {
    967                 MoviePlayer *player = makeMoviePlayer(sequenceId, _vm, _screen, _textMan, _mixer, _system);
    968                 if (player) {
    969                         if (player->load(sequenceId))
    970                                 player->play();
    971                         delete player;
    972                 }
     962        MoviePlayer *player = makeMoviePlayer(sequenceId, _vm, _textMan, _mixer, _system);
     963        if (player) {
     964                _screen->clearScreen();
     965                if (player->load(sequenceId))
     966                        player->play();
     967                delete player;
    973968        }
    974969        return SCRIPT_CONT;
    975970}
  • engines/sword1/module.mk

     
    33MODULE_OBJS := \
    44        animation.o \
    55        control.o \
    6         credits.o \
    76        debug.o \
    87        detection.o \
    98        eventman.o \
  • engines/sword1/sword1.cpp

     
    5858        Common::File::addDefaultDirectory(_gameDataDir.getChild("MUSIC"));
    5959        Common::File::addDefaultDirectory(_gameDataDir.getChild("SPEECH"));
    6060        Common::File::addDefaultDirectory(_gameDataDir.getChild("VIDEO"));
     61        Common::File::addDefaultDirectory(_gameDataDir.getChild("SMACKSHI"));
    6162        Common::File::addDefaultDirectory(_gameDataDir.getChild("clusters"));
    6263        Common::File::addDefaultDirectory(_gameDataDir.getChild("music"));
    6364        Common::File::addDefaultDirectory(_gameDataDir.getChild("speech"));
    6465        Common::File::addDefaultDirectory(_gameDataDir.getChild("video"));
     66        Common::File::addDefaultDirectory(_gameDataDir.getChild("smackshi"));
    6567}
    6668
    6769SwordEngine::~SwordEngine() {
     
    475477        */
    476478        // make the demo flag depend on the Gamesettings for now, and not on what the datafiles look like
    477479        _systemVars.isDemo = (_features & GF_DEMO) != 0;
    478         _systemVars.cutscenePackVersion = 0;
    479 #ifdef USE_MPEG2
    480         if (Common::File::exists("intro.snd")) {
    481                 _systemVars.cutscenePackVersion = 1;
    482         }
    483 #endif
    484480}
    485481
    486482Common::Error SwordEngine::go() {
  • engines/sword1/sword1.h

     
    6767        uint8   language;
    6868        bool    isDemo;
    6969        bool    isMac;
    70 
    71         uint8   cutscenePackVersion;
    7270};
    7371
    7472class SwordEngine : public Engine {
  • engines/sword2/animation.cpp

     
    4242#include "sword2/sound.h"
    4343#include "sword2/animation.h"
    4444
     45#include "gui/message.h"
     46
    4547namespace Sword2 {
    4648
    4749///////////////////////////////////////////////////////////////////////////////
     
    9193        _leadOutFrame = (uint)-1;
    9294        _seamless = false;
    9395        _framesSkipped = 0;
    94         _forceFrame = false;
    9596        _currentText = 0;
    9697}
    9798
     
    103104        return _system->getMillis() - _pauseTicks;
    104105}
    105106
    106 void MoviePlayer::updatePalette(byte *pal, bool packed) {
    107         byte palette[4 * 256];
    108         byte *p = palette;
    109 
    110         uint32 maxWeight = 0;
    111         uint32 minWeight = 0xFFFFFFFF;
    112 
    113         for (int i = 0; i < 256; i++) {
    114                 int r = *pal++;
    115                 int g = *pal++;
    116                 int b = *pal++;
    117 
    118                 if (!packed)
    119                         pal++;
    120 
    121                 uint32 weight = 3 * r * r + 6 * g * g + 2 * b * b;
    122 
    123                 if (weight >= maxWeight) {
    124                         _white = i;
    125                         maxWeight = weight;
    126                 }
    127 
    128                 if (weight <= minWeight) {
    129                         _black = i;
    130                         minWeight = i;
    131                 }
    132 
    133                 *p++ = r;
    134                 *p++ = g;
    135                 *p++ = b;
    136                 *p++ = 0;
    137         }
    138 
    139         _vm->_screen->setPalette(0, 256, palette, RDPAL_INSTANT);
    140         _forceFrame = true;
    141 }
    142 
    143107void MoviePlayer::savePalette() {
    144108        memcpy(_originalPalette, _vm->_screen->getPalette(), sizeof(_originalPalette));
    145109}
     
    157121}
    158122
    159123bool MoviePlayer::checkSkipFrame() {
    160         if (_forceFrame) {
    161                 _forceFrame = false;
    162                 return false;
    163         }
    164 
    165124        if (_framesSkipped > 10) {
    166125                warning("Forced frame %d to be displayed", _currentFrame);
    167126                _framesSkipped = 0;
     
    512471        }
    513472}
    514473
    515 #ifdef USE_ZLIB
     474#ifdef USE_SWORD_SMACKS
    516475
    517476///////////////////////////////////////////////////////////////////////////////
    518 // Movie player for the new DXA movies
     477// Movie player for the original SMK movies
    519478///////////////////////////////////////////////////////////////////////////////
    520479
    521 MoviePlayerDXA::MoviePlayerDXA(Sword2Engine *vm, const char *name)
    522         : MoviePlayer(vm, name) {
    523         debug(0, "Creating DXA cutscene player");
     480MoviePlayerSMK::MoviePlayerSMK(Sword2Engine *vm, const char *name)
     481        : MoviePlayer(vm, name), SMKPlayer(vm->_mixer) {
     482        debug(0, "Creating SMK cutscene player");
    524483}
    525484
    526 MoviePlayerDXA::~MoviePlayerDXA() {
     485MoviePlayerSMK::~MoviePlayerSMK() {
    527486        closeFile();
    528487}
    529488
    530 void MoviePlayerDXA::setPalette(byte *pal) {
    531         updatePalette(pal);
    532 }
    533 
    534 bool MoviePlayerDXA::decodeFrame() {
     489bool MoviePlayerSMK::decodeFrame() {
    535490        decodeNextFrame();
    536491        copyFrameToBuffer(_frameBuffer, _frameX, _frameY, _vm->_screen->getScreenWide());
    537492        return true;
    538493}
    539494
    540 bool MoviePlayerDXA::load() {
     495bool MoviePlayerSMK::load() {
    541496        if (!MoviePlayer::load())
    542497                return false;
    543498
    544499        char filename[20];
    545500
    546         snprintf(filename, sizeof(filename), "%s.dxa", _name);
     501        snprintf(filename, sizeof(filename), "%s.smk", _name);
    547502
    548503        if (loadFile(filename)) {
    549                 // The Broken Sword games always use external audio tracks.
    550                 if (_fileStream->readUint32BE() != MKID_BE('NULL'))
    551                         return false;
    552 
    553504                _frameBuffer = _vm->_screen->getScreen();
    554505
    555506                _frameWidth = getWidth();
     
    566517
    567518#endif
    568519
    569 #ifdef USE_MPEG2
     520#ifdef USE_ZLIB
    570521
    571522///////////////////////////////////////////////////////////////////////////////
    572 // Movie player for the old MPEG movies
     523// Movie player for the new DXA movies
    573524///////////////////////////////////////////////////////////////////////////////
    574525
    575 MoviePlayerMPEG::MoviePlayerMPEG(Sword2Engine *vm, const char *name)
     526MoviePlayerDXA::MoviePlayerDXA(Sword2Engine *vm, const char *name)
    576527        : MoviePlayer(vm, name) {
    577 #ifdef BACKEND_8BIT
    578         debug(0, "Creating MPEG cutscene player (8-bit)");
    579 #else
    580         debug(0, "Creating MPEG cutscene player (16-bit)");
    581 #endif
     528        debug(0, "Creating DXA cutscene player");
    582529}
    583530
    584 MoviePlayerMPEG::~MoviePlayerMPEG() {
    585         delete _anim;
    586         _anim = NULL;
     531MoviePlayerDXA::~MoviePlayerDXA() {
     532        closeFile();
    587533}
    588534
    589 bool MoviePlayerMPEG::load() {
    590         if (!MoviePlayer::load())
    591                 return false;
    592 
    593         _anim = new AnimationState(_vm, this);
    594 
    595         if (!_anim->init(_name)) {
    596                 delete _anim;
    597                 _anim = NULL;
    598                 return false;
    599         }
    600 
    601 #ifdef BACKEND_8BIT
    602         _frameBuffer = _vm->_screen->getScreen();
    603 #endif
    604 
     535bool MoviePlayerDXA::decodeFrame() {
     536        decodeNextFrame();
     537        copyFrameToBuffer(_frameBuffer, _frameX, _frameY, _vm->_screen->getScreenWide());
    605538        return true;
    606539}
    607540
    608 bool MoviePlayerMPEG::decodeFrame() {
    609         bool result = _anim->decodeFrame();
     541bool MoviePlayerDXA::load() {
     542        if (!MoviePlayer::load())
     543                return false;
    610544
    611 #ifdef BACKEND_8BIT
    612         _frameWidth = _anim->getFrameWidth();
    613         _frameHeight = _anim->getFrameHeight();
     545        char filename[20];
    614546
    615         _frameX = (_vm->_screen->getScreenWide() - _frameWidth) / 2;
    616         _frameY = (_vm->_screen->getScreenDeep() - _frameHeight) / 2;
    617 #endif
     547        snprintf(filename, sizeof(filename), "%s.dxa", _name);
    618548
    619         return result;
    620 }
     549        if (loadFile(filename)) {
     550                // The Broken Sword games always use external audio tracks.
     551                if (_fileStream->readUint32BE() != MKID_BE('NULL'))
     552                        return false;
    621553
    622 AnimationState::AnimationState(Sword2Engine *vm, MoviePlayer *player)
    623         : BaseAnimationState(vm->_system, 640, 480) {
    624         _vm = vm;
    625         _player = player;
    626 }
     554                _frameBuffer = _vm->_screen->getScreen();
    627555
    628 AnimationState::~AnimationState() {
    629 }
     556                _frameWidth = getWidth();
     557                _frameHeight = getHeight();
    630558
    631 #ifdef BACKEND_8BIT
     559                _frameX = (_vm->_screen->getScreenWide() - _frameWidth) / 2;
     560                _frameY = (_vm->_screen->getScreenDeep() - _frameHeight) / 2;
    632561
    633 void AnimationState::setPalette(byte *pal) {
    634         _player->updatePalette(pal, false);
    635 }
    636 
    637 #else
    638 
    639 void MoviePlayerMPEG::handleScreenChanged() {
    640         _anim->handleScreenChanged();
    641 }
    642 
    643 void MoviePlayerMPEG::clearFrame() {
    644         _anim->clearFrame();
    645 }
    646 
    647 void MoviePlayerMPEG::drawFrame() {
    648 }
    649 
    650 void MoviePlayerMPEG::updateScreen() {
    651         _anim->updateScreen();
    652 }
    653 
    654 void MoviePlayerMPEG::drawTextObject() {
    655         if (_textObject.textMem && _textSurface) {
    656                 _anim->drawTextObject(&_textObject.textSprite, _textSurface);
     562                return true;
    657563        }
    658 }
    659564
    660 void MoviePlayerMPEG::undrawTextObject() {
    661         // As long as we only have subtitles for full-sized cutscenes, we don't
    662         // really need to implement this function.
     565        return false;
    663566}
    664567
    665 void AnimationState::drawTextObject(SpriteInfo *s, byte *src) {
    666         int moviePitch = _movieScale * _movieWidth;
    667         int textX = _movieScale * s->x;
    668         int textY = _movieScale * (_frameHeight - s->h - 12);
    669 
    670         OverlayColor *dst = _overlay + textY * moviePitch + textX;
    671 
    672         Graphics::PixelFormat format = _sys->getOverlayFormat();
    673         OverlayColor pen = Graphics::RGBToColor(255, 255, 255, format);
    674         OverlayColor border = Graphics::RGBToColor(0, 0, 0, format);
    675 
    676         // TODO: Use the AdvMame scalers for the text? Pre-scale it?
    677 
    678         for (int y = 0; y < s->h; y++) {
    679                 OverlayColor *ptr = dst;
    680 
    681                 for (int x = 0; x < s->w; x++) {
    682                         switch (src[x]) {
    683                         case 1:
    684                                 *ptr++ = border;
    685                                 if (_movieScale > 1) {
    686                                         *ptr++ = border;
    687                                         if (_movieScale > 2)
    688                                                 *ptr++ = border;
    689                                 }
    690                                 break;
    691                         case 255:
    692                                 *ptr++ = pen;
    693                                 if (_movieScale > 1) {
    694                                         *ptr++ = pen;
    695                                         if (_movieScale > 2)
    696                                                 *ptr++ = pen;
    697                                 }
    698                                 break;
    699                         default:
    700                                 ptr += _movieScale;
    701                                 break;
    702                         }
    703                 }
    704 
    705                 if (_movieScale > 1) {
    706                         memcpy(dst + moviePitch, dst, _movieScale * s->w * sizeof(OverlayColor));
    707                         if (_movieScale > 2)
    708                                 memcpy(dst + 2 * moviePitch, dst, _movieScale * s->w * sizeof(OverlayColor));
    709                 }
    710 
    711                 dst += _movieScale * moviePitch;
    712                 src += s->w;
    713         }
    714 }
    715568#endif
    716569
    717 void AnimationState::clearFrame() {
    718 #ifdef BACKEND_8BIT
    719         memset(_vm->_screen->getScreen(), 0, _movieWidth * _movieHeight);
    720 #else
    721         Graphics::PixelFormat format = _sys->getOverlayFormat();
    722         OverlayColor black = Graphics::RGBToColor(0, 0, 0, format);
    723 
    724         for (int i = 0; i < _movieScale * _movieWidth * _movieScale * _movieHeight; i++)
    725                 _overlay[i] = black;
    726 #endif
    727 }
    728 
    729 void AnimationState::drawYUV(int width, int height, byte *const *dat) {
    730         _frameWidth = width;
    731         _frameHeight = height;
    732 
    733 #ifdef BACKEND_8BIT
    734         byte *buf = _vm->_screen->getScreen() + ((480 - height) / 2) * RENDERWIDE + (640 - width) / 2;
    735 
    736         int x, y;
    737 
    738         int ypos = 0;
    739         int cpos = 0;
    740         int linepos = 0;
    741 
    742         for (y = 0; y < height; y += 2) {
    743                 for (x = 0; x < width; x += 2) {
    744                         int i = ((((dat[2][cpos] + ROUNDADD) >> SHIFT) * (BITDEPTH + 1)) + ((dat[1][cpos] + ROUNDADD) >> SHIFT)) * (BITDEPTH + 1);
    745                         cpos++;
    746 
    747                         buf[linepos               ] = _lut[i + ((dat[0][        ypos  ] + ROUNDADD) >> SHIFT)];
    748                         buf[RENDERWIDE + linepos++] = _lut[i + ((dat[0][width + ypos++] + ROUNDADD) >> SHIFT)];
    749                         buf[linepos               ] = _lut[i + ((dat[0][        ypos  ] + ROUNDADD) >> SHIFT)];
    750                         buf[RENDERWIDE + linepos++] = _lut[i + ((dat[0][width + ypos++] + ROUNDADD) >> SHIFT)];
    751                 }
    752                 linepos += (2 * RENDERWIDE - width);
    753                 ypos += width;
    754         }
    755 #else
    756         plotYUV(width, height, dat);
    757 #endif
    758 }
    759 
    760 #endif
    761 
    762570///////////////////////////////////////////////////////////////////////////////
    763571// Dummy player for subtitled speech only
    764572///////////////////////////////////////////////////////////////////////////////
     
    802610
    803611                byte msgNoCutscenesRU[] = "Po\344uk - to\344\345ko pev\345: hagmute k\344abuwy Ucke\343n, u\344u nocetute ca\343t npoekta u ckava\343te budeo po\344uku";
    804612
    805 #if defined(USE_MPEG2) || defined(USE_ZLIB)
     613#if defined(USE_ZLIB)
    806614                byte msgNoCutscenes[] = "Cutscene - Narration Only: Press ESC to exit, or visit www.scummvm.org to download cutscene videos";
    807615#else
    808                 byte msgNoCutscenes[] = "Cutscene - Narration Only: Press ESC to exit, or recompile ScummVM with MPEG2 or ZLib support";
     616                byte msgNoCutscenes[] = "Cutscene - Narration Only: Press ESC to exit, or recompile ScummVM with ZLib support";
    809617#endif
    810618
    811619                byte *msg;
     
    885693MoviePlayer *makeMoviePlayer(Sword2Engine *vm, const char *name) {
    886694        static char filename[20];
    887695
     696#ifdef USE_SWORD_SMACKS
     697        snprintf(filename, sizeof(filename), "%s.smk", name);
     698
     699        if (Common::File::exists(filename)) {
     700                return new MoviePlayerSMK(vm, name);
     701        }
     702#endif
     703
    888704#ifdef USE_ZLIB
    889705        snprintf(filename, sizeof(filename), "%s.dxa", name);
    890706
     
    893709        }
    894710#endif
    895711
    896 #ifdef USE_MPEG2
    897712        snprintf(filename, sizeof(filename), "%s.mp2", name);
    898713
    899714        if (Common::File::exists(filename)) {
    900                 return new MoviePlayerMPEG(vm, name);
     715                GUI::MessageDialog dialog("MPEG2 cutscenes are no longer supported", "OK");
     716                dialog.runModal();
    901717        }
    902 #endif
    903718
    904719        return new MoviePlayerDummy(vm, name);
    905720}
  • engines/sword2/animation.h

     
    2929#define SWORD2_ANIMATION_H
    3030
    3131#include "graphics/video/dxa_player.h"
    32 #include "graphics/video/mpeg_player.h"
     32#ifdef USE_SWORD_SMACKS
     33#include "graphics/video/smk_player.h"
     34#endif
    3335#include "sound/mixer.h"
    3436
    3537#include "sword2/screen.h"
     
    9799        bool _seamless;
    98100
    99101        int _framesSkipped;
    100         bool _forceFrame;
    101102
    102103        static const MovieInfo _movies[];
    103104
     
    126127        MoviePlayer(Sword2Engine *vm, const char *name);
    127128        virtual ~MoviePlayer();
    128129
    129         void updatePalette(byte *pal, bool packed = true);
    130130        virtual bool load();
    131131        bool userInterrupt();
    132132        void play(SequenceTextInfo *textList, uint32 numLines, int32 leadIn, int32 leadOut);
     
    148148        bool load();
    149149};
    150150
    151 #ifdef USE_MPEG2
    152 class AnimationState : public ::Graphics::BaseAnimationState {
    153 private:
    154         Sword2Engine *_vm;
    155         MoviePlayer *_player;
    156 
    157 public:
    158         AnimationState(Sword2Engine *vm, MoviePlayer *player);
    159         ~AnimationState();
    160 
    161 #ifndef BACKEND_8BIT
    162         void drawTextObject(SpriteInfo *s, byte *src);
    163 #endif
    164 
    165         void clearFrame();
    166 
    167 private:
    168         void drawYUV(int width, int height, byte *const *dat);
    169 
    170 #ifdef BACKEND_8BIT
    171         void setPalette(byte *pal);
    172 #endif
    173 };
    174 
    175 class MoviePlayerMPEG : public MoviePlayer {
     151#ifdef USE_SWORD_SMACKS
     152class MoviePlayerSMK : public MoviePlayer, ::Graphics::SMKPlayer {
    176153protected:
    177         AnimationState *_anim;
     154        bool decodeFrame();
    178155
    179         virtual bool decodeFrame();
    180 
    181 #ifndef BACKEND_8BIT
    182         void handleScreenChanged();
    183         void clearFrame();
    184         void drawFrame();
    185         void updateScreen();
    186         void drawTextObject();
    187         void undrawTextObject();
    188 #endif
    189 
    190156public:
    191         MoviePlayerMPEG(Sword2Engine *vm, const char *name);
    192         ~MoviePlayerMPEG();
     157        MoviePlayerSMK(Sword2Engine *vm, const char *name);
     158        ~MoviePlayerSMK();
    193159
    194160        bool load();
    195161};
     
    198164#ifdef USE_ZLIB
    199165class MoviePlayerDXA : public MoviePlayer, ::Graphics::DXAPlayer {
    200166protected:
    201         void setPalette(byte *pal);
    202167        bool decodeFrame();
    203168
    204169public:
  • engines/sword2/sword2.cpp

     
    251251        Common::File::addDefaultDirectory(_gameDataDir.getChild("CLUSTERS"));
    252252        Common::File::addDefaultDirectory(_gameDataDir.getChild("SWORD2"));
    253253        Common::File::addDefaultDirectory(_gameDataDir.getChild("VIDEO"));
     254        Common::File::addDefaultDirectory(_gameDataDir.getChild("SMACKS"));
    254255        Common::File::addDefaultDirectory(_gameDataDir.getChild("clusters"));
    255256        Common::File::addDefaultDirectory(_gameDataDir.getChild("sword2"));
    256257        Common::File::addDefaultDirectory(_gameDataDir.getChild("video"));
     258        Common::File::addDefaultDirectory(_gameDataDir.getChild("smacks"));
    257259
    258260        if (0 == scumm_stricmp(ConfMan.get("gameid").c_str(), "sword2demo"))
    259261                _features = GF_DEMO;
  • graphics/video/video_player.h

     
    141141         */
    142142        virtual bool decodeNextFrame() = 0;
    143143
     144        /**
     145         * Used to read the sound header from DXA files. It's not pretty,
     146         * but it's slightly better than exposing _fileStream
     147         */
     148        uint32 readSoundHeader() { return _fileStream->readUint32BE(); }
     149
    144150protected:
    145151        struct {
    146152                uint32 width;