aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/graphics/picture.cpp
diff options
context:
space:
mode:
authorWillem Jan Palenstijn2011-03-04 18:24:46 +0100
committerWillem Jan Palenstijn2011-03-04 18:24:46 +0100
commitb40b87fdb5b4ee869cce55d852af409896b20c98 (patch)
tree42c05860291234f7989da4a76f796feab5c6cc20 /engines/sci/graphics/picture.cpp
parentef939772b39d3988ad31a77ea0bdc1bc149aa54a (diff)
downloadscummvm-rg350-b40b87fdb5b4ee869cce55d852af409896b20c98.tar.gz
scummvm-rg350-b40b87fdb5b4ee869cce55d852af409896b20c98.tar.bz2
scummvm-rg350-b40b87fdb5b4ee869cce55d852af409896b20c98.zip
SCI: Fix flood fill matching in EGA mode
In EGA games a pixel in the framebuffer is only 4 bits. We store a full byte per pixel to allow undithering, but when comparing pixels for flood-fill purposes, we should only compare the visible color of a pixel. This fixes bug #3078365 in Iceman.
Diffstat (limited to 'engines/sci/graphics/picture.cpp')
-rw-r--r--engines/sci/graphics/picture.cpp24
1 files changed, 19 insertions, 5 deletions
diff --git a/engines/sci/graphics/picture.cpp b/engines/sci/graphics/picture.cpp
index 7e71c1a258..91fa2e71e8 100644
--- a/engines/sci/graphics/picture.cpp
+++ b/engines/sci/graphics/picture.cpp
@@ -866,6 +866,8 @@ void GfxPicture::vectorFloodFill(int16 x, int16 y, byte color, byte priority, by
byte matchedMask, matchMask;
int16 w, e, a_set, b_set;
+ bool isEGA = (_resMan->getViewType() == kViewEga);
+
p.x = x + curPort->left;
p.y = y + curPort->top;
stack.push(p);
@@ -874,6 +876,18 @@ void GfxPicture::vectorFloodFill(int16 x, int16 y, byte color, byte priority, by
byte searchPriority = _screen->getPriority(p.x, p.y);
byte searchControl = _screen->getControl(p.x, p.y);
+ if (isEGA) {
+ // In EGA games a pixel in the framebuffer is only 4 bits. We store
+ // a full byte per pixel to allow undithering, but when comparing
+ // pixels for flood-fill purposes, we should only compare the
+ // visible color of a pixel.
+
+ if ((x ^ y) & 1)
+ searchColor = (searchColor ^ (searchColor >> 4)) & 0x0F;
+ else
+ searchColor = searchColor & 0x0F;
+ }
+
// This logic was taken directly from sierra sci, floodfill will get aborted on various occations
if (screenMask & GFX_SCREEN_MASK_VISUAL) {
if ((color == _screen->getColorWhite()) || (searchColor != _screen->getColorWhite()))
@@ -913,20 +927,20 @@ void GfxPicture::vectorFloodFill(int16 x, int16 y, byte color, byte priority, by
int b = curPort->rect.bottom + curPort->top - 1;
while (stack.size()) {
p = stack.pop();
- if ((matchedMask = _screen->isFillMatch(p.x, p.y, matchMask, searchColor, searchPriority, searchControl)) == 0) // already filled
+ if ((matchedMask = _screen->isFillMatch(p.x, p.y, matchMask, searchColor, searchPriority, searchControl, isEGA)) == 0) // already filled
continue;
_screen->putPixel(p.x, p.y, screenMask, color, priority, control);
w = p.x;
e = p.x;
// moving west and east pointers as long as there is a matching color to fill
- while (w > l && (matchedMask = _screen->isFillMatch(w - 1, p.y, matchMask, searchColor, searchPriority, searchControl)))
+ while (w > l && (matchedMask = _screen->isFillMatch(w - 1, p.y, matchMask, searchColor, searchPriority, searchControl, isEGA)))
_screen->putPixel(--w, p.y, screenMask, color, priority, control);
- while (e < r && (matchedMask = _screen->isFillMatch(e + 1, p.y, matchMask, searchColor, searchPriority, searchControl)))
+ while (e < r && (matchedMask = _screen->isFillMatch(e + 1, p.y, matchMask, searchColor, searchPriority, searchControl, isEGA)))
_screen->putPixel(++e, p.y, screenMask, color, priority, control);
// checking lines above and below for possible flood targets
a_set = b_set = 0;
while (w <= e) {
- if (p.y > t && (matchedMask = _screen->isFillMatch(w, p.y - 1, matchMask, searchColor, searchPriority, searchControl))) { // one line above
+ if (p.y > t && (matchedMask = _screen->isFillMatch(w, p.y - 1, matchMask, searchColor, searchPriority, searchControl, isEGA))) { // one line above
if (a_set == 0) {
p1.x = w;
p1.y = p.y - 1;
@@ -936,7 +950,7 @@ void GfxPicture::vectorFloodFill(int16 x, int16 y, byte color, byte priority, by
} else
a_set = 0;
- if (p.y < b && (matchedMask = _screen->isFillMatch(w, p.y + 1, matchMask, searchColor, searchPriority, searchControl))) { // one line below
+ if (p.y < b && (matchedMask = _screen->isFillMatch(w, p.y + 1, matchMask, searchColor, searchPriority, searchControl, isEGA))) { // one line below
if (b_set == 0) {
p1.x = w;
p1.y = p.y + 1;