[Scummvm-cvs-logs] SF.net SVN: scummvm:[44221] scummvm/trunk/engines/cine/pal.cpp

lordhoto at users.sourceforge.net lordhoto at users.sourceforge.net
Mon Sep 21 00:59:30 CEST 2009


Revision: 44221
          http://scummvm.svn.sourceforge.net/scummvm/?rev=44221&view=rev
Author:   lordhoto
Date:     2009-09-20 22:59:30 +0000 (Sun, 20 Sep 2009)

Log Message:
-----------
Implement more precise palette conversion in Palette::save. This makes the output look more like the original (compared against E-UAE), but still not perfect.

Modified Paths:
--------------
    scummvm/trunk/engines/cine/pal.cpp

Modified: scummvm/trunk/engines/cine/pal.cpp
===================================================================
--- scummvm/trunk/engines/cine/pal.cpp	2009-09-20 19:57:39 UTC (rev 44220)
+++ scummvm/trunk/engines/cine/pal.cpp	2009-09-20 22:59:30 UTC (rev 44221)
@@ -103,14 +103,7 @@
 	}
 }
 
-/*! \brief Shift byte to the left by given amount (Handles negative shifting amounts too, otherwise this would be trivial). */
-byte shiftByteLeft(const byte value, const signed shiftLeft) {
-	if (shiftLeft >= 0)
-		return value << shiftLeft;
-	else // right shift with negative shiftLeft values
-		return value >> abs(shiftLeft);
-}
-
+namespace {
 /*! \brief Is given endian type big endian? (Handles native endian type too, otherwise this would be trivial). */
 bool isBigEndian(const EndianType endian) {
 	assert(endian == CINE_NATIVE_ENDIAN || endian == CINE_LITTLE_ENDIAN || endian == CINE_BIG_ENDIAN);
@@ -138,6 +131,15 @@
 		return bitPos / 8;
 }
 
+/*! \brief Calculate the value of "base" to the power of "power". */
+int power(int base, int power) {
+	int result = 1;
+	while (power--)
+		result *= base;
+	return result;
+}
+} // end of anonymous namespace
+
 // a.k.a. palRotate
 Palette &Palette::rotateRight(byte firstIndex, byte lastIndex, signed rotationAmount) {
 	assert(rotationAmount == 0 || rotationAmount == 1);
@@ -317,25 +319,30 @@
 	// Clear the part of the output palette we're going to be writing to with all black
 	memset(buf, 0, format.bytesPerPixel * numColors);
 
-	// Calculate how much bit shifting the color components need (for positioning them correctly)
-	const signed rShiftLeft = (colorFormat().rLoss - (signed) format.rLoss) + (format.rShift % 8);
-	const signed gShiftLeft = (colorFormat().gLoss - (signed) format.gLoss) + (format.gShift % 8);
-	const signed bShiftLeft = (colorFormat().bLoss - (signed) format.bLoss) + (format.bShift % 8);
+	// Calculate original R/G/B max values
+	const int rOrigMax = power(2, 8 - colorFormat().rLoss) - 1;
+	const int gOrigMax = power(2, 8 - colorFormat().gLoss) - 1;
+	const int bOrigMax = power(2, 8 - colorFormat().bLoss) - 1;
 
-	// Calculate the byte masks for each color component (for masking away excess bits)
-	const byte rMask = format.rMax() << (format.rShift % 8);
-	const byte gMask = format.gMax() << (format.gShift % 8);
-	const byte bMask = format.bMax() << (format.bShift % 8);
+	// Calculate new R/G/B max values
+	const int rNewMax = power(2, 8 - format.rLoss) - 1;
+	const int gNewMax = power(2, 8 - format.gLoss) - 1;
+	const int bNewMax = power(2, 8 - format.bLoss) - 1;
 
+	// Calculate the byte position
 	const int rBytePos = bytePos(format.rShift, format.bytesPerPixel, isBigEndian(endian));
 	const int gBytePos = bytePos(format.gShift, format.bytesPerPixel, isBigEndian(endian));
 	const int bBytePos = bytePos(format.bShift, format.bytesPerPixel, isBigEndian(endian));
 
 	// Save the palette to the output in the specified format
 	for (uint i = firstIndex; i < firstIndex + numColors; i++) {
-		buf[i * format.bytesPerPixel + rBytePos] |= (shiftByteLeft(_colors[i].r, rShiftLeft) & rMask);
-		buf[i * format.bytesPerPixel + gBytePos] |= (shiftByteLeft(_colors[i].g, gShiftLeft) & gMask);
-		buf[i * format.bytesPerPixel + bBytePos] |= (shiftByteLeft(_colors[i].b, bShiftLeft) & bMask);
+		const uint r = (_colors[i].r * rNewMax) / rOrigMax;
+		const uint g = (_colors[i].g * gNewMax) / gOrigMax;
+		const uint b = (_colors[i].b * bNewMax) / bOrigMax;
+	
+		buf[i * format.bytesPerPixel + rBytePos] |= r << (format.rShift % 8);
+		buf[i * format.bytesPerPixel + gBytePos] |= g << (format.gShift % 8);
+		buf[i * format.bytesPerPixel + bBytePos] |= b << (format.bShift % 8);
 	}
 
 	// Return the pointer to the output palette


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