Skip to content

Commit

Permalink
SCI: Rewrite the color remapping code to support simultaneous effects
Browse files Browse the repository at this point in the history
Fixes the torch in the full version of QFG4
  • Loading branch information
bluegr committed Jul 24, 2012
1 parent 37b209d commit 537b196
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 30 deletions.
43 changes: 21 additions & 22 deletions engines/sci/graphics/palette.cpp
Expand Up @@ -143,8 +143,9 @@ void GfxPalette::createFromData(byte *data, int bytesLeft, Palette *paletteOut)
memset(paletteOut, 0, sizeof(Palette));

// Setup 1:1 mapping
for (colorNo = 0; colorNo < 256; colorNo++)
for (colorNo = 0; colorNo < 256; colorNo++) {
paletteOut->mapping[colorNo] = colorNo;
}

if (bytesLeft < 37) {
// This happens when loading palette of picture 0 in sq5 - the resource is broken and doesn't contain a full
Expand Down Expand Up @@ -332,18 +333,26 @@ void GfxPalette::set(Palette *newPalette, bool force, bool forceRealMerge) {
}
}

bool GfxPalette::isRemapMask(byte color) {
return (_remapOn && (color >= _remappingMaskFrom && color <= _remappingMaskTo));
byte GfxPalette::remapColor(byte remappedColor, byte screenColor) {
assert(_remapOn);
if (_remappingType[remappedColor] == kRemappingByRange)
return _remappingByRange[screenColor];
else if (_remappingType[remappedColor] == kRemappingByPercent)
return _remappingByPercent[screenColor];
else
error("remapColor(): Color %d isn't remapped", remappedColor);

return 0; // should never reach here
}

void GfxPalette::resetRemapping() {
_remapOn = false;
_remappingMaskFrom = 0;
_remappingMaskTo = 0;
_remappingPercentToSet = 0;

for (int i = 0; i < 256; i++) {
_remappingTable[i] = i;
_remappingType[i] = kRemappingNone;
_remappingByPercent[i] = i;
_remappingByRange[i] = i;
}
}

Expand All @@ -356,28 +365,17 @@ void GfxPalette::setRemappingPercent(byte color, byte percent) {
// copySysPaletteToScreen().
_remappingPercentToSet = percent;

if (_remappingMaskFrom > color || _remappingMaskFrom == 0)
_remappingMaskFrom = color;
if (_remappingMaskTo < color)
_remappingMaskTo = color;
_remappingType[color] = kRemappingByPercent;
}

void GfxPalette::setRemappingRange(byte color, byte from, byte to, byte base) {
_remapOn = true;

for (int i = from; i <= to; i++) {
_remappingTable[i] = i + base;
_remappingByRange[i] = i + base;
}

if (_remappingMaskFrom > color || _remappingMaskFrom == 0)
_remappingMaskFrom = color;
if (_remappingMaskTo < color)
_remappingMaskTo = color;
}

byte GfxPalette::remapColor(byte color) {
assert(_remapOn);
return _remappingTable[color];
_remappingType[color] = kRemappingByRange;
}

bool GfxPalette::insert(Palette *newPalette, Palette *destPalette) {
Expand Down Expand Up @@ -548,7 +546,7 @@ void GfxPalette::copySysPaletteToScreen() {
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);
_remappingByPercent[i] = kernelFindColor(r, g, b);
}
}

Expand Down Expand Up @@ -1060,8 +1058,9 @@ bool GfxPalette::loadClut(uint16 clutId) {
memset(&pal, 0, sizeof(Palette));

// Setup 1:1 mapping
for (int i = 0; i < 256; i++)
for (int i = 0; i < 256; i++) {
pal.mapping[i] = i;
}

// Now load in the palette
for (int i = 1; i <= 236; i++) {
Expand Down
17 changes: 13 additions & 4 deletions engines/sci/graphics/palette.h
Expand Up @@ -31,6 +31,12 @@ namespace Sci {
class ResourceManager;
class GfxScreen;

enum ColorRemappingType {
kRemappingNone = 0,
kRemappingByRange = 1,
kRemappingByPercent = 2
};

/**
* Palette class, handles palette operations like changing intensity, setting up the palette, merging different palettes
*/
Expand All @@ -56,8 +62,10 @@ class GfxPalette : public Common::Serializable {
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);
bool isRemapped(byte color) const {
return _remapOn && (_remappingType[color] != kRemappingNone);
}
byte remapColor(byte remappedColor, byte screenColor);

void setOnScreen();
void copySysPaletteToScreen();
Expand Down Expand Up @@ -130,8 +138,9 @@ class GfxPalette : public Common::Serializable {
uint16 _totalScreenColors;

bool _remapOn;
byte _remappingTable[256];
uint16 _remappingMaskFrom, _remappingMaskTo;
ColorRemappingType _remappingType[256];
byte _remappingByPercent[256];
byte _remappingByRange[256];
uint16 _remappingPercentToSet;

void loadMacIconBarPalette();
Expand Down
8 changes: 4 additions & 4 deletions engines/sci/graphics/view.cpp
Expand Up @@ -742,10 +742,10 @@ 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->isRemapMask(palette->mapping[color])) {
if (!_palette->isRemapped(palette->mapping[color])) {
_screen->putPixel(x2, y2, drawMask, palette->mapping[color], priority, 0);
} else {
byte remappedColor = _palette->remapColor(_screen->getVisual(x2, y2));
byte remappedColor = _palette->remapColor(palette->mapping[color], _screen->getVisual(x2, y2));
_screen->putPixel(x2, y2, drawMask, remappedColor, priority, 0);
}
}
Expand Down Expand Up @@ -857,10 +857,10 @@ 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)) {
if (!_palette->isRemapMask(palette->mapping[color])) {
if (!_palette->isRemapped(palette->mapping[color])) {
_screen->putPixel(x2, y2, drawMask, palette->mapping[color], priority, 0);
} else {
byte remappedColor = _palette->remapColor(_screen->getVisual(x2, y2));
byte remappedColor = _palette->remapColor(palette->mapping[color], _screen->getVisual(x2, y2));
_screen->putPixel(x2, y2, drawMask, remappedColor, priority, 0);
}
}
Expand Down

0 comments on commit 537b196

Please sign in to comment.