return GetCurrentResolutionInfo().iScreen;
}
+RESOLUTION CDisplaySettings::FindBestMatchingResolution(const std::map<RESOLUTION, RESOLUTION_INFO> &resolutionInfos, int screen, int width, int height, float refreshrate, bool interlaced)
+{
+ int interlace = interlaced ? 100 : 200;
+
+ // find the closest match to these in our res vector. If we have the screen, we score the res
+ RESOLUTION bestRes = RES_DESKTOP;
+ float bestScore = FLT_MAX;
+
+ for (std::map<RESOLUTION, RESOLUTION_INFO>::const_iterator it = resolutionInfos.begin(); it != resolutionInfos.end(); ++it)
+ {
+ const RESOLUTION_INFO &info = it->second;
+ if (info.iScreen != screen)
+ continue;
+ float score = 10 * (square_error((float)info.iScreenWidth, (float)width) +
+ square_error((float)info.iScreenHeight, (float)height) +
+ square_error(info.fRefreshRate, refreshrate) +
+ square_error((float)((info.dwFlags & D3DPRESENTFLAG_INTERLACED) ? 100 : 200), (float)interlace));
+ if (score < bestScore)
+ {
+ bestScore = score;
+ bestRes = it->first;
+ }
+ }
+
+ return bestRes;
+}
+
RESOLUTION CDisplaySettings::GetResolutionFromString(const std::string &strResolution)
{
if (strResolution == "DESKTOP")
float refresh = (float)strtod(StringUtils::Mid(strResolution, 11,9).c_str(), NULL);
// look for 'i' and treat everything else as progressive,
// and use 100/200 to get a nice square_error.
- int interlaced = (StringUtils::Right(strResolution, 1) == "i") ? 100 : 200;
+ bool interlaced = StringUtils::EndsWith(strResolution, "i");
- // find the closest match to these in our res vector. If we have the screen, we score the res
- RESOLUTION bestRes = RES_DESKTOP;
- float bestScore = FLT_MAX;
-
- for (size_t resolution = 0; resolution < CDisplaySettings::Get().ResolutionInfoSize(); resolution++)
- {
- const RESOLUTION_INFO &info = CDisplaySettings::Get().GetResolutionInfo(resolution);
- if (info.iScreen != screen)
- continue;
- float score = 10 * (square_error((float)info.iScreenWidth, (float)width) +
- square_error((float)info.iScreenHeight, (float)height) +
- square_error(info.fRefreshRate, refresh) +
- square_error((float)((info.dwFlags & D3DPRESENTFLAG_INTERLACED) ? 100 : 200), (float)interlaced));
- if (score < bestScore)
- {
- bestScore = score;
- bestRes = (RESOLUTION)resolution;
- }
- }
- return bestRes;
+ std::map<RESOLUTION, RESOLUTION_INFO> resolutionInfos;
+ for (size_t resolution = RES_DESKTOP; resolution < CDisplaySettings::Get().ResolutionInfoSize(); resolution++)
+ resolutionInfos.insert(make_pair((RESOLUTION)resolution, CDisplaySettings::Get().GetResolutionInfo(resolution)));
+
+ return FindBestMatchingResolution(resolutionInfos, screen, width, height, refresh, interlaced);
}
return RES_DESKTOP;
if (resolution == RES_WINDOW)
return "WINDOW";
- if (resolution >= RES_CUSTOM && resolution < (RESOLUTION)CDisplaySettings::Get().ResolutionInfoSize())
+ if (resolution >= RES_DESKTOP && resolution < (RESOLUTION)CDisplaySettings::Get().ResolutionInfoSize())
{
const RESOLUTION_INFO &info = CDisplaySettings::Get().GetResolutionInfo(resolution);
- return StringUtils::Format("%1i%05i%05i%09.5f%s", info.iScreen,
- info.iScreenWidth, info.iScreenHeight,
- refreshrate > 0.0f ? refreshrate : info.fRefreshRate,
- (info.dwFlags & D3DPRESENTFLAG_INTERLACED) ? "i":"p");
+ // also handle RES_DESKTOP resolutions with non-default refresh rates
+ if (resolution != RES_DESKTOP || (refreshrate > 0.0f && refreshrate != info.fRefreshRate))
+ {
+ return StringUtils::Format("%1i%05i%05i%09.5f%s", info.iScreen,
+ info.iScreenWidth, info.iScreenHeight,
+ refreshrate > 0.0f ? refreshrate : info.fRefreshRate,
+ (info.dwFlags & D3DPRESENTFLAG_INTERLACED) ? "i":"p");
+ }
}
return "DESKTOP";
void CDisplaySettings::SettingOptionsRefreshRatesFiller(const CSetting *setting, std::vector< std::pair<std::string, std::string> > &list, std::string ¤t)
{
// get the proper resolution
- RESOLUTION res = GetResolutionForScreen();
+ RESOLUTION res = CDisplaySettings::Get().GetDisplayResolution();
if (res < RES_WINDOW)
return;
return;
}
+ RESOLUTION_INFO resInfo = CDisplaySettings::Get().GetResolutionInfo(res);
// The only meaningful parts of res here are iScreen, iScreenWidth, iScreenHeight
- vector<REFRESHRATE> refreshrates = g_Windowing.RefreshRates(CDisplaySettings::Get().GetResolutionInfo(res).iScreen,
- CDisplaySettings::Get().GetResolutionInfo(res).iScreenWidth,
- CDisplaySettings::Get().GetResolutionInfo(res).iScreenHeight,
- CDisplaySettings::Get().GetResolutionInfo(res).dwFlags);
+ vector<REFRESHRATE> refreshrates = g_Windowing.RefreshRates(resInfo.iScreen, resInfo.iScreenWidth, resInfo.iScreenHeight, resInfo.dwFlags);
bool match = false;
for (vector<REFRESHRATE>::const_iterator refreshrate = refreshrates.begin(); refreshrate != refreshrates.end(); refreshrate++)
{
- std::string screenmode = GetStringFromResolution(res, refreshrate->RefreshRate);
+ std::string screenmode = GetStringFromResolution((RESOLUTION)refreshrate->ResInfo_Index, refreshrate->RefreshRate);
if (!match && StringUtils::EqualsNoCase(((CSettingString*)setting)->GetValue(), screenmode))
match = true;
list.push_back(make_pair(StringUtils::Format("%.02f", refreshrate->RefreshRate), screenmode));
}
if (!match)
- current = GetStringFromResolution(res, g_Windowing.DefaultRefreshRate(CDisplaySettings::Get().GetResolutionInfo(res).iScreen, refreshrates).RefreshRate);
+ current = GetStringFromResolution(res, g_Windowing.DefaultRefreshRate(resInfo.iScreen, refreshrates).RefreshRate);
}
void CDisplaySettings::SettingOptionsResolutionsFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int ¤t)
{
- RESOLUTION res = RES_INVALID;
- DisplayMode screen = CSettings::Get().GetInt("videoscreen.screen");
- if (screen == DM_WINDOWED)
+ RESOLUTION res = CDisplaySettings::Get().GetDisplayResolution();
+ RESOLUTION_INFO info = CDisplaySettings::Get().GetResolutionInfo(res);
+ if (res == RES_WINDOW)
{
- res = RES_WINDOW;
- list.push_back(make_pair(g_localizeStrings.Get(242), RES_WINDOW));
+ current = res;
+ list.push_back(make_pair(g_localizeStrings.Get(242), res));
}
else
{
- vector<RESOLUTION_WHR> resolutions = g_Windowing.ScreenResolutions(screen);
+ std::map<RESOLUTION, RESOLUTION_INFO> resolutionInfos;
+ vector<RESOLUTION_WHR> resolutions = g_Windowing.ScreenResolutions(info.iScreen, info.fRefreshRate);
for (vector<RESOLUTION_WHR>::const_iterator resolution = resolutions.begin(); resolution != resolutions.end(); resolution++)
{
list.push_back(make_pair(
- StringUtils::Format("%dx%d%s", resolution->width, resolution->height, (resolution->interlaced == D3DPRESENTFLAG_INTERLACED) ? "i" : "p"),
- resolution->ResInfo_Index));
-
- RESOLUTION_INFO res1 = CDisplaySettings::Get().GetCurrentResolutionInfo();
- RESOLUTION_INFO res2 = CDisplaySettings::Get().GetResolutionInfo(resolution->ResInfo_Index);
- if (res1.iScreen == res2.iScreen &&
- res1.iScreenWidth == res2.iScreenWidth &&
- res1.iScreenHeight == res2.iScreenHeight &&
- (res1.dwFlags & D3DPRESENTFLAG_INTERLACED) == (res2.dwFlags & D3DPRESENTFLAG_INTERLACED))
- res = (RESOLUTION)resolution->ResInfo_Index;
+ StringUtils::Format("%dx%d%s", resolution->width, resolution->height,
+ (resolution->interlaced == D3DPRESENTFLAG_INTERLACED) ? "i" : "p"),
+ resolution->ResInfo_Index));
+
+ resolutionInfos.insert(make_pair((RESOLUTION)resolution->ResInfo_Index, CDisplaySettings::Get().GetResolutionInfo(resolution->ResInfo_Index)));
}
- }
- if (res != RES_INVALID)
- current = res;
+ current = FindBestMatchingResolution(resolutionInfos, info.iScreen,
+ info.iScreenWidth, info.iScreenHeight,
+ info.fRefreshRate, info.dwFlags & D3DPRESENTFLAG_INTERLACED);
+ }
}
void CDisplaySettings::SettingOptionsScreensFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int ¤t)
}
RESOLUTION res = CDisplaySettings::Get().GetDisplayResolution();
-
if (res == RES_WINDOW)
current = DM_WINDOWED;
else