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 Debugger::Cmd_GfxObjects(int argc, const char **argv) { const char *objType[] = { "DOOR", "GET", "ANIM" }; DebugPrintf("+--------------------+-----+-----+-----+-----+-----+-------+-----+--------+\n" "| name | x | y | w | h | z | layer | f | type |\n" "+--------------------+-----+-----+-----+-----+-----+-------+-----+--------+\n"); GfxObjArray::iterator b = _vm->_gfx->_sceneObjects.begin(); GfxObjArray::iterator e = _vm->_gfx->_sceneObjects.end(); Common::Rect r; for ( ; b != e; ++b) { GfxObj *obj = *b; obj->getRect(obj->frame, r); DebugPrintf("|%-20s|%5i|%5i|%5i|%5i|%5i|%7i|%5i|%8s|\n", obj->getName(), r.left, r.top, r.width(), r.height(), obj->z, obj->layer, obj->frame, objType[obj->type]); } DebugPrintf("+--------------------+-----+-----+-----+-----+-----+-------+-----+--------+\n"); return true; }
void RivenGraphics::updateScreen(Common::Rect updateRect) { if (_updatesEnabled) { _vm->runUpdateScreenScript(); if (_dirtyScreen) { _activatedPLSTs.clear(); // Copy to screen if there's no transition. Otherwise transition. ;) if (_scheduledTransition < 0) _vm->_system->copyRectToScreen(_mainScreen->getBasePtr(updateRect.left, updateRect.top), _mainScreen->pitch, updateRect.left, updateRect.top, updateRect.width(), updateRect.height()); else runScheduledTransition(); // Finally, update the screen. _vm->_system->updateScreen(); _dirtyScreen = false; } } }
void GfxScreen::copyRectToScreen(const Common::Rect &rect, int16 x, int16 y) { if (!_upscaledHires) { g_system->copyRectToScreen(_activeScreen + rect.top * _displayWidth + rect.left, _displayWidth, x, y, rect.width(), rect.height()); } else { int rectHeight = _upscaledMapping[rect.bottom] - _upscaledMapping[rect.top]; g_system->copyRectToScreen(_activeScreen + _upscaledMapping[rect.top] * _displayWidth + rect.left * 2, _displayWidth, x * 2, _upscaledMapping[y], rect.width() * 2, rectHeight); } }
void Menu::renderSubmenu(MenuItem *menu) { Common::Rect *r = &menu->subbbox; if (r->width() == 0 || r->height() == 0) return; Design::drawFilledRect(&_gui->_screen, *r, kColorWhite, _gui->_patterns, kPatternSolid); Design::drawRect(&_gui->_screen, *r, 1, kColorBlack, _gui->_patterns, kPatternSolid); Design::drawVLine(&_gui->_screen, r->right + 1, r->top + 3, r->bottom + 1, 1, kColorBlack, _gui->_patterns, kPatternSolid); Design::drawHLine(&_gui->_screen, r->left + 3, r->right + 1, r->bottom + 1, 1, kColorBlack, _gui->_patterns, kPatternSolid); int x = r->left + kMenuDropdownPadding; int y = r->top + 1; for (uint i = 0; i < menu->subitems.size(); i++) { Common::String text(menu->subitems[i]->text); Common::String acceleratorText(getAcceleratorString(menu->subitems[i], "")); int accelX = r->right - 25; int color = kColorBlack; if (i == (uint)_activeSubItem && !text.empty() && menu->subitems[i]->enabled) { color = kColorWhite; Common::Rect trect(r->left, y - (_gui->_builtInFonts ? 1 : 0), r->right, y + _font->getFontHeight()); Design::drawFilledRect(&_gui->_screen, trect, kColorBlack, _gui->_patterns, kPatternSolid); } if (!text.empty()) { Graphics::ManagedSurface *s = &_gui->_screen; int tx = x, ty = y; if (!menu->subitems[i]->enabled) { s = &_tempSurface; tx = 0; ty = 0; accelX -= x; _tempSurface.clear(kColorGreen); } _font->drawString(s, text, tx, ty, r->width(), color); if (!acceleratorText.empty()) _font->drawString(s, acceleratorText, accelX, ty, r->width(), color); if (!menu->subitems[i]->enabled) { // I am lazy to extend drawString() with plotProc as a parameter, so // fake it here for (int ii = 0; ii < _tempSurface.h; ii++) { const byte *src = (const byte *)_tempSurface.getBasePtr(0, ii); byte *dst = (byte *)_gui->_screen.getBasePtr(x, y+ii); byte pat = _gui->_patterns[kPatternCheckers2 - 1][ii % 8]; for (int j = 0; j < r->width(); j++) { if (*src != kColorGreen && (pat & (1 << (7 - (x + j) % 8)))) *dst = *src; src++; dst++; } } } } else { // Delimiter Design::drawHLine(&_gui->_screen, r->left + 1, r->right - 1, y + kMenuDropdownItemHeight / 2, 1, kColorBlack, _gui->_patterns, kPatternStripes); } y += kMenuDropdownItemHeight; } g_system->copyRectToScreen(_gui->_screen.getBasePtr(r->left, r->top), _gui->_screen.pitch, r->left, r->top, r->width() + 3, r->height() + 3); }
bool VideoManager::drawNextFrame(VideoEntryPtr videoEntry) { Video::VideoDecoder *video = videoEntry->_video; const Graphics::Surface *frame = video->decodeNextFrame(); if (!frame || !videoEntry->isEnabled()) { return false; } Graphics::Surface *convertedFrame = nullptr; Graphics::PixelFormat pixelFormat = _vm->_system->getScreenFormat(); if (frame->format != pixelFormat) { // We don't support downconverting to 8bpp without having // support in the codec. Set _enableDither if shows up. if (pixelFormat.bytesPerPixel == 1) { warning("Cannot convert high color video frame to 8bpp"); return false; } // Convert to the current screen format convertedFrame = frame->convertTo(pixelFormat, video->getPalette()); frame = convertedFrame; } else if (pixelFormat.bytesPerPixel == 1 && video->hasDirtyPalette()) { // Set the palette when running in 8bpp mode only // Don't do this for Myst, which has its own per-stack handling if (_vm->getGameType() != GType_MYST) _vm->_system->getPaletteManager()->setPalette(video->getPalette(), 0, 256); } // Clip the video to make sure it stays on the screen (Myst does this a few times) Common::Rect targetRect = Common::Rect(video->getWidth(), video->getHeight()); targetRect.translate(videoEntry->getX(), videoEntry->getY()); Common::Rect frameRect = Common::Rect(video->getWidth(), video->getHeight()); if (targetRect.left < 0) { frameRect.left -= targetRect.left; targetRect.left = 0; } if (targetRect.top < 0) { frameRect.top -= targetRect.top; targetRect.top = 0; } if (targetRect.right > _vm->_system->getWidth()) { frameRect.right -= targetRect.right - _vm->_system->getWidth(); targetRect.right = _vm->_system->getWidth(); } if (targetRect.bottom > _vm->_system->getHeight()) { frameRect.bottom -= targetRect.bottom - _vm->_system->getHeight(); targetRect.bottom = _vm->_system->getHeight(); } _vm->_system->copyRectToScreen(frame->getBasePtr(frameRect.left, frameRect.top), frame->pitch, targetRect.left, targetRect.top, targetRect.width(), targetRect.height()); // Delete 8bpp conversion surface if (convertedFrame) { convertedFrame->free(); delete convertedFrame; } // We've drawn something to the screen, make sure we update it return true; }
void Screen::setDisplayBounds(const Common::Rect &r) { _sceneSurface.setPixels(_backBuffer1.getBasePtr(r.left, r.top), r.width(), r.height(), _backBuffer1.getPixelFormat()); _backBuffer = &_sceneSurface; }
void ShaderRenderer::draw2DText(const Common::String &text, const Common::Point &position) { OpenGLTexture *glFont = static_cast<OpenGLTexture *>(_font); // The font only has uppercase letters Common::String textToDraw = text; textToDraw.toUppercase(); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); if (_prevText != textToDraw || _prevTextPosition != position) { _prevText = textToDraw; _prevTextPosition = position; float x = position.x / _currentViewport.getWidth(); float y = position.y / _currentViewport.getHeight(); float *bufData = new float[16 * textToDraw.size()]; float *cur = bufData; for (uint i = 0; i < textToDraw.size(); i++) { Common::Rect textureRect = getFontCharacterRect(textToDraw[i]); float w = textureRect.width() / _currentViewport.getWidth(); float h = textureRect.height() / _currentViewport.getHeight(); float cw = textureRect.width() / (float)glFont->internalWidth; float ch = textureRect.height() / (float)glFont->internalHeight; float cx = textureRect.left / (float)glFont->internalWidth; float cy = textureRect.top / (float)glFont->internalHeight; const float charData[] = { cx, cy + ch, x, y, cx + cw, cy + ch, x + w, y, cx + cw, cy, x + w, y + h, cx, cy, x, y + h, }; memcpy(cur, charData, 16 * sizeof(float)); cur += 16; x += (textureRect.width() - 3) / _currentViewport.getWidth(); } glBindBuffer(GL_ARRAY_BUFFER, _textVBO); glBufferSubData(GL_ARRAY_BUFFER, 0, textToDraw.size() * 16 * sizeof(float), bufData); delete[] bufData; } _textShader->use(); glBindTexture(GL_TEXTURE_2D, glFont->id); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _quadEBO); glDrawElements(GL_TRIANGLES, 6 * textToDraw.size(), GL_UNSIGNED_SHORT, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); }
View::View(M4Engine *vm, const Common::Rect &viewBounds, bool transparent): _hotkeys(HotkeyList(this)), M4Surface(viewBounds.width(), viewBounds.height()), _vm(vm) { SCREEN_FLAGS_DEFAULT; _coords = viewBounds; _transparent = transparent; }
void Screen::addDirtyRect(const Common::Rect &r) { _dirtyRects.push_back(r); assert(r.width() > 0 && r.height() > 0); }
void Gfx::bltMaskScale(const Common::Rect& r, byte *data, Graphics::Surface *surf, uint16 z, uint scale, byte transparentColor) { if (scale == 100) { // use optimized path bltMaskNoScale(r, data, surf, z, transparentColor); return; } // unscaled rectangle size uint width = r.width(); uint height = r.height(); // scaled rectangle size uint scaledWidth = r.width() * scale / 100; uint scaledHeight = r.height() * scale / 100; // scaled rectangle origin uint scaledLeft = r.left + (width - scaledWidth) / 2; uint scaledTop = r.top + (height - scaledHeight); // clipped scaled destination rectangle Common::Rect dstRect(scaledWidth, scaledHeight); dstRect.moveTo(scaledLeft, scaledTop); Common::Rect clipper(surf->w, surf->h); dstRect.clip(clipper); if (!dstRect.isValidRect()) return; // clipped source rectangle Common::Rect srcRect; srcRect.left = (dstRect.left - scaledLeft) * 100 / scale; srcRect.top = (dstRect.top - scaledTop) * 100 / scale; srcRect.setWidth(dstRect.width() * 100 / scale); srcRect.setHeight(dstRect.height() * 100 / scale); if (!srcRect.isValidRect()) return; Common::Point dp; dp.x = dstRect.left; dp.y = dstRect.top; byte *s = data + srcRect.left + srcRect.top * width; byte *d = (byte*)surf->getBasePtr(dp.x, dp.y); uint line = 0, col = 0; uint xAccum = 0, yAccum = 0; uint inc = width * (100 - scale); uint thr = width * 100; for (uint16 i = 0; i < srcRect.height(); i++) { yAccum += inc; if (yAccum >= thr) { yAccum -= thr; s += width; continue; } xAccum = 0; byte *d2 = d; col = 0; for (uint16 j = 0; j < srcRect.width(); j++) { xAccum += inc; if (xAccum >= thr) { xAccum -= thr; s++; continue; } if (*s != transparentColor) { if (_backgroundInfo->hasMask()) { byte v = _backgroundInfo->_mask->getValue(dp.x + col, dp.y + line); if (z >= v) *d2 = *s; } else { *d2 = *s; } } s++; d2++; col++; } s += width - srcRect.width(); d += surf->w; line++; } }
void GfxScreen::copyRectToScreen(const Common::Rect &rect) { if (!_upscaledHires) { g_system->copyRectToScreen(_activeScreen + rect.top * _displayWidth + rect.left, _displayWidth, rect.left, rect.top, rect.width(), rect.height()); } else { int rectHeight = _upscaledHeightMapping[rect.bottom] - _upscaledHeightMapping[rect.top]; int rectWidth = _upscaledWidthMapping[rect.right] - _upscaledWidthMapping[rect.left]; g_system->copyRectToScreen(_activeScreen + _upscaledHeightMapping[rect.top] * _displayWidth + _upscaledWidthMapping[rect.left], _displayWidth, _upscaledWidthMapping[rect.left], _upscaledHeightMapping[rect.top], rectWidth, rectHeight); } }
void Animation::getFoot(Common::Point &foot) { Common::Rect rect; gfxobj->getRect(_frame, rect); foot.x = getX() + (rect.left + rect.width() / 2); foot.y = getY() + (rect.top + rect.height()); }
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; }
void Screen::restoreBackground(const Common::Rect &r) { if (r.width() > 0 && r.height() > 0) _backBuffer.SHblitFrom(_backBuffer2, Common::Point(r.left, r.top), r); }
void ShaderRenderer::setupCameraPerspective(float pitch, float heading, float fov) { Renderer::setupCameraPerspective(pitch, heading, fov); Common::Rect frame = frameViewport(); glViewport(frame.left, frame.top, frame.width(), frame.height()); }
void Screen::setDisplayBounds(const Common::Rect &r) { _backBuffer.create(_backBuffer1, r); assert(_backBuffer.width() == r.width()); assert(_backBuffer.height() == r.height()); }
// Replacement for SDL2's SDL_RenderCopy void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface) const { TransparentSurface src(*getSurface(), false); Common::Rect clipRect; clipRect.setWidth(getSurface()->w); clipRect.setHeight(getSurface()->h); if (_owner) { if (_transform._alphaDisable) { src._alphaMode = TransparentSurface::ALPHA_OPAQUE; } else { src._alphaMode = _owner->getAlphaType(); } } src.blit(*_targetSurface, _dstRect.left, _dstRect.top, _transform._flip, &clipRect, _transform._rgbaMod, clipRect.width(), clipRect.height()); }
reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxHeight) { reg_t stringObject = readSelector(_segMan, textObject, SELECTOR(text)); // The object in the text selector of the item can be either a raw string // or a Str object. In the latter case, we need to access the object's data // selector to get the raw string. if (_segMan->isHeapObject(stringObject)) stringObject = readSelector(_segMan, stringObject, SELECTOR(data)); Common::String text = _segMan->getString(stringObject); // HACK: The character offsets of the up and down arrow buttons are off by one // in GK1, for some unknown reason. Fix them here. if (text.size() == 1 && (text[0] == 29 || text[0] == 30)) { text.setChar(text[0] + 1, 0); } GuiResourceId fontId = readSelectorValue(_segMan, textObject, SELECTOR(font)); GfxFont *font = _cache->getFont(fontId); bool dimmed = readSelectorValue(_segMan, textObject, SELECTOR(dimmed)); int16 alignment = readSelectorValue(_segMan, textObject, SELECTOR(mode)); uint16 foreColor = readSelectorValue(_segMan, textObject, SELECTOR(fore)); uint16 backColor = readSelectorValue(_segMan, textObject, SELECTOR(back)); Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(textObject); uint16 width = nsRect.width() + 1; uint16 height = nsRect.height() + 1; // Limit rectangle dimensions, if requested if (maxWidth > 0) width = maxWidth; if (maxHeight > 0) height = maxHeight; // Upscale the coordinates/width if the fonts are already upscaled if (_screen->fontIsUpscaled()) { width = width * _screen->getDisplayWidth() / _screen->getWidth(); height = height * _screen->getDisplayHeight() / _screen->getHeight(); } int entrySize = width * height + BITMAP_HEADER_SIZE; reg_t memoryId = _segMan->allocateHunkEntry("TextBitmap()", entrySize); writeSelector(_segMan, textObject, SELECTOR(bitmap), memoryId); byte *memoryPtr = _segMan->getHunkPointer(memoryId); memset(memoryPtr, backColor, entrySize); byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE; // Save totalWidth, totalHeight WRITE_LE_UINT16(memoryPtr, width); WRITE_LE_UINT16(memoryPtr + 2, height); int16 charCount = 0; uint16 curX = 0, curY = 0; const char *txt = text.c_str(); int16 textWidth, textHeight, totalHeight = 0, offsetX = 0, offsetY = 0; uint16 start = 0; // Calculate total text height while (*txt) { charCount = GetLongest(txt, width, font); if (charCount == 0) break; Width(txt, 0, (int16)strlen(txt), fontId, textWidth, textHeight, true); totalHeight += textHeight; txt += charCount; while (*txt == ' ') txt++; // skip over breaking spaces } txt = text.c_str(); // Draw text in buffer while (*txt) { charCount = GetLongest(txt, width, font); if (charCount == 0) break; Width(txt, start, charCount, fontId, textWidth, textHeight, true); switch (alignment) { case SCI_TEXT32_ALIGNMENT_RIGHT: offsetX = width - textWidth; break; case SCI_TEXT32_ALIGNMENT_CENTER: // Center text both horizontally and vertically offsetX = (width - textWidth) / 2; offsetY = (height - totalHeight) / 2; break; case SCI_TEXT32_ALIGNMENT_LEFT: offsetX = 0; break; default: warning("Invalid alignment %d used in TextBox()", alignment); } for (int i = 0; i < charCount; i++) { unsigned char curChar = txt[i]; font->drawToBuffer(curChar, curY + offsetY, curX + offsetX, foreColor, dimmed, bitmap, width, height); curX += font->getCharWidth(curChar); } curX = 0; curY += font->getHeight(); txt += charCount; while (*txt == ' ') txt++; // skip over breaking spaces } return memoryId; }
void Cursor::render() { updateFadeLevel(); updateHintDelay(); if (!_gfx->isPosInScreenBounds(_mousePos)) { setCursorType(Cursor::kPassive); } if (_mouseText && _gfx->gameViewport().contains(_mousePos) && _hintDisplayDelay <= 0) { _gfx->setScreenViewport(false); // TODO: Should probably query the image for the width of the cursor // TODO: Add delay to the mouse hints like in the game const int16 cursorDistance = 32; Common::Rect mouseRect = _mouseText->getRect(); Common::Point pos = _gfx->convertCoordinateCurrentToOriginal(_mousePos); pos.x = CLIP<int16>(pos.x, 48, Gfx::Driver::kOriginalWidth - 48); pos.y = CLIP<int16>(pos.y, Gfx::Driver::kTopBorderHeight, Gfx::Driver::kOriginalHeight - Gfx::Driver::kBottomBorderHeight - cursorDistance - mouseRect.height()); pos.x -= mouseRect.width() / 2; pos.y += cursorDistance; _mouseText->render(pos); } if (_currentCursorType != kImage) { _cursorImage = StarkStaticProvider->getCursorImage(_currentCursorType); } if (_cursorImage) { _gfx->setScreenViewport(true); // Unscaled viewport so that cursor is drawn on native pixel space, thus no 'skipping', perform scaling below instead _cursorImage->setFadeLevel(_fadeLevel); _cursorImage->render(_mousePos, true, false); // Draws image (scaled) } }
/** * This copies a rect to screen w/o scaling adjustment and is only meant to be * used on hires graphics used in upscaled hires mode. */ void GfxScreen::copyDisplayRectToScreen(const Common::Rect &rect) { if (!_upscaledHires) error("copyDisplayRectToScreen: not in upscaled hires mode"); g_system->copyRectToScreen(_activeScreen + rect.top * _displayWidth + rect.left, _displayWidth, rect.left, rect.top, rect.width(), rect.height()); }
void CUP_Player::copyRectToScreen(const Common::Rect &r) { const uint8 *src = _offscreenBuffer + r.top * _width + r.left; _system->copyRectToScreen(src, _width, r.left, r.top, r.width() + 1, r.height() + 1); }
Common::Rect Surface::render(Graphics::Surface *surface, int dx, int dy, bool mirror, Common::Rect src_rect, uint zoom) const { if (src_rect.isEmpty()) { src_rect = Common::Rect(0, 0, w, h); } Common::Rect dst_rect(x + dx, y + dy, x + dx + zoom * src_rect.width() / 256, y + dy + zoom * src_rect.height() / 256); if (dst_rect.left < 0) { src_rect.left = -dst_rect.left; dst_rect.left = 0; } if (dst_rect.right > surface->w) { src_rect.right -= dst_rect.right - surface->w; dst_rect.right = surface->w; } if (dst_rect.top < 0) { src_rect.top -= dst_rect.top; dst_rect.top = 0; } if (dst_rect.bottom > surface->h) { src_rect.bottom -= dst_rect.bottom - surface->h; dst_rect.bottom = surface->h; } if (src_rect.isEmpty() || dst_rect.isEmpty()) return Common::Rect(); if (zoom == 256) { const byte *src = (const byte *)getBasePtr(0, src_rect.top); byte *dst_base = (byte *)surface->getBasePtr(dst_rect.left, dst_rect.top); for (int i = src_rect.top; i < src_rect.bottom; ++i) { byte *dst = dst_base; for (int j = src_rect.left; j < src_rect.right; ++j) { byte p = src[(mirror? w - j - 1: j)]; if (p != 0xff) *dst++ = p; else ++dst; } dst_base += surface->pitch; src += pitch; } } else { byte *dst = (byte *)surface->getBasePtr(dst_rect.left, dst_rect.top); for(int i = 0; i < dst_rect.height(); ++i) { for (int j = 0; j < dst_rect.width(); ++j) { int px = j * 256 / zoom; const byte *src = (const byte *)getBasePtr(src_rect.left + (mirror? w - px - 1: px), src_rect.top + i * 256 / zoom); byte p = *src; if (p != 0xff) dst[j] = p; } dst += surface->pitch; } } return dst_rect; }