aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/cine/pal.cpp83
-rw-r--r--engines/cine/pal.h38
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