diff options
Diffstat (limited to 'src/graphics.cpp')
-rw-r--r-- | src/graphics.cpp | 73 |
1 files changed, 50 insertions, 23 deletions
diff --git a/src/graphics.cpp b/src/graphics.cpp index ac3735f5..08b1b298 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -29,15 +29,19 @@ #include "utils/gettext.h" #include <SDL_gfxBlitFunc.h> +#include <SDL/SDL_rotozoom.h> Graphics::Graphics(): mWidth(0), mHeight(0), + mScale(1), mBpp(0), mFullscreen(false), mHWAccel(false), - mBlitMode(BLIT_NORMAL) + mBlitMode(BLIT_NORMAL), + mScreenSurface(0) { + mTarget = 0; } Graphics::~Graphics() @@ -64,13 +68,24 @@ bool Graphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel) else displayFlags |= SDL_SWSURFACE; - setTarget(SDL_SetVideoMode(w, h, bpp, displayFlags)); + SDL_FreeSurface(mTarget); + mTarget = 0; + + // Calculate scaling factor + mScale = std::max(w / 640, h / 360); + + mScreenSurface = SDL_SetVideoMode(w, h, bpp, displayFlags); + const SDL_PixelFormat& fmt = *(mScreenSurface->format); + setTarget(SDL_CreateRGBSurface(SDL_SWSURFACE, + w / mScale, h / mScale, + fmt.BitsPerPixel, + fmt.Rmask, fmt.Gmask, fmt.Bmask, 0)); if (!mTarget) return false; - mWidth = w; - mHeight = h; + mWidth = mTarget->w; + mHeight = mTarget->h; mBpp = bpp; mFullscreen = fs; mHWAccel = hwaccel; @@ -110,8 +125,8 @@ bool Graphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel) bool Graphics::changeVideoMode(int w, int h, int bpp, bool fs, bool hwaccel) { // Just return success if we're already in this mode - if (mWidth == w && - mHeight == h && + if (mScreenSurface && mScreenSurface->w == w && + mScreenSurface->h == h && mBpp == bpp && mFullscreen == fs && mHWAccel == hwaccel) @@ -121,12 +136,14 @@ bool Graphics::changeVideoMode(int w, int h, int bpp, bool fs, bool hwaccel) bool success = setVideoMode(w, h, bpp, fs, hwaccel); - // If it didn't work, try to restore the previous mode. If that doesn't + // If it didn't work, try to restore fallback resolution. If that doesn't // work either, we're in big trouble and bail out. - if (!success) { - if (!setVideoMode(mWidth, mHeight, mBpp, mFullscreen, mHWAccel)) { + if (!success) + { + if (!setVideoMode(640, 360, mBpp, mFullscreen, mHWAccel)) + { logger->error(_("Failed to change video mode and couldn't " - "switch back to the previous mode!")); + "switch back to the fallback mode!")); } } @@ -135,16 +152,6 @@ bool Graphics::changeVideoMode(int w, int h, int bpp, bool fs, bool hwaccel) return success; } -int Graphics::getWidth() const -{ - return mWidth; -} - -int Graphics::getHeight() const -{ - return mHeight; -} - bool Graphics::drawImage(Image *image, int x, int y) { if (image) @@ -181,8 +188,8 @@ bool Graphics::drawRescaledImage(Image *image, int srcX, int srcY, SDL_Rect srcRect; dstRect.x = dstX; dstRect.y = dstY; srcRect.x = srcX; srcRect.y = srcY; - srcRect.w = width; - srcRect.h = height; + srcRect.w = tmpImage->getWidth(); + srcRect.h = tmpImage->getHeight(); returnValue = !(SDL_BlitSurface(tmpImage->mSDLSurface, &srcRect, mTarget, &dstRect) < 0); @@ -361,7 +368,27 @@ void Graphics::drawImageRect(int x, int y, int w, int h, void Graphics::updateScreen() { - SDL_Flip(mTarget); + // Center viewport + SDL_Rect dstRect; + dstRect.x = (mScreenSurface->w-getWidth() * mScale) / 2; + dstRect.y = (mScreenSurface->h-getHeight() * mScale) / 2; + + // Zoom in if necessary + if (mScale > 1) + { + SDL_Surface *tmp = zoomSurface(mTarget, mScale, mScale, 0); + + // Copy temporary surface to screen + SDL_BlitSurface(tmp, NULL, mScreenSurface, &dstRect); + SDL_FreeSurface(tmp); + } + else + { + // Copy mTarget directly to screen + SDL_BlitSurface(mTarget, NULL, mScreenSurface, &dstRect); + } + + SDL_Flip(mScreenSurface); } SDL_Surface *Graphics::getScreenshot() |