diff options
author | Kari Salminen | 2008-11-20 22:16:18 +0000 |
---|---|---|
committer | Kari Salminen | 2008-11-20 22:16:18 +0000 |
commit | 16bf8d720b2b6cc5c19a70c691c443a644ef508e (patch) | |
tree | 0fad283a0607e8518b362a0bb19ebe75e1d83f51 | |
parent | 858cf88c4721d669ec0b4ab47230378cc5ca4e84 (diff) | |
download | scummvm-rg350-16bf8d720b2b6cc5c19a70c691c443a644ef508e.tar.gz scummvm-rg350-16bf8d720b2b6cc5c19a70c691c443a644ef508e.tar.bz2 scummvm-rg350-16bf8d720b2b6cc5c19a70c691c443a644ef508e.zip |
Add Palette-class for handling 9-bit and 24-bit palettes. WIP!
svn-id: r35135
-rw-r--r-- | engines/cine/pal.cpp | 83 | ||||
-rw-r--r-- | engines/cine/pal.h | 38 |
2 files changed, 121 insertions, 0 deletions
diff --git a/engines/cine/pal.cpp b/engines/cine/pal.cpp index 910ed4735a..8dc956a854 100644 --- a/engines/cine/pal.cpp +++ b/engines/cine/pal.cpp @@ -161,4 +161,87 @@ void transformPaletteRange(byte *dstPal, byte *srcPal, int startColor, int stopC } } +byte& Palette::getComponent(byte colorIndex, byte componentIndex) { + assert(colorIndex < getColorCount() && componentIndex < COMPONENTS_PER_COLOR); + return _colors[colorIndex * COMPONENTS_PER_COLOR + componentIndex]; +} + +void Palette::setComponent(byte colorIndex, byte componentIndex, byte value) { + getComponent(colorIndex, componentIndex) = value; +}; + +Palette::PackedColor Palette::getColor(byte colorIndex) { + return (getComponent(colorIndex, R_INDEX) << (R_INDEX * BITS_PER_COMPONENT)) | + (getComponent(colorIndex, G_INDEX) << (G_INDEX * BITS_PER_COMPONENT)) | + (getComponent(colorIndex, B_INDEX) << (B_INDEX * BITS_PER_COMPONENT)) | + (getComponent(colorIndex, A_INDEX) << (A_INDEX * BITS_PER_COMPONENT)); +} + +void Palette::setColor(byte colorIndex, PackedColor color) { + setComponent(colorIndex, R_INDEX, (color >> (R_INDEX * BITS_PER_COMPONENT)) & COMPONENT_MASK); + setComponent(colorIndex, G_INDEX, (color >> (G_INDEX * BITS_PER_COMPONENT)) & COMPONENT_MASK); + setComponent(colorIndex, B_INDEX, (color >> (B_INDEX * BITS_PER_COMPONENT)) & COMPONENT_MASK); + setComponent(colorIndex, A_INDEX, (color >> (A_INDEX * BITS_PER_COMPONENT)) & COMPONENT_MASK); +} + +// a.k.a. palRotate +Palette& Palette::rotateRight(byte firstIndex, byte lastIndex) { + PackedColor lastColor = getColor(lastIndex); + + for (int i = lastIndex; i > firstIndex; i--) { + setColor(i, getColor(i - 1)); + } + + setColor(firstIndex, lastColor); + return *this; +} + +uint Palette::getColorCount() const { + return _colors.size() / COMPONENTS_PER_COLOR; +} + +// a.k.a. transformPaletteRange +Palette& Palette::saturatedAddColor(byte firstIndex, byte lastIndex, signed r, signed g, signed b) { + for (uint i = firstIndex; i <= lastIndex; i++) { + saturatedAddColor(i, r, g, b); + } + return *this; +} + +// a.k.a. transformColor +// Parameter color components (i.e. r, g and b) are in range [-7, 7] +// e.g. r = 7 sets the resulting color's red component to maximum +// e.g. r = -7 sets the resulting color's red component to minimum (i.e. zero) +void Palette::saturatedAddColor(byte index, signed r, signed g, signed b) { + byte newR = CLIP<int>(getComponent(index, R_INDEX) + r * COMPONENT_MUL, 0, COMPONENT_MAX); + byte newG = CLIP<int>(getComponent(index, G_INDEX) + g * COMPONENT_MUL, 0, COMPONENT_MAX); + byte newB = CLIP<int>(getComponent(index, B_INDEX) + b * COMPONENT_MUL, 0, COMPONENT_MAX); + + setComponent(index, R_INDEX, newR); + setComponent(index, G_INDEX, newG); + setComponent(index, B_INDEX, newB); +} + +Palette& Palette::load9BitColors(uint16 *colors, uint colorCount) { + _colors.resize(colorCount); + for (uint i = 0; i < colorCount; i++) { + setComponent(i, R_INDEX, ((colors[i] >> 8) & 7) * COMPONENT_MUL); + setComponent(i, G_INDEX, ((colors[i] >> 4) & 7) * COMPONENT_MUL); + setComponent(i, B_INDEX, ((colors[i] >> 0) & 7) * COMPONENT_MUL); + setComponent(i, A_INDEX, 0); + } + return *this; +} + +Palette& Palette::load24BitColors(byte *colors, uint colorCount) { + _colors.resize(colorCount); + for (uint i = 0; i < colorCount; i++) { + setComponent(i, R_INDEX, colors[i * 3 + 0]); + setComponent(i, G_INDEX, colors[i * 3 + 1]); + setComponent(i, B_INDEX, colors[i * 3 + 2]); + setComponent(i, A_INDEX, 0); + } + return *this; +} + } // End of namespace Cine diff --git a/engines/cine/pal.h b/engines/cine/pal.h index 819680973c..7d7ab8e430 100644 --- a/engines/cine/pal.h +++ b/engines/cine/pal.h @@ -46,6 +46,44 @@ uint16 transformColor(uint16 baseColor, int r, int g, int b); void transformPaletteRange(uint16 *srcPal, uint16 *dstPal, int startColor, int stopColor, int r, int g, int b); void transformPaletteRange(byte *srcPal, byte *dstPal, int startColor, int stopColor, int r, int g, int b); +// This class might be used for handling Cine-engine's palettes in the future. WIP! +// All colors are represented internally as 32-bit RGBA, but +// 9-bit color palettes with 16 colors can be loaded and converted on-the-fly. +// TODO: Add palette saving in the peculiar but used 9-bit color format. +// TODO: Make use of this class. +class Palette { +public: + Palette& load24BitColors(byte *colors, uint colorCount = 256); + Palette& load9BitColors(uint16 *colors, uint colorCount = 16); + Palette& rotateRight(byte firstIndex, byte lastIndex); + Palette& saturatedAddColor(byte firstIndex, byte lastIndex, signed r, signed g, signed b); + uint getColorCount() const; + +private: + static const byte + R_INDEX = 0, + G_INDEX = 1, + B_INDEX = 2, + A_INDEX = 3; + + static const uint + COMPONENTS_PER_COLOR = 4, + BITS_PER_COMPONENT = 8, + COMPONENT_MASK = ((1 << BITS_PER_COMPONENT) - 1), + COMPONENT_MAX = COMPONENT_MASK, + COMPONENT_MUL = COMPONENT_MAX / 7; + + typedef uint32 PackedColor; + + byte& getComponent(byte colorIndex, byte componentIndex); + void setComponent(byte colorIndex, byte componentIndex, byte value); + PackedColor getColor(byte colorIndex); + void setColor(byte colorIndex, PackedColor color); + void saturatedAddColor(byte index, signed r, signed g, signed b); + + Common::Array<byte> _colors; +}; + } // End of namespace Cine #endif |