aboutsummaryrefslogtreecommitdiff
path: root/engines/mads/palette.cpp
diff options
context:
space:
mode:
authorPaul Gilbert2014-05-04 14:32:58 -0400
committerPaul Gilbert2014-05-04 14:32:58 -0400
commitff5b97e75af06e07692eb9ddd9da73055997eefe (patch)
tree2606dcf73787a2d4b041bc41286396f1c03c43a9 /engines/mads/palette.cpp
parentf894b3f1269203793214a750cbd5a9ae022d2d8c (diff)
downloadscummvm-rg350-ff5b97e75af06e07692eb9ddd9da73055997eefe.tar.gz
scummvm-rg350-ff5b97e75af06e07692eb9ddd9da73055997eefe.tar.bz2
scummvm-rg350-ff5b97e75af06e07692eb9ddd9da73055997eefe.zip
MADS: In progress greyscale fading for picking up inventory items
Diffstat (limited to 'engines/mads/palette.cpp')
-rw-r--r--engines/mads/palette.cpp159
1 files changed, 152 insertions, 7 deletions
diff --git a/engines/mads/palette.cpp b/engines/mads/palette.cpp
index 51de2768ed..ad45562181 100644
--- a/engines/mads/palette.cpp
+++ b/engines/mads/palette.cpp
@@ -69,7 +69,7 @@ static bool sortHelper(const PaletteUsage::UsageEntry &ue1, const PaletteUsage::
void PaletteUsage::prioritize(Common::Array<RGB6> &palette) {
for (uint i = 0; i < _data->size(); ++i) {
RGB6 &palEntry = palette[(*_data)[i]._palIndex];
- (*_data)[i]._sortValue = rgbMerge(palEntry);
+ (*_data)[i]._sortValue = _vm->_palette->rgbMerge(palEntry);
}
Common::sort(_data->begin(), _data->end(), sortHelper);
@@ -237,12 +237,6 @@ int PaletteUsage::process(Common::Array<RGB6> &palette, uint flags) {
return rgbIndex;
}
-
-int PaletteUsage::rgbMerge(RGB6 &palEntry) {
- return ((palEntry.r + 1) / 4 - 1) * 38 + ((palEntry.g + 1) / 4 - 1) * 76 +
- ((palEntry.b + 1) / 4 - 1) * 14;
-}
-
void PaletteUsage::transform(Common::Array<RGB6> &palette) {
if (!empty()) {
for (uint i = 0; i < _data->size(); ++i) {
@@ -336,6 +330,157 @@ int RGBList::scan() {
error("RGBList was full");
}
+void RGBList::copy(RGBList &src) {
+ Common::copy(&src._data[0], &src._data[32], &_data[0]);
+}
+
+/*------------------------------------------------------------------------*/
+
+Fader::Fader() {
+ _colorFlags[0] = _colorFlags[1] = _colorFlags[2] = true;
+ _colorFlags[3] = false;
+ _colorValues[0] = _colorValues[1] = 0;
+ _colorValues[2] = _colorValues[3] = 0;
+}
+
+void Fader::fadeToGrey(byte palette[PALETTE_SIZE], byte paletteMap[PALETTE_COUNT],
+ int baseColor, int numColors, int baseGrey, int numGreys,
+ int tickDelay, int steps) {
+ GreyEntry map[PALETTE_COUNT];
+ int intensity;
+ byte palIndex[PALETTE_COUNT][3];
+ bool signs[PALETTE_COUNT][3];
+
+ mapToGreyRamp(palette, baseColor, numColors, baseGrey, numGreys, map);
+
+ for (int palCtr = baseColor; palCtr < (baseColor + numColors); ++palCtr) {
+ int index = palCtr - baseColor;
+ for (int colorCtr = 0; colorCtr < 3; ++colorCtr) {
+ if (_colorFlags[colorCtr]) {
+ int shiftSign = _colorValues[colorCtr];
+ if (shiftSign >= 0) {
+ intensity = map[index]._intensity << shiftSign;
+ } else {
+ intensity = map[index]._intensity >> ABS(shiftSign);
+ }
+ } else {
+ intensity = _colorValues[colorCtr];
+ }
+
+ int diff = intensity - palette[palCtr * 3 + colorCtr];
+ palIndex[palCtr][colorCtr] = (byte)ABS(diff);
+ signs[palCtr][colorCtr] = diff / ABS(diff);
+ }
+ }
+
+ // TODO: More here
+}
+
+static bool greyCompareFunc(const Fader::GreyTableEntry &g1, const Fader::GreyTableEntry &g2) {
+ return g1._list < g2._list;
+}
+
+void Fader::mapToGreyRamp(byte palette[PALETTE_SIZE], int baseColor, int numColors,
+ int baseGrey, int numGreys, GreyEntry *map) {
+ GreyTableEntry greyList[PALETTE_COUNT];
+ byte greyTable[64];
+ byte greyIntensity[64];
+ int intensity, shiftSign;
+
+ getGreyValues(palette, greyList, baseColor, numColors);
+ greyPopularity(greyList, greyTable, numColors);
+
+ for (int idx = 0; idx < numColors; ++idx) {
+ greyList[idx]._mapping = idx;
+ Common::fill(&map[idx]._accum[0], &map[idx]._accum[3], 0);
+ }
+
+ for (int idx = 0; idx < PALETTE_COUNT; ++idx) {
+ map[idx]._mapColor = (byte)idx;
+ }
+
+ // Sort the mapping list
+ Common::sort(&greyList[0], &greyList[numColors], greyCompareFunc);
+
+ // Initialise state variables
+ int greySum = 0;
+ int greyScan = 0;
+ int greyMark = 0;
+ int greyColors = 0;
+ int greyAccum = 0;
+ int firstColor = 0;
+
+ for (int greyCtr = 0; greyCtr < 64; greyCtr++) {
+ for (int idx = 0; idx < greyTable[greyCtr]; idx++) {
+ greySum += greyList[greyScan++]._list;
+ ++greyColors;
+
+ greyAccum += numGreys;
+ while (greyAccum >= numColors) {
+ greyAccum -= numColors;
+ if (greyColors > 0) {
+ greyIntensity[greyMark] = (byte)(greySum / greyColors);
+ }
+
+ for (int rescan = firstColor; rescan < greyScan; ++rescan) {
+ map[greyList[rescan]._mapping]._intensity = greyIntensity[greyMark];
+ map[greyList[rescan]._mapping]._mapColor = (byte)(greyMark + baseGrey);
+ }
+
+ firstColor = greyScan;
+ greySum = 0;
+ greyColors = 0;
+ ++greyMark;
+ }
+ }
+ }
+
+ // Process palette with intensities
+ byte *palP = &palette[baseGrey * 3];
+ for (int greys = 0; greys < numGreys; ++greys) {
+ for (int color = 0; color < 3; ++color) {
+ if (_colorFlags[color]) {
+ shiftSign = (byte)_colorValues[color];
+ if (shiftSign >= 0) {
+ intensity = greyIntensity[greys] << shiftSign;
+ } else {
+ intensity = greyIntensity[greys] >> abs(shiftSign);
+ }
+ } else {
+ intensity = _colorValues[color];
+ }
+ *palP++ = VGA_COLOR_TRANS(intensity);
+ }
+ }
+}
+
+void Fader::getGreyValues(const byte palette[PALETTE_SIZE],
+ GreyTableEntry greyList[PALETTE_COUNT], int baseColor, int numColors) {
+ const byte *palP = &palette[baseColor * 3];
+ GreyTableEntry *destP = greyList;
+
+ for (int i = 0; i < numColors; ++i, palP += 3, ++destP) {
+ int v = rgbMerge(palP[0], palP[1], palP[2]);
+ destP->_list = v >> 7;
+ }
+}
+
+void Fader::greyPopularity(const GreyTableEntry greyList[PALETTE_COUNT],
+ byte greyTable[64], int numColors) {
+ Common::fill(&greyTable[0], &greyTable[64], 0);
+ for (int i = 0; i < 64; ++i) {
+ ++greyTable[greyList[i]._list];
+ }
+}
+
+int Fader::rgbMerge(RGB6 &palEntry) {
+ return rgbMerge(palEntry.r, palEntry.g, palEntry.b);
+}
+
+int Fader::rgbMerge(byte r, byte g, byte b) {
+ return ((r + 1) / 4 - 1) * 38 + ((g + 1) / 4 - 1) * 76 + ((b + 1) / 4 - 1) * 14;
+}
+
/*------------------------------------------------------------------------*/
Palette::Palette(MADSEngine *vm) : _vm(vm), _paletteUsage(vm) {