void splashScreen() { Common::MemoryReadStream stream(logo_data, ARRAYSIZE(logo_data)); Image::BitmapDecoder bitmap; if (!bitmap.loadStream(stream)) { warning("Error loading logo file"); return; } g_system->showOverlay(); // Fill with blue - ResidualVM theme Graphics::Surface screen; screen.create(g_system->getOverlayWidth(), g_system->getOverlayHeight(), g_system->getOverlayFormat()); screen.fillRect(Common::Rect(screen.w, screen.h), screen.format.ARGBToColor(0xff, 0x1e, 0x6f, 0x95)); // ResidualVM theme // Load logo Graphics::Surface *logo = bitmap.getSurface()->convertTo(g_system->getOverlayFormat(), bitmap.getPalette()); int lx = MAX((g_system->getOverlayWidth() - logo->w) / 2, 0); int ly = MAX((g_system->getOverlayHeight() - logo->h) / 2, 0); // Print version information const Graphics::Font *font = FontMan.getFontByUsage(Graphics::FontManager::kConsoleFont); int w = font->getStringWidth(gScummVMVersionDate); int x = g_system->getOverlayWidth() - w - 5; // lx + logo->w - w + 5; int y = g_system->getOverlayHeight() - font->getFontHeight() - 5; //ly + logo->h + 5; font->drawString(&screen, gScummVMVersionDate, x, y, w, screen.format.ARGBToColor(0xff, 0, 0, 0)); g_system->copyRectToOverlay(screen.getPixels(), screen.pitch, 0, 0, screen.w, screen.h); screen.free(); // Draw logo int lw = MIN<uint16>(logo->w, g_system->getOverlayWidth() - lx); int lh = MIN<uint16>(logo->h, g_system->getOverlayHeight() - ly); g_system->copyRectToOverlay(logo->getPixels(), logo->pitch, lx, ly, lw, lh); logo->free(); delete logo; g_system->updateScreen(); // Delay 0.6 secs uint time0 = g_system->getMillis(); Common::Event event; while (time0 + 600 > g_system->getMillis()) { (void)g_system->getEventManager()->pollEvent(event); g_system->delayMillis(10); } g_system->hideOverlay(); splash = true; }
void RenderManager::blitSurfaceToBkgScaled(const Graphics::Surface &src, const Common::Rect &_dstRect, int32 colorkey) { if (src.w == _dstRect.width() && src.h == _dstRect.height()) { blitSurfaceToBkg(src, _dstRect.left, _dstRect.top, colorkey); } else { Graphics::Surface *tmp = new Graphics::Surface; tmp->create(_dstRect.width(), _dstRect.height(), src.format); scaleBuffer(src.getPixels(), tmp->getPixels(), src.w, src.h, src.format.bytesPerPixel, _dstRect.width(), _dstRect.height()); blitSurfaceToBkg(*tmp, _dstRect.left, _dstRect.top, colorkey); tmp->free(); delete tmp; } }
Graphics::Surface *OpenGLRenderer::getScreenshot() { Common::Rect screen = viewport(); Graphics::Surface *s = new Graphics::Surface(); s->create(screen.width(), screen.height(), Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24)); glReadPixels(screen.left, screen.top, screen.width(), screen.height(), GL_RGBA, GL_UNSIGNED_BYTE, s->getPixels()); flipVertical(s); return s; }
Graphics::Surface *TruetypeFont::drawTextToSurface(const Common::String &text, uint16 textColor, int maxWidth, int maxHeight, Graphics::TextAlign align, bool wrap) { if (text.equals("")) { return nullptr; } Graphics::Surface *surface = new Graphics::Surface(); if (!wrap) { int width = MIN(_font->getStringWidth(text), maxWidth); surface->create(width, _lineHeight, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)); // TODO: Add better alpha support by getting the pixels from the backbuffer. // However doing that requires some kind of caching system so future text doesn't try to use this text as it's alpha background. surface->fillRect(Common::Rect(0, 0, surface->w, surface->h), 0); _font->drawString(surface, text, 0, 0, maxWidth, textColor, align); return surface; } Common::Array<Common::String> lines; _font->wordWrapText(text, maxWidth, lines); while (maxHeight > 0 && (int)lines.size() * _lineHeight > maxHeight) { lines.pop_back(); } if (lines.size() == 0) { delete surface; return nullptr; } surface->create(maxWidth, lines.size() * _lineHeight, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)); surface->fillRect(Common::Rect(0, 0, surface->w, surface->h), 0); int heightOffset = 0; for (Common::Array<Common::String>::iterator it = lines.begin(); it != lines.end(); it++) { _font->drawString(surface, *it, 0, 0 + heightOffset, maxWidth, textColor, align); heightOffset += _lineHeight; } return surface; }
static bool createThumbnail(Graphics::Surface &out, Graphics::Surface &in) { int height; if ((in.w == 320 && in.h == 200) || (in.w == 640 && in.h == 400)) { height = kThumbnailHeight1; } else { height = kThumbnailHeight2; } out.create(kThumbnailWidth, height, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)); scaleThumbnail(in, out); in.free(); return true; }
void EventsManager::setCursor(CursorType cursorId) { if (cursorId == _cursorId) return; _cursorId = cursorId; if (cursorId == CURSOR_INVENTORY) { // Set the cursor CursorMan.replaceCursor(_invCursor.getPixels(), _invCursor.w, _invCursor.h, _invCursor.w / 2, _invCursor.h / 2, 0); } else { // Get a pointer to the mouse data to use, and get the cursor hotspot const byte *srcP = Amazon::CURSORS[cursorId]; int hotspotX = (int16)READ_LE_UINT16(srcP); int hotspotY = (int16)READ_LE_UINT16(srcP + 2); srcP += 4; // Create a surface to build up the cursor on Graphics::Surface cursorSurface; cursorSurface.create(16, 16, Graphics::PixelFormat::createFormatCLUT8()); byte *destP = (byte *)cursorSurface.getPixels(); Common::fill(destP, destP + CURSOR_WIDTH * CURSOR_HEIGHT, 0); // Loop to build up the cursor for (int y = 0; y < CURSOR_HEIGHT; ++y) { destP = (byte *)cursorSurface.getBasePtr(0, y); int width = CURSOR_WIDTH; int skip = *srcP++; int plot = *srcP++; if (skip >= width) break; // Skip over pixels destP += skip; width -= skip; // Write out the pixels to plot while (plot > 0 && width > 0) { *destP++ = *srcP++; --plot; --width; } } // Set the cursor CursorMan.replaceCursor(cursorSurface.getPixels(), CURSOR_WIDTH, CURSOR_HEIGHT, hotspotX, hotspotY, 0); // Free the cursor surface cursorSurface.free(); } }
Graphics::Surface *RenderManager::getBkgRect(Common::Rect &rect) { Common::Rect dst = rect; dst.clip(_backgroundWidth, _backgroundHeight); if (dst.isEmpty() || !dst.isValidRect()) return NULL; Graphics::Surface *srf = new Graphics::Surface; srf->create(dst.width(), dst.height(), _currentBackgroundImage.format); srf->copyRectToSurface(_currentBackgroundImage, 0, 0, Common::Rect(dst)); return srf; }
Graphics::Surface *BalloonManager_br::expandBalloon(Frames *data, int frameNum) { Common::Rect rect; data->getRect(frameNum, rect); rect.translate(-rect.left, -rect.top); Graphics::Surface *surf = new Graphics::Surface; surf->create(rect.width(), rect.height(), 1); _vm->_gfx->unpackBlt(rect, data->getData(frameNum), data->getRawSize(frameNum), surf, LAYER_FOREGROUND, 100, BALLOON_TRANSPARENT_COLOR_BR); return surf; }
void MoviePlayer::drawFramePSX(const Graphics::Surface *frame) { // The PSX videos have half resolution Graphics::Surface scaledFrame; scaledFrame.create(frame->getWidth(), frame->getHeight() * 2, frame->getFormat()); for (int y = 0; y < scaledFrame.getHeight(); y++) memcpy(scaledFrame.getBasePtr(0, y), frame->getBasePtr(0, y / 2), scaledFrame.getWidth() * scaledFrame.getFormat().bytesPerPixel); uint16 x = (g_system->getWidth() - scaledFrame.getWidth()) / 2; uint16 y = (g_system->getHeight() - scaledFrame.getHeight()) / 2; _vm->_system->copyRectToScreen(scaledFrame.getPixels(), scaledFrame.getPitch(), x, y, scaledFrame.getWidth(), scaledFrame.getHeight()); }
SaveDataWidget::SaveDataWidget(int slot, Gfx::Driver *gfx, SaveLoadMenuScreen *screen) : StaticLocationWidget(nullptr, nullptr, nullptr), _slot(slot), _screen(screen), _thumbWidth(StarkUserInterface->kThumbnailWidth), _thumbHeight(StarkUserInterface->kThumbnailHeight), _texture(gfx->createTexture()), _outline(gfx->createTexture()), _surfaceRenderer(gfx->createSurfaceRenderer()), _textDesc(gfx), _textTime(gfx), _isMouseHovered(false), _hasSave(false), _name() { // Load from the save data loadSaveDataElements(); _textDesc.setColor(_textColor); _textDesc.setFont(FontProvider::kCustomFont, 3); _textTime.setColor(_textColor); _textTime.setFont(FontProvider::kCustomFont, 3); Graphics::PixelFormat pixelFormat = Gfx::Driver::getRGBAPixelFormat(); uint32 outlineColor = pixelFormat.ARGBToColor( _outlineColor.a, _outlineColor.r, _outlineColor.g, _outlineColor.b ); // Create the outline texture Graphics::Surface lineSurface; lineSurface.create(_thumbWidth, _thumbHeight, pixelFormat); lineSurface.drawThickLine(0, 0, _thumbWidth - 1, 0, 2, 2, outlineColor); lineSurface.drawThickLine(0, 0, 0, _thumbHeight - 1, 2, 2, outlineColor); lineSurface.drawThickLine(_thumbWidth - 2, 0, _thumbWidth - 2, _thumbHeight - 2, 2, 2, outlineColor); lineSurface.drawThickLine(0, _thumbHeight - 2, _thumbWidth - 2, _thumbHeight - 2, 2, 2, outlineColor); _outline->update(&lineSurface); lineSurface.free(); // Set the position _thumbPos.x = 41 + (_slot % SaveLoadMenuScreen::_slotPerRow) * (_thumbWidth + 39); _thumbPos.y = 61 + (_slot % SaveLoadMenuScreen::_slotPerPage / SaveLoadMenuScreen::_slotPerColumn) * (_thumbHeight + 38); _textDescPos.x = _thumbPos.x; _textDescPos.y = _thumbPos.y + _thumbHeight + 2; _textTimePos.x = _thumbPos.x; _textTimePos.y = _textDescPos.y + 12; }
Graphics::Surface BladeRunnerEngine::generateThumbnail() const { Graphics::Surface thumbnail; thumbnail.create(640 / 8, 480 / 8, createRGB555()); for (int y = 0; y < thumbnail.h; ++y) { for (int x = 0; x < thumbnail.w; ++x) { uint16 *dstPixel = (uint16 *)thumbnail.getBasePtr(x, y); const uint16 *srcPixel = (const uint16 *)_surfaceFront.getBasePtr(x * 8, y * 8); *dstPixel = *srcPixel; } } return thumbnail; }
void MoviePlayer::drawFramePSX(const Graphics::Surface *frame) { // The PSX videos have half resolution Graphics::Surface scaledFrame; scaledFrame.create(frame->w, frame->h * 2, frame->format); for (int y = 0; y < scaledFrame.h; y++) memcpy(scaledFrame.getBasePtr(0, y), frame->getBasePtr(0, y / 2), scaledFrame.w * scaledFrame.format.bytesPerPixel); uint16 x = (g_system->getWidth() - scaledFrame.w) / 2; uint16 y = (g_system->getHeight() - scaledFrame.h) / 2; _vm->_system->copyRectToScreen((byte *)scaledFrame.pixels, scaledFrame.pitch, x, y, scaledFrame.w, scaledFrame.h); scaledFrame.free(); }
virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor = 255, bool dontScale = false, const Graphics::PixelFormat *format = NULL) { const Graphics::PixelFormat mformat = format ? *format : Graphics::PixelFormat::createFormatCLUT8(); if(_mouseImage.w != w || _mouseImage.h != h || _mouseImage.format != mformat) { _mouseImage.create(w, h, mformat); } memcpy(_mouseImage.pixels, buf, h * _mouseImage.pitch); _mouseHotspotX = hotspotX; _mouseHotspotY = hotspotY; _mouseKeyColor = keycolor; _mouseDontScale = dontScale; }
Graphics::Surface *TinyGLRenderer::getScreenshot() { Graphics::Surface *s = new Graphics::Surface(); s->create(kOriginalWidth, kOriginalHeight, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24)); Graphics::PixelBuffer buf(s->format, (byte *)s->getPixels()); _fb->copyToBuffer(buf); //Vertical flip in place: Graphics::PixelBuffer startLine(s->format, kOriginalWidth, DisposeAfterUse::YES); Graphics::PixelBuffer endLine(s->format, kOriginalWidth, DisposeAfterUse::YES); for(int y = 0; y < kOriginalHeight / 2; y++) { startLine.copyBuffer(0, y * kOriginalWidth, kOriginalWidth, buf); endLine.copyBuffer(0, (kOriginalHeight - y - 1) * kOriginalWidth, kOriginalWidth, buf); buf.copyBuffer(y * kOriginalWidth, 0, kOriginalWidth, endLine); buf.copyBuffer((kOriginalHeight - y - 1) * kOriginalWidth, 0, kOriginalWidth, startLine); } return s; }
void AnimationResource::load(byte *source, int size) { Common::MemoryReadStream *sourceS = new Common::MemoryReadStream(source, size); sourceS->readUint32LE(); sourceS->readUint32LE(); sourceS->readUint16LE(); _flags = sourceS->readUint16LE(); _width = sourceS->readUint16LE(); _height = sourceS->readUint16LE(); sourceS->readUint32LE(); uint16 frameCount = sourceS->readUint16LE(); sourceS->readUint16LE(); sourceS->readUint16LE(); for (uint16 i = 0; i < frameCount; i++) { sourceS->seek(26 + i * 4); uint32 frameOffs = sourceS->readUint32LE(); sourceS->seek(frameOffs); sourceS->readUint32LE(); sourceS->readUint32LE(); uint16 frameWidth = sourceS->readUint16LE(); uint16 frameHeight = sourceS->readUint16LE(); uint16 cmdOffs = sourceS->readUint16LE(); sourceS->readUint16LE(); uint16 pixelOffs = sourceS->readUint16LE(); sourceS->readUint16LE(); uint16 maskOffs = sourceS->readUint16LE(); sourceS->readUint16LE(); uint16 lineSize = sourceS->readUint16LE(); Graphics::Surface *frame = new Graphics::Surface(); frame->create(frameWidth, frameHeight, Graphics::PixelFormat::createFormatCLUT8()); decompressImage(source + frameOffs, *frame, cmdOffs, pixelOffs, maskOffs, lineSize, 0, 0, 0, _flags & 1); _frames.push_back(frame); } delete sourceS; }
Graphics::Surface *RenderManager::tranposeSurface(const Graphics::Surface *surface) { Graphics::Surface *tranposedSurface = new Graphics::Surface(); tranposedSurface->create(surface->h, surface->w, surface->format); const uint16 *source = (const uint16 *)surface->getPixels(); uint16 *dest = (uint16 *)tranposedSurface->getPixels(); for (uint32 y = 0; y < tranposedSurface->h; ++y) { uint32 columnIndex = y * tranposedSurface->w; for (uint32 x = 0; x < tranposedSurface->w; ++x) { dest[columnIndex + x] = source[x * surface->w + y]; } } return tranposedSurface; }
int MenuSystem::run(MenuID menuId) { _background = new Graphics::Surface(); _background->create(640, 400, Graphics::PixelFormat::createFormatCLUT8()); // Save original background Graphics::Surface backgroundOrig; backgroundOrig.create(640, 400, Graphics::PixelFormat::createFormatCLUT8()); memcpy(backgroundOrig.getBasePtr(0,0), _vm->_screen->_frontScreen, 640 * 400); _currMenuID = kMenuIdNone; _newMenuID = menuId; _currItemID = kItemIdNone; _editingDescription = false; _running = true; _top = 30 - _vm->_guiHeight / 2; _needRedraw = false; _vm->_palette->buildColorTransTable(0, 16, 7); _vm->_screen->_renderQueue->clear(); // Draw the menu background and frame _vm->_screen->blastSprite(0x140 + _vm->_cameraX, 0x175 + _vm->_cameraY, 0, 1, 0x4000); shadeRect(60, 39, 520, 247, 225, 229); memcpy(_background->getPixels(), _vm->_screen->_frontScreen, 640 * 400); while (_running) { update(); _vm->_system->updateScreen(); } // Restore original background memcpy(_vm->_screen->_frontScreen, backgroundOrig.getBasePtr(0,0), 640 * 400); _vm->_system->copyRectToScreen(_vm->_screen->_frontScreen, 640, 0, 0, 640, 400); _vm->_system->updateScreen(); // Cleanup backgroundOrig.free(); _background->free(); delete _background; return 0; }
Graphics::Surface *Hero::zoomSprite(Graphics::Surface *heroFrame) { Graphics::Surface *zoomedFrame = new Graphics::Surface(); zoomedFrame->create(_scaledFrameXSize, _scaledFrameYSize, Graphics::PixelFormat::createFormatCLUT8()); int sprZoomX; int sprZoomY = _vm->_scaleValue; uint xSource = 0; uint ySource = 0; uint xDest = 0; uint yDest = 0; for (int i = 0; i < _scaledFrameYSize; i++) { // linear_loop: while (1) { sprZoomY -= 100; if (sprZoomY >= 0 || _vm->_scaleValue == 10000) { // all_r_y sprZoomX = _vm->_scaleValue; break; // to loop_lin } else { sprZoomY += _vm->_scaleValue; xSource = 0; ySource++; } } // loop_lin: for (int j = 0; j < _scaledFrameXSize; j++) { sprZoomX -= 100; if (sprZoomX >= 0) { // its_all_r memcpy(zoomedFrame->getBasePtr(xDest, yDest), heroFrame->getBasePtr(xSource, ySource), 1); xDest++; } else { sprZoomX += _vm->_scaleValue; j--; } xSource++; } xDest = 0; yDest++; xSource = 0; ySource++; } return zoomedFrame; }
bool createThumbnail(Graphics::Surface *surf, const uint8 *pixels, int w, int h, const uint8 *palette) { assert(surf); Graphics::Surface screen; screen.create(w, h, 2); for (uint y = 0; y < screen.h; ++y) { for (uint x = 0; x < screen.w; ++x) { byte r, g, b; r = palette[pixels[y * w + x] * 3]; g = palette[pixels[y * w + x] * 3 + 1]; b = palette[pixels[y * w + x] * 3 + 2]; ((uint16 *)screen.pixels)[y * screen.w + x] = Graphics::RGBToColor<Graphics::ColorMasks<565> >(r, g, b); } } return createThumbnail(*surf, screen); }
bool createThumbnail(Graphics::Surface *surf, const uint8 *pixels, int w, int h, const uint8 *palette) { assert(surf); Graphics::Surface screen; screen.create(w, h, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)); for (uint y = 0; y < screen.h; ++y) { for (uint x = 0; x < screen.w; ++x) { byte r, g, b; r = palette[pixels[y * w + x] * 3]; g = palette[pixels[y * w + x] * 3 + 1]; b = palette[pixels[y * w + x] * 3 + 2]; *((uint16 *)screen.getBasePtr(x, y)) = Graphics::RGBToColor<Graphics::ColorMasks<565> >(r, g, b); } } return createThumbnail(*surf, screen); }
bool InputControl::process(uint32 deltaTimeInMillis) { if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED) return false; // First see if we need to render the text if (_textChanged) { // Blit the text using the RenderManager Graphics::Surface txt; txt.create(_textRectangle.width(), _textRectangle.height(), _engine->_pixelFormat); if (!_readOnly || !_focused) _txtWidth = _engine->getTextRenderer()->drawTxt(_currentInputText, _stringInit, txt); else _txtWidth = _engine->getTextRenderer()->drawTxt(_currentInputText, _stringChooserInit, txt); _engine->getRenderManager()->blitSurfaceToBkg(txt, _textRectangle.left, _textRectangle.top); txt.free(); } if (_animation && !_readOnly && _focused) { bool needDraw = true;// = _textChanged; _frameDelay -= deltaTimeInMillis; if (_frameDelay <= 0) { _frame = (_frame + 1) % _animation->frameCount(); _frameDelay = _animation->frameTime(); needDraw = true; } if (needDraw) { const Graphics::Surface *srf = _animation->getFrameData(_frame); uint32 xx = _textRectangle.left + _txtWidth; if (xx >= _textRectangle.left + (_textRectangle.width() - _animation->width())) xx = _textRectangle.left + _textRectangle.width() - _animation->width(); _engine->getRenderManager()->blitSurfaceToBkg(*srf, xx, _textRectangle.top); } } _textChanged = false; return false; }
void RenderManager::processSubs(uint16 deltatime) { bool redraw = false; for (SubtitleMap::iterator it = _subsList.begin(); it != _subsList.end(); it++) { if (it->_value.timer != -1) { it->_value.timer -= deltatime; if (it->_value.timer <= 0) it->_value.todelete = true; } if (it->_value.todelete) { _subsList.erase(it); redraw = true; } else if (it->_value.redraw) { redraw = true; } } if (redraw) { _subtitleSurface.fillRect(Common::Rect(_subtitleSurface.w, _subtitleSurface.h), 0); for (SubtitleMap::iterator it = _subsList.begin(); it != _subsList.end(); it++) { OneSubtitle *sub = &it->_value; if (sub->txt.size()) { Graphics::Surface *rndr = new Graphics::Surface(); rndr->create(sub->r.width(), sub->r.height(), _engine->_resourcePixelFormat); _engine->getTextRenderer()->drawTxtInOneLine(sub->txt, *rndr); Common::Rect empty; blitSurfaceToSurface(*rndr, empty, _subtitleSurface, sub->r.left - _subtitleArea.left + _workingWindow.left, sub->r.top - _subtitleArea.top + _workingWindow.top); rndr->free(); delete rndr; } sub->redraw = false; } Common::Rect rect( _subtitleArea.left, _subtitleArea.top, _subtitleArea.left + _subtitleSurface.w, _subtitleArea.top + _subtitleSurface.h ); copyToScreen(_subtitleSurface, rect, 0, 0); } }
// TODO: this method will probably go away and be integrated in the main loop void Animation::play() { Common::EventManager *eventMan = g_system->getEventManager(); while (!hasEnded() && !Engine::shouldQuit()) { process(); if (_changed) { // Create a temporary surface to merge the overlay with the background Graphics::Surface *s = new Graphics::Surface; s->create(640, 480, Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0)); draw(s); // XXX: Update the screen g_system->copyRectToScreen(s->getPixels(), s->pitch, 0, 0, s->w, s->h); // Free the temporary surface s->free(); delete s; _changed = false; } g_system->updateScreen(); //FIXME: implement subtitles g_system->delayMillis(20); // Handle right-click to interrupt animations Common::Event ev = Common::Event(); while (eventMan->pollEvent(ev)) { if (ev.type == Common::EVENT_RBUTTONUP) { // Stop audio if (_audio) _audio->finish(); // TODO start LNK file sound? return; } } } }
const Graphics::Surface& getScreen() { const Graphics::Surface& srcSurface = (_overlayVisible) ? _overlay : _gameScreen; if(srcSurface.w != _screen.w || srcSurface.h != _screen.h) { _screen.create(srcSurface.w, srcSurface.h, Graphics::PixelFormat(2, 5, 5, 5, 1, 10, 5, 0, 15)); } if(srcSurface.w && srcSurface.h) { switch(srcSurface.format.bytesPerPixel) { case 1: blit<uint8, uint16>(_screen, srcSurface, 0, 0, _gamePalette, 0xFFFFFFFF); break; case 2: blit<uint16, uint16>(_screen, srcSurface, 0, 0, _gamePalette, 0xFFFFFFFF); break; case 3: blit<uint8, uint16>(_screen, srcSurface, 0, 0, _gamePalette, 0xFFFFFFFF); break; case 4: blit<uint32, uint16>(_screen, srcSurface, 0, 0, _gamePalette, 0xFFFFFFFF); break; } } // Draw Mouse if(_mouseVisible) { const int x = _mouseX - _mouseHotspotX; const int y = _mouseY - _mouseHotspotY; blit<uint8, uint16>(_screen, _mouseImage, x, y, _mousePaletteEnabled ? _mousePalette : _gamePalette, _mouseKeyColor); } return _screen; }
bool createScreenShot(Graphics::Surface &surf) { Graphics::PixelFormat screenFormat = g_system->getScreenFormat(); //convert surface to 2 bytes pixel format to avoid problems with palette saving and loading if ((screenFormat.bytesPerPixel == 1) || (screenFormat.bytesPerPixel == 2)) { return grabScreen565(&surf); } else { Graphics::Surface *screen = g_system->lockScreen(); if (!screen) { return false; } surf.create(screen->w, screen->h, Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)); for (uint y = 0; y < screen->h; ++y) { for (uint x = 0; x < screen->w; ++x) { byte r = 0, g = 0, b = 0, a = 0; uint32 col = READ_UINT32(screen->getBasePtr(x, y)); screenFormat.colorToARGB(col, a, r, g, b); *((uint32 *)surf.getBasePtr(x, y)) = Graphics::ARGBToColor<Graphics::ColorMasks<8888> >(a, r, g, b); } } g_system->unlockScreen(); return true; } }
Graphics::Surface *ShaderRenderer::getScreenshot() { Common::Rect screen = viewport(); Graphics::Surface *s = new Graphics::Surface(); s->create(screen.width(), screen.height(), Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24)); #if defined(USE_GLES2) GLenum format = GL_UNSIGNED_BYTE; #else GLenum format = GL_UNSIGNED_INT_8_8_8_8_REV; #endif glReadPixels(screen.left, screen.top, screen.width(), screen.height(), GL_RGBA, format, s->getPixels()); #if defined(USE_GLES2) && defined(SCUMM_BIG_ENDIAN) // OpenGL ES does not support the GL_UNSIGNED_INT_8_8_8_8_REV texture format, we need to byteswap the surface OpenGLTexture::byteswapSurface(s); #endif flipVertical(s); return s; }
PaintControl::PaintControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream) : Control(engine, key, CONTROL_PAINT) { _cursor = CursorIndex_Active; _paint = NULL; _bkg = NULL; _brush = NULL; _colorKey = 0; _mouseDown = false; // Loop until we find the closing brace Common::String line = stream.readLine(); trimCommentsAndWhiteSpace(&line); Common::String param; Common::String values; getParams(line, param, values); while (!stream.eos() && !line.contains('}')) { if (param.matchString("rectangle", true)) { int x; int y; int width; int height; sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height); _rectangle = Common::Rect(x, y, width + x, height + y); } else if (param.matchString("cursor", true)) { _cursor = _engine->getCursorManager()->getCursorId(values); } else if (param.matchString("brush_file", true)) { _brush = _engine->getRenderManager()->loadImage(values, false); } else if (param.matchString("venus_id", true)) { _venusId = atoi(values.c_str()); } else if (param.matchString("paint_file", true)) { _paint = _engine->getRenderManager()->loadImage(values, false); } else if (param.matchString("eligible_objects", true)) { char buf[256]; memset(buf, 0, 256); strcpy(buf, values.c_str()); char *curpos = buf; char *strend = buf + strlen(buf); while (true) { char *st = curpos; if (st >= strend) break; while (*curpos != ' ' && curpos < strend) curpos++; *curpos = 0; curpos++; int obj = atoi(st); _eligibleObjects.push_back(obj); } } line = stream.readLine(); trimCommentsAndWhiteSpace(&line); getParams(line, param, values); } if (_paint) { _colorKey = _paint->format.RGBToColor(255, 0, 255); _bkg = new Graphics::Surface; _bkg->create(_rectangle.width(), _rectangle.height(), _paint->format); _bkg->fillRect(Common::Rect(_rectangle.width(), _rectangle.height()), _colorKey); Graphics::Surface *tmp = new Graphics::Surface; tmp->create(_rectangle.width(), _rectangle.height(), _paint->format); _engine->getRenderManager()->blitSurfaceToSurface(*_paint, _rectangle, *tmp, 0, 0); _paint->free(); delete _paint; _paint = tmp; } }
bool VideoManager::updateMovies() { bool updateScreen = false; for (uint32 i = 0; i < _videoStreams.size() && !_vm->shouldQuit(); i++) { // Skip deleted videos if (!_videoStreams[i].video) continue; // Remove any videos that are over if (_videoStreams[i].endOfVideo()) { if (_videoStreams[i].loop) { _videoStreams[i]->seekToTime(_videoStreams[i].start); } else { // Check the video time one last time before deleting it _vm->doVideoTimer(i, true); delete _videoStreams[i].video; _videoStreams[i].clear(); continue; } } // Nothing more to do if we're paused if (_videoStreams[i]->isPaused()) continue; // Check if we need to draw a frame if (_videoStreams[i]->needsUpdate()) { const Graphics::Surface *frame = _videoStreams[i]->decodeNextFrame(); Graphics::Surface *convertedFrame = 0; if (frame && _videoStreams[i].enabled) { Graphics::PixelFormat pixelFormat = _vm->_system->getScreenFormat(); // Create (or resize) the off-screen surface if (frame->w > _videoStreams[i].surface.w || frame->h > _videoStreams[i].surface.h) { _videoStreams[i].surface.create(frame->w, frame->h, pixelFormat); } // Convert from 8bpp to the current screen format if necessary if (frame->format.bytesPerPixel == 1) { if (pixelFormat.bytesPerPixel == 1) { if (_videoStreams[i]->hasDirtyPalette()) _videoStreams[i]->setSystemPalette(); } else { convertedFrame = new Graphics::Surface(); const byte *palette = _videoStreams[i]->getPalette(); assert(palette); convertedFrame->create(frame->w, frame->h, pixelFormat); for (uint16 j = 0; j < frame->h; j++) { for (uint16 k = 0; k < frame->w; k++) { byte palIndex = *((const byte *)frame->getBasePtr(k, j)); byte r = palette[palIndex * 3]; byte g = palette[palIndex * 3 + 1]; byte b = palette[palIndex * 3 + 2]; if (pixelFormat.bytesPerPixel == 2) *((uint16 *)convertedFrame->getBasePtr(k, j)) = pixelFormat.RGBToColor(r, g, b); else *((uint32 *)convertedFrame->getBasePtr(k, j)) = pixelFormat.RGBToColor(r, g, b); } } frame = convertedFrame; } } // Copy frame to the off-screen surface for (int y = 0; y < frame->h; ++y) { memcpy(_videoStreams[i].surface.getBasePtr(0, y), frame->getBasePtr(0, y), frame->w * pixelFormat.bytesPerPixel); } // Delete 8bpp conversion surface if (convertedFrame) { convertedFrame->free(); delete convertedFrame; } } } // Don't draw anything until we have a valid surface if (_videoStreams[i].surface.w == 0 || _videoStreams[i].surface.h == 0) continue; // Clip the width/height to make sure we stay on the screen (Myst does this a few times) uint16 width = MIN<int32>(_videoStreams[i]->getWidth(), _vm->_system->getWidth() - _videoStreams[i].x); uint16 height = MIN<int32>(_videoStreams[i]->getHeight(), _vm->_system->getHeight() - _videoStreams[i].y); // Render the off-screen surface _vm->_system->copyRectToScreen((byte *)_videoStreams[i].surface.pixels, _videoStreams[i].surface.pitch, _videoStreams[i].x, _videoStreams[i].y, width, height); updateScreen = true; // Check the video time _vm->doVideoTimer(i, false); } // Return true if we need to update the screen return updateScreen; }
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<WideString> 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; } // TODO: This debug call does not work with WideString because text.c_str() returns an uint32 array. //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(); surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), _gameRef->_renderer->getPixelFormat()); uint32 useColor = 0xffffffff; Common::Array<WideString>::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(); if (_deletableFont) { // Reconstruct the alpha channel of the font. // Since we painted it with color 0xFFFFFFFF onto a black background, // the alpha channel is gone, but the color value of each pixel corresponds // to its original alpha value. Graphics::PixelFormat format = _gameRef->_renderer->getPixelFormat(); uint32 *pixels = (uint32 *)surface->getPixels(); // This is a Surface we created ourselves, so no empty space between rows. for (int i = 0; i < surface->w * surface->h; ++i) { uint8 a, r, g, b; format.colorToRGB(*pixels, r, g, b); a = r; *pixels++ = format.ARGBToColor(a, r, g, b); } } retSurface->putSurface(*surface, true); surface->free(); delete surface; return retSurface; // TODO: _isUnderline, _isBold, _isItalic, _isStriked }
void ZVision::playVideo(Video::VideoDecoder &vid, const Common::Rect &destRect, bool skippable, Subtitle *sub) { Common::Rect dst = destRect; // If destRect is empty, no specific scaling was requested. However, we may choose to do scaling anyway if (dst.isEmpty()) dst = Common::Rect(vid.getWidth(), vid.getHeight()); Graphics::Surface scaled; if (vid.getWidth() != dst.width() || vid.getHeight() != dst.height()) scaled.create(dst.width(), dst.height(), vid.getPixelFormat()); uint16 x = _workingWindow.left + dst.left; uint16 y = _workingWindow.top + dst.top; uint16 finalWidth = dst.width() < _workingWindow.width() ? dst.width() : _workingWindow.width(); uint16 finalHeight = dst.height() < _workingWindow.height() ? dst.height() : _workingWindow.height(); bool showSubs = (_scriptManager->getStateValue(StateKey_Subtitles) == 1); _clock.stop(); vid.start(); _videoIsPlaying = true; // Only continue while the video is still playing while (!shouldQuit() && !vid.endOfVideo() && vid.isPlaying()) { // Check for engine quit and video stop key presses while (_eventMan->pollEvent(_event)) { switch (_event.type) { case Common::EVENT_KEYDOWN: switch (_event.kbd.keycode) { case Common::KEYCODE_q: if (_event.kbd.hasFlags(Common::KBD_CTRL)) quitGame(); break; case Common::KEYCODE_SPACE: if (skippable) { vid.stop(); } break; default: break; } default: break; } } if (vid.needsUpdate()) { const Graphics::Surface *frame = vid.decodeNextFrame(); if (sub && showSubs) sub->process(vid.getCurFrame()); if (frame) { if (scaled.getPixels()) { _renderManager->scaleBuffer(frame->getPixels(), scaled.getPixels(), frame->getWidth(), frame->getHeight(), frame->getFormat().bytesPerPixel, scaled.getWidth(), scaled.getHeight()); frame = &scaled; } Common::Rect rect = Common::Rect(x, y, x + finalWidth, y + finalHeight); _renderManager->copyToScreen(*frame, rect, 0, 0); _renderManager->processSubs(0); } } // Always update the screen so the mouse continues to render _system->updateScreen(); _system->delayMillis(vid.getTimeToNextFrame() / 2); } _videoIsPlaying = false; _clock.start(); }