[Scummvm-git-logs] scummvm master -> 7948d123838d702bef44c0bb8e9b0f206fe63679

dreammaster paulfgilbert at gmail.com
Mon Apr 27 00:13:09 UTC 2020


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

Summary:
7948d12383 XEEN: Add missing sprite drawer for Energy Blast effect


Commit: 7948d123838d702bef44c0bb8e9b0f206fe63679
    https://github.com/scummvm/scummvm/commit/7948d123838d702bef44c0bb8e9b0f206fe63679
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-04-26T17:12:20-07:00

Commit Message:
XEEN: Add missing sprite drawer for Energy Blast effect

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


diff --git a/NEWS.md b/NEWS.md
index 2e7643c980..e0cd68c4ea 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -17,6 +17,9 @@ For a more comprehensive changelog of the latest experimental code, see:
  Sword1:
    - Added support for localized menus in Novy Disk Russian Trilogy release.
 
+ Xeen:
+   - Add missing sprite drawer for enemies hit by Energy Blast
+
  Linux port:
    - Added option to use the system file browser instead of the ScummVM file browser.
 
diff --git a/engines/xeen/sprites.cpp b/engines/xeen/sprites.cpp
index d6d0cf5154..8b847bea21 100644
--- a/engines/xeen/sprites.cpp
+++ b/engines/xeen/sprites.cpp
@@ -140,7 +140,8 @@ void SpriteResource::draw(XSurface &dest, int frame, const Common::Point &destPo
 		drawer = new SpriteDrawer1(_data, _filesize, flags & 0x1F);
 		break;
 	case SPRFLAG_DRAWER2:
-		error("TODO: Sprite drawer mode 2");
+		drawer = new SpriteDrawer2(_data, _filesize, flags & 0x1F);
+		break;
 	case SPRFLAG_DRAWER3:
 		drawer = new SpriteDrawer3(_data, _filesize, flags & 0x1F);
 		break;
@@ -206,6 +207,10 @@ void SpriteDrawer::draw(XSurface &dest, uint16 offset, const Common::Point &pt,
 	int xInc = flipped ? -1 : 1;
 	bool enlarge = (scale & SCALE_ENLARGE) != 0;
 
+	_destTop = (byte *)dest.getBasePtr(clipRect.left, clipRect.top);
+	_destBottom = (byte *)dest.getBasePtr(clipRect.right, clipRect.bottom - 1);
+	_pitch = dest.pitch;
+
 	// Get cell header
 	Common::MemoryReadStream f(_data, _filesize);
 	f.seek(offset);
@@ -356,6 +361,8 @@ void SpriteDrawer::draw(XSurface &dest, uint16 offset, const Common::Point &pt,
 
 			// Handle drawing out the line
 			byte *destP = (byte *)dest.getBasePtr(destPos.x, destPos.y);
+			_destLeft = (byte *)dest.getBasePtr(clipRect.left, destPos.y);
+			_destRight = (byte *)dest.getBasePtr(clipRect.right, destPos.y);
 			int16 xp = destPos.x;
 			lineP = &tempLine[SCREEN_WIDTH];
 
@@ -417,6 +424,12 @@ void SpriteDrawer::drawPixel(byte *dest, byte pixel) {
 	*dest = pixel;
 }
 
+void SpriteDrawer::rcr(uint16 &val, bool &cf) {
+	bool newCf = (val & 1);
+	val = (val >> 1) | (cf ? 0x8000 : 0);
+	cf = newCf;
+}
+
 /*------------------------------------------------------------------------*/
 
 const byte DRAWER1_OFFSET[24] = {
@@ -440,6 +453,55 @@ void SpriteDrawer1::drawPixel(byte *dest, byte pixel) {
 
 /*------------------------------------------------------------------------*/
 
+const byte DRAWER2_MASK1[32] = {
+	3, 0, 3, 0, 3, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0,
+	1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+const byte DRAWER2_MASK2[16] = {
+	0x7E, 0x7E, 0x7E, 0x7E, 0x3E, 0x3E, 0x3E, 0x3E,
+	0x1E, 0x1E, 0x1E, 0x1E, 0x0E, 0x0E, 0x0E, 0x0E
+};
+
+const int8 DRAWER2_DELTA[64] = {
+	-3, 3, 0, 0, 0, 0, 0, 0,
+	-5, 5, 0, 0, 0, 0, 0, 0,
+	-7, 7, 0, 0, 0, 0, 0, 0,
+	-9, 9, 0, 0, 0, 0, 0, 0,
+	-7, 7, 0, 0, 0, 0, 0, 0,
+	-9, 9, 0, 0, 0, 0, 0, 0,
+	-11, 11, 0, 0, 0, 0, 0, 0,
+	-13, 13, 0, 0, 0, 0, 0, 0
+};
+
+SpriteDrawer2::SpriteDrawer2(byte *data, size_t filesize, int index) : SpriteDrawer(data, filesize) {
+	_mask1 = DRAWER2_MASK1[index];
+	_mask2 = DRAWER2_MASK2[index];
+
+	_random1 = g_vm->getRandomNumber(0xffff);
+	_random2 = g_vm->getRandomNumber(0xffff);
+}
+
+void SpriteDrawer2::drawPixel(byte *dest, byte pixel) {
+	bool flag = (_random1 & 0x8000) != 0;
+	_random1 = (int)((uint16)_random1 << 1) - _random2 - (flag ? 1 : 0);
+
+	rcr(_random2, flag);
+	rcr(_random2, flag);
+	_random2 ^= _random1;
+
+	dest += DRAWER2_DELTA[(_random2 & _mask1 & _mask2) / 2];
+	if (dest >= _destLeft && dest < _destRight) {
+		dest += _pitch * DRAWER2_DELTA[((_random2 >> 8) &_mask1 &_mask2) / 2];
+
+		if (dest >= _destTop && dest < _destBottom) {
+			*dest = pixel;
+		}
+	}
+}
+
+/*------------------------------------------------------------------------*/
+
 const uint16 DRAWER3_MASK[4] = { 1, 3, 7, 15 };
 const uint16 DRAWER3_OFFSET[4] = { 1, 2, 4, 8 };
 
@@ -509,12 +571,6 @@ void SpriteDrawer5::drawPixel(byte *dest, byte pixel) {
 		*dest = pixel;
 }
 
-void SpriteDrawer5::rcr(uint16 &val, bool &cf) {
-	bool newCf = (val & 1);
-	val = (val >> 1) | (cf ? 0x8000 : 0);
-	cf = newCf;
-}
-
 /*------------------------------------------------------------------------*/
 
 const byte DRAWER6_MASK[16] = { 1, 2, 4, 8, 1, 3, 7, 15, 8, 12, 14, 15, 1, 2, 1, 2 };
diff --git a/engines/xeen/sprites.h b/engines/xeen/sprites.h
index e414c6ca55..366ad5e1ab 100644
--- a/engines/xeen/sprites.h
+++ b/engines/xeen/sprites.h
@@ -180,12 +180,21 @@ class SpriteDrawer {
 private:
 	byte *_data;
 	size_t _filesize;
+protected:
+	byte *_destTop, *_destBottom;
+	byte *_destLeft, *_destRight;
+	int _pitch;
 private:
 	/**
 	 * Scale a co-ordinate value based on the passed scaling mask
 	 */
 	static uint getScaledVal(int xy, uint16 &scaleMask);
 protected:
+	/**
+	 * Roll carry right opcode emulation
+	 */
+	void rcr(uint16 &val, bool &cf);
+
 	/**
 	 * Output a pixel
 	 */
@@ -223,6 +232,26 @@ public:
 	SpriteDrawer1(byte *data, size_t filesize, int index);
 };
 
+/**
+ * Scrambles up the sprite by drawing many of the pixels randomly
+ * at a horizontal or vertical offset
+ */
+class SpriteDrawer2 : public SpriteDrawer {
+private:
+	uint16 _mask1, _mask2;
+	uint16 _random1, _random2;
+private:
+	/**
+	 * Output a pixel
+	 */
+	void drawPixel(byte *dest, byte pixel) override;
+public:
+	/**
+	 * Constructor
+	 */
+	SpriteDrawer2(byte *data, size_t filesize, int index);
+};
+
 /**
  * Draws the sprite as faint ghostly, see-through.
  */
@@ -264,11 +293,6 @@ public:
 class SpriteDrawer5 : public SpriteDrawer {
 private:
 	uint16 _threshold, _random1, _random2;
-private:
-	/**
-	 * Roll carry right opcode emulation
-	 */
-	void rcr(uint16 &val, bool &cf);
 protected:
 	/**
 	 * Output a pixel




More information about the Scummvm-git-logs mailing list