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