[Scummvm-cvs-logs] SF.net SVN: scummvm:[51346] scummvm/branches/gsoc2010-opengl/backends/ graphics
vgvgf at users.sourceforge.net
vgvgf at users.sourceforge.net
Tue Jul 27 09:30:56 CEST 2010
Revision: 51346
http://scummvm.svn.sourceforge.net/scummvm/?rev=51346&view=rev
Author: vgvgf
Date: 2010-07-27 07:30:56 +0000 (Tue, 27 Jul 2010)
Log Message:
-----------
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.
Modified Paths:
--------------
scummvm/branches/gsoc2010-opengl/backends/graphics/opengl/opengl-graphics.cpp
scummvm/branches/gsoc2010-opengl/backends/graphics/opengl/opengl-graphics.h
scummvm/branches/gsoc2010-opengl/backends/graphics/openglsdl/openglsdl-graphics.cpp
scummvm/branches/gsoc2010-opengl/backends/graphics/openglsdl/openglsdl-graphics.h
scummvm/branches/gsoc2010-opengl/backends/graphics/sdl/sdl-graphics.cpp
Modified: scummvm/branches/gsoc2010-opengl/backends/graphics/opengl/opengl-graphics.cpp
===================================================================
--- scummvm/branches/gsoc2010-opengl/backends/graphics/opengl/opengl-graphics.cpp 2010-07-27 06:27:45 UTC (rev 51345)
+++ scummvm/branches/gsoc2010-opengl/backends/graphics/opengl/opengl-graphics.cpp 2010-07-27 07:30:56 UTC (rev 51346)
@@ -46,7 +46,8 @@
_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 @@
_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::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,19 +815,36 @@
_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) {
if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)) { // RGBA8888
bpp = 4;
@@ -873,7 +892,7 @@
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 @@
refreshOverlay();
// Draw the overlay
- _overlayTexture->drawTexture(0, 0, _videoMode.hardwareWidth, _videoMode.hardwareHeight);
+ _overlayTexture->drawTexture(_aspectX, _aspectY, _aspectWidth, _aspectHeight);
}
if (_cursorVisible) {
@@ -1046,6 +1065,8 @@
refreshCursorScale();
+ refreshAspectRatio();
+
internUpdateScreen();
return true;
@@ -1081,27 +1102,77 @@
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);
}
}
Modified: scummvm/branches/gsoc2010-opengl/backends/graphics/opengl/opengl-graphics.h
===================================================================
--- scummvm/branches/gsoc2010-opengl/backends/graphics/opengl/opengl-graphics.h 2010-07-27 06:27:45 UTC (rev 51345)
+++ scummvm/branches/gsoc2010-opengl/backends/graphics/opengl/opengl-graphics.h 2010-07-27 07:30:56 UTC (rev 51346)
@@ -133,6 +133,7 @@
kAspectRatioNone,
kAspectRatioConserve,
kAspectRatio4_3,
+ kAspectRatio16_9,
kAspectRatio16_10
};
@@ -140,6 +141,7 @@
bool setup;
bool fullscreen;
+ int activeFullscreenMode;
int aspectRatioCorrection;
int mode;
@@ -162,7 +164,16 @@
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;
Modified: scummvm/branches/gsoc2010-opengl/backends/graphics/openglsdl/openglsdl-graphics.cpp
===================================================================
--- scummvm/branches/gsoc2010-opengl/backends/graphics/openglsdl/openglsdl-graphics.cpp 2010-07-27 06:27:45 UTC (rev 51345)
+++ scummvm/branches/gsoc2010-opengl/backends/graphics/openglsdl/openglsdl-graphics.cpp 2010-07-27 07:30:56 UTC (rev 51346)
@@ -126,15 +126,10 @@
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 @@
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 @@
// 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;
+ if (_videoMode.activeFullscreenMode == -1) {
+ const SDL_Rect *bestMode = availableModes[0];
+ int bestModeIndex = 0;
+ uint bestMetric = (uint)-1;
- uint metric = mode->w * mode->h - _videoMode.hardwareWidth * _videoMode.hardwareHeight;
- if (metric > bestMetric)
- continue;
+ // 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;
- bestMode = mode;
- bestMetric = metric;
- }
+ uint metric = mode->w * mode->h - _videoMode.hardwareWidth * _videoMode.hardwareHeight;
+ if (metric > bestMetric)
+ continue;
- if (bestMode) {
- // If there is a suiting mode, use it
- _videoMode.hardwareWidth = bestMode->w;
- _videoMode.hardwareHeight = bestMode->h;
+ 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)
+ if (!availableModes[_videoMode.activeFullscreenMode])
+ _videoMode.activeFullscreenMode = 0;
+
+ if (availableModes[_videoMode.activeFullscreenMode]) {
+ _videoMode.hardwareWidth = availableModes[_videoMode.activeFullscreenMode]->w;
+ _videoMode.hardwareHeight = availableModes[_videoMode.activeFullscreenMode]->h;
+ } else {
return false;
-
- _videoMode.fullscreen = false;
+ }
}
}
@@ -249,16 +270,11 @@
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 @@
}
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 @@
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,10 +385,18 @@
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;
+ }
+
// Alt-S: Create a screenshot
if (event.kbd.hasFlags(Common::KBD_ALT) && event.kbd.keycode == 's') {
char filename[20];
@@ -381,7 +418,7 @@
}
// 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;
}
Modified: scummvm/branches/gsoc2010-opengl/backends/graphics/openglsdl/openglsdl-graphics.h
===================================================================
--- scummvm/branches/gsoc2010-opengl/backends/graphics/openglsdl/openglsdl-graphics.h 2010-07-27 06:27:45 UTC (rev 51345)
+++ scummvm/branches/gsoc2010-opengl/backends/graphics/openglsdl/openglsdl-graphics.h 2010-07-27 07:30:56 UTC (rev 51346)
@@ -63,7 +63,7 @@
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;
Modified: scummvm/branches/gsoc2010-opengl/backends/graphics/sdl/sdl-graphics.cpp
===================================================================
--- scummvm/branches/gsoc2010-opengl/backends/graphics/sdl/sdl-graphics.cpp 2010-07-27 06:27:45 UTC (rev 51345)
+++ scummvm/branches/gsoc2010-opengl/backends/graphics/sdl/sdl-graphics.cpp 2010-07-27 07:30:56 UTC (rev 51346)
@@ -2153,7 +2153,7 @@
}
// 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;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list