diff options
| -rw-r--r-- | engines/sci/gui/gui_gfx.cpp | 300 | ||||
| -rw-r--r-- | engines/sci/gui/gui_gfx.h | 7 | ||||
| -rw-r--r-- | engines/sci/gui/gui_picture.cpp | 313 | ||||
| -rw-r--r-- | engines/sci/gui/gui_picture.h | 6 | 
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; | 
