diff options
author | Paul Gilbert | 2019-08-30 19:18:27 -0700 |
---|---|---|
committer | Paul Gilbert | 2019-08-30 19:36:13 -0700 |
commit | 27efc15f8c22e550aaca36adc8ab9aef5fc9dee0 (patch) | |
tree | e49535cb1781797732dbeec5722f298c0b2e84df /engines/xeen/sprites.cpp | |
parent | e36a4be7ce1efd6c7fff6e3c1f3f583d2bc5c189 (diff) | |
download | scummvm-rg350-27efc15f8c22e550aaca36adc8ab9aef5fc9dee0.tar.gz scummvm-rg350-27efc15f8c22e550aaca36adc8ab9aef5fc9dee0.tar.bz2 scummvm-rg350-27efc15f8c22e550aaca36adc8ab9aef5fc9dee0.zip |
XEEN: Creating sprite drawer class hierarchy for missing draw modes
Diffstat (limited to 'engines/xeen/sprites.cpp')
-rw-r--r-- | engines/xeen/sprites.cpp | 215 |
1 files changed, 164 insertions, 51 deletions
diff --git a/engines/xeen/sprites.cpp b/engines/xeen/sprites.cpp index 7b484b53e3..fed8b6a410 100644 --- a/engines/xeen/sprites.cpp +++ b/engines/xeen/sprites.cpp @@ -109,7 +109,85 @@ void SpriteResource::clear() { _index.clear(); } -void SpriteResource::drawOffset(XSurface &dest, uint16 offset, const Common::Point &pt, +void SpriteResource::draw(XSurface &dest, int frame, const Common::Point &destPos, + uint flags, int scale) { + draw(dest, frame, destPos, Common::Rect(0, 0, dest.w, dest.h), flags, scale); +} + +void SpriteResource::draw(Window &dest, int frame, const Common::Point &destPos, + uint flags, int scale) { + draw(dest, frame, destPos, dest.getBounds(), flags, scale); +} + +void SpriteResource::draw(int windowIndex, int frame, const Common::Point &destPos, + uint flags, int scale) { + Window &win = (*g_vm->_windows)[windowIndex]; + draw(win, frame, destPos, flags, scale); +} + +void SpriteResource::draw(XSurface &dest, int frame, const Common::Point &destPos, + const Common::Rect &bounds, uint flags, int scale) { + Common::Rect r = bounds; + if (flags & SPRFLAG_BOTTOM_CLIPPED) + r.clip(SCREEN_WIDTH, _clippedBottom); + + // Create drawer to handle the rendering + SpriteDrawer *draw; + switch (flags & SPRFLAG_MODE_MASK) { + case SPRFLAG_DRAWER1: + draw = new SpriteDrawer1(_data, _filesize, flags & 0x1F); + break; + case SPRFLAG_DRAWER3: + draw = new SpriteDrawer3(_data, _filesize, flags & 0x1F); + break; + case SPRFLAG_DRAWER5: + draw = new SpriteDrawer5(_data, _filesize, flags & 0x1F); + break; + case SPRFLAG_DRAWER6: + draw = new SpriteDrawer6(_data, _filesize, flags & 0x1F); + break; + default: + draw = new SpriteDrawer(_data, _filesize); + break; + } + + // Sprites can consist of separate background & foreground + draw->draw(dest, _index[frame]._offset1, destPos, r, flags, scale); + if (_index[frame]._offset2) + draw->draw(dest, _index[frame]._offset2, destPos, r, flags, scale); + + delete draw; +} + +void SpriteResource::draw(XSurface &dest, int frame) { + draw(dest, frame, Common::Point()); +} + +void SpriteResource::draw(int windowIndex, int frame) { + draw((*g_vm->_windows)[windowIndex], frame, Common::Point()); +} + +Common::Point SpriteResource::getFrameSize(int frame) const { + Common::MemoryReadStream f(_data, _filesize); + Common::Point frameSize; + + for (int idx = 0; idx < (_index[frame]._offset2 ? 2 : 1); ++idx) { + f.seek((idx == 0) ? _index[frame]._offset1 : _index[frame]._offset2); + int xOffset = f.readUint16LE(); + int width = f.readUint16LE(); + int yOffset = f.readUint16LE(); + int height = f.readUint16LE(); + + frameSize.x = MAX((int)frameSize.x, xOffset + width); + frameSize.y = MAX((int)frameSize.y, yOffset + height); + } + + return frameSize; +} + +/*------------------------------------------------------------------------*/ + +void SpriteDrawer::draw(XSurface &dest, uint16 offset, const Common::Point &pt, const Common::Rect &clipRect, uint flags, int scale) { static const uint SCALE_TABLE[] = { 0xFFFF, 0xFFEF, 0xEFEF, 0xEFEE, 0xEEEE, 0xEEAE, 0xAEAE, 0xAEAA, @@ -287,11 +365,11 @@ void SpriteResource::drawOffset(XSurface &dest, uint16 offset, const Common::Poi if (*lineP != -1 && xp >= bounds.left && xp < bounds.right) { drawBounds.left = MIN(drawBounds.left, xp); drawBounds.right = MAX((int)drawBounds.right, xp + 1); - *destP = (byte)*lineP; + drawPixel(destP, (byte)*lineP); if (enlarge) { - *(destP + SCREEN_WIDTH) = (byte)*lineP; - *(destP + 1) = (byte)*lineP; - *(destP + 1 + SCREEN_WIDTH) = (byte)*lineP; + drawPixel(destP + SCREEN_WIDTH, (byte)*lineP); + drawPixel(destP + 1, (byte)*lineP); + drawPixel(destP + 1 + SCREEN_WIDTH, (byte)*lineP); } } @@ -317,72 +395,107 @@ void SpriteResource::drawOffset(XSurface &dest, uint16 offset, const Common::Poi } } -void SpriteResource::draw(XSurface &dest, int frame, const Common::Point &destPos, - uint flags, int scale) { - draw(dest, frame, destPos, Common::Rect(0, 0, dest.w, dest.h), flags, scale); +uint SpriteDrawer::getScaledVal(int xy, uint16 &scaleMask) { + if (!xy) + return 0; + + uint result = 0; + for (int idx = 0; idx < xy; ++idx) { + uint bit = (scaleMask >> 15) & 1; + scaleMask = ((scaleMask & 0x7fff) << 1) + bit; + result += bit; + } + + return result; } -void SpriteResource::draw(Window &dest, int frame, const Common::Point &destPos, - uint flags, int scale) { - draw(dest, frame, destPos, dest.getBounds(), flags, scale); +void SpriteDrawer::drawPixel(byte *dest, byte pixel) { + *dest = pixel; } -void SpriteResource::draw(int windowIndex, int frame, const Common::Point &destPos, - uint flags, int scale) { - Window &win = (*g_vm->_windows)[windowIndex]; - draw(win, frame, destPos, flags, scale); +/*------------------------------------------------------------------------*/ + +const byte DRAWER1_OFFSET[24] = { + 0x30, 0xC0, 0xB0, 0x10, 0x41, 0x20, 0x40, 0x21, 0x48, 0x46, 0x43, 0x40, + 0xD0, 0xD3, 0xD6, 0xD8, 0x01, 0x04, 0x07, 0x0A, 0xEA, 0xEE, 0xF2, 0xF6 +}; + +const byte DRAWER1_MASK[24] = { + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x0F, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07, 0x07 +}; + +SpriteDrawer1::SpriteDrawer1(byte *data, size_t filesize, int index) : SpriteDrawer(data, filesize) { + _offset = DRAWER1_OFFSET[index]; + _mask = DRAWER1_MASK[index]; } -void SpriteResource::draw(XSurface &dest, int frame, const Common::Point &destPos, - const Common::Rect &bounds, uint flags, int scale) { - Common::Rect r = bounds; - if (flags & SPRFLAG_BOTTOM_CLIPPED) - r.clip(SCREEN_WIDTH, _clippedBottom); +void SpriteDrawer1::drawPixel(byte *dest, byte pixel) { + *dest = (pixel & _mask) + _offset; +} - // Sprites can consist of separate background & foreground - drawOffset(dest, _index[frame]._offset1, destPos, r, flags, scale); - if (_index[frame]._offset2) - drawOffset(dest, _index[frame]._offset2, destPos, r, flags, scale); +/*------------------------------------------------------------------------*/ + +const uint16 DRAWER3_MASK[4] = { 0xF01, 0xF03, 0xF07, 0xF0F }; +const uint16 DRAWER3_OFFSET[4] = { 1, 2, 4, 8 }; + +SpriteDrawer3::SpriteDrawer3(byte *data, size_t filesize, int index) : SpriteDrawer(data, filesize) { + _offset = DRAWER3_OFFSET[index]; + _mask = DRAWER3_MASK[index]; } -void SpriteResource::draw(XSurface &dest, int frame) { - draw(dest, frame, Common::Point()); +void SpriteDrawer3::drawPixel(byte *dest, byte pixel) { + uint16 val = (int)*dest << 8 | pixel; + val = (val & _mask) - _offset; + + byte level = (val & 0xff) + (val >> 8); + if (level >= 0x80) { + *dest &= 0xf0; + } else if (level <= 0xf) { + *dest = (*dest & 0xf0) | level; + } else { + *dest |= 0xf; + } } -void SpriteResource::draw(int windowIndex, int frame) { - draw((*g_vm->_windows)[windowIndex], frame, Common::Point()); +/*------------------------------------------------------------------------*/ + +const uint16 DRAWER5_MASK[4] = { 0x3333, 0x6666, 0x999A, 0xCCCD }; + +SpriteDrawer5::SpriteDrawer5(byte *data, size_t filesize, int index) : SpriteDrawer(data, filesize) { + _mask = DRAWER5_MASK[index]; + _random1 = g_vm->getRandomNumber(0xffff); + _random2 = g_vm->getRandomNumber(0xffff); } -uint SpriteResource::getScaledVal(int xy, uint16 &scaleMask) { - if (!xy) - return 0; +void SpriteDrawer5::drawPixel(byte *dest, byte pixel) { + bool flag = (_random1 & 0x8000) != 0; + _random1 = (int)((uint16)_random1 << 1) - _random2 - (flag ? 1 : 0); - uint result = 0; - for (int idx = 0; idx < xy; ++idx) { - uint bit = (scaleMask >> 15) & 1; - scaleMask = ((scaleMask & 0x7fff) << 1) + bit; - result += bit; - } + rcr(_random2, flag); + rcr(_random2, flag); + _random2 ^= _random1; - return result; + if (_random2 > _mask) + *dest = pixel; } -Common::Point SpriteResource::getFrameSize(int frame) const { - Common::MemoryReadStream f(_data, _filesize); - Common::Point frameSize; +void SpriteDrawer5::rcr(uint16 &val, bool &cf) { + bool newCf = (val & 1); + val = (val >> 1) | (cf ? 0x8000 : 0); + cf = newCf; +} - for (int idx = 0; idx < (_index[frame]._offset2 ? 2 : 1); ++idx) { - f.seek((idx == 0) ? _index[frame]._offset1 : _index[frame]._offset2); - int xOffset = f.readUint16LE(); - int width = f.readUint16LE(); - int yOffset = f.readUint16LE(); - int height = f.readUint16LE(); +/*------------------------------------------------------------------------*/ - frameSize.x = MAX((int)frameSize.x, xOffset + width); - frameSize.y = MAX((int)frameSize.y, yOffset + height); - } +const byte DRAWER6_COLOR[16] = { 1, 2, 4, 8, 1, 3, 7, 15, 8, 12, 14, 15, 1, 2, 1, 2 }; - return frameSize; +SpriteDrawer6::SpriteDrawer6(byte *data, size_t filesize, int index) : SpriteDrawer(data, filesize) { + _color = DRAWER6_COLOR[index]; +} + +void SpriteDrawer6::drawPixel(byte *dest, byte pixel) { + *dest = _color; } } // End of namespace Xeen |