aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
authorColin Snover2016-01-14 10:56:58 -0600
committerColin Snover2016-01-14 17:21:05 -0600
commit8224d321226793c6d7499c1d1548269ef3912327 (patch)
treef1b01fe641fa61fb0da41981154590b236ed6e1d /engines/sci
parent76bd2eeb2e580a6a5d0b883dfc3e6b3c6e84e6b3 (diff)
downloadscummvm-rg350-8224d321226793c6d7499c1d1548269ef3912327.tar.gz
scummvm-rg350-8224d321226793c6d7499c1d1548269ef3912327.tar.bz2
scummvm-rg350-8224d321226793c6d7499c1d1548269ef3912327.zip
SCI: Implement SCI32 kPalette findColor and matchColor
It seems that findColor is used only by kPalette, and matchColor is used only by Remap.
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/graphics/palette.h2
-rw-r--r--engines/sci/graphics/palette32.cpp82
2 files changed, 83 insertions, 1 deletions
diff --git a/engines/sci/graphics/palette.h b/engines/sci/graphics/palette.h
index dfc276fa59..61a8d36cb9 100644
--- a/engines/sci/graphics/palette.h
+++ b/engines/sci/graphics/palette.h
@@ -82,7 +82,7 @@ public:
void kernelSetFlag(uint16 fromColor, uint16 toColor, uint16 flag);
void kernelUnsetFlag(uint16 fromColor, uint16 toColor, uint16 flag);
void kernelSetIntensity(uint16 fromColor, uint16 toColor, uint16 intensity, bool setPalette);
- int16 kernelFindColor(uint16 r, uint16 g, uint16 b);
+ virtual int16 kernelFindColor(uint16 r, uint16 g, uint16 b);
bool kernelAnimate(byte fromColor, byte toColor, int speed);
void kernelAnimateSet();
reg_t kernelSave();
diff --git a/engines/sci/graphics/palette32.cpp b/engines/sci/graphics/palette32.cpp
index 00e502c696..9aa08782a5 100644
--- a/engines/sci/graphics/palette32.cpp
+++ b/engines/sci/graphics/palette32.cpp
@@ -111,6 +111,45 @@ override bool GfxPalette32::kernelSetFromResource(GuiResourceId resourceId, bool
return false;
}
+// In SCI32 engine this method is SOLPalette::Match(Rgb24 *)
+// and is called as PaletteMgr.Current().Match(color)
+override int16 GfxPalette32::kernelFindColor(uint16 r, uint16 g, uint16 b) {
+ // SQ6 SCI32 engine takes the 16-bit r, g, b arguments from the
+ // VM and puts them into al, ah, dl. For compatibility, make sure
+ // to discard any high bits here too
+ r = r & 0xFF;
+ g = g & 0xFF;
+ b = b & 0xFF;
+ int16 bestIndex = 0;
+ int bestDifference = 0xFFFFF;
+ int difference;
+
+ // SQ6 DOS really does check only the first 236 entries
+ for (int i = 0, channelDifference; i < 236; ++i) {
+ difference = _sysPalette.colors[i].r - r;
+ difference *= difference;
+ if (bestDifference <= difference) {
+ continue;
+ }
+
+ channelDifference = _sysPalette.colors[i].g - g;
+ difference += channelDifference * channelDifference;
+ if (bestDifference <= difference) {
+ continue;
+ }
+
+ channelDifference = _sysPalette.colors[i].b - b;
+ difference += channelDifference * channelDifference;
+ if (bestDifference <= difference) {
+ continue;
+ }
+ bestDifference = difference;
+ bestIndex = i;
+ }
+
+ return bestIndex;
+}
+
// TODO: set is overridden for the time being to send palettes coming from
// various draw methods like GfxPicture::drawSci32Vga and GfxView::draw to
// _nextPalette instead of _sysPalette. In the SCI32 engine, CelObj palettes
@@ -123,6 +162,49 @@ override void GfxPalette32::set(Palette *newPalette, bool force, bool forceRealM
submit(*newPalette);
}
+// In SCI32 engine this method is SOLPalette::Match(Rgb24 *, int, int *, int *)
+// and is used by Remap
+// TODO: Anything that calls GfxPalette::matchColor(int, int, int) is going to
+// match using an algorithm from SCI16 engine right now. This needs to be
+// corrected in the future so either nothing calls
+// GfxPalette::matchColor(int, int, int), or it is fixed to match the other
+// SCI32 algorithms.
+int16 GfxPalette32::matchColor(const byte r, const byte g, const byte b, const int defaultDifference, int &lastCalculatedDifference, const bool *const matchTable) {
+ int16 bestIndex = -1;
+ int bestDifference = 0xFFFFF;
+ int difference = defaultDifference;
+
+ // SQ6 DOS really does check only the first 236 entries
+ for (int i = 0, channelDifference; i < 236; ++i) {
+ if (matchTable[i] == 0) {
+ continue;
+ }
+
+ difference = _sysPalette.colors[i].r - r;
+ difference *= difference;
+ if (bestDifference <= difference) {
+ continue;
+ }
+ channelDifference = _sysPalette.colors[i].g - g;
+ difference += channelDifference * channelDifference;
+ if (bestDifference <= difference) {
+ continue;
+ }
+ channelDifference = _sysPalette.colors[i].b - b;
+ difference += channelDifference * channelDifference;
+ if (bestDifference <= difference) {
+ continue;
+ }
+ bestDifference = difference;
+ bestIndex = i;
+ }
+
+ // NOTE: This value is only valid if the last index to
+ // perform a difference calculation was the best index
+ lastCalculatedDifference = difference;
+ return bestIndex;
+}
+
void GfxPalette32::updateForFrame() {
applyAll();
_versionUpdated = false;