bool BaseRenderOSystem::flip() { if (_renderQueue.size() > DIRTY_RECT_LIMIT) { _tempDisableDirtyRects++; } if (_skipThisFrame) { _skipThisFrame = false; delete _dirtyRect; _dirtyRect = nullptr; g_system->updateScreen(); _needsFlip = false; _drawNum = 1; addDirtyRect(_renderRect); return true; } if (!_tempDisableDirtyRects && !_disableDirtyRects) { drawTickets(); } else { // Clear the scale-buffered tickets that wasn't reused. RenderQueueIterator it = _renderQueue.begin(); while (it != _renderQueue.end()) { if ((*it)->_wantsDraw == false) { RenderTicket *ticket = *it; it = _renderQueue.erase(it); delete ticket; } else { (*it)->_wantsDraw = false; ++it; } } } if (_needsFlip || _disableDirtyRects || _tempDisableDirtyRects) { if (_disableDirtyRects || _tempDisableDirtyRects) { g_system->copyRectToScreen((byte *)_renderSurface->getPixels(), _renderSurface->pitch, 0, 0, _renderSurface->w, _renderSurface->h); } // g_system->copyRectToScreen((byte *)_renderSurface->getPixels(), _renderSurface->pitch, _dirtyRect->left, _dirtyRect->top, _dirtyRect->width(), _dirtyRect->height()); delete _dirtyRect; _dirtyRect = nullptr; g_system->updateScreen(); _needsFlip = false; } _drawNum = 1; if (_tempDisableDirtyRects && !_disableDirtyRects) { _tempDisableDirtyRects--; if (!_tempDisableDirtyRects) { Common::Rect screen(_screenRect.top, _screenRect.left, _screenRect.bottom, _screenRect.right); addDirtyRect(screen); // The queue has been ignored but updated, and is guaranteed to be in draw-order when run without dirty-rects. RenderQueueIterator it = _renderQueue.begin(); int drawNum = 1; while (it != _renderQueue.end()) { (*it)->_drawNum = drawNum++; ++it; } } } return STATUS_OK; }
void WINCESdlGraphicsManager::swap_panel_visibility() { //if (!_forcePanelInvisible && !_panelStateForced) { if (_zoomDown || _zoomUp) return; if (_panelVisible) { if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD) _panelVisible = !_panelVisible; else _toolbarHandler.setActive(NAME_PANEL_KEYBOARD); } else { _toolbarHandler.setActive(NAME_MAIN_PANEL); _panelVisible = !_panelVisible; } _toolbarHandler.setVisible(_panelVisible); _toolbarHighDrawn = false; if (_videoMode.screenHeight > 240) addDirtyRect(0, 400, 640, 80); else addDirtyRect(0, 200, 320, 40); if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD && _panelVisible) internUpdateScreen(); else { update_scalers(); hotswapGFXMode(); } //} }
void BaseRenderOSystem::drawFromTicket(RenderTicket *renderTicket) { renderTicket->_wantsDraw = true; // A new item always has _drawNum == 0 if (renderTicket->_drawNum == 0) { // In-order if (_renderQueue.empty() || _drawNum > (_renderQueue.back())->_drawNum) { renderTicket->_drawNum = _drawNum++; _renderQueue.push_back(renderTicket); addDirtyRect(renderTicket->_dstRect); ++_lastAddedTicket; } else { // Before something RenderQueueIterator pos; for (pos = _renderQueue.begin(); pos != _renderQueue.end(); pos++) { if ((*pos)->_drawNum >= _drawNum) { break; } } _renderQueue.insert(pos, renderTicket); renderTicket->_drawNum = _drawNum++; // Increment the following tickets, so they still are in line RenderQueueIterator it; for (it = pos; it != _renderQueue.end(); ++it) { (*it)->_drawNum++; (*it)->_wantsDraw = false; } addDirtyRect(renderTicket->_dstRect); _lastAddedTicket = pos; } } else { // Was drawn last round, still in the same order if (_drawNum == renderTicket->_drawNum) { _drawNum++; ++_lastAddedTicket; } else { // Remove the ticket from the list RenderQueueIterator it = _renderQueue.begin(); while (it != _renderQueue.end()) { if ((*it) == renderTicket) { it = _renderQueue.erase(it); break; } else { ++it; } } if (it != _renderQueue.end()) { // Decreement the following tickets. for (; it != _renderQueue.end(); ++it) { (*it)->_drawNum--; } } // Is not in order, so readd it as if it was a new ticket renderTicket->_drawNum = 0; drawFromTicket(renderTicket); } } }
void WINCESdlGraphicsManager::swap_smartphone_keyboard() { _toolbarHandler.setActive(NAME_PANEL_KEYBOARD); _panelVisible = !_panelVisible; _toolbarHandler.setVisible(_panelVisible); if (_videoMode.screenHeight > 240) addDirtyRect(0, 0, 640, 80); else addDirtyRect(0, 0, 320, 40); internUpdateScreen(); }
void Scalpel3DOScreen::blitFrom3DOcolorLimit(uint16 limitColor) { uint16 *currentScreenPtr = (uint16 *)getPixels(); uint16 *targetScreenPtr = (uint16 *)_backBuffer.getPixels(); uint16 currentScreenPixel = 0; uint16 screenWidth = SHERLOCK_SCREEN_WIDTH; uint16 screenHeight = SHERLOCK_SCREEN_HEIGHT; uint16 screenX = 0; uint16 screenY = 0; uint16 currentScreenPixelRed = 0; uint16 currentScreenPixelGreen = 0; uint16 currentScreenPixelBlue = 0; uint16 limitPixelRed = limitColor & 0xF800; uint16 limitPixelGreen = limitColor & 0x07E0; uint16 limitPixelBlue = limitColor & 0x001F; for (screenY = 0; screenY < screenHeight; screenY++) { for (screenX = 0; screenX < screenWidth; screenX++) { currentScreenPixel = *targetScreenPtr; currentScreenPixelRed = currentScreenPixel & 0xF800; currentScreenPixelGreen = currentScreenPixel & 0x07E0; currentScreenPixelBlue = currentScreenPixel & 0x001F; if (currentScreenPixelRed < limitPixelRed) currentScreenPixelRed = limitPixelRed; if (currentScreenPixelGreen < limitPixelGreen) currentScreenPixelGreen = limitPixelGreen; if (currentScreenPixelBlue < limitPixelBlue) currentScreenPixelBlue = limitPixelBlue; uint16 v = currentScreenPixelRed | currentScreenPixelGreen | currentScreenPixelBlue; *currentScreenPtr = v; if (_vm->_isScreenDoubled) { *(currentScreenPtr + 1) = v; *(currentScreenPtr + 640) = v; *(currentScreenPtr + 640 + 1) = v; } currentScreenPtr += _vm->_isScreenDoubled ? 2 : 1; targetScreenPtr++; } if (_vm->_isScreenDoubled) currentScreenPtr += 640; } // Too much considered dirty at the moment if (_vm->_isScreenDoubled) addDirtyRect(Common::Rect(0, 0, screenWidth * 2, screenHeight * 2)); else addDirtyRect(Common::Rect(0, 0, screenWidth, screenHeight)); }
void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &pt, bool flipped, int overrideColor, int scaleVal) { if (scaleVal == SCALE_THRESHOLD) { transBlitFromUnscaled(src, pt, flipped, overrideColor); return; } int destWidth = src.w * SCALE_THRESHOLD / scaleVal; int destHeight = src.h * SCALE_THRESHOLD / scaleVal; // Loop through drawing output lines for (int destY = pt.y, scaleYCtr = 0; destY < (pt.y + destHeight); ++destY, scaleYCtr += scaleVal) { if (destY < 0 || destY >= this->h()) continue; const byte *srcLine = (const byte *)src.getBasePtr(0, scaleYCtr / SCALE_THRESHOLD); byte *destLine = (byte *)getBasePtr(pt.x, destY); // Loop through drawing individual rows for (int xCtr = 0, scaleXCtr = 0; xCtr < destWidth; ++xCtr, scaleXCtr += scaleVal) { int destX = pt.x + xCtr; if (destX < 0 || destX >= this->w()) continue; byte srcVal = srcLine[flipped ? src.w - scaleXCtr / SCALE_THRESHOLD - 1 : scaleXCtr / SCALE_THRESHOLD]; if (srcVal != TRANSPARENCY) destLine[xCtr] = srcVal; } } // Mark the affected area addDirtyRect(Common::Rect(pt.x, pt.y, pt.x + destWidth, pt.y + destHeight)); }
void Screen::copyBlock(BaseSurface *src, const Common::Rect &bounds) { Common::Rect destBounds = bounds; destBounds.translate(_windowXAdd, _windowYAdd + _screenYOff); copyRectToSurface(*src, destBounds.left, destBounds.top, bounds); addDirtyRect(destBounds); }
void FontSurface::writeChar(char c, const Common::Rect &clipRect) { // Get y position, handling kerning int y = _writePos.y; if (c == 'g' || c == 'p' || c == 'q' || c == 'y') ++y; int yStart = y; // Get pointers into font data and surface to write pixels to int charIndex = (int)c + (_fontReduced ? 0x80 : 0); const byte *srcP = &_fontData[charIndex * 16]; for (int yp = 0; yp < FONT_HEIGHT; ++yp, ++y) { uint16 lineData = READ_LE_UINT16(srcP); srcP += 2; byte *destP = (byte *)getBasePtr(_writePos.x, y); // Ignore line if it's outside the clipping rect if (y < clipRect.top || y >= clipRect.bottom) continue; const byte *lineStart = (const byte *)getBasePtr(clipRect.left, y); const byte *lineEnd = (const byte *)getBasePtr(clipRect.right, y); for (int xp = 0; xp < FONT_WIDTH; ++xp, ++destP) { int colIndex = lineData & 3; lineData >>= 2; if (colIndex && destP >= lineStart && destP < lineEnd) *destP = _textColors[colIndex]; } } addDirtyRect(Common::Rect(_writePos.x, yStart, _writePos.x + FONT_WIDTH, yStart + FONT_HEIGHT)); _writePos.x += _fontData[0x1000 + charIndex]; }
void WINCESdlGraphicsManager::swap_zoom_down() { if (_zoomDown) { // restore visibility _toolbarHandler.setVisible(_saveToolbarZoom); // restore scaler _scaleFactorYd = 2; _scalerProc = DownscaleAllByHalf; _zoomDown = false; _zoomUp = false; } else { // only active if running on a PocketPC if (_scalerProc != DownscaleAllByHalf && _scalerProc != DownscaleHorizByHalf) return; if (_scalerProc == DownscaleAllByHalf) { _saveToolbarZoom = _toolbarHandler.visible(); _toolbarHandler.setVisible(false); // set zoom scaler _scaleFactorYd = 1; _scalerProc = DownscaleHorizByHalf; } _zoomUp = false; _zoomDown = true; } // redraw whole screen addDirtyRect(0, 0, 640, 480); internUpdateScreen(); }
void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &pt, bool flipped, int overrideColor) { Common::Rect drawRect(0, 0, src.w, src.h); Common::Rect destRect(pt.x, pt.y, pt.x + src.w, pt.y + src.h); // Clip the display area to on-screen if (!clip(drawRect, destRect)) // It's completely off-screen return; if (flipped) drawRect = Common::Rect(src.w - drawRect.right, src.h - drawRect.bottom, src.w - drawRect.left, src.h - drawRect.top); Common::Point destPt(destRect.left, destRect.top); addDirtyRect(Common::Rect(destPt.x, destPt.y, destPt.x + drawRect.width(), destPt.y + drawRect.height())); // Draw loop const int TRANSPARENCY = 0xFF; for (int yp = 0; yp < drawRect.height(); ++yp) { const byte *srcP = (const byte *)src.getBasePtr( flipped ? drawRect.right - 1 : drawRect.left, drawRect.top + yp); byte *destP = (byte *)getBasePtr(destPt.x, destPt.y + yp); for (int xp = 0; xp < drawRect.width(); ++xp, ++destP) { if (*srcP != TRANSPARENCY) *destP = overrideColor ? overrideColor : *srcP; srcP = flipped ? srcP - 1 : srcP + 1; } } }
void Scalpel3DOScreen::rawBlitFrom(const Graphics::Surface &src, const Common::Point &pt) { Common::Rect srcRect(0, 0, src.w, src.h); Common::Rect destRect(pt.x, pt.y, pt.x + src.w, pt.y + src.h); addDirtyRect(destRect); copyRectToSurface(src, destRect.left, destRect.top, srcRect); }
void Screen::randomTransition() { Events &events = *_vm->_events; const int TRANSITION_MULTIPLIER = 0x15a4e35; clearDirtyRects(); assert(IS_SERRATED_SCALPEL); for (int idx = 0; idx <= 65535 && !_vm->shouldQuit(); ++idx) { _transitionSeed = _transitionSeed * TRANSITION_MULTIPLIER + 1; int offset = _transitionSeed & 0xFFFF; if (offset < (this->width() * this->height())) *((byte *)getPixels() + offset) = *((const byte *)_backBuffer.getPixels() + offset); if (idx != 0 && (idx % 300) == 0) { // Ensure there's a full screen dirty rect for the next frame update if (!isDirty()) addDirtyRect(Common::Rect(0, 0, this->w, this->h)); events.pollEvents(); events.delay(1); } } // Make sure everything has been transferred SHblitFrom(_backBuffer); }
void Scalpel3DOScreen::SHblitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds) { if (!_vm->_isScreenDoubled) { ScalpelScreen::SHblitFrom(src, pt, srcBounds); return; } Common::Rect srcRect = srcBounds; Common::Rect destRect(pt.x, pt.y, pt.x + srcRect.width(), pt.y + srcRect.height()); if (!srcRect.isValidRect() || !clip(srcRect, destRect)) return; // Add dirty area remapped to the 640x200 surface addDirtyRect(Common::Rect(destRect.left * 2, destRect.top * 2, destRect.right * 2, destRect.bottom * 2)); // Transfer the area, doubling each pixel for (int yp = 0; yp < srcRect.height(); ++yp) { const uint16 *srcP = (const uint16 *)src.getBasePtr(srcRect.left, srcRect.top + yp); uint16 *destP = (uint16 *)getBasePtr(destRect.left * 2, (destRect.top + yp) * 2); for (int xp = srcRect.left; xp < srcRect.right; ++xp, ++srcP, destP += 2) { *destP = *srcP; *(destP + 1) = *srcP; *(destP + 640) = *srcP; *(destP + 640 + 1) = *srcP; } } }
void DINGUXSdlGraphicsManager::undrawMouse() { const int x = _mouseBackup.x; const int y = _mouseBackup.y; // When we switch bigger overlay off mouse jumps. Argh! // This is intended to prevent undrawing offscreen mouse if (!_overlayVisible && (x >= _videoMode.screenWidth || y >= _videoMode.screenHeight)) return; if (_mouseBackup.w != 0 && _mouseBackup.h != 0) { if (_videoMode.mode == GFX_HALF && !_overlayVisible) { addDirtyRect(x*2, y*2, _mouseBackup.w*2, _mouseBackup.h*2); } else { addDirtyRect(x, y, _mouseBackup.w, _mouseBackup.h); } } }
void WINCESdlGraphicsManager::undrawMouse() { assert(_transactionMode == kTransactionNone); if (_mouseNeedsRedraw) return; int old_mouse_x = _mouseCurState.x - _mouseHotspotX; int old_mouse_y = _mouseCurState.y - _mouseHotspotY; int old_mouse_w = _mouseCurState.w; int old_mouse_h = _mouseCurState.h; // clip the mouse rect, and adjust the src pointer accordingly if (old_mouse_x < 0) { old_mouse_w += old_mouse_x; old_mouse_x = 0; } if (old_mouse_y < 0) { old_mouse_h += old_mouse_y; old_mouse_y = 0; } if (old_mouse_w > _videoMode.screenWidth - old_mouse_x) old_mouse_w = _videoMode.screenWidth - old_mouse_x; if (old_mouse_h > _videoMode.screenHeight - old_mouse_y) old_mouse_h = _videoMode.screenHeight - old_mouse_y; // Quick check to see if anything has to be drawn at all if (old_mouse_w <= 0 || old_mouse_h <= 0) return; if (SDL_LockSurface(_overlayVisible ? _overlayscreen : _screen) == -1) error("SDL_LockSurface failed: %s", SDL_GetError()); int y; if (!_overlayVisible) { byte *dst, *bak = _mouseBackupOld; // No need to do clipping here, since drawMouse() did that already dst = (byte *)_screen->pixels + old_mouse_y * _videoMode.screenWidth + old_mouse_x; for (y = 0; y < old_mouse_h; ++y, bak += _mouseBackupDim, dst += _videoMode.screenWidth) memcpy(dst, bak, old_mouse_w); } else { byte *dst; uint16 *bak = (uint16 *)_mouseBackupOld; // No need to do clipping here, since drawMouse() did that already dst = (byte *)_overlayscreen->pixels + (old_mouse_y + 1) * _overlayscreen->pitch + (old_mouse_x + 1) * 2; for (y = 0; y < old_mouse_h; ++y, bak += _mouseBackupDim, dst += _overlayscreen->pitch) memcpy(dst, bak, old_mouse_w << 1); } addDirtyRect(old_mouse_x, old_mouse_y, old_mouse_w, old_mouse_h); SDL_UnlockSurface(_overlayVisible ? _overlayscreen : _screen); _mouseNeedsRedraw = true; }
void BaseRenderOSystem::drawFromTicket(RenderTicket *renderTicket) { renderTicket->_wantsDraw = true; ++_lastFrameIter; // In-order if (_renderQueue.empty() || _lastFrameIter == _renderQueue.end()) { _lastFrameIter--; _renderQueue.push_back(renderTicket); ++_lastFrameIter; addDirtyRect(renderTicket->_dstRect); } else { // Before something RenderQueueIterator pos = _lastFrameIter; _renderQueue.insert(pos, renderTicket); --_lastFrameIter; addDirtyRect(renderTicket->_dstRect); } }
void WINCESdlGraphicsManager::copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) { assert(_transactionMode == kTransactionNone); assert(buf); if (_screen == NULL) return; Common::StackLock lock(_graphicsMutex); // Lock the mutex until this function ends const byte *src = (const byte *)buf; /* Clip the coordinates */ if (x < 0) { w += x; src -= x; x = 0; } if (y < 0) { h += y; src -= y * pitch; y = 0; } if (w > _videoMode.screenWidth - x) { w = _videoMode.screenWidth - x; } if (h > _videoMode.screenHeight - y) { h = _videoMode.screenHeight - y; } if (w <= 0 || h <= 0) return; addDirtyRect(x, y, w, h); undrawMouse(); // Try to lock the screen surface if (SDL_LockSurface(_screen) == -1) error("SDL_LockSurface failed: %s", SDL_GetError()); byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x; if (_videoMode.screenWidth == pitch && pitch == w) { memcpy(dst, src, h * w); } else { do { memcpy(dst, src, w); src += pitch; dst += _videoMode.screenWidth; } while (--h); } // Unlock the screen surface SDL_UnlockSurface(_screen); }
void Surface::transBlitFromUnscaled(const Graphics::Surface &src, const Common::Point &pt, bool flipped, int overrideColor) { Common::Rect drawRect(0, 0, src.w, src.h); Common::Rect destRect(pt.x, pt.y, pt.x + src.w, pt.y + src.h); // Clip the display area to on-screen if (!clip(drawRect, destRect)) // It's completely off-screen return; if (flipped) drawRect = Common::Rect(src.w - drawRect.right, src.h - drawRect.bottom, src.w - drawRect.left, src.h - drawRect.top); Common::Point destPt(destRect.left, destRect.top); addDirtyRect(Common::Rect(destPt.x, destPt.y, destPt.x + drawRect.width(), destPt.y + drawRect.height())); switch (src.format.bytesPerPixel) { case 1: // 8-bit palettized: Draw loop assert(_surface.format.bytesPerPixel == 1); // Security check for (int yp = 0; yp < drawRect.height(); ++yp) { const byte *srcP = (const byte *)src.getBasePtr( flipped ? drawRect.right - 1 : drawRect.left, drawRect.top + yp); byte *destP = (byte *)getBasePtr(destPt.x, destPt.y + yp); for (int xp = 0; xp < drawRect.width(); ++xp, ++destP) { if (*srcP != TRANSPARENCY) *destP = overrideColor ? overrideColor : *srcP; srcP = flipped ? srcP - 1 : srcP + 1; } } break; case 2: // 3DO 15-bit RGB565: Draw loop assert(_surface.format.bytesPerPixel == 2); // Security check for (int yp = 0; yp < drawRect.height(); ++yp) { const uint16 *srcP = (const uint16 *)src.getBasePtr( flipped ? drawRect.right - 1 : drawRect.left, drawRect.top + yp); uint16 *destP = (uint16 *)getBasePtr(destPt.x, destPt.y + yp); for (int xp = 0; xp < drawRect.width(); ++xp, ++destP) { if (*srcP) // RGB 0, 0, 0 -> transparent on 3DO *destP = *srcP; // overrideColor ? overrideColor : *srcP; srcP = flipped ? srcP - 1 : srcP + 1; } } break; default: error("Surface: unsupported bytesperpixel"); break; } }
void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds) { Common::Rect srcRect = srcBounds; Common::Rect destRect(pt.x, pt.y, pt.x + srcRect.width(), pt.y + srcRect.height()); if (srcRect.isValidRect() && clip(srcRect, destRect)) { // Surface is at least partially or completely on-screen addDirtyRect(destRect); _surface.copyRectToSurface(src, destRect.left, destRect.top, srcRect); } }
void ThemeEngine::drawCaret(const Common::Rect &r, bool erase, WidgetStateInfo state) { if (!ready()) return; if (erase) { restoreBackground(r); addDirtyRect(r); } else queueDD(kDDCaret, r); }
bool BaseRenderOSystem::flip() { if (_skipThisFrame) { _skipThisFrame = false; delete _dirtyRect; _dirtyRect = nullptr; g_system->updateScreen(); _needsFlip = false; // Reset ticketing state _lastFrameIter = _renderQueue.end(); RenderQueueIterator it; for (it = _renderQueue.begin(); it != _renderQueue.end(); ++it) { (*it)->_wantsDraw = false; } addDirtyRect(_renderRect); return true; } if (!_disableDirtyRects) { drawTickets(); } else { // Clear the scale-buffered tickets that wasn't reused. RenderQueueIterator it = _renderQueue.begin(); while (it != _renderQueue.end()) { if ((*it)->_wantsDraw == false) { RenderTicket *ticket = *it; it = _renderQueue.erase(it); delete ticket; } else { (*it)->_wantsDraw = false; ++it; } } } int oldScreenChangeID = _lastScreenChangeID; _lastScreenChangeID = g_system->getScreenChangeID(); bool screenChanged = _lastScreenChangeID != oldScreenChangeID; if (_needsFlip || _disableDirtyRects || screenChanged) { if (_disableDirtyRects || screenChanged) { g_system->copyRectToScreen((byte *)_renderSurface->getPixels(), _renderSurface->pitch, 0, 0, _renderSurface->w, _renderSurface->h); } // g_system->copyRectToScreen((byte *)_renderSurface->getPixels(), _renderSurface->pitch, _dirtyRect->left, _dirtyRect->top, _dirtyRect->width(), _dirtyRect->height()); delete _dirtyRect; _dirtyRect = nullptr; _needsFlip = false; } _lastFrameIter = _renderQueue.end(); g_system->updateScreen(); return STATUS_OK; }
void WINCESdlGraphicsManager::swap_panel() { _toolbarHighDrawn = false; //if (!_panelStateForced) { if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD && _panelVisible) _toolbarHandler.setActive(NAME_MAIN_PANEL); else _toolbarHandler.setActive(NAME_PANEL_KEYBOARD); if (_videoMode.screenHeight > 240) addDirtyRect(0, 400, 640, 80); else addDirtyRect(0, 200, 320, 40); _toolbarHandler.setVisible(true); if (!_panelVisible) { _panelVisible = true; update_scalers(); hotswapGFXMode(); } //} }
void ThemeEngine::openDialog(bool doBuffer, ShadingStyle style) { if (doBuffer) _buffering = true; if (style != kShadingNone) { _vectorRenderer->applyScreenShading(style); addDirtyRect(Common::Rect(0, 0, _screen.w, _screen.h)); } memcpy(_backBuffer.getBasePtr(0, 0), _screen.getBasePtr(0, 0), _screen.pitch * _screen.h); _vectorRenderer->setSurface(&_screen); }
void OSystem_SDL::undrawMouse() { const int x = _mouseBackup.x; const int y = _mouseBackup.y; // When we switch bigger overlay off mouse jumps. Argh! // This is intended to prevent undrawing offscreen mouse if (!_overlayVisible && (x >= _screenWidth || y >= _screenHeight)) { return; } if (_mouseBackup.w != 0 && _mouseBackup.h != 0) addDirtyRect(x, y, _mouseBackup.w, _mouseBackup.h); }
void ThemeEngine::drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, WidgetStateInfo state, FontColor color) { if (!ready()) return; Common::Rect charArea = r; charArea.clip(_screen.w, _screen.h); uint32 rgbColor = _overlayFormat.RGBToColor(_textColors[color]->r, _textColors[color]->g, _textColors[color]->b); restoreBackground(charArea); font->drawChar(&_screen, ch, charArea.left, charArea.top, rgbColor); addDirtyRect(charArea); }
void WINCESdlGraphicsManager::copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) { assert(_transactionMode == kTransactionNone); if (_overlayscreen == NULL) return; const byte *src = (const byte *)buf; // Clip the coordinates if (x < 0) { w += x; src -= x * 2; x = 0; } if (y < 0) { h += y; src -= y * pitch; y = 0; } if (w > _videoMode.overlayWidth - x) { w = _videoMode.overlayWidth - x; } if (h > _videoMode.overlayHeight - y) { h = _videoMode.overlayHeight - y; } if (w <= 0 || h <= 0) return; // Mark the modified region as dirty addDirtyRect(x, y, w, h); undrawMouse(); if (SDL_LockSurface(_overlayscreen) == -1) error("SDL_LockSurface failed: %s", SDL_GetError()); byte *dst = (byte *)_overlayscreen->pixels + y * _overlayscreen->pitch + x * 2; do { memcpy(dst, src, w * 2); dst += _overlayscreen->pitch; src += pitch; } while (--h); SDL_UnlockSurface(_overlayscreen); }
void Scalpel3DOScreen::transBlitFromUnscaled(const Graphics::Surface &src, const Common::Point &pt, bool flipped, int overrideColor) { error("TODO: Refactor"); #if 0 if (!_vm->_isScreenDoubled) { ScalpelScreen::transBlitFromUnscaled(src, pt, flipped, overrideColor); return; } Common::Rect drawRect(0, 0, src.w, src.h); Common::Rect destRect(pt.x, pt.y, pt.x + src.w, pt.y + src.h); // Clip the display area to on-screen if (!clip(drawRect, destRect)) // It's completely off-screen return; if (flipped) drawRect = Common::Rect(src.w - drawRect.right, src.h - drawRect.bottom, src.w - drawRect.left, src.h - drawRect.top); Common::Point destPt(destRect.left, destRect.top); addDirtyRect(Common::Rect(destPt.x * 2, destPt.y * 2, (destPt.x + drawRect.width()) * 2, (destPt.y + drawRect.height()) * 2)); assert(src.format.bytesPerPixel == 2 && _surface.format.bytesPerPixel == 2); for (int yp = 0; yp < drawRect.height(); ++yp) { const uint16 *srcP = (const uint16 *)src.getBasePtr( flipped ? drawRect.right - 1 : drawRect.left, drawRect.top + yp); uint16 *destP = (uint16 *)getBasePtr(destPt.x * 2, (destPt.y + yp) * 2); for (int xp = 0; xp < drawRect.width(); ++xp, destP += 2) { // RGB 0, 0, 0 -> transparent on 3DO if (*srcP) { *destP = *srcP; *(destP + 1) = *srcP; *(destP + 640) = *srcP; *(destP + 640 + 1) = *srcP; } srcP = flipped ? srcP - 1 : srcP + 1; } } #endif }
void OSystem_SDL::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) { assert (_transactionMode == kTransactionNone); if (_overlayscreen == NULL) return; // Clip the coordinates if (x < 0) { w += x; buf -= x; x = 0; } if (y < 0) { h += y; buf -= y * pitch; y = 0; } if (w > _overlayWidth - x) { w = _overlayWidth - x; } if (h > _overlayHeight - y) { h = _overlayHeight - y; } if (w <= 0 || h <= 0) return; // Mark the modified region as dirty _cksumValid = false; addDirtyRect(x, y, w, h); if (SDL_LockSurface(_overlayscreen) == -1) error("SDL_LockSurface failed: %s", SDL_GetError()); byte *dst = (byte *)_overlayscreen->pixels + y * _overlayscreen->pitch + x * 2; do { memcpy(dst, buf, w * 2); dst += _overlayscreen->pitch; buf += pitch; } while (--h); SDL_UnlockSurface(_overlayscreen); }
void OSystem_SDL::addDirtyRgnAuto(const byte *buf) { assert(buf); assert(((long)buf & 3) == 0); /* generate a table of the checksums */ makeChecksums(buf); if (!_cksumValid) { _forceFull = true; _cksumValid = true; } /* go through the checksum list, compare it with the previous checksums, and add all dirty rectangles to a list. try to combine small rectangles into bigger ones in a simple way */ if (!_forceFull) { int x, y, w; uint32 *ck = _dirtyChecksums; for(y = 0; y != _screenHeight / 8; y++) { for(x = 0; x != _screenWidth / 8; x++, ck++) { if (ck[0] != ck[_cksumNum]) { /* found a dirty 8x8 block, now go as far to the right as possible, and at the same time, unmark the dirty status by setting old to new. */ w=0; do { ck[w + _cksumNum] = ck[w]; w++; } while (x + w != _screenWidth / 8 && ck[w] != ck[w + _cksumNum]); addDirtyRect(x * 8, y * 8, w * 8, 8); if (_forceFull) goto get_out; } } } } else { get_out:; /* Copy old checksums to new */ memcpy(_dirtyChecksums + _cksumNum, _dirtyChecksums, _cksumNum * sizeof(uint32)); } }
void Screen::blitFrom3DOcolorLimit(uint16 limitColor) { uint16 *currentScreenPtr = (uint16 *)getPixels(); uint16 *targetScreenPtr = (uint16 *)_backBuffer->getPixels(); uint16 currentScreenPixel = 0; uint16 screenWidth = this->w(); uint16 screenHeight = this->h(); uint16 screenX = 0; uint16 screenY = 0; uint16 currentScreenPixelRed = 0; uint16 currentScreenPixelGreen = 0; uint16 currentScreenPixelBlue = 0; uint16 limitPixelRed = limitColor & 0xF800; uint16 limitPixelGreen = limitColor & 0x07E0; uint16 limitPixelBlue = limitColor & 0x001F; for (screenY = 0; screenY < screenHeight; screenY++) { for (screenX = 0; screenX < screenWidth; screenX++) { currentScreenPixel = *targetScreenPtr; currentScreenPixelRed = currentScreenPixel & 0xF800; currentScreenPixelGreen = currentScreenPixel & 0x07E0; currentScreenPixelBlue = currentScreenPixel & 0x001F; if (currentScreenPixelRed < limitPixelRed) currentScreenPixelRed = limitPixelRed; if (currentScreenPixelGreen < limitPixelGreen) currentScreenPixelGreen = limitPixelGreen; if (currentScreenPixelBlue < limitPixelBlue) currentScreenPixelBlue = limitPixelBlue; *currentScreenPtr = currentScreenPixelRed | currentScreenPixelGreen | currentScreenPixelBlue; currentScreenPtr++; targetScreenPtr++; } } // Too much considered dirty at the moment addDirtyRect(Common::Rect(0, 0, screenWidth, screenHeight)); }