diff --git a/src/lang/english.txt b/src/lang/english.txt index 6e803a37c0..73fdefd2dd 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1021,6 +1021,14 @@ STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Double size STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Quad size +STR_GAME_OPTIONS_GRAPHICS :{BLACK}Graphics + +STR_GAME_OPTIONS_REFRESH_RATE :{BLACK}Display refresh rate +STR_GAME_OPTIONS_REFRESH_RATE_TOOLTIP :{BLACK}Select the screen refresh rate to use +STR_GAME_OPTIONS_REFRESH_RATE_OTHER :other +STR_GAME_OPTIONS_REFRESH_RATE_ITEM :{NUM}Hz +STR_GAME_OPTIONS_REFRESH_RATE_WARNING :{WHITE}Refresh rates higher than 60Hz might impact performance. + STR_GAME_OPTIONS_BASE_GRF :{BLACK}Base graphics set STR_GAME_OPTIONS_BASE_GRF_TOOLTIP :{BLACK}Select the base graphics set to use STR_GAME_OPTIONS_BASE_GRF_STATUS :{RED}{NUM} missing/corrupted file{P "" s} diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 0ef8176bc9..1d38c4e436 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -38,8 +38,10 @@ #include "video/video_driver.hpp" #include +#include #include "safeguards.h" +#include "video/video_driver.hpp" static const StringID _autosave_dropdown[] = { @@ -140,6 +142,22 @@ void ShowBaseSetTextfileWindow(TextfileType file_type, const TBaseSet* baseset, new BaseSetTextfileWindow(file_type, baseset, content_type); } +std::set _refresh_rates = { 30, 60, 75, 90, 100, 120, 144, 240 }; + +/** + * Add the refresh rate from the config and the refresh rates from all the monitors to + * our list of refresh rates shown in the GUI. + */ +static void AddRefreshRatesAndSelect() +{ + /* Add the refresh rate as selected in the config. */ + _refresh_rates.insert(_settings_client.gui.refresh_rate); + + /* Add all the refresh rates of all monitors connected to the machine. */ + std::vector monitorRates = VideoDriver::GetInstance()->GetListOfMonitorRefreshRates(); + std::copy(monitorRates.begin(), monitorRates.end(), std::inserter(_refresh_rates, _refresh_rates.end())); +} + struct GameOptionsWindow : Window { GameSettings *opt; bool reload; @@ -149,6 +167,8 @@ struct GameOptionsWindow : Window { this->opt = &GetGameSettings(); this->reload = false; + AddRefreshRatesAndSelect(); + this->InitNested(WN_GAME_OPTIONS_GAME_OPTIONS); this->OnInvalidateData(0); } @@ -215,6 +235,16 @@ struct GameOptionsWindow : Window { } break; + case WID_GO_REFRESH_RATE_DROPDOWN: // Setup refresh rate dropdown + for (auto it = _refresh_rates.begin(); it != _refresh_rates.end(); it++) { + auto i = std::distance(_refresh_rates.begin(), it); + if (*it == _settings_client.gui.refresh_rate) *selected_index = i; + auto item = new DropDownListParamStringItem(STR_GAME_OPTIONS_REFRESH_RATE_ITEM, i, false); + item->SetParam(0, *it); + list.emplace_back(item); + } + break; + case WID_GO_GUI_ZOOM_DROPDOWN: { *selected_index = _gui_zoom_cfg != ZOOM_LVL_CFG_AUTO ? ZOOM_LVL_OUT_4X - _gui_zoom + 1 : 0; const StringID *items = _gui_zoom_dropdown; @@ -252,17 +282,18 @@ struct GameOptionsWindow : Window { void SetStringParameters(int widget) const override { switch (widget) { - case WID_GO_CURRENCY_DROPDOWN: SetDParam(0, _currency_specs[this->opt->locale.currency].name); break; - case WID_GO_AUTOSAVE_DROPDOWN: SetDParam(0, _autosave_dropdown[_settings_client.gui.autosave]); break; - case WID_GO_LANG_DROPDOWN: SetDParamStr(0, _current_language->own_name); break; - case WID_GO_RESOLUTION_DROPDOWN: SetDParam(0, GetCurRes() == _resolutions.size() ? STR_GAME_OPTIONS_RESOLUTION_OTHER : SPECSTR_RESOLUTION_START + GetCurRes()); break; - case WID_GO_GUI_ZOOM_DROPDOWN: SetDParam(0, _gui_zoom_dropdown[_gui_zoom_cfg != ZOOM_LVL_CFG_AUTO ? ZOOM_LVL_OUT_4X - _gui_zoom_cfg + 1 : 0]); break; - case WID_GO_FONT_ZOOM_DROPDOWN: SetDParam(0, _font_zoom_dropdown[_font_zoom_cfg != ZOOM_LVL_CFG_AUTO ? ZOOM_LVL_OUT_4X - _font_zoom_cfg + 1 : 0]); break; - case WID_GO_BASE_GRF_DROPDOWN: SetDParamStr(0, BaseGraphics::GetUsedSet()->name.c_str()); break; - case WID_GO_BASE_GRF_STATUS: SetDParam(0, BaseGraphics::GetUsedSet()->GetNumInvalid()); break; - case WID_GO_BASE_SFX_DROPDOWN: SetDParamStr(0, BaseSounds::GetUsedSet()->name.c_str()); break; - case WID_GO_BASE_MUSIC_DROPDOWN: SetDParamStr(0, BaseMusic::GetUsedSet()->name.c_str()); break; - case WID_GO_BASE_MUSIC_STATUS: SetDParam(0, BaseMusic::GetUsedSet()->GetNumInvalid()); break; + case WID_GO_CURRENCY_DROPDOWN: SetDParam(0, _currency_specs[this->opt->locale.currency].name); break; + case WID_GO_AUTOSAVE_DROPDOWN: SetDParam(0, _autosave_dropdown[_settings_client.gui.autosave]); break; + case WID_GO_LANG_DROPDOWN: SetDParamStr(0, _current_language->own_name); break; + case WID_GO_RESOLUTION_DROPDOWN: SetDParam(0, GetCurRes() == _resolutions.size() ? STR_GAME_OPTIONS_RESOLUTION_OTHER : SPECSTR_RESOLUTION_START + GetCurRes()); break; + case WID_GO_GUI_ZOOM_DROPDOWN: SetDParam(0, _gui_zoom_dropdown[_gui_zoom_cfg != ZOOM_LVL_CFG_AUTO ? ZOOM_LVL_OUT_4X - _gui_zoom_cfg + 1 : 0]); break; + case WID_GO_FONT_ZOOM_DROPDOWN: SetDParam(0, _font_zoom_dropdown[_font_zoom_cfg != ZOOM_LVL_CFG_AUTO ? ZOOM_LVL_OUT_4X - _font_zoom_cfg + 1 : 0]); break; + case WID_GO_BASE_GRF_DROPDOWN: SetDParamStr(0, BaseGraphics::GetUsedSet()->name.c_str()); break; + case WID_GO_BASE_GRF_STATUS: SetDParam(0, BaseGraphics::GetUsedSet()->GetNumInvalid()); break; + case WID_GO_BASE_SFX_DROPDOWN: SetDParamStr(0, BaseSounds::GetUsedSet()->name.c_str()); break; + case WID_GO_BASE_MUSIC_DROPDOWN: SetDParamStr(0, BaseMusic::GetUsedSet()->name.c_str()); break; + case WID_GO_BASE_MUSIC_STATUS: SetDParam(0, BaseMusic::GetUsedSet()->GetNumInvalid()); break; + case WID_GO_REFRESH_RATE_DROPDOWN: SetDParam(0, _settings_client.gui.refresh_rate); break; } } @@ -451,6 +482,16 @@ struct GameOptionsWindow : Window { } break; + case WID_GO_REFRESH_RATE_DROPDOWN: { + _settings_client.gui.refresh_rate = *std::next(_refresh_rates.begin(), index); + if (_settings_client.gui.refresh_rate > 60) { + /* Show warning to the user that this refresh rate might not be suitable on + * larger maps with many NewGRFs and vehicles. */ + ShowErrorMessage(STR_GAME_OPTIONS_REFRESH_RATE_WARNING, INVALID_STRING_ID, WL_INFO); + } + break; + } + case WID_GO_GUI_ZOOM_DROPDOWN: { int8 new_zoom = index > 0 ? ZOOM_LVL_OUT_4X - index + 1 : ZOOM_LVL_CFG_AUTO; if (new_zoom != _gui_zoom_cfg) { @@ -528,36 +569,47 @@ static const NWidgetPart _nested_game_options_widgets[] = { NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_AUTOSAVE_FRAME, STR_NULL), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_AUTOSAVE_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP), SetFill(1, 0), EndContainer(), - NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_RESOLUTION, STR_NULL), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_RESOLUTION_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_RESOLUTION_TOOLTIP), SetFill(1, 0), SetPadding(0, 0, 3, 0), - NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0), SetPadding(0, 0, 3, 0), - NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_FULLSCREEN, STR_NULL), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_FULLSCREEN_BUTTON), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP), - EndContainer(), - NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0), - NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_VIDEO_ACCELERATION, STR_NULL), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_VIDEO_ACCEL_BUTTON), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_VIDEO_ACCELERATION_TOOLTIP), - EndContainer(), + NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_GUI_ZOOM_FRAME, STR_NULL), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_GUI_ZOOM_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP), SetFill(1, 0), + EndContainer(), + NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME, STR_NULL), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_CURRENCY_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP), SetFill(1, 0), EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 0), SetFill(0, 1), EndContainer(), NWidget(NWID_VERTICAL), SetPIP(0, 6, 0), NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_LANGUAGE, STR_NULL), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_LANG_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_RAW_STRING, STR_GAME_OPTIONS_LANGUAGE_TOOLTIP), SetFill(1, 0), EndContainer(), - NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME, STR_NULL), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_CURRENCY_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP), SetFill(1, 0), - EndContainer(), - NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_GUI_ZOOM_FRAME, STR_NULL), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_GUI_ZOOM_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP), SetFill(1, 0), - EndContainer(), NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_FONT_ZOOM, STR_NULL), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_FONT_ZOOM_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP), SetFill(1, 0), EndContainer(), EndContainer(), EndContainer(), + NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_GRAPHICS, STR_NULL), SetPadding(0, 10, 0, 10), + NWidget(NWID_HORIZONTAL), + NWidget(NWID_VERTICAL), + NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_RESOLUTION, STR_NULL), SetPadding(0, 0, 2, 0), + NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_REFRESH_RATE, STR_NULL), SetPadding(0, 0, 2, 0), + NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_FULLSCREEN, STR_NULL), SetPadding(0, 0, 2, 0), + NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_VIDEO_ACCELERATION, STR_NULL), + EndContainer(), + NWidget(NWID_VERTICAL), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_RESOLUTION_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_RESOLUTION_TOOLTIP), SetFill(1, 0), SetPadding(0, 0, 2, 0), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_REFRESH_RATE_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_GAME_OPTIONS_REFRESH_RATE_ITEM, STR_GAME_OPTIONS_REFRESH_RATE_TOOLTIP), SetFill(1, 0), SetPadding(0, 0, 2, 0), + NWidget(NWID_HORIZONTAL), SetPadding(0, 0, 2, 0), + NWidget(NWID_SPACER), SetMinimalSize(1, 0), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_FULLSCREEN_BUTTON), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(NWID_SPACER), SetMinimalSize(1, 0), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_VIDEO_ACCEL_BUTTON), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_VIDEO_ACCELERATION_TOOLTIP), + EndContainer(), + EndContainer(), + EndContainer(), + EndContainer(), + NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_GRF, STR_NULL), SetPadding(0, 10, 0, 10), NWidget(NWID_HORIZONTAL), SetPIP(0, 30, 0), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_GRF_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_RAW_STRING, STR_GAME_OPTIONS_BASE_GRF_TOOLTIP), diff --git a/src/video/allegro_v.cpp b/src/video/allegro_v.cpp index 0c064873b3..3d8ca65aa7 100644 --- a/src/video/allegro_v.cpp +++ b/src/video/allegro_v.cpp @@ -236,6 +236,16 @@ bool VideoDriver_Allegro::ClaimMousePointer() return true; } +std::vector VideoDriver_Allegro::GetListOfMonitorRefreshRates() +{ + std::vector rates = {}; + + int refresh_rate = get_refresh_rate(); + if (refresh_rate != 0) rates.push_back(refresh_rate); + + return rates; +} + struct AllegroVkMapping { uint16 vk_from; byte vk_count; diff --git a/src/video/allegro_v.h b/src/video/allegro_v.h index d67778b7f5..d1576fea9e 100644 --- a/src/video/allegro_v.h +++ b/src/video/allegro_v.h @@ -31,6 +31,8 @@ public: bool ClaimMousePointer() override; + std::vector GetListOfMonitorRefreshRates() override; + const char *GetName() const override { return "allegro"; } protected: diff --git a/src/video/cocoa/cocoa_v.h b/src/video/cocoa/cocoa_v.h index 371e4b5bc7..3d3db5454c 100644 --- a/src/video/cocoa/cocoa_v.h +++ b/src/video/cocoa/cocoa_v.h @@ -47,6 +47,8 @@ public: void EditBoxLostFocus() override; + std::vector GetListOfMonitorRefreshRates() override; + /* --- The following methods should be private, but can't be due to Obj-C limitations. --- */ void MainLoopReal(); diff --git a/src/video/cocoa/cocoa_v.mm b/src/video/cocoa/cocoa_v.mm index 8d1fd4447d..9fb74cd041 100644 --- a/src/video/cocoa/cocoa_v.mm +++ b/src/video/cocoa/cocoa_v.mm @@ -43,6 +43,7 @@ #import /* for MAXPATHLEN */ #import /* gettimeofday */ +#include /** * Important notice regarding all modifications!!!!!!! @@ -228,6 +229,30 @@ void VideoDriver_Cocoa::EditBoxLostFocus() HandleTextInput(nullptr, true); } +/** + * Get refresh rates of all connected monitors. + */ +std::vector VideoDriver_Cocoa::GetListOfMonitorRefreshRates() +{ + std::vector rates{}; + + if (MacOSVersionIsAtLeast(10, 6, 0)) { + std::array displays; + + uint32_t count = 0; + CGGetActiveDisplayList(displays.size(), displays.data(), &count); + + for (uint32_t i = 0; i < count; i++) { + CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displays[i]); + int rate = (int)CGDisplayModeGetRefreshRate(mode); + if (rate > 0) rates.push_back(rate); + CGDisplayModeRelease(mode); + } + } + + return rates; +} + /** * Get the resolution of the main screen. */ diff --git a/src/video/sdl2_v.cpp b/src/video/sdl2_v.cpp index 62675280ca..2d8558534f 100644 --- a/src/video/sdl2_v.cpp +++ b/src/video/sdl2_v.cpp @@ -237,6 +237,17 @@ void VideoDriver_SDL_Base::EditBoxLostFocus() } } +std::vector VideoDriver_SDL_Base::GetListOfMonitorRefreshRates() +{ + std::vector rates = {}; + for (int i = 0; i < SDL_GetNumVideoDisplays(); i++) { + SDL_DisplayMode mode = {}; + if (SDL_GetDisplayMode(i, 0, &mode) != 0) continue; + if (mode.refresh_rate != 0) rates.push_back(mode.refresh_rate); + } + return rates; +} + struct SDLVkMapping { SDL_Keycode vk_from; diff --git a/src/video/sdl2_v.h b/src/video/sdl2_v.h index b1a64dd9c8..bd43f71f89 100644 --- a/src/video/sdl2_v.h +++ b/src/video/sdl2_v.h @@ -39,6 +39,8 @@ public: void EditBoxLostFocus() override; + std::vector GetListOfMonitorRefreshRates() override; + const char *GetName() const override { return "sdl"; } protected: diff --git a/src/video/video_driver.hpp b/src/video/video_driver.hpp index 4b2de253a3..8c2b9d4375 100644 --- a/src/video/video_driver.hpp +++ b/src/video/video_driver.hpp @@ -149,6 +149,15 @@ public: */ virtual void EditBoxGainedFocus() {} + /** + * Get a list of refresh rates of each available monitor. + * @return A vector of the refresh rates of all available monitors. + */ + virtual std::vector GetListOfMonitorRefreshRates() + { + return {}; + } + /** * Get a suggested default GUI zoom taking screen DPI into account. */ diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp index 8030380ce0..a802cdafa4 100644 --- a/src/video/win32_v.cpp +++ b/src/video/win32_v.cpp @@ -916,6 +916,27 @@ void VideoDriver_Win32Base::EditBoxLostFocus() SetCandidatePos(this->main_wnd); } +std::vector VideoDriver_Win32Base::GetListOfMonitorRefreshRates() +{ + std::vector rates = {}; + EnumDisplayMonitors(nullptr, nullptr, [](HMONITOR hMonitor, HDC hDC, LPRECT rc, LPARAM data) -> BOOL { + auto &list = *reinterpret_cast*>(data); + + MONITORINFOEX monitorInfo = {}; + monitorInfo.cbSize = sizeof(MONITORINFOEX); + GetMonitorInfo(hMonitor, &monitorInfo); + + DEVMODE devMode = {}; + devMode.dmSize = sizeof(DEVMODE); + devMode.dmDriverExtra = 0; + EnumDisplaySettings(monitorInfo.szDevice, ENUM_CURRENT_SETTINGS, &devMode); + + if (devMode.dmDisplayFrequency != 0) list.push_back(devMode.dmDisplayFrequency); + return true; + }, reinterpret_cast(&rates)); + return rates; +} + Dimension VideoDriver_Win32Base::GetScreenSize() const { return { static_cast(GetSystemMetrics(SM_CXSCREEN)), static_cast(GetSystemMetrics(SM_CYSCREEN)) }; diff --git a/src/video/win32_v.h b/src/video/win32_v.h index 93ebdd83eb..f6ca291f10 100644 --- a/src/video/win32_v.h +++ b/src/video/win32_v.h @@ -33,6 +33,8 @@ public: void EditBoxLostFocus() override; + std::vector GetListOfMonitorRefreshRates() override; + protected: HWND main_wnd; ///< Handle to system window. bool fullscreen; ///< Whether to use (true) fullscreen mode. diff --git a/src/widgets/settings_widget.h b/src/widgets/settings_widget.h index 0b816ee1fe..7f8b0e1117 100644 --- a/src/widgets/settings_widget.h +++ b/src/widgets/settings_widget.h @@ -33,6 +33,7 @@ enum GameOptionsWidgets { WID_GO_BASE_MUSIC_DESCRIPTION = WID_GO_BASE_MUSIC_TEXTFILE + TFT_END, ///< Description of selected base music set. WID_GO_FONT_ZOOM_DROPDOWN, ///< Dropdown for the font zoom level. WID_GO_VIDEO_ACCEL_BUTTON, ///< Toggle for video acceleration. + WID_GO_REFRESH_RATE_DROPDOWN, ///< Dropdown for all available refresh rates. }; /** Widgets of the #GameSettingsWindow class. */