void OSystem_SDL::clearOverlay() { //assert (_transactionMode == kTransactionNone); Common::StackLock lock(_graphicsMutex); // Lock the mutex until this function ends if (!_overlayVisible) return; // Clear the overlay by making the game screen "look through" everywhere. SDL_Rect src, dst; src.x = src.y = 0; dst.x = dst.y = 1; src.w = dst.w = _screenWidth; src.h = dst.h = _screenHeight; if (SDL_BlitSurface(_screen, &src, _tmpscreen, &dst) != 0) error("SDL_BlitSurface failed: %s", SDL_GetError()); SDL_LockSurface(_tmpscreen); SDL_LockSurface(_overlayscreen); _scalerProc((byte *)(_tmpscreen->pixels) + _tmpscreen->pitch + 2, _tmpscreen->pitch, (byte *)_overlayscreen->pixels, _overlayscreen->pitch, _screenWidth, _screenHeight); #ifndef DISABLE_SCALERS if (_adjustAspectRatio) stretch200To240((uint8 *)_overlayscreen->pixels, _overlayscreen->pitch, _overlayWidth, _screenHeight * _scaleFactor, 0, 0, 0); #endif SDL_UnlockSurface(_tmpscreen); SDL_UnlockSurface(_overlayscreen); _forceFull = true; }
void WINCESdlGraphicsManager::internUpdateScreen() { SDL_Surface *srcSurf, *origSurf; static bool old_overlayVisible = false; int numRectsOut = 0; int16 routx, routy, routw, routh, stretch, shakestretch; assert(_hwscreen != NULL); // bail if the application is minimized, be nice to OS if (!_hasfocus) { Sleep(20); return; } // If the shake position changed, fill the dirty area with blackness if (_currentShakePos != _newShakePos) { SDL_Rect blackrect = {0, 0, _videoMode.screenWidth *_scaleFactorXm / _scaleFactorXd, _newShakePos *_scaleFactorYm / _scaleFactorYd}; if (_videoMode.aspectRatioCorrection) blackrect.h = real2Aspect(blackrect.h - 1) + 1; SDL_FillRect(_hwscreen, &blackrect, 0); _currentShakePos = _newShakePos; _forceFull = true; } // Make sure the mouse is drawn, if it should be drawn. drawMouse(); // Check whether the palette was changed in the meantime and update the // screen surface accordingly. if (_paletteDirtyEnd != 0) { SDL_SetColors(_screen, _currentPalette + _paletteDirtyStart, _paletteDirtyStart, _paletteDirtyEnd - _paletteDirtyStart); _paletteDirtyEnd = 0; _forceFull = true; } if (!_overlayVisible) { origSurf = _screen; srcSurf = _tmpscreen; } else { origSurf = _overlayscreen; srcSurf = _tmpscreen2; } if (old_overlayVisible != _overlayVisible) { old_overlayVisible = _overlayVisible; update_scalers(); } // Force a full redraw if requested if (_forceFull) { _numDirtyRects = 1; _dirtyRectList[0].x = 0; if (!_zoomDown) _dirtyRectList[0].y = 0; else _dirtyRectList[0].y = _videoMode.screenHeight / 2; _dirtyRectList[0].w = _videoMode.screenWidth; if (!_zoomUp && !_zoomDown) _dirtyRectList[0].h = _videoMode.screenHeight; else _dirtyRectList[0].h = _videoMode.screenHeight / 2; _toolbarHandler.forceRedraw(); } // Only draw anything if necessary if (_numDirtyRects > 0) { SDL_Rect *r, *rout; SDL_Rect dst; uint32 srcPitch, dstPitch; SDL_Rect *last_rect = _dirtyRectList + _numDirtyRects; bool toolbarVisible = _toolbarHandler.visible(); int toolbarOffset = _toolbarHandler.getOffset(); for (r = _dirtyRectList; r != last_rect; ++r) { dst = *r; dst.x++; // Shift rect by one since 2xSai needs to access the data around dst.y++; // any pixel to scale it, and we want to avoid mem access crashes. // NOTE: This is also known as BLACK MAGIC, copied from the sdl backend if (SDL_BlitSurface(origSurf, r, srcSurf, &dst) != 0) error("SDL_BlitSurface failed: %s", SDL_GetError()); } SDL_LockSurface(srcSurf); SDL_LockSurface(_hwscreen); srcPitch = srcSurf->pitch; dstPitch = _hwscreen->pitch; for (r = _dirtyRectList, rout = _dirtyRectOut; r != last_rect; ++r) { // always clamp to enclosing, downsampled-grid-aligned rect in the downscaled image if (_scaleFactorXd != 1) { stretch = r->x % _scaleFactorXd; r->x -= stretch; r->w += stretch; r->w = (r->x + r->w + _scaleFactorXd - 1) / _scaleFactorXd * _scaleFactorXd - r->x; } if (_scaleFactorYd != 1) { stretch = r->y % _scaleFactorYd; r->y -= stretch; r->h += stretch; r->h = (r->y + r->h + _scaleFactorYd - 1) / _scaleFactorYd * _scaleFactorYd - r->y; } // transform shakestretch = _currentShakePos * _scaleFactorYm / _scaleFactorYd; routx = r->x * _scaleFactorXm / _scaleFactorXd; // locate position in scaled screen routy = r->y * _scaleFactorYm / _scaleFactorYd + shakestretch; // adjust for shake offset routw = r->w * _scaleFactorXm / _scaleFactorXd; routh = r->h * _scaleFactorYm / _scaleFactorYd - shakestretch; // clipping destination rectangle inside device screen (more strict, also more tricky but more stable) // note that all current scalers do not make dst rect exceed left/right, unless chosen badly (FIXME) if (_zoomDown) routy -= 240; // adjust for zoom position if (routy + routh < 0) continue; if (routy < 0) { routh += routy; r->y -= routy * _scaleFactorYd / _scaleFactorYm; routy = 0; r->h = routh * _scaleFactorYd / _scaleFactorYm; } if (_orientationLandscape) { if (routy > OSystem_WINCE3::getScreenWidth()) continue; if (routy + routh > OSystem_WINCE3::getScreenWidth()) { routh = OSystem_WINCE3::getScreenWidth() - routy; r->h = routh * _scaleFactorYd / _scaleFactorYm; } } else { if (routy > OSystem_WINCE3::getScreenHeight()) continue; if (routy + routh > OSystem_WINCE3::getScreenHeight()) { routh = OSystem_WINCE3::getScreenHeight() - routy; r->h = routh * _scaleFactorYd / _scaleFactorYm; } } // check if the toolbar is overwritten if (toolbarVisible && r->y + r->h >= toolbarOffset) _toolbarHandler.forceRedraw(); // blit it (with added voodoo from the sdl backend, shifting the source rect again) _scalerProc((byte *)srcSurf->pixels + (r->x * 2 + 2) + (r->y + 1) * srcPitch, srcPitch, (byte *)_hwscreen->pixels + routx * 2 + routy * dstPitch, dstPitch, r->w, r->h - _currentShakePos); // add this rect to output rout->x = routx; rout->y = routy - shakestretch; rout->w = routw; rout->h = routh + shakestretch; numRectsOut++; rout++; } SDL_UnlockSurface(srcSurf); SDL_UnlockSurface(_hwscreen); } // Add the toolbar if needed SDL_Rect toolbar_rect[1]; if (_panelVisible && _toolbarHandler.draw(_toolbarLow, &toolbar_rect[0])) { // It can be drawn, scale it uint32 srcPitch, dstPitch; SDL_Surface *toolbarSurface; ScalerProc *toolbarScaler; if (_videoMode.screenHeight > 240) { if (!_toolbarHighDrawn) { // Resize the toolbar SDL_LockSurface(_toolbarLow); SDL_LockSurface(_toolbarHigh); Normal2x((byte *)_toolbarLow->pixels, _toolbarLow->pitch, (byte *)_toolbarHigh->pixels, _toolbarHigh->pitch, toolbar_rect[0].w, toolbar_rect[0].h); SDL_UnlockSurface(_toolbarHigh); SDL_UnlockSurface(_toolbarLow); _toolbarHighDrawn = true; } toolbar_rect[0].w *= 2; toolbar_rect[0].h *= 2; toolbarSurface = _toolbarHigh; } else toolbarSurface = _toolbarLow; drawToolbarMouse(toolbarSurface, true); // draw toolbar mouse if applicable // Apply the appropriate scaler SDL_LockSurface(toolbarSurface); SDL_LockSurface(_hwscreen); srcPitch = toolbarSurface->pitch; dstPitch = _hwscreen->pitch; toolbarScaler = _scalerProc; if (_videoMode.scaleFactor == 2) toolbarScaler = Normal2x; else if (_videoMode.scaleFactor == 3) toolbarScaler = Normal3x; toolbarScaler((byte *)toolbarSurface->pixels, srcPitch, (byte *)_hwscreen->pixels + (_toolbarHandler.getOffset() * _scaleFactorYm / _scaleFactorYd * dstPitch), dstPitch, toolbar_rect[0].w, toolbar_rect[0].h); SDL_UnlockSurface(toolbarSurface); SDL_UnlockSurface(_hwscreen); // And blit it toolbar_rect[0].y = _toolbarHandler.getOffset(); toolbar_rect[0].x = toolbar_rect[0].x * _scaleFactorXm / _scaleFactorXd; toolbar_rect[0].y = toolbar_rect[0].y * _scaleFactorYm / _scaleFactorYd; toolbar_rect[0].w = toolbar_rect[0].w * _scaleFactorXm / _scaleFactorXd; toolbar_rect[0].h = toolbar_rect[0].h * _scaleFactorYm / _scaleFactorYd; SDL_UpdateRects(_hwscreen, 1, toolbar_rect); drawToolbarMouse(toolbarSurface, false); // undraw toolbar mouse } // Finally, blit all our changes to the screen if (numRectsOut > 0) SDL_UpdateRects(_hwscreen, numRectsOut, _dirtyRectOut); _numDirtyRects = 0; _forceFull = false; }