aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/graphics
diff options
context:
space:
mode:
authorFilippos Karapetis2012-07-24 22:34:03 +0300
committerFilippos Karapetis2012-07-24 22:34:46 +0300
commit6f351302040be620aa039a7c605f3c23463b27db (patch)
tree381b86f3bb2424f6f82e18d59056c92fbbec6083 /engines/sci/graphics
parentd83764f05591ab552316fb6aa59ac92abc7c4680 (diff)
downloadscummvm-rg350-6f351302040be620aa039a7c605f3c23463b27db.tar.gz
scummvm-rg350-6f351302040be620aa039a7c605f3c23463b27db.tar.bz2
scummvm-rg350-6f351302040be620aa039a7c605f3c23463b27db.zip
SCI: More work on color remapping
More transparency/color mapping effects are now working (e.g. the flashlight at the Gedde tomb in GK1, the rays of light at Schloss Ritter in GK1, the torch in the QFG4 demo and the shadows in QFG4, PQ4 and KQ7)
Diffstat (limited to 'engines/sci/graphics')
-rw-r--r--engines/sci/graphics/palette.cpp64
-rw-r--r--engines/sci/graphics/palette.h12
-rw-r--r--engines/sci/graphics/view.cpp9
3 files changed, 66 insertions, 19 deletions
diff --git a/engines/sci/graphics/palette.cpp b/engines/sci/graphics/palette.cpp
index f16d607a29..b5154ef860 100644
--- a/engines/sci/graphics/palette.cpp
+++ b/engines/sci/graphics/palette.cpp
@@ -102,7 +102,7 @@ GfxPalette::GfxPalette(ResourceManager *resMan, GfxScreen *screen)
}
_remapOn = false;
- _remappingPercent = 0;
+ resetRemapping();
}
GfxPalette::~GfxPalette() {
@@ -332,24 +332,62 @@ void GfxPalette::set(Palette *newPalette, bool force, bool forceRealMerge) {
}
}
-bool GfxPalette::isRemapColor(byte color) {
- // TODO: Expand this for SCI32 (more than one remap color can be set).
- // Now, it is assumed that colors 253 and 254 are the remap colors.
- return _remapOn && (color == 253 || color == 254);
+bool GfxPalette::isRemapMask(byte color) {
+ return (_remapOn && (color >= _remappingMaskFrom && color <= _remappingMaskTo));
+}
+
+void GfxPalette::resetRemapping() {
+ _remappingMaskFrom = 0;
+ _remappingMaskTo = 0;
+ _remappingPercentToSet = 0;
+
+ for (int i = 0; i < 256; i++) {
+ _remappingTable[i] = i;
+ }
+}
+
+void GfxPalette::setRemappingPercent(byte color, byte percent) {
+ // We need to defer the setup of the remapping table until something is
+ // shown on screen, otherwise kernelFindColor() won't find correct
+ // colors. The actual setup of the remapping table will be performed in
+ // remapColor().
+ _remappingPercentToSet = percent;
+
+ if (_remappingMaskFrom > color || _remappingMaskFrom == 0)
+ _remappingMaskFrom = color;
+ if (_remappingMaskTo < color)
+ _remappingMaskTo = color;
+}
+
+void GfxPalette::setRemappingRange(byte color, byte from, byte to, byte base) {
+ for (int i = from; i <= to; i++) {
+ _remappingTable[i] = i + base;
+ }
+
+ if (_remappingMaskFrom > color || _remappingMaskFrom == 0)
+ _remappingMaskFrom = color;
+ if (_remappingMaskTo < color)
+ _remappingMaskTo = color;
}
byte GfxPalette::remapColor(byte color) {
assert(_remapOn);
- // TODO: Change this to use a table instead, like the original.
- if (_remappingPercent) {
- byte r = _sysPalette.colors[color].r * _remappingPercent / 100;
- byte g = _sysPalette.colors[color].g * _remappingPercent / 100;
- byte b = _sysPalette.colors[color].b * _remappingPercent / 100;
- return kernelFindColor(r, g, b);
- } else {
- return color;
+ // Check if we need to set remapping by percent. This can only be
+ // performed when something is shown on screen, so that the screen
+ // palette is set up and kernelFindColor() can work correctly.
+ if (_remappingPercentToSet) {
+ for (int i = 0; i < 256; i++) {
+ byte r = _sysPalette.colors[i].r * _remappingPercentToSet / 100;
+ byte g = _sysPalette.colors[i].g * _remappingPercentToSet / 100;
+ byte b = _sysPalette.colors[i].b * _remappingPercentToSet / 100;
+ _remappingTable[i] = kernelFindColor(r, g, b);
+ }
+
+ _remappingPercentToSet = 0;
}
+
+ return _remappingTable[color];
}
bool GfxPalette::insert(Palette *newPalette, Palette *destPalette) {
diff --git a/engines/sci/graphics/palette.h b/engines/sci/graphics/palette.h
index 6774094810..372f3c7090 100644
--- a/engines/sci/graphics/palette.h
+++ b/engines/sci/graphics/palette.h
@@ -53,9 +53,11 @@ public:
void getSys(Palette *pal);
uint16 getTotalColorCount() const { return _totalScreenColors; }
- void toggleRemap(bool remap) { _remapOn = remap; }
- void setRemappingPercent(uint16 percent) { _remappingPercent = percent; }
- bool isRemapColor(byte color);
+ void toggleRemapping(bool remap) { _remapOn = remap; }
+ void resetRemapping();
+ void setRemappingPercent(byte color, byte percent);
+ void setRemappingRange(byte color, byte from, byte to, byte base);
+ bool isRemapMask(byte color);
byte remapColor(byte color);
void setOnScreen();
@@ -129,7 +131,9 @@ private:
uint16 _totalScreenColors;
bool _remapOn;
- uint16 _remappingPercent;
+ byte _remappingTable[256];
+ uint16 _remappingMaskFrom, _remappingMaskTo;
+ uint16 _remappingPercentToSet;
void loadMacIconBarPalette();
byte *_macClut;
diff --git a/engines/sci/graphics/view.cpp b/engines/sci/graphics/view.cpp
index ae135d141c..f68ed1443a 100644
--- a/engines/sci/graphics/view.cpp
+++ b/engines/sci/graphics/view.cpp
@@ -742,7 +742,7 @@ void GfxView::draw(const Common::Rect &rect, const Common::Rect &clipRect, const
const int y2 = clipRectTranslated.top + y;
if (!upscaledHires) {
if (priority >= _screen->getPriority(x2, y2)) {
- if (!_palette->isRemapColor(palette->mapping[color])) {
+ if (!_palette->isRemapMask(palette->mapping[color])) {
_screen->putPixel(x2, y2, drawMask, palette->mapping[color], priority, 0);
} else {
byte remappedColor = _palette->remapColor(_screen->getVisual(x2, y2));
@@ -857,7 +857,12 @@ void GfxView::drawScaled(const Common::Rect &rect, const Common::Rect &clipRect,
const int x2 = clipRectTranslated.left + x;
const int y2 = clipRectTranslated.top + y;
if (color != clearKey && priority >= _screen->getPriority(x2, y2)) {
- _screen->putPixel(x2, y2, drawMask, palette->mapping[color], priority, 0);
+ if (!_palette->isRemapMask(palette->mapping[color])) {
+ _screen->putPixel(x2, y2, drawMask, palette->mapping[color], priority, 0);
+ } else {
+ byte remappedColor = _palette->remapColor(_screen->getVisual(x2, y2));
+ _screen->putPixel(x2, y2, drawMask, remappedColor, priority, 0);
+ }
}
}
}