changeset 642:6e2151325017

* Added the ability to query the current running screen mode * Added a method to detect the closest supported screen mode (not complete yet). If no matching screen modes are detected an exception is thrown. * Small change to the way the screen is initialized. The screen mode now MUST be in the supported screen mode list before the screen will initialize.
author prock@33b003aa-7bff-0310-803a-e67f0ece8222
date Fri, 08 Oct 2010 21:22:02 +0000
parents 52708806f35c
children edf6dcfe8cd4
files engine/core/controller/engine.cpp engine/core/controller/engine.h engine/core/controller/engine.i engine/core/video/devicecaps.cpp engine/core/video/devicecaps.h engine/core/video/opengl/renderbackendopengl.cpp engine/core/video/opengl/renderbackendopengl.h engine/core/video/renderbackend.cpp engine/core/video/renderbackend.h engine/core/video/sdl/renderbackendsdl.cpp engine/core/video/sdl/renderbackendsdl.h engine/core/video/video.i
diffstat 12 files changed, 144 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/engine/core/controller/engine.cpp	Thu Oct 07 19:39:58 2010 +0000
+++ b/engine/core/controller/engine.cpp	Fri Oct 08 21:22:02 2010 +0000
@@ -125,10 +125,14 @@
 		return m_settings;
 	}
 
-	DeviceCaps& Engine::getDeviceCaps() {
+	const DeviceCaps& Engine::getDeviceCaps() const {
 		return m_devcaps;
 	}
 
+	const ScreenMode& Engine::getCurrentScreenMode() const{
+		return m_screenMode;
+	}
+
 	void Engine::preInit() {
 		m_logmanager = LogManager::instance();
 
@@ -200,12 +204,18 @@
 		FL_LOG(_log, "Querying device capabilities");
 		m_devcaps.fillDeviceCaps();
 
+		uint32_t bpp = m_settings.getBitsPerPixel();
+
+		m_screenMode = m_devcaps.getNearestScreenMode(
+			m_settings.getScreenWidth(),
+			m_settings.getScreenHeight(),
+			(bpp ? bpp : 32) , //if it's 0 we use 32 bit as a default
+			rbackend,
+			m_settings.isFullScreen());
+
 		FL_LOG(_log, "Creating main screen");
 		m_renderbackend->createMainScreen(
-			m_settings.getScreenWidth(),
-			m_settings.getScreenHeight(),
-			static_cast<unsigned char>(m_settings.getBitsPerPixel()),
-			m_settings.isFullScreen(),
+			m_screenMode,
 			m_settings.getWindowTitle(),
 			m_settings.getWindowIcon());
 		FL_LOG(_log, "Main screen created");
--- a/engine/core/controller/engine.h	Thu Oct 07 19:39:58 2010 +0000
+++ b/engine/core/controller/engine.h	Fri Oct 08 21:22:02 2010 +0000
@@ -86,7 +86,11 @@
 
 		/** Gets device capabilities
 		 */
-		DeviceCaps& getDeviceCaps();
+		const DeviceCaps& getDeviceCaps() const;
+
+		/** Get current video mode
+		 */
+		const ScreenMode& getCurrentScreenMode() const;
 
 		/** Initializes the engine
 		 */
@@ -185,6 +189,8 @@
 		EngineSettings m_settings;
 		DeviceCaps m_devcaps;
 
+		ScreenMode m_screenMode;
+
 		std::vector<RendererBase*> m_renderers;
 
 #ifdef USE_COCOA
--- a/engine/core/controller/engine.i	Thu Oct 07 19:39:58 2010 +0000
+++ b/engine/core/controller/engine.i	Fri Oct 08 21:22:02 2010 +0000
@@ -40,6 +40,7 @@
 	class Cursor;
 	class RendererBase;
 	class DeviceCaps;
+	class ScreenMode;
 
 	class EngineSettings {
 	public:
@@ -93,7 +94,8 @@
 		void pump();
 
 		EngineSettings& getSettings();
-		DeviceCaps& getDeviceCaps();
+		const DeviceCaps& getDeviceCaps() const;
+		const ScreenMode& getCurrentScreenMode() const;
 		
 		void init();
 		void destroy();
--- a/engine/core/video/devicecaps.cpp	Thu Oct 07 19:39:58 2010 +0000
+++ b/engine/core/video/devicecaps.cpp	Fri Oct 08 21:22:02 2010 +0000
@@ -30,6 +30,8 @@
 // These includes are split up in two parts, separated by one empty line
 // First block: files included from the FIFE root src directory
 // Second block: files included from the same folder
+#include "util/base/exception.h"
+
 #include "devicecaps.h"
 
 namespace FIFE {
@@ -127,21 +129,21 @@
 		Uint32 flags[numFlags];
 
 		//OpenGL, windowed, hw accel
-		flags[0] = SDL_OPENGL | SDL_HWPALETTE | SDL_HWACCEL;
+		flags[0] = ScreenMode::HW_WINDOWED_OPENGL;
 		//OpenGL, fullscree, hw accel
-		flags[1] = SDL_OPENGL | SDL_HWPALETTE | SDL_HWACCEL | SDL_FULLSCREEN;
+		flags[1] = ScreenMode::HW_FULLSCREEN_OPENGL;
 		//SDL, windowed
-		flags[2] = 0;
+		flags[2] = ScreenMode::WINDOWED_SDL;
 		//SDL, fullscreen
-		flags[3] = SDL_FULLSCREEN;
+		flags[3] = ScreenMode::FULLSCREEN_SDL;
 #else
 		int numFlags = 2;
 		Uint32 flags[numFlags];
 
 		//SDL, windowed
-		flags[0] = 0;
+		flags[0] = ScreenMode::WINDOWED_SDL;
 		//SDL, fullscreen
-		flags[1] = SDL_FULLSCREEN;
+		flags[1] = ScreenMode::FULLSCREEN_SDL;
 #endif
 		//BITS PER PIXEL
 
@@ -195,4 +197,62 @@
 		m_videoMem = vInfo->video_mem;
 	}
 
+	ScreenMode DeviceCaps::getNearestScreenMode(uint32_t width, uint32_t height, uint32_t bpp, const std::string& renderer, bool fs) const {
+		ScreenMode mode;
+		bool foundMode = false;
+
+		bool widthCheck = false;
+		bool heightCheck = false;
+		bool bppCheck = false;
+		bool rendCheck = false;
+		bool fsCheck = false;
+
+
+		for (uint32_t i = 0; i < m_screenModes.size(); i++) {
+			if (m_screenModes[i].getWidth() == width) {
+				widthCheck = true;
+			}
+			if (m_screenModes[i].getHeight() == height) {
+				heightCheck = true;
+			}
+			if (m_screenModes[i].getBPP() == bpp) {
+				bppCheck = true;
+			}
+			if (m_screenModes[i].isFullScreen() == fs) {
+				fsCheck = true;
+			}
+
+			if ((m_screenModes[i].isOpenGL() && renderer == "OpenGL") || (!m_screenModes[i].isOpenGL() && renderer == "SDL")){
+				rendCheck = true;
+			}
+
+			//check for exact match
+			if (widthCheck && heightCheck && bppCheck && fsCheck && rendCheck) {
+				mode = m_screenModes[i];
+				foundMode = true;
+				break;
+			}
+
+			//@note When the width and height to 0 that means that all
+			//resolutions are supported
+			if (m_screenModes[i].getWidth() == 0 && m_screenModes[i].getHeight() == 0 && bppCheck && fsCheck && rendCheck) {
+				mode = ScreenMode(width, height, bpp, m_screenModes[i].getSDLFlags());
+				foundMode = true;
+				break;
+			}
+
+			widthCheck = false;
+			heightCheck = false;
+			bppCheck = false;
+			rendCheck = false;
+			fsCheck = false;
+		}
+
+		if (!foundMode) {
+			throw NotSupported("Could not find a maching screen mode for the values given!");
+		}
+
+		return mode;
+	}
+
 } //FIFE
--- a/engine/core/video/devicecaps.h	Thu Oct 07 19:39:58 2010 +0000
+++ b/engine/core/video/devicecaps.h	Fri Oct 08 21:22:02 2010 +0000
@@ -37,7 +37,6 @@
 
 namespace FIFE {
 
-
 	class ScreenMode {
 	public:
 		/** Default Constructor
@@ -80,6 +79,16 @@
 		 */
 		bool isOpenGL() const { return (m_SDLFlags & SDL_OPENGL) ? true : false; };
 
+
+		//OpenGL, windowed, hw accel
+		static const uint32_t HW_WINDOWED_OPENGL = SDL_OPENGL | SDL_HWPALETTE | SDL_HWACCEL;
+		//OpenGL, fullscreen, hw accel
+		static const uint32_t HW_FULLSCREEN_OPENGL = SDL_OPENGL | SDL_HWPALETTE | SDL_HWACCEL | SDL_FULLSCREEN;
+		//SDL, windowed
+		static const uint32_t WINDOWED_SDL = 0;
+		//SDL, fullscreen
+		static const uint32_t FULLSCREEN_SDL = SDL_FULLSCREEN;
+
 	private:
 		uint16_t m_width;
 		uint16_t m_height;
@@ -114,6 +123,10 @@
 		 */
 		std::vector<ScreenMode> getSupportedScreenModes() const { return m_screenModes; };
 
+		/** Gets the nearest valid screen mode based on the arguments passed
+		 */
+		ScreenMode getNearestScreenMode(uint32_t width, uint32_t height, uint32_t bpp, const std::string& renderer, bool fs) const;
+
 		/** Returns the name of the current video driver.
 		 */
 		std::string getDriverName() const { return m_driverName; };
@@ -179,6 +192,8 @@
 		 */
 		void fillAvailableDrivers();
 	}; //DeviceCaps
-}
+} //FIFE
+
+
 
 #endif //FIFE_DEVICECAPS_H
--- a/engine/core/video/opengl/renderbackendopengl.cpp	Thu Oct 07 19:39:58 2010 +0000
+++ b/engine/core/video/opengl/renderbackendopengl.cpp	Fri Oct 08 21:22:02 2010 +0000
@@ -28,6 +28,8 @@
 
 // FIFE includes
 #include "util/base/exception.h"
+#include "util/log/logger.h"
+#include "video/devicecaps.h"
 
 #include "fife_opengl.h"
 #include "glimage.h"
@@ -35,6 +37,7 @@
 #include "SDL_image.h"
 
 namespace FIFE {
+	static Logger _log(LM_VIDEO);
 
 	RenderBackendOpenGL::RenderBackendOpenGL(const SDL_Color& colorkey) : RenderBackend(colorkey) {
 		// Get the pixelformat we want.
@@ -72,15 +75,16 @@
 		glClear(GL_COLOR_BUFFER_BIT);
 	}
 
-	Image* RenderBackendOpenGL::createMainScreen(unsigned int width, unsigned int height, unsigned char bitsPerPixel, bool fs, const std::string& title, const std::string& icon) {
+	Image* RenderBackendOpenGL::createMainScreen(const ScreenMode& mode, const std::string& title, const std::string& icon){
+		unsigned int width = mode.getWidth();
+		unsigned int height = mode.getHeight();
+		unsigned char bitsPerPixel = mode.getBPP();
+		bool fs = mode.isFullScreen();
+		Uint32 flags = mode.getSDLFlags();
+
 		delete m_screen;
 		m_screen = 0;
 
-		Uint32 flags = SDL_OPENGL | SDL_HWPALETTE | SDL_HWACCEL;
-		if ( fs ) {
-			flags |= SDL_FULLSCREEN;
-		}
-
 		if(icon != "") {
 			SDL_Surface *img = IMG_Load(icon.c_str());
 			if(img != NULL) {
@@ -115,6 +119,10 @@
 			screen = SDL_SetVideoMode(width, height, bitsPerPixel, flags);
 		}
 
+		FL_LOG(_log, LMsg("RenderBackendOpenGL")
+			<< "Videomode " << width << "x" << height
+			<< " at " << int(bitsPerPixel) << " bpp");
+
 		SDL_WM_SetCaption(title.c_str(), 0);
 
 		if (!screen) {
--- a/engine/core/video/opengl/renderbackendopengl.h	Thu Oct 07 19:39:58 2010 +0000
+++ b/engine/core/video/opengl/renderbackendopengl.h	Fri Oct 08 21:22:02 2010 +0000
@@ -34,6 +34,8 @@
 
 namespace FIFE {
 
+	class ScreenMode;
+
 	/** The main class of the OpenGL-based renderer.
 	 * @see RenderBackend
 	 */
@@ -47,7 +49,7 @@
 		void init(const std::string& driver);
 		void clearBackBuffer();
 
-		Image* createMainScreen(unsigned int width, unsigned int height, unsigned char bitsPerPixel, bool fullscreen, const std::string& title, const std::string& icon);
+		Image* createMainScreen(const ScreenMode& mode, const std::string& title, const std::string& icon);
 		Image* createImage(const uint8_t* data, unsigned int width, unsigned int height);
 		Image* createImage(SDL_Surface* surface);
  		bool putPixel(int x, int y, int r, int g, int b, int a = 255);
--- a/engine/core/video/renderbackend.cpp	Thu Oct 07 19:39:58 2010 +0000
+++ b/engine/core/video/renderbackend.cpp	Fri Oct 08 21:22:02 2010 +0000
@@ -45,12 +45,6 @@
 	RenderBackend::~RenderBackend() {
 	}
 
-	Image* RenderBackend::createMainScreen(const ScreenMode& mode, const std::string& title, const std::string& icon)
-	{
-		bool fs = (mode.getSDLFlags() & SDL_FULLSCREEN) ? true : false;
-		return createMainScreen(mode.getWidth(), mode.getHeight(), mode.getBPP(), fs, title, icon);
-	}
-
 	void RenderBackend::deinit() {
 		delete m_screen;
 		m_screen = NULL;
--- a/engine/core/video/renderbackend.h	Thu Oct 07 19:39:58 2010 +0000
+++ b/engine/core/video/renderbackend.h	Fri Oct 08 21:22:02 2010 +0000
@@ -85,15 +85,12 @@
 		virtual void deinit();
 
 		/** Creates the mainscreen (the display window).
-		 * @param width Width of the window.
-		 * @param height Height of the window.
-		 * @param bitsPerPixel Bits per pixel, 0 means autodetect.
-		 * @param fullscreen Use fullscreen mode?
+		 * @param mode The ScreenMode to use.  @see FIFE::ScreenMode.
+		 * @param tite The window title to use.
+		 * @param icon The window icon to use.
 		 * @return The new Screen Image
 		 */
-		virtual Image* createMainScreen(unsigned int width, unsigned int height, unsigned char bitsPerPixel, bool fullscreen, const std::string& title, const std::string& icon) = 0;
-
-		Image* createMainScreen(const ScreenMode& mode, const std::string& title, const std::string& icon);
+		virtual Image* createMainScreen(const ScreenMode& mode, const std::string& title, const std::string& icon) = 0;
 
 		/** Creates an Image suitable for this renderbackend.
 		 * @param data Pointer to the imagedata (needs to be in RGBA, 8 bits per channel).
--- a/engine/core/video/sdl/renderbackendsdl.cpp	Thu Oct 07 19:39:58 2010 +0000
+++ b/engine/core/video/sdl/renderbackendsdl.cpp	Fri Oct 08 21:22:02 2010 +0000
@@ -31,6 +31,7 @@
 #include "util/base/exception.h"
 #include "util/math/fife_math.h"
 #include "util/log/logger.h"
+#include "video/devicecaps.h"
 
 #include "renderbackendsdl.h"
 #include "sdlimage.h"
@@ -78,11 +79,12 @@
 		SDL_FillRect(m_screen->getSurface(), 0, 0x00);
 	}
 
-	Image* RenderBackendSDL::createMainScreen(unsigned int width, unsigned int height, unsigned char bitsPerPixel, bool fs, const std::string& title, const std::string& icon) {
-		Uint32 flags = 0;
-		if (fs) {
-			flags |= SDL_FULLSCREEN;
-		}
+	Image* RenderBackendSDL::createMainScreen(const ScreenMode& mode, const std::string& title, const std::string& icon){
+		unsigned int width = mode.getWidth();
+		unsigned int height = mode.getHeight();
+		unsigned char bitsPerPixel = mode.getBPP();
+		bool fs = mode.isFullScreen();
+		Uint32 flags = mode.getSDLFlags();
 
 		if(icon != "") {
 			SDL_Surface *img = IMG_Load(icon.c_str());
--- a/engine/core/video/sdl/renderbackendsdl.h	Thu Oct 07 19:39:58 2010 +0000
+++ b/engine/core/video/sdl/renderbackendsdl.h	Fri Oct 08 21:22:02 2010 +0000
@@ -34,6 +34,8 @@
 
 namespace FIFE {
 
+	class ScreenMode;
+
 	/** The main class of the SDL-based renderer.
 	 *
 	 * @see RenderBackend
@@ -49,7 +51,7 @@
 		void init(const std::string& driver);
 		void clearBackBuffer();
 
-		Image* createMainScreen(unsigned int width, unsigned int height, unsigned char bitsPerPixel, bool fullscreen, const std::string& title, const std::string& icon);
+		Image* createMainScreen(const ScreenMode& mode, const std::string& title, const std::string& icon);
 		Image* createImage(const uint8_t* data, unsigned int width, unsigned int height);
 		Image* createImage(SDL_Surface* surface);
  		bool putPixel(int x, int y, int r, int g, int b, int a = 255);
--- a/engine/core/video/video.i	Thu Oct 07 19:39:58 2010 +0000
+++ b/engine/core/video/video.i	Fri Oct 08 21:22:02 2010 +0000
@@ -239,6 +239,11 @@
 		uint32_t getSDLFlags() const;
 		bool isFullScreen();
 		bool isOpenGL();
+		
+		static const uint32_t HW_WINDOWED_OPENGL;
+		static const uint32_t HW_FULLSCREEN_OPENGL;
+		static const uint32_t WINDOWED_SDL;
+		static const uint32_t FULLSCREEN_SDL;
 	};
 
 	class DeviceCaps {