Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}