summaryrefslogtreecommitdiff
path: root/src/graphics.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/graphics.cpp')
-rw-r--r--src/graphics.cpp73
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()