aboutsummaryrefslogtreecommitdiff
path: root/backends/graphics/opengl/opengl-graphics.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'backends/graphics/opengl/opengl-graphics.cpp')
-rw-r--r--backends/graphics/opengl/opengl-graphics.cpp117
1 files changed, 94 insertions, 23 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);
}
}