void RenderManager::copyToScreen(const Graphics::Surface &surface, Common::Rect &rect, int16 srcLeft, int16 srcTop) { // Convert the surface to RGB565, if needed Graphics::Surface *outSurface = surface.convertTo(_engine->_screenPixelFormat); _system->copyRectToScreen(outSurface->getBasePtr(srcLeft, srcTop), outSurface->pitch, rect.left, rect.top, rect.width(), rect.height()); outSurface->free(); delete outSurface; }
void OSystem_3DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) { Common::Rect rect(x, y, x+w, y+h); _gameScreen.copyRectToSurface(buf, pitch, x, y, w, h); Graphics::Surface subSurface = _gameScreen.getSubArea(rect); Graphics::Surface *convertedSubSurface = subSurface.convertTo(_pfGameTexture, _palette); _gameTopTexture.copyRectToSurface(*convertedSubSurface, x, y, Common::Rect(w, h)); convertedSubSurface->free(); delete convertedSubSurface; _gameTopTexture.markDirty(); }
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 }
void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Common::Rect &_srcRect , Graphics::Surface &dst, int _x, int _y) { Common::Rect srcRect = _srcRect; if (srcRect.isEmpty()) srcRect = Common::Rect(src.w, src.h); srcRect.clip(src.w, src.h); Common::Rect dstRect = Common::Rect(-_x + srcRect.left , -_y + srcRect.top, -_x + srcRect.left + dst.w, -_y + srcRect.top + dst.h); srcRect.clip(dstRect); if (srcRect.isEmpty() || !srcRect.isValidRect()) return; Graphics::Surface *srcAdapted = src.convertTo(dst.format); // Copy srcRect from src surface to dst surface const byte *srcBuffer = (const byte *)srcAdapted->getBasePtr(srcRect.left, srcRect.top); int xx = _x; int yy = _y; if (xx < 0) xx = 0; if (yy < 0) yy = 0; if (_x >= dst.w || _y >= dst.h) { srcAdapted->free(); delete srcAdapted; return; } byte *dstBuffer = (byte *)dst.getBasePtr(xx, yy); int32 w = srcRect.width(); int32 h = srcRect.height(); for (int32 y = 0; y < h; y++) { memcpy(dstBuffer, srcBuffer, w * srcAdapted->format.bytesPerPixel); srcBuffer += srcAdapted->pitch; dstBuffer += dst.pitch; } srcAdapted->free(); delete srcAdapted; }
void BasePersistenceManager::getSaveStateDesc(int slot, SaveStateDescriptor &desc) { Common::String filename = getFilenameForSlot(slot); debugC(kWintermuteDebugSaveGame, "Trying to list savegame %s in slot %d", filename.c_str(), slot); if (DID_FAIL(readHeader(filename))) { debugC(kWintermuteDebugSaveGame, "getSavedDesc(%d) - Failed for %s", slot, filename.c_str()); return; } desc.setSaveSlot(slot); desc.setDescription(_savedDescription); desc.setDeletableFlag(true); desc.setWriteProtectedFlag(false); int thumbSize = 0; byte *thumbData = nullptr; if (_scummVMThumbSize > 0) { thumbSize = _scummVMThumbSize; thumbData = _scummVMThumbnailData; } else if (_thumbnailDataSize > 0) { thumbSize = _thumbnailDataSize; thumbData = _thumbnailData; } if (thumbSize > 0) { Common::MemoryReadStream thumbStream(thumbData, thumbSize, DisposeAfterUse::NO); Graphics::BitmapDecoder bmpDecoder; if (bmpDecoder.loadStream(thumbStream)) { const Graphics::Surface *bmpSurface = bmpDecoder.getSurface(); TransparentSurface *scaleableSurface = new TransparentSurface(*bmpSurface, false); Graphics::Surface *scaled = scaleableSurface->scale(kThumbnailWidth, kThumbnailHeight2); Graphics::Surface *thumb = scaled->convertTo(g_system->getOverlayFormat()); desc.setThumbnail(thumb); delete scaleableSurface; scaled->free(); delete scaled; } } desc.setSaveDate(_savedTimestamp.tm_year, _savedTimestamp.tm_mon, _savedTimestamp.tm_mday); desc.setSaveTime(_savedTimestamp.tm_hour, _savedTimestamp.tm_min); desc.setPlayTime(0); }
void AVISurface::copyMovieFrame(const Graphics::Surface &src, Graphics::ManagedSurface &dest) { // WORKAROUND: Handle rare cases where frame sizes don't match the video size Common::Rect copyRect(0, 0, MIN(src.w, dest.w), MIN(src.h, dest.h)); if (src.format.bytesPerPixel == 1) { // Paletted 8-bit, so convert to 16-bit and copy over const byte *palette = _decoder->getPalette(); if (palette) { Graphics::Surface *s = src.convertTo(dest.format, palette); dest.blitFrom(*s, copyRect, Common::Point(0, 0)); s->free(); delete s; } } else if (src.format.bytesPerPixel == 2) { // Source is already 16-bit, with no alpha, so do a straight copy dest.blitFrom(src, copyRect, Common::Point(0, 0)); } else { // Source is 32-bit which may have transparent pixels. Copy over each // pixel, replacing transparent pixels with the special transparency color byte a, r, g, b; assert(src.format.bytesPerPixel == 4 && dest.format.bytesPerPixel == 2); uint16 transPixel = _videoSurface->getTransparencyColor(); for (uint y = 0; y < MIN(src.h, dest.h); ++y) { const uint32 *pSrc = (const uint32 *)src.getBasePtr(0, y); uint16 *pDest = (uint16 *)dest.getBasePtr(0, y); for (uint x = 0; x < MIN(src.w, dest.w); ++x, ++pSrc, ++pDest) { src.format.colorToARGB(*pSrc, a, r, g, b); assert(a == 0 || a == 0xff); *pDest = (a == 0) ? transPixel : dest.format.RGBToColor(r, g, b); } } } }
bool writePNG(Common::WriteStream &out, const Graphics::Surface &input, const bool bottomUp) { #ifdef USE_PNG const Graphics::PixelFormat requiredFormat_3byte(3, 8, 8, 8, 0, 16, 8, 0, 0); const Graphics::PixelFormat requiredFormat_4byte(4, 8, 8, 8, 8, 0, 8, 16, 24); if (input.format.bytesPerPixel == 3) { if (input.format != requiredFormat_3byte) { warning("Cannot currently write PNG with 3-byte pixel format other than %s", requiredFormat_3byte.toString().c_str()); return false; } } else if (input.format.bytesPerPixel != 4) { warning("Cannot currently write PNG with pixel format of bpp other than 3, 4"); return false; } int colorType; Graphics::Surface *tmp = NULL; const Graphics::Surface *surface; if (input.format == requiredFormat_3byte) { surface = &input; colorType = PNG_COLOR_TYPE_RGB; } else { if (input.format == requiredFormat_4byte) { surface = &input; } else { surface = tmp = input.convertTo(requiredFormat_4byte); } colorType = PNG_COLOR_TYPE_RGB_ALPHA; } png_structp pngPtr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!pngPtr) { return false; } png_infop infoPtr = png_create_info_struct(pngPtr); if (!infoPtr) { png_destroy_write_struct(&pngPtr, NULL); return false; } png_set_error_fn(pngPtr, NULL, pngError, pngWarning); // TODO: The manual says errors should be handled via setjmp png_set_write_fn(pngPtr, &out, pngWriteToStream, pngFlushStream); png_set_IHDR(pngPtr, infoPtr, surface->w, surface->h, 8, colorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); Common::Array<const uint8 *> rows; rows.reserve(surface->h); if (bottomUp) { for (uint y = surface->h; y-- > 0;) { rows.push_back((const uint8 *)surface->getBasePtr(0, y)); } } else { for (uint y = 0; y < surface->h; ++y) { rows.push_back((const uint8 *)surface->getBasePtr(0, y)); } } png_set_rows(pngPtr, infoPtr, const_cast<uint8 **>(&rows.front())); png_write_png(pngPtr, infoPtr, 0, NULL); png_destroy_write_struct(&pngPtr, &infoPtr); // free tmp surface if (tmp) { tmp->free(); delete tmp; } return true; #else return false; #endif }
void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Common::Rect &_srcRect , Graphics::Surface &dst, int _x, int _y, uint32 colorkey) { Common::Rect srcRect = _srcRect; if (srcRect.isEmpty()) srcRect = Common::Rect(src.w, src.h); srcRect.clip(src.w, src.h); Common::Rect dstRect = Common::Rect(-_x + srcRect.left , -_y + srcRect.top, -_x + srcRect.left + dst.w, -_y + srcRect.top + dst.h); srcRect.clip(dstRect); if (srcRect.isEmpty() || !srcRect.isValidRect()) return; Graphics::Surface *srcAdapted = src.convertTo(dst.format); uint32 keycolor = colorkey & ((1 << (src.format.bytesPerPixel << 3)) - 1); // Copy srcRect from src surface to dst surface const byte *srcBuffer = (const byte *)srcAdapted->getBasePtr(srcRect.left, srcRect.top); int xx = _x; int yy = _y; if (xx < 0) xx = 0; if (yy < 0) yy = 0; if (_x >= dst.w || _y >= dst.h) { srcAdapted->free(); delete srcAdapted; return; } byte *dstBuffer = (byte *)dst.getBasePtr(xx, yy); int32 w = srcRect.width(); int32 h = srcRect.height(); for (int32 y = 0; y < h; y++) { switch (srcAdapted->format.bytesPerPixel) { case 1: { const uint *srcTemp = (const uint *)srcBuffer; uint *dstTemp = (uint *)dstBuffer; for (int32 x = 0; x < w; x++) { if (*srcTemp != keycolor) *dstTemp = *srcTemp; srcTemp++; dstTemp++; } } break; case 2: { const uint16 *srcTemp = (const uint16 *)srcBuffer; uint16 *dstTemp = (uint16 *)dstBuffer; for (int32 x = 0; x < w; x++) { if (*srcTemp != keycolor) *dstTemp = *srcTemp; srcTemp++; dstTemp++; } } break; case 4: { const uint32 *srcTemp = (const uint32 *)srcBuffer; uint32 *dstTemp = (uint32 *)dstBuffer; for (int32 x = 0; x < w; x++) { if (*srcTemp != keycolor) *dstTemp = *srcTemp; srcTemp++; dstTemp++; } } break; default: break; } srcBuffer += srcAdapted->pitch; dstBuffer += dst.pitch; } srcAdapted->free(); delete srcAdapted; }