- allow changes to video resolution and fullscreen mode without restart

This commit is contained in:
Mark Vejvoda 2013-01-01 02:24:23 +00:00
parent 5643cc67a4
commit 9275debe2d
10 changed files with 171 additions and 33 deletions

View File

@ -24,6 +24,15 @@ namespace Glest{ namespace Game{
// ===================================================== // =====================================================
Metrics::Metrics() { Metrics::Metrics() {
reloadData();
}
void Metrics::reload() {
Metrics *metrics = getInstancePtr();
metrics->reloadData();
}
void Metrics::reloadData() {
Config &config = Config::getInstance(); Config &config = Config::getInstance();
virtualW= 1000; virtualW= 1000;
@ -43,9 +52,14 @@ Metrics::Metrics() {
displayH= 480; displayH= 480;
} }
Metrics * Metrics::getInstancePtr() {
static Metrics metrics;
return &metrics;
}
const Metrics &Metrics::getInstance(){ const Metrics &Metrics::getInstance(){
static const Metrics metrics; Metrics *metrics = getInstancePtr();
return metrics; return *metrics;
} }
float Metrics::getAspectRatio() const{ float Metrics::getAspectRatio() const{

View File

@ -43,6 +43,8 @@ private:
private: private:
Metrics(); Metrics();
static Metrics *getInstancePtr();
void reloadData();
public: public:
static const Metrics &getInstance(); static const Metrics &getInstance();
@ -66,6 +68,8 @@ public:
bool isInDisplay(int x, int y) const; bool isInDisplay(int x, int y) const;
bool isInMinimap(int x, int y) const; bool isInMinimap(int x, int y) const;
static void reload();
}; };
}}//end namespace }}//end namespace

View File

@ -785,15 +785,8 @@ void Program::setDisplaySettings(){
config.setInt("ScreenWidth",screenWidth); config.setInt("ScreenWidth",screenWidth);
config.setInt("ScreenHeight",screenHeight); config.setInt("ScreenHeight",screenHeight);
} }
if(!(changeVideoMode(screenWidth, screenHeight, colorBits, freq) ||
changeVideoMode(screenWidth, screenHeight, colorBits, 0)))
{
throw megaglest_runtime_error(
"Error setting video mode: " +
intToStr(screenWidth) + "x" + intToStr(screenHeight) + "x" + intToStr(colorBits));
}
} }
changeVideoModeFullScreen(!config.getBool("Windowed"));
} }
void Program::restoreDisplaySettings(){ void Program::restoreDisplaySettings(){

View File

@ -22,6 +22,7 @@
#include "menu_state_graphic_info.h" #include "menu_state_graphic_info.h"
#include "menu_state_keysetup.h" #include "menu_state_keysetup.h"
#include "string_utils.h" #include "string_utils.h"
#include "metrics.h"
#include "leak_dumper.h" #include "leak_dumper.h"
using namespace Shared::Util; using namespace Shared::Util;
@ -859,21 +860,19 @@ void MenuStateOptions::mouseClick(int x, int y, MouseButton mouseButton){
CoreData &coreData= CoreData::getInstance(); CoreData &coreData= CoreData::getInstance();
SoundRenderer &soundRenderer= SoundRenderer::getInstance(); SoundRenderer &soundRenderer= SoundRenderer::getInstance();
if(mainMessageBox.getEnabled()){ if(mainMessageBox.getEnabled()) {
int button= 0; int button= 0;
if(mainMessageBox.mouseClick(x, y, button)) if(mainMessageBox.mouseClick(x, y, button)) {
{
soundRenderer.playFx(coreData.getClickSoundA()); soundRenderer.playFx(coreData.getClickSoundA());
if(button==0) if(button==0) {
{ if(mainMessageBoxState==1) {
if(mainMessageBoxState==1)
{
mainMessageBox.setEnabled(false); mainMessageBox.setEnabled(false);
saveConfig(); saveConfig();
mainMenu->setState(new MenuStateRoot(program, mainMenu)); mainMenu->setState(new MenuStateRoot(program, mainMenu));
} }
else else {
mainMessageBox.setEnabled(false); mainMessageBox.setEnabled(false);
}
} }
} }
} }
@ -904,15 +903,15 @@ void MenuStateOptions::mouseClick(int x, int y, MouseButton mouseButton){
string currentResolution=config.getString("ScreenWidth")+"x"+config.getString("ScreenHeight")+"-"+intToStr(config.getInt("ColorBits")); string currentResolution=config.getString("ScreenWidth")+"x"+config.getString("ScreenHeight")+"-"+intToStr(config.getInt("ColorBits"));
string selectedResolution=listBoxScreenModes.getSelectedItem(); string selectedResolution=listBoxScreenModes.getSelectedItem();
if(currentResolution!=selectedResolution){ if(currentResolution != selectedResolution){
mainMessageBoxState=1; //mainMessageBoxState=1;
Lang &lang= Lang::getInstance(); //Lang &lang= Lang::getInstance();
showMessageBox(lang.get("RestartNeeded"), lang.get("ResolutionChanged"), false); //showMessageBox(lang.get("RestartNeeded"), lang.get("ResolutionChanged"), false);
return; //return;
} }
string currentFontSizeAdjustment=config.getString("FontSizeAdjustment"); string currentFontSizeAdjustment=config.getString("FontSizeAdjustment");
string selectedFontSizeAdjustment=listFontSizeAdjustment.getSelectedItem(); string selectedFontSizeAdjustment=listFontSizeAdjustment.getSelectedItem();
if(currentFontSizeAdjustment!=selectedFontSizeAdjustment){ if(currentFontSizeAdjustment != selectedFontSizeAdjustment){
mainMessageBoxState=1; mainMessageBoxState=1;
Lang &lang= Lang::getInstance(); Lang &lang= Lang::getInstance();
showMessageBox(lang.get("RestartNeeded"), lang.get("FontSizeAdjustmentChanged"), false); showMessageBox(lang.get("RestartNeeded"), lang.get("FontSizeAdjustmentChanged"), false);
@ -921,14 +920,35 @@ void MenuStateOptions::mouseClick(int x, int y, MouseButton mouseButton){
bool currentFullscreenWindowed=config.getBool("Windowed"); bool currentFullscreenWindowed=config.getBool("Windowed");
bool selectedFullscreenWindowed = checkBoxFullscreenWindowed.getValue(); bool selectedFullscreenWindowed = checkBoxFullscreenWindowed.getValue();
if(currentFullscreenWindowed!=selectedFullscreenWindowed){ if(currentFullscreenWindowed != selectedFullscreenWindowed) {
mainMessageBoxState=1; //mainMessageBoxState=1;
Lang &lang= Lang::getInstance(); //Lang &lang= Lang::getInstance();
showMessageBox(lang.get("RestartNeeded"), lang.get("DisplaySettingsChanged"), false); //showMessageBox(lang.get("RestartNeeded"), lang.get("DisplaySettingsChanged"), false);
return; //return;
} }
saveConfig(); saveConfig();
if(currentResolution != selectedResolution ||
currentFullscreenWindowed != selectedFullscreenWindowed) {
changeVideoModeFullScreen(!config.getBool("Windowed"));
WindowGl *window = this->program->getWindow();
window->ChangeVideoMode(true,
config.getInt("ScreenWidth"),
config.getInt("ScreenHeight"),
!config.getBool("Windowed"),
config.getInt("ColorBits"),
config.getInt("DepthBits"),
config.getInt("StencilBits"),
config.getBool("HardwareAcceleration","false"),
config.getBool("FullScreenAntiAliasing","false"),
config.getFloat("GammaValue","0.0"));
Metrics::reload();
this->mainMenu->init();
}
mainMenu->setState(new MenuStateRoot(program, mainMenu)); mainMenu->setState(new MenuStateRoot(program, mainMenu));
return; return;
} }

View File

@ -213,7 +213,7 @@ string extractExtension(const string& filename);
void getFullscreenVideoModes(vector<ModeInfo> *modeinfos,bool isFullscreen); void getFullscreenVideoModes(vector<ModeInfo> *modeinfos,bool isFullscreen);
void getFullscreenVideoInfo(int &colorBits,int &screenWidth,int &screenHeight,bool isFullscreen); void getFullscreenVideoInfo(int &colorBits,int &screenWidth,int &screenHeight,bool isFullscreen);
bool changeVideoMode(int resH, int resW, int colorBits, int refreshFrequency); void changeVideoModeFullScreen(bool value);
void restoreVideoMode(bool exitingApp=false); void restoreVideoMode(bool exitingApp=false);
bool StartsWith(const std::string &str, const std::string &key); bool StartsWith(const std::string &str, const std::string &key);

View File

@ -143,6 +143,10 @@ public:
Window(); Window();
virtual ~Window(); virtual ~Window();
virtual bool ChangeVideoMode(bool preserveContext,int resWidth, int resHeight,
bool fullscreenWindow, int colorBits, int depthBits, int stencilBits,
bool hardware_acceleration, bool fullscreen_anti_aliasing,
float gammaValue) = 0;
//static void setMasterserverMode(bool value) { Window::masterserverMode = value;} //static void setMasterserverMode(bool value) { Window::masterserverMode = value;}
//static bool getMasterserverMode() { return Window::masterserverMode;} //static bool getMasterserverMode() { return Window::masterserverMode;}

View File

@ -35,6 +35,11 @@ public:
void makeCurrentGl(); void makeCurrentGl();
void swapBuffersGl(); void swapBuffersGl();
void setGamma(float gammaValue){context.setGammaValue(gammaValue);} void setGamma(float gammaValue){context.setGammaValue(gammaValue);}
virtual bool ChangeVideoMode(bool preserveContext, int resWidth, int resHeight,
bool fullscreenWindow, int colorBits, int depthBits, int stencilBits,
bool hardware_acceleration, bool fullscreen_anti_aliasing,
float gammaValue);
}; };
}}//end namespace }}//end namespace

View File

@ -1694,9 +1694,8 @@ void getFullscreenVideoModes(vector<ModeInfo> *modeinfos, bool isFullscreen) {
bool changeVideoMode(int resW, int resH, int colorBits, int ) { void changeVideoModeFullScreen(bool value) {
Private::shouldBeFullscreen = true; Private::shouldBeFullscreen = value;
return true;
} }
void restoreVideoMode(bool exitingApp) { void restoreVideoMode(bool exitingApp) {

View File

@ -105,6 +105,8 @@ void PlatformContextGl::init(int colorBits, int depthBits, int stencilBits,
// try different color bits // try different color bits
screen = SDL_SetVideoMode(resW, resH, i, flags); screen = SDL_SetVideoMode(resW, resH, i, flags);
if(screen != 0) { if(screen != 0) {
glViewport( 0, 0, resW, resH ) ;
break; break;
} }
} }
@ -116,6 +118,8 @@ void PlatformContextGl::init(int colorBits, int depthBits, int stencilBits,
if(screen != 0) { if(screen != 0) {
resW = 800; resW = 800;
resH = 600; resH = 600;
glViewport( 0, 0, resW, resH ) ;
break; break;
} }
} }
@ -127,6 +131,8 @@ void PlatformContextGl::init(int colorBits, int depthBits, int stencilBits,
if(screen != 0) { if(screen != 0) {
resW = 640; resW = 640;
resH = 480; resH = 480;
glViewport( 0, 0, resW, resH ) ;
break; break;
} }
} }
@ -136,6 +142,10 @@ void PlatformContextGl::init(int colorBits, int depthBits, int stencilBits,
throw std::runtime_error(msg.str()); throw std::runtime_error(msg.str());
} }
} }
else {
glViewport( 0, 0, resW, resH ) ;
//printf("Reset resolution to [%d] x [%d]\n",resW, resH);
}
#ifndef WIN32 #ifndef WIN32
string mg_icon_file = ""; string mg_icon_file = "";

View File

@ -12,9 +12,12 @@
#include "gl_wrap.h" #include "gl_wrap.h"
#include "graphics_interface.h" #include "graphics_interface.h"
#include "util.h"
#include "platform_util.h"
#include "leak_dumper.h" #include "leak_dumper.h"
using namespace Shared::Graphics; using namespace Shared::Graphics;
using namespace Shared::Util;
namespace Shared{ namespace Platform{ namespace Shared{ namespace Platform{
@ -44,4 +47,90 @@ void WindowGl::swapBuffersGl(){
context.swapBuffers(); context.swapBuffers();
} }
// changes display resolution at any time
bool WindowGl::ChangeVideoMode(bool preserveContext, int resWidth, int resHeight,
bool fullscreenWindow,
int colorBits, int depthBits, int stencilBits, bool hardware_acceleration,
bool fullscreen_anti_aliasing, float gammaValue) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d] preserveContext = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,preserveContext);
#ifdef WIN32
if(preserveContext == true) {
SDL_SysWMinfo info;
// get window handle from SDL
SDL_VERSION(&info.version);
if (SDL_GetWMInfo(&info) == -1) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s %d] SDL_GetWMInfo #1 failed\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
return false;
}
// get device context handle
HDC tempDC = GetDC( info.window );
// create temporary context
HGLRC tempRC = wglCreateContext( tempDC );
if (tempRC == NULL) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s %d] wglCreateContext failed\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
return false;
}
// share resources to temporary context
SetLastError(0);
if (!wglShareLists(info.hglrc, tempRC)) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s %d] wglShareLists #1 failed\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
return false;
}
}
#endif
// set video mode
//if (!SetVideoMode())
// return false;
// this->initGl(config.getInt("ColorBits"),
// config.getInt("DepthBits"),
// config.getInt("StencilBits"),
// config.getBool("HardwareAcceleration","false"),
// config.getBool("FullScreenAntiAliasing","false"),
// config.getFloat("GammaValue","0.0"));
this->setStyle(fullscreenWindow ? wsWindowedFixed: wsFullscreen);
this->setPos(0, 0);
this->setSize(resWidth, resHeight);
this->initGl(colorBits, depthBits, stencilBits,hardware_acceleration,
fullscreen_anti_aliasing,gammaValue);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
this->makeCurrentGl();
#ifdef WIN32
if(preserveContext == true) {
// previously used structure may possibly be invalid, to be sure we get it again
SDL_VERSION(&info.version);
if (SDL_GetWMInfo(&info) == -1) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s %d] SDL_GetWMInfo #2 failed\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
return false;
}
// share resources to new SDL-created context
if (!wglShareLists(tempRC, info.hglrc)) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s %d] wglShareLists #2 failed\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
return false;
}
// we no longer need our temporary context
if (!wglDeleteContext(tempRC)) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s %d] wglDeleteContext failed\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
return false;
}
}
#endif
// success
return true;
}
}}//end namespace }}//end namespace