Ticket #8545: dxa-unification_v2.diff

File dxa-unification_v2.diff, 22.4 KB (added by Kirben, 13 years ago)

Updated patch

  • engines/scumm/he/animation_he.h

     
    2525#define ANIMATION_H
    2626
    2727#include "common/file.h"
     28#include "graphics/animation.h"
    2829
    2930namespace Scumm {
    3031
    3132class ScummEngine_v90he;
    3233
    33 class MoviePlayer {
     34class MoviePlayer : public Graphics::DXAPlayer {
    3435        ScummEngine_v90he *_vm;
    3536
    36         Common::File _fd;
    37         uint8 *_frameBuffer1;
    38         uint8 *_frameBuffer2;
    39         uint16 _width;
    40         uint16 _height;
    41         uint16 _framesCount;
    42         uint32 _framesPerSec;
    43         uint16 _frameNum;
    44         uint32 _frameSize;
    45         uint32 _frameTicks;
    46 
    4737        uint32 _flags;
    4838        uint32 _wizResNum;
    4939       
    5040public:
    5141        MoviePlayer(ScummEngine_v90he *vm);
    52         ~MoviePlayer();
    5342
    54         int getWidth();
    55         int getHeight();
    56         int getCurFrame();
    57         int getFrameCount();
    5843        int getImageNum();
    5944        int load(const char *filename, int flags, int image = 0);
    6045
    6146        void handleNextFrame();
    62         void close();
    6347
    64 private:
    65         void copyFrame(byte *dst, uint x, uint y);
    66         void decodeFrame();
    67         void decodeZlib(uint8 *data, int size, int totalSize);
     48protected:
     49        virtual void setPalette(byte *pal);
    6850};
    6951
    7052} // End of namespace Simon
  • engines/scumm/he/script_v90he.cpp

     
    550550                        }
    551551                } else if (_videoParams.status == 165) {
    552552                        // Stop video
    553                         _moviePlay->close();
     553                        _moviePlay->closeFile();
    554554                }
    555555                break;
    556556        default:
  • engines/scumm/he/animation_he.cpp

     
    2626#include "scumm/he/animation_he.h"
    2727#include "scumm/he/intern_he.h"
    2828
    29 #ifdef USE_ZLIB
    30 #include <zlib.h>
    31 #endif
    32 
    3329namespace Scumm {
    3430
    3531MoviePlayer::MoviePlayer(ScummEngine_v90he *vm)
    36         : _vm(vm) {
     32        : DXAPlayer(), _vm(vm) {
    3733
    38         _frameBuffer1 = 0;
    39         _frameBuffer2 = 0;
    40 
    41         _width = 0;
    42         _height = 0;
    43 
    44         _frameSize = 0;
    45         _framesCount = 0;
    46         _frameNum = 0;
    47         _framesPerSec = 0;
    48         _frameTicks = 0;
    49 
    5034        _flags = 0;
    5135        _wizResNum = 0;
    5236}
    5337
    54 MoviePlayer::~MoviePlayer() {
    55 }
    56 
    57 int MoviePlayer::getWidth() {
    58         if (_fd.isOpen() == false)
    59                 return 0;
    60         return _width;
    61 }
    62 
    63 int MoviePlayer::getHeight() {
    64         if (_fd.isOpen() == false)
    65                 return 0;
    66         return _height;
    67 }
    68 
    69 int MoviePlayer::getCurFrame() {
    70         if (_fd.isOpen() == false)
    71                 return -1;
    72         return _frameNum;
    73 }
    74 
    75 int MoviePlayer::getFrameCount() {
    76         if (_fd.isOpen() == false)
    77                 return 0;
    78         return _framesCount;
    79 }
    80 
    8138int MoviePlayer::getImageNum() {
    82         if (_fd.isOpen() == false)
     39        if (!_fd.isOpen())
    8340                return 0;
    8441        return _wizResNum;
    8542}
    8643
    8744int MoviePlayer::load(const char *filename, int flags, int image) {
    8845        char videoName[100];
    89         uint32 tag;
    90         int32 frameRate;
    9146
    92         if (_fd.isOpen() == true) {
    93                 close();
     47        if (_fd.isOpen()) {
     48                closeFile();
    9449        }
    9550
    9651        // Change file extension to dxa
     
    10055        videoName[len++] = 'x';
    10156        videoName[len++] = 'a';
    10257       
    103         if (_fd.open(videoName) == false) {
     58        if (!loadFile(videoName)) {
    10459                warning("Failed to load video file %s", videoName);
    10560                return -1;
    10661        }
    10762        debug(1, "Playing video %s", videoName);
    10863
    109         tag = _fd.readUint32BE();
    110         assert(tag == MKID_BE('DEXA'));
    111 
    112         _fd.readByte();
    113         _framesCount = _fd.readUint16BE();
    114         frameRate = _fd.readUint32BE();
    115 
    116         if (frameRate > 0)
    117                 _framesPerSec = 1000 / frameRate;
    118         else if (frameRate < 0)
    119                 _framesPerSec = 100000 / (-frameRate);
    120         else
    121                 _framesPerSec = 10;
    122 
    123         if (frameRate < 0)
    124                 _frameTicks = -frameRate / 100;
    125         else
    126                 _frameTicks = frameRate;
    127 
    128         _width = _fd.readUint16BE();
    129         _height = _fd.readUint16BE();
    130 
    13164        // Skip sound tag
    13265        _fd.readUint32BE();
    13366
    134         _frameSize = _width * _height;
    135         _frameBuffer1 = (uint8 *)malloc(_frameSize);
    136         _frameBuffer2 = (uint8 *)malloc(_frameSize);
    137         if (!_frameBuffer1 || !_frameBuffer2) {
    138                 error("error allocating frame tables, size %d\n", _frameSize);
    139         }
    140 
    14167        if (flags & 2) {
    14268                _vm->_wiz->createWizEmptyImage(image, 0, 0, _width, _height);
    14369        }
    14470
    145         _frameNum = 0;
    146 
    14771        _flags = flags;
    14872        _wizResNum = image;
    14973
    15074        return 0;
    15175}
    15276
    153 void MoviePlayer::close() {
    154         if (_fd.isOpen() == false)
    155                 return;
    156 
    157         _fd.close();
    158         free(_frameBuffer1);
    159         free(_frameBuffer2);
    160 }
    161 
    16277void MoviePlayer::handleNextFrame() {
    16378        if (_fd.isOpen() == false) {
    16479                return;
    16580        }
    16681
    16782        VirtScreen *pvs = &_vm->virtscr[kMainVirtScreen];
    168         uint8 *dst;
     83        ;
    16984
    17085        decodeFrame();
    17186
    17287        if (_flags & 2) {
    17388                uint8 *dstPtr = _vm->getResourceAddress(rtImage, _wizResNum);
    17489                assert(dstPtr);
    175                 dst = _vm->findWrappedBlock(MKID_BE('WIZD'), dstPtr, 0, 0);
     90                uint8 *dst = _vm->findWrappedBlock(MKID_BE('WIZD'), dstPtr, 0, 0);
    17691                assert(dst);
    177                 copyFrame(dst, 0, 0);
     92                copyFrame(dst, 0, 0, _vm->_screenWidth);
    17893        } else if (_flags & 1) {
    179                 dst = pvs->getBackPixels(0, 0);
    180                 copyFrame(dst, 0, 0);
     94                copyFrame(pvs->getBackPixels(0, 0), 0, 0, _vm->_screenWidth);
    18195               
    18296                Common::Rect imageRect(_width, _height);
    18397                _vm->gdi.copyVirtScreenBuffers(imageRect);
    18498        } else {
    185                 dst = pvs->getPixels(0, 0);
    186                 copyFrame(dst, 0, 0);
     99                copyFrame(pvs->getPixels(0, 0), 0, 0, _vm->_screenWidth);
    187100
    188101                _vm->markRectAsDirty(kMainVirtScreen, 0, 0, _width, _height);
    189102        }
    190103
    191104        _frameNum++;
    192105        if (_frameNum == _framesCount) {
    193                 close();
     106                closeFile();
    194107        }
    195108}
    196109
    197 void MoviePlayer::copyFrame(byte *dst, uint x, uint y) {
    198         uint h = _height;
    199         uint w = _width;
    200 
    201         dst += y * _vm->_screenWidth + x;
    202         byte *src = _frameBuffer1;
    203 
    204         do {
    205                 memcpy(dst, src, w);
    206                 dst += _vm->_screenWidth;
    207                 src += _width;
    208         } while (--h);
     110void MoviePlayer::setPalette(byte *pal) {
     111        _vm->setPaletteFromPtr(pal, 256);
    209112}
    210113
    211 void MoviePlayer::decodeZlib(uint8 *data, int size, int totalSize) {
    212 #ifdef USE_ZLIB
    213         uint8 *temp = (uint8 *)malloc(size);
    214         if (temp) {
    215                 memcpy(temp, data, size);
    216         z_stream d_stream;
    217         d_stream.zalloc = (alloc_func)0;
    218         d_stream.zfree = (free_func)0;
    219         d_stream.opaque = (voidpf)0;
    220         d_stream.next_in = temp;
    221         d_stream.avail_in = size;
    222         d_stream.total_in = size;
    223         d_stream.next_out = data;
    224         d_stream.avail_out = totalSize;
    225         inflateInit(&d_stream);
    226         inflate(&d_stream, Z_FINISH);
    227         inflateEnd(&d_stream);
    228                 free(temp);
    229         }
    230 #endif
    231 }
    232 
    233 void MoviePlayer::decodeFrame() {
    234         uint32 tag;
    235 
    236         tag = _fd.readUint32BE();
    237         if (tag == MKID_BE('CMAP')) {
    238                 uint8 rgb[768];
    239 
    240                 _fd.read(rgb, ARRAYSIZE(rgb));
    241                 _vm->setPaletteFromPtr(rgb, 256);
    242         }
    243 
    244         tag = _fd.readUint32BE();
    245         if (tag == MKID_BE('FRAM')) {
    246                 uint8 type = _fd.readByte();
    247                 uint32 size = _fd.readUint32BE();
    248 
    249                 _fd.read(_frameBuffer2, size);
    250 
    251                 switch (type) {
    252                 case 2:
    253                 case 3:
    254                         decodeZlib(_frameBuffer2, size, _frameSize);
    255                         break;
    256                 default:
    257                         error("decodeFrame: Unknown compression type %d", type);
    258                 }
    259                 if (type == 2) {
    260                         memcpy(_frameBuffer1, _frameBuffer2, _frameSize);
    261                 } else {
    262                         for (int j = 0; j < _height; ++j) {
    263                                 for (int i = 0; i < _width; ++i) {
    264                                         const int offs = j * _width + i;
    265                                         _frameBuffer1[offs] ^= _frameBuffer2[offs];
    266                                 }
    267                         }
    268                 }
    269         }
    270 }
    271 
    272114} // End of namespace Simon
  • engines/simon/animation.h

     
    2727#include "common/file.h"
    2828#include "common/stream.h"
    2929
     30#include "graphics/animation.h"
    3031#include "sound/mixer.h"
    3132
    3233namespace Simon {
    3334
    3435class SimonEngine;
    3536
    36 class MoviePlayer {
     37class MoviePlayer : public Graphics::DXAPlayer {
    3738        SimonEngine *_vm;
    3839
    3940        Audio::Mixer *_mixer;
     
    4243        Audio::AudioStream *_bgSoundStream;
    4344
    4445        bool _omniTV;
    45         bool _playing;
    4646        bool _leftButtonDown;
    4747        bool _rightButtonDown;
    48         Common::File _fd;
    49         uint8 *_frameBuffer1;
    50         uint8 *_frameBuffer2;
    51         uint16 _width;
    52         uint16 _height;
    53         uint16 _framesCount;
    54         uint32 _framesPerSec;
    55         uint16 _frameNum;
    56         uint32 _frameSize;
    57         uint16 _frameSkipped;
    58         uint32 _frameTicks;
    5948        uint32 _ticks;
    6049       
    6150        char baseName[40];
     
    6352        uint8 _sequenceNum;
    6453public:
    6554        MoviePlayer(SimonEngine *vm, Audio::Mixer *mixer);
    66         ~MoviePlayer();
    6755
    6856        bool load(const char *filename);
    6957        void play();
    7058        void nextFrame();
     59protected:
     60        virtual void setPalette(byte *pal);
    7161private:
    7262        void playOmniTV();
    73         void close();
    7463
    75         void copyFrame(byte *dst, uint x, uint y);
    76         void decodeFrame();
    7764        void handleNextFrame();
    7865        void processFrame();
    7966        void startSound();
    80         void decodeZlib(uint8 *data, int size, int totalSize);
    8167};
    8268
    8369} // End of namespace Simon
  • engines/simon/animation.cpp

     
    3535#include "sound/audiostream.h"
    3636#include "sound/wave.h"
    3737
    38 
    39 #ifdef USE_ZLIB
    40 #include <zlib.h>
    41 #endif
    42 
    4338namespace Simon {
    4439
    4540MoviePlayer::MoviePlayer(SimonEngine *vm, Audio::Mixer *mixer)
    46         : _vm(vm), _mixer(mixer) {
     41        : DXAPlayer(), _vm(vm), _mixer(mixer) {
    4742        _omniTV = false;
    48         _playing = false;
    4943
    5044        _leftButtonDown = false;
    5145        _rightButtonDown = false;
    5246
    53         _frameBuffer1 = 0;
    54         _frameBuffer2 = 0;
    55 
    56         _width = 0;
    57         _height = 0;
    58 
    59         _frameSize = 0;
    60         _framesCount = 0;
    61         _frameNum = 0;
    62         _framesPerSec = 0;
    63         _frameTicks = 0;
    64         _frameSkipped = 0;
    65 
    6647        memset(baseName, 0, sizeof(baseName));
    6748
    6849        _sequenceNum = 0;
    6950        _ticks = 0;
    7051}
    7152
    72 MoviePlayer::~MoviePlayer() {
    73 }
    74 
    7553bool MoviePlayer::load(const char *filename) {
    7654        char videoName[20];
    7755        uint32 tag;
     
    8563        // Change file extension to dxa
    8664        sprintf(videoName, "%s.dxa", baseName);
    8765       
    88         if (_fd.open(videoName) == false) {
     66        if (!loadFile(videoName)) {
    8967                // Check short filename to work around
    9068                // bug in a German Windows 2CD version.
    9169                if (baseLen >= 8) {
     
    9876                        memset(baseName, 0, sizeof(baseName));
    9977                        memcpy(baseName, shortName, 8);
    10078
    101                         if (_fd.open(shortName) == false) {
     79                        if (!loadFile(shortName)) {
    10280                                error("Failed to load video file %s or %s", videoName, shortName);
    10381                        } else {
    10482                                debug(0, "Playing video %s", shortName);
     
    12199                }
    122100        }
    123101
    124         tag = _fd.readUint32BE();
    125         assert(tag == MKID_BE('DEXA'));
    126 
    127         _fd.readByte();
    128         _framesCount = _fd.readUint16BE();
    129         frameRate = _fd.readUint32BE();
    130 
    131         if (frameRate > 0)
    132                 _framesPerSec = 1000 / frameRate;
    133         else if (frameRate < 0)
    134                 _framesPerSec = 100000 / (-frameRate);
    135         else
    136                 _framesPerSec = 10;
    137 
    138         if (frameRate < 0)
    139                 _frameTicks = -frameRate / 100;
    140         else
    141                 _frameTicks = frameRate;
    142 
    143         _width = _fd.readUint16BE();
    144         _height = _fd.readUint16BE();
    145         debug(0, "frames_count %d width %d height %d rate %d ticks %d", _framesCount, _width, _height, _framesPerSec, _frameTicks);
    146 
    147         _frameSize = _width * _height;
    148         _frameBuffer1 = (uint8 *)malloc(_frameSize);
    149         _frameBuffer2 = (uint8 *)malloc(_frameSize);
    150         if (!_frameBuffer1 || !_frameBuffer2) {
    151                 error("error allocating frame tables, size %d\n", _frameSize);
    152         }
    153 
    154         _frameNum = 0;
    155         _frameSkipped = 0;
    156 
    157102        return true;
    158103}
    159104
    160105void MoviePlayer::playOmniTV() {
    161106        // Load OmniTV video
    162         if (_fd.isOpen() == false) {
     107        if (!_fd.isOpen()) {
    163108                _vm->_variableArray[254] = 6747;
    164109                return;
    165110        } else {
     
    177122                return;
    178123        }
    179124
    180         if (_fd.isOpen() == false) {
     125        if (!_fd.isOpen()) {
    181126                return;
    182127        }
    183128
     
    198143        while (_frameNum < _framesCount)
    199144                handleNextFrame();
    200145
    201         close();
     146        closeFile();
    202147
    203148        _vm->o_killAnimate();
    204149
     
    214159        _vm->_fastFadeOutFlag = true;
    215160}
    216161
    217 void MoviePlayer::close() {
    218         _fd.close();
    219         free(_frameBuffer1);
    220         free(_frameBuffer2);
    221 }
    222 
    223162void MoviePlayer::startSound() {
    224163        byte *buffer;
    225164        uint32 offset, size, tag;
     
    234173                        _fd.seek(size, SEEK_CUR);
    235174
    236175                        in.open((const char *)"audio.wav");
    237                         if (in.isOpen() == false) {
     176                        if (!in.isOpen()) {
    238177                                error("Can't read offset file 'audio.wav'");
    239178                        }
    240179
     
    271210
    272211        if (_vm->getBitFlag(42)) {
    273212                _omniTV = false;
    274                 close();
     213                closeFile();
    275214                return;
    276215        }
    277216
    278217        if (_mixer->isSoundHandleActive(_bgSound) && (_mixer->getSoundElapsedTime(_bgSound) * _framesPerSec) / 1000 < _frameNum) {
    279                 copyFrame(_vm->getBackBuf(), 465, 222);
     218                copyFrame(_vm->getBackBuf(), 465, 222, _vm->_screenWidth);
    280219                return;
    281220        }
    282221
    283222        if (_frameNum < _framesCount) {
    284223                decodeFrame();
    285                 copyFrame(_vm->getBackBuf(), 465, 222);
     224                copyFrame(_vm->getBackBuf(), 465, 222, _vm->_screenWidth);
    286225                _frameNum++;
    287226        } else {
    288227                _omniTV = false;
    289                 close();
     228                closeFile();
    290229                _vm->_variableArray[254] = 6747;
    291230        }
    292231}
     
    332271        }
    333272}
    334273
    335 void MoviePlayer::copyFrame(byte *dst, uint x, uint y) {
    336         uint h = _height;
    337         uint w = _width;
     274void MoviePlayer::setPalette(byte *pal) {
     275        byte palette[1024];
     276        byte *p = palette;
    338277
    339         dst += y * _vm->_screenWidth + x;
    340         byte *src = _frameBuffer1;
    341 
    342         do {
    343                 memcpy(dst, src, w);
    344                 dst += _vm->_screenWidth;
    345                 src += _width;
    346         } while (--h);
    347 }
    348 
    349 void MoviePlayer::decodeZlib(uint8 *data, int size, int totalSize) {
    350 #ifdef USE_ZLIB
    351         uint8 *temp = (uint8 *)malloc(size);
    352         if (temp) {
    353                 memcpy(temp, data, size);
    354         z_stream d_stream;
    355         d_stream.zalloc = (alloc_func)0;
    356         d_stream.zfree = (free_func)0;
    357         d_stream.opaque = (voidpf)0;
    358         d_stream.next_in = temp;
    359         d_stream.avail_in = size;
    360         d_stream.total_in = size;
    361         d_stream.next_out = data;
    362         d_stream.avail_out = totalSize;
    363         inflateInit(&d_stream);
    364         inflate(&d_stream, Z_FINISH);
    365         inflateEnd(&d_stream);
    366                 free(temp);
     278        for (int i = 0; i <= 256; i++) {
     279                *p++ = *pal++;
     280                *p++ = *pal++;
     281                *p++ = *pal++;
     282                *p++ = 0;
    367283        }
    368 #endif
    369 }
    370284
    371 void MoviePlayer::decodeFrame() {
    372         uint32 tag;
    373 
    374         tag = _fd.readUint32BE();
    375         if (tag == MKID_BE('CMAP')) {
    376                 uint8 rgb[768];
    377                 byte palette[1024];
    378                 byte *p = palette;
    379 
    380                 _fd.read(rgb, ARRAYSIZE(rgb));
    381                 for (int i = 0; i <= 256; i++) {
    382                         *p++ = rgb[i * 3 + 0];
    383                         *p++ = rgb[i * 3 + 1];
    384                         *p++ = rgb[i * 3 + 2];
    385                         *p++ = 0;
    386                 }
    387                 _vm->_system->setPalette(palette, 0, 256);
    388         }
    389 
    390         tag = _fd.readUint32BE();
    391         if (tag == MKID_BE('FRAM')) {
    392                 uint8 type = _fd.readByte();
    393                 uint32 size = _fd.readUint32BE();
    394                 debug(5, "frame %d type %d size %d", _frameNum, type, size);
    395 
    396                 _fd.read(_frameBuffer2, size);
    397 
    398                 switch (type) {
    399                 case 2:
    400                 case 3:
    401                         decodeZlib(_frameBuffer2, size, _frameSize);
    402                         break;
    403                 default:
    404                         error("decodeFrame: Unknown compression type %d", type);
    405                 }
    406                 if (type == 2) {
    407                         memcpy(_frameBuffer1, _frameBuffer2, _frameSize);
    408                 } else {
    409                         for (int j = 0; j < _height; ++j) {
    410                                 for (int i = 0; i < _width; ++i) {
    411                                         const int offs = j * _width + i;
    412                                         _frameBuffer1[offs] ^= _frameBuffer2[offs];
    413                                 }
    414                         }
    415                 }
    416         }
     285        _vm->_system->setPalette(palette, 0, 256);
    417286}
    418287
    419288void MoviePlayer::processFrame() {
    420         copyFrame(_vm->getFrontBuf(), (_vm->_screenWidth - _width) / 2, (_vm->_screenHeight - _height) / 2);
     289        copyFrame(_vm->getFrontBuf(), (_vm->_screenWidth - _width) / 2, (_vm->_screenHeight - _height) / 2, _vm->_screenWidth);
    421290        _vm->_system->copyRectToScreen(_vm->getFrontBuf(), _vm->_screenWidth, 0, 0, _vm->_screenWidth, _vm->_screenHeight);
    422291
    423292        if ((_bgSoundStream == NULL) || ((int)(_mixer->getSoundElapsedTime(_bgSound) * _framesPerSec) / 1000 < _frameNum + 1) ||
  • graphics/animation.cpp

     
    2121 */
    2222
    2323#include "common/stdafx.h"
     24#include "common/endian.h"
    2425#include "graphics/animation.h"
    2526#include "sound/audiostream.h"
    2627#include "common/config-manager.h"
     
    2930#include "common/util.h"
    3031#include "graphics/scaler/intern.h"
    3132
     33#ifdef USE_ZLIB
     34#include <zlib.h>
     35#endif
     36
    3237namespace Graphics {
    3338
    3439BaseAnimationState::BaseAnimationState(Audio::Mixer *snd, OSystem *sys, int width, int height)
     
    680685        _sys->updateScreen();
    681686}
    682687
     688DXAPlayer::DXAPlayer() {
     689        _frameBuffer1 = 0;
     690        _frameBuffer2 = 0;
     691
     692        _width = 0;
     693        _height = 0;
     694
     695        _frameSize = 0;
     696        _framesCount = 0;
     697        _frameNum = 0;
     698        _framesPerSec = 0;
     699        _frameSkipped = 0;
     700        _frameTicks = 0;
     701}
     702
     703DXAPlayer::~DXAPlayer() {
     704}
     705
     706int DXAPlayer::getWidth() {
     707        if (_fd.isOpen() == false)
     708                return 0;
     709        return _width;
     710}
     711
     712int DXAPlayer::getHeight() {
     713        if (_fd.isOpen() == false)
     714                return 0;
     715        return _height;
     716}
     717
     718int DXAPlayer::getCurFrame() {
     719        if (_fd.isOpen() == false)
     720                return -1;
     721        return _frameNum;
     722}
     723
     724int DXAPlayer::getFrameCount() {
     725        if (_fd.isOpen() == false)
     726                return 0;
     727        return _framesCount;
     728}
     729
     730bool DXAPlayer::loadFile(const char *filename) {
     731        uint32 tag;
     732        int32 frameRate;
     733
     734        if (!_fd.open(filename)) {
     735                return 0;
     736        }
     737
     738        tag = _fd.readUint32BE();
     739        assert(tag == MKID_BE('DEXA'));
     740
     741        _fd.readByte();
     742        _framesCount = _fd.readUint16BE();
     743        frameRate = _fd.readUint32BE();
     744
     745        if (frameRate > 0)
     746                _framesPerSec = 1000 / frameRate;
     747        else if (frameRate < 0)
     748                _framesPerSec = 100000 / (-frameRate);
     749        else
     750                _framesPerSec = 10;
     751
     752        if (frameRate < 0)
     753                _frameTicks = -frameRate / 100;
     754        else
     755                _frameTicks = frameRate;
     756
     757        _width = _fd.readUint16BE();
     758        _height = _fd.readUint16BE();
     759        debug(0, "frames_count %d width %d height %d rate %d ticks %d", _framesCount, _width, _height, _framesPerSec, _frameTicks);
     760
     761        _frameSize = _width * _height;
     762        _frameBuffer1 = (uint8 *)malloc(_frameSize);
     763        _frameBuffer2 = (uint8 *)malloc(_frameSize);
     764        if (!_frameBuffer1 || !_frameBuffer2) {
     765                error("error allocating frame tables, size %d\n", _frameSize);
     766        }
     767
     768        _frameNum = 0;
     769        _frameSkipped = 0;
     770
     771        return true;
     772}
     773
     774void DXAPlayer::closeFile() {
     775        if (_fd.isOpen() == false)
     776                return;
     777
     778        _fd.close();
     779        free(_frameBuffer1);
     780        free(_frameBuffer2);
     781}
     782
     783void DXAPlayer::copyFrame(byte *dst, uint x, uint y, uint pitch) {
     784        uint h = _height;
     785        uint w = _width;
     786
     787        dst += y * pitch + x;
     788        byte *src = _frameBuffer1;
     789
     790        do {
     791                memcpy(dst, src, w);
     792                dst += pitch;
     793                src += _width;
     794        } while (--h);
     795}
     796
     797void DXAPlayer::decodeZlib(byte *data, int size, int totalSize) {
     798#ifdef USE_ZLIB
     799        byte *temp = (byte *)malloc(size);
     800        if (temp) {
     801                memcpy(temp, data, size);
     802
     803                z_stream d_stream;
     804                d_stream.zalloc = (alloc_func)0;
     805                d_stream.zfree = (free_func)0;
     806                d_stream.opaque = (voidpf)0;
     807                d_stream.next_in = temp;
     808                d_stream.avail_in = size;
     809                d_stream.total_in = size;
     810                d_stream.next_out = data;
     811                d_stream.avail_out = totalSize;
     812                inflateInit(&d_stream);
     813                inflate(&d_stream, Z_FINISH);
     814                inflateEnd(&d_stream);
     815                free(temp);
     816        }
     817#endif
     818}
     819
     820#define BLOCKW 4
     821#define BLOCKH 4
     822
     823void DXAPlayer::decode12(byte *data, int size, int totalSize) {
     824#ifdef USE_ZLIB
     825        /* decompress the input data */
     826        decodeZlib(data, size, totalSize);
     827
     828        byte *dat = data;
     829        byte *frame2 = (byte *)malloc(totalSize);
     830
     831        memcpy(frame2, _frameBuffer1, totalSize);
     832
     833        for (int by = 0; by < _height; by += BLOCKH) {
     834                for (int bx = 0; bx < _width; bx += BLOCKW) {
     835                        byte type = *dat++;
     836                        byte *b2 = frame2 + bx + by * _width;
     837
     838                        switch (type) {
     839                        case 0:
     840                                break;
     841                        case 10:
     842                        case 11:
     843                        case 12:
     844                        case 13:
     845                        case 14:
     846                        case 15:
     847                        case 1: {
     848                                unsigned short diffMap;
     849                                if (type >= 10 && type <= 15) {
     850                                        static const struct { uint8 sh1, sh2; } shiftTbl[6] = {
     851                                                {0, 0}, {8, 0}, {8, 8}, {8, 4}, {4, 0}, {4, 4}
     852                                        };
     853                                        diffMap = ((*dat & 0xF0) << shiftTbl[type-10].sh1) |
     854                                                  ((*dat & 0x0F) << shiftTbl[type-10].sh2);
     855                                        dat++;
     856                                } else {
     857                                        diffMap = *(unsigned short*)dat;
     858                                        dat += 2;
     859                                }
     860
     861                                for (int yc = 0; yc < BLOCKH; yc++) {
     862                                        for (int xc = 0; xc < BLOCKW; xc++) {
     863                                                if (diffMap & 0x8000) {
     864                                                        b2[xc] = *dat++;
     865                                                }
     866                                                diffMap <<= 1;
     867                                        }
     868                                        b2 += _width;
     869                                }
     870                                break;
     871                        }
     872                        case 2: {
     873                                byte color = *dat++;
     874
     875                                for (int yc = 0; yc < BLOCKH; yc++) {
     876                                        for (int xc = 0; xc < BLOCKW; xc++) {
     877                                                b2[xc] = color;
     878                                        }
     879                                        b2 += _width;
     880                                }
     881                                break;
     882                        }
     883                        case 3: {
     884                                for (int yc = 0; yc < BLOCKH; yc++) {
     885                                        for (int xc = 0; xc < BLOCKW; xc++) {
     886                                                b2[xc] = *dat++;
     887                                        }
     888                                        b2 += _width;
     889                                }
     890                                break;
     891                        }
     892                        case 4: {
     893                                byte mbyte = *dat++;
     894                                int mx = (mbyte >> 4) & 0x07;
     895                                if (mbyte & 0x80)
     896                                        mx = -mx;
     897                                int my = mbyte & 0x07;
     898                                if (mbyte & 0x08)
     899                                        my = -my;
     900                                byte *b1 = _frameBuffer1 + (bx+mx) + (by+my) * _width;
     901                                for (int yc = 0; yc < BLOCKH; yc++) {
     902                                        memcpy(b2, b1, BLOCKW);
     903                                        b1 += _width;
     904                                        b2 += _width;
     905                                }
     906                                break;
     907                        }
     908                        case 5:
     909                                break;
     910                        }
     911                }
     912        }
     913
     914        memcpy(data, frame2, totalSize);
     915        free(frame2);
     916#endif
     917}
     918
     919void DXAPlayer::decodeFrame() {
     920        uint32 tag;
     921
     922        tag = _fd.readUint32BE();
     923        if (tag == MKID_BE('CMAP')) {
     924                byte rgb[768];
     925
     926                _fd.read(rgb, ARRAYSIZE(rgb));
     927                setPalette(rgb);
     928        }
     929
     930        tag = _fd.readUint32BE();
     931        if (tag == MKID_BE('FRAM')) {
     932                byte type = _fd.readByte();
     933                uint32 size = _fd.readUint32BE();
     934
     935                _fd.read(_frameBuffer2, size);
     936
     937                switch (type) {
     938                case 2:
     939                case 3:
     940                        decodeZlib(_frameBuffer2, size, _frameSize);
     941                        break;
     942                case 12:
     943                        decode12(_frameBuffer2, size, _frameSize);
     944                        break;
     945                default:
     946                        error("decodeFrame: Unknown compression type %d", type);
     947                }
     948                if (type == 2 || type == 4 || type == 6 || type == 12) {
     949                        memcpy(_frameBuffer1, _frameBuffer2, _frameSize);
     950                } else {
     951                        for (int j = 0; j < _height; ++j) {
     952                                for (int i = 0; i < _width; ++i) {
     953                                        const int offs = j * _width + i;
     954                                        _frameBuffer1[offs] ^= _frameBuffer2[offs];
     955                                }
     956                        }
     957                }
     958        }
     959}
     960
    683961} // End of namespace Graphics
  • graphics/animation.h

     
    2424#define GRAPHICS_ANIMATION_H
    2525
    2626#include "common/scummsys.h"
     27#include "common/file.h"
     28
    2729#include "sound/mixer.h"
    2830
    2931namespace Audio {
     
    156158#endif
    157159};
    158160
     161class DXAPlayer {
     162protected:
     163        Common::File _fd;
    159164
     165        byte *_frameBuffer1;
     166        byte *_frameBuffer2;
     167        uint16 _width;
     168        uint16 _height;
     169        uint16 _framesCount;
     170        uint32 _framesPerSec;
     171        uint16 _frameNum;
     172        uint32 _frameSize;
     173        uint16 _frameSkipped;
     174        uint32 _frameTicks;
     175
     176public:
     177        DXAPlayer();
     178        virtual ~DXAPlayer();
     179
     180        int getWidth();
     181        int getHeight();
     182        int getCurFrame();
     183        int getFrameCount();
     184
     185        bool loadFile(const char *filename);
     186        void closeFile();
     187
     188protected:
     189        virtual void setPalette(byte *pal) = 0;
     190
     191        void copyFrame(byte *dst, uint x, uint y, uint pitch);
     192        void decodeFrame();
     193        void decodeZlib(byte *data, int size, int totalSize);
     194        void decode12(byte *data, int size, int totalSize);
     195};
     196 
    160197} // End of namespace Graphics
    161198
    162199#endif