aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/gui
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/gui')
-rw-r--r--engines/sci/gui/gui_gfx.cpp300
-rw-r--r--engines/sci/gui/gui_gfx.h7
-rw-r--r--engines/sci/gui/gui_picture.cpp313
-rw-r--r--engines/sci/gui/gui_picture.h6
4 files changed, 313 insertions, 313 deletions
diff --git a/engines/sci/gui/gui_gfx.cpp b/engines/sci/gui/gui_gfx.cpp
index 02c23c5528..873b0c1ddb 100644
--- a/engines/sci/gui/gui_gfx.cpp
+++ b/engines/sci/gui/gui_gfx.cpp
@@ -694,238 +694,6 @@ void SciGuiGfx::drawLine(int16 left, int16 top, int16 right, int16 bottom, byte
//ShowBits(&_rThePort->rect,6);
}
-// Bitmap for drawing sierra circles
-static const byte s_patternCircles[8][30] = {
- { 0x01 },
- { 0x4C, 0x02 },
- { 0xCE, 0xF7, 0x7D, 0x0E },
- { 0x1C, 0x3E, 0x7F, 0x7F, 0x7F, 0x3E, 0x1C, 0x00 },
- { 0x38, 0xF8, 0xF3, 0xDF, 0x7F, 0xFF, 0xFD, 0xF7, 0x9F, 0x3F, 0x38 },
- { 0x70, 0xC0, 0x1F, 0xFE, 0xE3, 0x3F, 0xFF, 0xF7, 0x7F, 0xFF, 0xE7, 0x3F, 0xFE, 0xC3, 0x1F, 0xF8, 0x00 },
- { 0xF0, 0x01, 0xFF, 0xE1, 0xFF, 0xF8, 0x3F, 0xFF, 0xDF, 0xFF, 0xF7, 0xFF, 0xFD, 0x7F, 0xFF, 0x9F, 0xFF,
- 0xE3, 0xFF, 0xF0, 0x1F, 0xF0, 0x01 },
- { 0xE0, 0x03, 0xF8, 0x0F, 0xFC, 0x1F, 0xFE, 0x3F, 0xFE, 0x3F, 0xFF, 0x7F, 0xFF, 0x7F, 0xFF, 0x7F, 0xFF,
- 0x7F, 0xFF, 0x7F, 0xFE, 0x3F, 0xFE, 0x3F, 0xFC, 0x1F, 0xF8, 0x0F, 0xE0, 0x03 }
-// { 0x01 };
-// { 0x03, 0x03, 0x03 },
-// { 0x02, 0x07, 0x07, 0x07, 0x02 },
-// { 0x06, 0x06, 0x0F, 0x0F, 0x0F, 0x06, 0x06 },
-// { 0x04, 0x0E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x04 },
-// { 0x0C, 0x1E, 0x1E, 0x1E, 0x3F, 0x3F, 0x3F, 0x1E, 0x1E, 0x1E, 0x0C },
-// { 0x1C, 0x3E, 0x3E, 0x3E, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x3E, 0x3E, 0x3E, 0x1C },
-// { 0x18, 0x3C, 0x7E, 0x7E, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7E, 0x7E, 0x3C, 0x18 }
-};
-
-// TODO: perhaps this is a better way to set the s_patternTextures array below?
-// in that case one would need to adjust bits of secondary table. Bit 256 is ignored by original interpreter
-#if 0
-static const byte patternTextures[32 * 2] = {
- 0x04, 0x29, 0x40, 0x24, 0x09, 0x41, 0x25, 0x45,
- 0x41, 0x90, 0x50, 0x44, 0x48, 0x08, 0x42, 0x28,
- 0x89, 0x52, 0x89, 0x88, 0x10, 0x48, 0xA4, 0x08,
- 0x44, 0x15, 0x28, 0x24, 0x00, 0x0A, 0x24, 0x20,
- // Now the table is actually duplicated, so we won't need to wrap around
- 0x04, 0x29, 0x40, 0x24, 0x09, 0x41, 0x25, 0x45,
- 0x41, 0x90, 0x50, 0x44, 0x48, 0x08, 0x42, 0x28,
- 0x89, 0x52, 0x89, 0x88, 0x10, 0x48, 0xA4, 0x08,
- 0x44, 0x15, 0x28, 0x24, 0x00, 0x0A, 0x24, 0x20,
-};
-#endif
-
-// This table is bitwise upwards (from bit0 to bit7), sierras original table went down the bits (bit7 to bit0)
-// this was done to simplify things, so we can just run through the table w/o worrying too much about clipping
-static const bool s_patternTextures[32 * 8 * 2] = {
- false, false, true, false, false, false, false, false, // 0x04
- true, false, false, true, false, true, false, false, // 0x29
- false, false, false, false, false, false, true, false, // 0x40
- false, false, true, false, false, true, false, false, // 0x24
- true, false, false, true, false, false, false, false, // 0x09
- true, false, false, false, false, false, true, false, // 0x41
- true, false, true, false, false, true, false, false, // 0x25
- true, false, true, false, false, false, true, false, // 0x45
- true, false, false, false, false, false, true, false, // 0x41
- false, false, false, false, true, false, false, true, // 0x90
- false, false, false, false, true, false, true, false, // 0x50
- false, false, true, false, false, false, true, false, // 0x44
- false, false, false, true, false, false, true, false, // 0x48
- false, false, false, true, false, false, false, false, // 0x08
- false, true, false, false, false, false, true, false, // 0x42
- false, false, false, true, false, true, false, false, // 0x28
- true, false, false, true, false, false, false, true, // 0x89
- false, true, false, false, true, false, true, false, // 0x52
- true, false, false, true, false, false, false, true, // 0x89
- false, false, false, true, false, false, false, true, // 0x88
- false, false, false, false, true, false, false, false, // 0x10
- false, false, false, true, false, false, true, false, // 0x48
- false, false, true, false, false, true, false, true, // 0xA4
- false, false, false, true, false, false, false, false, // 0x08
- false, false, true, false, false, false, true, false, // 0x44
- true, false, true, false, true, false, false, false, // 0x15
- false, false, false, true, false, true, false, false, // 0x28
- false, false, true, false, false, true, false, false, // 0x24
- false, false, false, false, false, false, false, false, // 0x00
- false, true, false, true, false, false, false, false, // 0x0A
- false, false, true, false, false, true, false, false, // 0x24
- false, false, false, false, false, true, false, // 0x20 (last bit is not mentioned cause original interpreter also ignores that bit)
- // Now the table is actually duplicated, so we won't need to wrap around
- false, false, true, false, false, false, false, false, // 0x04
- true, false, false, true, false, true, false, false, // 0x29
- false, false, false, false, false, false, true, false, // 0x40
- false, false, true, false, false, true, false, false, // 0x24
- true, false, false, true, false, false, false, false, // 0x09
- true, false, false, false, false, false, true, false, // 0x41
- true, false, true, false, false, true, false, false, // 0x25
- true, false, true, false, false, false, true, false, // 0x45
- true, false, false, false, false, false, true, false, // 0x41
- false, false, false, false, true, false, false, true, // 0x90
- false, false, false, false, true, false, true, false, // 0x50
- false, false, true, false, false, false, true, false, // 0x44
- false, false, false, true, false, false, true, false, // 0x48
- false, false, false, true, false, false, false, false, // 0x08
- false, true, false, false, false, false, true, false, // 0x42
- false, false, false, true, false, true, false, false, // 0x28
- true, false, false, true, false, false, false, true, // 0x89
- false, true, false, false, true, false, true, false, // 0x52
- true, false, false, true, false, false, false, true, // 0x89
- false, false, false, true, false, false, false, true, // 0x88
- false, false, false, false, true, false, false, false, // 0x10
- false, false, false, true, false, false, true, false, // 0x48
- false, false, true, false, false, true, false, true, // 0xA4
- false, false, false, true, false, false, false, false, // 0x08
- false, false, true, false, false, false, true, false, // 0x44
- true, false, true, false, true, false, false, false, // 0x15
- false, false, false, true, false, true, false, false, // 0x28
- false, false, true, false, false, true, false, false, // 0x24
- false, false, false, false, false, false, false, false, // 0x00
- false, true, false, true, false, false, false, false, // 0x0A
- false, false, true, false, false, true, false, false, // 0x24
- false, false, false, false, false, true, false, // 0x20 (last bit is not mentioned cause original interpreter also ignores that bit)
-};
-
-// Bit offsets into pattern_textures
-static const byte s_patternTextureOffset[128] = {
- 0x00, 0x18, 0x30, 0xc4, 0xdc, 0x65, 0xeb, 0x48,
- 0x60, 0xbd, 0x89, 0x05, 0x0a, 0xf4, 0x7d, 0x7d,
- 0x85, 0xb0, 0x8e, 0x95, 0x1f, 0x22, 0x0d, 0xdf,
- 0x2a, 0x78, 0xd5, 0x73, 0x1c, 0xb4, 0x40, 0xa1,
- 0xb9, 0x3c, 0xca, 0x58, 0x92, 0x34, 0xcc, 0xce,
- 0xd7, 0x42, 0x90, 0x0f, 0x8b, 0x7f, 0x32, 0xed,
- 0x5c, 0x9d, 0xc8, 0x99, 0xad, 0x4e, 0x56, 0xa6,
- 0xf7, 0x68, 0xb7, 0x25, 0x82, 0x37, 0x3a, 0x51,
- 0x69, 0x26, 0x38, 0x52, 0x9e, 0x9a, 0x4f, 0xa7,
- 0x43, 0x10, 0x80, 0xee, 0x3d, 0x59, 0x35, 0xcf,
- 0x79, 0x74, 0xb5, 0xa2, 0xb1, 0x96, 0x23, 0xe0,
- 0xbe, 0x05, 0xf5, 0x6e, 0x19, 0xc5, 0x66, 0x49,
- 0xf0, 0xd1, 0x54, 0xa9, 0x70, 0x4b, 0xa4, 0xe2,
- 0xe6, 0xe5, 0xab, 0xe4, 0xd2, 0xaa, 0x4c, 0xe3,
- 0x06, 0x6f, 0xc6, 0x4a, 0xa4, 0x75, 0x97, 0xe1
-};
-
-void SciGuiGfx::Draw_Box(Common::Rect box, byte color, byte prio, byte control) {
- byte flag = _screen->getDrawingMask(color, prio, control);
- int y, x;
-
- for (y = box.top; y < box.bottom; y++) {
- for (x = box.left; x < box.right; x++) {
- _screen->putPixel(x, y, flag, color, prio, control);
- }
- }
-}
-
-void SciGuiGfx::Draw_TexturedBox(Common::Rect box, byte color, byte prio, byte control, byte texture) {
- byte flag = _screen->getDrawingMask(color, prio, control);
- const bool *textureData = &s_patternTextures[s_patternTextureOffset[texture]];
- int y, x;
-
- for (y = box.top; y < box.bottom; y++) {
- for (x = box.left; x < box.right; x++) {
- if (*textureData) {
- _screen->putPixel(x, y, flag, color, prio, control);
- }
- textureData++;
- }
- }
-}
-
-void SciGuiGfx::Draw_Circle(Common::Rect box, byte size, byte color, byte prio, byte control) {
- byte flag = _screen->getDrawingMask(color, prio, control);
- byte *circleData = (byte *)&s_patternCircles[size];
- byte bitmap = *circleData;
- byte bitNo = 0;
- int y, x;
-
- for (y = box.top; y < box.bottom; y++) {
- for (x = box.left; x < box.right; x++) {
- if (bitmap & 1) {
- _screen->putPixel(x, y, flag, color, prio, control);
- }
- bitNo++;
- if (bitNo == 8) {
- circleData++; bitmap = *circleData; bitNo = 0;
- } else {
- bitmap = bitmap >> 1;
- }
- }
- }
-}
-
-void SciGuiGfx::Draw_TexturedCircle(Common::Rect box, byte size, byte color, byte prio, byte control, byte texture) {
- byte flag = _screen->getDrawingMask(color, prio, control);
- byte *circleData = (byte *)&s_patternCircles[size];
- byte bitmap = *circleData;
- byte bitNo = 0;
- const bool *textureData = &s_patternTextures[s_patternTextureOffset[texture]];
- int y, x;
-
- for (y = box.top; y < box.bottom; y++) {
- for (x = box.left; x < box.right; x++) {
- if (bitmap & 1) {
- if (*textureData) {
- _screen->putPixel(x, y, flag, color, prio, control);
- }
- textureData++;
- }
- bitNo++;
- if (bitNo == 8) {
- circleData++; bitmap = *circleData; bitNo = 0;
- } else {
- bitmap = bitmap >> 1;
- }
- }
- }
-}
-
-void SciGuiGfx::Draw_Pattern(int16 x, int16 y, byte color, byte priority, byte control, byte code, byte texture) {
- byte size = code & SCI_PATTERN_CODE_PENSIZE;
- Common::Rect rect;
-
- // We need to adjust the given coordinates, because the ones given us do not define upper left but somewhat middle
- y -= size; if (y < 0) y = 0;
- x -= size; if (x < 0) x = 0;
-
- rect.top = y; rect.left = x;
- rect.setHeight((size*2)+1); rect.setWidth((size*2)+2);
- OffsetRect(rect);
- rect.clip(_screen->_width, _screen->_height);
-
- if (code & SCI_PATTERN_CODE_RECTANGLE) {
- // Rectangle
- if (code & SCI_PATTERN_CODE_USE_TEXTURE) {
- Draw_TexturedBox(rect, color, priority, control, texture);
- } else {
- Draw_Box(rect, color, priority, control);
- }
-
- } else {
- // Circle
- if (code & SCI_PATTERN_CODE_USE_TEXTURE) {
- Draw_TexturedCircle(rect, size, color, priority, control, texture);
- } else {
- Draw_Circle(rect, size, color, priority, control);
- }
- }
-}
-
void SciGuiGfx::Draw_String(const char *text) {
GuiResourceId orgFontId = GetFontId();
int16 orgPenColor = _curPort->penClr;
@@ -935,74 +703,6 @@ void SciGuiGfx::Draw_String(const char *text) {
PenColor(orgPenColor);
}
-// Do not replace w/ some generic code. This algo really needs to behave exactly as the one from sierra
-void SciGuiGfx::FloodFill(int16 x, int16 y, byte color, byte priority, byte control) {
- Common::Stack<Common::Point> stack;
- Common::Point p, p1;
-
- byte screenMask = _screen->getDrawingMask(color, priority, control), matchMask;
- p.x = x + _curPort->left;
- p.y = y + _curPort->top;
- stack.push(p);
-
- byte searchColor = _screen->getVisual(p.x, p.y);
- byte searchPriority = _screen->getPriority(p.x, p.y);
- byte searchControl = _screen->getControl(p.x, p.y);
- int16 w, e, a_set, b_set;
- // if in 1st point priority,control or color is already set to target, clear the flag
- if (screenMask & SCI_SCREEN_MASK_VISUAL && searchColor == color)
- screenMask ^= SCI_SCREEN_MASK_VISUAL;
- if (screenMask & SCI_SCREEN_MASK_PRIORITY && searchPriority == priority)
- screenMask ^= SCI_SCREEN_MASK_PRIORITY;
- if (screenMask & SCI_SCREEN_MASK_CONTROL && searchControl == control)
- screenMask ^= SCI_SCREEN_MASK_CONTROL;
- if (screenMask == 0)// nothing to fill
- return;
-
- // hard borders for filling
- int l = _curPort->rect.left + _curPort->left;
- int t = _curPort->rect.top + _curPort->top;
- int r = _curPort->rect.right + _curPort->left - 1;
- int b = _curPort->rect.bottom + _curPort->top - 1;
- while (stack.size()) {
- p = stack.pop();
- if ((matchMask = _screen->isFillMatch(p.x, p.y, screenMask, searchColor, searchPriority, searchControl)) == 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 && (matchMask == _screen->isFillMatch(w - 1, p.y, screenMask, searchColor, searchPriority, searchControl)))
- _screen->putPixel(--w, p.y, matchMask, color, priority, control);
- while (e < r && (matchMask == _screen->isFillMatch(e + 1, p.y, screenMask, searchColor, searchPriority, searchControl)))
- _screen->putPixel(++e, p.y, matchMask, color, priority, control);
- // checking lines above and below for possible flood targets
- a_set = b_set = 0;
- while (w <= e) {
- if (p.y > t && (matchMask == _screen->isFillMatch(w, p.y - 1, screenMask, searchColor, searchPriority, searchControl))) { // one line above
- if (a_set == 0) {
- p1.x = w;
- p1.y = p.y - 1;
- stack.push(p1);
- a_set = 1;
- }
- } else
- a_set = 0;
-
- if (p.y < b && (matchMask == _screen->isFillMatch(w, p.y + 1, screenMask, searchColor, searchPriority, searchControl))) { // one line below
- if (b_set == 0) {
- p1.x = w;
- p1.y = p.y + 1;
- stack.push(p1);
- b_set = 1;
- }
- } else
- b_set = 0;
- w++;
- }
- }
-}
-
void SciGuiGfx::drawPicture(GuiResourceId pictureId, int16 animationNr, bool mirroredFlag, bool addToFlag, GuiResourceId paletteId) {
SciGuiPicture *picture;
diff --git a/engines/sci/gui/gui_gfx.h b/engines/sci/gui/gui_gfx.h
index 51d43439bf..0161c03b8b 100644
--- a/engines/sci/gui/gui_gfx.h
+++ b/engines/sci/gui/gui_gfx.h
@@ -106,9 +106,7 @@ public:
void RestoreBits(GuiMemoryHandle memoryHandle);
void drawLine(int16 left, int16 top, int16 right, int16 bottom, byte color, byte prio, byte control);
- void Draw_Pattern(int16 x, int16 y, byte pic_color, byte pic_priority, byte pic_control, byte code, byte texture);
void Draw_String(const char *text);
- void FloodFill(int16 x, int16 y, byte color, byte prio, byte control);
void drawPicture(GuiResourceId pictureId, int16 animationNr, bool mirroredFlag, bool addToFlag, GuiResourceId paletteId);
void drawCel(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, uint16 leftPos, uint16 topPos, byte priority, uint16 paletteNo);
@@ -142,11 +140,6 @@ private:
void DrawText(const char *str, int16 from, int16 len, GuiResourceId orgFontId, int16 orgPenColor);
void ShowText(const char *str, int16 from, int16 len, GuiResourceId orgFontId, int16 orgPenColor);
- void Draw_Box(Common::Rect box, byte color, byte prio, byte control);
- void Draw_TexturedBox(Common::Rect box, byte color, byte prio, byte control, byte texture);
- void Draw_Circle(Common::Rect box, byte size, byte color, byte prio, byte control);
- void Draw_TexturedCircle(Common::Rect box, byte size, byte color, byte prio, byte control, byte texture);
-
EngineState *_s;
SciGuiScreen *_screen;
SciGuiPalette *_palette;
diff --git a/engines/sci/gui/gui_picture.cpp b/engines/sci/gui/gui_picture.cpp
index 4a093be42e..ef5d65b95e 100644
--- a/engines/sci/gui/gui_picture.cpp
+++ b/engines/sci/gui/gui_picture.cpp
@@ -380,7 +380,7 @@ void SciGuiPicture::drawVectorData(byte *data, int dataSize) {
case PIC_OP_FILL: //fill
while (vectorIsNonOpcode(data[curPos])) {
vectorGetAbsCoords(data, curPos, x, y);
- _gfx->FloodFill(x, y, pic_color, pic_priority, pic_control);
+ vectorFloodFill(x, y, pic_color, pic_priority, pic_control);
}
break;
@@ -390,28 +390,28 @@ void SciGuiPicture::drawVectorData(byte *data, int dataSize) {
case PIC_OP_SHORT_PATTERNS:
vectorGetPatternTexture(data, curPos, pattern_Code, pattern_Texture);
vectorGetAbsCoords(data, curPos, x, y);
- _gfx->Draw_Pattern(x, y, pic_color, pic_priority, pic_control, pattern_Code, pattern_Texture);
+ vectorPattern(x, y, pic_color, pic_priority, pic_control, pattern_Code, pattern_Texture);
while (vectorIsNonOpcode(data[curPos])) {
vectorGetPatternTexture(data, curPos, pattern_Code, pattern_Texture);
vectorGetRelCoords(data, curPos, x, y);
- _gfx->Draw_Pattern(x, y, pic_color, pic_priority, pic_control, pattern_Code, pattern_Texture);
+ vectorPattern(x, y, pic_color, pic_priority, pic_control, pattern_Code, pattern_Texture);
}
break;
case PIC_OP_MEDIUM_PATTERNS:
vectorGetPatternTexture(data, curPos, pattern_Code, pattern_Texture);
vectorGetAbsCoords(data, curPos, x, y);
- _gfx->Draw_Pattern(x, y, pic_color, pic_priority, pic_control, pattern_Code, pattern_Texture);
+ vectorPattern(x, y, pic_color, pic_priority, pic_control, pattern_Code, pattern_Texture);
while (vectorIsNonOpcode(data[curPos])) {
vectorGetPatternTexture(data, curPos, pattern_Code, pattern_Texture);
vectorGetRelCoordsMed(data, curPos, x, y);
- _gfx->Draw_Pattern(x, y, pic_color, pic_priority, pic_control, pattern_Code, pattern_Texture);
+ vectorPattern(x, y, pic_color, pic_priority, pic_control, pattern_Code, pattern_Texture);
}
break;
case PIC_OP_ABSOLUTE_PATTERN:
while (vectorIsNonOpcode(data[curPos])) {
vectorGetPatternTexture(data, curPos, pattern_Code, pattern_Texture);
vectorGetAbsCoords(data, curPos, x, y);
- _gfx->Draw_Pattern(x, y, pic_color, pic_priority, pic_control, pattern_Code, pattern_Texture);
+ vectorPattern(x, y, pic_color, pic_priority, pic_control, pattern_Code, pattern_Texture);
}
break;
@@ -556,4 +556,305 @@ void SciGuiPicture::vectorGetPatternTexture(byte *data, int &curPos, int16 patte
}
}
+// Do not replace w/ some generic code. This algo really needs to behave exactly as the one from sierra
+void SciGuiPicture::vectorFloodFill(int16 x, int16 y, byte color, byte priority, byte control) {
+ GuiPort *curPort = _gfx->GetPort();
+ Common::Stack<Common::Point> stack;
+ Common::Point p, p1;
+
+ byte screenMask = _screen->getDrawingMask(color, priority, control), matchMask;
+ p.x = x + curPort->left;
+ p.y = y + curPort->top;
+ stack.push(p);
+
+ byte searchColor = _screen->getVisual(p.x, p.y);
+ byte searchPriority = _screen->getPriority(p.x, p.y);
+ byte searchControl = _screen->getControl(p.x, p.y);
+ int16 w, e, a_set, b_set;
+ // if in 1st point priority,control or color is already set to target, clear the flag
+ if (screenMask & SCI_SCREEN_MASK_VISUAL && searchColor == color)
+ screenMask ^= SCI_SCREEN_MASK_VISUAL;
+ if (screenMask & SCI_SCREEN_MASK_PRIORITY && searchPriority == priority)
+ screenMask ^= SCI_SCREEN_MASK_PRIORITY;
+ if (screenMask & SCI_SCREEN_MASK_CONTROL && searchControl == control)
+ screenMask ^= SCI_SCREEN_MASK_CONTROL;
+ if (screenMask == 0)// nothing to fill
+ return;
+
+ // hard borders for filling
+ int l = curPort->rect.left + curPort->left;
+ int t = curPort->rect.top + curPort->top;
+ int r = curPort->rect.right + curPort->left - 1;
+ int b = curPort->rect.bottom + curPort->top - 1;
+ while (stack.size()) {
+ p = stack.pop();
+ if ((matchMask = _screen->isFillMatch(p.x, p.y, screenMask, searchColor, searchPriority, searchControl)) == 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 && (matchMask == _screen->isFillMatch(w - 1, p.y, screenMask, searchColor, searchPriority, searchControl)))
+ _screen->putPixel(--w, p.y, matchMask, color, priority, control);
+ while (e < r && (matchMask == _screen->isFillMatch(e + 1, p.y, screenMask, searchColor, searchPriority, searchControl)))
+ _screen->putPixel(++e, p.y, matchMask, color, priority, control);
+ // checking lines above and below for possible flood targets
+ a_set = b_set = 0;
+ while (w <= e) {
+ if (p.y > t && (matchMask == _screen->isFillMatch(w, p.y - 1, screenMask, searchColor, searchPriority, searchControl))) { // one line above
+ if (a_set == 0) {
+ p1.x = w;
+ p1.y = p.y - 1;
+ stack.push(p1);
+ a_set = 1;
+ }
+ } else
+ a_set = 0;
+
+ if (p.y < b && (matchMask == _screen->isFillMatch(w, p.y + 1, screenMask, searchColor, searchPriority, searchControl))) { // one line below
+ if (b_set == 0) {
+ p1.x = w;
+ p1.y = p.y + 1;
+ stack.push(p1);
+ b_set = 1;
+ }
+ } else
+ b_set = 0;
+ w++;
+ }
+ }
+}
+
+// Bitmap for drawing sierra circles
+static const byte vectorPatternCircles[8][30] = {
+ { 0x01 },
+ { 0x4C, 0x02 },
+ { 0xCE, 0xF7, 0x7D, 0x0E },
+ { 0x1C, 0x3E, 0x7F, 0x7F, 0x7F, 0x3E, 0x1C, 0x00 },
+ { 0x38, 0xF8, 0xF3, 0xDF, 0x7F, 0xFF, 0xFD, 0xF7, 0x9F, 0x3F, 0x38 },
+ { 0x70, 0xC0, 0x1F, 0xFE, 0xE3, 0x3F, 0xFF, 0xF7, 0x7F, 0xFF, 0xE7, 0x3F, 0xFE, 0xC3, 0x1F, 0xF8, 0x00 },
+ { 0xF0, 0x01, 0xFF, 0xE1, 0xFF, 0xF8, 0x3F, 0xFF, 0xDF, 0xFF, 0xF7, 0xFF, 0xFD, 0x7F, 0xFF, 0x9F, 0xFF,
+ 0xE3, 0xFF, 0xF0, 0x1F, 0xF0, 0x01 },
+ { 0xE0, 0x03, 0xF8, 0x0F, 0xFC, 0x1F, 0xFE, 0x3F, 0xFE, 0x3F, 0xFF, 0x7F, 0xFF, 0x7F, 0xFF, 0x7F, 0xFF,
+ 0x7F, 0xFF, 0x7F, 0xFE, 0x3F, 0xFE, 0x3F, 0xFC, 0x1F, 0xF8, 0x0F, 0xE0, 0x03 }
+// { 0x01 };
+// { 0x03, 0x03, 0x03 },
+// { 0x02, 0x07, 0x07, 0x07, 0x02 },
+// { 0x06, 0x06, 0x0F, 0x0F, 0x0F, 0x06, 0x06 },
+// { 0x04, 0x0E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x04 },
+// { 0x0C, 0x1E, 0x1E, 0x1E, 0x3F, 0x3F, 0x3F, 0x1E, 0x1E, 0x1E, 0x0C },
+// { 0x1C, 0x3E, 0x3E, 0x3E, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x3E, 0x3E, 0x3E, 0x1C },
+// { 0x18, 0x3C, 0x7E, 0x7E, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7E, 0x7E, 0x3C, 0x18 }
+};
+
+// TODO: perhaps this is a better way to set the s_patternTextures array below?
+// in that case one would need to adjust bits of secondary table. Bit 256 is ignored by original interpreter
+#if 0
+static const byte patternTextures[32 * 2] = {
+ 0x04, 0x29, 0x40, 0x24, 0x09, 0x41, 0x25, 0x45,
+ 0x41, 0x90, 0x50, 0x44, 0x48, 0x08, 0x42, 0x28,
+ 0x89, 0x52, 0x89, 0x88, 0x10, 0x48, 0xA4, 0x08,
+ 0x44, 0x15, 0x28, 0x24, 0x00, 0x0A, 0x24, 0x20,
+ // Now the table is actually duplicated, so we won't need to wrap around
+ 0x04, 0x29, 0x40, 0x24, 0x09, 0x41, 0x25, 0x45,
+ 0x41, 0x90, 0x50, 0x44, 0x48, 0x08, 0x42, 0x28,
+ 0x89, 0x52, 0x89, 0x88, 0x10, 0x48, 0xA4, 0x08,
+ 0x44, 0x15, 0x28, 0x24, 0x00, 0x0A, 0x24, 0x20,
+};
+#endif
+
+// This table is bitwise upwards (from bit0 to bit7), sierras original table went down the bits (bit7 to bit0)
+// this was done to simplify things, so we can just run through the table w/o worrying too much about clipping
+static const bool vectorPatternTextures[32 * 8 * 2] = {
+ false, false, true, false, false, false, false, false, // 0x04
+ true, false, false, true, false, true, false, false, // 0x29
+ false, false, false, false, false, false, true, false, // 0x40
+ false, false, true, false, false, true, false, false, // 0x24
+ true, false, false, true, false, false, false, false, // 0x09
+ true, false, false, false, false, false, true, false, // 0x41
+ true, false, true, false, false, true, false, false, // 0x25
+ true, false, true, false, false, false, true, false, // 0x45
+ true, false, false, false, false, false, true, false, // 0x41
+ false, false, false, false, true, false, false, true, // 0x90
+ false, false, false, false, true, false, true, false, // 0x50
+ false, false, true, false, false, false, true, false, // 0x44
+ false, false, false, true, false, false, true, false, // 0x48
+ false, false, false, true, false, false, false, false, // 0x08
+ false, true, false, false, false, false, true, false, // 0x42
+ false, false, false, true, false, true, false, false, // 0x28
+ true, false, false, true, false, false, false, true, // 0x89
+ false, true, false, false, true, false, true, false, // 0x52
+ true, false, false, true, false, false, false, true, // 0x89
+ false, false, false, true, false, false, false, true, // 0x88
+ false, false, false, false, true, false, false, false, // 0x10
+ false, false, false, true, false, false, true, false, // 0x48
+ false, false, true, false, false, true, false, true, // 0xA4
+ false, false, false, true, false, false, false, false, // 0x08
+ false, false, true, false, false, false, true, false, // 0x44
+ true, false, true, false, true, false, false, false, // 0x15
+ false, false, false, true, false, true, false, false, // 0x28
+ false, false, true, false, false, true, false, false, // 0x24
+ false, false, false, false, false, false, false, false, // 0x00
+ false, true, false, true, false, false, false, false, // 0x0A
+ false, false, true, false, false, true, false, false, // 0x24
+ false, false, false, false, false, true, false, // 0x20 (last bit is not mentioned cause original interpreter also ignores that bit)
+ // Now the table is actually duplicated, so we won't need to wrap around
+ false, false, true, false, false, false, false, false, // 0x04
+ true, false, false, true, false, true, false, false, // 0x29
+ false, false, false, false, false, false, true, false, // 0x40
+ false, false, true, false, false, true, false, false, // 0x24
+ true, false, false, true, false, false, false, false, // 0x09
+ true, false, false, false, false, false, true, false, // 0x41
+ true, false, true, false, false, true, false, false, // 0x25
+ true, false, true, false, false, false, true, false, // 0x45
+ true, false, false, false, false, false, true, false, // 0x41
+ false, false, false, false, true, false, false, true, // 0x90
+ false, false, false, false, true, false, true, false, // 0x50
+ false, false, true, false, false, false, true, false, // 0x44
+ false, false, false, true, false, false, true, false, // 0x48
+ false, false, false, true, false, false, false, false, // 0x08
+ false, true, false, false, false, false, true, false, // 0x42
+ false, false, false, true, false, true, false, false, // 0x28
+ true, false, false, true, false, false, false, true, // 0x89
+ false, true, false, false, true, false, true, false, // 0x52
+ true, false, false, true, false, false, false, true, // 0x89
+ false, false, false, true, false, false, false, true, // 0x88
+ false, false, false, false, true, false, false, false, // 0x10
+ false, false, false, true, false, false, true, false, // 0x48
+ false, false, true, false, false, true, false, true, // 0xA4
+ false, false, false, true, false, false, false, false, // 0x08
+ false, false, true, false, false, false, true, false, // 0x44
+ true, false, true, false, true, false, false, false, // 0x15
+ false, false, false, true, false, true, false, false, // 0x28
+ false, false, true, false, false, true, false, false, // 0x24
+ false, false, false, false, false, false, false, false, // 0x00
+ false, true, false, true, false, false, false, false, // 0x0A
+ false, false, true, false, false, true, false, false, // 0x24
+ false, false, false, false, false, true, false, // 0x20 (last bit is not mentioned cause original interpreter also ignores that bit)
+};
+
+// Bit offsets into pattern_textures
+static const byte vectorPatternTextureOffset[128] = {
+ 0x00, 0x18, 0x30, 0xc4, 0xdc, 0x65, 0xeb, 0x48,
+ 0x60, 0xbd, 0x89, 0x05, 0x0a, 0xf4, 0x7d, 0x7d,
+ 0x85, 0xb0, 0x8e, 0x95, 0x1f, 0x22, 0x0d, 0xdf,
+ 0x2a, 0x78, 0xd5, 0x73, 0x1c, 0xb4, 0x40, 0xa1,
+ 0xb9, 0x3c, 0xca, 0x58, 0x92, 0x34, 0xcc, 0xce,
+ 0xd7, 0x42, 0x90, 0x0f, 0x8b, 0x7f, 0x32, 0xed,
+ 0x5c, 0x9d, 0xc8, 0x99, 0xad, 0x4e, 0x56, 0xa6,
+ 0xf7, 0x68, 0xb7, 0x25, 0x82, 0x37, 0x3a, 0x51,
+ 0x69, 0x26, 0x38, 0x52, 0x9e, 0x9a, 0x4f, 0xa7,
+ 0x43, 0x10, 0x80, 0xee, 0x3d, 0x59, 0x35, 0xcf,
+ 0x79, 0x74, 0xb5, 0xa2, 0xb1, 0x96, 0x23, 0xe0,
+ 0xbe, 0x05, 0xf5, 0x6e, 0x19, 0xc5, 0x66, 0x49,
+ 0xf0, 0xd1, 0x54, 0xa9, 0x70, 0x4b, 0xa4, 0xe2,
+ 0xe6, 0xe5, 0xab, 0xe4, 0xd2, 0xaa, 0x4c, 0xe3,
+ 0x06, 0x6f, 0xc6, 0x4a, 0xa4, 0x75, 0x97, 0xe1
+};
+
+void SciGuiPicture::vectorPatternBox(Common::Rect box, byte color, byte prio, byte control) {
+ byte flag = _screen->getDrawingMask(color, prio, control);
+ int y, x;
+
+ for (y = box.top; y < box.bottom; y++) {
+ for (x = box.left; x < box.right; x++) {
+ _screen->putPixel(x, y, flag, color, prio, control);
+ }
+ }
+}
+
+void SciGuiPicture::vectorPatternTexturedBox(Common::Rect box, byte color, byte prio, byte control, byte texture) {
+ byte flag = _screen->getDrawingMask(color, prio, control);
+ const bool *textureData = &vectorPatternTextures[vectorPatternTextureOffset[texture]];
+ int y, x;
+
+ for (y = box.top; y < box.bottom; y++) {
+ for (x = box.left; x < box.right; x++) {
+ if (*textureData) {
+ _screen->putPixel(x, y, flag, color, prio, control);
+ }
+ textureData++;
+ }
+ }
+}
+
+void SciGuiPicture::vectorPatternCircle(Common::Rect box, byte size, byte color, byte prio, byte control) {
+ byte flag = _screen->getDrawingMask(color, prio, control);
+ byte *circleData = (byte *)&vectorPatternCircles[size];
+ byte bitmap = *circleData;
+ byte bitNo = 0;
+ int y, x;
+
+ for (y = box.top; y < box.bottom; y++) {
+ for (x = box.left; x < box.right; x++) {
+ if (bitmap & 1) {
+ _screen->putPixel(x, y, flag, color, prio, control);
+ }
+ bitNo++;
+ if (bitNo == 8) {
+ circleData++; bitmap = *circleData; bitNo = 0;
+ } else {
+ bitmap = bitmap >> 1;
+ }
+ }
+ }
+}
+
+void SciGuiPicture::vectorPatternTexturedCircle(Common::Rect box, byte size, byte color, byte prio, byte control, byte texture) {
+ byte flag = _screen->getDrawingMask(color, prio, control);
+ byte *circleData = (byte *)&vectorPatternCircles[size];
+ byte bitmap = *circleData;
+ byte bitNo = 0;
+ const bool *textureData = &vectorPatternTextures[vectorPatternTextureOffset[texture]];
+ int y, x;
+
+ for (y = box.top; y < box.bottom; y++) {
+ for (x = box.left; x < box.right; x++) {
+ if (bitmap & 1) {
+ if (*textureData) {
+ _screen->putPixel(x, y, flag, color, prio, control);
+ }
+ textureData++;
+ }
+ bitNo++;
+ if (bitNo == 8) {
+ circleData++; bitmap = *circleData; bitNo = 0;
+ } else {
+ bitmap = bitmap >> 1;
+ }
+ }
+ }
+}
+
+void SciGuiPicture::vectorPattern(int16 x, int16 y, byte color, byte priority, byte control, byte code, byte texture) {
+ byte size = code & SCI_PATTERN_CODE_PENSIZE;
+ Common::Rect rect;
+
+ // We need to adjust the given coordinates, because the ones given us do not define upper left but somewhat middle
+ y -= size; if (y < 0) y = 0;
+ x -= size; if (x < 0) x = 0;
+
+ rect.top = y; rect.left = x;
+ rect.setHeight((size*2)+1); rect.setWidth((size*2)+2);
+ _gfx->OffsetRect(rect);
+ rect.clip(_screen->_width, _screen->_height);
+
+ if (code & SCI_PATTERN_CODE_RECTANGLE) {
+ // Rectangle
+ if (code & SCI_PATTERN_CODE_USE_TEXTURE) {
+ vectorPatternTexturedBox(rect, color, priority, control, texture);
+ } else {
+ vectorPatternBox(rect, color, priority, control);
+ }
+
+ } else {
+ // Circle
+ if (code & SCI_PATTERN_CODE_USE_TEXTURE) {
+ vectorPatternTexturedCircle(rect, size, color, priority, control, texture);
+ } else {
+ vectorPatternCircle(rect, size, color, priority, control);
+ }
+ }
+}
+
} // End of namespace Sci
diff --git a/engines/sci/gui/gui_picture.h b/engines/sci/gui/gui_picture.h
index f60b5c059e..3b3d31a902 100644
--- a/engines/sci/gui/gui_picture.h
+++ b/engines/sci/gui/gui_picture.h
@@ -48,6 +48,12 @@ private:
void vectorGetRelCoords(byte *data, int &curPos, int16 &x, int16 &y);
void vectorGetRelCoordsMed(byte *data, int &curPos, int16 &x, int16 &y);
void vectorGetPatternTexture(byte *data, int &curPos, int16 pattern_Code, int16 &pattern_Texture);
+ void vectorFloodFill(int16 x, int16 y, byte color, byte prio, byte control);
+ void vectorPattern(int16 x, int16 y, byte pic_color, byte pic_priority, byte pic_control, byte code, byte texture);
+ void vectorPatternBox(Common::Rect box, byte color, byte prio, byte control);
+ void vectorPatternTexturedBox(Common::Rect box, byte color, byte prio, byte control, byte texture);
+ void vectorPatternCircle(Common::Rect box, byte size, byte color, byte prio, byte control);
+ void vectorPatternTexturedCircle(Common::Rect box, byte size, byte color, byte prio, byte control, byte texture);
EngineState *_s;
SciGuiGfx *_gfx;