From 8a5c4a84d082074ad7aa47c5f797876b1cb7120f Mon Sep 17 00:00:00 2001 From: johndoe123 Date: Thu, 14 Jul 2011 08:20:40 +0000 Subject: NEVERHOOD: Implement color replace in AnimatedSprite (used to disable a color in sprite drawing) --- engines/neverhood/graphics.cpp | 45 ++++++++++++++++++++++++++++++++++++++++ engines/neverhood/graphics.h | 1 + engines/neverhood/module1000.cpp | 10 ++++----- engines/neverhood/resource.cpp | 15 ++++++++++---- engines/neverhood/resource.h | 6 ++++-- engines/neverhood/sprite.cpp | 35 +++++++++++++++++++------------ engines/neverhood/sprite.h | 6 ++++-- 7 files changed, 92 insertions(+), 26 deletions(-) diff --git a/engines/neverhood/graphics.cpp b/engines/neverhood/graphics.cpp index 68134bda97..b9e2c482a1 100644 --- a/engines/neverhood/graphics.cpp +++ b/engines/neverhood/graphics.cpp @@ -197,6 +197,51 @@ void unpackSpriteRle(byte *source, int width, int height, byte *dest, int destPi } +void unpackSpriteRleRepl(byte *source, int width, int height, byte *dest, int destPitch, byte oldColor, byte newColor, bool flipX, bool flipY) { + + // TODO: Flip Y + + debug("unpackSpriteRleRepl(%d, %d)", oldColor, newColor); + + int16 rows, chunks; + int16 skip, copy; + + rows = READ_LE_UINT16(source); + chunks = READ_LE_UINT16(source + 2); + source += 4; + + do { + if (chunks == 0) { + dest += rows * destPitch; + } else { + while (rows-- > 0) { + uint16 rowChunks = chunks; + while (rowChunks-- > 0) { + skip = READ_LE_UINT16(source); + copy = READ_LE_UINT16(source + 2); + source += 4; + if (!flipX) { + for (int xc = 0; xc < copy; xc++) { + dest[skip + xc] = source[xc] == oldColor ? newColor : source[xc]; + } + } else { + byte *flipDest = dest + width - skip - 1; + for (int xc = 0; xc < copy; xc++) { + *flipDest-- = source[xc] == oldColor ? newColor : source[xc]; + } + } + source += copy; + } + dest += destPitch; + } + } + rows = READ_LE_UINT16(source); + chunks = READ_LE_UINT16(source + 2); + source += 4; + } while (rows > 0); + +} + void unpackSpriteNormal(byte *source, int width, int height, byte *dest, int destPitch, bool flipX, bool flipY) { // TODO: Flip Y diff --git a/engines/neverhood/graphics.h b/engines/neverhood/graphics.h index 2bddea3156..9ac23a81f5 100644 --- a/engines/neverhood/graphics.h +++ b/engines/neverhood/graphics.h @@ -91,6 +91,7 @@ protected: void parseBitmapResource(byte *sprite, bool *rle, NDimensions *dimensions, NPoint *position, byte **palette, byte **pixels); void unpackSpriteRle(byte *source, int width, int height, byte *dest, int destPitch, bool flipX, bool flipY); +void unpackSpriteRleRepl(byte *source, int width, int height, byte *dest, int destPitch, byte oldColor, byte newColor, bool flipX, bool flipY); void unpackSpriteNormal(byte *source, int width, int height, byte *dest, int destPitch, bool flipX, bool flipY); } // End of namespace Neverhood diff --git a/engines/neverhood/module1000.cpp b/engines/neverhood/module1000.cpp index 529cbeab07..04059caf7d 100644 --- a/engines/neverhood/module1000.cpp +++ b/engines/neverhood/module1000.cpp @@ -924,10 +924,10 @@ Class426::Class426(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, ui _fileHashes[0] = fileHash1; _fileHashes[1] = fileHash2; - + _spriteResource.load2(fileHash1); createSurface(surfacePriority, 40, 40); - + _surface->getDrawRect().x = 0; _surface->getDrawRect().y = 0; _surface->getDrawRect().width = _spriteResource.getDimensions().width; @@ -1379,7 +1379,7 @@ Scene1002::Scene1002(NeverhoodEngine *vm, Module *parentModule, int which) //_class478 = addSprite(new Class478(_vm, _klayman)); setMessageList(0x004B4270); // TODO - // TODO _klayman->setRepl(64, 0); + _klayman->setRepl(64, 0); } else { _klayman = new KmScene1002(_vm, this, _class599, _ssLadderArch, 379, 435); //_class478 = addSprite(new Class478(_vm, _klayman)); @@ -1407,7 +1407,7 @@ Scene1002::Scene1002(NeverhoodEngine *vm, Module *parentModule, int which) // TODO //_class479 = addSprite(new Class479(_vm, this, _klayman)); // TODO - // TODO _klayman->setRepl(64, 0); + _klayman->setRepl(64, 0); _vm->_gameState.field2 = 0; } } @@ -1461,7 +1461,7 @@ void Scene1002::update() { if (!_flag1B4 && _klayman->getY() > 230) { // TODO deleteSprite(&_ssLadderArchPart3); - // TODO _klayman->clearRepl(); + _klayman->clearRepl(); _flag1B4 = true; _vm->_gameState.field2 = 1; } diff --git a/engines/neverhood/resource.cpp b/engines/neverhood/resource.cpp index dde80ebe79..97eae89bd5 100644 --- a/engines/neverhood/resource.cpp +++ b/engines/neverhood/resource.cpp @@ -158,8 +158,10 @@ void AnimResource::draw(uint frameIndex, byte *dest, int destPitch, bool flipX, _currSpriteData = _spriteData + frameInfo.spriteDataOffs; _width = frameInfo.rect.width; _height = frameInfo.rect.height; - // TODO: Repl stuff - unpackSpriteRle(_currSpriteData, _width, _height, dest, destPitch, flipX, flipY); + if (_replEnabled && _replOldColor != _replNewColor) + unpackSpriteRleRepl(_currSpriteData, _width, _height, dest, destPitch, _replOldColor, _replNewColor, flipX, flipY); + else + unpackSpriteRle(_currSpriteData, _width, _height, dest, destPitch, flipX, flipY); } bool AnimResource::load(uint32 fileHash) { @@ -276,8 +278,8 @@ void AnimResource::clear() { void AnimResource::clear2() { clear(); _replEnabled = true; - _replOldByte = 0; - _replNewByte = 0; + _replOldColor = 0; + _replNewColor = 0; } bool AnimResource::loadInternal(uint32 fileHash) { @@ -301,6 +303,11 @@ int16 AnimResource::getFrameIndex(uint32 frameHash) { return frameIndex; } +void AnimResource::setRepl(byte oldColor, byte newColor) { + _replOldColor = oldColor; + _replNewColor = newColor; +} + MouseCursorResource::MouseCursorResource(NeverhoodEngine *vm) : _cursorSprite(vm), _cursorNum(4), _currFileHash(0) { diff --git a/engines/neverhood/resource.h b/engines/neverhood/resource.h index b2a98c7670..610973c155 100644 --- a/engines/neverhood/resource.h +++ b/engines/neverhood/resource.h @@ -87,6 +87,8 @@ public: uint getFrameCount() const { return _frames.size(); } const AnimFrameInfo& getFrameInfo(int16 index) const { return _frames[index]; } int16 getFrameIndex(uint32 frameHash); + void setReplEnabled(bool value) { _replEnabled = value; } + void setRepl(byte oldColor, byte newColor); protected: NeverhoodEngine *_vm; int _resourceHandle; @@ -96,8 +98,8 @@ protected: byte *_paletteData; byte *_spriteData; bool _replEnabled; - byte _replOldByte; - byte _replNewByte; + byte _replOldColor; + byte _replNewColor; Common::Array _frames; }; diff --git a/engines/neverhood/sprite.cpp b/engines/neverhood/sprite.cpp index 155d3254ec..78c780bdbb 100644 --- a/engines/neverhood/sprite.cpp +++ b/engines/neverhood/sprite.cpp @@ -227,9 +227,9 @@ void AnimatedSprite::init() { _newHashListIndex = -1; _fileHash4 = 0; _flag = false; - _replOldByte = 0; - _replNewByte = 0; - // TODO _animResource.replEnabled = 0; + _replOldColor = 0; + _replNewColor = 0; + _animResource.setReplEnabled(false); _playBackwards = false; } @@ -255,6 +255,18 @@ void AnimatedSprite::updateDeltaXY() { processDelta(); } +void AnimatedSprite::setRepl(byte oldColor, byte newColor) { + _replOldColor = oldColor; + _replNewColor = newColor; + _animResource.setReplEnabled(true); +} + +void AnimatedSprite::clearRepl() { + _replOldColor = 0; + _replNewColor = 0; + _animResource.setReplEnabled(false); +} + void AnimatedSprite::updateAnim() { _flag = false; @@ -280,9 +292,8 @@ void AnimatedSprite::updateAnim() { // TODO _animResource.loadInternal(calcHash("sqDefault")); _fileHash3 = 0; } - if (_replNewByte != _replOldByte) { - debug("TODO"); - // TODO _animResource.setRepl(_replOldByte, _replNewByte); + if (_replOldColor != _replNewColor) { + _animResource.setRepl(_replOldColor, _replNewColor); } _fileHash2 = 0; if (_animStatus != 0) { @@ -313,9 +324,8 @@ void AnimatedSprite::updateAnim() { // TODO _animResource.loadInternal(calcHash("sqDefault")); _fileHash3 = 0; } - if (_replNewByte != _replOldByte) { - debug("TODO"); - // TODO _animResource.setRepl(_replOldByte, _replNewByte); + if (_replOldColor != _replNewColor) { + _animResource.setRepl(_replOldColor, _replNewColor); } _fileHash1 = 0; _frameIndex = _fileHash6 != 0 ? MAX(0, _animResource.getFrameIndex(_fileHash6)) : 0; @@ -328,9 +338,8 @@ void AnimatedSprite::updateAnim() { // TODO _animResource.loadInternal(calcHash("sqDefault")); _fileHash3 = 0; } - if (_replNewByte != _replOldByte) { - debug("TODO"); - // TODO _animResource.setRepl(_replOldByte, _replNewByte); + if (_replOldColor != _replNewColor) { + _animResource.setRepl(_replOldColor, _replNewColor); } _fileHash1 = 0; _frameIndex = _frameIndex3 != -1 ? _frameIndex3 : _animResource.getFrameCount() - 1; @@ -377,7 +386,7 @@ void AnimatedSprite::updatePosition() { void AnimatedSprite::updateFrameIndex() { if (!_playBackwards) { - debug("%08X ### _frameIndex = %d; _frameIndex2 = %d", _fileHash3, _frameIndex, _frameIndex2); + //debug("%08X ### _frameIndex = %d; _frameIndex2 = %d", _fileHash3, _frameIndex, _frameIndex2); if (_frameIndex < _frameIndex2) { _frameIndex++; } else { diff --git a/engines/neverhood/sprite.h b/engines/neverhood/sprite.h index 996c063b42..71660ff985 100644 --- a/engines/neverhood/sprite.h +++ b/engines/neverhood/sprite.h @@ -107,6 +107,8 @@ public: AnimatedSprite(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority, int16 x, int16 y); void update(); void updateDeltaXY(); + void setRepl(byte oldColor, byte newColor); + void clearRepl(); protected: typedef void (AnimatedSprite::*AnimationCb)(); AnimResource _animResource; @@ -125,8 +127,8 @@ protected: int _newHashListIndex; uint32 _fileHash4; int16 _deltaX, _deltaY; - byte _replOldByte; - byte _replNewByte; + byte _replOldColor; + byte _replNewColor; bool _playBackwards; bool _flag; /* TODO -- cgit v1.2.3