diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 0fc25db4c..6abd3c0c9 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -14,6 +14,7 @@ #include #include +#include #include "../engine.hpp" @@ -101,10 +102,13 @@ namespace MWInput OMW::Engine& engine, const std::string& userFile, bool userFileExists, const std::string& controllerBindingsFile, bool grab) - : mJoystickLastUsed(false) + : mWindow(window) + , mViewer(viewer) + , mJoystickLastUsed(false) , mPlayer(NULL) , mEngine(engine) , mInputManager(NULL) + , mVideoWrapper(NULL) , mUserFile(userFile) , mDragDrop(false) , mGrabCursor (Settings::Manager::getBool("grab cursor", "Input")) @@ -141,6 +145,10 @@ namespace MWInput mInputManager->setWindowEventCallback(this); mInputManager->setControllerEventCallback(this); + mVideoWrapper = new SDLUtil::VideoWrapper(window, viewer); + mVideoWrapper->setGammaContrast(Settings::Manager::getFloat("gamma", "Video"), + Settings::Manager::getFloat("contrast", "Video")); + std::string file = userFileExists ? userFile : ""; mInputBinder = new ICS::InputControlSystem(file, true, this, NULL, A_Last); @@ -201,6 +209,8 @@ namespace MWInput delete mInputBinder; delete mInputManager; + + delete mVideoWrapper; } void InputManager::setPlayerControlsEnabled(bool enabled) @@ -614,6 +624,8 @@ namespace MWInput void InputManager::processChangedSettings(const Settings::CategorySettingVector& changed) { + bool changeRes = false; + for (Settings::CategorySettingVector::const_iterator it = changed.begin(); it != changed.end(); ++it) { @@ -629,6 +641,27 @@ namespace MWInput if (it->first == "Input" && it->second == "grab cursor") mGrabCursor = Settings::Manager::getBool("grab cursor", "Input"); + if (it->first == "Video" && ( + it->second == "resolution x" + || it->second == "resolution y" + || it->second == "fullscreen" + || it->second == "window border")) + changeRes = true; + + if (it->first == "Video" && it->second == "vsync") + mVideoWrapper->setSyncToVBlank(Settings::Manager::getBool("vsync", "Video")); + + if (it->first == "Video" && (it->second == "gamma" || it->second == "contrast")) + mVideoWrapper->setGammaContrast(Settings::Manager::getFloat("gamma", "Video"), + Settings::Manager::getFloat("contrast", "Video")); + } + + if (changeRes) + { + mVideoWrapper->setVideoMode(Settings::Manager::getInt("resolution x", "Video"), + Settings::Manager::getInt("resolution y", "Video"), + Settings::Manager::getBool("fullscreen", "Video"), + Settings::Manager::getBool("window border", "Video")); } } diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 27c08ed32..6b636058f 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -48,6 +48,7 @@ namespace Files namespace SDLUtil { class InputWrapper; + class VideoWrapper; } namespace osgViewer @@ -151,6 +152,9 @@ namespace MWInput void clearAllControllerBindings (ICS::Control* control); private: + SDL_Window* mWindow; + osg::ref_ptr mViewer; + bool mJoystickLastUsed; MWWorld::Player* mPlayer; OMW::Engine& mEngine; @@ -158,6 +162,7 @@ namespace MWInput ICS::InputControlSystem* mInputBinder; SDLUtil::InputWrapper* mInputManager; + SDLUtil::VideoWrapper* mVideoWrapper; std::string mUserFile; diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 0c76f666b..b800da701 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -127,7 +127,7 @@ add_component_dir (fontloader ) add_component_dir (sdlutil - sdlgraphicswindow imagetosurface sdlinputwrapper OISCompat events sdlcursormanager + sdlgraphicswindow imagetosurface sdlinputwrapper sdlvideowrapper OISCompat events sdlcursormanager ) add_component_dir (version diff --git a/components/sdlutil/sdlvideowrapper.cpp b/components/sdlutil/sdlvideowrapper.cpp new file mode 100644 index 000000000..dd89d1072 --- /dev/null +++ b/components/sdlutil/sdlvideowrapper.cpp @@ -0,0 +1,94 @@ +#include "sdlvideowrapper.hpp" + +#include + +#include + +#include + +namespace SDLUtil +{ + + VideoWrapper::VideoWrapper(SDL_Window *window, osg::ref_ptr viewer) + : mWindow(window) + , mViewer(viewer) + , mGamma(1.f) + , mContrast(1.f) + , mHasSetGammaContrast(false) + { + SDL_GetWindowGammaRamp(mWindow, mOldSystemGammaRamp, &mOldSystemGammaRamp[256], &mOldSystemGammaRamp[512]); + } + + VideoWrapper::~VideoWrapper() + { + SDL_SetWindowFullscreen(mWindow, 0); + + // If user hasn't touched the defaults no need to restore + if (mHasSetGammaContrast) + SDL_SetWindowGammaRamp(mWindow, mOldSystemGammaRamp, &mOldSystemGammaRamp[256], &mOldSystemGammaRamp[512]); + } + + void VideoWrapper::setSyncToVBlank(bool sync) + { + osgViewer::Viewer::Windows windows; + mViewer->getWindows(windows); + mViewer->stopThreading(); + for (osgViewer::Viewer::Windows::iterator it = windows.begin(); it != windows.end(); ++it) + { + osgViewer::GraphicsWindow* win = *it; + win->setSyncToVBlank(sync); + } + mViewer->startThreading(); + } + + void VideoWrapper::setGammaContrast(float gamma, float contrast) + { + if (gamma == mGamma && contrast == mContrast) + return; + + mGamma = gamma; + mContrast = contrast; + + mHasSetGammaContrast = true; + + Uint16 red[256], green[256], blue[256]; + for (int i = 0; i < 256; i++) + { + float k = i/256.0f; + k = (k - 0.5f) * contrast + 0.5f; + k = pow(k, 1.f/gamma); + k *= 256; + float value = k*256; + if (value > 65535) value = 65535; + else if (value < 0) value = 0; + + red[i] = green[i] = blue[i] = static_cast(value); + } + if (SDL_SetWindowGammaRamp(mWindow, red, green, blue) < 0) + std::cout << "Couldn't set gamma: " << SDL_GetError() << std::endl; + } + + void VideoWrapper::setVideoMode(int width, int height, bool fullscreen, bool windowBorder) + { + SDL_SetWindowFullscreen(mWindow, 0); + + if (SDL_GetWindowFlags(mWindow) & SDL_WINDOW_MAXIMIZED) + SDL_RestoreWindow(mWindow); + + if (fullscreen) + { + SDL_DisplayMode mode; + SDL_GetWindowDisplayMode(mWindow, &mode); + mode.w = width; + mode.h = height; + SDL_SetWindowDisplayMode(mWindow, &mode); + SDL_SetWindowFullscreen(mWindow, fullscreen); + } + else + { + SDL_SetWindowSize(mWindow, width, height); + SDL_SetWindowBordered(mWindow, windowBorder ? SDL_TRUE : SDL_FALSE); + } + } + +} diff --git a/components/sdlutil/sdlvideowrapper.hpp b/components/sdlutil/sdlvideowrapper.hpp new file mode 100644 index 000000000..77f0b8039 --- /dev/null +++ b/components/sdlutil/sdlvideowrapper.hpp @@ -0,0 +1,44 @@ +#ifndef OPENMW_COMPONENTS_SDLUTIL_SDLVIDEOWRAPPER_H +#define OPENMW_COMPONENTS_SDLUTIL_SDLVIDEOWRAPPER_H + +#include + +#include + +struct SDL_Window; + +namespace osgViewer +{ + class Viewer; +} + +namespace SDLUtil +{ + + class VideoWrapper + { + public: + VideoWrapper(SDL_Window* window, osg::ref_ptr viewer); + ~VideoWrapper(); + + void setSyncToVBlank(bool sync); + + void setGammaContrast(float gamma, float contrast); + + void setVideoMode(int width, int height, bool fullscreen, bool windowBorder); + + private: + SDL_Window* mWindow; + osg::ref_ptr mViewer; + + float mGamma; + float mContrast; + bool mHasSetGammaContrast; + + // Store system gamma ramp on window creation. Restore system gamma ramp on exit + Uint16 mOldSystemGammaRamp[256*3]; + }; + +} + +#endif diff --git a/files/mygui/openmw_settings_window.layout b/files/mygui/openmw_settings_window.layout index 768652e1a..397a9df04 100644 --- a/files/mygui/openmw_settings_window.layout +++ b/files/mygui/openmw_settings_window.layout @@ -299,7 +299,7 @@ - + diff --git a/files/settings-default.cfg b/files/settings-default.cfg index eeea0e6e1..d28240f2c 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -26,6 +26,9 @@ vsync = false # PBuffer, FBO, Copy opengl rtt mode = FBO +gamma = 1.00 +contrast = 1.00 + [GUI] # 1 is fully opaque menu transparency = 0.84 @@ -43,8 +46,6 @@ stretch menu background = false [General] # Camera field of view field of view = 55 -gamma = 1.00 -contrast = 1.00 # Texture filtering mode. valid values: # none