diff options
Diffstat (limited to 'engines/gob/scenery.cpp')
-rw-r--r-- | engines/gob/scenery.cpp | 156 |
1 files changed, 154 insertions, 2 deletions
diff --git a/engines/gob/scenery.cpp b/engines/gob/scenery.cpp index 5979927dfa..3f9ec9e6f2 100644 --- a/engines/gob/scenery.cpp +++ b/engines/gob/scenery.cpp @@ -33,6 +33,8 @@ #include "gob/draw.h" #include "gob/game.h" #include "gob/inter.h" +#include "gob/map.h" +#include "gob/videoplayer.h" namespace Gob { @@ -454,6 +456,7 @@ int16 Scenery::loadAnim(char search) { ptr->layers = new AnimLayer[ptr->layersCount]; ptr->pieces = new PieceDesc*[picsCount]; ptr->piecesFromExt = new bool[picsCount]; + ptr->sizes = new uint16[picsCount]; for (i = 0; i < ptr->layersCount; i++) { int16 offset = READ_LE_UINT16(dataPtr + i * 2); @@ -492,13 +495,19 @@ int16 Scenery::loadAnim(char search) { for (i = 0; i < picsCount; i++) { pictDescId = _vm->_inter->load16(); if (pictDescId >= 30000) { + uint32 size; + ptr->pieces[i] = - (PieceDesc *) _vm->_game->loadExtData(pictDescId, 0, 0); + (PieceDesc *) _vm->_game->loadExtData(pictDescId, 0, 0, &size); ptr->piecesFromExt[i] = true; + ptr->sizes[i] = size / 8; } else { + int16 size; + ptr->pieces[i] = - (PieceDesc *) _vm->_game->loadTotResource(pictDescId); + (PieceDesc *) _vm->_game->loadTotResource(pictDescId, &size); ptr->piecesFromExt[i] = false; + ptr->sizes[i] = size / 8; } width = _vm->_inter->load16(); @@ -561,6 +570,7 @@ void Scenery::freeAnim(int16 index) { delete[] _animations[index].layers; delete[] _animations[index].pieces; delete[] _animations[index].piecesFromExt; + delete[] _animations[index].sizes; _animPictCount[index] = 0; } @@ -592,6 +602,138 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, int16 destX; int16 destY; + if (animation < 0) { + // Object video + + if (flags & 1) { // Do capture + updateAnim(layer, frame, animation, 0, drawDeltaX, drawDeltaY, 0); + + if (_toRedrawLeft == -12345) + return; + + _vm->_game->capturePush(_toRedrawLeft, _toRedrawTop, + _toRedrawRight - _toRedrawLeft + 1, + _toRedrawBottom - _toRedrawTop + 1); + + *_pCaptureCounter = *_pCaptureCounter + 1; + } + + Mult::Mult_Object &obj = _vm->_mult->_objects[-animation - 1]; + + if (!_vm->_vidPlayer->slotIsOpen(obj.videoSlot - 1)) { + _toRedrawLeft = -1234; + return; + } + + if (frame >= _vm->_vidPlayer->getFramesCount(obj.videoSlot - 1)) + frame = _vm->_vidPlayer->getFramesCount(obj.videoSlot - 1) - 1; + + // Seek to frame + while (_vm->_vidPlayer->getCurrentFrame(obj.videoSlot - 1) <= frame) + _vm->_vidPlayer->slotPlay(obj.videoSlot - 1); + + destX = 0; + destY = 0; + left = *(obj.pPosX); + top = *(obj.pPosY); + right = left + _vm->_vidPlayer->getWidth(obj.videoSlot - 1) - 1; + bottom = top + _vm->_vidPlayer->getHeight(obj.videoSlot - 1) - 1; + + if (flags & 2) { + if (left < _vm->_mult->_animLeft) { + destX += _vm->_mult->_animLeft - left; + left = _vm->_mult->_animLeft; + } + + if ((_vm->_mult->_animLeft + _vm->_mult->_animWidth) <= right) + right = _vm->_mult->_animLeft + _vm->_mult->_animWidth - 1; + + if (top < _vm->_mult->_animTop) { + destY += _vm->_mult->_animTop - top; + top = _vm->_mult->_animTop; + } + + if ((_vm->_mult->_animTop + _vm->_mult->_animHeight) <= bottom) + bottom = _vm->_mult->_animTop + _vm->_mult->_animHeight - 1; + + } else if (flags & 4) { + if (left < _toRedrawLeft) { + destX += _toRedrawLeft - left; + left = _toRedrawLeft; + } + + if (right > _toRedrawRight) + right = _toRedrawRight; + + if (top < _toRedrawTop) { + destY += _toRedrawTop - top; + top = _toRedrawTop; + } + + if (bottom > _toRedrawBottom) + bottom = _toRedrawBottom; + + } else { + _toRedrawTop = top; + _toRedrawLeft = left; + _toRedrawRight = right; + _toRedrawBottom = bottom; + } + + if (doDraw) { + if ((left > right) || (top > bottom)) + return; + + if (left < _vm->_mult->_animLeft) { + destX += _vm->_mult->_animLeft - left; + left = _vm->_mult->_animLeft; + } + + if ((_vm->_mult->_animLeft + _vm->_mult->_animWidth) <= right) + right = _vm->_mult->_animLeft + _vm->_mult->_animWidth - 1; + + if (top < _vm->_mult->_animTop) { + destY += _vm->_mult->_animTop - top; + top = _vm->_mult->_animTop; + } + + if ((_vm->_mult->_animTop + _vm->_mult->_animHeight) <= bottom) + bottom = _vm->_mult->_animTop + _vm->_mult->_animHeight - 1; + + _vm->_draw->_spriteLeft = destX; + _vm->_draw->_spriteTop = destY; + _vm->_draw->_spriteRight = right - left + 1; + _vm->_draw->_spriteBottom = bottom - top + 1; + _vm->_draw->_destSpriteX = left; + _vm->_draw->_destSpriteY = top; + _vm->_draw->_transparency = layer; + if (layer & 0x80) + _vm->_draw->_spriteLeft = _vm->_vidPlayer->getWidth(obj.videoSlot - 1) - + (destX + _vm->_draw->_spriteRight); + + _vm->_vidPlayer->slotCopyFrame(obj.videoSlot - 1, _vm->_draw->_backSurface->getVidMem(), + _vm->_draw->_spriteLeft, _vm->_draw->_spriteTop, + _vm->_draw->_spriteRight, _vm->_draw->_spriteBottom, + _vm->_draw->_destSpriteX, _vm->_draw->_destSpriteY, + _vm->_draw->_backSurface->getWidth(), + (_vm->_draw->_transparency != 0) ? 0 : -1); + + _vm->_draw->invalidateRect(_vm->_draw->_destSpriteX, _vm->_draw->_destSpriteY, + _vm->_draw->_destSpriteX + _vm->_draw->_spriteRight - 1, + _vm->_draw->_destSpriteY + _vm->_draw->_spriteBottom - 1); + + } + + if (flags & 4) { + _animLeft = _toRedrawLeft = left; + _animTop = _toRedrawTop = top; + _animRight = _toRedrawRight = right; + _animBottom = _toRedrawBottom = bottom; + } + + return; + } + if ((_animPictCount[animation] == 0) || (layer < 0)) return; if (layer >= _animations[animation].layersCount) @@ -670,6 +812,16 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, pictIndex = (pictIndex & 15) - 1; + if ((pictIndex == 0xFFFF) || (_animPictCount[animation] <= pictIndex)) { + warning("Scenery::updateAnim: pictIndex out of range"); + return; + } + + if (_animations[animation].sizes[pictIndex] <= pieceIndex) { + warning("Scenery::updateAnim: pieceIndex out of range"); + continue; + } + left = READ_LE_UINT16(&pictPtr[pictIndex][pieceIndex].left); right = READ_LE_UINT16(&pictPtr[pictIndex][pieceIndex].right); top = READ_LE_UINT16(&pictPtr[pictIndex][pieceIndex].top); |