aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
authorAlejandro Marzini2010-07-27 07:30:56 +0000
committerAlejandro Marzini2010-07-27 07:30:56 +0000
commit2636ac4f36b412a8d6c62267393a19e8ba181388 (patch)
tree1b8acccc0f1310d6b2265fb421f83d10787718a3 /backends
parent591b371f2be62a8140431e9e482011c4315bc7de (diff)
downloadscummvm-rg350-2636ac4f36b412a8d6c62267393a19e8ba181388.tar.gz
scummvm-rg350-2636ac4f36b412a8d6c62267393a19e8ba181388.tar.bz2
scummvm-rg350-2636ac4f36b412a8d6c62267393a19e8ba181388.zip
OPENGL: Implement aspect ratio support and toggling. Improve fullscreen switching. Fix cursor scaling bug.
Now the hotkey Ctrl-Alt-Enter will switch between all available fullscreen modes. Alt-Enter will only switch to the best mode available, and exit fullscreen mode if already on it. The different aspect ratios can be switched with Ctrl-Alt-A. The normal mode will stretch the contents to the screen, while other modes will stretch only one dimension to the screen size, and maintain the aspect ratio for the other dimension. svn-id: r51346
Diffstat (limited to 'backends')
-rw-r--r--backends/graphics/opengl/opengl-graphics.cpp117
-rw-r--r--backends/graphics/opengl/opengl-graphics.h11
-rw-r--r--backends/graphics/openglsdl/openglsdl-graphics.cpp135
-rw-r--r--backends/graphics/openglsdl/openglsdl-graphics.h2
-rw-r--r--backends/graphics/sdl/sdl-graphics.cpp2
5 files changed, 193 insertions, 74 deletions
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index ac3f561f9e..a0ffa1fcd2 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -46,7 +46,8 @@ OpenGLGraphicsManager::OpenGLGraphicsManager()
_cursorNeedsRedraw(false), _cursorPaletteDisabled(true),
_cursorVisible(false), _cursorKeyColor(0),
_cursorTargetScale(1),
- _formatBGR(false) {
+ _formatBGR(false),
+ _aspectX(0), _aspectY(0), _aspectWidth(0), _aspectHeight(0) {
memset(&_oldVideoMode, 0, sizeof(_oldVideoMode));
memset(&_videoMode, 0, sizeof(_videoMode));
@@ -56,6 +57,7 @@ OpenGLGraphicsManager::OpenGLGraphicsManager()
_videoMode.scaleFactor = 2;
_videoMode.fullscreen = false;
_videoMode.antialiasing = false;
+ _videoMode.aspectRatioCorrection = 0;
_gamePalette = (byte *)calloc(sizeof(byte) * 4, 256);
_cursorPalette = (byte *)calloc(sizeof(byte) * 4, 256);
@@ -801,10 +803,10 @@ void OpenGLGraphicsManager::refreshCursor() {
void OpenGLGraphicsManager::refreshCursorScale() {
// Get the window minimum scale factor. The cursor will mantain its original aspect
// ratio, and we do not want it to get too big if only one dimension is resized
- float scaleFactor = MIN((float)_videoMode.hardwareWidth / _videoMode.screenWidth,
+ float screenScaleFactor = MIN((float)_videoMode.hardwareWidth / _videoMode.screenWidth,
(float)_videoMode.hardwareHeight / _videoMode.screenHeight);
- if (_cursorTargetScale >= scaleFactor && _videoMode.scaleFactor >= scaleFactor) {
+ if (_cursorTargetScale >= screenScaleFactor && _videoMode.scaleFactor >= screenScaleFactor) {
// If the cursor target scale and the video mode scale factor are bigger than
// the current window scale, do not scale the cursor for the overlay
_cursorState.rW = _cursorState.w;
@@ -813,17 +815,34 @@ void OpenGLGraphicsManager::refreshCursorScale() {
_cursorState.rHotY = _cursorState.hotY;
} else {
// Otherwise, scale the cursor for the overlay
- _cursorState.rW = _cursorState.w * (scaleFactor - _cursorTargetScale + 1);
- _cursorState.rH = _cursorState.h * (scaleFactor - _cursorTargetScale + 1);
- _cursorState.rHotX = _cursorState.hotX * (scaleFactor - _cursorTargetScale + 1);
- _cursorState.rHotY = _cursorState.hotY * (scaleFactor - _cursorTargetScale + 1);
+ float targetScaleFactor = MIN(_cursorTargetScale, _videoMode.scaleFactor);
+ _cursorState.rW = _cursorState.w * (screenScaleFactor - targetScaleFactor + 1);
+ _cursorState.rH = _cursorState.h * (screenScaleFactor - targetScaleFactor + 1);
+ _cursorState.rHotX = _cursorState.hotX * (screenScaleFactor - targetScaleFactor + 1);
+ _cursorState.rHotY = _cursorState.hotY * (screenScaleFactor - targetScaleFactor + 1);
}
// Always scale the cursor for the game
- _cursorState.vW = _cursorState.w * scaleFactor;
- _cursorState.vH = _cursorState.h * scaleFactor;
- _cursorState.vHotX = _cursorState.hotX * scaleFactor;
- _cursorState.vHotY = _cursorState.hotY * scaleFactor;
+ _cursorState.vW = _cursorState.w * screenScaleFactor;
+ _cursorState.vH = _cursorState.h * screenScaleFactor;
+ _cursorState.vHotX = _cursorState.hotX * screenScaleFactor;
+ _cursorState.vHotY = _cursorState.hotY * screenScaleFactor;
+}
+
+void OpenGLGraphicsManager::refreshAspectRatio() {
+ _aspectWidth = _videoMode.hardwareWidth;
+ _aspectHeight = _videoMode.hardwareHeight;
+
+ float aspectRatio = (float)_videoMode.hardwareWidth / _videoMode.hardwareHeight;
+ float desiredAspectRatio = getAspectRatio();
+
+ if (aspectRatio < desiredAspectRatio)
+ _aspectHeight = (int)(_aspectWidth / desiredAspectRatio + 0.5f);
+ else if (aspectRatio > desiredAspectRatio)
+ _aspectWidth = (int)(_aspectHeight * desiredAspectRatio + 0.5f);
+
+ _aspectX = (_videoMode.hardwareWidth - _aspectWidth) / 2;
+ _aspectY = (_videoMode.hardwareHeight - _aspectHeight) / 2;
}
void OpenGLGraphicsManager::getGLPixelFormat(Graphics::PixelFormat pixelFormat, byte &bpp, GLenum &glFormat, GLenum &gltype) {
@@ -873,7 +892,7 @@ void OpenGLGraphicsManager::internUpdateScreen() {
glTranslatef(0, _shakePos * scaleFactor, 0); CHECK_GL_ERROR();
// Draw the game screen
- _gameTexture->drawTexture(0, 0, _videoMode.hardwareWidth, _videoMode.hardwareHeight);
+ _gameTexture->drawTexture(_aspectX, _aspectY, _aspectWidth, _aspectHeight);
glPopMatrix();
@@ -883,7 +902,7 @@ void OpenGLGraphicsManager::internUpdateScreen() {
refreshOverlay();
// Draw the overlay
- _overlayTexture->drawTexture(0, 0, _videoMode.hardwareWidth, _videoMode.hardwareHeight);
+ _overlayTexture->drawTexture(_aspectX, _aspectY, _aspectWidth, _aspectHeight);
}
if (_cursorVisible) {
@@ -1046,6 +1065,8 @@ bool OpenGLGraphicsManager::loadGFXMode() {
refreshCursorScale();
+ refreshAspectRatio();
+
internUpdateScreen();
return true;
@@ -1081,27 +1102,77 @@ void OpenGLGraphicsManager::setAspectRatioCorrection(int ratio) {
if (_transactionMode == kTransactionActive) {
if (ratio == -1)
- _videoMode.aspectRatioCorrection = (_videoMode.aspectRatioCorrection + 1) % 4;
+ _videoMode.aspectRatioCorrection = (_videoMode.aspectRatioCorrection + 1) % 5;
else
_videoMode.aspectRatioCorrection = ratio;
_transactionDetails.needHotswap = true;
}
}
+Common::String OpenGLGraphicsManager::getAspectRatioName() {
+ switch (_videoMode.aspectRatioCorrection) {
+ case kAspectRatioNone:
+ return "None";
+ case kAspectRatioConserve:
+ return "Conserve";
+ case kAspectRatio4_3:
+ return "4/3";
+ case kAspectRatio16_9:
+ return "16/9";
+ case kAspectRatio16_10:
+ return "16/10";
+ }
+ return "";
+}
+
+float OpenGLGraphicsManager::getAspectRatio() {
+ switch (_videoMode.aspectRatioCorrection) {
+ case kAspectRatioConserve:
+ return (float)_videoMode.screenWidth / _videoMode.screenHeight;
+ case kAspectRatio4_3:
+ return 4.0f / 3.0f;
+ case kAspectRatio16_9:
+ return 16.0f / 9.0f;
+ case kAspectRatio16_10:
+ return 16.0f / 10.0f;
+ default:
+ return (float)_videoMode.hardwareWidth / _videoMode.hardwareHeight;
+ }
+}
+
void OpenGLGraphicsManager::adjustMouseEvent(const Common::Event &event) {
if (!event.synthetic) {
Common::Event newEvent(event);
newEvent.synthetic = true;
- if (!_overlayVisible) {
- newEvent.mouse.x /= _videoMode.scaleFactor;
- newEvent.mouse.y /= _videoMode.scaleFactor;
- //if (_videoMode.aspectRatioCorrection)
- // newEvent.mouse.y = aspect2Real(newEvent.mouse.y);
+
+ if (!_videoMode.aspectRatioCorrection) {
+ if (_videoMode.hardwareWidth != _videoMode.overlayWidth)
+ newEvent.mouse.x = newEvent.mouse.x * _videoMode.overlayWidth / _videoMode.hardwareWidth;
+ if (_videoMode.hardwareHeight != _videoMode.overlayHeight)
+ newEvent.mouse.y = newEvent.mouse.y * _videoMode.overlayHeight / _videoMode.hardwareHeight;
+
+ if (!_overlayVisible) {
+ newEvent.mouse.x /= _videoMode.scaleFactor;
+ newEvent.mouse.y /= _videoMode.scaleFactor;
+ }
+
+ } else {
+ newEvent.mouse.x -= _aspectX;
+ newEvent.mouse.y -= _aspectY;
+
+ if (_overlayVisible) {
+ if (_aspectWidth != _videoMode.overlayWidth)
+ newEvent.mouse.x = newEvent.mouse.x * _videoMode.overlayWidth / _aspectWidth;
+ if (_aspectHeight != _videoMode.overlayHeight)
+ newEvent.mouse.y = newEvent.mouse.y * _videoMode.overlayHeight / _aspectHeight;
+ } else {
+ if (_aspectWidth != _videoMode.screenWidth)
+ newEvent.mouse.x = newEvent.mouse.x * _videoMode.screenWidth / _aspectWidth;
+ if (_aspectHeight != _videoMode.screenHeight)
+ newEvent.mouse.y = newEvent.mouse.y * _videoMode.screenHeight / _aspectHeight;
+ }
}
- if (_videoMode.hardwareWidth != _videoMode.overlayWidth)
- newEvent.mouse.x = newEvent.mouse.x * _videoMode.overlayWidth / _videoMode.hardwareWidth;
- if (_videoMode.hardwareHeight != _videoMode.overlayHeight)
- newEvent.mouse.y = newEvent.mouse.y * _videoMode.overlayHeight / _videoMode.hardwareHeight;
+
g_system->getEventManager()->pushEvent(newEvent);
}
}
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index efc8114e3d..ee14df836e 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -133,6 +133,7 @@ protected:
kAspectRatioNone,
kAspectRatioConserve,
kAspectRatio4_3,
+ kAspectRatio16_9,
kAspectRatio16_10
};
@@ -140,6 +141,7 @@ protected:
bool setup;
bool fullscreen;
+ int activeFullscreenMode;
int aspectRatioCorrection;
int mode;
@@ -162,7 +164,16 @@ protected:
virtual void unloadGFXMode();
virtual void setScale(int newScale);
+
+ int _aspectX;
+ int _aspectY;
+ int _aspectWidth;
+ int _aspectHeight;
+
virtual void setAspectRatioCorrection(int mode);
+ virtual void refreshAspectRatio();
+ virtual Common::String getAspectRatioName();
+ virtual float getAspectRatio();
bool _formatBGR;
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index ea01727238..4dac109a01 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -126,15 +126,10 @@ Common::List<Graphics::PixelFormat> OpenGLSdlGraphicsManager::getSupportedFormat
void OpenGLSdlGraphicsManager::warpMouse(int x, int y) {
if (_cursorState.x != x || _cursorState.y != y) {
- int y1 = y;
-
- /*if (_videoMode.aspectRatioCorrection && !_overlayVisible)
- y1 = real2Aspect(y);*/
-
if (!_overlayVisible)
- SDL_WarpMouse(x * _videoMode.scaleFactor, y1 * _videoMode.scaleFactor);
+ SDL_WarpMouse(x * _videoMode.scaleFactor, y * _videoMode.scaleFactor);
else
- SDL_WarpMouse(x, y1);
+ SDL_WarpMouse(x, y);
setMousePos(x, y);
}
@@ -153,7 +148,22 @@ bool OpenGLSdlGraphicsManager::loadGFXMode() {
if (!_screenResized) {
_videoMode.hardwareWidth = _videoMode.overlayWidth;
_videoMode.hardwareHeight = _videoMode.overlayHeight;
+
+ float screenAspectRatio = (float)_videoMode.screenWidth / _videoMode.screenHeight;
+ float desiredAspectRatio = getAspectRatio();
+
+ // Do not downscale dimensions, only enlarge them if needed
+ if (screenAspectRatio > desiredAspectRatio)
+ _videoMode.hardwareHeight = (int)(_videoMode.overlayWidth / desiredAspectRatio + 0.5f);
+ else if (screenAspectRatio < desiredAspectRatio)
+ _videoMode.hardwareWidth = (int)(_videoMode.overlayHeight * desiredAspectRatio + 0.5f);
+
+ // Only adjust the overlay height if it is bigger than original one. If
+ // the width is modified it can break the overlay.
+ if (_videoMode.hardwareHeight > _videoMode.overlayHeight)
+ _videoMode.overlayHeight = _videoMode.hardwareHeight;
}
+
_screenResized = false;
// Setup OpenGL attributes for SDL
@@ -166,34 +176,45 @@ bool OpenGLSdlGraphicsManager::loadGFXMode() {
// Find the best mode for fullscreen
if (_videoMode.fullscreen) {
SDL_Rect const* const*availableModes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_OPENGL);
- const SDL_Rect *bestMode = NULL;
- uint bestMetric = (uint)-1;
-
- // Iterate over all available fullscreen modes
- while (const SDL_Rect *mode = *availableModes++) {
- if (mode->w < _videoMode.hardwareWidth)
- continue;
- if (mode->h < _videoMode.hardwareHeight)
- continue;
-
- uint metric = mode->w * mode->h - _videoMode.hardwareWidth * _videoMode.hardwareHeight;
- if (metric > bestMetric)
- continue;
-
- bestMode = mode;
- bestMetric = metric;
- }
- if (bestMode) {
- // If there is a suiting mode, use it
- _videoMode.hardwareWidth = bestMode->w;
- _videoMode.hardwareHeight = bestMode->h;
+ if (_videoMode.activeFullscreenMode == -1) {
+ const SDL_Rect *bestMode = availableModes[0];
+ int bestModeIndex = 0;
+ uint bestMetric = (uint)-1;
+
+ // Iterate over all available fullscreen modes
+ for (int i = 0; const SDL_Rect *mode = availableModes[i]; i++) {
+ if (mode->w < _videoMode.hardwareWidth)
+ continue;
+ if (mode->h < _videoMode.hardwareHeight)
+ continue;
+
+ uint metric = mode->w * mode->h - _videoMode.hardwareWidth * _videoMode.hardwareHeight;
+ if (metric > bestMetric)
+ continue;
+
+ bestMode = mode;
+ bestMetric = metric;
+ bestModeIndex = i;
+ }
+
+ if (bestMode) {
+ // If there is a suiting mode, use it
+ _videoMode.hardwareWidth = bestMode->w;
+ _videoMode.hardwareHeight = bestMode->h;
+
+ _videoMode.activeFullscreenMode = bestModeIndex;
+ }
} else {
- // If the last mode was in fullscreen, cancel GFX load
- if (_oldVideoMode.fullscreen)
- return false;
+ if (!availableModes[_videoMode.activeFullscreenMode])
+ _videoMode.activeFullscreenMode = 0;
- _videoMode.fullscreen = false;
+ if (availableModes[_videoMode.activeFullscreenMode]) {
+ _videoMode.hardwareWidth = availableModes[_videoMode.activeFullscreenMode]->w;
+ _videoMode.hardwareHeight = availableModes[_videoMode.activeFullscreenMode]->h;
+ } else {
+ return false;
+ }
}
}
@@ -249,16 +270,11 @@ bool OpenGLSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
endGFXTransaction();
#ifdef USE_OSD
char buffer[128];
- if (_videoMode.aspectRatioCorrection)
- sprintf(buffer, "Enabled aspect ratio correction\n%d x %d -> %d x %d",
- _videoMode.screenWidth, _videoMode.screenHeight,
- _hwscreen->w, _hwscreen->h
- );
- else
- sprintf(buffer, "Disabled aspect ratio correction\n%d x %d -> %d x %d",
- _videoMode.screenWidth, _videoMode.screenHeight,
- _hwscreen->w, _hwscreen->h
- );
+ sprintf(buffer, "Current aspect ratio mode: %s\n%d x %d -> %d x %d",
+ getAspectRatioName().c_str(),
+ _videoMode.screenWidth, _videoMode.screenHeight,
+ _hwscreen->w, _hwscreen->h
+ );
displayMessageOnOSD(buffer);
#endif
internUpdateScreen();
@@ -318,7 +334,8 @@ bool OpenGLSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
}
void OpenGLSdlGraphicsManager::setFullscreenMode(bool enable) {
- if (_oldVideoMode.setup && _oldVideoMode.fullscreen == enable)
+ if (_oldVideoMode.setup && _oldVideoMode.fullscreen == enable &&
+ _oldVideoMode.activeFullscreenMode == _videoMode.activeFullscreenMode)
return;
if (_transactionMode == kTransactionActive) {
@@ -337,15 +354,27 @@ bool OpenGLSdlGraphicsManager::isScalerHotkey(const Common::Event &event) {
return false;
}
-void OpenGLSdlGraphicsManager::toggleFullScreen() {
+void OpenGLSdlGraphicsManager::toggleFullScreen(bool loop) {
beginGFXTransaction();
- setFullscreenMode(!_videoMode.fullscreen);
+ if (_videoMode.fullscreen && loop) {
+ _videoMode.activeFullscreenMode += 1;
+ setFullscreenMode(true);
+ } else {
+ _videoMode.activeFullscreenMode = -1;
+ setFullscreenMode(!_videoMode.fullscreen);
+ }
endGFXTransaction();
#ifdef USE_OSD
+ char buffer[128];
if (_videoMode.fullscreen)
- displayMessageOnOSD("Fullscreen mode");
+ sprintf(buffer, "Fullscreen mode\n%d x %d",
+ _hwscreen->w, _hwscreen->h
+ );
else
- displayMessageOnOSD("Windowed mode");
+ sprintf(buffer, "Windowed mode\n%d x %d",
+ _hwscreen->w, _hwscreen->h
+ );
+ displayMessageOnOSD(buffer);
#endif
}
@@ -356,7 +385,15 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
if (event.kbd.hasFlags(Common::KBD_ALT) &&
(event.kbd.keycode == Common::KEYCODE_RETURN ||
event.kbd.keycode == (Common::KeyCode)SDLK_KP_ENTER)) {
- toggleFullScreen();
+ toggleFullScreen(false);
+ return true;
+ }
+
+ // Ctrl-Alt-Return and Ctrl-Alt-Enter switches between full screen modes
+ if (event.kbd.hasFlags(Common::KBD_CTRL|Common::KBD_ALT) &&
+ (event.kbd.keycode == Common::KEYCODE_RETURN ||
+ event.kbd.keycode == (Common::KeyCode)SDLK_KP_ENTER)) {
+ toggleFullScreen(true);
return true;
}
@@ -381,7 +418,7 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
}
// Ctrl-Alt-<key> will change the GFX mode
- if ((event.kbd.flags & (Common::KBD_CTRL|Common::KBD_ALT)) == (Common::KBD_CTRL|Common::KBD_ALT)) {
+ if (event.kbd.hasFlags(Common::KBD_CTRL|Common::KBD_ALT)) {
if (handleScalerHotkeys(event.kbd.keycode))
return true;
}
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.h b/backends/graphics/openglsdl/openglsdl-graphics.h
index f11782131c..2db9c2dbe6 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.h
+++ b/backends/graphics/openglsdl/openglsdl-graphics.h
@@ -63,7 +63,7 @@ protected:
virtual bool handleScalerHotkeys(Common::KeyCode key);
virtual bool isScalerHotkey(const Common::Event &event);
- virtual void toggleFullScreen();
+ virtual void toggleFullScreen(bool loop);
// Hardware screen
SDL_Surface *_hwscreen;
diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp
index c2f859a949..2d61cec185 100644
--- a/backends/graphics/sdl/sdl-graphics.cpp
+++ b/backends/graphics/sdl/sdl-graphics.cpp
@@ -2153,7 +2153,7 @@ bool SdlGraphicsManager::notifyEvent(const Common::Event &event) {
}
// Ctrl-Alt-<key> will change the GFX mode
- if ((event.kbd.flags & (Common::KBD_CTRL|Common::KBD_ALT)) == (Common::KBD_CTRL|Common::KBD_ALT)) {
+ if (event.kbd.hasFlags(Common::KBD_CTRL|Common::KBD_ALT)) {
if (handleScalerHotkeys(event.kbd.keycode))
return true;
}