aboutsummaryrefslogtreecommitdiff
path: root/engines/xeen/sprites.cpp
diff options
context:
space:
mode:
authorPaul Gilbert2019-08-30 19:18:27 -0700
committerPaul Gilbert2019-08-30 19:36:13 -0700
commit27efc15f8c22e550aaca36adc8ab9aef5fc9dee0 (patch)
treee49535cb1781797732dbeec5722f298c0b2e84df /engines/xeen/sprites.cpp
parente36a4be7ce1efd6c7fff6e3c1f3f583d2bc5c189 (diff)
downloadscummvm-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.cpp215
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