diff options
author | Paul Gilbert | 2012-02-26 21:34:38 +1100 |
---|---|---|
committer | Paul Gilbert | 2012-02-26 21:34:38 +1100 |
commit | b341ff04faba379a524d941db0bcc918a9238b22 (patch) | |
tree | 1542ca469fc3940d1f551cd3c57e7043afd581da /engines | |
parent | d5127d49ee50e9b3cfb8bcc6643dfb81b49ca96b (diff) | |
download | scummvm-rg350-b341ff04faba379a524d941db0bcc918a9238b22.tar.gz scummvm-rg350-b341ff04faba379a524d941db0bcc918a9238b22.tar.bz2 scummvm-rg350-b341ff04faba379a524d941db0bcc918a9238b22.zip |
TSAGE: Implement R2R Animation Player drawing code
Diffstat (limited to 'engines')
-rw-r--r-- | engines/tsage/ringworld2/ringworld2_logic.cpp | 129 | ||||
-rw-r--r-- | engines/tsage/ringworld2/ringworld2_logic.h | 8 |
2 files changed, 117 insertions, 20 deletions
diff --git a/engines/tsage/ringworld2/ringworld2_logic.cpp b/engines/tsage/ringworld2/ringworld2_logic.cpp index 8a1030597a..37fbceb532 100644 --- a/engines/tsage/ringworld2/ringworld2_logic.cpp +++ b/engines/tsage/ringworld2/ringworld2_logic.cpp @@ -1555,7 +1555,7 @@ void AnimationSplice::load(Common::File &f) { _spliceOffset = f.readUint32LE(); f.skip(6); _drawMode = f.readByte(); - _fieldB = f.readByte(); + _secondaryIndex = f.readByte(); } /*--------------------------------------------------------------------------*/ @@ -1597,7 +1597,7 @@ void AnimationPlayerSubData::load(Common::File &f) { _fieldE = f.readUint16LE(); f.skip(2); _sliceSize = f.readUint16LE(); - _field14 = f.readUint16LE(); + _ySlices = f.readUint16LE(); _field16 = f.readUint16LE(); f.skip(4); _palStart = f.readUint16LE(); @@ -1700,7 +1700,7 @@ bool AnimationPlayer::load(int animId, Action *endAction) { if (_subData._field320) { _dataNeeded = _subData._field320; } else { - int v = (_subData._sliceSize + 2) * _subData._field14 * _subData._fieldC; + int v = (_subData._sliceSize + 2) * _subData._ySlices * _subData._fieldC; _dataNeeded = (_subData._field16 / _subData._fieldC) + v + 96; } @@ -1765,24 +1765,94 @@ bool AnimationPlayer::load(int animId, Action *endAction) { return true; } -void AnimationPlayer::drawFrame(int frameIndex) { -/* - uint32 v = READ_LE_UINT32(_dataP); -warning("v = %d", v); -//TODO +void AnimationPlayer::drawFrame(int spliceIndex) { + assert(spliceIndex < 4); + AnimationSplices &splices = _animData->_splices; + AnimationSplice &splice = _animData->_splices._splices[spliceIndex]; - // End check - if (_field56 == 42) { - _screenBounds.expandPanes(); + byte *sliceDataStart = &splices._pixelData[splice._spliceOffset]; + byte *sliceData1 = sliceDataStart; - R2_GLOBALS._sceneObjects->draw(); - } else { - if (R2_GLOBALS._sceneManager._hasPalette) { - R2_GLOBALS._sceneManager._hasPalette = false; - R2_GLOBALS._scenePalette.refresh(); + Rect playerBounds = _screenBounds; + int y = _screenBounds.top; + R2_GLOBALS._screenSurface.addDirtyRect(playerBounds); + + Graphics::Surface surface = R2_GLOBALS._screenSurface.lockSurface(); + + // Handle different drawing modes + switch (splice._drawMode) { + case 0: + // Draw from uncompressed source + for (int sliceNum = 0; sliceNum < _subData._ySlices; ++sliceNum) { + for (int yIndex = 0; yIndex < _sliceHeight; ++yIndex) { + // TODO: Check of _subData._fieldE was done for two different kinds of + // line slice drawing in original + const byte *pSrc = (const byte *)sliceDataStart + READ_LE_UINT16(sliceData1 + sliceNum * 2); + byte *pDest = (byte *)surface.getBasePtr(playerBounds.left, y++); + + Common::copy(pSrc, pSrc + _subData._sliceSize, pDest); + } } + break; + + case 1: + switch (splice._secondaryIndex) { + case 0xfe: + // Draw from uncompressed source with optional skipped rows + for (int sliceNum = 0; sliceNum < _subData._ySlices; ++sliceNum) { + for (int yIndex = 0; yIndex < _sliceHeight; ++yIndex) { + int offset = READ_LE_UINT16(sliceData1 + sliceNum * 2); + + if (offset) { + const byte *pSrc = (const byte *)sliceDataStart + offset; + byte *pDest = (byte *)surface.getBasePtr(playerBounds.left, y++); + + Common::copy(pSrc, pSrc + _subData._sliceSize, pDest); + } + } + } + break; + case 0xff: + // Draw from RLE compressed source + for (int sliceNum = 0; sliceNum < _subData._ySlices; ++sliceNum) { + for (int yIndex = 0; yIndex < _sliceHeight; ++yIndex) { + // TODO: Check of _subData._fieldE was done for two different kinds of + // line slice drawing in original + const byte *pSrc = (const byte *)sliceDataStart + READ_LE_UINT16(sliceData1 + sliceNum * 2); + byte *pDest = (byte *)surface.getBasePtr(playerBounds.left, y++); + + rleDecode(pSrc, pDest, _subData._sliceSize); + } + } + break; + default: { + // Draw from two splice sets simultaneously + AnimationSplice &splice2 = _animData->_splices._splices[splice._secondaryIndex]; + byte *sliceData2 = &splices._pixelData[splice2._spliceOffset]; + + for (int sliceNum = 0; sliceNum < _subData._ySlices; ++sliceNum) { + for (int yIndex = 0; yIndex < _sliceHeight; ++yIndex) { + const byte *pSrc1 = (const byte *)sliceDataStart + READ_LE_UINT16(sliceData2 + sliceNum * 2); + const byte *pSrc2 = (const byte *)sliceDataStart + READ_LE_UINT16(sliceData1 + sliceNum * 2); + byte *pDest = (byte *)surface.getBasePtr(playerBounds.left, y++); + + if (splice2._drawMode == 0) { + // Uncompressed background, foreground compressed + Common::copy(pSrc1, pSrc1 + _subData._sliceSize, pDest); + rleDecode(pSrc2, pDest, _subData._sliceSize); + } else { + // Both background and foreground is compressed + rleDecode(pSrc1, pDest, _subData._sliceSize); + rleDecode(pSrc2, pDest, _subData._sliceSize); + } + } + } + break; + } + } + default: + break; } -*/ } void AnimationPlayer::method2() { @@ -1813,6 +1883,31 @@ void AnimationPlayer::method4() { // TODO } +void AnimationPlayer::rleDecode(const byte *pSrc, byte *pDest, int size) { + while (size > 0) { + byte v = *pSrc++; + if (!(v & 0x80)) { + // Following uncompressed set of bytes + Common::copy(pSrc, pSrc + v, pDest); + pSrc += v; + pDest += v; + size -= v; + } else { + int count = v & 0x3F; + size -= count; + + if (!(v & 0x40)) { + // Skip over a number of bytes + pDest += count; + } else { + // Replicate a number of bytes + Common::fill(pDest, pDest + count, *pSrc++); + pDest += count; + } + } + } +} + /*--------------------------------------------------------------------------*/ AnimationPlayerExt::AnimationPlayerExt(): AnimationPlayer() { diff --git a/engines/tsage/ringworld2/ringworld2_logic.h b/engines/tsage/ringworld2/ringworld2_logic.h index 4ad0c3b15a..c575927827 100644 --- a/engines/tsage/ringworld2/ringworld2_logic.h +++ b/engines/tsage/ringworld2/ringworld2_logic.h @@ -331,7 +331,7 @@ class AnimationSplice { public: int _spliceOffset; int _drawMode; - int _fieldB; + int _secondaryIndex; public: void load(Common::File &f); }; @@ -356,7 +356,7 @@ public: int _fieldC; int _fieldE; int _sliceSize; - int _field14; + int _ySlices; int _field16; int _palStart; int _palSize; @@ -375,6 +375,8 @@ public: }; class AnimationPlayer: public EventHandler { +private: + void rleDecode(const byte *pSrc, byte *pDest, int size); public: AnimationData *_animData; AnimationData *_animData1, *_animData2; @@ -409,7 +411,7 @@ public: virtual void proc14() {} bool load(int animId, Action *endAction = NULL); - void drawFrame(int frameIndex); + void drawFrame(int spliceIndex); void method2(); bool method3(); void method4(); |