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; }
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; }
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); }
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; }
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; } } }
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; }
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; }
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; }
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 }