void OpenGLSdlGraphicsManager::toggleFullScreen(int loop) {
	beginGFXTransaction();
		const bool isFullscreen = getFullscreenMode();

		if (isFullscreen && loop) {
			_activeFullscreenMode += loop;
			setFullscreenMode(true);
		} else {
			_activeFullscreenMode = -2;
			setFullscreenMode(!isFullscreen);
		}

		// HACK: We need to force a refresh here, since we change the
		// fullscreen mode.
		_transactionDetails.needRefresh = true;
	endGFXTransaction();

	// Ignore resize events for the next 10 frames
	_ignoreResizeFrames = 10;

#ifdef USE_OSD
	Common::String osdMessage;
	if (getFullscreenMode())
		osdMessage = Common::String::format("%s\n%d x %d",
			_("Fullscreen mode"),
			_hwscreen->w, _hwscreen->h
			);
	else
		osdMessage = Common::String::format("%s\n%d x %d",
			_("Windowed mode"),
			_hwscreen->w, _hwscreen->h
			);
	displayMessageOnOSD(osdMessage.c_str());
#endif
}
Example #2
0
void OpenGLSdlGraphicsManager::toggleFullScreen(int loop) {
	beginGFXTransaction();
		const bool isFullscreen = getFullscreenMode();

		if (isFullscreen && loop) {
			_activeFullscreenMode += loop;
			setFullscreenMode(true);
		} else {
			_activeFullscreenMode = -2;
			setFullscreenMode(!isFullscreen);
		}
	endGFXTransaction();

	// Ignore resize events for the next 10 frames
	_ignoreResizeFrames = 10;

#ifdef USE_OSD
	char buffer[128];
	if (getFullscreenMode())
		sprintf(buffer, "Fullscreen mode\n%d x %d",
			_hwscreen->w, _hwscreen->h
			);
	else
		sprintf(buffer, "Windowed mode\n%d x %d",
			_hwscreen->w, _hwscreen->h
			);
	displayMessageOnOSD(buffer);
#endif
}
void OpenGLSdlGraphicsManager::notifyResize(const uint width, const uint height) {
	// Do not resize if ignoring resize events.
	if (!_ignoreResizeFrames && !getFullscreenMode()) {
		bool scaleChanged = false;
		beginGFXTransaction();
			_videoMode.hardwareWidth = width;
			_videoMode.hardwareHeight = height;

			_screenResized = true;

			int scale = MIN(_videoMode.hardwareWidth / _videoMode.screenWidth,
			                _videoMode.hardwareHeight / _videoMode.screenHeight);

			if (getScale() != scale) {
				scaleChanged = true;
				setScale(MAX(MIN(scale, 3), 1));
			}

			_transactionDetails.sizeChanged = true;
		endGFXTransaction();
#ifdef USE_OSD
		if (scaleChanged)
			displayScaleChangedMsg();
#endif
	}
}
bool OpenGLSdlGraphicsManager::loadGFXMode() {
	// If the screen was resized, do not change its size
	if (!_screenResized) {
		const int scaleFactor = getScale();
		_videoMode.overlayWidth = _videoMode.hardwareWidth = _videoMode.screenWidth * scaleFactor;
		_videoMode.overlayHeight = _videoMode.hardwareHeight = _videoMode.screenHeight * scaleFactor;

		// The only modes where we need to adapt the aspect ratio are 320x200
		// and 640x400. That is since our aspect ratio correction in fact is
		// only used to ensure that the original pixel size aspect for these
		// modes is used.
		// (Non-square pixels on old monitors vs square pixel on new ones).
		if (_videoMode.aspectRatioCorrection
		    && ((_videoMode.screenWidth == 320 && _videoMode.screenHeight == 200)
		    || (_videoMode.screenWidth == 640 && _videoMode.screenHeight == 400)))
			_videoMode.overlayHeight = _videoMode.hardwareHeight = 240 * scaleFactor;
		else
			_videoMode.overlayHeight = _videoMode.hardwareHeight = _videoMode.screenHeight * scaleFactor;
	}

	_screenResized = false;

	// Setup OpenGL attributes for SDL
	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

	const bool isFullscreen = getFullscreenMode();

	// In case we have an fullscreen mode and we are not in a rollback, detect
	// a proper mode to use. In case we are in a rollback, we already detected
	// a proper mode when setting up that mode, thus there is no need to run
	// the detection again.
	if (isFullscreen && _transactionMode != kTransactionRollback) {
		if (!setupFullscreenMode())
			// Failed setuping a fullscreen mode
			return false;
	}

	_videoMode.overlayWidth = _videoMode.hardwareWidth;
	_videoMode.overlayHeight = _videoMode.hardwareHeight;

	uint32 flags = SDL_OPENGL;

	if (isFullscreen)
		flags |= SDL_FULLSCREEN;
	else
		flags |= SDL_RESIZABLE;

	// Create our window
	_hwscreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 32, flags);
#ifdef USE_RGB_COLOR
	detectSupportedFormats();
#endif

	if (_hwscreen == NULL) {
		// DON'T use error(), as this tries to bring up the debug
		// console, which WON'T WORK now that _hwscreen is hosed.

		if (!_oldVideoMode.setup) {
			warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError());
			g_system->quit();
		} else
			// Cancel GFX load, and go back to last mode
			return false;
	}

	// Check if the screen is BGR format
	_formatBGR = _hwscreen->format->Rshift != 0;

	if (isFullscreen) {
		_lastFullscreenModeWidth = _videoMode.hardwareWidth;
		_lastFullscreenModeHeight = _videoMode.hardwareHeight;
		ConfMan.setInt("last_fullscreen_mode_width", _lastFullscreenModeWidth);
		ConfMan.setInt("last_fullscreen_mode_height", _lastFullscreenModeHeight);
	}

	// Call and return parent implementation of this method
	return OpenGLGraphicsManager::loadGFXMode();
}
Example #5
0
bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
	switch ((int)event.type) {
	case Common::EVENT_KEYDOWN:
		if (event.kbd.hasFlags(Common::KBD_ALT)) {
			// Alt-Return and Alt-Enter toggle full screen mode
			if (event.kbd.keycode == Common::KEYCODE_RETURN ||
				event.kbd.keycode == (Common::KeyCode)SDLK_KP_ENTER) {
				toggleFullScreen(0);
				return true;
			}

			// Alt-S create a screenshot
			if (event.kbd.keycode == 's') {
				char filename[20];

				for (int n = 0;; n++) {
					SDL_RWops *file;

					sprintf(filename, "scummvm%05d.bmp", n);
					file = SDL_RWFromFile(filename, "r");
					if (!file)
						break;
					SDL_RWclose(file);
				}
				if (saveScreenshot(filename))
					debug("Saved screenshot '%s'", filename);
				else
					warning("Could not save screenshot");
				return true;
			}
		}

		if (event.kbd.hasFlags(Common::KBD_CTRL|Common::KBD_ALT)) {
			// Ctrl-Alt-Return and Ctrl-Alt-Enter switch between full screen modes
			if (event.kbd.keycode == Common::KEYCODE_RETURN ||
				event.kbd.keycode == (Common::KeyCode)SDLK_KP_ENTER) {
				toggleFullScreen(1);
				return true;
			}

			// Ctrl-Alt-a switch between display modes
			if (event.kbd.keycode == 'a') {
				beginGFXTransaction();
					setFeatureState(OSystem::kFeatureAspectRatioCorrection, !getFeatureState(OSystem::kFeatureAspectRatioCorrection));
				endGFXTransaction();
#ifdef USE_OSD
			char buffer[128];
			if (getFeatureState(OSystem::kFeatureAspectRatioCorrection))
				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);
			displayMessageOnOSD(buffer);
#endif
				internUpdateScreen();
				return true;
			}

			// Ctrl-Alt-f toggles antialiasing
			if (event.kbd.keycode == 'f') {
				beginGFXTransaction();
					toggleAntialiasing();
				endGFXTransaction();

#ifdef USE_OSD
				// TODO: This makes guesses about what internal antialiasing
				// modes we use, we might want to consider a better way of
				// displaying information to the user.
				if (getAntialiasingState())
					displayMessageOnOSD("Active filter mode: Linear");
				else
					displayMessageOnOSD("Active filter mode: Nearest");
#endif
				return true;
			}

			SDLKey sdlKey = (SDLKey)event.kbd.keycode;

			// Ctrl+Alt+Plus/Minus Increase/decrease the scale factor
			if ((sdlKey == SDLK_EQUALS || sdlKey == SDLK_PLUS || sdlKey == SDLK_MINUS ||
				sdlKey == SDLK_KP_PLUS || sdlKey == SDLK_KP_MINUS)) {
				int factor = getScale();
				factor += (sdlKey == SDLK_MINUS || sdlKey == SDLK_KP_MINUS) ? -1 : +1;
				if (0 < factor && factor < 4) {
					// Check if the desktop resolution has been detected
					if (_desktopWidth > 0 && _desktopHeight > 0)
						// If the new scale factor is too big, do not scale
						if (_videoMode.screenWidth * factor > _desktopWidth || 
							_videoMode.screenHeight * factor > _desktopHeight)
							return false;

					beginGFXTransaction();
						setScale(factor);
					endGFXTransaction();
#ifdef USE_OSD
					displayScaleChangedMsg();
#endif
					return true;
				}
			}

			const bool isNormalNumber = (SDLK_1 <= sdlKey && sdlKey <= SDLK_3);
			const bool isKeypadNumber = (SDLK_KP1 <= sdlKey && sdlKey <= SDLK_KP3);

			// Ctrl-Alt-<number key> will change the GFX mode
			if (isNormalNumber || isKeypadNumber) {
				if (sdlKey - (isNormalNumber ? SDLK_1 : SDLK_KP1) <= 3) {
#ifdef USE_OSD
					int lastMode = _videoMode.mode;
#endif
					// We need to query the scale and set it up, because
					// setGraphicsMode sets the default scale to 2
					int oldScale = getScale();
					beginGFXTransaction();
						setGraphicsMode(sdlKey - (isNormalNumber ? SDLK_1 : SDLK_KP1));
						setScale(oldScale);
					endGFXTransaction();
#ifdef USE_OSD
					if (lastMode != _videoMode.mode)
						displayModeChangedMsg();
#endif
					internUpdateScreen();
				}
			}
		}

		if (event.kbd.hasFlags(Common::KBD_CTRL|Common::KBD_SHIFT)) {
			// Ctrl-Shift-Return and Ctrl-Shift-Enter switch backwards between full screen modes
			if (event.kbd.keycode == Common::KEYCODE_RETURN ||
				event.kbd.keycode == (Common::KeyCode)SDLK_KP_ENTER) {
				toggleFullScreen(-1);
				return true;
			}
		}
		break;
	case Common::EVENT_KEYUP:
		return isHotkey(event);
	// HACK: Handle special SDL event 
	// The new screen size is saved on the mouse event as part of HACK,
	// there is no common resize event.
	case OSystem_SDL::kSdlEventResize:
		// Do not resize if ignoring resize events.
		if (!_ignoreResizeFrames && !getFullscreenMode()) {
			bool scaleChanged = false;
			beginGFXTransaction();
				_videoMode.hardwareWidth = event.mouse.x;
				_videoMode.hardwareHeight = event.mouse.y;

				if (_videoMode.mode != OpenGL::GFX_ORIGINAL) {
					_screenResized = true;
					calculateDisplaySize(_videoMode.hardwareWidth, _videoMode.hardwareHeight);
				}

				int scale = MIN(_videoMode.hardwareWidth / _videoMode.screenWidth,
				                _videoMode.hardwareHeight / _videoMode.screenHeight);

				if (getScale() != scale) {
					scaleChanged = true;
					setScale(MAX(MIN(scale, 3), 1));
				}

				if (_videoMode.mode == OpenGL::GFX_ORIGINAL) {
					calculateDisplaySize(_videoMode.hardwareWidth, _videoMode.hardwareHeight);
				}

				_transactionDetails.sizeChanged = true;
			endGFXTransaction();
#ifdef USE_OSD
			if (scaleChanged)
				displayScaleChangedMsg();
#endif
		}
		return true;

	default:
		break;
	}

	return OpenGLGraphicsManager::notifyEvent(event);
}
Example #6
0
bool OpenGLSdlGraphicsManager::loadGFXMode() {
	// If the screen was resized, do not change its size
	if (!_screenResized) {
		const int scaleFactor = getScale();
		_videoMode.overlayWidth = _videoMode.hardwareWidth = _videoMode.screenWidth * scaleFactor;
		_videoMode.overlayHeight = _videoMode.hardwareHeight = _videoMode.screenHeight * scaleFactor;

		int screenAspectRatio = _videoMode.screenWidth * 10000 / _videoMode.screenHeight;
		int desiredAspectRatio = getAspectRatio();
	
		// Do not downscale dimensions, only enlarge them if needed
		if (screenAspectRatio > desiredAspectRatio)
			_videoMode.hardwareHeight = (_videoMode.overlayWidth * 10000  + 5000) / desiredAspectRatio;
		else if (screenAspectRatio < desiredAspectRatio)
			_videoMode.hardwareWidth = (_videoMode.overlayHeight * desiredAspectRatio + 5000) / 10000;
	}

	_screenResized = false;

	// Setup OpenGL attributes for SDL
	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

	const bool isFullscreen = getFullscreenMode();

	// In case we have an fullscreen mode and we are not in a rollback, detect
	// a proper mode to use. In case we are in a rollback, we already detected
	// a proper mode when setting up that mode, thus there is no need to run
	// the detection again.
	if (isFullscreen && _transactionMode != kTransactionRollback) {
		if (!setupFullscreenMode())
			// Failed setuping a fullscreen mode
			return false;
	}

	_videoMode.overlayWidth = _videoMode.hardwareWidth;
	_videoMode.overlayHeight = _videoMode.hardwareHeight;

	uint32 flags = SDL_OPENGL;

	if (isFullscreen)
		flags |= SDL_FULLSCREEN;
	else
		flags |= SDL_RESIZABLE;

	// Create our window
	_hwscreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 32, flags);
#ifdef USE_RGB_COLOR
	detectSupportedFormats();
#endif

	if (_hwscreen == NULL) {
		// DON'T use error(), as this tries to bring up the debug
		// console, which WON'T WORK now that _hwscreen is hosed.

		if (!_oldVideoMode.setup) {
			warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError());
			g_system->quit();
		} else
			// Cancel GFX load, and go back to last mode
			return false;
	}

	// Check if the screen is BGR format
	_formatBGR = _hwscreen->format->Rshift != 0;

	if (isFullscreen) {
		_lastFullscreenModeWidth = _videoMode.hardwareWidth;
		_lastFullscreenModeHeight = _videoMode.hardwareHeight;
		ConfMan.setInt("last_fullscreen_mode_width", _lastFullscreenModeWidth);
		ConfMan.setInt("last_fullscreen_mode_height", _lastFullscreenModeHeight);
	}

	// Call and return parent implementation of this method
	return OpenGLGraphicsManager::loadGFXMode();
}