Ticket #8594: dxa_update.diff

File dxa_update.diff, 8.2 KB (added by Kirben, 17 years ago)

Patch for ScummVM SVN

  • graphics/dxa_player.cpp

     
    3434DXAPlayer::DXAPlayer() {
    3535        _frameBuffer1 = 0;
    3636        _frameBuffer2 = 0;
     37        _scaledBuffer = 0;
    3738
    3839        _width = 0;
    3940        _height = 0;
     
    4445        _framesPerSec = 0;
    4546        _frameSkipped = 0;
    4647        _frameTicks = 0;
     48
     49        _scaleMode = S_NONE;
    4750}
    4851
    4952DXAPlayer::~DXAPlayer() {
     
    8487        tag = _fd.readUint32BE();
    8588        assert(tag == MKID_BE('DEXA'));
    8689
    87         _fd.readByte();
     90        uint8 flags = _fd.readByte();
    8891        _framesCount = _fd.readUint16BE();
    8992        frameRate = _fd.readUint32BE();
    9093
     
    103106        _width = _fd.readUint16BE();
    104107        _height = _fd.readUint16BE();
    105108
     109        if (flags & 0x80) {
     110                _scaleMode = S_INTERLACED;
     111                _curHeight = _height / 2;
     112        } else if (flags & 0x40) {
     113                _scaleMode = S_DOUBLE;
     114                _curHeight = _height / 2;
     115        } else {
     116                _scaleMode = S_NONE;
     117                _curHeight = _height;
     118        }
     119               
    106120        debug(2, "frames_count %d width %d height %d rate %d ticks %d", _framesCount, _width, _height, _framesPerSec, _frameTicks);
    107121
    108122        _frameSize = _width * _height;
    109123        _frameBuffer1 = (uint8 *)malloc(_frameSize);
    110124        _frameBuffer2 = (uint8 *)malloc(_frameSize);
    111         if (!_frameBuffer1 || !_frameBuffer2) {
    112                 error("error allocating frame tables, size %d\n", _frameSize);
     125        if (!_frameBuffer1 || !_frameBuffer2)
     126                error("Error allocating frame buffers (size %d)", _frameSize);
     127
     128        if (_scaleMode != S_NONE) {
     129                _scaledBuffer = (uint8 *)malloc(_frameSize);
     130                if (_scaledBuffer)
     131                        error("Error allocating scale buffer (size %d)", _frameSize);
    113132        }
    114133
    115134        _frameNum = 0;
     
    125144        _fd.close();
    126145        free(_frameBuffer1);
    127146        free(_frameBuffer2);
     147        free(_scaledBuffer);
    128148}
    129149
    130150void DXAPlayer::copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch) {
     151        byte *src;
     152
     153        switch (_scaleMode) {
     154        case S_INTERLACED:
     155                memset(_scaledBuffer, 0, _width * _height);
     156                for (int cy = 0; cy < _curHeight; cy++)
     157                        memcpy(&_scaledBuffer[2 * cy * _width], &_frameBuffer1[cy * _width], _width);
     158                src = _scaledBuffer;
     159                break;
     160        case S_DOUBLE:
     161                for (int cy = 0; cy < _curHeight; cy++) {
     162                        memcpy(&_scaledBuffer[2 * cy * _width], &_frameBuffer1[cy * _width], _width);
     163                        memcpy(&_scaledBuffer[((2 * cy) + 1) * _width], &_frameBuffer1[cy * _width], _width);
     164                }
     165                src = _scaledBuffer;
     166                break;
     167        case S_NONE:
     168                src = _frameBuffer1;
     169                break;
     170        }
     171
    131172        uint h = _height;
    132173        uint w = _width;
    133174
    134175        dst += y * pitch + x;
    135         byte *src = _frameBuffer1;
    136176
    137177        do {
    138178                memcpy(dst, src, w);
     
    254294                        }
    255295                        case 5:
    256296                                break;
     297                        default:
     298                                error("decode12: Unknown type %d", type);
    257299                        }
    258300                }
    259301        }
     
    263305#endif
    264306}
    265307
     308void DXAPlayer::decode13(uint8 *data, int size, int totalSize) {
     309#ifdef USE_ZLIB
     310        uint8 *codeBuf, *dataBuf, *motBuf, *maskBuf;
     311
     312        /* decompress the input data */
     313        decodeZlib(data, size, totalSize);
     314
     315        uint8 *frame2 = (uint8*)malloc(totalSize);
     316        memcpy(frame2, _frameBuffer1, totalSize);
     317
     318        int codeSize = _width * _curHeight / 16;
     319        int dataSize, motSize, maskSize;
     320        memcpy(&dataSize, data, 4);
     321        memcpy(&motSize, &data[4], 4);
     322        memcpy(&maskSize, &data[8], 4);
     323
     324        codeBuf = &data[12];
     325        dataBuf = &codeBuf[codeSize];
     326        motBuf = &dataBuf[dataSize];
     327        maskBuf = &motBuf[motSize];
     328
     329        for (int by = 0; by < _curHeight; by += BLOCKH) {
     330                for (int bx = 0; bx < _width; bx += BLOCKW) {
     331                        uint8 type = *codeBuf++;
     332                        uint8 *b2 = (uint8*)frame2 + bx + by * _width;
     333
     334                        switch (type) {
     335                        case 0:
     336                                break;
     337
     338                        case 1: {
     339                                uint16 diffMap = *(unsigned short*)maskBuf;
     340                                maskBuf += 2;
     341
     342                                for (int yc = 0; yc < BLOCKH; yc++) {
     343                                        for (int xc = 0; xc < BLOCKW; xc++) {
     344                                                if (diffMap & 0x8000) {
     345                                                        b2[xc] = *dataBuf++;
     346                                                }
     347                                                diffMap <<= 1;
     348                                        }
     349                                        b2 += _width;
     350                                }
     351                                break;
     352                        }
     353                        case 2: {
     354                                uint8 color = *dataBuf++;
     355
     356                                for (int yc = 0; yc < BLOCKH; yc++) {
     357                                        for (int xc = 0; xc < BLOCKW; xc++) {
     358                                                b2[xc] = color;
     359                                        }
     360                                        b2 += _width;
     361                                }
     362                                break;
     363                        }
     364                        case 3: {
     365                                for (int yc = 0; yc < BLOCKH; yc++) {
     366                                        for (int xc = 0; xc < BLOCKW; xc++) {
     367                                                b2[xc] = *dataBuf++;
     368                                        }
     369                                        b2 += _width;
     370                                }
     371                                break;
     372                        }
     373                        case 4: {
     374                                uint8 mbyte = *motBuf++;
     375
     376                                int mx = (mbyte >> 4) & 0x07;
     377                                if (mbyte & 0x80)
     378                                        mx = -mx;
     379                                int my = mbyte & 0x07;
     380                                if (mbyte & 0x08)
     381                                        my = -my;
     382
     383                                uint8 *b1 = (uint8*)_frameBuffer1 + (bx+mx) + (by+my) * _width;
     384                                for (int yc = 0; yc < BLOCKH; yc++) {
     385                                        memcpy(b2, b1, BLOCKW);
     386                                        b1 += _width;
     387                                        b2 += _width;
     388                                }
     389                                break;
     390                        }
     391                        case 8: {
     392                                static const int subX[4] = {0, 2, 0, 2};
     393                                static const int subY[4] = {0, 0, 2, 2};
     394
     395                                uint8 subMask = *maskBuf++;
     396
     397                                for (int subBlock = 0; subBlock < 4; subBlock++) {
     398                                        int sx = bx + subX[subBlock], sy = by + subY[subBlock];
     399                                        b2 = (uint8*)frame2 + sx + sy * _width;
     400                                        switch (subMask & 0xC0) {
     401                                        // 00: skip
     402                                        case 0x00:
     403                                                break;
     404                                        // 01: solid color
     405                                        case 0x40: {
     406                                                uint8 subColor = *dataBuf++;
     407                                                for (int yc = 0; yc < BLOCKH / 2; yc++) {
     408                                                        for (int xc = 0; xc < BLOCKW / 2; xc++) {
     409                                                                b2[xc] = subColor;
     410                                                        }
     411                                                        b2 += _width;
     412                                                }
     413                                                break;
     414                                        }
     415                                        // 02: motion vector
     416                                        case 0x80: {
     417                                                uint8 mbyte = *motBuf++;
     418
     419                                                int mx = (mbyte >> 4) & 0x07;
     420                                                if (mbyte & 0x80)
     421                                                        mx = -mx;
     422
     423                                                int my = mbyte & 0x07;
     424                                                if (mbyte & 0x08)
     425                                                        my = -my;
     426
     427                                                uint8 *b1 = (uint8*)_frameBuffer1 + (sx+mx) + (sy+my) * _width;
     428                                                for (int yc = 0; yc < BLOCKH / 2; yc++) {
     429                                                        memcpy(b2, b1, BLOCKW / 2);
     430                                                        b1 += _width;
     431                                                        b2 += _width;
     432                                                }
     433                                                break;
     434                                        }
     435                                        // 03: raw
     436                                        case 0xC0:
     437                                                for (int yc = 0; yc < BLOCKH / 2; yc++) {
     438                                                        for (int xc = 0; xc < BLOCKW / 2; xc++) {
     439                                                                b2[xc] = *dataBuf++;
     440                                                        }
     441                                                        b2 += _width;
     442                                                }
     443                                                break;
     444                                        }
     445                                        subMask <<= 2;
     446                                }
     447                        break;
     448                        }
     449                        case 32:
     450                        case 33:
     451                        case 34: {
     452                                int count = type - 30;
     453                                uint8 pixels[4];
     454
     455                                for (int i = 0; i < count; i++)
     456                                        pixels[i] = *dataBuf++;
     457
     458                                if (count == 2) {
     459                                        uint16 code = *(uint16*)maskBuf;
     460                                        maskBuf += 2;
     461                                        for (int yc = 0; yc < BLOCKH; yc++) {
     462                                                for (int xc = 0; xc < BLOCKW; xc++) {
     463                                                        b2[xc] = pixels[code & 1];
     464                                                        code >>= 1;
     465                                                }
     466                                                b2 += _width;
     467                                        }
     468                                } else {
     469                                        uint32 code = *(uint32*)maskBuf;
     470                                        maskBuf += 4;
     471                                        for (int yc = 0; yc < BLOCKH; yc++) {
     472                                                for (int xc = 0; xc < BLOCKW; xc++) {
     473                                                        b2[xc] = pixels[code & 3];
     474                                                        code >>= 2;
     475                                                }
     476                                                b2 += _width;
     477                                        }
     478                                }
     479                                break;
     480                        }
     481                        default:
     482                                error("decode13: Unknown type %d", type);
     483                        }
     484                }
     485        }
     486
     487        memcpy(data, frame2, totalSize);
     488        free(frame2);
     489#endif
     490}
     491
    266492void DXAPlayer::decodeNextFrame() {
    267493        uint32 tag;
    268494
     
    289515                case 12:
    290516                        decode12(_frameBuffer2, size, _frameSize);
    291517                        break;
     518                case 13:
     519                        decode13(_frameBuffer2, size, _frameSize);
     520                        break;
    292521                default:
    293522                        error("decodeFrame: Unknown compression type %d", type);
    294523                }
    295                 if (type == 2 || type == 4 || type == 12) {
     524                if (type == 2 || type == 4 || type == 12 || type == 13) {
    296525                        memcpy(_frameBuffer1, _frameBuffer2, _frameSize);
    297526                } else {
    298527                        for (int j = 0; j < _height; ++j) {
  • graphics/dxa_player.h

     
    3232
    3333namespace Graphics {
    3434
     35enum ScaleMode {
     36        S_NONE,
     37        S_INTERLACED,
     38        S_DOUBLE
     39};
     40
    3541class DXAPlayer {
    3642protected:
    3743        Common::File _fd;
    3844
    3945        byte *_frameBuffer1;
    4046        byte *_frameBuffer2;
     47        byte *_scaledBuffer;
    4148        uint16 _width;
    42         uint16 _height;
     49        uint16 _height, _curHeight;
    4350        uint16 _framesCount;
    4451        uint32 _framesPerSec;
    4552        uint16 _frameNum;
    4653        uint32 _frameSize;
    4754        uint16 _frameSkipped;
    4855        uint32 _frameTicks;
     56        ScaleMode _scaleMode;
    4957
    5058public:
    5159        DXAPlayer();
     
    110118
    111119        void decodeZlib(byte *data, int size, int totalSize);
    112120        void decode12(byte *data, int size, int totalSize);
     121        void decode13(byte *data, int size, int totalSize);
    113122};
    114123 
    115124} // End of namespace Graphics