diff options
author | Filippos Karapetis | 2012-07-24 22:34:03 +0300 |
---|---|---|
committer | Filippos Karapetis | 2012-07-24 22:34:46 +0300 |
commit | 6f351302040be620aa039a7c605f3c23463b27db (patch) | |
tree | 381b86f3bb2424f6f82e18d59056c92fbbec6083 /engines/sci/graphics | |
parent | d83764f05591ab552316fb6aa59ac92abc7c4680 (diff) | |
download | scummvm-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.cpp | 64 | ||||
-rw-r--r-- | engines/sci/graphics/palette.h | 12 | ||||
-rw-r--r-- | engines/sci/graphics/view.cpp | 9 |
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); + } } } } |