aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;
}