diff options
Diffstat (limited to 'src/graphics.cpp')
-rw-r--r-- | src/graphics.cpp | 69 |
1 files changed, 48 insertions, 21 deletions
diff --git a/src/graphics.cpp b/src/graphics.cpp index 7b56d974..d36d2fa7 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -30,15 +30,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() @@ -65,13 +69,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; @@ -111,8 +126,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) @@ -122,12 +137,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!")); } } @@ -136,16 +153,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) @@ -371,7 +378,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() |