aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCrystalPT <CrystalPT@svn>2010-07-02 03:39:12 +0000
committerCrystalPT <CrystalPT@svn>2010-07-02 03:39:12 +0000
commit5a8d600d32a81acbaa614b5b7edc8f5638799c24 (patch)
tree56125115632c42026a1db0e579a1783eefd8bac6
parente64333e3370f52cd5b96bbd6659af241d557af80 (diff)
changed: Refresh Rate Spinner - add spinner
git-svn-id: https://xbmc.svn.sourceforge.net/svnroot/xbmc/trunk@31549 568bbfeb-2a22-0410-94d2-cc84cf5bfa90
-rw-r--r--language/English/strings.xml1
-rw-r--r--xbmc/GUISettings.cpp7
-rw-r--r--xbmc/GUIWindowSettingsCategory.cpp171
-rw-r--r--xbmc/GUIWindowSettingsCategory.h7
-rw-r--r--xbmc/WinSystem.cpp67
-rw-r--r--xbmc/WinSystem.h9
6 files changed, 202 insertions, 60 deletions
diff --git a/language/English/strings.xml b/language/English/strings.xml
index eb8b74ec30..def358a1df 100644
--- a/language/English/strings.xml
+++ b/language/English/strings.xml
@@ -193,6 +193,7 @@
<string id="240">Display Mode</string>
<string id="241">Full Screen #%d</string>
<string id="242">Windowed</string>
+ <string id="243">Refresh Rate</string>
<string id="247">Scripts</string>
<string id="248">Language</string>
diff --git a/xbmc/GUISettings.cpp b/xbmc/GUISettings.cpp
index 39593dd008..47a2a0f0a3 100644
--- a/xbmc/GUISettings.cpp
+++ b/xbmc/GUISettings.cpp
@@ -364,10 +364,13 @@ void CGUISettings::Initialize()
// this setting would ideally not be saved, as its value is systematically derived from videoscreen.screenmode.
AddInt(vs, "videoscreen.screen", 240, 0, -1, 1, g_Windowing.GetNumScreens(), SPIN_CONTROL_TEXT);
#if defined (__APPLE__)
- AddString(vs, "videoscreen.screenmode", 131, "DESKTOP", SPIN_CONTROL_TEXT);
+ AddInt(vs, "videoscreen.resolution", 131, -1, 0, 1, INT_MAX, SPIN_CONTROL_TEXT);
#else
- AddString(vs, "videoscreen.screenmode", 169, "DESKTOP", SPIN_CONTROL_TEXT);
+ AddInt(vs, "videoscreen.resolution", 169, -1, 0, 1, INT_MAX, SPIN_CONTROL_TEXT);
#endif
+//TODO: attach to vs in standalone mode only
+ AddString(vs, "videoscreen.screenmode", 243, "DESKTOP", SPIN_CONTROL_TEXT);
+
#if defined(_WIN32) || defined (__APPLE__)
// We prefer a fake fullscreen mode (window covering the screen rather than dedicated fullscreen)
// as it works nicer with switching to other applications. However on some systems vsync is broken
diff --git a/xbmc/GUIWindowSettingsCategory.cpp b/xbmc/GUIWindowSettingsCategory.cpp
index 29fb094a48..5f09604b10 100644
--- a/xbmc/GUIWindowSettingsCategory.cpp
+++ b/xbmc/GUIWindowSettingsCategory.cpp
@@ -483,9 +483,15 @@ void CGUIWindowSettingsCategory::CreateSettings()
{
FillInScreens(strSetting, g_guiSettings.GetResolution());
}
+ else if (strSetting.Equals("videoscreen.resolution"))
+ {
+ FillInResolutions(strSetting, g_guiSettings.GetInt("videoscreen.screen"), false);
+ CGUISpinControlEx *pControl = (CGUISpinControlEx *)GetControl(GetSetting(strSetting)->GetID());
+ pControl->SetValue(g_guiSettings.GetResolution());
+ }
else if (strSetting.Equals("videoscreen.screenmode"))
{
- FillInResolutions(pSetting);
+ FillInRefreshRates(strSetting, g_guiSettings.GetResolution(), false);
}
else if (strSetting.Equals("lookandfeel.skintheme"))
{
@@ -495,10 +501,13 @@ void CGUIWindowSettingsCategory::CreateSettings()
{
FillInSkinColors(pSetting);
}
+ /*
+ FIXME: setting is hidden in GUI because not supported properly.
else if (strSetting.Equals("videoplayer.displayresolution") || strSetting.Equals("pictures.displayresolution"))
{
FillInResolutions(pSetting);
}
+ */
else if (strSetting.Equals("videoplayer.highqualityupscaling"))
{
CSettingInt *pSettingInt = (CSettingInt*)pSetting;
@@ -626,6 +635,12 @@ void CGUIWindowSettingsCategory::UpdateSettings()
}
}
#endif
+ else if (strSetting.Equals("videoscreen.resolution"))
+ {
+ CGUIControl *pControl = (CGUIControl *)GetControl(pSettingControl->GetID());
+ if (pControl)
+ pControl->SetEnabled(g_guiSettings.GetInt("videoscreen.screen") != DM_WINDOWED);
+ }
else if (strSetting.Equals("videoscreen.screenmode"))
{
CGUIControl *pControl = (CGUIControl *)GetControl(pSettingControl->GetID());
@@ -1434,41 +1449,23 @@ void CGUIWindowSettingsCategory::OnSettingChanged(CBaseSettingControl *pSettingC
else if (strSetting.Equals("videoscreen.screen"))
{
DisplayMode mode = g_guiSettings.GetInt("videoscreen.screen");
-
// Cascade
- FillInResolutionsInternal("videoscreen.screenmode", mode);
-
- // Auto-select the windowed or desktop resolution of the screen
- int autoresolution = RES_DESKTOP;
- if (mode == DM_WINDOWED)
- {
- autoresolution = RES_WINDOW;
- }
- else
- {
- for (int idx=0; idx < g_Windowing.GetNumScreens(); idx++)
- if (g_settings.m_ResInfo[RES_DESKTOP + idx].iScreen == mode)
- {
- autoresolution = RES_DESKTOP + idx;
- break;
- }
- }
-
- // force the resolution and the settings changed event
- CBaseSettingControl *control = GetSetting("videoscreen.screenmode");
- CGUISpinControlEx *pControl = (CGUISpinControlEx *)GetControl(control->GetID());
- pControl->SetValue(autoresolution);
-
- OnResolutionChanged((RESOLUTION)autoresolution);
+ FillInResolutions("videoscreen.resolution", mode, true);
+ }
+ else if (strSetting.Equals("videoscreen.resolution"))
+ {
+ RESOLUTION nextRes = (RESOLUTION) g_guiSettings.GetInt("videoscreen.resolution");
+ // Cascade
+ FillInRefreshRates("videoscreen.screenmode", nextRes, true);
}
else if (strSetting.Equals("videoscreen.screenmode"))
- { // new resolution choosen... - update if necessary
+ {
int iControlID = pSettingControl->GetID();
CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), iControlID);
g_windowManager.SendMessage(msg);
RESOLUTION nextRes = (RESOLUTION)msg.GetParam1();
- OnResolutionChanged(nextRes);
+ OnRefreshRateChanged(nextRes);
}
else if (strSetting.Equals("videoscreen.vsync"))
{
@@ -2289,19 +2286,12 @@ DisplayMode CGUIWindowSettingsCategory::FillInScreens(CStdString strSetting, RES
return mode;
}
-void CGUIWindowSettingsCategory::FillInResolutions(CSetting *pSetting)
-{
- FillInResolutionsInternal(pSetting->GetSetting(), g_guiSettings.GetInt("videoscreen.screen"));
- CBaseSettingControl *control = GetSetting(pSetting->GetSetting());
- CGUISpinControlEx *pControl = (CGUISpinControlEx *)GetControl(control->GetID());
- pControl->SetValue(CGUISettings::GetResFromString(((CSettingString*) pSetting)->GetData()));
-}
-
-void CGUIWindowSettingsCategory::FillInResolutionsInternal(CStdString strSetting, DisplayMode mode)
+void CGUIWindowSettingsCategory::FillInResolutions(CStdString strSetting, DisplayMode mode, bool UserChange)
{
CBaseSettingControl *control = GetSetting(strSetting);
control->SetDelayed();
CGUISpinControlEx *pControl = (CGUISpinControlEx *)GetControl(control->GetID());
+
pControl->Clear();
if (mode == DM_WINDOWED)
@@ -2319,25 +2309,102 @@ void CGUIWindowSettingsCategory::FillInResolutionsInternal(CStdString strSetting
pControl->AddLabel(strRes, resolutions[idx].ResInfo_Index);
}
}
+
+ if (UserChange)
+ {
+ // Auto-select the windowed or desktop resolution of the screen
+ int autoresolution = RES_DESKTOP;
+ if (mode == DM_WINDOWED)
+ {
+ autoresolution = RES_WINDOW;
+ }
+ else
+ {
+ for (int idx=0; idx < g_Windowing.GetNumScreens(); idx++)
+ if (g_settings.m_ResInfo[RES_DESKTOP + idx].iScreen == mode)
+ {
+ autoresolution = RES_DESKTOP + idx;
+ break;
+ }
+ }
+ pControl->SetValue(autoresolution);
+
+ // Cascade
+ FillInRefreshRates("videoscreen.screenmode", (RESOLUTION) autoresolution, true);
+ }
+ else
+ {
+ // selecting a value is done outside of this function for UserChange = false
+ }
}
-void CGUIWindowSettingsCategory::OnResolutionChanged(RESOLUTION nextRes)
+void CGUIWindowSettingsCategory::FillInRefreshRates(CStdString strSetting, RESOLUTION res, bool UserChange)
{
- RESOLUTION lastRes = g_graphicsContext.GetVideoResolution();
- g_guiSettings.SetResolution(nextRes);
- g_graphicsContext.SetVideoResolution(nextRes);
- bool cancelled = false;
- if (!CGUIDialogYesNo::ShowAndGetInput(13110, 13111, 20022, 20022, -1, -1, cancelled, 10000))
- {
- g_guiSettings.SetResolution(lastRes);
- g_graphicsContext.SetVideoResolution(lastRes);
-
- DisplayMode mode = FillInScreens("videoscreen.screen", lastRes);
- FillInResolutionsInternal("videoscreen.screenmode", mode);
- CBaseSettingControl *control = GetSetting("videoscreen.screenmode");
- CGUISpinControlEx *pControl = (CGUISpinControlEx *)GetControl(control->GetID());
- pControl->SetValue(g_guiSettings.GetResolution());
+ // The only meaningful parts of res here are iScreen, iWidth, iHeight
+ CBaseSettingControl *control = GetSetting(strSetting);
+ control->SetDelayed();
+ CGUISpinControlEx *pControl = (CGUISpinControlEx *)GetControl(control->GetID());
+ pControl->Clear();
+
+ vector<REFRESHRATE> refreshrates;
+
+ // Populate the list
+ if (res == RES_WINDOW)
+ {
+ pControl->AddLabel(g_localizeStrings.Get(242), RES_WINDOW);
+ }
+ else
+ {
+ refreshrates = g_Windowing.RefreshRates(g_settings.m_ResInfo[res].iScreen, g_settings.m_ResInfo[res].iWidth, g_settings.m_ResInfo[res].iHeight);
+
+ for (unsigned int idx = 0; idx < refreshrates.size(); idx++)
+ {
+ CStdString strRR;
+ strRR.Format("%.02f%s", refreshrates[idx].RefreshRate, refreshrates[idx].Interlaced ? "i" : "");
+ pControl->AddLabel(strRR, refreshrates[idx].ResInfo_Index);
+ }
+ }
+
+ // Select a rate
+ if (UserChange)
+ {
+ if (res == RES_WINDOW)
+ {
+ OnRefreshRateChanged(RES_WINDOW);
+ }
+ else
+ {
+ REFRESHRATE rr = g_Windowing.DefaultRefreshRate(g_settings.m_ResInfo[res].iScreen, refreshrates);
+ pControl->SetValue(rr.ResInfo_Index);
+ OnRefreshRateChanged((RESOLUTION)rr.ResInfo_Index);
}
+ }
+ else
+ {
+ pControl->SetValue(res);
+ }
+
+}
+
+void CGUIWindowSettingsCategory::OnRefreshRateChanged(RESOLUTION nextRes)
+{
+ RESOLUTION lastRes = g_graphicsContext.GetVideoResolution();
+ bool cancelled = false;
+
+ g_guiSettings.SetResolution(nextRes);
+ g_graphicsContext.SetVideoResolution(nextRes);
+
+ if (!CGUIDialogYesNo::ShowAndGetInput(13110, 13111, 20022, 20022, -1, -1, cancelled, 10000))
+ {
+ g_guiSettings.SetResolution(lastRes);
+ g_graphicsContext.SetVideoResolution(lastRes);
+
+ DisplayMode mode = FillInScreens("videoscreen.screen", lastRes);
+ FillInResolutions("videoscreen.resolution", mode, false);
+ CGUISpinControlEx *pControl = (CGUISpinControlEx *)GetControl(GetSetting("videoscreen.resolution")->GetID());
+ pControl->SetValue(lastRes);
+ FillInRefreshRates("videoscreen.screenmode", lastRes, false);
+ }
}
void CGUIWindowSettingsCategory::FillInLanguages(CSetting *pSetting)
diff --git a/xbmc/GUIWindowSettingsCategory.h b/xbmc/GUIWindowSettingsCategory.h
index 456ade51f6..472db96aed 100644
--- a/xbmc/GUIWindowSettingsCategory.h
+++ b/xbmc/GUIWindowSettingsCategory.h
@@ -49,9 +49,10 @@ protected:
void FillInSoundSkins(CSetting *pSetting);
void FillInLanguages(CSetting *pSetting);
DisplayMode FillInScreens(CStdString strSetting, RESOLUTION res);
- void FillInResolutions(CSetting *pSetting);
- void FillInResolutionsInternal(CStdString strSetting, DisplayMode mode);
- void OnResolutionChanged(RESOLUTION resolution);
+ void FillInResolutions(CStdString strSetting, DisplayMode mode, bool UserChange);
+ void FillInRefreshRates(CStdString strSetting, RESOLUTION res, bool UserChange);
+ void OnRefreshRateChanged(RESOLUTION resolution);
+
void FillInRegions(CSetting *pSetting);
void FillInStartupWindow(CSetting *pSetting);
void FillInViewModes(CSetting *pSetting, int windowID);
diff --git a/xbmc/WinSystem.cpp b/xbmc/WinSystem.cpp
index d2959472b9..b289cf3d88 100644
--- a/xbmc/WinSystem.cpp
+++ b/xbmc/WinSystem.cpp
@@ -108,6 +108,8 @@ static void AddResolution(vector<RESOLUTION_WHR> &resolutions, int width, int he
if (resolutions[idx].width == width && resolutions[idx].height == height)
return; // this width*height was taken care of.
+// TODO: shouldn't need this 'best refresh rate' selection here anymore, should move elsewhere
+
int screen = g_settings.m_ResInfo[screenDefaultRes].iScreen;
float targetfps = g_settings.m_ResInfo[screenDefaultRes].fRefreshRate;
//TODO: get it from another source if we can have stupid values like 0, 1?
@@ -119,9 +121,9 @@ static void AddResolution(vector<RESOLUTION_WHR> &resolutions, int width, int he
{
RESOLUTION_INFO &info = g_settings.m_ResInfo[i];
- if (info.iWidth != width
- || info.iHeight != height
- || info.iScreen != screen)
+ if ( info.iWidth != width
+ || info.iHeight != height
+ || info.iScreen != screen)
continue;
float fitness = fabs(targetfps - info.fRefreshRate);
@@ -159,3 +161,62 @@ vector<RESOLUTION_WHR> CWinSystemBase::ScreenResolutions(int screen)
return resolutions;
}
+
+static void AddRefreshRate(vector<REFRESHRATE> &refreshrates, unsigned addindex)
+{
+ float RefreshRate = g_settings.m_ResInfo[addindex].fRefreshRate;
+ bool Interlaced = ((g_settings.m_ResInfo[addindex].dwFlags & D3DPRESENTFLAG_INTERLACED) == D3DPRESENTFLAG_INTERLACED);
+
+ for (unsigned int idx = 0; idx < refreshrates.size(); idx++)
+ if ( refreshrates[idx].RefreshRate == RefreshRate
+ && refreshrates[idx].Interlaced == Interlaced )
+ return; // already taken care of.
+
+ REFRESHRATE rr = {RefreshRate, Interlaced, addindex};
+ refreshrates.push_back(rr);
+}
+
+static bool rrSortPredicate (REFRESHRATE i, REFRESHRATE j)
+{
+ return ( i.RefreshRate < j.RefreshRate
+ || i.RefreshRate == j.RefreshRate && !i.Interlaced);
+}
+
+vector<REFRESHRATE> CWinSystemBase::RefreshRates(int screen, int width, int height)
+{
+ vector<REFRESHRATE> refreshrates;
+
+ for (unsigned int idx = RES_DESKTOP; idx < g_settings.m_ResInfo.size(); idx++)
+ if ( g_settings.m_ResInfo[idx].iScreen == screen
+ && g_settings.m_ResInfo[idx].iWidth == width
+ && g_settings.m_ResInfo[idx].iHeight == height)
+ AddRefreshRate(refreshrates, idx);
+
+ // Can't assume the resolutions are sorted
+ sort(refreshrates.begin(), refreshrates.end(), rrSortPredicate);
+
+ return refreshrates;
+}
+
+REFRESHRATE CWinSystemBase::DefaultRefreshRate(int screen, vector<REFRESHRATE> rates)
+{
+ REFRESHRATE bestmatch = rates[0];
+ float bestfitness = -1.0f;
+
+ float targetfps = g_settings.m_ResInfo[DesktopResolution(screen)].fRefreshRate;
+
+ for (unsigned i = 0; i < rates.size(); i++)
+ {
+ float fitness = fabs(targetfps - rates[i].RefreshRate);
+
+ if (bestfitness <0 || fitness < bestfitness)
+ {
+ bestfitness = fitness;
+ bestmatch = rates[i];
+ if (bestfitness == 0.0f) // perfect match
+ break;
+ }
+ }
+
+ return bestmatch;
+} \ No newline at end of file
diff --git a/xbmc/WinSystem.h b/xbmc/WinSystem.h
index 55083d571e..a6935e1495 100644
--- a/xbmc/WinSystem.h
+++ b/xbmc/WinSystem.h
@@ -42,6 +42,13 @@ struct RESOLUTION_WHR
int ResInfo_Index;
};
+struct REFRESHRATE
+{
+ float RefreshRate;
+ bool Interlaced;
+ int ResInfo_Index;
+};
+
class CWinSystemBase
{
public:
@@ -81,6 +88,8 @@ public:
void SetWindowResolution(int width, int height);
int DesktopResolution(int screen);
std::vector<RESOLUTION_WHR> ScreenResolutions(int screen);
+ std::vector<REFRESHRATE> RefreshRates(int screen, int width, int height);
+ REFRESHRATE DefaultRefreshRate(int screen, std::vector<REFRESHRATE> rates);
protected:
void UpdateDesktopResolution(RESOLUTION_INFO& newRes, int screen, int width, int height, float refreshRate, uint32_t dwFlags = 0);