Example #1
0
void GfxControls16::kernelDrawText(Common::Rect rect, reg_t obj, const char *text, int16 fontId, TextAlignment alignment, int16 style, bool hilite) {
	if (!hilite) {
		rect.grow(1);
		_paint16->eraseRect(rect);
		rect.grow(-1);
	//20140521
		std::map<std::string, std::string>::iterator iter;
		if(g_sci->_ScriptData)
		{		
			_ShouterInfo* pInfo = g_sci->_ScriptData->GetShouterInfo();
			iter = pInfo->SentenceList.find(text);
			if(iter == pInfo->SentenceList.end())
				_text16->Box(text, false, rect, alignment, fontId);
			else
				_text16->Box(iter->second.c_str(), false, rect, alignment, fontId);
		}
		else
		{
			_text16->Box(text, false, rect, alignment, fontId);
		}


		if (style & SCI_CONTROLS_STYLE_SELECTED) {
			_paint16->frameRect(rect);
		}
		if (!getPicNotValid())
			_paint16->bitsShow(rect);
	} else {
		_paint16->invertRect(rect);
		_paint16->bitsShow(rect);
	}
}
Example #2
0
void GfxControls16::drawListControl(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 upperPos, int16 cursorPos, bool isAlias) {
	Common::Rect workerRect = rect;
	GuiResourceId oldFontId = _text16->GetFontId();
	int16 oldPenColor = _ports->_curPort->penClr;
	uint16 fontSize = 0;
	int16 i;
	const char *listEntry;
	int16 listEntryLen;
	int16 lastYpos;

	// draw basic window
	_paint16->eraseRect(workerRect);
	workerRect.grow(1);
	_paint16->frameRect(workerRect);

	// draw UP/DOWN arrows
	//  we draw UP arrow one pixel lower than sierra did, because it looks nicer. Also the DOWN arrow has one pixel
	//  line inbetween as well
	// They "fixed" this in SQ4 by having the arrow character start one pixel line later, we don't adjust there
	if (g_sci->getGameId() != GID_SQ4)
		workerRect.top++;
	_text16->Box(controlListUpArrow, false, workerRect, SCI_TEXT16_ALIGNMENT_CENTER, 0);
	workerRect.top = workerRect.bottom - 10;
	_text16->Box(controlListDownArrow, false, workerRect, SCI_TEXT16_ALIGNMENT_CENTER, 0);

	// Draw inner lines
	workerRect.top = rect.top + 9;
	workerRect.bottom -= 10;
	_paint16->frameRect(workerRect);
	workerRect.grow(-1);

	_text16->SetFont(fontId);
	fontSize = _ports->_curPort->fontHeight;
	_ports->penColor(_ports->_curPort->penClr); _ports->backColor(_ports->_curPort->backClr);
	workerRect.bottom = workerRect.top + fontSize;
	lastYpos = rect.bottom - fontSize;

	// Write actual text
	for (i = upperPos; i < count; i++) {
		_paint16->eraseRect(workerRect);
		listEntry = entries[i];
		if (listEntry[0]) {
			_ports->moveTo(workerRect.left, workerRect.top);
			listEntryLen = strlen(listEntry);
			_text16->Draw(listEntry, 0, MIN(maxChars, listEntryLen), oldFontId, oldPenColor);
			if ((!isAlias) && (i == cursorPos)) {
				_paint16->invertRect(workerRect);
			}
		}
		workerRect.translate(0, fontSize);
		if (workerRect.bottom > lastYpos)
			break;
	}

	_text16->SetFont(oldFontId);
}
Example #3
0
void GfxControls16::kernelDrawButton(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 style, bool hilite) {
	int16 sci0EarlyPen = 0, sci0EarlyBack = 0;
	if (!hilite) {
		if (getSciVersion() == SCI_VERSION_0_EARLY) {
			// SCI0early actually used hardcoded green/black buttons instead of using the port colors
			sci0EarlyPen = _ports->_curPort->penClr;
			sci0EarlyBack = _ports->_curPort->backClr;
			_ports->penColor(0);
			_ports->backColor(2);
		}
		rect.grow(1);
		_paint16->eraseRect(rect);
		_paint16->frameRect(rect);
		rect.grow(-2);
		_ports->textGreyedOutput(!(style & SCI_CONTROLS_STYLE_ENABLED));

	//20140521
		//_text16->Box(text, false, rect, SCI_TEXT16_ALIGNMENT_CENTER, fontId);

		std::map<std::string, std::string>::iterator iter;
		if(g_sci->_ScriptData)
		{		
			_ShouterInfo* pInfo = g_sci->_ScriptData->GetShouterInfo();
			iter = pInfo->SentenceList.find(text);
			if(iter == pInfo->SentenceList.end())
				_text16->Box(text, false, rect, SCI_TEXT16_ALIGNMENT_CENTER, fontId, true);
			else
				_text16->Box(iter->second.c_str(), false, rect, SCI_TEXT16_ALIGNMENT_CENTER, fontId, true);
		}
		else
		{
			_text16->Box(text, false, rect, SCI_TEXT16_ALIGNMENT_CENTER, fontId);
		}
//End

		_ports->textGreyedOutput(false);
		rect.grow(1);
		if (style & SCI_CONTROLS_STYLE_SELECTED)
			_paint16->frameRect(rect);
		if (!getPicNotValid()) {
			rect.grow(1);
			_paint16->bitsShow(rect);
		}
		if (getSciVersion() == SCI_VERSION_0_EARLY) {
			_ports->penColor(sci0EarlyPen);
			_ports->backColor(sci0EarlyBack);
		}
	} else {
		// SCI0early used xor to invert button rectangles resulting in pink/white buttons
		if (getSciVersion() == SCI_VERSION_0_EARLY)
			_paint16->invertRectViaXOR(rect);
		else
			_paint16->invertRect(rect);
		_paint16->bitsShow(rect);
	}
}
Example #4
0
void GfxControls16::kernelDrawText(Common::Rect rect, reg_t obj, const char *text, uint16 languageSplitter, int16 fontId, TextAlignment alignment, int16 style, bool hilite) {
	if (!hilite) {
		rect.grow(1);
		_paint16->eraseRect(rect);
		rect.grow(-1);
		_text16->Box(text, languageSplitter, false, rect, alignment, fontId);
		if (style & SCI_CONTROLS_STYLE_SELECTED) {
			_paint16->frameRect(rect);
		}
		if (!getPicNotValid())
			_paint16->bitsShow(rect);
	} else {
		_paint16->invertRect(rect);
		_paint16->bitsShow(rect);
	}
}
Example #5
0
void GfxControls16::kernelDrawList(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 style, int16 upperPos, int16 cursorPos, bool isAlias, bool hilite) {
	if (!hilite) {
		drawListControl(rect, obj, maxChars, count, entries, fontId, upperPos, cursorPos, isAlias);
		rect.grow(1);
		if (isAlias && (style & SCI_CONTROLS_STYLE_SELECTED)) {
			_paint16->frameRect(rect);
		}
		if (!getPicNotValid())
			_paint16->bitsShow(rect);
	}
}
Example #6
0
void GfxControls16::kernelDrawTextEdit(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 mode, int16 style, int16 cursorPos, int16 maxChars, bool hilite) {
	Common::Rect textRect = rect;
	uint16 oldFontId = _text16->GetFontId();

	rect.grow(1);
	_texteditCursorVisible = false;
	texteditCursorErase();
	_paint16->eraseRect(rect);
	_text16->Box(text, false, textRect, SCI_TEXT16_ALIGNMENT_LEFT, fontId);
	_paint16->frameRect(rect);
	if (style & SCI_CONTROLS_STYLE_SELECTED) {
		_text16->SetFont(fontId);
		rect.grow(-1);
		texteditCursorDraw(rect, text, cursorPos);
		_text16->SetFont(oldFontId);
		rect.grow(1);
	}
	if (!getPicNotValid())
		_paint16->bitsShow(rect);
}
Example #7
0
void DropHighlight::draw(const Common::Rect &) {
	Graphics::Surface *screen = ((PegasusEngine *)g_engine)->_gfx->getWorkArea();

	// Since this is only used in two different ways, I'm only
	// going to implement it in those two ways. Deal with it.

	Common::Rect rect = _bounds;
	rect.grow(-_thickness);
	screen->frameRect(rect, _highlightColor);
	rect.grow(1);
	screen->frameRect(rect, _highlightColor);

	if (_cornerDiameter == 8 && _thickness == 4) {
		rect.grow(1);
		screen->frameRect(rect, _highlightColor);
		screen->hLine(rect.left + 1, rect.top - 1, rect.right - 2, _highlightColor);
		screen->hLine(rect.left + 1, rect.bottom, rect.right - 2, _highlightColor);
		screen->vLine(rect.left - 1, rect.top + 1, rect.bottom - 2, _highlightColor);
		screen->vLine(rect.right, rect.top + 1, rect.bottom - 2, _highlightColor);
	}
}
Example #8
0
void WidgetBase::drawBackground() {
	TattooEngine &vm = *(TattooEngine *)_vm;
	Screen &screen = *_vm->_screen;
	TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;

	Common::Rect bounds = _bounds;

	if (vm._transparentMenus) {
		ui.makeBGArea(bounds);
	} else {
		bounds.grow(-3);
		screen._backBuffer1.fillRect(bounds, MENU_BACKGROUND);
	}
}
Example #9
0
void GfxControls16::kernelDrawButton(Common::Rect rect, reg_t obj, const char *text, uint16 languageSplitter, int16 fontId, int16 style, bool hilite) {
	int16 sci0EarlyPen = 0, sci0EarlyBack = 0;
	if (!hilite) {
		if (getSciVersion() == SCI_VERSION_0_EARLY) {
			// SCI0early actually used hardcoded green/black buttons instead of using the port colors
			sci0EarlyPen = _ports->_curPort->penClr;
			sci0EarlyBack = _ports->_curPort->backClr;
			_ports->penColor(0);
			_ports->backColor(2);
		}
		rect.grow(1);
		_paint16->eraseRect(rect);
		_paint16->frameRect(rect);
		rect.grow(-2);
		_ports->textGreyedOutput(!(style & SCI_CONTROLS_STYLE_ENABLED));
		_text16->Box(text, languageSplitter, false, rect, SCI_TEXT16_ALIGNMENT_CENTER, fontId);
		_ports->textGreyedOutput(false);
		rect.grow(1);
		if (style & SCI_CONTROLS_STYLE_SELECTED)
			_paint16->frameRect(rect);
		if (!getPicNotValid()) {
			rect.grow(1);
			_paint16->bitsShow(rect);
		}
		if (getSciVersion() == SCI_VERSION_0_EARLY) {
			_ports->penColor(sci0EarlyPen);
			_ports->backColor(sci0EarlyBack);
		}
	} else {
		// SCI0early used xor to invert button rectangles resulting in pink/white buttons
		if (getSciVersion() == SCI_VERSION_0_EARLY)
			_paint16->invertRectViaXOR(rect);
		else
			_paint16->invertRect(rect);
		_paint16->bitsShow(rect);
	}
}
Example #10
0
void CSTimeModule::bubbleTextDrawProc(Feature *feature) {
	Common::Rect bounds = feature->_data.bounds;
	bounds.grow(-5);
	const Graphics::Font &font = _vm->getInterface()->getDialogFont();
	uint height = font.getFontHeight();

	Common::Array<Common::String> lines;
	font.wordWrapText(_vm->getInterface()->getCurrBubbleText(), bounds.width(), lines);

	Graphics::Surface *screen = _vm->_system->lockScreen();
	for (int x = -2; x < 2; x++)
		for (int y = -1; y < 3; y++)
			for (uint i = 0; i < lines.size(); i++)
				font.drawString(screen, lines[i], bounds.left + x, bounds.top + y + i*height, bounds.width(), 241, Graphics::kTextAlignCenter);
	for (uint i = 0; i < lines.size(); i++)
		font.drawString(screen, lines[i], bounds.left, bounds.top + i*height, bounds.width(), 32, Graphics::kTextAlignCenter);
	_vm->_system->unlockScreen();
}
Example #11
0
Common::Rect MystAreaSlider::boundingBox() {
	Common::Rect bb;

	bb.top = _rect.top;
	bb.bottom = _rect.bottom;
	bb.left = _rect.left;
	bb.right = _rect.right;

	if (_flagHV & 1) {
		bb.left = _minH - _sliderWidth / 2;
		bb.right = _maxH + _sliderWidth / 2;
	}

	if (_flagHV & 2) {
		bb.top = _minV - _sliderHeight / 2;
		bb.bottom = _maxV + _sliderHeight / 2;
	}

	bb.grow(1);

	return bb;
}
Example #12
0
void WidgetVerbs::highlightVerbControls() {
	Events &events = *_vm->_events;
	Screen &screen = *_vm->_screen;
	Common::Point mousePos = events.mousePos();

	// Get highlighted verb
	_selector = -1;
	Common::Rect bounds = _bounds;
	bounds.grow(-3);
	if (bounds.contains(mousePos))
		_selector = (mousePos.y - bounds.top) / (screen.fontHeight() + 7);

	// See if a new verb is being pointed at
	if (_selector != _oldSelector) {
		// Redraw the verb list
		for (int idx = 0; idx < (int)_verbCommands.size(); ++idx) {
			byte color = (idx == _selector) ? (byte)COMMAND_HIGHLIGHTED : (byte)INFO_TOP;
			_surface.writeString(_verbCommands[idx], Common::Point((_bounds.width() - screen.stringWidth(_verbCommands[idx])) / 2,
				(screen.fontHeight() + 7) * idx + 5), color);
		}

		_oldSelector = _selector;
	}
}
Example #13
0
void GfxPorts::drawWindow(Window *pWnd) {
	if (pWnd->bDrawn)
		return;
	int16 wndStyle = pWnd->wndStyle;

	pWnd->bDrawn = true;
	Port *oldport = setPort(_wmgrPort);
	penColor(0);
	if ((wndStyle & SCI_WINDOWMGR_STYLE_TRANSPARENT) == 0) {
		pWnd->hSaved1 = _paint16->bitsSave(pWnd->restoreRect, GFX_SCREEN_MASK_VISUAL);
		if (pWnd->saveScreenMask & GFX_SCREEN_MASK_PRIORITY) {
			pWnd->hSaved2 = _paint16->bitsSave(pWnd->restoreRect, GFX_SCREEN_MASK_PRIORITY);
			if ((wndStyle & SCI_WINDOWMGR_STYLE_USER) == 0)
				_paint16->fillRect(pWnd->restoreRect, GFX_SCREEN_MASK_PRIORITY, 0, 15);
		}
	}

	// drawing frame,shadow and title
	if ((getSciVersion() >= SCI_VERSION_1_LATE) ? !(wndStyle & _styleUser) : wndStyle != _styleUser) {
		Common::Rect r = pWnd->dims;

		if (!(wndStyle & SCI_WINDOWMGR_STYLE_NOFRAME)) {
			r.top++;
			r.left++;
			_paint16->frameRect(r);// draw shadow
			r.translate(-1, -1);
			_paint16->frameRect(r);// draw actual window frame

			if (wndStyle & SCI_WINDOWMGR_STYLE_TITLE) {
				if (getSciVersion() <= SCI_VERSION_0_LATE) {
					// draw a black line between titlebar and actual window content for SCI0
					r.bottom = r.top + 10;
					_paint16->frameRect(r);
				}
				r.grow(-1);
				if (getSciVersion() <= SCI_VERSION_0_LATE)
					_paint16->fillRect(r, GFX_SCREEN_MASK_VISUAL, 8); // grey titlebar for SCI0
				else
					_paint16->fillRect(r, GFX_SCREEN_MASK_VISUAL, 0); // black titlebar for SCI01+
				if (!pWnd->title.empty()) {
					int16 oldcolor = getPort()->penClr;
					penColor(_screen->getColorWhite());
					_text16->Box(pWnd->title.c_str(), true, r, SCI_TEXT16_ALIGNMENT_CENTER, 0);
					penColor(oldcolor);
				}

				r.grow(+1);
				r.bottom = pWnd->dims.bottom - 1;
				r.top += 9;
			}

			r.grow(-1);
		}

		if (!(wndStyle & SCI_WINDOWMGR_STYLE_TRANSPARENT))
			_paint16->fillRect(r, GFX_SCREEN_MASK_VISUAL, pWnd->backClr);

		_paint16->bitsShow(pWnd->dims);
	}
	setPort(oldport);
}
Example #14
0
Window *GfxPorts::addWindow(const Common::Rect &dims, const Common::Rect *restoreRect, const char *title, uint16 style, int16 priority, bool draw) {
	// Find an unused window/port id
	uint id = PORTS_FIRSTWINDOWID;
	while (id < _windowsById.size() && _windowsById[id]) {
		if (_windowsById[id]->counterTillFree) {
			// port that is already disposed, but not freed yet
			freeWindow((Window *)_windowsById[id]);
			_freeCounter--;
			break; // reuse the handle
			// we do this especially for sq4cd. it creates and disposes the
			//  inventory window all the time, but reuses old handles as well
			//  this worked somewhat under the original interpreter, because
			//  it put the new window where the old was.
		}
		++id;
	}
	if (id == _windowsById.size())
		_windowsById.push_back(0);
	assert(0 < id && id < 0xFFFF);

	Window *pwnd = new Window(id);
	Common::Rect r;

	if (!pwnd) {
		error("Can't open window");
		return 0;
	}

	_windowsById[id] = pwnd;

	// KQ1sci, KQ4, iceman, QfG2 always add windows to the back of the list.
	// KQ5CD checks style.
	// Hoyle3-demo also always adds to the back (#3036763).
	bool forceToBack = (getSciVersion() <= SCI_VERSION_1_EGA_ONLY) ||
	                   (g_sci->getGameId() == GID_HOYLE3 && g_sci->isDemo());

	if (!forceToBack && (style & SCI_WINDOWMGR_STYLE_TOPMOST))
		_windowList.push_front(pwnd);
	else
		_windowList.push_back(pwnd);
	openPort(pwnd);

	r = dims;
	// This looks fishy, but it's exactly what Sierra did. They removed last
	// bit of the left dimension in their interpreter. It seems Sierra did it
	// for EGA byte alignment (EGA uses 1 byte for 2 pixels) and left it in
	// their interpreter even in the newer VGA games.
	r.left = r.left & 0xFFFE;

	if (r.width() > _screen->getWidth()) {
		// We get invalid dimensions at least at the end of sq3 (script bug!).
		// Same happens very often in lsl5, sierra sci didnt fix it but it looked awful.
		// Also happens frequently in the demo of GK1.
		warning("Fixing too large window, left: %d, right: %d", dims.left, dims.right);
		r.left = 0;
		r.right = _screen->getWidth() - 1;
		if ((style != _styleUser) && !(style & SCI_WINDOWMGR_STYLE_NOFRAME))
			r.right--;
	}
	pwnd->rect = r;
	if (restoreRect)
		pwnd->restoreRect = *restoreRect;

	pwnd->wndStyle = style;
	pwnd->hSaved1 = pwnd->hSaved2 = NULL_REG;
	pwnd->bDrawn = false;
	if ((style & SCI_WINDOWMGR_STYLE_TRANSPARENT) == 0)
		pwnd->saveScreenMask = (priority == -1 ? GFX_SCREEN_MASK_VISUAL : GFX_SCREEN_MASK_VISUAL | GFX_SCREEN_MASK_PRIORITY);

	if (title && (style & SCI_WINDOWMGR_STYLE_TITLE)) {
		pwnd->title = title;
	}

	r = pwnd->rect;
	if ((style != _styleUser) && !(style & SCI_WINDOWMGR_STYLE_NOFRAME)) {
		r.grow(1);
		if (style & SCI_WINDOWMGR_STYLE_TITLE) {
			r.top -= 10;
			r.bottom++;
		}
	}

	pwnd->dims = r;

	// Clip window, if needed
	Common::Rect wmprect = _wmgrPort->rect;
	// Handle a special case for Dr. Brain 1 Mac. When hovering the mouse cursor
	// over the status line on top, the game scripts try to draw the game's icon
	// bar above the current port, by specifying a negative window top, so that
	// the end result will be drawn 10 pixels above the current port. This is a
	// hack by Sierra, and is only limited to user style windows. Normally, we
	// should not clip, same as what Sierra does. However, this will result in
	// having invalid rectangles with negative coordinates. For this reason, we
	// adjust the containing rectangle instead.
	if (pwnd->dims.top < 0 && g_sci->getPlatform() == Common::kPlatformMacintosh &&
		(style & SCI_WINDOWMGR_STYLE_USER) && _wmgrPort->top + pwnd->dims.top >= 0) {
		// Offset the final rect top by the requested pixels
		wmprect.top += pwnd->dims.top;
	}

	int16 oldtop = pwnd->dims.top;
	int16 oldleft = pwnd->dims.left;

	// WORKAROUND: We also adjust the restore rect when adjusting the window
	// rect.
	// SSCI does not do this. It wasn't necessary in the original interpreter,
	// but it is needed for Freddy Pharkas CD. This version does not normally
	// have text, but we allow this by modifying the text/speech setting
	// according to what is set in the ScummVM GUI (refer to syncIngameAudioOptions()
	// in sci.cpp). Since the text used in Freddy Pharkas CD is quite large in
	// some cases, it ends up being offset in order to fit inside the screen,
	// but the associated restore rect isn't adjusted accordingly, leading to
	// artifacts being left on screen when some text boxes are removed. The
	// fact that the restore rect wasn't ever adjusted doesn't make sense, and
	// adjusting it shouldn't have any negative side-effects (it *should* be
	// adjusted, normally, but SCI doesn't do it). The big text boxes are still
	// odd-looking, because the text rect is drawn outside the text window rect,
	// but at least there aren't any leftover textbox artifacts left when the
	// boxes are removed. Adjusting the text window rect would require more
	// invasive changes than this one, thus it's not really worth the effort
	// for a feature that was not present in the original game, and its
	// implementation is buggy in the first place.
	// Adjusting the restore rect properly fixes bug #3575276.

	if (wmprect.top > pwnd->dims.top) {
		pwnd->dims.moveTo(pwnd->dims.left, wmprect.top);
		if (restoreRect)
			pwnd->restoreRect.moveTo(pwnd->restoreRect.left, wmprect.top);
	}

	if (wmprect.bottom < pwnd->dims.bottom) {
		pwnd->dims.moveTo(pwnd->dims.left, wmprect.bottom - pwnd->dims.bottom + pwnd->dims.top);
		if (restoreRect)
			pwnd->restoreRect.moveTo(pwnd->restoreRect.left, wmprect.bottom - pwnd->restoreRect.bottom + pwnd->restoreRect.top);
	}

	if (wmprect.right < pwnd->dims.right) {
		pwnd->dims.moveTo(wmprect.right + pwnd->dims.left - pwnd->dims.right, pwnd->dims.top);
		if (restoreRect)
			pwnd->restoreRect.moveTo(wmprect.right + pwnd->restoreRect.left - pwnd->restoreRect.right, pwnd->restoreRect.top);
	}

	if (wmprect.left > pwnd->dims.left) {
		pwnd->dims.moveTo(wmprect.left, pwnd->dims.top);
		if (restoreRect)
			pwnd->restoreRect.moveTo(wmprect.left, pwnd->restoreRect.top);
	}

	pwnd->rect.moveTo(pwnd->rect.left + pwnd->dims.left - oldleft, pwnd->rect.top + pwnd->dims.top - oldtop);

	if (restoreRect == 0)
		pwnd->restoreRect = pwnd->dims;

	if (pwnd->restoreRect.top < 0 && g_sci->getPlatform() == Common::kPlatformMacintosh &&
		(style & SCI_WINDOWMGR_STYLE_USER) && _wmgrPort->top + pwnd->restoreRect.top >= 0) {
		// Special case for Dr. Brain 1 Mac (check above), applied to the
		// restore rectangle.
		pwnd->restoreRect.moveTo(pwnd->restoreRect.left, wmprect.top);
	}

	if (draw)
		drawWindow(pwnd);
	setPort((Port *)pwnd);

	// All SCI0 games till kq4 .502 (not including) did not adjust against _wmgrPort, we set _wmgrPort->top to 0 in that case
	setOrigin(pwnd->rect.left, pwnd->rect.top + _wmgrPort->top);
	pwnd->rect.moveTo(0, 0);
	return pwnd;
}
void TattooUserInterface::drawInterface(int bufferNum) {
	TattooScene &scene = *(TattooScene *)_vm->_scene;
	Screen &screen = *_vm->_screen;
	TattooEngine &vm = *(TattooEngine *)_vm;
	
	if (_invMenuBuffer != nullptr) {
		Common::Rect r = _invMenuBounds;
		r.grow(-3);
		r.translate(-_currentScroll.x, 0);
		_grayAreas.clear();
		_grayAreas.push_back(r);

		drawGrayAreas();
		screen._backBuffer1.transBlitFrom(*_invMenuBuffer, Common::Point(_invMenuBounds.left, _invMenuBounds.top));
	}

	if (_menuBuffer != nullptr) {
		Common::Rect r = _menuBounds;
		r.grow(-3);
		r.translate(-_currentScroll.x, 0);
		_grayAreas.clear();
		_grayAreas.push_back(r);

		drawGrayAreas();
		screen._backBuffer1.transBlitFrom(*_menuBuffer, Common::Point(_invMenuBounds.left, _invMenuBounds.top));
	}

	// See if we need to draw a Text Tag floating with the cursor
	if (_tagBuffer != nullptr)
		screen._backBuffer1.transBlitFrom(*_tagBuffer, Common::Point(_tagBounds.left, _tagBounds.top));

	// See if we need to draw an Inventory Item Graphic floating with the cursor
	if (_invGraphic != nullptr)
		screen._backBuffer1.transBlitFrom(*_invGraphic, Common::Point(_invGraphicBounds.left, _invGraphicBounds.top));

	if (vm._creditsActive)
		vm.drawCredits();

	// Bring the widgets to the screen
	if (scene._mask != nullptr)
		screen._flushScreen = true;

	if (screen._flushScreen)
		screen.blockMove(_currentScroll);

	// If there are UI widgets open, slam the areas they were drawn on to the physical screen
	if (_menuBuffer != nullptr)
		screen.slamArea(_menuBounds.left - _currentScroll.x, _menuBounds.top, _menuBounds.width(), _menuBounds.height());
	
	if (_invMenuBuffer != nullptr)
		screen.slamArea(_invMenuBounds.left - _currentScroll.x, _invMenuBounds.top, _invMenuBounds.width(), _invMenuBounds.height());

	// If therea re widgets being cleared, then restore that area of the screen
	if (_oldMenuBounds.right) {
		screen.slamArea(_oldMenuBounds.left - _currentScroll.x, _oldMenuBounds.top, _oldMenuBounds.width(), _oldMenuBounds.height());
		_oldMenuBounds.left = _oldMenuBounds.top = _oldMenuBounds.right = _oldMenuBounds.bottom = 0;
	}
	
	if (_oldInvMenuBounds.left) {
		screen.slamArea(_oldInvMenuBounds.left - _currentScroll.x, _oldInvMenuBounds.top, _oldInvMenuBounds.width(), _oldInvMenuBounds.height());
		_oldInvMenuBounds.left = _oldInvMenuBounds.top = _oldInvMenuBounds.right = _oldInvMenuBounds.bottom = 0;
	}

	// See if  need to clear any tags
	if (_oldTagBounds.right) {
		screen.slamArea(_oldTagBounds.left - _currentScroll.x, _oldTagBounds.top, _oldTagBounds.width(), _oldTagBounds.height());

		// If there's no tag actually being displayed, then reset bounds so we don't keep restoring the area
		if (_tagBuffer == nullptr) {
			_tagBounds.left = _tagBounds.top = _tagBounds.right = _tagBounds.bottom = 0;
			_oldTagBounds.left = _oldTagBounds.top = _oldTagBounds.right = _oldTagBounds.bottom = 0;
		}
	}
	if (_tagBuffer != nullptr)
		screen.slamArea(_tagBounds.left - _currentScroll.x, _tagBounds.top, _tagBounds.width(), _tagBounds.height());

	// See if we need to flush areas assocaited with the inventory graphic
	if (_oldInvGraphicBounds.right) {
		screen.slamArea(_oldInvGraphicBounds.left - _currentScroll.x, _oldInvGraphicBounds.top,
			_oldInvGraphicBounds.width(), _oldInvGraphicBounds.height());

		// If there's no graphic actually being displayed, then reset bounds so we don't keep restoring the area
		if (_invGraphic == nullptr) {
			_invGraphicBounds.left = _invGraphicBounds.top = _invGraphicBounds.right = _invGraphicBounds.bottom = 0;
			_oldInvGraphicBounds.left = _oldInvGraphicBounds.top = _oldInvGraphicBounds.right = _oldInvGraphicBounds.bottom = 0;
		}
	}
	if (_invGraphic != nullptr)
		screen.slamArea(_invGraphicBounds.left - _currentScroll.x, _invGraphicBounds.top, _invGraphicBounds.width(), _invGraphicBounds.height());
}
Example #16
0
reg_t GfxPaint32::makeLineBitmap(const Common::Point &startPoint, const Common::Point &endPoint, const int16 priority, const uint8 color, const LineStyle style, uint16 pattern, uint8 thickness, Common::Rect &outRect) {
	const uint8 skipColor = color != kDefaultSkipColor ? kDefaultSkipColor : 0;

	// Line thickness is expected to be 2 * thickness + 1
	thickness = (MAX<uint8>(1, thickness) - 1) | 1;
	const uint8 halfThickness = thickness >> 1;

	const uint16 scriptWidth  = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
	const uint16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;

	outRect.left   = MIN<int16>(startPoint.x, endPoint.x);
	outRect.top    = MIN<int16>(startPoint.y, endPoint.y);
	outRect.right  = MAX<int16>(startPoint.x, endPoint.x) + 1 + 1;	// rect lower edge + thickness offset
	outRect.bottom = MAX<int16>(startPoint.y, endPoint.y) + 1 + 1;	// rect lower edge + thickness offset

	outRect.grow(halfThickness);
	outRect.clip(Common::Rect(scriptWidth, scriptHeight));

	reg_t bitmapId;
	SciBitmap &bitmap = *_segMan->allocateBitmap(&bitmapId, outRect.width(), outRect.height(), skipColor, 0, 0, scriptWidth, scriptHeight, 0, false, true);

	byte *pixels = bitmap.getPixels();
	memset(pixels, skipColor, bitmap.getWidth() * bitmap.getHeight());

	LineProperties properties;
	properties.bitmap = &bitmap;

	switch (style) {
	case kLineStyleSolid:
		pattern = 0xFFFF;
		properties.solid = true;
		break;
	case kLineStyleDashed:
		pattern = 0xFF00;
		properties.solid = false;
		break;
	case kLineStylePattern:
		properties.solid = pattern == 0xFFFF;
		break;
	}

	// Change coordinates to be relative to the bitmap
	const int16 x1 = startPoint.x - outRect.left;
	const int16 y1 = startPoint.y - outRect.top;
	const int16 x2 =   endPoint.x - outRect.left;
	const int16 y2 =   endPoint.y - outRect.top;

	if (!properties.solid) {
		for (int i = 0; i < ARRAYSIZE(properties.pattern); ++i) {
			properties.pattern[i] = (pattern & 0x8000);
			pattern <<= 1;
		}

		properties.patternIndex = 0;
		properties.horizontal = ABS(x2 - x1) > ABS(y2 - y1);
		properties.lastAddress = properties.horizontal ? x1 : y1;
	}

	if (thickness <= 1) {
		Graphics::drawLine(x1, y1, x2, y2, color, plotter, &properties);
	} else {
		Graphics::drawThickLine2(x1, y1, x2, y2, thickness, color, plotter, &properties);
	}

	return bitmapId;
}