[Scummvm-cvs-logs] SF.net SVN: scummvm: [25436] scummvm/trunk/engines/agos

kirben at users.sourceforge.net kirben at users.sourceforge.net
Fri Feb 9 01:35:58 CET 2007


Revision: 25436
          http://scummvm.svn.sourceforge.net/scummvm/?rev=25436&view=rev
Author:   kirben
Date:     2007-02-08 16:35:57 -0800 (Thu, 08 Feb 2007)

Log Message:
-----------
Add cyx's patch for cleanup for planar conversion code, and support for 32 color planar graphics of Amiga ECS version of Simon the Sorcerer 1.

Modified Paths:
--------------
    scummvm/trunk/engines/agos/agos.h
    scummvm/trunk/engines/agos/gfx.cpp
    scummvm/trunk/engines/agos/res_ami.cpp
    scummvm/trunk/engines/agos/vga.cpp

Modified: scummvm/trunk/engines/agos/agos.h
===================================================================
--- scummvm/trunk/engines/agos/agos.h	2007-02-09 00:06:54 UTC (rev 25435)
+++ scummvm/trunk/engines/agos/agos.h	2007-02-09 00:35:57 UTC (rev 25436)
@@ -1278,6 +1278,7 @@
 	bool drawImages_clip(VC10_state *state);
 
 	void drawImages(VC10_state *state);
+	void drawImages_Amiga(VC10_state *state);
 	void drawImages_Simon(VC10_state *state);
 	void drawImages_Feeble(VC10_state *state);
 
@@ -1336,7 +1337,7 @@
 	byte *getBackGround();
 	byte *getScaleBuf();
 
-	byte *convertclip(const byte *src, uint height, uint width, byte flags);
+	byte *convertclip(const byte *src, bool is32Colors, uint height, uint width, byte flags);
 
 	bool decrunchFile(byte *src, byte *dst, uint32 size);
 	void loadVGABeardFile(uint id);

Modified: scummvm/trunk/engines/agos/gfx.cpp
===================================================================
--- scummvm/trunk/engines/agos/gfx.cpp	2007-02-09 00:06:54 UTC (rev 25435)
+++ scummvm/trunk/engines/agos/gfx.cpp	2007-02-09 00:35:57 UTC (rev 25436)
@@ -425,36 +425,30 @@
 			dst = state->surf_addr + w * 2;		/* edi */
 
 			h = state->draw_height;
-			if ((getGameType() == GType_SIMON1) && getBitFlag(88)) {
-				/* transparency */
-				do {
-					if (mask[0] & 0xF0) {
-						if ((dst[0] & 0x0F0) == 0x20)
+			do {
+				if ((getGameType() == GType_SIMON1) && getBitFlag(88)) {
+					/* transparency */
+						if (mask[0] & 0xF0) {
+							if ((dst[0] & 0x0F0) == 0x20)
+								dst[0] = src[0];
+						}
+						if (mask[0] & 0x0F) {
+							if ((dst[1] & 0x0F0) == 0x20)
+								dst[1] = src[1];
+						}
+				} else {
+					/* no transparency */
+						if (mask[0] & 0xF0)
 							dst[0] = src[0];
-					}
-					if (mask[0] & 0x0F) {
-						if ((dst[1] & 0x0F0) == 0x20)
+						if (mask[0] & 0x0F)
 							dst[1] = src[1];
-					}
-					mask++;
-					dst += state->surf_pitch;
-					src += state->surf2_pitch;
-				} while (--h);
-			} else {
-				/* no transparency */
-				do {
-					if (mask[0] & 0xF0)
-						dst[0] = src[0];
-					if (mask[0] & 0x0F)
-						dst[1] = src[1];
-					mask++;
-					dst += state->surf_pitch;
-					src += state->surf2_pitch;
-				} while (--h);
-			}
+				}
+				mask++;
+				dst += state->surf_pitch;
+				src += state->surf2_pitch;
+			} while (--h);
 		} while (++w != state->draw_width);
-	} else if ((((_lockWord & 0x20) && state->palette == 0) || state->palette == 0xC0) &&
-		getPlatform() != Common::kPlatformAmiga) {
+	} else if ((((_lockWord & 0x20) && state->palette == 0) || state->palette == 0xC0)) {
 		const byte *src;
 		byte *dst;
 		uint h, i;
@@ -589,6 +583,61 @@
 	}
 }
 
+void AGOSEngine::drawImages_Amiga(VC10_state *state) {
+	uint8 *dst;
+	const byte *src;
+	const uint16 *vlut = &_videoWindows[_windowNum * 4];
+
+	if (drawImages_clip(state) == 0)
+		return;
+
+	uint xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
+	uint yoffs = (vlut[1] - _videoWindows[17] + state->y);
+
+	state->surf2_addr += xoffs + yoffs * state->surf_pitch;
+	state->surf_addr += xoffs + yoffs * state->surf2_pitch;
+
+	if (state->flags & kDFMasked) {
+		const byte *mask = state->depack_src + (state->width * state->y_skip * 16) + (state->x_skip * 8);
+		src = state->surf2_addr;
+		dst = state->surf_addr;
+
+		state->draw_width *= 2;
+
+		uint h = state->draw_height;
+		do {
+			for (uint i = 0; i != state->draw_width; i++) {
+				if ((getGameType() == GType_SIMON1) && getBitFlag(88)) {
+					/* transparency */
+					if (mask[i] & 1 && (dst[i] & 1) == 0x20)
+						dst[i] = src[i];
+				} else {
+					/* no transparency */
+					if (mask[i] & 1)
+						dst[i] = src[i];
+				}
+			}
+			dst += state->surf_pitch;
+			src += state->surf2_pitch;
+			mask += state->width * 16;
+		} while (--h);
+	} else {
+		src = state->depack_src + (state->width * state->y_skip * 16) + (state->x_skip * 8);
+		dst = state->surf_addr;
+
+		state->draw_width *= 2;
+
+		uint h = state->draw_height;
+		do {
+			for (uint i = 0; i != state->draw_width; i++)
+				if ((state->flags & kDFNonTrans) || src[i])
+					dst[i] = src[i];
+			dst += _screenWidth;
+			src += state->width * 16;
+		} while (--h);
+	}
+}
+
 void AGOSEngine::drawImages(VC10_state *state) {
 	const uint16 *vlut = &_videoWindows[_windowNum * 4];
 

Modified: scummvm/trunk/engines/agos/res_ami.cpp
===================================================================
--- scummvm/trunk/engines/agos/res_ami.cpp	2007-02-09 00:06:54 UTC (rev 25435)
+++ scummvm/trunk/engines/agos/res_ami.cpp	2007-02-09 00:35:57 UTC (rev 25436)
@@ -29,29 +29,29 @@
 
 namespace AGOS {
 
+enum {
+	kMaxColorDepth = 5
+};
+
 static void uncompressplane(const byte *plane, byte *outptr, uint16 length) {
-	char x;
-	byte y, z;
-	while (length) {
-		x = *plane++;
+	while (length != 0) {
+		char x = *plane++;
 		if (x >= 0) {
-			x += 1;
-			y = *plane++;
-			z = *plane++;
-			while (x) {
+			x++;
+			byte y = *plane++;
+			byte z = *plane++;
+			while (x != 0) {
 				*outptr++ = y;
 				*outptr++ = z;
-				length--;
-				if (length == 0)
+				if (--length == 0)
 					break;
 				x--;
 			}
 		} else {
-			while (x) {
+			while (x != 0) {
 				*outptr++ = *plane++;
 				*outptr++ = *plane++;
-				length--;
-				if (length == 0)
+				if (--length == 0)
 					break;
 				x++;
 			}
@@ -59,183 +59,87 @@
 	}
 }
 
-static void convertcompressedclip(const byte *src, byte *dst, uint16 height, uint16 width) {
-	const byte *plane0, *plane1, *plane2, *plane3;
-	byte *uncbuffer;
-	byte *uncptr0, *uncptr1, *uncptr2, *uncptr3;
-	byte *uncbfrout;
-	byte *uncbfroutptr;
-	uint16 length, i, j, k, word1, word2, word3, word4, cliplength;
-	byte outbyte, outbyte1, x, y;
-	char n;
-	uncbuffer = (byte *)malloc(height * width * 4);
-	uncbfrout = (byte *)malloc(height * width * 4);
-	
-	byte *free_uncbuffer = uncbuffer;
-	byte *free_uncbfrout = uncbfrout;
-	
-	length = width / 16;
-	length *= height;
-	plane0 = READ_BE_UINT16(src) + READ_BE_UINT16(src + 2) + src; src += 4; plane0 += 4;
-	plane1 = READ_BE_UINT16(src) + READ_BE_UINT16(src + 2) + src; src += 4; plane1 += 4;
-	plane2 = READ_BE_UINT16(src) + READ_BE_UINT16(src + 2) + src; src += 4; plane2 += 4;
-	plane3 = READ_BE_UINT16(src) + READ_BE_UINT16(src + 2) + src; src += 4; plane3 += 4;
-	plane0 -= 4;
-	plane1 -= 8;
-	plane2 -= 12;
-	plane3 -= 16;
-	uncptr0 = uncbuffer;
-	uncptr1 = uncptr0+(length * 2);
-	uncptr2 = uncptr1+(length * 2);
-	uncptr3 = uncptr2+(length * 2);
-	uncompressplane(plane0, uncptr0, length);
-	uncompressplane(plane1, uncptr1, length);
-	uncompressplane(plane2, uncptr2, length);
-	uncompressplane(plane3, uncptr3, length);
-	uncbfroutptr = uncbfrout;
-	for (i = 0; i < length; i++) {
-		word1=READ_BE_UINT16(uncptr0); uncptr0 += 2;
-		word2=READ_BE_UINT16(uncptr1); uncptr1 += 2;
-		word3=READ_BE_UINT16(uncptr2); uncptr2 += 2;
-		word4=READ_BE_UINT16(uncptr3); uncptr3 += 2;
-		for (j = 0; j < 8; j++) {
-			outbyte = ((word1 / 32768) + ((word2 / 32768) * 2) + ((word3 / 32768) * 4) + ((word4 / 32768) * 8));
-			word1 <<= 1;
-			word2 <<= 1;
-			word3 <<= 1;
-			word4 <<= 1;
-			outbyte1 = ((word1 / 32768) + ((word2 / 32768) * 2) + ((word3 / 32768) * 4) + ((word4 / 32768) * 8));
-			word1 <<= 1;
-			word2 <<= 1;
-			word3 <<= 1;
-			word4 <<= 1;
-			*uncbfroutptr++ = (outbyte * 16 + outbyte1);
+static void bitplanetochunky(uint16 *w, uint8 colorDepth, uint8 *&dst) {
+	for (int j = 0; j < 8; j++) {
+		byte color1 = 0;
+		byte color2 = 0;
+		for (int p = 0; p < 5; ++p) {
+			if (w[p] & 0x8000) {
+				color1 |= 1 << p;
+			}
+			if (w[p] & 0x4000) {
+				color2 |= 1 << p;
+			}
+			w[p] <<= 2;
 		}
+		if (colorDepth > 4) {
+			*dst++ = color1;
+			*dst++ = color2;
+		} else {
+			*dst++ = (color1 << 4) | color2;
+		}
 	}
-	uncptr0 = uncbuffer;
-	uncptr1 = uncbfrout;
-	uncptr2 = uncbfrout;
-	uncptr3 = uncbfrout;
-	for (i = 0; i < (width / 16); i++) {
-		for (k = 0; k < 8; k++) {
-			for (j = 0; j < height; j++) {
-				*uncptr0++ = *uncptr1;
-				uncptr1 += 8;
-			}
-			uncptr2++;
-			uncptr1 = uncptr2;
+}
+
+static void convertcompressedclip(const byte *src, byte *dst, uint8 colorDepth, uint16 height, uint16 width) {
+	const byte *plane[kMaxColorDepth];
+	byte *uncptr[kMaxColorDepth];
+	uint32 length, i, j;
+	uint16 w[kMaxColorDepth];
+
+	byte *uncbfrout = (byte *)malloc(width * height);
+
+	length = (width + 15) / 16 * height;
+
+	for (i = 0; i < colorDepth; ++i) {
+		plane[i] = src + READ_BE_UINT16(src + i * 4) + READ_BE_UINT16(src + i * 4 + 2);
+		uncptr[i] = (uint8 *)malloc(length * 2);
+		uncompressplane(plane[i], uncptr[i], length);
+		plane[i] = uncptr[i];
+	}
+
+	byte *uncbfroutptr = uncbfrout;
+	for (i = 0; i < length; ++i) {
+		for (j = 0; j < colorDepth; ++j) {
+			w[j] = READ_BE_UINT16(plane[j]); plane[j] += 2;
 		}
-		uncptr3 += (height * 8);
-		uncptr2 = uncptr3;
-		uncptr1 = uncptr2;
+		bitplanetochunky(w, colorDepth, uncbfroutptr);
 	}
-	length *= 8;
-	cliplength = 0;
-	while(1) {
-		if (length == 1) {
-			*dst++ = 0xFF;
-			*dst++ = *uncbuffer;
-			cliplength += 2;
-			break;
+
+	uncbfroutptr = uncbfrout;
+	const int chunkSize = colorDepth > 4 ? 16 : 8;
+	for (i = 0; i < width / 16; ++i) {
+		for (j = 0; j < height; ++j) {
+			memcpy(dst + width * chunkSize / 16 * j + chunkSize * i, uncbfroutptr, chunkSize);
+			uncbfroutptr += chunkSize;
 		}
-		x = *uncbuffer++;
-		y = *uncbuffer++;
-		length -= 2;
-		if (x == y) {
-			n = 1;
-			y = *uncbuffer++;
-			if (length == 0) {
-				*dst++ = n;
-				*dst++ = x;
-				cliplength += 2;
-				break;
-			}
-			length--;
-			while (x == y) 	{
-				n++;
-				y = *uncbuffer++;
-				if (length == 0)
-					break;
-				length--;
-				if(n == 127)
-					break;
-			}
-			*dst++ = n;
-			*dst++ = x;
-			cliplength += 2;
-			uncbuffer--;
-			if (length == 0)
-				break;
-			length++;
-		} else {
-			n =- 1;
-			uncptr0 = dst;
-			dst++;
-			*dst++ = x;
-			cliplength += 2;
-			x = y;
-			y = *uncbuffer++;
-			if (length == 0) {
-				*uncptr0 = n;
-				break;
-			}
-			length--;
-			while (x != y) {
-				if (n == -127)
-					break;
-				n--;
-				*dst++ = x;
-				cliplength++;
-				x = y;
-				y = *uncbuffer++;
-				if (length == 0)
-					break;
-				length--;
-			}
-			*uncptr0 = n;
-			if (length == 0)
-				break;
-			uncbuffer -= 2;
-			length += 2;
-		}
 	}
 
-	free(free_uncbuffer);
-	free(free_uncbfrout);
+	free(uncbfrout);
+	for (i = 0; i < colorDepth; ++i) {
+		free(uncptr[i]);
+  	}
 }
 
-byte *AGOSEngine::convertclip(const byte *src, uint height, uint width, byte flags) {
+byte *AGOSEngine::convertclip(const byte *src, bool is32Colors, uint height, uint width, byte flags) {
+	uint8 colorDepth = is32Colors ? 5 : 4;
+
 	uint32 length, i, j;
-	uint16 word1, word2, word3, word4;
-	byte outbyte, outbyte1;
 
 	free(_planarBuf);
 	_planarBuf = (byte *)malloc(width * height);
 	byte *dst = _planarBuf;
 
 	if (flags & 0x80) {
-		convertcompressedclip(src, dst, height, width);
+		convertcompressedclip(src, dst, colorDepth, height, width);
 	} else {
-		width /= 16;
-		length = height * width;
+		length = (width + 15) / 16 * height;
 		for (i = 0; i < length; i++) {
-			word1 = READ_BE_UINT16(src); src += 2;
-			word2 = READ_BE_UINT16(src); src += 2;
-			word3 = READ_BE_UINT16(src); src += 2;
-			word4 = READ_BE_UINT16(src); src += 2;
-			for (j = 0; j < 8; j++) {
-				outbyte = ((word1 / 32768) + ((word2 / 32768) * 2) + ((word3 / 32768) * 4) + ((word4 / 32768) * 8));
-				word1 <<= 1;
-				word2 <<= 1;
-				word3 <<= 1;
-				word4 <<= 1;
-				outbyte1 = ((word1 / 32768) + ((word2 / 32768) * 2) + ((word3 / 32768) * 4) + ((word4 / 32768) * 8));
-				word1 <<= 1;
-				word2 <<= 1;
-				word3 <<= 1;
-				word4 <<= 1;
-				*dst++ = (outbyte * 16 + outbyte1);
+			uint16 w[kMaxColorDepth];
+			for (j = 0; j < colorDepth; ++j) {
+				w[j] = READ_BE_UINT16(src); src += 2;
 			}
+			bitplanetochunky(w, colorDepth, dst);
 		}
 	}
 

Modified: scummvm/trunk/engines/agos/vga.cpp
===================================================================
--- scummvm/trunk/engines/agos/vga.cpp	2007-02-09 00:06:54 UTC (rev 25435)
+++ scummvm/trunk/engines/agos/vga.cpp	2007-02-09 00:35:57 UTC (rev 25436)
@@ -541,25 +541,39 @@
 }
 
 byte *AGOSEngine::vc10_flip(const byte *src, uint w, uint h) {
-	w *= 8;
-
 	byte *dstPtr;
 	uint i;
 
-	dstPtr = _videoBuf1 + w;
+	if (getFeatures() & GF_32COLOR) {
+		w *= 16;
+		dstPtr = _videoBuf1 + w;
 
-	do {
-		byte *dst = dstPtr;
-		for (i = 0; i != w; ++i) {
-			byte b = src[i];
-			b = (b >> 4) | (b << 4);
-			*--dst = b;
-		}
+		do {
+			byte *dst = dstPtr;
+			for (i = 0; i != w; ++i) {
+				*--dst = src[i];
+			}
 
-		src += w;
-		dstPtr += w;
-	} while (--h);
+			src += w;
+			dstPtr += w;
+		} while (--h);
+	} else {
+		w *= 8;
+		dstPtr = _videoBuf1 + w;
 
+		do {
+			byte *dst = dstPtr;
+			for (i = 0; i != w; ++i) {
+				byte b = src[i];
+				b = (b >> 4) | (b << 4);
+				*--dst = b;
+			}
+
+			src += w;
+			dstPtr += w;
+		} while (--h);
+	}
+
 	return _videoBuf1;
 }
 
@@ -583,10 +597,6 @@
 		state.palette = 0;
 	}
 
-	if (getFeatures() & GF_32COLOR) {
-		state.palette = 0;
-	}
-
 	state.x = (int16)vcReadNextWord();
 	state.x -= _scrollX;
 
@@ -617,15 +627,29 @@
 	if (height == 0 || width == 0)
 		return;
 
-	if (getFeatures() & GF_PLANAR) {
-		state.depack_src = convertclip(state.depack_src, height, width * 16, flags);
-	}
-
 	if (_dumpImages)
 		dumpSingleBitmap(_vgaCurZoneNum, state.image, state.depack_src, width, height,
 											 state.palette);
-	// Check if image is compressed
-	if (getGameType() == GType_FF || getGameType() == GType_PP) {
+	if (getFeatures() & GF_PLANAR) {
+		bool is32Colors = false;
+		if (getGameType() == GType_SIMON1) {
+			if (((_lockWord & 0x20) && !state.palette) || state.palette == 0xC0 ||
+			(getFeatures() & GF_32COLOR)) {
+				is32Colors = true;
+			}
+		}
+
+		state.depack_src = convertclip(state.depack_src, is32Colors, height, width * 16, flags);
+
+		// converted planar clip is already uncompressed
+		if (state.flags & kDFCompressedFlip) {
+			state.flags &= ~kDFCompressedFlip;
+			state.flags |= kDFFlip;
+		}
+		if (state.flags & kDFCompressed) {
+			state.flags &= ~kDFCompressed;
+		}
+	} else if (getGameType() == GType_FF || getGameType() == GType_PP) {
 		if (flags & 0x80) {
 			state.flags |= kDFCompressed;
 		}
@@ -674,6 +698,8 @@
 
 	if (getGameType() == GType_FF || getGameType() == GType_PP) {
 		drawImages_Feeble(&state);
+	} else if (getFeatures() & GF_32COLOR) {
+		drawImages_Amiga(&state);
 	} else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
 		drawImages_Simon(&state);
 	} else {


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list