Esempio n. 1
0
bool BaseRenderOSystem::drawLine(int x1, int y1, int x2, int y2, uint32 color) {
	// This function isn't used outside of indicator-displaying, and thus quite unused in
	// BaseRenderOSystem when dirty-rects are enabled.
	if (!_tempDisableDirtyRects && !_disableDirtyRects && !_indicatorDisplay) {
		error("BaseRenderOSystem::DrawLine - doesn't work for dirty rects yet");
	}

	byte r = RGBCOLGetR(color);
	byte g = RGBCOLGetG(color);
	byte b = RGBCOLGetB(color);
	byte a = RGBCOLGetA(color);

	//SDL_SetRenderDrawColor(_renderer, r, g, b, a);
	//SDL_SetRenderDrawBlendMode(_renderer, SDL_BLENDMODE_BLEND);

	Point32 point1, point2;
	point1.x = x1;
	point1.y = y1;
	pointToScreen(&point1);

	point2.x = x2;
	point2.y = y2;
	pointToScreen(&point2);

	// TODO: This thing is mostly here until I'm sure about the final color-format.
	uint32 colorVal = _renderSurface->format.ARGBToColor(a, r, g, b);
	_renderSurface->drawLine(point1.x, point1.y, point2.x, point2.y, colorVal);
	//SDL_RenderDrawLine(_renderer, point1.x, point1.y, point2.x, point2.y);
	return STATUS_OK;
}
Esempio n. 2
0
void BaseUtils::RGBtoHSL(uint32 rgbColor, byte *outH, byte *outS, byte *outL) {
	float varR = (RGBCOLGetR(rgbColor) / 255.0f);
	float varG = (RGBCOLGetG(rgbColor) / 255.0f);
	float varB = (RGBCOLGetB(rgbColor) / 255.0f);

	//Min. value of RGB
	float varMin = MIN(varR, varG);
	varMin = MIN(varMin, varB);

	//Max. value of RGB
	float varMax = MAX(varR, varG);
	varMax = MAX(varMax, varB);

	//Delta RGB value
	float delMax = varMax - varMin;

	float H = 0.0f, S = 0.0f, L = 0.0f;

	L = (varMax + varMin) / 2.0f;

	//This is a gray, no chroma...
	if (delMax == 0) {
		H = 0;
		S = 0;
	}
	//Chromatic data...
	else {
		if (L < 0.5f) {
			S = delMax / (varMax + varMin);
		} else {
			S = delMax / (2.0f - varMax - varMin);
		}

		float delR = (((varMax - varR) / 6.0f) + (delMax / 2.0f)) / delMax;
		float delG = (((varMax - varG) / 6.0f) + (delMax / 2.0f)) / delMax;
		float delB = (((varMax - varB) / 6.0f) + (delMax / 2.0f)) / delMax;

		if (varR == varMax) {
			H = delB - delG;
		} else if (varG == varMax) {
			H = (1.0f / 3.0f) + delR - delB;
		} else if (varB == varMax) {
			H = (2.0f / 3.0f) + delG - delR;
		}

		if (H < 0) {
			H += 1;
		}
		if (H > 1) {
			H -= 1;
		}
	}

	*outH = (byte)(H * 255);
	*outS = (byte)(S * 255);
	*outL = (byte)(L * 255);
}
Esempio n. 3
0
bool BaseFader::fadeIn(uint32 sourceColor, uint32 duration, bool system) {
	_ready = false;
	_active = true;

	_red   = RGBCOLGetR(sourceColor);
	_green = RGBCOLGetG(sourceColor);
	_blue  = RGBCOLGetB(sourceColor);

	_sourceAlpha = RGBCOLGetA(sourceColor);
	_targetAlpha = 0;

	_duration = duration;
	_system = system;

	if (_system) {
		_startTime = g_system->getMillis();
	} else {
		_startTime = BaseEngine::getTimer()->getTime();
	}

	return STATUS_OK;
}
Esempio n. 4
0
void BaseFontTT::drawText(const byte *text, int x, int y, int width, TTextAlign align, int maxHeight, int maxLength) {
	if (text == nullptr || strcmp((const char *)text, "") == 0) {
		return;
	}

	WideString textStr;

	// TODO: Why do we still insist on Widestrings everywhere?
	// HACK: J.U.L.I.A. uses CP1252, we need to fix that,
	// And we still don't have any UTF8-support.
	if (_gameRef->_textEncoding == TEXT_UTF8) {
		textStr = StringUtil::utf8ToWide((const char *)text);
	} else {
		textStr = StringUtil::ansiToWide((const char *)text);
	}

	if (maxLength >= 0 && textStr.size() > (uint32)maxLength) {
		textStr = WideString(textStr.c_str(), (uint32)maxLength);
	}
	//text = text.substr(0, MaxLength); // TODO: Remove

	BaseRenderer *renderer = _gameRef->_renderer;

	// find cached surface, if exists
	uint32 minUseTime = UINT_MAX;
	int minIndex = -1;
	BaseSurface *surface = nullptr;
	int textOffset = 0;

	for (int i = 0; i < NUM_CACHED_TEXTS; i++) {
		if (_cachedTexts[i] == nullptr) {
			minUseTime = 0;
			minIndex = i;
		} else {
			if (_cachedTexts[i]->_text == textStr && _cachedTexts[i]->_align == align && _cachedTexts[i]->_width == width && _cachedTexts[i]->_maxHeight == maxHeight && _cachedTexts[i]->_maxLength == maxLength) {
				surface = _cachedTexts[i]->_surface;
				textOffset = _cachedTexts[i]->_textOffset;
				_cachedTexts[i]->_marked = true;
				_cachedTexts[i]->_lastUsed = g_system->getMillis();
				break;
			} else {
				if (_cachedTexts[i]->_lastUsed < minUseTime) {
					minUseTime = _cachedTexts[i]->_lastUsed;
					minIndex = i;
				}
			}
		}
	}

	// not found, create one
	if (!surface) {
		debugC(kWintermuteDebugFont, "Draw text: %s", text);
		surface = renderTextToTexture(textStr, width, align, maxHeight, textOffset);
		if (surface) {
			// write surface to cache
			if (_cachedTexts[minIndex] != nullptr) {
				delete _cachedTexts[minIndex];
			}
			_cachedTexts[minIndex] = new BaseCachedTTFontText;

			_cachedTexts[minIndex]->_surface = surface;
			_cachedTexts[minIndex]->_align = align;
			_cachedTexts[minIndex]->_width = width;
			_cachedTexts[minIndex]->_maxHeight = maxHeight;
			_cachedTexts[minIndex]->_maxLength = maxLength;
			_cachedTexts[minIndex]->_text = textStr;
			_cachedTexts[minIndex]->_textOffset = textOffset;
			_cachedTexts[minIndex]->_marked = true;
			_cachedTexts[minIndex]->_lastUsed = g_system->getMillis();
		}
	}


	// and paint it
	if (surface) {
		Rect32 rc;
		rc.setRect(0, 0, surface->getWidth(), surface->getHeight());
		for (uint32 i = 0; i < _layers.size(); i++) {
			uint32 color = _layers[i]->_color;
			uint32 origForceAlpha = renderer->_forceAlphaColor;
			if (renderer->_forceAlphaColor != 0) {
				color = BYTETORGBA(RGBCOLGetR(color), RGBCOLGetG(color), RGBCOLGetB(color), RGBCOLGetA(renderer->_forceAlphaColor));
				renderer->_forceAlphaColor = 0;
			}
			surface->displayTransOffset(x, y - textOffset, rc, color, Graphics::BLEND_NORMAL, false, false, _layers[i]->_offsetX, _layers[i]->_offsetY);

			renderer->_forceAlphaColor = origForceAlpha;
		}
	}


}
Esempio n. 5
0
bool UIWindow::display(int offsetX, int offsetY) {
	// go exclusive
	if (_mode == WINDOW_EXCLUSIVE || _mode == WINDOW_SYSTEM_EXCLUSIVE) {
		if (!_shieldWindow) {
			_shieldWindow = new UIWindow(_gameRef);
		}
		if (_shieldWindow) {
			_shieldWindow->_posX = _shieldWindow->_posY = 0;
			_shieldWindow->_width = _gameRef->_renderer->getWidth();
			_shieldWindow->_height = _gameRef->_renderer->getHeight();

			_shieldWindow->display();
		}
	} else if (_isMenu) {
		if (!_shieldButton) {
			_shieldButton = new UIButton(_gameRef);
			_shieldButton->setName("close");
			_shieldButton->setListener(this, _shieldButton, 0);
			_shieldButton->_parent = this;
		}
		if (_shieldButton) {
			_shieldButton->_posX = _shieldButton->_posY = 0;
			_shieldButton->setWidth(_gameRef->_renderer->getWidth());
			_shieldButton->setHeight(_gameRef->_renderer->getHeight());

			_shieldButton->display();
		}
	}

	if (!_visible) {
		return STATUS_OK;
	}

	if (_fadeBackground) {
		Graphics::PixelFormat format = _gameRef->_renderer->getPixelFormat();
		byte fadeR, fadeG, fadeB, fadeA;
		// First convert from the internal format to the screen-format
		uint32 fadeColor = format.ARGBToColor(RGBCOLGetA(_fadeColor), RGBCOLGetR(_fadeColor), RGBCOLGetG(_fadeColor), RGBCOLGetB(_fadeColor));
		// Then get components
		format.colorToARGB(fadeColor, fadeA, fadeR, fadeG, fadeB);
		_gameRef->_renderer->fadeToColor(fadeR, fadeG, fadeB, fadeA);
	}

	if (_dragging) {
		_posX += (_gameRef->_mousePos.x - _dragFrom.x);
		_posY += (_gameRef->_mousePos.y - _dragFrom.y);

		_dragFrom.x = _gameRef->_mousePos.x;
		_dragFrom.y = _gameRef->_mousePos.y;
	}

	if (!_focusedWidget || (!_focusedWidget->canFocus() || _focusedWidget->isDisabled() || !_focusedWidget->isVisible())) {
		moveFocus();
	}

	bool popViewport = false;
	if (_clipContents) {
		if (!_viewport) {
			_viewport = new BaseViewport(_gameRef);
		}
		if (_viewport) {
			_viewport->setRect(_posX + offsetX, _posY + offsetY, _posX + _width + offsetX, _posY + _height + offsetY);
			_gameRef->pushViewport(_viewport);
			popViewport = true;
		}
	}


	UITiledImage *back = _back;
	BaseSprite *image = _image;
	BaseFont *font = _font;

	if (!isFocused()) {
		if (_backInactive) {
			back = _backInactive;
		}
		if (_imageInactive) {
			image = _imageInactive;
		}
		if (_fontInactive) {
			font = _fontInactive;
		}
	}

	if (_alphaColor != 0) {
		_gameRef->_renderer->_forceAlphaColor = _alphaColor;
	}
	if (back) {
		back->display(_posX + offsetX, _posY + offsetY, _width, _height);
	}
	if (image) {
		image->draw(_posX + offsetX, _posY + offsetY, _transparent ? nullptr : this);
	}

	if (!BasePlatform::isRectEmpty(&_titleRect) && font && _text) {
		font->drawText((byte *)_text, _posX + offsetX + _titleRect.left, _posY + offsetY + _titleRect.top, _titleRect.right - _titleRect.left, _titleAlign, _titleRect.bottom - _titleRect.top);
	}

	if (!_transparent && !image) {
		_gameRef->_renderer->addRectToList(new BaseActiveRect(_gameRef,  this, nullptr, _posX + offsetX, _posY + offsetY, _width, _height, 100, 100, false));
	}

	for (uint32 i = 0; i < _widgets.size(); i++) {
		_widgets[i]->display(_posX + offsetX, _posY + offsetY);
	}

	if (_alphaColor != 0) {
		_gameRef->_renderer->_forceAlphaColor = 0;
	}

	if (popViewport) {
		_gameRef->popViewport();
	}

	return STATUS_OK;
}
Esempio n. 6
0
bool AdRegion::saveAsText(BaseDynamicBuffer *buffer, int indent) {
	buffer->putTextIndent(indent, "REGION {\n");
	buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", getName());
	buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption());
	buffer->putTextIndent(indent + 2, "BLOCKED=%s\n", _blocked ? "TRUE" : "FALSE");
	buffer->putTextIndent(indent + 2, "DECORATION=%s\n", _decoration ? "TRUE" : "FALSE");
	buffer->putTextIndent(indent + 2, "ACTIVE=%s\n", _active ? "TRUE" : "FALSE");
	buffer->putTextIndent(indent + 2, "SCALE=%d\n", (int)_zoom);
	buffer->putTextIndent(indent + 2, "ALPHA_COLOR { %d,%d,%d }\n", RGBCOLGetR(_alpha), RGBCOLGetG(_alpha), RGBCOLGetB(_alpha));
	buffer->putTextIndent(indent + 2, "ALPHA = %d\n", RGBCOLGetA(_alpha));
	buffer->putTextIndent(indent + 2, "EDITOR_SELECTED=%s\n", _editorSelected ? "TRUE" : "FALSE");

	for (uint32 i = 0; i < _scripts.size(); i++) {
		buffer->putTextIndent(indent + 2, "SCRIPT=\"%s\"\n", _scripts[i]->_filename);
	}

	if (_scProp) {
		_scProp->saveAsText(buffer, indent + 2);
	}

	for (uint32 i = 0; i < _points.size(); i++) {
		buffer->putTextIndent(indent + 2, "POINT {%d,%d}\n", _points[i]->x, _points[i]->y);
	}

	BaseClass::saveAsText(buffer, indent + 2);

	buffer->putTextIndent(indent, "}\n\n");

	return STATUS_OK;
}
Esempio n. 7
0
bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, float zoomX, float zoomY, uint32 alpha, bool alphaDisable, TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY, int offsetX, int offsetY) {
	BaseRenderOSystem *renderer = static_cast<BaseRenderOSystem *>(_gameRef->_renderer);

	if (!_loaded) {
		finishLoad();
	}

	if (renderer->_forceAlphaColor != 0) {
		alpha = renderer->_forceAlphaColor;
	}

	byte r = RGBCOLGetR(alpha);
	byte g = RGBCOLGetG(alpha);
	byte b = RGBCOLGetB(alpha);
	byte a = RGBCOLGetA(alpha);

	renderer->setAlphaMod(a);
	renderer->setColorMod(r, g, b);

#if 0 // These are kept for reference if BlendMode is reimplemented at some point.
	if (alphaDisable) {
		SDL_SetTextureBlendMode(_texture, SDL_BLENDMODE_NONE);
	} else {
		SDL_SetTextureBlendMode(_texture, SDL_BLENDMODE_BLEND);
	}
#endif
	// TODO: This _might_ miss the intended behaviour by 1 in each direction
	// But I think it fits the model used in Wintermute.
	Common::Rect srcRect;
	srcRect.left = rect->left;
	srcRect.top = rect->top;
	srcRect.setWidth(rect->right - rect->left);
	srcRect.setHeight(rect->bottom - rect->top);

	Common::Rect position;
	position.left = x + offsetX;
	position.top = y + offsetY;

	// Crop off-by-ones:
	if (position.left == -1) {
		position.left = 0; // TODO: Something is wrong
	}
	if (position.top == -1) {
		position.top = 0; // TODO: Something is wrong
	}

	position.setWidth((int16)((float)srcRect.width() * zoomX / 100.f));
	position.setHeight((int16)((float)srcRect.height() * zoomX / 100.f));

	renderer->modTargetRect(&position);

	/*  position.left += offsetX;
	    position.top += offsetY;*/

	// TODO: This actually requires us to have the SAME source-offsets every time,
	// But no checking is in place for that yet.

	// TODO: Optimize by not doing alpha-blits if we lack or disable alpha
	bool hasAlpha;
	if (_hasAlpha && !alphaDisable) {
		hasAlpha = true;
	} else {
		hasAlpha = false;
	}
	if (alphaDisable) {
		warning("BaseSurfaceOSystem::drawSprite - AlphaDisable ignored");
	}

	renderer->drawSurface(this, _surface, &srcRect, &position, mirrorX, mirrorY, !hasAlpha);

	return STATUS_OK;
}
Esempio n. 8
0
bool AdEntity::saveAsText(BaseDynamicBuffer *buffer, int indent) {
	buffer->putTextIndent(indent, "ENTITY {\n");
	buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", getName());
	if (_subtype == ENTITY_SOUND) {
		buffer->putTextIndent(indent + 2, "SUBTYPE=\"SOUND\"\n");
	}
	buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption());
	buffer->putTextIndent(indent + 2, "ACTIVE=%s\n", _active ? "TRUE" : "FALSE");
	buffer->putTextIndent(indent + 2, "X=%d\n", _posX);
	buffer->putTextIndent(indent + 2, "Y=%d\n", _posY);
	buffer->putTextIndent(indent + 2, "SCALABLE=%s\n", _zoomable ? "TRUE" : "FALSE");
	buffer->putTextIndent(indent + 2, "INTERACTIVE=%s\n", _registrable ? "TRUE" : "FALSE");
	buffer->putTextIndent(indent + 2, "COLORABLE=%s\n", _shadowable ? "TRUE" : "FALSE");
	buffer->putTextIndent(indent + 2, "EDITOR_SELECTED=%s\n", _editorSelected ? "TRUE" : "FALSE");
	if (_ignoreItems) {
		buffer->putTextIndent(indent + 2, "IGNORE_ITEMS=%s\n", _ignoreItems ? "TRUE" : "FALSE");
	}
	if (_rotatable) {
		buffer->putTextIndent(indent + 2, "ROTATABLE=%s\n", _rotatable ? "TRUE" : "FALSE");
	}

	if (!_autoSoundPanning) {
		buffer->putTextIndent(indent + 2, "SOUND_PANNING=%s\n", _autoSoundPanning ? "TRUE" : "FALSE");
	}

	if (!_saveState) {
		buffer->putTextIndent(indent + 2, "SAVE_STATE=%s\n", _saveState ? "TRUE" : "FALSE");
	}

	if (_item && _item[0] != '\0') {
		buffer->putTextIndent(indent + 2, "ITEM=\"%s\"\n", _item);
	}

	buffer->putTextIndent(indent + 2, "WALK_TO_X=%d\n", _walkToX);
	buffer->putTextIndent(indent + 2, "WALK_TO_Y=%d\n", _walkToY);
	if (_walkToDir != DI_NONE) {
		buffer->putTextIndent(indent + 2, "WALK_TO_DIR=%d\n", (int)_walkToDir);
	}

	for (uint32 i = 0; i < _scripts.size(); i++) {
		buffer->putTextIndent(indent + 2, "SCRIPT=\"%s\"\n", _scripts[i]->_filename);
	}

	if (_subtype == ENTITY_NORMAL && _sprite && _sprite->getFilename()) {
		buffer->putTextIndent(indent + 2, "SPRITE=\"%s\"\n", _sprite->getFilename());
	}

	if (_subtype == ENTITY_SOUND && _sFX && _sFX->getFilename()) {
		buffer->putTextIndent(indent + 2, "SOUND=\"%s\"\n", _sFX->getFilename());
		buffer->putTextIndent(indent + 2, "SOUND_START_TIME=%d\n", _sFXStart);
		buffer->putTextIndent(indent + 2, "SOUND_VOLUME=%d\n", _sFXVolume);
	}


	if (RGBCOLGetR(_alphaColor) != 0 || RGBCOLGetG(_alphaColor) != 0 ||  RGBCOLGetB(_alphaColor) != 0) {
		buffer->putTextIndent(indent + 2, "ALPHA_COLOR { %d,%d,%d }\n", RGBCOLGetR(_alphaColor), RGBCOLGetG(_alphaColor), RGBCOLGetB(_alphaColor));
	}

	if (RGBCOLGetA(_alphaColor) != 0) {
		buffer->putTextIndent(indent + 2, "ALPHA = %d\n", RGBCOLGetA(_alphaColor));
	}

	if (_scale >= 0) {
		buffer->putTextIndent(indent + 2, "SCALE = %d\n", (int)_scale);
	}

	if (_relativeScale != 0) {
		buffer->putTextIndent(indent + 2, "RELATIVE_SCALE = %d\n", (int)_relativeScale);
	}

	if (_font && _font->getFilename()) {
		buffer->putTextIndent(indent + 2, "FONT=\"%s\"\n", _font->getFilename());
	}

	if (_cursor && _cursor->getFilename()) {
		buffer->putTextIndent(indent + 2, "CURSOR=\"%s\"\n", _cursor->getFilename());
	}

	AdTalkHolder::saveAsText(buffer, indent + 2);

	if (_region) {
		_region->saveAsText(buffer, indent + 2);
	}

	if (_scProp) {
		_scProp->saveAsText(buffer, indent + 2);
	}

	AdObject::saveAsText(buffer, indent + 2);

	buffer->putTextIndent(indent, "}\n\n");

	return STATUS_OK;
}
Esempio n. 9
0
BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width, TTextAlign align, int maxHeight, int &textOffset) {
	//TextLineList lines;
	// TODO: Use WideString-conversion here.
	//WrapText(text, width, maxHeight, lines);
	Common::Array<Common::String> lines;
	_font->wordWrapText(text, width, lines);

	while (maxHeight > 0 && lines.size() * _lineHeight > maxHeight) {
		lines.pop_back();
	}
	if (lines.size() == 0) {
		return nullptr;
	}

	Graphics::TextAlign alignment = Graphics::kTextAlignInvalid;
	if (align == TAL_LEFT) {
		alignment = Graphics::kTextAlignLeft;
	} else if (align == TAL_CENTER) {
		alignment = Graphics::kTextAlignCenter;
	} else if (align == TAL_RIGHT) {
		alignment = Graphics::kTextAlignRight;
	}

	debugC(kWintermuteDebugFont, "%s %d %d %d %d", text.c_str(), RGBCOLGetR(_layers[0]->_color), RGBCOLGetG(_layers[0]->_color), RGBCOLGetB(_layers[0]->_color), RGBCOLGetA(_layers[0]->_color));
//	void drawString(Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true) const;
	Graphics::Surface *surface = new Graphics::Surface();
	if (_deletableFont) { // We actually have a TTF
		surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24));
	} else { // We are using a fallback, they can't do 32bpp
		surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0));
	}
	uint32 useColor = 0xffffffff;
	Common::Array<Common::String>::iterator it;
	int heightOffset = 0;
	for (it = lines.begin(); it != lines.end(); ++it) {
		_font->drawString(surface, *it, 0, heightOffset, width, useColor, alignment);
		heightOffset += (int)_lineHeight;
	}

	BaseSurface *retSurface = _gameRef->_renderer->createSurface();
	Graphics::Surface *convertedSurface = surface->convertTo(Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24));
	retSurface->putSurface(*convertedSurface, true);
	convertedSurface->free();
	surface->free();
	delete surface;
	delete convertedSurface;
	return retSurface;
	// TODO: _isUnderline, _isBold, _isItalic, _isStriked
}