forked from Mirrors/openclonk
Previously, the graphics code tried to set a refresh rate as close to 85 Hz as possible. This led to black screens when the display driver would report a refresh rate that was not actually supported by the monitor. This change also uses the currently set monitor orientation, instead of always selecting a non-rotated display mode. Conflicts: src/gui/C4StartupOptionsDlg.cppstable-5.1
parent
b3a34fea69
commit
e9d9e7c178
|
@ -178,7 +178,7 @@ bool C4Application::DoInit(int argc, char * argv[])
|
|||
|
||||
if (!isEditor)
|
||||
{
|
||||
if (!SetVideoMode(Config.Graphics.ResX, Config.Graphics.ResY, Config.Graphics.BitDepth, Config.Graphics.Monitor, !Config.Graphics.Windowed))
|
||||
if (!SetVideoMode(Config.Graphics.ResX, Config.Graphics.ResY, Config.Graphics.BitDepth, Config.Graphics.RefreshRate, Config.Graphics.Monitor, !Config.Graphics.Windowed))
|
||||
pWindow->SetSize(Config.Graphics.ResX, Config.Graphics.ResY);
|
||||
}
|
||||
|
||||
|
@ -428,13 +428,13 @@ void C4Application::ParseCommandLine(int argc, char * argv[])
|
|||
void C4Application::ApplyResolutionConstraints()
|
||||
{
|
||||
// Enumerate display modes
|
||||
int32_t idx = 0, iXRes, iYRes, iBitDepth;
|
||||
int32_t idx = 0, iXRes, iYRes, iBitDepth, iRefreshRate;
|
||||
int32_t best_match = -1;
|
||||
uint32_t best_delta = ~0;
|
||||
while (GetIndexedDisplayMode(idx++, &iXRes, &iYRes, &iBitDepth, Config.Graphics.Monitor))
|
||||
while (GetIndexedDisplayMode(idx++, &iXRes, &iYRes, &iBitDepth, &iRefreshRate, Config.Graphics.Monitor))
|
||||
{
|
||||
uint32_t delta = std::abs(Config.Graphics.ResX*Config.Graphics.ResY - iXRes*iYRes);
|
||||
if (!delta && iBitDepth == Config.Graphics.BitDepth)
|
||||
if (!delta && iBitDepth == Config.Graphics.BitDepth && iRefreshRate == Config.Graphics.RefreshRate)
|
||||
return; // Exactly the expected mode
|
||||
if (delta < best_delta)
|
||||
{
|
||||
|
@ -446,12 +446,14 @@ void C4Application::ApplyResolutionConstraints()
|
|||
if (best_match != -1)
|
||||
{
|
||||
// Apply next-best mode
|
||||
GetIndexedDisplayMode(best_match, &iXRes, &iYRes, &iBitDepth, Config.Graphics.Monitor);
|
||||
GetIndexedDisplayMode(best_match, &iXRes, &iYRes, &iBitDepth, &iRefreshRate, Config.Graphics.Monitor);
|
||||
if (iXRes != Config.Graphics.ResX || iYRes != Config.Graphics.ResY)
|
||||
// Don't warn if only bit depth changes
|
||||
// Also, lang table not loaded yet
|
||||
LogF("Warning: The selected resolution %dx%d is not available and has been changed to %dx%d.", Config.Graphics.ResX, Config.Graphics.ResY, iXRes, iYRes);
|
||||
Config.Graphics.ResX = iXRes; Config.Graphics.ResY = iYRes;
|
||||
Config.Graphics.BitDepth = iBitDepth;
|
||||
Config.Graphics.RefreshRate = iRefreshRate;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -118,6 +118,7 @@ void C4ConfigGraphics::CompileFunc(StdCompiler *pComp)
|
|||
{
|
||||
pComp->Value(mkNamingAdapt(ResX, "ResolutionX", 800 ,false, true));
|
||||
pComp->Value(mkNamingAdapt(ResY, "ResolutionY", 600 ,false, true));
|
||||
pComp->Value(mkNamingAdapt(RefreshRate, "RefreshRate", 0 ));
|
||||
pComp->Value(mkNamingAdapt(GuiResX, "GuiResolutionX", 800 ,false, true));
|
||||
pComp->Value(mkNamingAdapt(GuiResY, "GuiResolutionY", 600 ,false, true));
|
||||
pComp->Value(mkNamingAdapt(ShowAllResolutions, "ShowAllResolutions", 0 ,false, true));
|
||||
|
|
|
@ -118,6 +118,7 @@ public:
|
|||
int32_t UpperBoard;
|
||||
int32_t ShowClock;
|
||||
int32_t ResX,ResY;
|
||||
int32_t RefreshRate; // monitor vertical refresh rate
|
||||
int32_t GuiResX,GuiResY;
|
||||
int32_t Windowed;
|
||||
int32_t ShowAllResolutions;
|
||||
|
|
|
@ -1083,7 +1083,7 @@ void C4StartupOptionsDlg::OnGfxResComboFill(C4GUI::ComboBox_FillCB *pFiller)
|
|||
pFiller->ClearEntries();
|
||||
// fill with all possible resolutions
|
||||
int32_t idx = 0, iXRes, iYRes, iBitDepth;
|
||||
while (Application.GetIndexedDisplayMode(idx++, &iXRes, &iYRes, &iBitDepth, Config.Graphics.Monitor))
|
||||
while (Application.GetIndexedDisplayMode(idx++, &iXRes, &iYRes, &iBitDepth, NULL, Config.Graphics.Monitor))
|
||||
#ifdef _WIN32 // why only WIN32?
|
||||
if (iBitDepth == Config.Graphics.BitDepth)
|
||||
if ((iXRes <= 1024 && iXRes>=600 && iYRes>=460) || Config.Graphics.ShowAllResolutions)
|
||||
|
@ -1125,7 +1125,7 @@ bool C4StartupOptionsDlg::TryNewResolution(int32_t iResX, int32_t iResY)
|
|||
else
|
||||
iNewFontSize = 16;
|
||||
// call application to set it
|
||||
if (!Application.SetVideoMode(iResX, iResY,Config.Graphics.BitDepth, Config.Graphics.Monitor,!Config.Graphics.Windowed))
|
||||
if (!Application.SetVideoMode(iResX, iResY, Config.Graphics.BitDepth, Config.Graphics.RefreshRate, Config.Graphics.Monitor, !Config.Graphics.Windowed))
|
||||
{
|
||||
StdCopyStrBuf strChRes(LoadResStr("IDS_MNU_SWITCHRESOLUTION"));
|
||||
pScreen->ShowMessage(FormatString(LoadResStr("IDS_ERR_SWITCHRES"), Application.GetLastError()).getData(), strChRes.getData(), C4GUI::Ico_Clonk, NULL);
|
||||
|
@ -1151,13 +1151,10 @@ bool C4StartupOptionsDlg::TryNewResolution(int32_t iResX, int32_t iResY)
|
|||
if (!pScreen->ShowModalDlg(pConfirmDlg, true))
|
||||
{
|
||||
// abort: Restore screen, if this was not some program abort
|
||||
if (C4GUI::IsGUIValid())
|
||||
if (Application.SetVideoMode(iOldResX, iOldResY, Config.Graphics.BitDepth, Config.Graphics.RefreshRate, Config.Graphics.Monitor, !Config.Graphics.Windowed))
|
||||
{
|
||||
if (Application.SetVideoMode(iOldResX, iOldResY, Config.Graphics.BitDepth, Config.Graphics.Monitor,!Config.Graphics.Windowed))
|
||||
{
|
||||
if (iNewFontSize != iOldFontSize) Application.SetGameFont(Config.General.RXFontName, iOldFontSize);
|
||||
RecreateDialog(false);
|
||||
}
|
||||
if (iNewFontSize != iOldFontSize) Application.SetGameFont(Config.General.RXFontName, iOldFontSize);
|
||||
RecreateDialog(false);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -1200,7 +1197,7 @@ void C4StartupOptionsDlg::OnGfxClrDepthCheck(C4GUI::Element *pCheckBox)
|
|||
void C4StartupOptionsDlg::OnFullscreenChange(C4GUI::Element *pCheckBox)
|
||||
{
|
||||
Config.Graphics.Windowed = !static_cast<C4GUI::CheckBox *>(pCheckBox)->GetChecked();
|
||||
Application.SetVideoMode(Config.Graphics.ResX, Config.Graphics.ResY, Config.Graphics.BitDepth, Config.Graphics.Monitor, !Config.Graphics.Windowed);
|
||||
Application.SetVideoMode(Config.Graphics.ResX, Config.Graphics.ResY, Config.Graphics.BitDepth, Config.Graphics.RefreshRate, Config.Graphics.Monitor, !Config.Graphics.Windowed);
|
||||
}
|
||||
|
||||
void C4StartupOptionsDlg::OnGfxAllResolutionsChange(C4GUI::Element *pCheckBox)
|
||||
|
|
|
@ -2042,7 +2042,7 @@ void CStdGL::TaskIn()
|
|||
#ifdef _WIN32
|
||||
if (!Editor && !Config.Graphics.Windowed)
|
||||
{
|
||||
Application.SetVideoMode(Config.Graphics.ResX, Config.Graphics.ResY, Config.Graphics.BitDepth, Config.Graphics.Monitor, !Config.Graphics.Windowed);
|
||||
Application.SetVideoMode(Config.Graphics.ResX, Config.Graphics.ResY, Config.Graphics.BitDepth, Config.Graphics.RefreshRate, Config.Graphics.Monitor, !Config.Graphics.Windowed);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -90,14 +90,14 @@ void CStdApp::Quit()
|
|||
fQuitMsgReceived = true;
|
||||
}
|
||||
|
||||
bool CStdApp::GetIndexedDisplayMode(int32_t iIndex, int32_t *piXRes, int32_t *piYRes, int32_t *piBitDepth, uint32_t iMonitor)
|
||||
bool CStdApp::GetIndexedDisplayMode(int32_t iIndex, int32_t *piXRes, int32_t *piYRes, int32_t *piBitDepth, int32_t *piRefreshRate, uint32_t iMonitor)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void CStdApp::RestoreVideoMode() {}
|
||||
|
||||
bool CStdApp::SetVideoMode(unsigned int, unsigned int, unsigned int, unsigned int, bool) {}
|
||||
bool CStdApp::SetVideoMode(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, bool) {}
|
||||
|
||||
// Copy the text to the clipboard or the primary selection
|
||||
bool CStdApp::Copy(const StdStrBuf & text, bool fClipboard)
|
||||
|
|
|
@ -298,7 +298,7 @@ BOOL CALLBACK GLMonitorInfoEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lp
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CStdApp::GetIndexedDisplayMode(int32_t iIndex, int32_t *piXRes, int32_t *piYRes, int32_t *piBitDepth, uint32_t iMonitor)
|
||||
bool CStdApp::GetIndexedDisplayMode(int32_t iIndex, int32_t *piXRes, int32_t *piYRes, int32_t *piBitDepth, int32_t *piRefreshRate, uint32_t iMonitor)
|
||||
{
|
||||
// prepare search struct
|
||||
DEVMODE dmode;
|
||||
|
@ -312,6 +312,7 @@ bool CStdApp::GetIndexedDisplayMode(int32_t iIndex, int32_t *piXRes, int32_t *pi
|
|||
if (piXRes) *piXRes = dmode.dmPelsWidth;
|
||||
if (piYRes) *piYRes = dmode.dmPelsHeight;
|
||||
if (piBitDepth) *piBitDepth = dmode.dmBitsPerPel;
|
||||
if (piRefreshRate) *piRefreshRate = dmode.dmDisplayFrequency;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -319,7 +320,7 @@ void CStdApp::RestoreVideoMode()
|
|||
{
|
||||
}
|
||||
|
||||
bool CStdApp::SetVideoMode(unsigned int iXRes, unsigned int iYRes, unsigned int iColorDepth, unsigned int iMonitor, bool fFullScreen)
|
||||
bool CStdApp::SetVideoMode(unsigned int iXRes, unsigned int iYRes, unsigned int iColorDepth, unsigned int iRefreshRate, unsigned int iMonitor, bool fFullScreen)
|
||||
{
|
||||
#ifdef USE_DIRECTX
|
||||
if (pD3D)
|
||||
|
@ -354,25 +355,29 @@ bool CStdApp::SetVideoMode(unsigned int iXRes, unsigned int iYRes, unsigned int
|
|||
StdStrBuf Mon;
|
||||
if (iMonitor)
|
||||
Mon.Format("\\\\.\\Display%d", iMonitor+1);
|
||||
|
||||
ZeroMemory(&dmode, sizeof(dmode)); dmode.dmSize = sizeof(dmode);
|
||||
|
||||
// Get current display settings
|
||||
if (!EnumDisplaySettings(Mon.getData(), ENUM_CURRENT_SETTINGS, &dmode))
|
||||
return false;
|
||||
if (!iRefreshRate)
|
||||
{
|
||||
// Default to current
|
||||
iRefreshRate = dmode.dmDisplayFrequency;
|
||||
}
|
||||
int orientation = dmode.dmDisplayOrientation;
|
||||
// enumerate modes
|
||||
int i=0;
|
||||
ZeroMemory(&dmode, sizeof(dmode)); dmode.dmSize = sizeof(dmode);
|
||||
while (EnumDisplaySettings(Mon.getData(), i++, &dmode))
|
||||
// size and bit depth is OK?
|
||||
if (dmode.dmPelsWidth==iXRes && dmode.dmPelsHeight==iYRes && dmode.dmBitsPerPel==iColorDepth && dmode.dmDisplayOrientation==0)
|
||||
// compare enumerated mode with requested settings
|
||||
if (dmode.dmPelsWidth==iXRes && dmode.dmPelsHeight==iYRes && dmode.dmBitsPerPel==iColorDepth && dmode.dmDisplayOrientation==orientation && dmode.dmDisplayFrequency==iRefreshRate)
|
||||
{
|
||||
// compare with found one
|
||||
if (fFound)
|
||||
// try getting a mode that is close to 85Hz, rather than taking the one with highest refresh rate
|
||||
// (which may set absurd modes on some devices)
|
||||
if (Abs<int>(85-dmode.dmDisplayFrequency)>Abs<int>(85-dspMode.dmDisplayFrequency))
|
||||
// the previous one was better
|
||||
continue;
|
||||
// choose this one
|
||||
fFound=true;
|
||||
dspMode=dmode;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!fFound) return false;
|
||||
// change mode
|
||||
if (!fFullScreen)
|
||||
{
|
||||
|
@ -380,25 +385,14 @@ bool CStdApp::SetVideoMode(unsigned int iXRes, unsigned int iYRes, unsigned int
|
|||
SetWindowLong(pWindow->hWindow, GWL_STYLE,
|
||||
GetWindowLong(pWindow->hWindow, GWL_STYLE) | (WS_CAPTION|WS_THICKFRAME|WS_BORDER));
|
||||
}
|
||||
// save original display mode
|
||||
// if a monitor is given, use that
|
||||
else
|
||||
{
|
||||
if (iMonitor)
|
||||
{
|
||||
dspMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
|
||||
if (ChangeDisplaySettingsEx(Mon.getData(), &dspMode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL)
|
||||
if (ChangeDisplaySettingsEx(iMonitor ? Mon.getData() : NULL, &dspMode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ChangeDisplaySettings(&dspMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SetWindowLong(pWindow->hWindow, GWL_STYLE,
|
||||
GetWindowLong(pWindow->hWindow, GWL_STYLE) & ~ (WS_CAPTION|WS_THICKFRAME|WS_BORDER));
|
||||
}
|
||||
|
|
|
@ -381,8 +381,8 @@ public:
|
|||
}
|
||||
virtual void Quit();
|
||||
|
||||
bool GetIndexedDisplayMode(int32_t iIndex, int32_t *piXRes, int32_t *piYRes, int32_t *piBitDepth, uint32_t iMonitor);
|
||||
bool SetVideoMode(unsigned int iXRes, unsigned int iYRes, unsigned int iColorDepth, unsigned int iMonitor, bool fFullScreen);
|
||||
bool GetIndexedDisplayMode(int32_t iIndex, int32_t *piXRes, int32_t *piYRes, int32_t *piBitDepth, int32_t *piRefreshRate, uint32_t iMonitor);
|
||||
bool SetVideoMode(unsigned int iXRes, unsigned int iYRes, unsigned int iColorDepth, unsigned int iRefreshRate, unsigned int iMonitor, bool fFullScreen);
|
||||
void RestoreVideoMode();
|
||||
bool ScheduleProcs(int iTimeout = -1)
|
||||
{
|
||||
|
|
|
@ -387,7 +387,7 @@ void CStdApp::HandleXMessage()
|
|||
pWindow->HandleMessage(event);
|
||||
}
|
||||
|
||||
bool CStdApp::SetVideoMode(unsigned int iXRes, unsigned int iYRes, unsigned int iColorDepth, unsigned int iMonitor, bool fFullScreen)
|
||||
bool CStdApp::SetVideoMode(unsigned int iXRes, unsigned int iYRes, unsigned int iColorDepth, unsigned int iRefreshRate, unsigned int iMonitor, bool fFullScreen)
|
||||
{
|
||||
if (Priv->tasked_out)
|
||||
return false;
|
||||
|
@ -458,7 +458,7 @@ void CStdApp::RestoreVideoMode()
|
|||
}
|
||||
}
|
||||
|
||||
bool CStdApp::GetIndexedDisplayMode(int32_t iIndex, int32_t *piXRes, int32_t *piYRes, int32_t *piBitDepth, uint32_t iMonitor)
|
||||
bool CStdApp::GetIndexedDisplayMode(int32_t iIndex, int32_t *piXRes, int32_t *piYRes, int32_t *piBitDepth, int32_t *piRefreshRate, uint32_t iMonitor)
|
||||
{
|
||||
if (xf86vmode_major_version < 0) return false;
|
||||
bool r = false;
|
||||
|
|
Loading…
Reference in New Issue