diff options
author | CrystalPT <CrystalPT@svn> | 2010-07-02 03:39:12 +0000 |
---|---|---|
committer | CrystalPT <CrystalPT@svn> | 2010-07-02 03:39:12 +0000 |
commit | 5a8d600d32a81acbaa614b5b7edc8f5638799c24 (patch) | |
tree | 56125115632c42026a1db0e579a1783eefd8bac6 | |
parent | e64333e3370f52cd5b96bbd6659af241d557af80 (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.xml | 1 | ||||
-rw-r--r-- | xbmc/GUISettings.cpp | 7 | ||||
-rw-r--r-- | xbmc/GUIWindowSettingsCategory.cpp | 171 | ||||
-rw-r--r-- | xbmc/GUIWindowSettingsCategory.h | 7 | ||||
-rw-r--r-- | xbmc/WinSystem.cpp | 67 | ||||
-rw-r--r-- | xbmc/WinSystem.h | 9 |
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); |