aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/engine/kgraphics.cpp17
-rw-r--r--engines/sci/engine/kgraphics32.cpp47
-rw-r--r--engines/sci/graphics/palette.cpp64
-rw-r--r--engines/sci/graphics/palette.h12
-rw-r--r--engines/sci/graphics/view.cpp9
5 files changed, 97 insertions, 52 deletions
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index bd78c56416..55c0202048 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -1228,15 +1228,18 @@ reg_t kRemapColors(EngineState *s, int argc, reg_t *argv) {
switch (operation) {
case 0: { // remap by percent
uint16 percent = argv[1].toUint16();
- g_sci->_gfxPalette->toggleRemap(true);
- g_sci->_gfxPalette->setRemappingPercent(percent);
+ g_sci->_gfxPalette->toggleRemapping(true);
+ g_sci->_gfxPalette->resetRemapping();
+ g_sci->_gfxPalette->setRemappingPercent(254, percent);
}
break;
- case 1: { // set remapping base
- //int16 unk1 = argv[1].toSint16();
- //int16 unk2 = argv[2].toSint16();
- //int16 unk3 = argv[3].toSint16();
- kStub(s, argc, argv);
+ case 1: { // remap by range
+ uint16 from = argv[1].toUint16();
+ uint16 to = argv[2].toUint16();
+ uint16 base = argv[3].toUint16();
+ g_sci->_gfxPalette->toggleRemapping(true);
+ g_sci->_gfxPalette->resetRemapping();
+ g_sci->_gfxPalette->setRemappingRange(254, from, to, base);
}
break;
case 2: // turn remapping off (unused)
diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp
index 1b7b628e7d..7240308f4a 100644
--- a/engines/sci/engine/kgraphics32.cpp
+++ b/engines/sci/engine/kgraphics32.cpp
@@ -737,46 +737,44 @@ reg_t kRemapColors32(EngineState *s, int argc, reg_t *argv) {
uint16 operation = argv[0].toUint16();
switch (operation) {
- case 0: { // Set remapping to base. 0 turns remapping off.
+ case 0: { // turn remapping off
int16 base = (argc >= 2) ? argv[1].toSint16() : 0;
- if (base != 0) // 0 is the default behavior when changing rooms in GK1, thus silencing the warning
- warning("kRemapColors: Set remapping to base %d", base);
+ if (base > 0)
+ warning("kRemapColors(0) called with base %d", base);
+ g_sci->_gfxPalette->toggleRemapping(false);
+ g_sci->_gfxPalette->resetRemapping();
}
- // TODO: Don't turn remapping off always
- g_sci->_gfxPalette->toggleRemap(false);
- g_sci->_gfxPalette->setRemappingPercent(0);
break;
- case 1: { // set remapping base
- //int16 unk1 = argv[1].toSint16();
- //int16 unk2 = argv[2].toSint16();
- //int16 unk3 = argv[3].toSint16();
- //uint16 unk4 = argv[4].toUint16();
- //uint16 unk5 = (argc >= 6) ? argv[5].toUint16() : 0;
- kStub(s, argc, argv);
+ case 1: { // remap by range
+ uint16 color = argv[1].toUint16();
+ uint16 from = argv[2].toUint16();
+ uint16 to = argv[3].toUint16();
+ uint16 base = argv[4].toUint16();
+ uint16 unk5 = (argc >= 6) ? argv[5].toUint16() : 0;
+ if (unk5 > 0)
+ warning("kRemapColors(1) called with 6 parameters, unknown parameter is %d", unk5);
+ g_sci->_gfxPalette->toggleRemapping(true);
+ g_sci->_gfxPalette->setRemappingRange(color, from, to, base);
}
break;
case 2: { // remap by percent
- // TODO: Use the color index. The -10 offset is wrong.
- /*int16 color = argv[1].toSint16();
- if (color >= 10)
- color -= 10;*/
+ uint16 color = argv[1].toUint16();
uint16 percent = argv[2].toUint16(); // 0 - 100
if (argc >= 4)
warning("RemapByPercent called with 4 parameters, unknown parameter is %d", argv[3].toUint16());
- g_sci->_gfxPalette->toggleRemap(true);
- g_sci->_gfxPalette->setRemappingPercent(percent);
+ g_sci->_gfxPalette->toggleRemapping(true);
+ g_sci->_gfxPalette->setRemappingPercent(color, percent);
}
break;
case 3: { // remap to gray
- // NOTE: This adjusts the alpha value of a specific color, and it operates on
- // an RGBA palette
int16 color = argv[1].toSint16(); // this is subtracted from a maximum color value, and can be offset by 10
int16 percent = argv[2].toSint16(); // 0 - 100
uint16 unk3 = (argc >= 4) ? argv[3].toUint16() : 0;
warning("kRemapColors: RemapToGray color %d by %d percent (unk3 = %d)", color, percent, unk3);
+ // TODO
}
break;
- case 4: { // unknown
+ case 4: { // remap to percent gray
//int16 unk1 = argv[1].toSint16();
//uint16 unk2 = argv[2].toUint16();
//uint16 unk3 = argv[3].toUint16();
@@ -784,10 +782,7 @@ reg_t kRemapColors32(EngineState *s, int argc, reg_t *argv) {
kStub(s, argc, argv);
}
break;
- case 5: { // set color intensity
- // TODO: This isn't right, it should be setting a mapping table instead.
- // For PQ4, we can emulate this with kernelSetIntensity(). In QFG4, this
- // won't do.
+ case 5: { // don't map to range
//int16 mapping = argv[1].toSint16();
uint16 intensity = argv[2].toUint16();
// HACK for PQ4
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);
+ }
}
}
}