From 32f9e4df6c8bb43d2870d33038e07f0af1beeeb7 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Thu, 18 Jun 2026 18:22:17 +0200 Subject: [PATCH] Codechange: make Currency scoped --- src/currency.cpp | 62 ++++++------- src/currency_func.h | 4 +- src/currency_type.h | 99 +++++++++++---------- src/newgrf/newgrf_act0_globalvar.cpp | 12 +-- src/saveload/afterload.cpp | 12 +-- src/settings_gui.cpp | 18 ++-- src/table/settings/locale_settings.ini | 6 +- src/table/settings/old_gameopt_settings.ini | 4 +- 8 files changed, 110 insertions(+), 107 deletions(-) diff --git a/src/currency.cpp b/src/currency.cpp index c33ac86eb4..0160c66558 100644 --- a/src/currency.cpp +++ b/src/currency.cpp @@ -27,7 +27,7 @@ * | | Euro year | | | | name * | | | | | | | | */ /** The original currency specifications. */ -static const std::array origin_currency_specs = {{ +static const EnumIndexArray _origin_currency_specs = {{{ { 1, "", CF_NOEURO, "\u00a3", "", "GBP", CurrencySymbolPosition::Prefix, STR_GAME_OPTIONS_CURRENCY_GBP }, ///< british pound { 2, "", CF_NOEURO, "$", "", "USD", CurrencySymbolPosition::Prefix, STR_GAME_OPTIONS_CURRENCY_USD }, ///< american dollar { 2, "", CF_ISEURO, "\u20ac", "", "EUR", CurrencySymbolPosition::Prefix, STR_GAME_OPTIONS_CURRENCY_EUR }, ///< euro @@ -74,10 +74,10 @@ static const std::array origin_currency_specs = {{ { 400, "", TimerGameCalendar::Year{2002}, "", "$00", "PTE", CurrencySymbolPosition::Suffix, STR_GAME_OPTIONS_CURRENCY_PTE }, ///< portuguese escudo { 50, "", CF_NOEURO, "", NBSP "\u20B4", "UAH", CurrencySymbolPosition::Suffix, STR_GAME_OPTIONS_CURRENCY_UAH }, ///< ukrainian hryvnia {35000, "", CF_NOEURO, "", NBSP "\u20AB", "VND", CurrencySymbolPosition::Suffix, STR_GAME_OPTIONS_CURRENCY_VND }, ///< Vietnamese Dong -}}; +}}}; /** Array of currencies used by the system */ -std::array _currency_specs; +EnumIndexArray _currency_specs; /** * This array represent the position of OpenTTD's currencies, @@ -86,25 +86,25 @@ std::array _currency_specs; * So, we must reindex them to our own order. */ const Currency _ttdpatch_to_ottd_currency[] = { - CURRENCY_GBP, - CURRENCY_USD, - CURRENCY_FRF, - CURRENCY_DEM, - CURRENCY_JPY, - CURRENCY_ESP, - CURRENCY_HUF, - CURRENCY_PLN, - CURRENCY_ATS, - CURRENCY_BEF, - CURRENCY_DKK, - CURRENCY_FIM, - CURRENCY_GRD, - CURRENCY_CHF, - CURRENCY_NLG, - CURRENCY_ITL, - CURRENCY_SEK, - CURRENCY_RUR, - CURRENCY_EUR, + Currency::GBP, + Currency::USD, + Currency::FRF, + Currency::DEM, + Currency::JPY, + Currency::ESP, + Currency::HUF, + Currency::PLN, + Currency::ATS, + Currency::BEF, + Currency::DKK, + Currency::FIM, + Currency::GRD, + Currency::CHF, + Currency::NLG, + Currency::ITL, + Currency::SEK, + Currency::RUR, + Currency::EUR, }; /** @@ -113,11 +113,11 @@ const Currency _ttdpatch_to_ottd_currency[] = { * it is a grf written for ottd, thus returning the same id. * Only called from newgrf.cpp * @param grfcurr_id currency id coming from newgrf - * @return The corrected index, or \c CURRENCY_END when invalid. + * @return The corrected index, or \c Currency::End when invalid. */ Currency GetNewgrfCurrencyIdConverted(uint8_t grfcurr_id) { - if (grfcurr_id >= std::size(_ttdpatch_to_ottd_currency)) return CURRENCY_END; + if (grfcurr_id >= std::size(_ttdpatch_to_ottd_currency)) return Currency::End; return _ttdpatch_to_ottd_currency[grfcurr_id]; } @@ -129,14 +129,14 @@ Currencies GetMaskOfAllowedCurrencies() { Currencies mask{}; - for (Currency i : EnumRange(CURRENCY_END)) { + for (Currency i : EnumRange(Currency::End)) { TimerGameCalendar::Year to_euro = _currency_specs[i].to_euro; if (to_euro != CF_NOEURO && to_euro != CF_ISEURO && TimerGameCalendar::year >= to_euro) continue; if (to_euro == CF_ISEURO && TimerGameCalendar::year < 2000) continue; mask.Set(i); } - mask.Set(CURRENCY_CUSTOM); // always allow custom currency + mask.Set(Currency::Custom); // always allow custom currency return mask; } @@ -148,21 +148,21 @@ static const IntervalTimer _check_switch_to_euro({TimerGameCa if (_currency_specs[_settings_game.locale.currency].to_euro != CF_NOEURO && _currency_specs[_settings_game.locale.currency].to_euro != CF_ISEURO && TimerGameCalendar::year >= _currency_specs[_settings_game.locale.currency].to_euro) { - _settings_game.locale.currency = CURRENCY_EUR; + _settings_game.locale.currency = Currency::EUR; AddNewsItem(GetEncodedString(STR_NEWS_EURO_INTRODUCTION), NewsType::Economy, NewsStyle::Normal, {}); } }); /** * Will fill _currency_specs array with - * default values from origin_currency_specs + * default values from _origin_currency_specs * Called only from newgrf.cpp and settings.cpp. * @param preserve_custom will not reset custom currency */ void ResetCurrencies(bool preserve_custom) { - for (Currency i : EnumRange(CURRENCY_END)) { - if (preserve_custom && i == CURRENCY_CUSTOM) continue; - _currency_specs[i] = origin_currency_specs[i]; + for (Currency i : EnumRange(Currency::End)) { + if (preserve_custom && i == Currency::Custom) continue; + _currency_specs[i] = _origin_currency_specs[i]; } } diff --git a/src/currency_func.h b/src/currency_func.h index 0713cd5931..ec68fd095f 100644 --- a/src/currency_func.h +++ b/src/currency_func.h @@ -13,7 +13,7 @@ #include "currency_type.h" #include "settings_type.h" -extern std::array _currency_specs; +extern EnumIndexArray _currency_specs; /** * Get the custom currency. @@ -21,7 +21,7 @@ extern std::array _currency_specs; */ inline CurrencySpec &GetCustomCurrency() { - return _currency_specs[CURRENCY_CUSTOM]; + return _currency_specs[Currency::Custom]; } /** diff --git a/src/currency_type.h b/src/currency_type.h index 99137c22b6..143dee5bc2 100644 --- a/src/currency_type.h +++ b/src/currency_type.h @@ -22,58 +22,59 @@ static constexpr TimerGameCalendar::Year MIN_EURO_YEAR{2000}; ///< The earliest * savegame compatibility and in order to refer to them quickly, especially * for referencing the custom one. */ -enum Currency : uint8_t { - CURRENCY_GBP, ///< British Pound - CURRENCY_USD, ///< US Dollar - CURRENCY_EUR, ///< Euro - CURRENCY_JPY, ///< Japanese Yen - CURRENCY_ATS, ///< Austrian Schilling - CURRENCY_BEF, ///< Belgian Franc - CURRENCY_CHF, ///< Swiss Franc - CURRENCY_CZK, ///< Czech Koruna - CURRENCY_DEM, ///< Deutsche Mark - CURRENCY_DKK, ///< Danish Krona - CURRENCY_ESP, ///< Spanish Peseta - CURRENCY_FIM, ///< Finish Markka - CURRENCY_FRF, ///< French Franc - CURRENCY_GRD, ///< Greek Drachma - CURRENCY_HUF, ///< Hungarian Forint - CURRENCY_ISK, ///< Icelandic Krona - CURRENCY_ITL, ///< Italian Lira - CURRENCY_NLG, ///< Dutch Gulden - CURRENCY_NOK, ///< Norwegian Krone - CURRENCY_PLN, ///< Polish Zloty - CURRENCY_RON, ///< Romanian Leu - CURRENCY_RUR, ///< Russian Rouble - CURRENCY_SIT, ///< Slovenian Tolar - CURRENCY_SEK, ///< Swedish Krona - CURRENCY_YTL, ///< Turkish Lira - CURRENCY_SKK, ///< Slovak Kornuna - CURRENCY_BRL, ///< Brazilian Real - CURRENCY_EEK, ///< Estonian Krooni - CURRENCY_LTL, ///< Lithuanian Litas - CURRENCY_KRW, ///< South Korean Won - CURRENCY_ZAR, ///< South African Rand - CURRENCY_CUSTOM, ///< Custom currency - CURRENCY_GEL, ///< Georgian Lari - CURRENCY_IRR, ///< Iranian Rial - CURRENCY_RUB, ///< New Russian Ruble - CURRENCY_MXN, ///< Mexican Peso - CURRENCY_NTD, ///< New Taiwan Dollar - CURRENCY_CNY, ///< Chinese Renminbi - CURRENCY_HKD, ///< Hong Kong Dollar - CURRENCY_INR, ///< Indian Rupee - CURRENCY_IDR, ///< Indonesian Rupiah - CURRENCY_MYR, ///< Malaysian Ringgit - CURRENCY_LVL, ///< Latvian Lats - CURRENCY_PTE, ///< Portuguese Escudo - CURRENCY_UAH, ///< Ukrainian Hryvnia - CURRENCY_VND, ///< Vietnamese Dong - CURRENCY_END, ///< always the last item +enum class Currency : uint8_t { + GBP, ///< British Pound + USD, ///< US Dollar + EUR, ///< Euro + JPY, ///< Japanese Yen + ATS, ///< Austrian Schilling + BEF, ///< Belgian Franc + CHF, ///< Swiss Franc + CZK, ///< Czech Koruna + DEM, ///< Deutsche Mark + DKK, ///< Danish Krona + ESP, ///< Spanish Peseta + FIM, ///< Finish Markka + FRF, ///< French Franc + GRD, ///< Greek Drachma + HUF, ///< Hungarian Forint + ISK, ///< Icelandic Krona + ITL, ///< Italian Lira + NLG, ///< Dutch Gulden + NOK, ///< Norwegian Krone + PLN, ///< Polish Zloty + RON, ///< Romanian Leu + RUR, ///< Russian Rouble + SIT, ///< Slovenian Tolar + SEK, ///< Swedish Krona + YTL, ///< Turkish Lira + SKK, ///< Slovak Kornuna + BRL, ///< Brazilian Real + EEK, ///< Estonian Krooni + LTL, ///< Lithuanian Litas + KRW, ///< South Korean Won + ZAR, ///< South African Rand + Custom, ///< Custom currency + GEL, ///< Georgian Lari + IRR, ///< Iranian Rial + RUB, ///< New Russian Ruble + MXN, ///< Mexican Peso + NTD, ///< New Taiwan Dollar + CNY, ///< Chinese Renminbi + HKD, ///< Hong Kong Dollar + INR, ///< Indian Rupee + IDR, ///< Indonesian Rupiah + MYR, ///< Malaysian Ringgit + LVL, ///< Latvian Lats + PTE, ///< Portuguese Escudo + UAH, ///< Ukrainian Hryvnia + VND, ///< Vietnamese Dong + + End, ///< Always the last item. }; /** Bitmask of \c Currency. */ -using Currencies = EnumBitSet; +using Currencies = EnumBitSet; /** The currency symbol positions that we can show. */ enum class CurrencySymbolPosition : uint8_t { diff --git a/src/newgrf/newgrf_act0_globalvar.cpp b/src/newgrf/newgrf_act0_globalvar.cpp index 6f78be220a..b4caaf6807 100644 --- a/src/newgrf/newgrf_act0_globalvar.cpp +++ b/src/newgrf/newgrf_act0_globalvar.cpp @@ -147,7 +147,7 @@ static ChangeInfoResult GlobalVarChangeInfo(uint first, uint last, int prop, Byt case 0x0A: { // Currency display names Currency curidx = GetNewgrfCurrencyIdConverted(id); - if (curidx < CURRENCY_END) { + if (curidx < Currency::End) { AddStringForMapping(GRFStringID{buf.ReadWord()}, [curidx](StringID str) { _currency_specs[curidx].name = str; _currency_specs[curidx].code.clear(); @@ -162,7 +162,7 @@ static ChangeInfoResult GlobalVarChangeInfo(uint first, uint last, int prop, Byt Currency curidx = GetNewgrfCurrencyIdConverted(id); uint32_t rate = buf.ReadDWord(); - if (curidx < CURRENCY_END) { + if (curidx < Currency::End) { /* TTDPatch uses a multiple of 1000 for its conversion calculations, * which OTTD does not. For this reason, divide grf value by 1000, * to be compatible */ @@ -177,7 +177,7 @@ static ChangeInfoResult GlobalVarChangeInfo(uint first, uint last, int prop, Byt Currency curidx = GetNewgrfCurrencyIdConverted(id); uint16_t options = buf.ReadWord(); - if (curidx < CURRENCY_END) { + if (curidx < Currency::End) { _currency_specs[curidx].separator.clear(); _currency_specs[curidx].separator.push_back(GB(options, 0, 8)); StrMakeValidInPlace(_currency_specs[curidx].separator); @@ -194,7 +194,7 @@ static ChangeInfoResult GlobalVarChangeInfo(uint first, uint last, int prop, Byt Currency curidx = GetNewgrfCurrencyIdConverted(id); std::string prefix = ReadDWordAsString(buf); - if (curidx < CURRENCY_END) { + if (curidx < Currency::End) { _currency_specs[curidx].prefix = std::move(prefix); } else { GrfMsg(1, "GlobalVarChangeInfo: Currency symbol {} out of range, ignoring", id); @@ -206,7 +206,7 @@ static ChangeInfoResult GlobalVarChangeInfo(uint first, uint last, int prop, Byt Currency curidx = GetNewgrfCurrencyIdConverted(id); std::string suffix = ReadDWordAsString(buf); - if (curidx < CURRENCY_END) { + if (curidx < Currency::End) { _currency_specs[curidx].suffix = std::move(suffix); } else { GrfMsg(1, "GlobalVarChangeInfo: Currency symbol {} out of range, ignoring", id); @@ -218,7 +218,7 @@ static ChangeInfoResult GlobalVarChangeInfo(uint first, uint last, int prop, Byt Currency curidx = GetNewgrfCurrencyIdConverted(id); TimerGameCalendar::Year year_euro{buf.ReadWord()}; - if (curidx < CURRENCY_END) { + if (curidx < Currency::End) { _currency_specs[curidx].to_euro = year_euro; } else { GrfMsg(1, "GlobalVarChangeInfo: Euro intro date {} out of range, ignoring", id); diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 308f89a778..84c9c26186 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -190,14 +190,14 @@ static void UpdateExclusiveRights() static void UpdateCurrencies() { constexpr Currency convert_currency[] = { - CURRENCY_GBP, CURRENCY_USD, CURRENCY_FRF, CURRENCY_DEM, CURRENCY_JPY, - CURRENCY_ESP, CURRENCY_HUF, CURRENCY_PLN, CURRENCY_ATS, CURRENCY_BEF, - CURRENCY_DKK, CURRENCY_FIM, CURRENCY_GRD, CURRENCY_CHF, CURRENCY_NLG, - CURRENCY_ITL, CURRENCY_SIT, CURRENCY_RUR, CURRENCY_CZK, CURRENCY_ISK, - CURRENCY_NOK, CURRENCY_EUR, CURRENCY_RON, + Currency::GBP, Currency::USD, Currency::FRF, Currency::DEM, Currency::JPY, + Currency::ESP, Currency::HUF, Currency::PLN, Currency::ATS, Currency::BEF, + Currency::DKK, Currency::FIM, Currency::GRD, Currency::CHF, Currency::NLG, + Currency::ITL, Currency::SIT, Currency::RUR, Currency::CZK, Currency::ISK, + Currency::NOK, Currency::EUR, Currency::RON, }; - _settings_game.locale.currency = convert_currency[_settings_game.locale.currency]; + _settings_game.locale.currency = convert_currency[to_underlying(_settings_game.locale.currency)]; } /** diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 1c6fc2ac55..794df58324 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -476,13 +476,13 @@ struct GameOptionsWindow : Window { DropDownList list; switch (widget) { case WID_GO_CURRENCY_DROPDOWN: { // Setup currencies dropdown - *selected_index = this->opt->locale.currency; + *selected_index = to_underlying(this->opt->locale.currency); Currencies disabled = _game_mode == GameMode::Menu ? Currencies{} : GetMaskOfAllowedCurrencies().Flip(); /* Add non-custom currencies; sorted naturally */ - for (Currency i : EnumRange(CURRENCY_END)) { - if (i == CURRENCY_CUSTOM) continue; - const CurrencySpec ¤cy = _currency_specs[i]; + for (Currency i : EnumRange(Currency::End)) { + if (i == Currency::Custom) continue; + CurrencySpec ¤cy = _currency_specs[i]; if (currency.code.empty()) { list.push_back(MakeDropDownListStringItem(currency.name, i, disabled.Test(i))); } else { @@ -493,7 +493,7 @@ struct GameOptionsWindow : Window { /* Append custom currency at the end */ list.push_back(MakeDropDownListDividerItem()); // separator line - list.push_back(MakeDropDownListStringItem(STR_GAME_OPTIONS_CURRENCY_CUSTOM, CURRENCY_CUSTOM, disabled.Test(CURRENCY_CUSTOM))); + list.push_back(MakeDropDownListStringItem(STR_GAME_OPTIONS_CURRENCY_CUSTOM, Currency::Custom, disabled.Test(Currency::Custom))); break; } @@ -1423,11 +1423,13 @@ struct GameOptionsWindow : Window { void OnDropdownSelect(WidgetID widget, int index, int) override { switch (widget) { - case WID_GO_CURRENCY_DROPDOWN: // Currency - if (index == CURRENCY_CUSTOM) ShowCustCurrency(); - this->opt->locale.currency = static_cast(index); + case WID_GO_CURRENCY_DROPDOWN: { // Currency + Currency currency = static_cast(index); + if (currency == Currency::Custom) ShowCustCurrency(); + this->opt->locale.currency = currency; ReInitAllWindows(false); break; + } case WID_GO_AUTOSAVE_DROPDOWN: // Autosave options _settings_client.gui.autosave_interval = _autosave_dropdown_to_minutes[index]; diff --git a/src/table/settings/locale_settings.ini b/src/table/settings/locale_settings.ini index 21061d5c5c..ffcb61ae40 100644 --- a/src/table/settings/locale_settings.ini +++ b/src/table/settings/locale_settings.ini @@ -15,7 +15,7 @@ uint8_t _old_units; ///< Old units from old static constexpr std::initializer_list _locale_currencies{"GBP"sv, "USD"sv, "EUR"sv, "JPY"sv, "ATS"sv, "BEF"sv, "CHF"sv, "CZK"sv, "DEM"sv, "DKK"sv, "ESP"sv, "FIM"sv, "FRF"sv, "GRD"sv, "HUF"sv, "ISK"sv, "ITL"sv, "NLG"sv, "NOK"sv, "PLN"sv, "RON"sv, "RUR"sv, "SIT"sv, "SEK"sv, "TRY"sv, "SKK"sv, "BRL"sv, "EEK"sv, "LTL"sv, "KRW"sv, "ZAR"sv, "custom"sv, "GEL"sv, "IRR"sv, "RUB"sv, "MXN"sv, "NTD"sv, "CNY"sv, "HKD"sv, "INR"sv, "IDR"sv, "MYR"sv, "LVL"sv, "PTE"sv, "UAH"sv, "VND"sv}; static constexpr std::initializer_list _locale_units{"imperial"sv, "metric"sv, "si"sv, "gameunits"sv, "knots"sv}; -static_assert(_locale_currencies.size() == CURRENCY_END); +static_assert(_locale_currencies.size() == to_underlying(Currency::End)); static const SettingVariant _locale_settings_table[] = { [post-amble] @@ -54,8 +54,8 @@ var = locale.currency type = SLE_UINT8 from = SLV_97 flags = SettingFlag::NoNetworkSync -def = 0 -max = CURRENCY_END - 1 +def = Currency::GBP +max = static_cast(to_underlying(Currency::End) - 1) full = _locale_currencies post_cb = [](auto) { MarkWholeScreenDirty(); } cat = SC_BASIC diff --git a/src/table/settings/old_gameopt_settings.ini b/src/table/settings/old_gameopt_settings.ini index ef976b188a..001681f539 100644 --- a/src/table/settings/old_gameopt_settings.ini +++ b/src/table/settings/old_gameopt_settings.ini @@ -104,8 +104,8 @@ cat = SC_BASIC var = locale.currency type = SLE_UINT8 flags = SettingFlag::NoNetworkSync -def = 0 -max = CURRENCY_END - 1 +def = Currency::GBP +max = static_cast(to_underlying(Currency::End) - 1) full = _locale_currencies cat = SC_BASIC