[Scummvm-cvs-logs] CVS: scummvm/scumm gfx.cpp,2.379,2.380 gfx.h,1.95,1.96 intern.h,2.315,2.316 script_v90he.cpp,2.110,2.111

Gregory Montoir cyx at users.sourceforge.net
Mon Nov 22 12:35:01 CET 2004


Update of /cvsroot/scummvm/scummvm/scumm
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15295/scumm

Modified Files:
	gfx.cpp gfx.h intern.h script_v90he.cpp 
Log Message:
HE wiz update, o90_unknown29 fully implemented.
Next step : move all the wiz related stuff to a specific class/struct.


Index: gfx.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/gfx.cpp,v
retrieving revision 2.379
retrieving revision 2.380
diff -u -d -r2.379 -r2.380
--- gfx.cpp	21 Nov 2004 21:40:51 -0000	2.379
+++ gfx.cpp	22 Nov 2004 20:34:28 -0000	2.380
@@ -1624,7 +1624,50 @@
 	}
 }
 
-uint8 Gdi::getWizPixelColor_type0(const uint8 *data, int x, int y, int w, int h, uint8 color) {
+int Gdi::isWizPixelNonTransparent(const uint8 *data, int x, int y, int w, int h) {
+	int ret = 0;
+	while (y != 0) {
+		data += READ_LE_UINT16(data) + 2;
+		--y;
+	}
+	uint16 off = READ_LE_UINT16(data); data += 2;
+	if (off != 0) {
+		if (x == 0) {
+			ret = (~*data) & 1;			
+		} else {
+			do {
+				uint8 code = *data++;
+				if (code & 1) {
+					code >>= 1;
+					if (code > x) {
+						ret = 0;
+						break;
+					}
+					x -= code;
+				} else if (code & 2) {
+					code = (code >> 2) + 1;
+					if (code > x) {
+						ret = 1;
+						break;
+					}
+					x -= code;
+					++data;
+				} else {
+					code = (code >> 2) + 1;
+					if (code > x) {
+						ret = 1;
+						break;
+					}
+					x -= code;
+					data += code;
+				}				
+			} while (x > 0);
+		}
+	}
+	return ret;
+}
+
+uint8 Gdi::getRawWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 color) {
 	uint8 c;
 	if (x >= 0 && x < w && y >= 0 && y < h) {
 		c = *(data + y * w + x);
@@ -1634,14 +1677,14 @@
 	return c;
 }
 
-uint8 Gdi::getWizPixelColor_type1(const uint8 *data, int x, int y, int w, int h, uint8 color) {
+uint8 Gdi::getWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 color) {
 	uint8 c = color;
 	if (x >= 0 && x < w && y >= 0 && y < h) {
 		while (y != 0) {
 			data += READ_LE_UINT16(data) + 2;
 			--y;
 		}
-		uint16 off = READ_LE_UINT16(data);
+		uint16 off = READ_LE_UINT16(data); data += 2;
 		if (off != 0) {
 			if (x == 0) {
 				c = (*data & 1) ? color : *data;
@@ -1679,6 +1722,90 @@
 	return c;
 }
 
+void Gdi::computeWizHistogram(uint32 *histogram, const uint8 *data, const Common::Rect *srcRect) {
+	int y = srcRect->top;
+	while (y != 0) {
+		data += READ_LE_UINT16(data) + 2;
+		--y;
+	}
+	int ih = srcRect->height();
+	while (ih--) {
+		uint16 off = READ_LE_UINT16(data); data += 2;
+		if (off != 0) {
+			const uint8 *p = data;
+			int x1 = srcRect->left;
+			int x2 = srcRect->right;
+			uint8 code;
+			while (x1 > 0) {
+				code = *p++;
+				if (code & 1) {
+					code >>= 1;
+					if (code > x1) {
+						code -= x1;
+						x2 -= code;
+						break;
+					}
+					x1 -= code;
+				} else if (code & 2) {
+					code = (code >> 2) + 1;
+					if (code > x1) {
+						code -= x1;
+						goto dec_sub2;
+					}
+					x1 -= code;
+					++p;
+				} else {
+					code = (code >> 2) + 1;
+					if (code > x1) {
+						code -= x1;
+						p += x1;
+						goto dec_sub3;
+					}
+					x1 -= code;
+					p += code;
+				}
+			}
+			while (x2 > 0) {
+				code = *p++;
+				if (code & 1) {
+					code >>= 1;
+					x2 -= code;
+				} else if (code & 2) {
+					code = (code >> 2) + 1;
+dec_sub2:			x2 -= code;
+					if (x2 < 0) {
+						code += x2;
+					}
+					histogram[*p++] += code;
+				} else {
+					code = (code >> 2) + 1;
+dec_sub3:			x2 -= code;
+					if (x2 < 0) {
+						code += x2;
+					}
+					int n = code;
+					while (n--) {
+						++histogram[*p++];
+					}
+				}
+			}
+			data += off;
+		}
+	}
+}
+
+void Gdi::computeRawWizHistogram(uint32 *histogram, const uint8 *data, int srcPitch, const Common::Rect *srcRect) {
+	data += srcRect->top * srcPitch + srcRect->left;
+	int iw = srcRect->width();
+	int ih = srcRect->height();
+	while (ih--) {
+		for (int i = 0; i < iw; ++i) {
+			++histogram[data[i]];
+		}
+		data += srcPitch;
+	}
+}
+
 void Gdi::copyAuxImage(uint8 *dst1, uint8 *dst2, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect) {
 	Common::Rect r1, r2;
 	if (calcClipRects(dstw, dsth, srcx, srcy, srcw, srch, rect, r1, r2)) {

Index: gfx.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/gfx.h,v
retrieving revision 1.95
retrieving revision 1.96
diff -u -d -r1.95 -r1.96
--- gfx.h	21 Nov 2004 21:31:28 -0000	1.95
+++ gfx.h	22 Nov 2004 20:34:29 -0000	1.96
@@ -280,8 +280,11 @@
 	void copyWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect);
 	void copyRawWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor);
 	void decompressWizImage(uint8 *dst, int dstPitch, const Common::Rect &dstRect, const uint8 *src, const Common::Rect &srcRect);
-	uint8 getWizPixelColor_type0(const uint8 *data, int x, int y, int w, int h, uint8 color);
-	uint8 getWizPixelColor_type1(const uint8 *data, int x, int y, int w, int h, uint8 color);
+	int isWizPixelNonTransparent(const uint8 *data, int x, int y, int w, int h);
+	uint8 getWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 color);
+	uint8 getRawWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 color);
+	void computeWizHistogram(uint32 *histogram, const uint8 *data, const Common::Rect *srcRect);
+	void computeRawWizHistogram(uint32 *histogram, const uint8 *data, int srcPitch, const Common::Rect *srcRect);
 	void copyAuxImage(uint8 *dst1, uint8 *dst2, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect);
 	void decompressAuxImage(uint8 *dst1, uint8 *dst2, int dstPitch, const Common::Rect &dstRect, const uint8 *src, const Common::Rect &srcRect);
 	void copyVirtScreenBuffers(const Common::Rect &rect);

Index: intern.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/intern.h,v
retrieving revision 2.315
retrieving revision 2.316
diff -u -d -r2.315 -r2.316
--- intern.h	21 Nov 2004 21:31:28 -0000	2.315
+++ intern.h	22 Nov 2004 20:34:29 -0000	2.316
@@ -877,6 +877,7 @@
 	void processWizImage(const WizParameters *params);
 	int isWizPixelNonTransparent(int restype, int resnum, int state, int x, int y, int flags);
 	uint8 getWizPixelColor(int restype, int resnum, int state, int x, int y, int flags);
+	int computeWizHistogram(int resnum, int state, int x, int y, int w, int h);
 	
 	/* HE version 90 script opcodes */
 	void o90_dup();
@@ -895,7 +896,7 @@
 	void o90_unknown26();
 	void o90_unknown27();
 	void o90_unknown28();
-	void o90_unknown29();
+	void o90_getWizData();
 	void o90_unknown2F();
 	void o90_mod();
 	void o90_unknown31();

Index: script_v90he.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/script_v90he.cpp,v
retrieving revision 2.110
retrieving revision 2.111
diff -u -d -r2.110 -r2.111
--- script_v90he.cpp	21 Nov 2004 21:31:28 -0000	2.110
+++ script_v90he.cpp	22 Nov 2004 20:34:29 -0000	2.111
@@ -95,7 +95,7 @@
 		OPCODE(o90_unknown27),
 		/* 28 */
 		OPCODE(o90_unknown28),
-		OPCODE(o90_unknown29),
+		OPCODE(o90_getWizData),
 		OPCODE(o6_invalid),
 		OPCODE(o90_startScriptUnk),
 		/* 2C */
@@ -1197,8 +1197,30 @@
 }
 
 int ScummEngine_v90he::isWizPixelNonTransparent(int restype, int resnum, int state, int x, int y, int flags) {
-	warning("ScummEngine_v90he::isWizPixelNonTransparent() unimplemented");
-	return 0;
+	int ret = 0;
+	const uint8 *data = getResourceAddress(restype, resnum);
+	assert(data);
+	const uint8 *wizh = findWrappedBlock(MKID('WIZH'), data, state, 0);
+	assert(wizh);
+	uint32 c = READ_LE_UINT32(wizh + 0x0);
+	int w = READ_LE_UINT32(wizh + 0x4);
+	int h = READ_LE_UINT32(wizh + 0x8);
+	const uint8 *wizd = findWrappedBlock(MKID('WIZD'), data, state, 0);
+	assert(wizd);
+	if (x >= 0 && x < w && y >= 0 && y < h) {
+		if (flags & 0x400) {
+			x = w - x - 1;
+		}
+		if (flags & 0x800) {
+			y = h - y - 1;
+		}
+		if (c == 1) {
+			ret = gdi.isWizPixelNonTransparent(wizd, x, y, w, h);
+		} else if (c == 0 || c == 2 || c == 3) {
+			ret = gdi.getRawWizPixelColor(wizd, x, y, w, h, VAR(VAR_WIZ_TCOLOR)) != VAR(VAR_WIZ_TCOLOR);
+		}
+	}
+	return ret;
 }
 
 uint8 ScummEngine_v90he::getWizPixelColor(int restype, int resnum, int state, int x, int y, int flags) {
@@ -1213,16 +1235,50 @@
 	const uint8 *wizd = findWrappedBlock(MKID('WIZD'), data, state, 0);
 	assert(wizd);		
 	if (c == 1) {
-		color = gdi.getWizPixelColor_type1(wizd, x, y, w, h, VAR(VAR_WIZ_TCOLOR));
+		color = gdi.getWizPixelColor(wizd, x, y, w, h, VAR(VAR_WIZ_TCOLOR));
 	} else if (c == 0 || c == 2 || c == 3) {
-		color = gdi.getWizPixelColor_type0(wizd, x, y, w, h, VAR(VAR_WIZ_TCOLOR));
+		color = gdi.getRawWizPixelColor(wizd, x, y, w, h, VAR(VAR_WIZ_TCOLOR));
 	} else {
 		color = VAR(VAR_WIZ_TCOLOR);
 	}
 	return color;
 }
 
-void ScummEngine_v90he::o90_unknown29() {
+int ScummEngine_v90he::computeWizHistogram(int resnum, int state, int x, int y, int w, int h) {
+	writeVar(0, 0);
+	defineArray(0, kDwordArray, 0, 0, 0, 255);
+	if (readVar(0) != 0) {
+		const uint8 *data = getResourceAddress(rtImage, resnum);
+		assert(data);
+		const uint8 *wizh = findWrappedBlock(MKID('WIZH'), data, state, 0);
+		assert(wizh);
+		uint32 ic = READ_LE_UINT32(wizh + 0x0);
+		uint32 iw = READ_LE_UINT32(wizh + 0x4);
+		uint32 ih = READ_LE_UINT32(wizh + 0x8);
+		const uint8 *wizd = findWrappedBlock(MKID('WIZD'), data, state, 0);
+		assert(wizd);
+		Common::Rect rWiz(iw, ih);
+		Common::Rect rCap(x, y, w + 1, h + 1);
+		if (rCap.intersects(rWiz)) {
+			rCap.clip(rWiz);
+			uint32 histogram[0x100];
+			memset(histogram, 0, sizeof(histogram));
+			if (ic == 1) {
+				gdi.computeWizHistogram(histogram, wizd, &rCap);
+			} else if (ic == 0) {
+				gdi.computeRawWizHistogram(histogram, wizd, w, &rCap);
+			} else {
+				warning("Unable to return histogram for type %d", ic);
+			}
+			for (int i = 0; i < 0x100; ++i) {
+				writeArray(0, 0, i, histogram[i]);
+			}
+		}
+	}
+	return readVar(0);
+}
+
+void ScummEngine_v90he::o90_getWizData() {
 	int state, resId;
 	int32 w, h;
 	int16 x, y;
@@ -1273,14 +1329,19 @@
 		resId = pop();
 		push(getWizPixelColor(rtImage, resId, state, x, y, 0));
 		break;
-	case 100: // SO_GET_WIZ_HISTOGRAM
-		pop();
-		pop();
-		pop();
-		pop();
-		pop();
-		pop();
-		push(0);
+	case 100:
+		h = pop();
+		w = pop();
+		y = pop();
+		x = pop();
+		state = pop();
+		resId = pop();
+		if (x == -1 && y == -1 && w == -1 && h == -1) {
+			getWizImageDim(resId, state, w, h);
+			x = 0;
+			y = 0;
+		}		
+		push(computeWizHistogram(resId, state, x, y, w, h));		
 		break;
 	case 109:
 		pop();
@@ -1288,10 +1349,8 @@
 		push(0);
 		break;		
 	default:
-		error("o90_unknown29: Unknown case %d", subOp);
+		error("o90_getWizData: Unknown case %d", subOp);
 	}
-
-	debug(1,"o90_unknown29 stub (%d)", subOp);
 }
 
 void ScummEngine_v90he::o90_unknown2F() {





More information about the Scummvm-git-logs mailing list