[Scummvm-cvs-logs] SF.net SVN: scummvm:[44880] scummvm/trunk/engines/sci/gui

m_kiewitz at users.sourceforge.net m_kiewitz at users.sourceforge.net
Sat Oct 10 19:40:30 CEST 2009


Revision: 44880
          http://scummvm.svn.sourceforge.net/scummvm/?rev=44880&view=rev
Author:   m_kiewitz
Date:     2009-10-10 17:40:29 +0000 (Sat, 10 Oct 2009)

Log Message:
-----------
SCI/newgui: intelligent cel undithering implemented

Modified Paths:
--------------
    scummvm/trunk/engines/sci/gui/gui_view.cpp
    scummvm/trunk/engines/sci/gui/gui_view.h

Modified: scummvm/trunk/engines/sci/gui/gui_view.cpp
===================================================================
--- scummvm/trunk/engines/sci/gui/gui_view.cpp	2009-10-10 17:15:10 UTC (rev 44879)
+++ scummvm/trunk/engines/sci/gui/gui_view.cpp	2009-10-10 17:40:29 UTC (rev 44880)
@@ -335,22 +335,97 @@
 	assert(width * height <= 64000);
 	uint16 pixelCount = width * height;
 	_loop[loopNo].cel[celNo].rawBitmap = new byte[pixelCount];
-	byte *pOut = _loop[loopNo].cel[celNo].rawBitmap;
+	byte *pBitmap = _loop[loopNo].cel[celNo].rawBitmap;
 
 	// Some RLE compressed cels end with the last non-transparent pixel, thats why we fill it up here
 	//  FIXME: change this to fill the remaining bytes within unpackCel()
-	memset(pOut, _loop[loopNo].cel[celNo].clearKey, pixelCount);
-	unpackCel(loopNo, celNo, pOut, pixelCount);
+	memset(pBitmap, _loop[loopNo].cel[celNo].clearKey, pixelCount);
+	unpackCel(loopNo, celNo, pBitmap, pixelCount);
 
+	if (!_resMan->isVGA()) {
+		unditherBitmap(pBitmap, width, height, _loop[loopNo].cel[celNo].clearKey);
+	}
+
 	// mirroring the cel if needed
 	if (_loop[loopNo].mirrorFlag) {
-		for (int i = 0; i < height; i++, pOut += width)
+		for (int i = 0; i < height; i++, pBitmap += width)
 			for (int j = 0; j < width / 2; j++)
-				SWAP(pOut[j], pOut[width - j - 1]);
+				SWAP(pBitmap[j], pBitmap[width - j - 1]);
 	}
 	return _loop[loopNo].cel[celNo].rawBitmap;
 }
 
+// Called after unpacking an EGA cel, this will try to undither (parts) of the cel if the dithering in here
+//  matches dithering used by the current picture
+void SciGuiView::unditherBitmap(byte *bitmapPtr, int16 width, int16 height, byte clearKey) {
+	int16 *unditherMemorial = _screen->unditherGetMemorial();
+
+	// It makes no sense to go further, if no memorial data from current picture is available
+	if (!unditherMemorial)
+		return;
+
+	// Makes no sense to process bitmaps that are 3 pixels wide or less
+	if (width <= 3) return;
+
+	// Walk through the bitmap and remember all combinations of colors
+	int16 bitmapMemorial[SCI_SCREEN_UNDITHERMEMORIAL_SIZE];
+	byte *curPtr;
+	byte color1, color2;
+	int16 y, x;
+
+	memset(&bitmapMemorial, 0, sizeof(bitmapMemorial));
+
+	// Count all seemingly dithered pixel-combinations as soon as at least 4 pixels are adjacent
+	curPtr = bitmapPtr;
+	for (y = 0; y < height; y++) {
+		color1 = (curPtr[0] << 8) | (curPtr[1] << 4); color2 = curPtr[2];
+		curPtr += 3;
+		for (x = 3; x < width; x++) {
+			color1 = (color1 << 4) | (color2 >> 4);
+			color2 = (color2 << 4) | *curPtr++;
+			if (color1 == color2)
+				bitmapMemorial[color1]++;
+		}
+	}
+
+	// Now compare both memorial tables to find out matching dithering-combinations
+	bool unditherTable[SCI_SCREEN_UNDITHERMEMORIAL_SIZE];
+	byte color, unditherCount = 0;
+	memset(&unditherTable, false, sizeof(unditherTable));
+	for (color = 0; color < 255; color++) {
+		if ((bitmapMemorial[color] > 5) && (unditherMemorial[color] > 200)) {
+			// match found, check if colorKey is contained -> if so, we ignore of course
+			color1 = color & 0x0F; color2 = color >> 4;
+			if ((color1 != clearKey) && (color2 != clearKey) && (color1 != color2)) {
+				// so set this and the reversed color-combination for undithering
+				unditherTable[color] = true; unditherTable[(color1 << 4) | color2] = true;
+				unditherCount++;
+			}
+		}
+	}
+
+	// Nothing found to undither -> exit straight away
+	if (!unditherCount)
+		return;
+
+	// We now need to replace color-combinations
+	curPtr = bitmapPtr;
+	for (y = 0; y < height; y++) {
+		color = *curPtr;
+		for (x = 1; x < width; x++) {
+			color = (color << 4) | curPtr[1];
+			if (unditherTable[color]) {
+				// some color with black? turn colors around otherwise it wont be the right color at all
+				if ((color & 0xF0)==0)
+					color = (color << 4) | (color >> 4);
+				curPtr[0] = color; curPtr[1] = color;
+			}
+			curPtr++;
+		}
+		curPtr++;
+	}
+}
+
 void SciGuiView::draw(Common::Rect rect, Common::Rect clipRect, Common::Rect clipRectTranslated, GuiViewLoopNo loopNo, GuiViewCelNo celNo, byte priority, uint16 paletteNo) {
 	GuiPalette *palette = _embeddedPal ? &_viewPalette : &_palette->_sysPalette;
 	sciViewCelInfo *celInfo = getCelInfo(loopNo, celNo);

Modified: scummvm/trunk/engines/sci/gui/gui_view.h
===================================================================
--- scummvm/trunk/engines/sci/gui/gui_view.h	2009-10-10 17:15:10 UTC (rev 44879)
+++ scummvm/trunk/engines/sci/gui/gui_view.h	2009-10-10 17:40:29 UTC (rev 44880)
@@ -65,6 +65,7 @@
 private:
 	void initData(GuiResourceId resourceId);
 	void unpackCel(GuiViewLoopNo loopNo, GuiViewCelNo celNo, byte *outPtr, uint16 pixelCount);
+	void unditherBitmap(byte *bitmap, int16 width, int16 height, byte clearKey);
 
 	ResourceManager *_resMan;
 	SciGuiScreen *_screen;


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