Logo Search packages:      
Sourcecode: scummvm version File versions

scenery_v1.cpp

/* ScummVM - Scumm Interpreter
 * Copyright (C) 2004 Ivan Dubrov
 * Copyright (C) 2004-2006 The ScummVM project
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.      See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * $URL: https://svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-0-9-1/engines/gob/scenery_v1.cpp $
 * $Id: scenery_v1.cpp 23847 2006-09-09 14:36:20Z chrilith $
 *
 */

#include "common/stdafx.h"
#include "common/endian.h"

#include "gob/gob.h"
#include "gob/scenery.h"
#include "gob/anim.h"
#include "gob/draw.h"
#include "gob/game.h"

namespace Gob {

Scenery_v1::Scenery_v1(GobEngine *vm) : Scenery(vm) {
}

// flags & 1 - do capture all area animation is occupying
// flags & 4 == 0 - calculate animation final size
// flags & 2 != 0 - don't check with "toRedraw"'s
// flags & 4 != 0 - checkk view toRedraw
void Scenery_v1::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
          int16 drawDeltaX, int16 drawDeltaY, char doDraw) {
      AnimLayer *layerPtr;
      PieceDesc **pictPtr;

      uint16 pieceIndex;
      uint16 pictIndex;

      int16 curFrame;

      int16 left;
      int16 right;
      int16 top;
      int16 bottom;

      byte highX;
      byte highY;

      int16 i;
      int16 transp;

      int16 destX;
      int16 destY;

      if (layer >= _animations[animation].layersCount)
            return;

      layerPtr = &_animations[animation].layers[layer];

      if (frame >= layerPtr->framesCount)
            return;

      if (flags & 1)          // Do capture
      {
            updateAnim(layer, frame, animation, 0, drawDeltaX,
                drawDeltaY, 0);

            if (_toRedrawLeft == -12345)  // Some magic number?
                  return;

            _vm->_game->capturePush(_toRedrawLeft, _toRedrawTop,
                _toRedrawRight - _toRedrawLeft + 1,
                _toRedrawBottom - _toRedrawTop + 1);

            *_pCaptureCounter = *_pCaptureCounter + 1;
      }
      pictPtr = _animations[animation].pieces;
      curFrame = 0;

      for (i = 0; i < frame; i++, curFrame++) {
            while (layerPtr->frames[curFrame].notFinal == 1)
                  curFrame++;
      }

      if ((flags & 4) == 0) {
            _toRedrawLeft = -12345;
      } else {
            _toRedrawLeft =
                MAX(_toRedrawLeft, _vm->_anim->_areaLeft);
            _toRedrawTop =
                MAX(_toRedrawTop, _vm->_anim->_areaTop);
            _toRedrawRight =
                MIN(_toRedrawRight,
                (int16)(_vm->_anim->_areaLeft + _vm->_anim->_areaWidth - 1));
            _toRedrawBottom =
                MIN(_toRedrawBottom,
                (int16)(_vm->_anim->_areaTop + _vm->_anim->_areaHeight - 1));
      }

      transp = layerPtr->transp ? 3 : 0;

      curFrame--;
      do {
            curFrame++;

            pieceIndex = layerPtr->frames[curFrame].pieceIndex;
            pictIndex = layerPtr->frames[curFrame].pictIndex;

            destX = layerPtr->frames[curFrame].destX;
            destY = layerPtr->frames[curFrame].destY;

            highX = pictIndex & 0xc0;
            highY = pictIndex & 0x30;
            highX >>= 6;
            highY >>= 4;
            if (destX >= 0)
                  destX += ((uint16)highX) << 7;
            else
                  destX -= ((uint16)highX) << 7;

            if (destY >= 0)
                  destY += ((uint16)highY) << 7;
            else
                  destY -= ((uint16)highY) << 7;

            if (drawDeltaX == 1000)
                  destX += layerPtr->posX;
            else
                  destX += drawDeltaX;

            if (drawDeltaY == 1000)
                  destY += layerPtr->posY;
            else
                  destY += drawDeltaY;

            pictIndex = (pictIndex & 15) - 1;

            left = READ_LE_UINT16(&pictPtr[pictIndex][pieceIndex].left);
            right = READ_LE_UINT16(&pictPtr[pictIndex][pieceIndex].right);
            top = READ_LE_UINT16(&pictPtr[pictIndex][pieceIndex].top);
            bottom = READ_LE_UINT16(&pictPtr[pictIndex][pieceIndex].bottom);

            if (flags & 2) {
                  if (destX < _vm->_anim->_areaLeft) {
                        left += _vm->_anim->_areaLeft - destX;
                        destX = _vm->_anim->_areaLeft;
                  }

                  if (left <= right
                      && destX + right - left >=
                      _vm->_anim->_areaLeft + _vm->_anim->_areaWidth)
                        right -=
                            (destX + right - left) -
                            (_vm->_anim->_areaLeft + _vm->_anim->_areaWidth) +
                            1;

                  if (destY < _vm->_anim->_areaTop) {
                        top += _vm->_anim->_areaTop - destY;
                        destY = _vm->_anim->_areaTop;
                  }

                  if (top <= bottom
                      && destY + bottom - top >=
                      _vm->_anim->_areaTop + _vm->_anim->_areaHeight)
                        bottom -=
                            (destY + bottom - top) -
                            (_vm->_anim->_areaTop + _vm->_anim->_areaHeight) +
                            1;

            } else if (flags & 4) {
                  if (destX < _toRedrawLeft) {
                        left += _toRedrawLeft - destX;
                        destX = _toRedrawLeft;
                  }

                  if (left <= right
                      && destX + right - left > _toRedrawRight)
                        right -=
                            destX + right - left - _toRedrawRight;

                  if (destY < _toRedrawTop) {
                        top += _toRedrawTop - destY;
                        destY = _toRedrawTop;
                  }

                  if (top <= bottom
                      && destY + bottom - top > _toRedrawBottom)
                        bottom -=
                            destY + bottom - top - _toRedrawBottom;
            }

            if (left > right || top > bottom)
                  continue;

            if (doDraw) {
                  _vm->_draw->_sourceSurface =
                      _animPictToSprite[animation * 7 + pictIndex];
                  _vm->_draw->_destSurface = 21;

                  _vm->_draw->_spriteLeft = left;
                  _vm->_draw->_spriteTop = top;
                  _vm->_draw->_spriteRight = right - left + 1;
                  _vm->_draw->_spriteBottom = bottom - top + 1;
                  _vm->_draw->_destSpriteX = destX;
                  _vm->_draw->_destSpriteY = destY;
                  _vm->_draw->_transparency = transp;
                  _vm->_draw->spriteOperation(DRAW_BLITSURF);
            }

            if ((flags & 4) == 0) {
                  if (_toRedrawLeft == -12345) {
                        _toRedrawLeft = destX;
                        _animLeft = destX;
                        _toRedrawTop = destY;
                        _animTop = destY;
                        _toRedrawRight = destX + right - left;
                        _toRedrawBottom = destY + bottom - top;
                  } else {
                        _toRedrawLeft =
                            MIN(_toRedrawLeft, destX);
                        _toRedrawTop =
                            MIN(_toRedrawTop, destY);
                        _toRedrawRight =
                            MAX(_toRedrawRight,
                            (int16)(destX + right - left));
                        _toRedrawBottom =
                            MAX(_toRedrawBottom,
                            (int16)(destY + bottom - top));
                  }
            }
      } while (layerPtr->frames[curFrame].notFinal == 1);
}

} // End of namespace Gob

Generated by  Doxygen 1.6.0   Back to index