diff options
author | Alejandro Marzini | 2010-07-27 07:30:56 +0000 |
---|---|---|
committer | Alejandro Marzini | 2010-07-27 07:30:56 +0000 |
commit | 2636ac4f36b412a8d6c62267393a19e8ba181388 (patch) | |
tree | 1b8acccc0f1310d6b2265fb421f83d10787718a3 /backends/graphics/opengl/opengl-graphics.cpp | |
parent | 591b371f2be62a8140431e9e482011c4315bc7de (diff) | |
download | scummvm-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/graphics/opengl/opengl-graphics.cpp')
-rw-r--r-- | backends/graphics/opengl/opengl-graphics.cpp | 117 |
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); } } |