[Scummvm-git-logs] scummvm master -> 1588218f6f7f3c23d8c4d4b4186c51b1bae1100b

dreammaster paulfgilbert at gmail.com
Sat Aug 31 04:36:21 CEST 2019


This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
27efc15f8c XEEN: Creating sprite drawer class hierarchy for missing draw modes
1588218f6f XEEN: Further sprite drawer mode code


Commit: 27efc15f8c22e550aaca36adc8ab9aef5fc9dee0
    https://github.com/scummvm/scummvm/commit/27efc15f8c22e550aaca36adc8ab9aef5fc9dee0
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-08-30T19:36:13-07:00

Commit Message:
XEEN: Creating sprite drawer class hierarchy for missing draw modes

Changed paths:
    engines/xeen/sprites.cpp
    engines/xeen/sprites.h


diff --git a/engines/xeen/sprites.cpp b/engines/xeen/sprites.cpp
index 7b484b5..fed8b6a 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
diff --git a/engines/xeen/sprites.h b/engines/xeen/sprites.h
index fe4c45c..beb310e 100644
--- a/engines/xeen/sprites.h
+++ b/engines/xeen/sprites.h
@@ -40,7 +40,9 @@ enum {
 };
 
 enum SpriteFlags {
-	SPRFLAG_800 = 0x800, SPRFLAG_SCENE_CLIPPED = 0x2000, SPRFLAG_BOTTOM_CLIPPED = 0x4000,
+	SPRFLAG_MODE_MASK = 0xF00, SPRFLAG_DRAWER1 = 0x100, SPRFLAG_DRAWER3 = 0X300,
+	SPRFLAG_DRAWER5 = 0x500, SPRFLAG_DRAWER6 = 0x600, SPRFLAG_800 = 0x800,
+	SPRFLAG_SCENE_CLIPPED = 0x2000, SPRFLAG_BOTTOM_CLIPPED = 0x4000,
 	SPRFLAG_HORIZ_FLIPPED = 0x8000, SPRFLAG_RESIZE = 0x10000
 };
 
@@ -50,7 +52,7 @@ private:
 		uint16 _offset1, _offset2;
 	};
 	Common::Array<IndexEntry> _index;
-	int32 _filesize;
+	size_t _filesize;
 	byte *_data;
 	int _scaledWidth, _scaledHeight;
 	Common::String _filename;
@@ -72,17 +74,6 @@ private:
 	 */
 	void draw(int windowNum, int frame, const Common::Point &destPos,
 		const Common::Rect &bounds, uint flags = 0, int scale = 0);
-
-	/**
-	 * Draw a sprite frame based on a passed offset into the data stream
-	 */
-	void drawOffset(XSurface &dest, uint16 offset, const Common::Point &pt,
-		const Common::Rect &clipRect, uint flags, int scale);
-
-	/**
-	 * Scale a co-ordinate value based on the passed scaling mask
-	 */
-	static uint getScaledVal(int xy, uint16 &scaleMask);
 public:
 	SpriteResource();
 	SpriteResource(const Common::String &filename);
@@ -182,6 +173,107 @@ public:
 	static void setClippedBottom(int y) { _clippedBottom = y; }
 };
 
+/**
+ * Basic sprite drawer
+ */
+class SpriteDrawer {
+private:
+	byte *_data;
+	size_t _filesize;
+private:
+	/**
+	 * Scale a co-ordinate value based on the passed scaling mask
+	 */
+	static uint getScaledVal(int xy, uint16 &scaleMask);
+protected:
+	/**
+	 * Output a pixel
+	 */
+	virtual void drawPixel(byte *dest, byte pixel);
+public:
+	/**
+	 * Constructor
+	 */
+	SpriteDrawer(byte *data, size_t filesize) : _data(data), _filesize(filesize) {}
+
+	/**
+	 * Draw a sprite frame based on a passed offset into the data stream
+	 */
+	void draw(XSurface &dest, uint16 offset, const Common::Point &pt,
+		const Common::Rect &clipRect, uint flags, int scale);
+};
+
+/**
+ * Handles drawing a sprite as masked/offset
+ */
+class SpriteDrawer1 : public SpriteDrawer {
+private:
+	byte _offset, _mask;
+protected:
+	/**
+	 * Output a pixel
+	 */
+	virtual void drawPixel(byte *dest, byte pixel) override;
+public:
+	/**
+	 * Constructor
+	 */
+	SpriteDrawer1(byte *data, size_t filesize, int index);
+};
+
+class SpriteDrawer3 : public SpriteDrawer {
+private:
+	uint16 _offset, _mask;
+private:
+	/**
+	 * Output a pixel
+	 */
+	virtual void drawPixel(byte *dest, byte pixel) override;
+public:
+	/**
+	 * Constructor
+	 */
+	SpriteDrawer3(byte *data, size_t filesize, int index);
+};
+
+class SpriteDrawer5 : public SpriteDrawer {
+private:
+	uint16 _mask, _random1, _random2;
+private:
+	/**
+	 * Roll carry right opcode emulation
+	 */
+	void rcr(uint16 &val, bool &cf);
+protected:
+	/**
+	 * Output a pixel
+	 */
+	virtual void drawPixel(byte *dest, byte pixel) override;
+public:
+	/**
+	 * Constructor
+	 */
+	SpriteDrawer5(byte *data, size_t filesize, int index);
+};
+
+/**
+ * Handles drawing a sprite as a solid color
+ */
+class SpriteDrawer6 : public SpriteDrawer {
+private:
+	byte _color;
+protected:
+	/**
+	 * Output a pixel
+	 */
+	virtual void drawPixel(byte *dest, byte pixel) override;
+public:
+	/**
+	 * Constructor
+	 */
+	SpriteDrawer6(byte *data, size_t filesize, int index);
+};
+
 } // End of namespace Xeen
 
 #endif /* MADS_SPRITES_H */


Commit: 1588218f6f7f3c23d8c4d4b4186c51b1bae1100b
    https://github.com/scummvm/scummvm/commit/1588218f6f7f3c23d8c4d4b4186c51b1bae1100b
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-08-30T19:36:13-07:00

Commit Message:
XEEN: Further sprite drawer mode code

Changed paths:
    engines/xeen/sprites.cpp
    engines/xeen/sprites.h


diff --git a/engines/xeen/sprites.cpp b/engines/xeen/sprites.cpp
index fed8b6a..fc2159b 100644
--- a/engines/xeen/sprites.cpp
+++ b/engines/xeen/sprites.cpp
@@ -137,6 +137,8 @@ void SpriteResource::draw(XSurface &dest, int frame, const Common::Point &destPo
 	case SPRFLAG_DRAWER1:
 		draw = new SpriteDrawer1(_data, _filesize, flags & 0x1F);
 		break;
+	case SPRFLAG_DRAWER2:
+		error("TODO: Sprite drawer mode 2");
 	case SPRFLAG_DRAWER3:
 		draw = new SpriteDrawer3(_data, _filesize, flags & 0x1F);
 		break;
@@ -460,6 +462,19 @@ void SpriteDrawer3::drawPixel(byte *dest, byte pixel) {
 
 /*------------------------------------------------------------------------*/
 
+const byte DRAWER4_THRESHOLD[4] = { 4, 7, 10, 13 };
+
+SpriteDrawer4::SpriteDrawer4(byte *data, size_t filesize, int index) : SpriteDrawer(data, filesize) {
+	_threshold = DRAWER4_THRESHOLD[index];
+}
+
+void SpriteDrawer4::drawPixel(byte *dest, byte pixel) {
+	if ((pixel & 0xf) >= _threshold)
+		*dest = pixel;
+}
+
+/*------------------------------------------------------------------------*/
+
 const uint16 DRAWER5_MASK[4] = { 0x3333, 0x6666, 0x999A, 0xCCCD };
 
 SpriteDrawer5::SpriteDrawer5(byte *data, size_t filesize, int index) : SpriteDrawer(data, filesize) {
diff --git a/engines/xeen/sprites.h b/engines/xeen/sprites.h
index beb310e..e8d83e1 100644
--- a/engines/xeen/sprites.h
+++ b/engines/xeen/sprites.h
@@ -40,10 +40,10 @@ enum {
 };
 
 enum SpriteFlags {
-	SPRFLAG_MODE_MASK = 0xF00, SPRFLAG_DRAWER1 = 0x100, SPRFLAG_DRAWER3 = 0X300,
-	SPRFLAG_DRAWER5 = 0x500, SPRFLAG_DRAWER6 = 0x600, SPRFLAG_800 = 0x800,
-	SPRFLAG_SCENE_CLIPPED = 0x2000, SPRFLAG_BOTTOM_CLIPPED = 0x4000,
-	SPRFLAG_HORIZ_FLIPPED = 0x8000, SPRFLAG_RESIZE = 0x10000
+	SPRFLAG_MODE_MASK = 0xF00, SPRFLAG_DRAWER1 = 0x100, SPRFLAG_DRAWER2 = 0x200,
+	SPRFLAG_DRAWER3 = 0x300, SPRFLAG_DRAWER4 = 0x400, SPRFLAG_DRAWER5 = 0x500, SPRFLAG_DRAWER6 = 0x600,
+	SPRFLAG_DRAWER7 = 0x700, SPRFLAG_800 = 0x800, SPRFLAG_SCENE_CLIPPED = 0x2000,
+	SPRFLAG_BOTTOM_CLIPPED = 0x4000, SPRFLAG_HORIZ_FLIPPED = 0x8000, SPRFLAG_RESIZE = 0x10000
 };
 
 class SpriteResource {
@@ -203,9 +203,6 @@ public:
 		const Common::Rect &clipRect, uint flags, int scale);
 };
 
-/**
- * Handles drawing a sprite as masked/offset
- */
 class SpriteDrawer1 : public SpriteDrawer {
 private:
 	byte _offset, _mask;
@@ -236,6 +233,21 @@ public:
 	SpriteDrawer3(byte *data, size_t filesize, int index);
 };
 
+class SpriteDrawer4 : public SpriteDrawer {
+private:
+	byte _threshold;
+protected:
+	/**
+	 * Output a pixel
+	 */
+	virtual void drawPixel(byte *dest, byte pixel) override;
+public:
+	/**
+	 * Constructor
+	 */
+	SpriteDrawer4(byte *data, size_t filesize, int index);
+};
+
 class SpriteDrawer5 : public SpriteDrawer {
 private:
 	uint16 _mask, _random1, _random2;
@@ -256,9 +268,6 @@ public:
 	SpriteDrawer5(byte *data, size_t filesize, int index);
 };
 
-/**
- * Handles drawing a sprite as a solid color
- */
 class SpriteDrawer6 : public SpriteDrawer {
 private:
 	byte _color;





More information about the Scummvm-git-logs mailing list