diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/cine/pal.cpp | 84 | ||||
-rw-r--r-- | engines/cine/pal.h | 49 |
2 files changed, 83 insertions, 50 deletions
diff --git a/engines/cine/pal.cpp b/engines/cine/pal.cpp index 97d4b319dd..9fbb51b915 100644 --- a/engines/cine/pal.cpp +++ b/engines/cine/pal.cpp @@ -29,10 +29,6 @@ namespace Cine { -static const Graphics::PixelFormat kLowPalFormat = {2, 5, 5, 5, 8, 8, 4, 0, 0}; -static const Graphics::PixelFormat kHighPalFormat = {3, 0, 0, 0, 8, 0, 8, 16, 0}; -static const Graphics::PixelFormat kSystemPalFormat = {4, 0, 0, 0, 8, 0, 8, 16, 0}; - Common::Array<PalEntry> palArray; static byte paletteBuffer1[16]; static byte paletteBuffer2[16]; @@ -165,6 +161,13 @@ void transformPaletteRange(byte *dstPal, byte *srcPal, int startColor, int stopC } } +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); +} + // a.k.a. palRotate Palette &Palette::rotateRight(byte firstIndex, byte lastIndex) { const Color lastColor = _colors[lastIndex]; @@ -216,16 +219,9 @@ void Palette::saturatedAddColor(byte index, signed r, signed g, signed b) { _colors[index].b = CLIP<int>(_colors[index].b + b, 0, _bMax); } -Palette &Palette::loadCineLowPal(const byte *colors, const uint numColors) { - return load(colors, kLowPalFormat, numColors); -} - -Palette &Palette::loadCineHighPal(const byte *colors, const uint numColors) { - return load(colors, kHighPalFormat, numColors); -} - -Palette &Palette::load(const byte *colors, const Graphics::PixelFormat format, const uint numColors) { - assert(format.aLoss == 8); // No alpha +Palette &Palette::load(const byte *buf, const uint size, const Graphics::PixelFormat format, const uint numColors) { + 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 @@ -237,46 +233,52 @@ Palette &Palette::load(const byte *colors, const Graphics::PixelFormat format, c for (uint i = 0; i < numColors; i++) { // _rMax, _gMax, _bMax are also used as masks here - _colors[i].r = (colors[i * format.bytesPerPixel + (format.rShift / 8)] >> (format.rShift % 8)) & _rMax; - _colors[i].g = (colors[i * format.bytesPerPixel + (format.gShift / 8)] >> (format.gShift % 8)) & _gMax; - _colors[i].b = (colors[i * format.bytesPerPixel + (format.bShift / 8)] >> (format.bShift % 8)) & _bMax; + _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; } return *this; } -byte *Palette::save(byte *colors, const uint numBytes, const Graphics::PixelFormat format) const { - assert(format.bytesPerPixel * colorCount() <= numBytes); // Make sure there's enough output space +byte *Palette::save(byte *buf, const uint size) const { + return save(buf, size, colorFormat(), colorCount()); +} + +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 uint numColors, 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 + 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 // Clear the part of the output palette we're going to be writing to with all black - memset(colors, 0, format.bytesPerPixel * colorCount()); + 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 the byte masks for each color component (for masking away excess bits) + const byte rMask = ((1 << (8 - format.rLoss)) - 1) << (format.rShift % 8); + const byte gMask = ((1 << (8 - format.gLoss)) - 1) << (format.gShift % 8); + const byte bMask = ((1 << (8 - format.bLoss)) - 1) << (format.bShift % 8); // Save the palette to the output in the specified format - for (uint i = 0; i < colorCount(); i++) { + for (uint i = firstIndex; i < firstIndex + numColors; i++) { // _rMax, _gMax, _bMax are also used as masks here - colors[i * format.bytesPerPixel + (format.rShift / 8)] |= ((_colors[i].r & _rMax) << (format.rShift % 8)); - colors[i * format.bytesPerPixel + (format.gShift / 8)] |= ((_colors[i].g & _gMax) << (format.gShift % 8)); - colors[i * format.bytesPerPixel + (format.bShift / 8)] |= ((_colors[i].b & _bMax) << (format.bShift % 8)); + 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); } // Return the pointer to the output palette - return colors; -} - -byte *Palette::saveCineLowPal(byte *colors, const uint numBytes) const { - return save(colors, numBytes, kLowPalFormat); -} - -byte *Palette::saveCineHighPal(byte *colors, const uint numBytes) const { - return save(colors, numBytes, kHighPalFormat); -} - -byte *Palette::saveOrigFormat(byte *colors, const uint numBytes) const { - return save(colors, numBytes, colorFormat()); -} - -byte *Palette::saveSystemFormat(byte *colors, const uint numBytes) const { - return save(colors, numBytes, kSystemPalFormat); + return buf; } } // End of namespace Cine diff --git a/engines/cine/pal.h b/engines/cine/pal.h index 4d59a6e998..23c9007986 100644 --- a/engines/cine/pal.h +++ b/engines/cine/pal.h @@ -30,6 +30,15 @@ namespace Cine { +/*! \brief Low resolution (9-bit) color format used in Cine's 16-color modes. */ +static const Graphics::PixelFormat kLowPalFormat = {2, 5, 5, 5, 8, 8, 4, 0, 0}; + +/*! \brief High resolution (24-bit) color format used in Cine's 256-color modes. */ +static const Graphics::PixelFormat kHighPalFormat = {3, 0, 0, 0, 8, 0, 8, 16, 0}; + +/*! \brief The color format used by OSystem's setPalette-function. */ +static const Graphics::PixelFormat kSystemPalFormat = {4, 0, 0, 0, 8, 0, 8, 16, 0}; + struct PalEntry { char name[10]; byte pal1[16]; @@ -54,19 +63,41 @@ void transformPaletteRange(byte *srcPal, byte *dstPal, int startColor, int stopC // TODO: Test class Palette { public: - Palette &loadCineLowPal(const byte *colors, const uint numColors = 16); - Palette &loadCineHighPal(const byte *colors, const uint numColors = 256); - Palette &load(const byte *colors, const Graphics::PixelFormat format, const uint numColors); - - byte *saveCineLowPal(byte *colors, const uint numBytes) const; - byte *saveCineHighPal(byte *colors, const uint numBytes) const; - byte *saveOrigFormat(byte *colors, const uint numBytes) const; - byte *saveSystemFormat(byte *colors, const uint numBytes) const; - byte *save(byte *colors, const uint numBytes, const Graphics::PixelFormat format) const; + /*! \brief Load palette from buffer with given color format 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 + */ + Palette &load(const byte *buf, const uint size, const Graphics::PixelFormat format, const uint numColors); + + /*! \brief Save the whole palette to buffer in original color format. + * \param buf Output buffer + * \param size Output buffer size in bytes + */ + byte *save(byte *buf, const uint size) const; + + /*! \brief Save the whole palette to buffer with given color format. + * \param buf Output buffer + * \param size Output buffer size in bytes + * \param format Output color format + */ + byte *save(byte *buf, const uint size, const Graphics::PixelFormat format) const; + + /*! \brief Save (partial) palette to buffer with given color format. + * \param buf Output buffer + * \param size Output buffer size in bytes + * \param format Output color format + * \param numColors Number of colors to save + * \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; Palette &rotateRight(byte firstIndex, byte lastIndex); Palette &saturatedAddColor(byte firstIndex, byte lastIndex, signed r, signed g, signed b); uint colorCount() const; + + /*! \brief The original color format in which this palette was loaded. */ Graphics::PixelFormat colorFormat() const; private: |