void Surface::allocateSurface(const Common::Rect &bounds) { deallocateSurface(); if (bounds.isEmpty()) return; _bounds = bounds; _surface = new Graphics::Surface(); _surface->create(bounds.width(), bounds.height(), g_system->getScreenFormat()); _ownsSurface = true; }
void PanoramaScroll::setBounds(const Common::Rect &r) { Animation::setBounds(r); _boundsWidth = r.width(); Common::Rect r2; _panorama.getViewBounds(r2); r2.right = r2.left + _boundsWidth; r2.bottom = r2.top + r.height(); _panorama.setViewBounds(r2); }
void GfxTransitions::scrollCopyOldToScreen(Common::Rect screenRect, int16 x, int16 y) { byte *oldScreenPtr = _oldScreen; int16 screenWidth = _screen->getDisplayWidth(); if (_screen->getUpscaledHires()) { _screen->adjustToUpscaledCoordinates(screenRect.top, screenRect.left); _screen->adjustToUpscaledCoordinates(screenRect.bottom, screenRect.right); _screen->adjustToUpscaledCoordinates(y, x); } oldScreenPtr += screenRect.left + screenRect.top * screenWidth; g_system->copyRectToScreen(oldScreenPtr, screenWidth, x, y, screenRect.width(), screenRect.height()); }
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 Screen::flushImage(ImageFrame *frame, const Common::Point &pt, Common::Rect &newBounds, int scaleVal) { Common::Point newPos(newBounds.left, newBounds.top); Common::Point newSize(newBounds.width(), newBounds.height()); if (scaleVal == SCALE_THRESHOLD) flushImage(frame, pt, &newPos.x, &newPos.y, &newSize.x, &newSize.y); else flushScaleImage(frame, pt, &newPos.x, &newPos.y, &newSize.x, &newSize.y, scaleVal); // Transfer the pos and size amounts into a single bounds rect newBounds = Common::Rect(newPos.x, newPos.y, newPos.x + newSize.x, newPos.y + newSize.y); }
void OpenGLRenderer::setupCameraPerspective(float pitch, float heading, float fov) { BaseRenderer::setupCameraPerspective(pitch, heading, fov); Common::Rect frame = frameViewport(); glViewport(frame.left, frame.top, frame.width(), frame.height()); glMatrixMode(GL_PROJECTION); glLoadMatrixf(_projectionMatrix.getData()); glMatrixMode(GL_MODELVIEW); glLoadMatrixf(_modelViewMatrix.getData()); }
void UISlots::add(const Common::Rect &bounds) { assert(size() < 50); UISlot ie; ie._flags = IMG_OVERPRINT; ie._segmentId = IMG_TEXT_UPDATE; ie._position = Common::Point(bounds.left, bounds.top); ie._width = bounds.width(); ie._height = bounds.height(); push_back(ie); }
void ShaderRenderer::drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture, float transparency) { OpenGLTexture *glTexture = static_cast<OpenGLTexture *>(texture); const float tLeft = textureRect.left / (float) glTexture->internalWidth; const float tWidth = textureRect.width() / (float) glTexture->internalWidth; const float tTop = textureRect.top / (float) glTexture->internalHeight; const float tHeight = textureRect.height() / (float) glTexture->internalHeight; const float sLeft = screenRect.left; const float sTop = screenRect.top; const float sWidth = screenRect.width(); const float sHeight = screenRect.height(); if (transparency >= 0.0) { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); } else { transparency = 1.0; } _box_shader->use(); _box_shader->setUniform("textured", true); _box_shader->setUniform("color", Math::Vector4d(1.0f, 1.0f, 1.0f, transparency)); _box_shader->setUniform("verOffsetXY", scaled(sLeft, sTop)); _box_shader->setUniform("verSizeWH", scaled(sWidth, sHeight)); _box_shader->setUniform("texOffsetXY", Math::Vector2d(tLeft, tTop)); _box_shader->setUniform("texSizeWH", Math::Vector2d(tWidth, tHeight)); glEnable(GL_TEXTURE_2D); glDepthMask(GL_FALSE); glBindTexture(GL_TEXTURE_2D, glTexture->id); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisable(GL_BLEND); glDepthMask(GL_TRUE); }
void RivenGraphics::drawExtrasImage(uint16 id, Common::Rect dstRect) { MohawkSurface *mhkSurface = _bitmapDecoder->decodeImage(_vm->getExtrasResource(ID_TBMP, id)); mhkSurface->convertToTrueColor(); Graphics::Surface *surface = mhkSurface->getSurface(); assert(dstRect.width() == surface->w); for (uint16 i = 0; i < surface->h; i++) memcpy(_mainScreen->getBasePtr(dstRect.left, i + dstRect.top), surface->getBasePtr(0, i), surface->pitch); delete mhkSurface; _dirtyScreen = true; }
int BitmapFont::getSourceCharacterWidth(uint charIndex, const Graphics::Surface &src, const Common::Rect &charBounds) { if (charIndex == 0) // The space character is treated as half the width of bounding area return charBounds.width() / 2; // Scan through the rows to find the right most pixel, getting the width from that int maxWidth = 0, rowX; for (int y = charBounds.top; y < charBounds.bottom; ++y) { rowX = 0; const byte *srcP = (const byte *)src.getBasePtr(charBounds.left, y); for (int x = 0; x < charBounds.width(); ++x, ++srcP) { if (!*srcP) rowX = x; } maxWidth = MAX(maxWidth, MIN(rowX + 2, (int)charBounds.width())); } return maxWidth; }
void Surface::copyToCurrentPort(const Common::Rect &srcRect, const Common::Rect &dstRect) const { Graphics::Surface *screen = ((PegasusEngine *)g_engine)->_gfx->getCurSurface(); byte *src = (byte *)_surface->getBasePtr(srcRect.left, srcRect.top); byte *dst = (byte *)screen->getBasePtr(dstRect.left, dstRect.top); int lineSize = srcRect.width() * _surface->format.bytesPerPixel; for (int y = 0; y < srcRect.height(); y++) { memcpy(dst, src, lineSize); src += _surface->pitch; dst += screen->pitch; } }
void CSTimeGraphics::drawRect(Common::Rect rect, byte color) { rect.clip(Common::Rect(640, 480)); // Useful with debugging. Shows where hotspots are on the screen and whether or not they're active. if (!rect.isValidRect() || rect.width() == 0 || rect.height() == 0) return; Graphics::Surface *screen = _vm->_system->lockScreen(); screen->frameRect(rect, color); _vm->_system->unlockScreen(); }
/** * Copies a section of the game frame in a circle bounded by the specified rectangle */ void RMWindow::getNewFrameWipe(byte *lpBuf, Common::Rect &rcBoundEllipse) { // Clear the screen g_system->fillScreen(0); if (!rcBoundEllipse.isValidRect()) return; Common::Point center(rcBoundEllipse.left + rcBoundEllipse.width() / 2, rcBoundEllipse.top + rcBoundEllipse.height() / 2); // The rectangle technically defines the area inside the ellipse, with the corners touching // the ellipse boundary. Since we're currently simulating the ellipse using a plain circle, // we need to calculate a necessary width using the hypotenuse of X/2 & Y/2 int x2y2 = (rcBoundEllipse.width() / 2) * (rcBoundEllipse.width() / 2) + (rcBoundEllipse.height() / 2) * (rcBoundEllipse.height() / 2); int radius = 0; while ((radius * radius) < x2y2) ++radius; // Proceed copying a circular area of the frame with the calculated radius onto the screen int error = -radius; int x = radius; int y = 0; while (x >= y) { plotSplices(lpBuf, center, x, y); error += y; ++y; error += y; if (error >= 0) { error -= x; --x; error -= x; } } }
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; }
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; }
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; }
void TinyGLRenderer::draw2DText(const Common::String &text, const Common::Point &position) { TinyGLTexture *glFont = static_cast<TinyGLTexture *>(_font); // The font only has uppercase letters Common::String textToDraw = text; textToDraw.toUppercase(); tglEnable(TGL_BLEND); tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA); tglEnable(TGL_TEXTURE_2D); tglDepthMask(TGL_FALSE); tglColor3f(1.0f, 1.0f, 1.0f); tglBindTexture(TGL_TEXTURE_2D, glFont->id); int x = position.x; int y = position.y; for (uint i = 0; i < textToDraw.size(); i++) { Common::Rect textureRect = getFontCharacterRect(textToDraw[i]); int w = textureRect.width(); int h = textureRect.height(); Graphics::BlitTransform transform(x, y); transform.sourceRectangle(textureRect.left, textureRect.top, w, h); transform.flip(true, false); Graphics::tglBlit(glFont->getBlitTexture(), transform); x += textureRect.width() - 3; } tglDisable(TGL_TEXTURE_2D); tglDisable(TGL_BLEND); tglDepthMask(TGL_TRUE); }
void Frame::drawGhostSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect) { uint8 skipColor = _vm->getPaletteColorCount() - 1; for (int ii = 0; ii < sprite.h; ii++) { const byte *src = (const byte *)sprite.getBasePtr(0, ii); byte *dst = (byte *)target.getBasePtr(drawRect.left, drawRect.top + ii); for (int j = 0; j < drawRect.width(); j++) { if ((getSpriteIDFromPos(Common::Point(drawRect.left + j, drawRect.top + ii)) != 0) && (*src != skipColor)) *dst = (_vm->getPaletteColorCount() - 1) - *src; //Oposite color src++; dst++; } } }
/** * Wipes an area of the screen */ void RMWindow::wipeEffect(Common::Rect &rcBoundEllipse) { if ((rcBoundEllipse.left == 0) && (rcBoundEllipse.top == 0) && (rcBoundEllipse.right == RM_SX) && (rcBoundEllipse.bottom == RM_SY)) { // Full screen clear wanted, so use shortcut method g_system->fillScreen(0); } else { // Clear the designated area a line at a time uint16 line[RM_SX]; Common::fill(line, line + RM_SX, 0); // Loop through each line for (int yp = rcBoundEllipse.top; yp < rcBoundEllipse.bottom; ++yp) { copyRectToScreen((const byte *)&line[0], RM_SX * 2, rcBoundEllipse.left, yp, rcBoundEllipse.width(), 1); } } }
void Compass::draw(const Common::Rect &r1) { if (_compassImage.isSurfaceValid()) { Common::Rect bounds; getBounds(bounds); Common::Rect r2; _compassImage.getSurfaceBounds(r2); CoordType width = r2.width(); CoordType offsetH = width / 10 - bounds.width() / 2 + (getFaderValue() * width) / 450 - bounds.left; CoordType offsetV = -bounds.top; r2 = r1; r2.translate(offsetH, offsetV); _compassImage.drawImage(r2, r1); } }
void Frame::drawBackgndTransSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect) { uint8 skipColor = _vm->getPaletteColorCount() - 1; //FIXME is it always white (last entry in pallette) ? for (int ii = 0; ii < sprite.h; ii++) { const byte *src = (const byte *)sprite.getBasePtr(0, ii); byte *dst = (byte *)target.getBasePtr(drawRect.left, drawRect.top + ii); for (int j = 0; j < drawRect.width(); j++) { if (*src != skipColor) *dst = *src; src++; dst++; } } }
void Node::loadMenuSpotItem(uint16 id, uint16 condition, const Common::Rect &rect) { SpotItem *spotItem = new SpotItem(_vm); spotItem->setCondition(condition); spotItem->setFade(false); spotItem->setFadeVar(abs(condition)); SpotItemFace *spotItemFace = new SpotItemFace(_faces[0], rect.left, rect.top); spotItemFace->initBlack(rect.width(), rect.height()); if (id == 1) _vm->_menu->setSaveLoadSpotItem(spotItemFace); spotItem->addFace(spotItemFace); _spotItems.push_back(spotItem); }
IngameMenuInputState_BR(Parallaction_br *vm, MenuInputHelper *helper) : MenuInputState("ingamemenu", helper), _vm(vm) { Frames *menuFrames = _vm->_disk->loadFrames("request.win"); assert(menuFrames); _menuObj = new GfxObj(kGfxObjTypeMenu, menuFrames, "ingamemenu"); Frames *mscFrames = _vm->_disk->loadFrames("onoff.win"); assert(mscFrames); _mscMenuObj = new GfxObj(kGfxObjTypeMenu, mscFrames, "msc"); Frames *sfxFrames = _vm->_disk->loadFrames("sfx.win"); assert(sfxFrames); _sfxMenuObj = new GfxObj(kGfxObjTypeMenu, sfxFrames, "sfx"); _menuObj->getRect(0, _menuRect); _cellW = _menuRect.width() / 3; _cellH = _menuRect.height() / 2; }
void ASurface::transBlitFrom(ASurface *src, const Common::Rect &bounds) { const int SCALE_LIMIT = 0x100; int scaleX = SCALE_LIMIT * bounds.width() / src->w; int scaleY = SCALE_LIMIT * bounds.height() / src->h; int scaleXCtr = 0, scaleYCtr = 0; for (int yCtr = 0, destY = bounds.top; yCtr < src->h; ++yCtr) { // Handle skipping lines if Y scaling scaleYCtr += scaleY; if (scaleYCtr < SCALE_LIMIT) continue; scaleYCtr -= SCALE_LIMIT; // Handle off-screen lines if (destY >= this->h) break; if (destY >= 0) { // Handle drawing the line const byte *pSrc = (const byte *)src->getBasePtr(0, yCtr); byte *pDest = (byte *)getBasePtr(bounds.left, destY); scaleXCtr = 0; int x = bounds.left; for (int xCtr = 0; xCtr < src->w; ++xCtr, ++pSrc) { // Handle horizontal scaling scaleXCtr += scaleX; if (scaleXCtr < SCALE_LIMIT) continue; scaleXCtr -= SCALE_LIMIT; // Only handle on-screen pixels if (x >= this->w) break; if (x >= 0 && *pSrc != 0) *pDest = *pSrc; ++pDest; ++x; } } ++destY; } }
RenderManager::RenderManager(OSystem *system, uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow, const Graphics::PixelFormat pixelFormat) : _system(system), _workingWidth(workingWindow.width()), _workingHeight(workingWindow.height()), _screenCenterX(_workingWidth / 2), _screenCenterY(_workingHeight / 2), _workingWindow(workingWindow), _pixelFormat(pixelFormat), _backgroundWidth(0), _backgroundHeight(0), _backgroundInverseVelocity(0), _backgroundOffset(0, 0), _accumulatedVelocityMilliseconds(0), _renderTable(_workingWidth, _workingHeight) { _workingWindowBuffer.create(_workingWidth, _workingHeight, _pixelFormat); _backBuffer.create(windowWidth, windowHeight, pixelFormat); }
int Sprite::getPixel(int x, int y, const Displacement &displacement) const { Common::Rect rect = getRect(displacement); int dy = y - rect.top; int dx = x - rect.left; // Calculate scaling factors double scaleX = double(rect.width()) / _width; double scaleY = double(rect.height()) / _height; int sy = scummvm_lround(dy / scaleY); int sx = scummvm_lround(dx / scaleX); if (_mirror) return _data[sy * _width + (_width - sx)]; else return _data[sy * _width + sx]; }
void MystScriptParser::o_copyImageToBackBuffer(uint16 var, const ArgumentsArray &args) { uint16 imageId = args[0]; // WORKAROUND wrong image id in mechanical staircase if (imageId == 7158) imageId = 7178; Common::Rect srcRect = Common::Rect(args[1], args[2], args[3], args[4]); Common::Rect dstRect = Common::Rect(args[5], args[6], 544, 333); if (dstRect.left == -1) { dstRect.left = 0; } if (dstRect.top == -1) { dstRect.top = 0; } dstRect.right = dstRect.left + srcRect.width(); dstRect.bottom = dstRect.top + srcRect.height(); debugC(kDebugScript, "\tsrcRect.left: %d", srcRect.left); debugC(kDebugScript, "\tsrcRect.top: %d", srcRect.top); debugC(kDebugScript, "\tsrcRect.right: %d", srcRect.right); debugC(kDebugScript, "\tsrcRect.bottom: %d", srcRect.bottom); debugC(kDebugScript, "\tdstRect.left: %d", dstRect.left); debugC(kDebugScript, "\tdstRect.top: %d", dstRect.top); debugC(kDebugScript, "\tdstRect.right: %d", dstRect.right); debugC(kDebugScript, "\tdstRect.bottom: %d", dstRect.bottom); _vm->_gfx->copyImageSectionToBackBuffer(imageId, srcRect, dstRect); // WORKAROUND: When hitting the switch of the torture chamber in Achenar's // hidden room on the Mechanical Age, the game calls this opcode multiple // times in a row with different images without waiting in between. // As a result the images are not shown since the screen is only // updated once per frame. The original engine misbehaves as well. // Here we artificially introduce a delay after each image to allow // them to be visible for a few frames. if (_vm->getCard()->getId() == 6009) { _vm->wait(100); } }
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 GfxPicture::drawSci32Vga(int16 celNo, int16 drawX, int16 drawY, int16 pictureX, bool mirrored) { byte *inbuffer = _resource->data; int size = _resource->size; int header_size = READ_SCI11ENDIAN_UINT16(inbuffer); int palette_data_ptr = READ_SCI11ENDIAN_UINT32(inbuffer + 6); // int celCount = inbuffer[2]; int cel_headerPos = header_size; int cel_RlePos, cel_LiteralPos; Palette palette; // HACK _mirroredFlag = mirrored; _addToFlag = false; _resourceType = SCI_PICTURE_TYPE_SCI32; if (celNo == 0) { // Create palette and set it _palette->createFromData(inbuffer + palette_data_ptr, size - palette_data_ptr, &palette); _palette->set(&palette, true); } // Header // [headerSize:WORD] [celCount:BYTE] [Unknown:BYTE] [Unknown:WORD] [paletteOffset:DWORD] [Unknown:DWORD] // cel-header follow afterwards, each is 42 bytes // Cel-Header // [width:WORD] [height:WORD] [displaceX:WORD] [displaceY:WORD] [clearColor:BYTE] [compressed:BYTE] // offset 10-23 is unknown // [rleOffset:DWORD] [literalOffset:DWORD] [Unknown:WORD] [Unknown:WORD] [priority:WORD] [relativeXpos:WORD] [relativeYpos:WORD] cel_headerPos += 42 * celNo; if (mirrored) { // switch around relativeXpos Common::Rect displayArea = _coordAdjuster->pictureGetDisplayArea(); drawX = displayArea.width() - drawX - READ_SCI11ENDIAN_UINT16(inbuffer + cel_headerPos + 0); } cel_RlePos = READ_SCI11ENDIAN_UINT32(inbuffer + cel_headerPos + 24); cel_LiteralPos = READ_SCI11ENDIAN_UINT32(inbuffer + cel_headerPos + 28); drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, drawX, drawY, pictureX); cel_headerPos += 42; }
void ThemeEngine::drawSlider(const Common::Rect &r, int width, WidgetStateInfo state) { if (!ready()) return; DrawData dd = kDDSliderFull; if (state == kStateHighlight) dd = kDDSliderHover; else if (state == kStateDisabled) dd = kDDSliderDisabled; Common::Rect r2 = r; r2.setWidth(MIN((int16)width, r.width())); // r2.top++; r2.bottom--; r2.left++; r2.right--; drawWidgetBackground(r, 0, kWidgetBackgroundSlider, kStateEnabled); queueDD(dd, r2); }