diff options
| author | Martin Kiewitz | 2009-10-10 17:40:29 +0000 | 
|---|---|---|
| committer | Martin Kiewitz | 2009-10-10 17:40:29 +0000 | 
| commit | 17ee52170789b6d2485cf096309189f7c0bdcb2e (patch) | |
| tree | 7a50808b53e287f46a74bc3b7cb6a993a49d9697 | |
| parent | a15cf067a78f065e1b7f0893efa8c3fe80f518dd (diff) | |
| download | scummvm-rg350-17ee52170789b6d2485cf096309189f7c0bdcb2e.tar.gz scummvm-rg350-17ee52170789b6d2485cf096309189f7c0bdcb2e.tar.bz2 scummvm-rg350-17ee52170789b6d2485cf096309189f7c0bdcb2e.zip | |
SCI/newgui: intelligent cel undithering implemented
svn-id: r44880
| -rw-r--r-- | engines/sci/gui/gui_view.cpp | 85 | ||||
| -rw-r--r-- | engines/sci/gui/gui_view.h | 1 | 
2 files changed, 81 insertions, 5 deletions
| diff --git a/engines/sci/gui/gui_view.cpp b/engines/sci/gui/gui_view.cpp index cb7c9c5af2..bff2e38e3b 100644 --- a/engines/sci/gui/gui_view.cpp +++ b/engines/sci/gui/gui_view.cpp @@ -335,22 +335,97 @@ byte *SciGuiView::getBitmap(GuiViewLoopNo loopNo, GuiViewCelNo celNo) {  	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); diff --git a/engines/sci/gui/gui_view.h b/engines/sci/gui/gui_view.h index ffee17a026..fdf4ba6353 100644 --- a/engines/sci/gui/gui_view.h +++ b/engines/sci/gui/gui_view.h @@ -65,6 +65,7 @@ public:  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; | 
