[Scummvm-cvs-logs] SF.net SVN: scummvm:[39452] scummvm/trunk/engines/cine
buddha_ at users.sourceforge.net
buddha_ at users.sourceforge.net
Mon Mar 16 21:24:28 CET 2009
Revision: 39452
http://scummvm.svn.sourceforge.net/scummvm/?rev=39452&view=rev
Author: buddha_
Date: 2009-03-16 20:24:28 +0000 (Mon, 16 Mar 2009)
Log Message:
-----------
Add endianness handling to Cine::Palette's load and save functions.
Modified Paths:
--------------
scummvm/trunk/engines/cine/pal.cpp
scummvm/trunk/engines/cine/pal.h
Modified: scummvm/trunk/engines/cine/pal.cpp
===================================================================
--- scummvm/trunk/engines/cine/pal.cpp 2009-03-16 19:19:59 UTC (rev 39451)
+++ scummvm/trunk/engines/cine/pal.cpp 2009-03-16 20:24:28 UTC (rev 39452)
@@ -161,6 +161,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;
@@ -168,6 +169,33 @@
return value >> abs(shiftLeft);
}
+/*! \brief Is given endian type big endian? (Handles native endian type too, otherwise this would be trivial). */
+bool isBigEndian(const EndianType endianType) {
+ assert(endianType == NATIVE_ENDIAN || endianType == LITTLE_ENDIAN || endianType == BIG_ENDIAN);
+
+ // Handle explicit little and big endian types here
+ if (endianType != NATIVE_ENDIAN) {
+ return (endianType == BIG_ENDIAN);
+ }
+
+ // Handle native endian type here
+#if defined(SCUMM_BIG_ENDIAN)
+ return true;
+#elif defined(SCUMM_LITTLE_ENDIAN)
+ return false;
+#else
+ #error No endianness defined
+#endif
+}
+
+/*! \brief Calculate byte position of given bit position in a multibyte variable using defined endianness. */
+int bytePos(const int bitPos, const int numBytes, const bool bigEndian) {
+ if (bigEndian)
+ return (numBytes - 1) - (bitPos / 8);
+ else // little endian
+ return bitPos / 8;
+}
+
// a.k.a. palRotate
Palette &Palette::rotateRight(byte firstIndex, byte lastIndex) {
const Color lastColor = _colors[lastIndex];
@@ -183,6 +211,10 @@
return _colors.size();
}
+const EndianType Palette::endianType() const {
+ return (_bigEndian ? BIG_ENDIAN : LITTLE_ENDIAN);
+}
+
Graphics::PixelFormat Palette::colorFormat() const {
return _format;
}
@@ -199,6 +231,10 @@
_bMax = (1 << _bBits) - 1;
}
+void Palette::setEndianType(const EndianType endianType) {
+ _bigEndian = isBigEndian(endianType);
+}
+
// a.k.a. transformPaletteRange
Palette &Palette::saturatedAddColor(byte firstIndex, byte lastIndex, signed r, signed g, signed b) {
assert(firstIndex < colorCount() && lastIndex < colorCount());
@@ -219,37 +255,42 @@
_colors[index].b = CLIP<int>(_colors[index].b + b, 0, _bMax);
}
-Palette &Palette::load(const byte *buf, const uint size, const Graphics::PixelFormat format, const uint numColors) {
+Palette &Palette::load(const byte *buf, const uint size, const Graphics::PixelFormat format, const uint numColors, const EndianType endianType) {
assert(format.bytesPerPixel * numColors <= size); // Make sure there's enough input space
assert(format.aLoss == 8); // No alpha
assert(format.rShift / 8 == (format.rShift + MAX<int>(0, 8 - format.rLoss - 1)) / 8); // R must be inside one byte
assert(format.gShift / 8 == (format.gShift + MAX<int>(0, 8 - format.gLoss - 1)) / 8); // G must be inside one byte
assert(format.bShift / 8 == (format.bShift + MAX<int>(0, 8 - format.bLoss - 1)) / 8); // B must be inside one byte
+ setEndianType(endianType);
setColorFormat(format);
_colors.clear();
_colors.resize(numColors);
+
+ const int rBytePos = bytePos(format.rShift, format.bytesPerPixel, isBigEndian(endianType));
+ const int gBytePos = bytePos(format.gShift, format.bytesPerPixel, isBigEndian(endianType));
+ const int bBytePos = bytePos(format.bShift, format.bytesPerPixel, isBigEndian(endianType));
for (uint i = 0; i < numColors; i++) {
// _rMax, _gMax, _bMax are also used as masks here
- _colors[i].r = (buf[i * format.bytesPerPixel + (format.rShift / 8)] >> (format.rShift % 8)) & _rMax;
- _colors[i].g = (buf[i * format.bytesPerPixel + (format.gShift / 8)] >> (format.gShift % 8)) & _gMax;
- _colors[i].b = (buf[i * format.bytesPerPixel + (format.bShift / 8)] >> (format.bShift % 8)) & _bMax;
+ _colors[i].r = (buf[i * format.bytesPerPixel + rBytePos] >> (format.rShift % 8)) & _rMax;
+ _colors[i].g = (buf[i * format.bytesPerPixel + gBytePos] >> (format.gShift % 8)) & _gMax;
+ _colors[i].b = (buf[i * format.bytesPerPixel + bBytePos] >> (format.bShift % 8)) & _bMax;
}
return *this;
}
-byte *Palette::save(byte *buf, const uint size) const {
- return save(buf, size, colorFormat(), colorCount());
+byte *Palette::save(byte *buf, const uint size, const EndianType endianType) const {
+ return save(buf, size, colorFormat(), colorCount(), endianType);
}
-byte *Palette::save(byte *buf, const uint size, const Graphics::PixelFormat format) const {
- return save(buf, size, format, colorCount());
+byte *Palette::save(byte *buf, const uint size, const Graphics::PixelFormat format, const EndianType endianType) const {
+ return save(buf, size, format, colorCount(), endianType);
}
-byte *Palette::save(byte *buf, const uint size, const Graphics::PixelFormat format, const uint numColors, const byte firstIndex) const {
+byte *Palette::save(byte *buf, const uint size, const Graphics::PixelFormat format, const uint numColors, const EndianType endianType, const byte firstIndex) const {
assert(format.bytesPerPixel * numColors <= size); // Make sure there's enough output space
assert(format.aLoss == 8); // No alpha
assert(format.rShift / 8 == (format.rShift + MAX<int>(0, 8 - format.rLoss - 1)) / 8); // R must be inside one byte
@@ -269,12 +310,16 @@
const byte gMask = ((1 << (8 - format.gLoss)) - 1) << (format.gShift % 8);
const byte bMask = ((1 << (8 - format.bLoss)) - 1) << (format.bShift % 8);
+ const int rBytePos = bytePos(format.rShift, format.bytesPerPixel, isBigEndian(endianType));
+ const int gBytePos = bytePos(format.gShift, format.bytesPerPixel, isBigEndian(endianType));
+ const int bBytePos = bytePos(format.bShift, format.bytesPerPixel, isBigEndian(endianType));
+
// Save the palette to the output in the specified format
for (uint i = firstIndex; i < firstIndex + numColors; i++) {
// _rMax, _gMax, _bMax are also used as masks here
- buf[i * format.bytesPerPixel + (format.rShift / 8)] |= (shiftByteLeft(_colors[i].r, rShiftLeft) & rMask);
- buf[i * format.bytesPerPixel + (format.gShift / 8)] |= (shiftByteLeft(_colors[i].g, gShiftLeft) & gMask);
- buf[i * format.bytesPerPixel + (format.bShift / 8)] |= (shiftByteLeft(_colors[i].b, bShiftLeft) & bMask);
+ 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);
}
// Return the pointer to the output palette
Modified: scummvm/trunk/engines/cine/pal.h
===================================================================
--- scummvm/trunk/engines/cine/pal.h 2009-03-16 19:19:59 UTC (rev 39451)
+++ scummvm/trunk/engines/cine/pal.h 2009-03-16 20:24:28 UTC (rev 39452)
@@ -39,6 +39,15 @@
/*! \brief The color format used by OSystem's setPalette-function. */
static const Graphics::PixelFormat kSystemPalFormat = {4, 0, 0, 0, 8, 0, 8, 16, 0};
+/*! \brief Endian types. Used at least by Palette class's load and save functions.
+ * TODO: Move somewhere more general as this is definitely not Cine-engine specific
+ */
+enum EndianType {
+ NATIVE_ENDIAN,
+ LITTLE_ENDIAN,
+ BIG_ENDIAN
+};
+
struct PalEntry {
char name[10];
byte pal1[16];
@@ -63,45 +72,55 @@
// TODO: Test
class Palette {
public:
- /*! \brief Load palette from buffer with given color format and number of colors.
+ /*! \brief Load palette from buffer with given color format, endianness and number of colors.
* \param buf Input buffer
* \param size Input buffer size in bytes
* \param format Input color format
* \param numColors Number of colors to load
+ * \param endianType The endianness of the colors in the input buffer
*/
- Palette &load(const byte *buf, const uint size, const Graphics::PixelFormat format, const uint numColors);
+ Palette &load(const byte *buf, const uint size, const Graphics::PixelFormat format, const uint numColors, const EndianType endianType);
- /*! \brief Save the whole palette to buffer in original color format.
+ /*! \brief Save the whole palette to buffer in original color format using defined endianness.
* \param buf Output buffer
* \param size Output buffer size in bytes
+ * \param endianType The endian type to use
*/
- byte *save(byte *buf, const uint size) const;
+ byte *save(byte *buf, const uint size, const EndianType endianType) const;
- /*! \brief Save the whole palette to buffer with given color format.
+ /*! \brief Save the whole palette to buffer in given color format using defined endianness.
* \param buf Output buffer
* \param size Output buffer size in bytes
* \param format Output color format
+ * \param endianType The endian type to use
*/
- byte *save(byte *buf, const uint size, const Graphics::PixelFormat format) const;
+ byte *save(byte *buf, const uint size, const Graphics::PixelFormat format, const EndianType endianType) const;
- /*! \brief Save (partial) palette to buffer with given color format.
+ /*! \brief Save (partial) palette to buffer in given color format using defined endianness.
* \param buf Output buffer
* \param size Output buffer size in bytes
* \param format Output color format
* \param numColors Number of colors to save
+ * \param endianType The endian type to use
* \param firstIndex Starting color index (from which onwards to save the colors)
*/
- byte *save(byte *buf, const uint size, const Graphics::PixelFormat format, const uint numColors, const byte firstIndex = 0) const;
+ byte *save(byte *buf, const uint size, const Graphics::PixelFormat format, const uint numColors, const EndianType endianType, const byte firstIndex = 0) const;
Palette &rotateRight(byte firstIndex, byte lastIndex);
Palette &saturatedAddColor(byte firstIndex, byte lastIndex, signed r, signed g, signed b);
uint colorCount() const;
+ /*! \brief The original endian type in which this palette was loaded.
+ * \note This will always return either BIG_ENDIAN or LITTLE_ENDIAN (So no NATIVE_ENDIAN).
+ */
+ const EndianType endianType() const;
+
/*! \brief The original color format in which this palette was loaded. */
Graphics::PixelFormat colorFormat() const;
private:
void setColorFormat(const Graphics::PixelFormat format);
+ void setEndianType(const EndianType endianType);
void saturatedAddColor(byte index, signed r, signed g, signed b);
private:
@@ -109,9 +128,11 @@
uint8 r, g, b;
};
+ // The used source format, its endianness etc.
Graphics::PixelFormat _format;
uint _rBits, _gBits, _bBits;
uint _rMax, _gMax, _bMax;
+ bool _bigEndian;
Common::Array<Color> _colors;
};
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