[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