@@ -51,212 +51,212 @@ static const StringID _autosave_dropdown
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_6_MONTHS,
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_12_MONTHS,
INVALID_STRING_ID,
};
static const StringID _gui_zoom_dropdown[] = {
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO,
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL,
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM,
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM,
static const StringID _font_zoom_dropdown[] = {
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO,
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL,
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM,
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM,
static Dimension _circle_size; ///< Dimension of the circle +/- icon. This is here as not all users are within the class of the settings window.
static const void *ResolveVariableAddress(const GameSettings *settings_ptr, const SettingDesc *sd);
/**
* Get index of the current screen resolution.
* @return Index of the current screen resolution if it is a known resolution, _resolutions.size() otherwise.
*/
static uint GetCurrentResolutionIndex()
{
auto it = std::find(_resolutions.begin(), _resolutions.end(), Dimension(_screen.width, _screen.height));
return std::distance(_resolutions.begin(), it);
}
static void ShowCustCurrency();
template <class T>
static DropDownList BuildSetDropDownList(int *selected_index, bool allow_selection)
int n = T::GetNumSets();
*selected_index = T::GetIndexOfUsedSet();
DropDownList list;
for (int i = 0; i < n; i++) {
list.emplace_back(new DropDownListCharStringItem(T::GetSet(i)->name, i, !allow_selection && (*selected_index != i)));
return list;
DropDownList BuildMusicSetDropDownList(int *selected_index)
return BuildSetDropDownList<BaseMusic>(selected_index, true);
/** Window for displaying the textfile of a BaseSet. */
template <class TBaseSet>
struct BaseSetTextfileWindow : public TextfileWindow {
const TBaseSet* baseset; ///< View the textfile of this BaseSet.
StringID content_type; ///< STR_CONTENT_TYPE_xxx for title.
BaseSetTextfileWindow(TextfileType file_type, const TBaseSet* baseset, StringID content_type) : TextfileWindow(file_type), baseset(baseset), content_type(content_type)
const char *textfile = this->baseset->GetTextfile(file_type);
this->LoadTextfile(textfile, BASESET_DIR);
void SetStringParameters(int widget) const override
if (widget == WID_TF_CAPTION) {
SetDParam(0, content_type);
SetDParamStr(1, this->baseset->name.c_str());
* Open the BaseSet version of the textfile window.
* @param file_type The type of textfile to display.
* @param baseset The BaseSet to use.
* @param content_type STR_CONTENT_TYPE_xxx for title.
void ShowBaseSetTextfileWindow(TextfileType file_type, const TBaseSet* baseset, StringID content_type)
DeleteWindowById(WC_TEXTFILE, file_type);
new BaseSetTextfileWindow<TBaseSet>(file_type, baseset, content_type);
std::set<int> _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()
static void AddCustomRefreshRates()
/* 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<int> monitorRates = VideoDriver::GetInstance()->GetListOfMonitorRefreshRates();
std::copy(monitorRates.begin(), monitorRates.end(), std::inserter(_refresh_rates, _refresh_rates.end()));
struct GameOptionsWindow : Window {
GameSettings *opt;
bool reload;
GameOptionsWindow(WindowDesc *desc) : Window(desc)
this->opt = &GetGameSettings();
this->reload = false;
AddRefreshRatesAndSelect();
AddCustomRefreshRates();
this->InitNested(WN_GAME_OPTIONS_GAME_OPTIONS);
this->OnInvalidateData(0);
~GameOptionsWindow()
DeleteWindowById(WC_CUSTOM_CURRENCY, 0);
DeleteWindowByClass(WC_TEXTFILE);
if (this->reload) _switch_mode = SM_MENU;
* Build the dropdown list for a specific widget.
* @param widget Widget to build list for
* @param selected_index Currently selected item
* @return the built dropdown list, or nullptr if the widget has no dropdown menu.
DropDownList BuildDropDownList(int widget, int *selected_index) const
switch (widget) {
case WID_GO_CURRENCY_DROPDOWN: { // Setup currencies dropdown
*selected_index = this->opt->locale.currency;
StringID *items = BuildCurrencyDropdown();
uint64 disabled = _game_mode == GM_MENU ? 0LL : ~GetMaskOfAllowedCurrencies();
/* Add non-custom currencies; sorted naturally */
for (uint i = 0; i < CURRENCY_END; items++, i++) {
if (i == CURRENCY_CUSTOM) continue;
list.emplace_back(new DropDownListStringItem(*items, i, HasBit(disabled, i)));
std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc);
/* Append custom currency at the end */
list.emplace_back(new DropDownListItem(-1, false)); // separator line
list.emplace_back(new DropDownListStringItem(STR_GAME_OPTIONS_CURRENCY_CUSTOM, CURRENCY_CUSTOM, HasBit(disabled, CURRENCY_CUSTOM)));
break;
case WID_GO_AUTOSAVE_DROPDOWN: { // Setup autosave dropdown
*selected_index = _settings_client.gui.autosave;
const StringID *items = _autosave_dropdown;
for (uint i = 0; *items != INVALID_STRING_ID; items++, i++) {
list.emplace_back(new DropDownListStringItem(*items, i, false));
case WID_GO_LANG_DROPDOWN: { // Setup interface language dropdown
for (uint i = 0; i < _languages.size(); i++) {
auto item = new DropDownListParamStringItem(STR_JUST_RAW_STRING, i, false);
if (&_languages[i] == _current_language) {
*selected_index = i;
item->SetParamStr(0, _languages[i].own_name);
} else {
/* Especially with sprite-fonts, not all localized
* names can be rendered. So instead, we use the
* international names for anything but the current
* selected language. This avoids showing a few ????
* entries in the dropdown list. */
item->SetParamStr(0, _languages[i].name);
list.emplace_back(item);
case WID_GO_RESOLUTION_DROPDOWN: // Setup resolution dropdown
if (_resolutions.empty()) break;
*selected_index = GetCurrentResolutionIndex();
for (uint i = 0; i < _resolutions.size(); i++) {
auto item = new DropDownListParamStringItem(STR_GAME_OPTIONS_RESOLUTION_ITEM, i, false);
item->SetParam(0, _resolutions[i].width);
item->SetParam(1, _resolutions[i].height);
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);
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;
for (int i = 0; *items != INVALID_STRING_ID; items++, i++) {
list.emplace_back(new DropDownListStringItem(*items, i, i != 0 && _settings_client.gui.zoom_min > ZOOM_LVL_OUT_4X - i + 1));
Status change: